]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/exp_aggr.adb
[Ada] Fix obsolete comments/name referring to girder discriminants
[gcc.git] / gcc / ada / exp_aggr.adb
CommitLineData
70482933
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- E X P _ A G G R --
6-- --
7-- B o d y --
8-- --
8d0d46f4 9-- Copyright (C) 1992-2021, Free Software Foundation, Inc. --
70482933
RK
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- --
b5c84c3c 13-- ware Foundation; either version 3, or (at your option) any later ver- --
70482933
RK
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 --
b5c84c3c
RD
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. --
70482933
RK
20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
70482933
RK
23-- --
24------------------------------------------------------------------------------
25
104f58db
BD
26with Aspects; use Aspects;
27with Atree; use Atree;
28with Checks; use Checks;
29with Debug; use Debug;
30with Einfo; use Einfo;
76f9c7f4 31with Einfo.Entities; use Einfo.Entities;
104f58db
BD
32with Einfo.Utils; use Einfo.Utils;
33with Elists; use Elists;
34with Errout; use Errout;
35with Expander; use Expander;
36with Exp_Util; use Exp_Util;
37with Exp_Ch3; use Exp_Ch3;
38with Exp_Ch6; use Exp_Ch6;
39with Exp_Ch7; use Exp_Ch7;
40with Exp_Ch9; use Exp_Ch9;
41with Exp_Disp; use Exp_Disp;
42with Exp_Tss; use Exp_Tss;
43with Freeze; use Freeze;
44with Itypes; use Itypes;
45with Lib; use Lib;
46with Namet; use Namet;
47with Nmake; use Nmake;
48with Nlists; use Nlists;
49with Opt; use Opt;
50with Restrict; use Restrict;
51with Rident; use Rident;
52with Rtsfind; use Rtsfind;
53with Ttypes; use Ttypes;
54with Sem; use Sem;
55with Sem_Aggr; use Sem_Aggr;
56with Sem_Aux; use Sem_Aux;
e1dfbb03 57with Sem_Case; use Sem_Case;
104f58db
BD
58with Sem_Ch3; use Sem_Ch3;
59with Sem_Ch8; use Sem_Ch8;
60with Sem_Ch13; use Sem_Ch13;
61with Sem_Eval; use Sem_Eval;
62with Sem_Mech; use Sem_Mech;
63with Sem_Res; use Sem_Res;
64with Sem_Util; use Sem_Util;
65with Sinfo; use Sinfo;
66with Sinfo.Nodes; use Sinfo.Nodes;
67with Sinfo.Utils; use Sinfo.Utils;
68with Snames; use Snames;
69with Stand; use Stand;
70with Stringt; use Stringt;
71with Tbuild; use Tbuild;
72with Uintp; use Uintp;
73with Urealp; use Urealp;
70482933
RK
74
75package body Exp_Aggr is
76
77 type Case_Bounds is record
78 Choice_Lo : Node_Id;
79 Choice_Hi : Node_Id;
80 Choice_Node : Node_Id;
81 end record;
82
83 type Case_Table_Type is array (Nat range <>) of Case_Bounds;
84 -- Table type used by Check_Case_Choices procedure
85
9eb8d5b4
AC
86 procedure Expand_Delta_Array_Aggregate (N : Node_Id; Deltas : List_Id);
87 procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id);
745f5698 88 procedure Expand_Container_Aggregate (N : Node_Id);
9eb8d5b4 89
a80b1eb7
EB
90 function Get_Base_Object (N : Node_Id) return Entity_Id;
91 -- Return the base object, i.e. the outermost prefix object, that N refers
92 -- to statically, or Empty if it cannot be determined. The assumption is
93 -- that all dereferences are explicit in the tree rooted at N.
94
df3e68b1
HK
95 function Has_Default_Init_Comps (N : Node_Id) return Boolean;
96 -- N is an aggregate (record or array). Checks the presence of default
97 -- initialization (<>) in any component (Ada 2005: AI-287).
98
9f51b855
JM
99 function Is_CCG_Supported_Aggregate (N : Node_Id) return Boolean;
100 -- Return True if aggregate N is located in a context supported by the
101 -- CCG backend; False otherwise.
6031f544 102
df3e68b1
HK
103 function Is_Static_Dispatch_Table_Aggregate (N : Node_Id) return Boolean;
104 -- Returns true if N is an aggregate used to initialize the components
b465ef6f 105 -- of a statically allocated dispatch table.
df3e68b1 106
937e9676
AC
107 function Late_Expansion
108 (N : Node_Id;
109 Typ : Entity_Id;
110 Target : Node_Id) return List_Id;
111 -- This routine implements top-down expansion of nested aggregates. In
112 -- doing so, it avoids the generation of temporaries at each level. N is
113 -- a nested record or array aggregate with the Expansion_Delayed flag.
114 -- Typ is the expected type of the aggregate. Target is a (duplicatable)
115 -- expression that will hold the result of the aggregate expansion.
116
117 function Make_OK_Assignment_Statement
118 (Sloc : Source_Ptr;
119 Name : Node_Id;
120 Expression : Node_Id) return Node_Id;
121 -- This is like Make_Assignment_Statement, except that Assignment_OK
122 -- is set in the left operand. All assignments built by this unit use
123 -- this routine. This is needed to deal with assignments to initialized
124 -- constants that are done in place.
125
3cf3e5c6
AC
126 function Must_Slide
127 (Obj_Type : Entity_Id;
128 Typ : Entity_Id) return Boolean;
129 -- A static array aggregate in an object declaration can in most cases be
130 -- expanded in place. The one exception is when the aggregate is given
131 -- with component associations that specify different bounds from those of
132 -- the type definition in the object declaration. In this pathological
133 -- case the aggregate must slide, and we must introduce an intermediate
134 -- temporary to hold it.
135 --
136 -- The same holds in an assignment to one-dimensional array of arrays,
137 -- when a component may be given with bounds that differ from those of the
138 -- component type.
139
937e9676
AC
140 function Number_Of_Choices (N : Node_Id) return Nat;
141 -- Returns the number of discrete choices (not including the others choice
142 -- if present) contained in (sub-)aggregate N.
143
144 procedure Process_Transient_Component
145 (Loc : Source_Ptr;
146 Comp_Typ : Entity_Id;
147 Init_Expr : Node_Id;
148 Fin_Call : out Node_Id;
149 Hook_Clear : out Node_Id;
150 Aggr : Node_Id := Empty;
151 Stmts : List_Id := No_List);
152 -- Subsidiary to the expansion of array and record aggregates. Generate
153 -- part of the necessary code to finalize a transient component. Comp_Typ
154 -- is the component type. Init_Expr is the initialization expression of the
155 -- component which is always a function call. Fin_Call is the finalization
156 -- call used to clean up the transient function result. Hook_Clear is the
157 -- hook reset statement. Aggr and Stmts both control the placement of the
158 -- generated code. Aggr is the related aggregate. If present, all code is
159 -- inserted prior to Aggr using Insert_Action. Stmts is the initialization
160 -- statements of the component. If present, all code is added to Stmts.
161
162 procedure Process_Transient_Component_Completion
163 (Loc : Source_Ptr;
164 Aggr : Node_Id;
165 Fin_Call : Node_Id;
166 Hook_Clear : Node_Id;
167 Stmts : List_Id);
168 -- Subsidiary to the expansion of array and record aggregates. Generate
169 -- part of the necessary code to finalize a transient component. Aggr is
170 -- the related aggregate. Fin_Clear is the finalization call used to clean
171 -- up the transient component. Hook_Clear is the hook reset statment. Stmts
172 -- is the initialization statement list for the component. All generated
173 -- code is added to Stmts.
174
70482933
RK
175 procedure Sort_Case_Table (Case_Table : in out Case_Table_Type);
176 -- Sort the Case Table using the Lower Bound of each Choice as the key.
177 -- A simple insertion sort is used since the number of choices in a case
178 -- statement of variant part will usually be small and probably in near
179 -- sorted order.
180
181 ------------------------------------------------------
182 -- Local subprograms for Record Aggregate Expansion --
183 ------------------------------------------------------
184
d4dfb005
BD
185 function Is_Build_In_Place_Aggregate_Return (N : Node_Id) return Boolean;
186 -- True if N is an aggregate (possibly qualified or converted) that is
187 -- being returned from a build-in-place function.
188
df3e68b1 189 function Build_Record_Aggr_Code
f7e6fc47
RD
190 (N : Node_Id;
191 Typ : Entity_Id;
192 Lhs : Node_Id) return List_Id;
df3e68b1
HK
193 -- N is an N_Aggregate or an N_Extension_Aggregate. Typ is the type of the
194 -- aggregate. Target is an expression containing the location on which the
195 -- component by component assignments will take place. Returns the list of
196 -- assignments plus all other adjustments needed for tagged and controlled
203ddcea 197 -- types.
df3e68b1
HK
198
199 procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
d4dfb005 200 -- Transform a record aggregate into a sequence of assignments performed
64ac53f4 201 -- component by component. N is an N_Aggregate or N_Extension_Aggregate.
d4dfb005 202 -- Typ is the type of the record aggregate.
df3e68b1 203
70482933
RK
204 procedure Expand_Record_Aggregate
205 (N : Node_Id;
206 Orig_Tag : Node_Id := Empty;
207 Parent_Expr : Node_Id := Empty);
208 -- This is the top level procedure for record aggregate expansion.
209 -- Expansion for record aggregates needs expand aggregates for tagged
210 -- record types. Specifically Expand_Record_Aggregate adds the Tag
211 -- field in front of the Component_Association list that was created
212 -- during resolution by Resolve_Record_Aggregate.
213 --
214 -- N is the record aggregate node.
215 -- Orig_Tag is the value of the Tag that has to be provided for this
216 -- specific aggregate. It carries the tag corresponding to the type
217 -- of the outermost aggregate during the recursive expansion
218 -- Parent_Expr is the ancestor part of the original extension
219 -- aggregate
220
fbf5a39b 221 function Has_Mutable_Components (Typ : Entity_Id) return Boolean;
b465ef6f 222 -- Return true if one of the components is of a discriminated type with
fbf5a39b
AC
223 -- defaults. An aggregate for a type with mutable components must be
224 -- expanded into individual assignments.
225
a80b1eb7
EB
226 function In_Place_Assign_OK
227 (N : Node_Id;
228 Target_Object : Entity_Id := Empty) return Boolean;
4ff5aa0c
AC
229 -- Predicate to determine whether an aggregate assignment can be done in
230 -- place, because none of the new values can depend on the components of
231 -- the target of the assignment.
232
07fc65c4
GB
233 procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id);
234 -- If the type of the aggregate is a type extension with renamed discrimi-
235 -- nants, we must initialize the hidden discriminants of the parent.
236 -- Otherwise, the target object must not be initialized. The discriminants
237 -- are initialized by calling the initialization procedure for the type.
238 -- This is incorrect if the initialization of other components has any
239 -- side effects. We restrict this call to the case where the parent type
240 -- has a variant part, because this is the only case where the hidden
241 -- discriminants are accessed, namely when calling discriminant checking
242 -- functions of the parent type, and when applying a stream attribute to
243 -- an object of the derived type.
244
70482933 245 -----------------------------------------------------
07fc65c4 246 -- Local Subprograms for Array Aggregate Expansion --
70482933
RK
247 -----------------------------------------------------
248
2fedcc18
EB
249 function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean;
250 -- Returns true if an aggregate assignment can be done by the back end
251
eaf6e63a 252 function Aggr_Size_OK (N : Node_Id) return Boolean;
841dd0f5
AC
253 -- Very large static aggregates present problems to the back-end, and are
254 -- transformed into assignments and loops. This function verifies that the
255 -- total number of components of an aggregate is acceptable for rewriting
74e7891f
RD
256 -- into a purely positional static form. Aggr_Size_OK must be called before
257 -- calling Flatten.
258 --
841dd0f5 259 -- This function also detects and warns about one-component aggregates that
d940c627 260 -- appear in a nonstatic context. Even if the component value is static,
841dd0f5 261 -- such an aggregate must be expanded into an assignment.
643a0839 262
df3e68b1
HK
263 function Backend_Processing_Possible (N : Node_Id) return Boolean;
264 -- This function checks if array aggregate N can be processed directly
b465ef6f 265 -- by the backend. If this is the case, True is returned.
df3e68b1
HK
266
267 function Build_Array_Aggr_Code
268 (N : Node_Id;
269 Ctype : Entity_Id;
270 Index : Node_Id;
271 Into : Node_Id;
272 Scalar_Comp : Boolean;
273 Indexes : List_Id := No_List) return List_Id;
274 -- This recursive routine returns a list of statements containing the
275 -- loops and assignments that are needed for the expansion of the array
276 -- aggregate N.
277 --
278 -- N is the (sub-)aggregate node to be expanded into code. This node has
279 -- been fully analyzed, and its Etype is properly set.
280 --
d74716b3 281 -- Index is the index node corresponding to the array subaggregate N
df3e68b1
HK
282 --
283 -- Into is the target expression into which we are copying the aggregate.
284 -- Note that this node may not have been analyzed yet, and so the Etype
285 -- field may not be set.
286 --
287 -- Scalar_Comp is True if the component type of the aggregate is scalar
288 --
289 -- Indexes is the current list of expressions used to index the object we
290 -- are writing into.
291
6f639c98
ES
292 procedure Convert_Array_Aggr_In_Allocator
293 (Decl : Node_Id;
294 Aggr : Node_Id;
295 Target : Node_Id);
296 -- If the aggregate appears within an allocator and can be expanded in
297 -- place, this routine generates the individual assignments to components
298 -- of the designated object. This is an optimization over the general
299 -- case, where a temporary is first created on the stack and then used to
300 -- construct the allocated object on the heap.
301
07fc65c4 302 procedure Convert_To_Positional
c42006e9
AC
303 (N : Node_Id;
304 Handle_Bit_Packed : Boolean := False);
07fc65c4 305 -- If possible, convert named notation to positional notation. This
3cf3e5c6
AC
306 -- conversion is possible only in some static cases. If the conversion is
307 -- possible, then N is rewritten with the analyzed converted aggregate.
c42006e9 308 -- The parameter Handle_Bit_Packed is usually set False (since we do
3cf3e5c6
AC
309 -- not expect the back end to handle bit packed arrays, so the normal case
310 -- of conversion is pointless), but in the special case of a call from
311 -- Packed_Array_Aggregate_Handled, we set this parameter to True, since
312 -- these are cases we handle in there.
07fc65c4 313
70482933
RK
314 procedure Expand_Array_Aggregate (N : Node_Id);
315 -- This is the top-level routine to perform array aggregate expansion.
316 -- N is the N_Aggregate node to be expanded.
317
dc3af7e2 318 function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean;
dc3af7e2
AC
319 -- For two-dimensional packed aggregates with constant bounds and constant
320 -- components, it is preferable to pack the inner aggregates because the
321 -- whole matrix can then be presented to the back-end as a one-dimensional
322 -- list of literals. This is much more efficient than expanding into single
2791be24
AC
323 -- component assignments. This function determines if the type Typ is for
324 -- an array that is suitable for this optimization: it returns True if Typ
325 -- is a two dimensional bit packed array with component size 1, 2, or 4.
dc3af7e2 326
c42006e9 327 function Max_Aggregate_Size
eaf6e63a 328 (N : Node_Id;
c42006e9 329 Default_Size : Nat := 5000) return Nat;
eaf6e63a
BD
330 -- Return the max size for a static aggregate N. Return Default_Size if no
331 -- other special criteria trigger.
c42006e9 332
07fc65c4
GB
333 function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean;
334 -- Given an array aggregate, this function handles the case of a packed
335 -- array aggregate with all constant values, where the aggregate can be
336 -- evaluated at compile time. If this is possible, then N is rewritten
337 -- to be its proper compile time value with all the components properly
50decc81
RD
338 -- assembled. The expression is analyzed and resolved and True is returned.
339 -- If this transformation is not possible, N is unchanged and False is
340 -- returned.
07fc65c4 341
5eeeed5e
AC
342 function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean;
343 -- If the type of the aggregate is a two-dimensional bit_packed array
344 -- it may be transformed into an array of bytes with constant values,
345 -- and presented to the back-end as a static value. The function returns
346 -- false if this transformation cannot be performed. THis is similar to,
347 -- and reuses part of the machinery in Packed_Array_Aggregate_Handled.
348
2fedcc18
EB
349 ------------------------------------
350 -- Aggr_Assignment_OK_For_Backend --
351 ------------------------------------
352
353 -- Back-end processing by Gigi/gcc is possible only if all the following
354 -- conditions are met:
355
356 -- 1. N consists of a single OTHERS choice, possibly recursively, or
357 -- of a single choice, possibly recursively, if it is surrounded by
358 -- a qualified expression whose subtype mark is unconstrained.
359
360 -- 2. The array type has no null ranges (the purpose of this is to
361 -- avoid a bogus warning for an out-of-range value).
362
363 -- 3. The array type has no atomic components
364
365 -- 4. The component type is elementary
366
367 -- 5. The component size is a multiple of Storage_Unit
368
369 -- 6. The component size is Storage_Unit or the value is of the form
370 -- M * (1 + A**1 + A**2 + .. A**(K-1)) where A = 2**(Storage_Unit)
371 -- and M in 0 .. A-1. This can also be viewed as K occurrences of
372 -- the Storage_Unit value M, concatenated together.
373
374 -- The ultimate goal is to generate a call to a fast memset routine
375 -- specifically optimized for the target.
376
377 function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean is
2fedcc18
EB
378
379 function Is_OK_Aggregate (Aggr : Node_Id) return Boolean;
380 -- Return true if Aggr is suitable for back-end assignment
381
382 ---------------------
383 -- Is_OK_Aggregate --
384 ---------------------
385
386 function Is_OK_Aggregate (Aggr : Node_Id) return Boolean is
387 Assoc : constant List_Id := Component_Associations (Aggr);
388
389 begin
390 -- An "others" aggregate is most likely OK, but see below
391
392 if Is_Others_Aggregate (Aggr) then
393 null;
394
395 -- An aggregate with a single choice requires a qualified expression
396 -- whose subtype mark is an unconstrained type because we need it to
397 -- have the semantics of an "others" aggregate.
398
399 elsif Nkind (Parent (N)) = N_Qualified_Expression
400 and then not Is_Constrained (Entity (Subtype_Mark (Parent (N))))
401 and then Is_Single_Aggregate (Aggr)
402 then
403 null;
404
405 -- The other cases are not OK
406
407 else
408 return False;
409 end if;
410
411 -- In any case we do not support an iterated association
412
413 return Nkind (First (Assoc)) /= N_Iterated_Component_Association;
414 end Is_OK_Aggregate;
415
7c4f3267
BD
416 Bounds : Range_Nodes;
417 Csiz : Uint := No_Uint;
418 Ctyp : Entity_Id;
419 Expr : Node_Id;
420 Index : Entity_Id;
421 Nunits : Int;
422 Remainder : Uint;
423 Value : Uint;
424
b120ca61
EB
425 -- Start of processing for Aggr_Assignment_OK_For_Backend
426
2fedcc18
EB
427 begin
428 -- Back end doesn't know about <>
429
430 if Has_Default_Init_Comps (N) then
431 return False;
432 end if;
433
434 -- Recurse as far as possible to find the innermost component type
435
436 Ctyp := Etype (N);
437 Expr := N;
438 while Is_Array_Type (Ctyp) loop
439 if Nkind (Expr) /= N_Aggregate
440 or else not Is_OK_Aggregate (Expr)
441 then
442 return False;
443 end if;
444
445 Index := First_Index (Ctyp);
446 while Present (Index) loop
7c4f3267 447 Bounds := Get_Index_Bounds (Index);
2fedcc18 448
7c4f3267 449 if Is_Null_Range (Bounds.First, Bounds.Last) then
2fedcc18
EB
450 return False;
451 end if;
452
453 Next_Index (Index);
454 end loop;
455
456 Expr := Expression (First (Component_Associations (Expr)));
457
458 for J in 1 .. Number_Dimensions (Ctyp) - 1 loop
459 if Nkind (Expr) /= N_Aggregate
460 or else not Is_OK_Aggregate (Expr)
461 then
462 return False;
463 end if;
464
465 Expr := Expression (First (Component_Associations (Expr)));
466 end loop;
467
468 if Has_Atomic_Components (Ctyp) then
469 return False;
470 end if;
471
472 Csiz := Component_Size (Ctyp);
473 Ctyp := Component_Type (Ctyp);
474
b120ca61 475 if Is_Full_Access (Ctyp) then
2fedcc18
EB
476 return False;
477 end if;
478 end loop;
479
480 -- Access types need to be dealt with specially
481
482 if Is_Access_Type (Ctyp) then
483
484 -- Component_Size is not set by Layout_Type if the component
485 -- type is an access type ???
486
487 Csiz := Esize (Ctyp);
488
489 -- Fat pointers are rejected as they are not really elementary
490 -- for the backend.
491
492 if Csiz /= System_Address_Size then
493 return False;
494 end if;
495
496 -- The supported expressions are NULL and constants, others are
497 -- rejected upfront to avoid being analyzed below, which can be
498 -- problematic for some of them, for example allocators.
499
500 if Nkind (Expr) /= N_Null and then not Is_Entity_Name (Expr) then
501 return False;
502 end if;
503
504 -- Scalar types are OK if their size is a multiple of Storage_Unit
505
506 elsif Is_Scalar_Type (Ctyp) then
2175b50b 507 pragma Assert (Present (Csiz));
2fedcc18
EB
508
509 if Csiz mod System_Storage_Unit /= 0 then
510 return False;
511 end if;
512
513 -- Composite types are rejected
514
515 else
516 return False;
517 end if;
518
519 -- If the expression has side effects (e.g. contains calls with
520 -- potential side effects) reject as well. We only preanalyze the
521 -- expression to prevent the removal of intended side effects.
522
523 Preanalyze_And_Resolve (Expr, Ctyp);
524
525 if not Side_Effect_Free (Expr) then
526 return False;
527 end if;
528
529 -- The expression needs to be analyzed if True is returned
530
531 Analyze_And_Resolve (Expr, Ctyp);
532
533 -- Strip away any conversions from the expression as they simply
534 -- qualify the real expression.
535
4a08c95c 536 while Nkind (Expr) in N_Unchecked_Type_Conversion | N_Type_Conversion
2fedcc18
EB
537 loop
538 Expr := Expression (Expr);
539 end loop;
540
541 Nunits := UI_To_Int (Csiz) / System_Storage_Unit;
542
543 if Nunits = 1 then
544 return True;
545 end if;
546
547 if not Compile_Time_Known_Value (Expr) then
548 return False;
549 end if;
550
551 -- The only supported value for floating point is 0.0
552
553 if Is_Floating_Point_Type (Ctyp) then
554 return Expr_Value_R (Expr) = Ureal_0;
555 end if;
556
557 -- For other types, we can look into the value as an integer, which
558 -- means the representation value for enumeration literals.
559
560 Value := Expr_Rep_Value (Expr);
561
562 if Has_Biased_Representation (Ctyp) then
563 Value := Value - Expr_Value (Type_Low_Bound (Ctyp));
564 end if;
565
566 -- Values 0 and -1 immediately satisfy the last check
567
568 if Value = Uint_0 or else Value = Uint_Minus_1 then
569 return True;
570 end if;
571
572 -- We need to work with an unsigned value
573
574 if Value < 0 then
575 Value := Value + 2**(System_Storage_Unit * Nunits);
576 end if;
577
578 Remainder := Value rem 2**System_Storage_Unit;
579
580 for J in 1 .. Nunits - 1 loop
581 Value := Value / 2**System_Storage_Unit;
582
583 if Value rem 2**System_Storage_Unit /= Remainder then
584 return False;
585 end if;
586 end loop;
587
588 return True;
589 end Aggr_Assignment_OK_For_Backend;
590
643a0839
ES
591 ------------------
592 -- Aggr_Size_OK --
593 ------------------
594
eaf6e63a
BD
595 function Aggr_Size_OK (N : Node_Id) return Boolean is
596 Typ : constant Entity_Id := Etype (N);
643a0839
ES
597 Lo : Node_Id;
598 Hi : Node_Id;
599 Indx : Node_Id;
4167b075 600 Size : Uint;
643a0839
ES
601 Lov : Uint;
602 Hiv : Uint;
603
303fbb20
AC
604 Max_Aggr_Size : Nat;
605 -- Determines the maximum size of an array aggregate produced by
606 -- converting named to positional notation (e.g. from others clauses).
607 -- This avoids running away with attempts to convert huge aggregates,
608 -- which hit memory limits in the backend.
643a0839 609
16e764a7 610 function Component_Count (T : Entity_Id) return Nat;
457cee0b 611 -- The limit is applied to the total number of subcomponents that the
643a0839
ES
612 -- aggregate will have, which is the number of static expressions
613 -- that will appear in the flattened array. This requires a recursive
16b05213 614 -- computation of the number of scalar components of the structure.
643a0839
ES
615
616 ---------------------
617 -- Component_Count --
618 ---------------------
619
16e764a7
AC
620 function Component_Count (T : Entity_Id) return Nat is
621 Res : Nat := 0;
643a0839
ES
622 Comp : Entity_Id;
623
624 begin
625 if Is_Scalar_Type (T) then
626 return 1;
627
628 elsif Is_Record_Type (T) then
629 Comp := First_Component (T);
630 while Present (Comp) loop
631 Res := Res + Component_Count (Etype (Comp));
632 Next_Component (Comp);
633 end loop;
634
635 return Res;
636
637 elsif Is_Array_Type (T) then
638 declare
639 Lo : constant Node_Id :=
15f0f591 640 Type_Low_Bound (Etype (First_Index (T)));
643a0839 641 Hi : constant Node_Id :=
15f0f591 642 Type_High_Bound (Etype (First_Index (T)));
643a0839 643
16e764a7 644 Siz : constant Nat := Component_Count (Component_Type (T));
643a0839
ES
645
646 begin
b4213ffd
AC
647 -- Check for superflat arrays, i.e. arrays with such bounds
648 -- as 4 .. 2, to insure that this function never returns a
649 -- meaningless negative value.
650
643a0839
ES
651 if not Compile_Time_Known_Value (Lo)
652 or else not Compile_Time_Known_Value (Hi)
b4213ffd 653 or else Expr_Value (Hi) < Expr_Value (Lo)
643a0839
ES
654 then
655 return 0;
b4213ffd 656
643a0839 657 else
457cee0b
AC
658 -- If the number of components is greater than Int'Last,
659 -- then return Int'Last, so caller will return False (Aggr
660 -- size is not OK). Otherwise, UI_To_Int will crash.
661
662 declare
663 UI : constant Uint :=
664 Expr_Value (Hi) - Expr_Value (Lo) + 1;
665 begin
666 if UI_Is_In_Int_Range (UI) then
667 return Siz * UI_To_Int (UI);
668 else
669 return Int'Last;
670 end if;
671 end;
643a0839
ES
672 end if;
673 end;
674
675 else
676 -- Can only be a null for an access type
677
678 return 1;
679 end if;
680 end Component_Count;
681
682 -- Start of processing for Aggr_Size_OK
683
684 begin
c42006e9 685 -- We bump the maximum size unless the aggregate has a single component
b9ec8463 686 -- association, which will be more efficient if implemented with a loop.
73b670e3 687 -- The -gnatd_g switch disables this bumping.
b9ec8463 688
73b670e3
BD
689 if (No (Expressions (N))
690 and then No (Next (First (Component_Associations (N)))))
691 or else Debug_Flag_Underscore_G
b9ec8463 692 then
eaf6e63a 693 Max_Aggr_Size := Max_Aggregate_Size (N);
c42006e9 694 else
eaf6e63a 695 Max_Aggr_Size := Max_Aggregate_Size (N, 500_000);
303fbb20
AC
696 end if;
697
4167b075 698 Size := UI_From_Int (Component_Count (Component_Type (Typ)));
643a0839 699
5277cab6 700 Indx := First_Index (Typ);
643a0839
ES
701 while Present (Indx) loop
702 Lo := Type_Low_Bound (Etype (Indx));
703 Hi := Type_High_Bound (Etype (Indx));
704
705 -- Bounds need to be known at compile time
706
707 if not Compile_Time_Known_Value (Lo)
708 or else not Compile_Time_Known_Value (Hi)
709 then
710 return False;
711 end if;
712
713 Lov := Expr_Value (Lo);
714 Hiv := Expr_Value (Hi);
715
716 -- A flat array is always safe
717
718 if Hiv < Lov then
719 return True;
720 end if;
721
86038a88 722 -- One-component aggregates are suspicious, and if the context type
d940c627 723 -- is an object declaration with nonstatic bounds it will trip gcc;
86038a88 724 -- such an aggregate must be expanded into a single assignment.
58fda84d 725
36a66365 726 if Hiv = Lov and then Nkind (Parent (N)) = N_Object_Declaration then
58fda84d
ES
727 declare
728 Index_Type : constant Entity_Id :=
15f0f591
AC
729 Etype
730 (First_Index (Etype (Defining_Identifier (Parent (N)))));
86038a88
RD
731 Indx : Node_Id;
732
58fda84d
ES
733 begin
734 if not Compile_Time_Known_Value (Type_Low_Bound (Index_Type))
36a66365
AC
735 or else not Compile_Time_Known_Value
736 (Type_High_Bound (Index_Type))
58fda84d
ES
737 then
738 if Present (Component_Associations (N)) then
739 Indx :=
00f45f30
AC
740 First
741 (Choice_List (First (Component_Associations (N))));
324ac540 742
58fda84d
ES
743 if Is_Entity_Name (Indx)
744 and then not Is_Type (Entity (Indx))
745 then
746 Error_Msg_N
324ac540
AC
747 ("single component aggregate in "
748 & "non-static context??", Indx);
749 Error_Msg_N ("\maybe subtype name was meant??", Indx);
58fda84d
ES
750 end if;
751 end if;
752
753 return False;
754 end if;
755 end;
756 end if;
757
643a0839
ES
758 declare
759 Rng : constant Uint := Hiv - Lov + 1;
760
761 begin
762 -- Check if size is too large
763
764 if not UI_Is_In_Int_Range (Rng) then
765 return False;
766 end if;
767
4167b075
GD
768 -- Compute the size using universal arithmetic to avoid the
769 -- possibility of overflow on very large aggregates.
643a0839 770
4167b075
GD
771 Size := Size * Rng;
772
773 if Size <= 0
774 or else Size > Max_Aggr_Size
775 then
776 return False;
777 end if;
778 end;
643a0839
ES
779
780 -- Bounds must be in integer range, for later array construction
781
782 if not UI_Is_In_Int_Range (Lov)
783 or else
784 not UI_Is_In_Int_Range (Hiv)
785 then
786 return False;
787 end if;
788
789 Next_Index (Indx);
790 end loop;
791
792 return True;
793 end Aggr_Size_OK;
794
70482933
RK
795 ---------------------------------
796 -- Backend_Processing_Possible --
797 ---------------------------------
798
799 -- Backend processing by Gigi/gcc is possible only if all the following
800 -- conditions are met:
801
802 -- 1. N is fully positional
803
804 -- 2. N is not a bit-packed array aggregate;
805
806 -- 3. The size of N's array type must be known at compile time. Note
807 -- that this implies that the component size is also known
808
809 -- 4. The array type of N does not follow the Fortran layout convention
810 -- or if it does it must be 1 dimensional.
811
0f95b178
JM
812 -- 5. The array component type may not be tagged (which could necessitate
813 -- reassignment of proper tags).
70482933 814
0f95b178
JM
815 -- 6. The array component type must not have unaligned bit components
816
817 -- 7. None of the components of the aggregate may be bit unaligned
818 -- components.
819
820 -- 8. There cannot be delayed components, since we do not know enough
821 -- at this stage to know if back end processing is possible.
822
823 -- 9. There cannot be any discriminated record components, since the
824 -- back end cannot handle this complex case.
91b1417d 825
7f4c1903 826 -- 10. No controlled actions need to be generated for components
a8f59a33 827
7e22a38c
AC
828 -- 11. When generating C code, N must be part of a N_Object_Declaration
829
2d6aa715
AC
830 -- 12. When generating C code, N must not include function calls
831
70482933
RK
832 function Backend_Processing_Possible (N : Node_Id) return Boolean is
833 Typ : constant Entity_Id := Etype (N);
3cf3e5c6 834 -- Typ is the correct constrained array subtype of the aggregate
70482933 835
0f95b178
JM
836 function Component_Check (N : Node_Id; Index : Node_Id) return Boolean;
837 -- This routine checks components of aggregate N, enforcing checks
d74716b3 838 -- 1, 7, 8, 9, 11, and 12. In the multidimensional case, these checks
2d6aa715 839 -- are performed on subaggregates. The Index value is the current index
d74716b3 840 -- being checked in the multidimensional case.
70482933 841
0f95b178
JM
842 ---------------------
843 -- Component_Check --
844 ---------------------
70482933 845
0f95b178 846 function Component_Check (N : Node_Id; Index : Node_Id) return Boolean is
35f4f238
JM
847 function Ultimate_Original_Expression (N : Node_Id) return Node_Id;
848 -- Given a type conversion or an unchecked type conversion N, return
849 -- its innermost original expression.
850
851 ----------------------------------
852 -- Ultimate_Original_Expression --
853 ----------------------------------
854
855 function Ultimate_Original_Expression (N : Node_Id) return Node_Id is
856 Expr : Node_Id := Original_Node (N);
857
858 begin
4a08c95c
AC
859 while Nkind (Expr) in
860 N_Type_Conversion | N_Unchecked_Type_Conversion
35f4f238
JM
861 loop
862 Expr := Original_Node (Expression (Expr));
863 end loop;
864
865 return Expr;
866 end Ultimate_Original_Expression;
867
868 -- Local variables
869
70482933
RK
870 Expr : Node_Id;
871
bbe008b6
HK
872 -- Start of processing for Component_Check
873
70482933 874 begin
0f95b178 875 -- Checks 1: (no component associations)
70482933
RK
876
877 if Present (Component_Associations (N)) then
878 return False;
879 end if;
880
7ec25b2b
AC
881 -- Checks 11: The C code generator cannot handle aggregates that are
882 -- not part of an object declaration.
7e22a38c 883
4ff5aa0c
AC
884 if Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
885 return False;
7e22a38c
AC
886 end if;
887
0f95b178
JM
888 -- Checks on components
889
70482933
RK
890 -- Recurse to check subaggregates, which may appear in qualified
891 -- expressions. If delayed, the front-end will have to expand.
d940c627 892 -- If the component is a discriminated record, treat as nonstatic,
5277cab6 893 -- as the back-end cannot handle this properly.
70482933
RK
894
895 Expr := First (Expressions (N));
70482933 896 while Present (Expr) loop
0f95b178
JM
897
898 -- Checks 8: (no delayed components)
899
70482933
RK
900 if Is_Delayed_Aggregate (Expr) then
901 return False;
902 end if;
903
0f95b178
JM
904 -- Checks 9: (no discriminated records)
905
5277cab6
ES
906 if Present (Etype (Expr))
907 and then Is_Record_Type (Etype (Expr))
908 and then Has_Discriminants (Etype (Expr))
909 then
910 return False;
911 end if;
912
0f95b178
JM
913 -- Checks 7. Component must not be bit aligned component
914
915 if Possible_Bit_Aligned_Component (Expr) then
916 return False;
917 end if;
918
2d6aa715
AC
919 -- Checks 12: (no function call)
920
35f4f238
JM
921 if Modify_Tree_For_C
922 and then
923 Nkind (Ultimate_Original_Expression (Expr)) = N_Function_Call
924 then
2d6aa715
AC
925 return False;
926 end if;
927
0f95b178
JM
928 -- Recursion to following indexes for multiple dimension case
929
70482933 930 if Present (Next_Index (Index))
36a66365 931 and then not Component_Check (Expr, Next_Index (Index))
70482933
RK
932 then
933 return False;
934 end if;
935
0f95b178
JM
936 -- All checks for that component finished, on to next
937
70482933
RK
938 Next (Expr);
939 end loop;
940
941 return True;
0f95b178 942 end Component_Check;
70482933
RK
943
944 -- Start of processing for Backend_Processing_Possible
945
946 begin
a8f59a33 947 -- Checks 2 (array not bit packed) and 10 (no controlled actions)
70482933 948
a8f59a33 949 if Is_Bit_Packed_Array (Typ) or else Needs_Finalization (Typ) then
70482933
RK
950 return False;
951 end if;
952
a38ff9b1
ES
953 -- If component is limited, aggregate must be expanded because each
954 -- component assignment must be built in place.
955
51245e2d 956 if Is_Limited_View (Component_Type (Typ)) then
a38ff9b1
ES
957 return False;
958 end if;
959
d74716b3 960 -- Checks 4 (array must not be multidimensional Fortran case)
70482933
RK
961
962 if Convention (Typ) = Convention_Fortran
963 and then Number_Dimensions (Typ) > 1
964 then
965 return False;
966 end if;
967
968 -- Checks 3 (size of array must be known at compile time)
969
970 if not Size_Known_At_Compile_Time (Typ) then
971 return False;
972 end if;
973
0f95b178 974 -- Checks on components
70482933 975
0f95b178 976 if not Component_Check (N, First_Index (Typ)) then
70482933
RK
977 return False;
978 end if;
979
0f95b178 980 -- Checks 5 (if the component type is tagged, then we may need to do
36a66365
AC
981 -- tag adjustments. Perhaps this should be refined to check for any
982 -- component associations that actually need tag adjustment, similar
d4dfb005
BD
983 -- to the test in Component_OK_For_Backend for record aggregates with
984 -- tagged components, but not clear whether it's worthwhile ???; in the
985 -- case of virtual machines (no Tagged_Type_Expansion), object tags are
986 -- handled implicitly).
70482933 987
1f110335
AC
988 if Is_Tagged_Type (Component_Type (Typ))
989 and then Tagged_Type_Expansion
990 then
70482933
RK
991 return False;
992 end if;
993
91b1417d
AC
994 -- Checks 6 (component type must not have bit aligned components)
995
996 if Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)) then
997 return False;
998 end if;
999
70482933
RK
1000 -- Backend processing is possible
1001
70482933
RK
1002 return True;
1003 end Backend_Processing_Possible;
1004
1005 ---------------------------
1006 -- Build_Array_Aggr_Code --
1007 ---------------------------
1008
1009 -- The code that we generate from a one dimensional aggregate is
1010
d74716b3 1011 -- 1. If the subaggregate contains discrete choices we
70482933
RK
1012
1013 -- (a) Sort the discrete choices
1014
1015 -- (b) Otherwise for each discrete choice that specifies a range we
1016 -- emit a loop. If a range specifies a maximum of three values, or
1017 -- we are dealing with an expression we emit a sequence of
1018 -- assignments instead of a loop.
1019
3cf3e5c6 1020 -- (c) Generate the remaining loops to cover the others choice if any
70482933
RK
1021
1022 -- 2. If the aggregate contains positional elements we
1023
3cf3e5c6 1024 -- (a) translate the positional elements in a series of assignments
70482933
RK
1025
1026 -- (b) Generate a final loop to cover the others choice if any.
1027 -- Note that this final loop has to be a while loop since the case
1028
1029 -- L : Integer := Integer'Last;
1030 -- H : Integer := Integer'Last;
1031 -- A : array (L .. H) := (1, others =>0);
1032
1033 -- cannot be handled by a for loop. Thus for the following
1034
1035 -- array (L .. H) := (.. positional elements.., others =>E);
1036
1037 -- we always generate something like:
1038
07fc65c4
GB
1039 -- J : Index_Type := Index_Of_Last_Positional_Element;
1040 -- while J < H loop
1041 -- J := Index_Base'Succ (J)
1042 -- Tmp (J) := E;
70482933
RK
1043 -- end loop;
1044
1045 function Build_Array_Aggr_Code
1046 (N : Node_Id;
c45b6ae0 1047 Ctype : Entity_Id;
70482933
RK
1048 Index : Node_Id;
1049 Into : Node_Id;
1050 Scalar_Comp : Boolean;
df3e68b1 1051 Indexes : List_Id := No_List) return List_Id
70482933
RK
1052 is
1053 Loc : constant Source_Ptr := Sloc (N);
1054 Index_Base : constant Entity_Id := Base_Type (Etype (Index));
1055 Index_Base_L : constant Node_Id := Type_Low_Bound (Index_Base);
1056 Index_Base_H : constant Node_Id := Type_High_Bound (Index_Base);
1057
1058 function Add (Val : Int; To : Node_Id) return Node_Id;
3cf3e5c6
AC
1059 -- Returns an expression where Val is added to expression To, unless
1060 -- To+Val is provably out of To's base type range. To must be an
1061 -- already analyzed expression.
70482933
RK
1062
1063 function Empty_Range (L, H : Node_Id) return Boolean;
3cf3e5c6 1064 -- Returns True if the range defined by L .. H is certainly empty
70482933
RK
1065
1066 function Equal (L, H : Node_Id) return Boolean;
3cf3e5c6 1067 -- Returns True if L = H for sure
70482933
RK
1068
1069 function Index_Base_Name return Node_Id;
3cf3e5c6 1070 -- Returns a new reference to the index type name
70482933 1071
937e9676
AC
1072 function Gen_Assign
1073 (Ind : Node_Id;
1074 Expr : Node_Id;
1075 In_Loop : Boolean := False) return List_Id;
d74716b3
AC
1076 -- Ind must be a side-effect-free expression. If the input aggregate N
1077 -- to Build_Loop contains no subaggregates, then this function returns
1078 -- the assignment statement:
70482933 1079 --
deeb1604 1080 -- Into (Indexes, Ind) := Expr;
70482933 1081 --
937e9676
AC
1082 -- Otherwise we call Build_Code recursively. Flag In_Loop should be set
1083 -- when the assignment appears within a generated loop.
c45b6ae0 1084 --
0ab80019
AC
1085 -- Ada 2005 (AI-287): In case of default initialized component, Expr
1086 -- is empty and we generate a call to the corresponding IP subprogram.
70482933
RK
1087
1088 function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
d74716b3
AC
1089 -- Nodes L and H must be side-effect-free expressions. If the input
1090 -- aggregate N to Build_Loop contains no subaggregates, this routine
1091 -- returns the for loop statement:
70482933
RK
1092 --
1093 -- for J in Index_Base'(L) .. Index_Base'(H) loop
deeb1604 1094 -- Into (Indexes, J) := Expr;
70482933
RK
1095 -- end loop;
1096 --
937e9676
AC
1097 -- Otherwise we call Build_Code recursively. As an optimization if the
1098 -- loop covers 3 or fewer scalar elements we generate a sequence of
1099 -- assignments.
00f45f30
AC
1100 -- If the component association that generates the loop comes from an
1101 -- Iterated_Component_Association, the loop parameter has the name of
1102 -- the corresponding parameter in the original construct.
70482933
RK
1103
1104 function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id;
d74716b3
AC
1105 -- Nodes L and H must be side-effect-free expressions. If the input
1106 -- aggregate N to Build_Loop contains no subaggregates, this routine
1107 -- returns the while loop statement:
70482933 1108 --
07fc65c4
GB
1109 -- J : Index_Base := L;
1110 -- while J < H loop
1111 -- J := Index_Base'Succ (J);
deeb1604 1112 -- Into (Indexes, J) := Expr;
70482933
RK
1113 -- end loop;
1114 --
fbf5a39b 1115 -- Otherwise we call Build_Code recursively
70482933 1116
59e9bc0b 1117 function Get_Assoc_Expr (Assoc : Node_Id) return Node_Id;
e9999161
AC
1118 -- For an association with a box, use value given by aspect
1119 -- Default_Component_Value of array type if specified, else use
1120 -- value given by aspect Default_Value for component type itself
1121 -- if specified, else return Empty.
59e9bc0b 1122
70482933
RK
1123 function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean;
1124 function Local_Expr_Value (E : Node_Id) return Uint;
1125 -- These two Local routines are used to replace the corresponding ones
1126 -- in sem_eval because while processing the bounds of an aggregate with
1127 -- discrete choices whose index type is an enumeration, we build static
1128 -- expressions not recognized by Compile_Time_Known_Value as such since
1129 -- they have not yet been analyzed and resolved. All the expressions in
1130 -- question are things like Index_Base_Name'Val (Const) which we can
1131 -- easily recognize as being constant.
1132
1133 ---------
1134 -- Add --
1135 ---------
1136
1137 function Add (Val : Int; To : Node_Id) return Node_Id is
1138 Expr_Pos : Node_Id;
1139 Expr : Node_Id;
1140 To_Pos : Node_Id;
fbf5a39b
AC
1141 U_To : Uint;
1142 U_Val : constant Uint := UI_From_Int (Val);
70482933
RK
1143
1144 begin
1145 -- Note: do not try to optimize the case of Val = 0, because
1146 -- we need to build a new node with the proper Sloc value anyway.
1147
1148 -- First test if we can do constant folding
1149
1150 if Local_Compile_Time_Known_Value (To) then
1151 U_To := Local_Expr_Value (To) + Val;
1152
1153 -- Determine if our constant is outside the range of the index.
1154 -- If so return an Empty node. This empty node will be caught
1155 -- by Empty_Range below.
1156
1157 if Compile_Time_Known_Value (Index_Base_L)
1158 and then U_To < Expr_Value (Index_Base_L)
1159 then
1160 return Empty;
1161
1162 elsif Compile_Time_Known_Value (Index_Base_H)
1163 and then U_To > Expr_Value (Index_Base_H)
1164 then
1165 return Empty;
1166 end if;
1167
1168 Expr_Pos := Make_Integer_Literal (Loc, U_To);
1169 Set_Is_Static_Expression (Expr_Pos);
1170
1171 if not Is_Enumeration_Type (Index_Base) then
1172 Expr := Expr_Pos;
1173
1174 -- If we are dealing with enumeration return
1175 -- Index_Base'Val (Expr_Pos)
1176
1177 else
1178 Expr :=
1179 Make_Attribute_Reference
1180 (Loc,
1181 Prefix => Index_Base_Name,
1182 Attribute_Name => Name_Val,
1183 Expressions => New_List (Expr_Pos));
1184 end if;
1185
1186 return Expr;
1187 end if;
1188
1189 -- If we are here no constant folding possible
1190
1191 if not Is_Enumeration_Type (Index_Base) then
1192 Expr :=
1193 Make_Op_Add (Loc,
47c14114
AC
1194 Left_Opnd => Duplicate_Subexpr (To),
1195 Right_Opnd => Make_Integer_Literal (Loc, U_Val));
70482933
RK
1196
1197 -- If we are dealing with enumeration return
1198 -- Index_Base'Val (Index_Base'Pos (To) + Val)
1199
1200 else
1201 To_Pos :=
1202 Make_Attribute_Reference
1203 (Loc,
1204 Prefix => Index_Base_Name,
1205 Attribute_Name => Name_Pos,
1206 Expressions => New_List (Duplicate_Subexpr (To)));
1207
1208 Expr_Pos :=
1209 Make_Op_Add (Loc,
47c14114
AC
1210 Left_Opnd => To_Pos,
1211 Right_Opnd => Make_Integer_Literal (Loc, U_Val));
70482933
RK
1212
1213 Expr :=
1214 Make_Attribute_Reference
1215 (Loc,
1216 Prefix => Index_Base_Name,
1217 Attribute_Name => Name_Val,
1218 Expressions => New_List (Expr_Pos));
1219 end if;
1220
1221 return Expr;
1222 end Add;
1223
1224 -----------------
1225 -- Empty_Range --
1226 -----------------
1227
1228 function Empty_Range (L, H : Node_Id) return Boolean is
1229 Is_Empty : Boolean := False;
1230 Low : Node_Id;
1231 High : Node_Id;
1232
1233 begin
1234 -- First check if L or H were already detected as overflowing the
1235 -- index base range type by function Add above. If this is so Add
1236 -- returns the empty node.
1237
1238 if No (L) or else No (H) then
1239 return True;
1240 end if;
1241
1242 for J in 1 .. 3 loop
1243 case J is
1244
1245 -- L > H range is empty
1246
1247 when 1 =>
1248 Low := L;
1249 High := H;
1250
1251 -- B_L > H range must be empty
1252
1253 when 2 =>
1254 Low := Index_Base_L;
1255 High := H;
1256
1257 -- L > B_H range must be empty
1258
1259 when 3 =>
1260 Low := L;
1261 High := Index_Base_H;
1262 end case;
1263
1264 if Local_Compile_Time_Known_Value (Low)
36a66365
AC
1265 and then
1266 Local_Compile_Time_Known_Value (High)
70482933
RK
1267 then
1268 Is_Empty :=
1269 UI_Gt (Local_Expr_Value (Low), Local_Expr_Value (High));
1270 end if;
1271
1272 exit when Is_Empty;
1273 end loop;
1274
1275 return Is_Empty;
1276 end Empty_Range;
1277
1278 -----------
1279 -- Equal --
1280 -----------
1281
1282 function Equal (L, H : Node_Id) return Boolean is
1283 begin
1284 if L = H then
1285 return True;
1286
1287 elsif Local_Compile_Time_Known_Value (L)
36a66365
AC
1288 and then
1289 Local_Compile_Time_Known_Value (H)
70482933
RK
1290 then
1291 return UI_Eq (Local_Expr_Value (L), Local_Expr_Value (H));
1292 end if;
1293
1294 return False;
1295 end Equal;
1296
1297 ----------------
1298 -- Gen_Assign --
1299 ----------------
1300
937e9676
AC
1301 function Gen_Assign
1302 (Ind : Node_Id;
1303 Expr : Node_Id;
1304 In_Loop : Boolean := False) return List_Id
1305 is
70482933 1306 function Add_Loop_Actions (Lis : List_Id) return List_Id;
937e9676
AC
1307 -- Collect insert_actions generated in the construction of a loop,
1308 -- and prepend them to the sequence of assignments to complete the
1309 -- eventual body of the loop.
1310
1311 procedure Initialize_Array_Component
1312 (Arr_Comp : Node_Id;
1313 Comp_Typ : Node_Id;
1314 Init_Expr : Node_Id;
1315 Stmts : List_Id);
1316 -- Perform the initialization of array component Arr_Comp with
1317 -- expected type Comp_Typ. Init_Expr denotes the initialization
1318 -- expression of the array component. All generated code is added
1319 -- to list Stmts.
1320
1321 procedure Initialize_Ctrl_Array_Component
1322 (Arr_Comp : Node_Id;
1323 Comp_Typ : Entity_Id;
1324 Init_Expr : Node_Id;
1325 Stmts : List_Id);
1326 -- Perform the initialization of array component Arr_Comp when its
1327 -- expected type Comp_Typ needs finalization actions. Init_Expr is
1328 -- the initialization expression of the array component. All hook-
1329 -- related declarations are inserted prior to aggregate N. Remaining
1330 -- code is added to list Stmts.
10edebe7 1331
70482933
RK
1332 ----------------------
1333 -- Add_Loop_Actions --
1334 ----------------------
1335
1336 function Add_Loop_Actions (Lis : List_Id) return List_Id is
1337 Res : List_Id;
1338
1339 begin
0ab80019 1340 -- Ada 2005 (AI-287): Do nothing else in case of default
6e937c1c 1341 -- initialized component.
c45b6ae0 1342
d8f7b976 1343 if No (Expr) then
c45b6ae0
AC
1344 return Lis;
1345
1346 elsif Nkind (Parent (Expr)) = N_Component_Association
70482933
RK
1347 and then Present (Loop_Actions (Parent (Expr)))
1348 then
1349 Append_List (Lis, Loop_Actions (Parent (Expr)));
1350 Res := Loop_Actions (Parent (Expr));
1351 Set_Loop_Actions (Parent (Expr), No_List);
1352 return Res;
1353
1354 else
1355 return Lis;
1356 end if;
1357 end Add_Loop_Actions;
1358
937e9676
AC
1359 --------------------------------
1360 -- Initialize_Array_Component --
1361 --------------------------------
10edebe7 1362
937e9676
AC
1363 procedure Initialize_Array_Component
1364 (Arr_Comp : Node_Id;
1365 Comp_Typ : Node_Id;
10edebe7 1366 Init_Expr : Node_Id;
937e9676
AC
1367 Stmts : List_Id)
1368 is
bb072d1c
AC
1369 Exceptions_OK : constant Boolean :=
1370 not Restriction_Active
1371 (No_Exception_Propagation);
1372
1373 Finalization_OK : constant Boolean :=
1374 Present (Comp_Typ)
1375 and then Needs_Finalization (Comp_Typ);
1376
937e9676 1377 Full_Typ : constant Entity_Id := Underlying_Type (Comp_Typ);
2168d7cc 1378 Adj_Call : Node_Id;
bb072d1c 1379 Blk_Stmts : List_Id;
937e9676 1380 Init_Stmt : Node_Id;
10edebe7
AC
1381
1382 begin
bb072d1c
AC
1383 -- Protect the initialization statements from aborts. Generate:
1384
1385 -- Abort_Defer;
1386
1387 if Finalization_OK and Abort_Allowed then
1388 if Exceptions_OK then
1389 Blk_Stmts := New_List;
1390 else
1391 Blk_Stmts := Stmts;
1392 end if;
1393
1394 Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
1395
1396 -- Otherwise aborts are not allowed. All generated code is added
1397 -- directly to the input list.
1398
1399 else
1400 Blk_Stmts := Stmts;
1401 end if;
1402
937e9676 1403 -- Initialize the array element. Generate:
10edebe7 1404
937e9676 1405 -- Arr_Comp := Init_Expr;
10edebe7 1406
937e9676
AC
1407 -- Note that the initialization expression is replicated because
1408 -- it has to be reevaluated within a generated loop.
10edebe7 1409
937e9676
AC
1410 Init_Stmt :=
1411 Make_OK_Assignment_Statement (Loc,
1412 Name => New_Copy_Tree (Arr_Comp),
1413 Expression => New_Copy_Tree (Init_Expr));
1414 Set_No_Ctrl_Actions (Init_Stmt);
10edebe7 1415
937e9676
AC
1416 -- If this is an aggregate for an array of arrays, each
1417 -- subaggregate will be expanded as well, and even with
1418 -- No_Ctrl_Actions the assignments of inner components will
1419 -- require attachment in their assignments to temporaries. These
1420 -- temporaries must be finalized for each subaggregate. Generate:
10edebe7 1421
937e9676
AC
1422 -- begin
1423 -- Arr_Comp := Init_Expr;
1424 -- end;
10edebe7 1425
bb072d1c 1426 if Finalization_OK and then Is_Array_Type (Comp_Typ) then
937e9676
AC
1427 Init_Stmt :=
1428 Make_Block_Statement (Loc,
1429 Handled_Statement_Sequence =>
1430 Make_Handled_Sequence_Of_Statements (Loc,
1431 Statements => New_List (Init_Stmt)));
1432 end if;
10edebe7 1433
bb072d1c 1434 Append_To (Blk_Stmts, Init_Stmt);
10edebe7 1435
937e9676 1436 -- Adjust the tag due to a possible view conversion. Generate:
10edebe7 1437
937e9676
AC
1438 -- Arr_Comp._tag := Full_TypP;
1439
1440 if Tagged_Type_Expansion
1441 and then Present (Comp_Typ)
1442 and then Is_Tagged_Type (Comp_Typ)
1443 then
bb072d1c 1444 Append_To (Blk_Stmts,
937e9676
AC
1445 Make_OK_Assignment_Statement (Loc,
1446 Name =>
1447 Make_Selected_Component (Loc,
1448 Prefix => New_Copy_Tree (Arr_Comp),
1449 Selector_Name =>
1450 New_Occurrence_Of
1451 (First_Tag_Component (Full_Typ), Loc)),
1452
1453 Expression =>
1454 Unchecked_Convert_To (RTE (RE_Tag),
1455 New_Occurrence_Of
1456 (Node (First_Elmt (Access_Disp_Table (Full_Typ))),
1457 Loc))));
1458 end if;
10edebe7 1459
937e9676
AC
1460 -- Adjust the array component. Controlled subaggregates are not
1461 -- considered because each of their individual elements will
1462 -- receive an adjustment of its own. Generate:
10edebe7 1463
937e9676 1464 -- [Deep_]Adjust (Arr_Comp);
10edebe7 1465
bb072d1c 1466 if Finalization_OK
937e9676 1467 and then not Is_Limited_Type (Comp_Typ)
e201023c 1468 and then not Is_Build_In_Place_Function_Call (Init_Expr)
937e9676
AC
1469 and then not
1470 (Is_Array_Type (Comp_Typ)
1471 and then Is_Controlled (Component_Type (Comp_Typ))
1472 and then Nkind (Expr) = N_Aggregate)
1473 then
2168d7cc 1474 Adj_Call :=
937e9676
AC
1475 Make_Adjust_Call
1476 (Obj_Ref => New_Copy_Tree (Arr_Comp),
2168d7cc
AC
1477 Typ => Comp_Typ);
1478
1479 -- Guard against a missing [Deep_]Adjust when the component
1480 -- type was not frozen properly.
1481
1482 if Present (Adj_Call) then
1483 Append_To (Blk_Stmts, Adj_Call);
1484 end if;
937e9676 1485 end if;
bb072d1c
AC
1486
1487 -- Complete the protection of the initialization statements
1488
1489 if Finalization_OK and Abort_Allowed then
1490
1491 -- Wrap the initialization statements in a block to catch a
1492 -- potential exception. Generate:
1493
1494 -- begin
1495 -- Abort_Defer;
1496 -- Arr_Comp := Init_Expr;
1497 -- Arr_Comp._tag := Full_TypP;
1498 -- [Deep_]Adjust (Arr_Comp);
1499 -- at end
1500 -- Abort_Undefer_Direct;
1501 -- end;
1502
1503 if Exceptions_OK then
1504 Append_To (Stmts,
1505 Build_Abort_Undefer_Block (Loc,
1506 Stmts => Blk_Stmts,
1507 Context => N));
1508
1509 -- Otherwise exceptions are not propagated. Generate:
1510
1511 -- Abort_Defer;
1512 -- Arr_Comp := Init_Expr;
1513 -- Arr_Comp._tag := Full_TypP;
1514 -- [Deep_]Adjust (Arr_Comp);
1515 -- Abort_Undefer;
1516
1517 else
1518 Append_To (Blk_Stmts,
1519 Build_Runtime_Call (Loc, RE_Abort_Undefer));
1520 end if;
1521 end if;
937e9676 1522 end Initialize_Array_Component;
10edebe7 1523
937e9676
AC
1524 -------------------------------------
1525 -- Initialize_Ctrl_Array_Component --
1526 -------------------------------------
10edebe7 1527
937e9676
AC
1528 procedure Initialize_Ctrl_Array_Component
1529 (Arr_Comp : Node_Id;
1530 Comp_Typ : Entity_Id;
1531 Init_Expr : Node_Id;
1532 Stmts : List_Id)
1533 is
1534 Act_Aggr : Node_Id;
1535 Act_Stmts : List_Id;
d89ce432 1536 Expr : Node_Id;
937e9676
AC
1537 Fin_Call : Node_Id;
1538 Hook_Clear : Node_Id;
10edebe7 1539
937e9676
AC
1540 In_Place_Expansion : Boolean;
1541 -- Flag set when a nonlimited controlled function call requires
1542 -- in-place expansion.
10edebe7 1543
937e9676 1544 begin
d89ce432
AC
1545 -- Duplicate the initialization expression in case the context is
1546 -- a multi choice list or an "others" choice which plugs various
1547 -- holes in the aggregate. As a result the expression is no longer
1548 -- shared between the various components and is reevaluated for
1549 -- each such component.
1550
1551 Expr := New_Copy_Tree (Init_Expr);
1552 Set_Parent (Expr, Parent (Init_Expr));
1553
937e9676
AC
1554 -- Perform a preliminary analysis and resolution to determine what
1555 -- the initialization expression denotes. An unanalyzed function
1556 -- call may appear as an identifier or an indexed component.
1557
4a08c95c
AC
1558 if Nkind (Expr) in N_Function_Call
1559 | N_Identifier
1560 | N_Indexed_Component
d89ce432 1561 and then not Analyzed (Expr)
937e9676 1562 then
d89ce432 1563 Preanalyze_And_Resolve (Expr, Comp_Typ);
937e9676
AC
1564 end if;
1565
1566 In_Place_Expansion :=
d89ce432 1567 Nkind (Expr) = N_Function_Call
d4dfb005 1568 and then not Is_Build_In_Place_Result_Type (Comp_Typ);
937e9676
AC
1569
1570 -- The initialization expression is a controlled function call.
1571 -- Perform in-place removal of side effects to avoid creating a
1572 -- transient scope, which leads to premature finalization.
1573
1574 -- This in-place expansion is not performed for limited transient
bc1146e5 1575 -- objects, because the initialization is already done in place.
937e9676
AC
1576
1577 if In_Place_Expansion then
1578
bc1146e5 1579 -- Suppress the removal of side effects by general analysis,
937e9676
AC
1580 -- because this behavior is emulated here. This avoids the
1581 -- generation of a transient scope, which leads to out-of-order
1582 -- adjustment and finalization.
1583
d89ce432 1584 Set_No_Side_Effect_Removal (Expr);
937e9676
AC
1585
1586 -- When the transient component initialization is related to a
1587 -- range or an "others", keep all generated statements within
1588 -- the enclosing loop. This way the controlled function call
1589 -- will be evaluated at each iteration, and its result will be
1590 -- finalized at the end of each iteration.
1591
1592 if In_Loop then
1593 Act_Aggr := Empty;
1594 Act_Stmts := Stmts;
1595
1596 -- Otherwise this is a single component initialization. Hook-
1597 -- related statements are inserted prior to the aggregate.
1598
1599 else
1600 Act_Aggr := N;
1601 Act_Stmts := No_List;
1602 end if;
1603
1604 -- Install all hook-related declarations and prepare the clean
1605 -- up statements.
1606
1607 Process_Transient_Component
1608 (Loc => Loc,
1609 Comp_Typ => Comp_Typ,
d89ce432 1610 Init_Expr => Expr,
937e9676
AC
1611 Fin_Call => Fin_Call,
1612 Hook_Clear => Hook_Clear,
1613 Aggr => Act_Aggr,
1614 Stmts => Act_Stmts);
10edebe7 1615 end if;
937e9676
AC
1616
1617 -- Use the noncontrolled component initialization circuitry to
1618 -- assign the result of the function call to the array element.
1619 -- This also performs subaggregate wrapping, tag adjustment, and
1620 -- [deep] adjustment of the array element.
1621
1622 Initialize_Array_Component
1623 (Arr_Comp => Arr_Comp,
1624 Comp_Typ => Comp_Typ,
d89ce432 1625 Init_Expr => Expr,
937e9676
AC
1626 Stmts => Stmts);
1627
1628 -- At this point the array element is fully initialized. Complete
1629 -- the processing of the controlled array component by finalizing
1630 -- the transient function result.
1631
1632 if In_Place_Expansion then
1633 Process_Transient_Component_Completion
1634 (Loc => Loc,
1635 Aggr => N,
1636 Fin_Call => Fin_Call,
1637 Hook_Clear => Hook_Clear,
1638 Stmts => Stmts);
1639 end if;
1640 end Initialize_Ctrl_Array_Component;
10edebe7
AC
1641
1642 -- Local variables
1643
1644 Stmts : constant List_Id := New_List;
1645
1646 Comp_Typ : Entity_Id := Empty;
1647 Expr_Q : Node_Id;
1648 Indexed_Comp : Node_Id;
2168d7cc 1649 Init_Call : Node_Id;
10edebe7 1650 New_Indexes : List_Id;
10edebe7 1651
70482933
RK
1652 -- Start of processing for Gen_Assign
1653
1654 begin
deeb1604
AC
1655 if No (Indexes) then
1656 New_Indexes := New_List;
70482933 1657 else
deeb1604 1658 New_Indexes := New_Copy_List_Tree (Indexes);
70482933
RK
1659 end if;
1660
deeb1604 1661 Append_To (New_Indexes, Ind);
70482933 1662
70482933
RK
1663 if Present (Next_Index (Index)) then
1664 return
1665 Add_Loop_Actions (
1666 Build_Array_Aggr_Code
c45b6ae0
AC
1667 (N => Expr,
1668 Ctype => Ctype,
1669 Index => Next_Index (Index),
1670 Into => Into,
1671 Scalar_Comp => Scalar_Comp,
df3e68b1 1672 Indexes => New_Indexes));
70482933
RK
1673 end if;
1674
1675 -- If we get here then we are at a bottom-level (sub-)aggregate
1676
fbf5a39b
AC
1677 Indexed_Comp :=
1678 Checks_Off
1679 (Make_Indexed_Component (Loc,
1680 Prefix => New_Copy_Tree (Into),
deeb1604 1681 Expressions => New_Indexes));
70482933
RK
1682
1683 Set_Assignment_OK (Indexed_Comp);
1684
0ab80019 1685 -- Ada 2005 (AI-287): In case of default initialized component, Expr
6e937c1c 1686 -- is not present (and therefore we also initialize Expr_Q to empty).
c45b6ae0 1687
d8f7b976 1688 if No (Expr) then
c45b6ae0
AC
1689 Expr_Q := Empty;
1690 elsif Nkind (Expr) = N_Qualified_Expression then
70482933
RK
1691 Expr_Q := Expression (Expr);
1692 else
1693 Expr_Q := Expr;
1694 end if;
1695
36a66365 1696 if Present (Etype (N)) and then Etype (N) /= Any_Composite then
10edebe7
AC
1697 Comp_Typ := Component_Type (Etype (N));
1698 pragma Assert (Comp_Typ = Ctype); -- AI-287
70482933 1699
deeb1604 1700 elsif Present (Next (First (New_Indexes))) then
70482933 1701
0ab80019 1702 -- Ada 2005 (AI-287): Do nothing in case of default initialized
c45b6ae0
AC
1703 -- component because we have received the component type in
1704 -- the formal parameter Ctype.
6e937c1c
AC
1705
1706 -- ??? Some assert pragmas have been added to check if this new
36a66365 1707 -- formal can be used to replace this code in all cases.
70482933 1708
c45b6ae0 1709 if Present (Expr) then
70482933 1710
36a66365
AC
1711 -- This is a multidimensional array. Recover the component type
1712 -- from the outermost aggregate, because subaggregates do not
1713 -- have an assigned type.
70482933 1714
c45b6ae0 1715 declare
5277cab6 1716 P : Node_Id;
70482933 1717
c45b6ae0 1718 begin
5277cab6 1719 P := Parent (Expr);
c45b6ae0 1720 while Present (P) loop
c45b6ae0
AC
1721 if Nkind (P) = N_Aggregate
1722 and then Present (Etype (P))
1723 then
10edebe7 1724 Comp_Typ := Component_Type (Etype (P));
c45b6ae0
AC
1725 exit;
1726
1727 else
1728 P := Parent (P);
1729 end if;
1730 end loop;
6e937c1c 1731
10edebe7 1732 pragma Assert (Comp_Typ = Ctype); -- AI-287
c45b6ae0
AC
1733 end;
1734 end if;
70482933
RK
1735 end if;
1736
0ab80019 1737 -- Ada 2005 (AI-287): We only analyze the expression in case of non-
6e937c1c 1738 -- default initialized components (otherwise Expr_Q is not present).
c45b6ae0
AC
1739
1740 if Present (Expr_Q)
4a08c95c 1741 and then Nkind (Expr_Q) in N_Aggregate | N_Extension_Aggregate
70482933 1742 then
d7f94401
AC
1743 -- At this stage the Expression may not have been analyzed yet
1744 -- because the array aggregate code has not been updated to use
1745 -- the Expansion_Delayed flag and avoid analysis altogether to
1746 -- solve the same problem (see Resolve_Aggr_Expr). So let us do
1747 -- the analysis of non-array aggregates now in order to get the
1748 -- value of Expansion_Delayed flag for the inner aggregate ???
70482933 1749
6cbd45e4
PMR
1750 -- In the case of an iterated component association, the analysis
1751 -- of the generated loop will analyze the expression in the
1752 -- proper context, in which the loop parameter is visible.
1753
d940c627 1754 if Present (Comp_Typ) and then not Is_Array_Type (Comp_Typ) then
10fdda1c
HK
1755 if Nkind (Parent (Expr_Q)) = N_Iterated_Component_Association
1756 or else Nkind (Parent (Parent ((Expr_Q)))) =
1757 N_Iterated_Component_Association
d940c627
ES
1758 then
1759 null;
1760 else
1761 Analyze_And_Resolve (Expr_Q, Comp_Typ);
1762 end if;
70482933
RK
1763 end if;
1764
1765 if Is_Delayed_Aggregate (Expr_Q) then
3cf3e5c6 1766
308e6f3a 1767 -- This is either a subaggregate of a multidimensional array,
3cf3e5c6
AC
1768 -- or a component of an array type whose component type is
1769 -- also an array. In the latter case, the expression may have
1770 -- component associations that provide different bounds from
1771 -- those of the component type, and sliding must occur. Instead
1772 -- of decomposing the current aggregate assignment, force the
937e9676 1773 -- reanalysis of the assignment, so that a temporary will be
3cf3e5c6
AC
1774 -- generated in the usual fashion, and sliding will take place.
1775
1776 if Nkind (Parent (N)) = N_Assignment_Statement
10edebe7 1777 and then Is_Array_Type (Comp_Typ)
3cf3e5c6 1778 and then Present (Component_Associations (Expr_Q))
10edebe7 1779 and then Must_Slide (Comp_Typ, Etype (Expr_Q))
3cf3e5c6
AC
1780 then
1781 Set_Expansion_Delayed (Expr_Q, False);
1782 Set_Analyzed (Expr_Q, False);
1783
1784 else
1785 return
1786 Add_Loop_Actions (
df3e68b1 1787 Late_Expansion (Expr_Q, Etype (Expr_Q), Indexed_Comp));
3cf3e5c6 1788 end if;
70482933
RK
1789 end if;
1790 end if;
1791
937e9676
AC
1792 if Present (Expr) then
1793
1794 -- Handle an initialization expression of a controlled type in
1795 -- case it denotes a function call. In general such a scenario
1796 -- will produce a transient scope, but this will lead to wrong
1797 -- order of initialization, adjustment, and finalization in the
1798 -- context of aggregates.
1799
1800 -- Target (1) := Ctrl_Func_Call;
1801
1802 -- begin -- scope
1803 -- Trans_Obj : ... := Ctrl_Func_Call; -- object
1804 -- Target (1) := Trans_Obj;
1805 -- Finalize (Trans_Obj);
1806 -- end;
1807 -- Target (1)._tag := ...;
1808 -- Adjust (Target (1));
1809
1810 -- In the example above, the call to Finalize occurs too early
1811 -- and as a result it may leave the array component in a bad
1812 -- state. Finalization of the transient object should really
1813 -- happen after adjustment.
1814
1815 -- To avoid this scenario, perform in-place side-effect removal
1816 -- of the function call. This eliminates the transient property
1817 -- of the function result and ensures correct order of actions.
1818
1819 -- Res : ... := Ctrl_Func_Call;
1820 -- Target (1) := Res;
1821 -- Target (1)._tag := ...;
1822 -- Adjust (Target (1));
1823 -- Finalize (Res);
1824
1825 if Present (Comp_Typ)
1826 and then Needs_Finalization (Comp_Typ)
1827 and then Nkind (Expr) /= N_Aggregate
1828 then
1829 Initialize_Ctrl_Array_Component
1830 (Arr_Comp => Indexed_Comp,
1831 Comp_Typ => Comp_Typ,
1832 Init_Expr => Expr,
1833 Stmts => Stmts);
1834
1835 -- Otherwise perform simple component initialization
1836
1837 else
1838 Initialize_Array_Component
1839 (Arr_Comp => Indexed_Comp,
1840 Comp_Typ => Comp_Typ,
1841 Init_Expr => Expr,
1842 Stmts => Stmts);
1843 end if;
1844
0ab80019 1845 -- Ada 2005 (AI-287): In case of default initialized component, call
6e937c1c 1846 -- the initialization subprogram associated with the component type.
3b9fa2df
ES
1847 -- If the component type is an access type, add an explicit null
1848 -- assignment, because for the back-end there is an initialization
1849 -- present for the whole aggregate, and no default initialization
1850 -- will take place.
1851
1852 -- In addition, if the component type is controlled, we must call
1853 -- its Initialize procedure explicitly, because there is no explicit
1854 -- object creation that will invoke it otherwise.
70482933 1855
937e9676 1856 else
3b9fa2df 1857 if Present (Base_Init_Proc (Base_Type (Ctype)))
615cbd95
AC
1858 or else Has_Task (Base_Type (Ctype))
1859 then
10edebe7 1860 Append_List_To (Stmts,
c45b6ae0
AC
1861 Build_Initialization_Call (Loc,
1862 Id_Ref => Indexed_Comp,
1863 Typ => Ctype,
1864 With_Default_Init => True));
3b9fa2df 1865
ffcfb997
ES
1866 -- If the component type has invariants, add an invariant
1867 -- check after the component is default-initialized. It will
1868 -- be analyzed and resolved before the code for initialization
1869 -- of other components.
1870
1871 if Has_Invariants (Ctype) then
1872 Set_Etype (Indexed_Comp, Ctype);
10edebe7 1873 Append_To (Stmts, Make_Invariant_Call (Indexed_Comp));
ffcfb997
ES
1874 end if;
1875
3b9fa2df 1876 elsif Is_Access_Type (Ctype) then
10edebe7 1877 Append_To (Stmts,
ffcfb997 1878 Make_Assignment_Statement (Loc,
10edebe7 1879 Name => New_Copy_Tree (Indexed_Comp),
ffcfb997 1880 Expression => Make_Null (Loc)));
3b9fa2df
ES
1881 end if;
1882
048e5cef 1883 if Needs_Finalization (Ctype) then
2168d7cc 1884 Init_Call :=
37368818
RD
1885 Make_Init_Call
1886 (Obj_Ref => New_Copy_Tree (Indexed_Comp),
2168d7cc
AC
1887 Typ => Ctype);
1888
1889 -- Guard against a missing [Deep_]Initialize when the component
1890 -- type was not properly frozen.
1891
1892 if Present (Init_Call) then
1893 Append_To (Stmts, Init_Call);
1894 end if;
615cbd95 1895 end if;
097826df
GD
1896
1897 -- If Default_Initial_Condition applies to the component type,
1898 -- add a DIC check after the component is default-initialized,
1899 -- as well as after an Initialize procedure is called, in the
1900 -- case of components of a controlled type. It will be analyzed
1901 -- and resolved before the code for initialization of other
1902 -- components.
1903
1904 -- Theoretically this might also be needed for cases where Expr
1905 -- is not empty, but a default init still applies, such as for
1906 -- Default_Value cases, in which case we won't get here. ???
1907
1908 if Has_DIC (Ctype) and then Present (DIC_Procedure (Ctype)) then
1909 Append_To (Stmts,
1910 Build_DIC_Call (Loc, New_Copy_Tree (Indexed_Comp), Ctype));
1911 end if;
70482933
RK
1912 end if;
1913
10edebe7 1914 return Add_Loop_Actions (Stmts);
70482933
RK
1915 end Gen_Assign;
1916
1917 --------------
1918 -- Gen_Loop --
1919 --------------
1920
1921 function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is
00f45f30 1922 Is_Iterated_Component : constant Boolean :=
898edf75 1923 Parent_Kind (Expr) = N_Iterated_Component_Association;
00f45f30 1924
07fc65c4 1925 L_J : Node_Id;
70482933 1926
240fe2a4
AC
1927 L_L : Node_Id;
1928 -- Index_Base'(L)
1929
1930 L_H : Node_Id;
1931 -- Index_Base'(H)
1932
70482933
RK
1933 L_Range : Node_Id;
1934 -- Index_Base'(L) .. Index_Base'(H)
1935
1936 L_Iteration_Scheme : Node_Id;
07fc65c4 1937 -- L_J in Index_Base'(L) .. Index_Base'(H)
70482933
RK
1938
1939 L_Body : List_Id;
1940 -- The statements to execute in the loop
1941
fbf5a39b
AC
1942 S : constant List_Id := New_List;
1943 -- List of statements
70482933
RK
1944
1945 Tcopy : Node_Id;
1946 -- Copy of expression tree, used for checking purposes
1947
1948 begin
1949 -- If loop bounds define an empty range return the null statement
1950
1951 if Empty_Range (L, H) then
1952 Append_To (S, Make_Null_Statement (Loc));
1953
0ab80019 1954 -- Ada 2005 (AI-287): Nothing else need to be done in case of
6e937c1c 1955 -- default initialized component.
70482933 1956
d8f7b976 1957 if No (Expr) then
c45b6ae0
AC
1958 null;
1959
1960 else
1961 -- The expression must be type-checked even though no component
1962 -- of the aggregate will have this value. This is done only for
1963 -- actual components of the array, not for subaggregates. Do
1964 -- the check on a copy, because the expression may be shared
1965 -- among several choices, some of which might be non-null.
1966
1967 if Present (Etype (N))
1968 and then Is_Array_Type (Etype (N))
1969 and then No (Next_Index (Index))
1970 then
1971 Expander_Mode_Save_And_Set (False);
1972 Tcopy := New_Copy_Tree (Expr);
1973 Set_Parent (Tcopy, N);
4270e945
PT
1974
1975 -- For iterated_component_association analyze and resolve
1976 -- the expression with name of the index parameter visible.
1977 -- To manipulate scopes, we use entity of the implicit loop.
1978
1979 if Is_Iterated_Component then
1980 declare
1981 Index_Parameter : constant Entity_Id :=
1982 Defining_Identifier (Parent (Expr));
1983 begin
1984 Push_Scope (Scope (Index_Parameter));
1985 Enter_Name (Index_Parameter);
1986 Analyze_And_Resolve
1987 (Tcopy, Component_Type (Etype (N)));
1988 End_Scope;
1989 end;
1990
1991 -- For ordinary component association, just analyze and
1992 -- resolve the expression.
1993
1994 else
1995 Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
1996 end if;
1997
c45b6ae0
AC
1998 Expander_Mode_Restore;
1999 end if;
70482933
RK
2000 end if;
2001
2002 return S;
2003
00f45f30
AC
2004 -- If loop bounds are the same then generate an assignment, unless
2005 -- the parent construct is an Iterated_Component_Association.
70482933 2006
00f45f30 2007 elsif Equal (L, H) and then not Is_Iterated_Component then
70482933
RK
2008 return Gen_Assign (New_Copy_Tree (L), Expr);
2009
3b9fa2df
ES
2010 -- If H - L <= 2 then generate a sequence of assignments when we are
2011 -- processing the bottom most aggregate and it contains scalar
2012 -- components.
70482933
RK
2013
2014 elsif No (Next_Index (Index))
2015 and then Scalar_Comp
2016 and then Local_Compile_Time_Known_Value (L)
2017 and then Local_Compile_Time_Known_Value (H)
2018 and then Local_Expr_Value (H) - Local_Expr_Value (L) <= 2
00f45f30 2019 and then not Is_Iterated_Component
70482933
RK
2020 then
2021 Append_List_To (S, Gen_Assign (New_Copy_Tree (L), Expr));
2022 Append_List_To (S, Gen_Assign (Add (1, To => L), Expr));
2023
2024 if Local_Expr_Value (H) - Local_Expr_Value (L) = 2 then
2025 Append_List_To (S, Gen_Assign (Add (2, To => L), Expr));
2026 end if;
2027
2028 return S;
2029 end if;
2030
07fc65c4 2031 -- Otherwise construct the loop, starting with the loop index L_J
70482933 2032
00f45f30 2033 if Is_Iterated_Component then
72cdccfa
HK
2034 L_J :=
2035 Make_Defining_Identifier (Loc,
2036 Chars => (Chars (Defining_Identifier (Parent (Expr)))));
00f45f30
AC
2037
2038 else
2039 L_J := Make_Temporary (Loc, 'J', L);
2040 end if;
70482933 2041
240fe2a4
AC
2042 -- Construct "L .. H" in Index_Base. We use a qualified expression
2043 -- for the bound to convert to the index base, but we don't need
2044 -- to do that if we already have the base type at hand.
2045
2046 if Etype (L) = Index_Base then
2047 L_L := L;
2048 else
2049 L_L :=
2050 Make_Qualified_Expression (Loc,
2051 Subtype_Mark => Index_Base_Name,
00f45f30 2052 Expression => New_Copy_Tree (L));
240fe2a4
AC
2053 end if;
2054
2055 if Etype (H) = Index_Base then
2056 L_H := H;
2057 else
2058 L_H :=
2059 Make_Qualified_Expression (Loc,
2060 Subtype_Mark => Index_Base_Name,
00f45f30 2061 Expression => New_Copy_Tree (H));
240fe2a4 2062 end if;
70482933
RK
2063
2064 L_Range :=
240fe2a4 2065 Make_Range (Loc,
ffcfb997 2066 Low_Bound => L_L,
240fe2a4 2067 High_Bound => L_H);
70482933 2068
07fc65c4 2069 -- Construct "for L_J in Index_Base range L .. H"
70482933
RK
2070
2071 L_Iteration_Scheme :=
2072 Make_Iteration_Scheme
2073 (Loc,
2074 Loop_Parameter_Specification =>
2075 Make_Loop_Parameter_Specification
2076 (Loc,
07fc65c4 2077 Defining_Identifier => L_J,
70482933
RK
2078 Discrete_Subtype_Definition => L_Range));
2079
2080 -- Construct the statements to execute in the loop body
2081
937e9676
AC
2082 L_Body :=
2083 Gen_Assign (New_Occurrence_Of (L_J, Loc), Expr, In_Loop => True);
70482933
RK
2084
2085 -- Construct the final loop
2086
37368818
RD
2087 Append_To (S,
2088 Make_Implicit_Loop_Statement
2089 (Node => N,
2090 Identifier => Empty,
2091 Iteration_Scheme => L_Iteration_Scheme,
2092 Statements => L_Body));
70482933 2093
3b9fa2df
ES
2094 -- A small optimization: if the aggregate is initialized with a box
2095 -- and the component type has no initialization procedure, remove the
2096 -- useless empty loop.
0f95b178
JM
2097
2098 if Nkind (First (S)) = N_Loop_Statement
2099 and then Is_Empty_List (Statements (First (S)))
2100 then
2101 return New_List (Make_Null_Statement (Loc));
2102 else
2103 return S;
2104 end if;
70482933
RK
2105 end Gen_Loop;
2106
2107 ---------------
2108 -- Gen_While --
2109 ---------------
2110
2111 -- The code built is
2112
07fc65c4
GB
2113 -- W_J : Index_Base := L;
2114 -- while W_J < H loop
2115 -- W_J := Index_Base'Succ (W);
70482933
RK
2116 -- L_Body;
2117 -- end loop;
2118
2119 function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
07fc65c4 2120 W_J : Node_Id;
70482933
RK
2121
2122 W_Decl : Node_Id;
07fc65c4 2123 -- W_J : Base_Type := L;
70482933
RK
2124
2125 W_Iteration_Scheme : Node_Id;
07fc65c4 2126 -- while W_J < H
70482933
RK
2127
2128 W_Index_Succ : Node_Id;
07fc65c4 2129 -- Index_Base'Succ (J)
70482933 2130
fbf5a39b 2131 W_Increment : Node_Id;
07fc65c4 2132 -- W_J := Index_Base'Succ (W)
70482933 2133
fbf5a39b 2134 W_Body : constant List_Id := New_List;
70482933
RK
2135 -- The statements to execute in the loop
2136
fbf5a39b 2137 S : constant List_Id := New_List;
70482933
RK
2138 -- list of statement
2139
2140 begin
2141 -- If loop bounds define an empty range or are equal return null
2142
2143 if Empty_Range (L, H) or else Equal (L, H) then
2144 Append_To (S, Make_Null_Statement (Loc));
2145 return S;
2146 end if;
2147
07fc65c4 2148 -- Build the decl of W_J
70482933 2149
191fcb3a 2150 W_J := Make_Temporary (Loc, 'J', L);
70482933
RK
2151 W_Decl :=
2152 Make_Object_Declaration
2153 (Loc,
07fc65c4 2154 Defining_Identifier => W_J,
70482933
RK
2155 Object_Definition => Index_Base_Name,
2156 Expression => L);
2157
2158 -- Theoretically we should do a New_Copy_Tree (L) here, but we know
2159 -- that in this particular case L is a fresh Expr generated by
2160 -- Add which we are the only ones to use.
2161
2162 Append_To (S, W_Decl);
2163
fbf5a39b 2164 -- Construct " while W_J < H"
70482933
RK
2165
2166 W_Iteration_Scheme :=
2167 Make_Iteration_Scheme
2168 (Loc,
2169 Condition => Make_Op_Lt
2170 (Loc,
e4494292 2171 Left_Opnd => New_Occurrence_Of (W_J, Loc),
70482933
RK
2172 Right_Opnd => New_Copy_Tree (H)));
2173
2174 -- Construct the statements to execute in the loop body
2175
2176 W_Index_Succ :=
2177 Make_Attribute_Reference
2178 (Loc,
2179 Prefix => Index_Base_Name,
2180 Attribute_Name => Name_Succ,
e4494292 2181 Expressions => New_List (New_Occurrence_Of (W_J, Loc)));
70482933
RK
2182
2183 W_Increment :=
2184 Make_OK_Assignment_Statement
2185 (Loc,
e4494292 2186 Name => New_Occurrence_Of (W_J, Loc),
70482933
RK
2187 Expression => W_Index_Succ);
2188
2189 Append_To (W_Body, W_Increment);
937e9676 2190
70482933 2191 Append_List_To (W_Body,
937e9676 2192 Gen_Assign (New_Occurrence_Of (W_J, Loc), Expr, In_Loop => True));
70482933
RK
2193
2194 -- Construct the final loop
2195
37368818
RD
2196 Append_To (S,
2197 Make_Implicit_Loop_Statement
2198 (Node => N,
2199 Identifier => Empty,
2200 Iteration_Scheme => W_Iteration_Scheme,
2201 Statements => W_Body));
70482933
RK
2202
2203 return S;
2204 end Gen_While;
2205
59e9bc0b
AC
2206 --------------------
2207 -- Get_Assoc_Expr --
2208 --------------------
2209
2210 function Get_Assoc_Expr (Assoc : Node_Id) return Node_Id is
e9999161
AC
2211 Typ : constant Entity_Id := Base_Type (Etype (N));
2212
59e9bc0b
AC
2213 begin
2214 if Box_Present (Assoc) then
e9999161
AC
2215 if Is_Scalar_Type (Ctype) then
2216 if Present (Default_Aspect_Component_Value (Typ)) then
2217 return Default_Aspect_Component_Value (Typ);
e9999161
AC
2218 elsif Present (Default_Aspect_Value (Ctype)) then
2219 return Default_Aspect_Value (Ctype);
2220 else
2221 return Empty;
2222 end if;
e0c23ac7 2223
59e9bc0b
AC
2224 else
2225 return Empty;
2226 end if;
2227
2228 else
2229 return Expression (Assoc);
2230 end if;
2231 end Get_Assoc_Expr;
2232
70482933
RK
2233 ---------------------
2234 -- Index_Base_Name --
2235 ---------------------
2236
2237 function Index_Base_Name return Node_Id is
2238 begin
e4494292 2239 return New_Occurrence_Of (Index_Base, Sloc (N));
70482933
RK
2240 end Index_Base_Name;
2241
2242 ------------------------------------
2243 -- Local_Compile_Time_Known_Value --
2244 ------------------------------------
2245
2246 function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean is
2247 begin
2248 return Compile_Time_Known_Value (E)
2249 or else
2250 (Nkind (E) = N_Attribute_Reference
fbf5a39b
AC
2251 and then Attribute_Name (E) = Name_Val
2252 and then Compile_Time_Known_Value (First (Expressions (E))));
70482933
RK
2253 end Local_Compile_Time_Known_Value;
2254
2255 ----------------------
2256 -- Local_Expr_Value --
2257 ----------------------
2258
2259 function Local_Expr_Value (E : Node_Id) return Uint is
2260 begin
2261 if Compile_Time_Known_Value (E) then
2262 return Expr_Value (E);
2263 else
2264 return Expr_Value (First (Expressions (E)));
2265 end if;
2266 end Local_Expr_Value;
2267
937e9676 2268 -- Local variables
70482933 2269
937e9676 2270 New_Code : constant List_Id := New_List;
70482933
RK
2271
2272 Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
2273 Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
d74716b3
AC
2274 -- The aggregate bounds of this specific subaggregate. Note that if the
2275 -- code generated by Build_Array_Aggr_Code is executed then these bounds
2276 -- are OK. Otherwise a Constraint_Error would have been raised.
70482933 2277
fbf5a39b
AC
2278 Aggr_Low : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_L);
2279 Aggr_High : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_H);
7324bf49 2280 -- After Duplicate_Subexpr these are side-effect free
70482933 2281
937e9676
AC
2282 Assoc : Node_Id;
2283 Choice : Node_Id;
2284 Expr : Node_Id;
937e9676 2285 Typ : Entity_Id;
70482933 2286
7c4f3267
BD
2287 Bounds : Range_Nodes;
2288 Low : Node_Id renames Bounds.First;
2289 High : Node_Id renames Bounds.Last;
2290
70482933
RK
2291 Nb_Choices : Nat := 0;
2292 Table : Case_Table_Type (1 .. Number_Of_Choices (N));
2293 -- Used to sort all the different choice values
2294
2295 Nb_Elements : Int;
2296 -- Number of elements in the positional aggregate
2297
937e9676 2298 Others_Assoc : Node_Id := Empty;
70482933
RK
2299
2300 -- Start of processing for Build_Array_Aggr_Code
2301
2302 begin
fbf5a39b
AC
2303 -- First before we start, a special case. if we have a bit packed
2304 -- array represented as a modular type, then clear the value to
2305 -- zero first, to ensure that unused bits are properly cleared.
2306
2307 Typ := Etype (N);
2308
2309 if Present (Typ)
2310 and then Is_Bit_Packed_Array (Typ)
8ca597af 2311 and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ))
fbf5a39b 2312 then
445514c0
EB
2313 declare
2314 Zero : constant Node_Id := Make_Integer_Literal (Loc, Uint_0);
2315 begin
2316 Analyze_And_Resolve (Zero, Packed_Array_Impl_Type (Typ));
2317 Append_To (New_Code,
2318 Make_Assignment_Statement (Loc,
2319 Name => New_Copy_Tree (Into),
2320 Expression => Unchecked_Convert_To (Typ, Zero)));
2321 end;
fbf5a39b
AC
2322 end if;
2323
0e08f7ab
ES
2324 -- If the component type contains tasks, we need to build a Master
2325 -- entity in the current scope, because it will be needed if build-
2326 -- in-place functions are called in the expanded code.
2327
36a66365 2328 if Nkind (Parent (N)) = N_Object_Declaration and then Has_Task (Typ) then
0e08f7ab
ES
2329 Build_Master_Entity (Defining_Identifier (Parent (N)));
2330 end if;
2331
70482933 2332 -- STEP 1: Process component associations
3b9fa2df 2333
fbf5a39b
AC
2334 -- For those associations that may generate a loop, initialize
2335 -- Loop_Actions to collect inserted actions that may be crated.
70482933 2336
3b9fa2df
ES
2337 -- Skip this if no component associations
2338
70482933
RK
2339 if No (Expressions (N)) then
2340
2341 -- STEP 1 (a): Sort the discrete choices
2342
2343 Assoc := First (Component_Associations (N));
2344 while Present (Assoc) loop
00f45f30 2345 Choice := First (Choice_List (Assoc));
70482933 2346 while Present (Choice) loop
70482933 2347 if Nkind (Choice) = N_Others_Choice then
59e9bc0b 2348 Others_Assoc := Assoc;
70482933
RK
2349 exit;
2350 end if;
2351
7c4f3267 2352 Bounds := Get_Index_Bounds (Choice);
70482933 2353
fbf5a39b
AC
2354 if Low /= High then
2355 Set_Loop_Actions (Assoc, New_List);
2356 end if;
2357
70482933 2358 Nb_Choices := Nb_Choices + 1;
59e9bc0b
AC
2359
2360 Table (Nb_Choices) :=
2361 (Choice_Lo => Low,
2362 Choice_Hi => High,
2363 Choice_Node => Get_Assoc_Expr (Assoc));
2364
70482933
RK
2365 Next (Choice);
2366 end loop;
2367
2368 Next (Assoc);
2369 end loop;
2370
2371 -- If there is more than one set of choices these must be static
2372 -- and we can therefore sort them. Remember that Nb_Choices does not
2373 -- account for an others choice.
2374
2375 if Nb_Choices > 1 then
2376 Sort_Case_Table (Table);
2377 end if;
2378
74580e1b 2379 -- STEP 1 (b): take care of the whole set of discrete choices
70482933
RK
2380
2381 for J in 1 .. Nb_Choices loop
2382 Low := Table (J).Choice_Lo;
2383 High := Table (J).Choice_Hi;
2384 Expr := Table (J).Choice_Node;
70482933
RK
2385 Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
2386 end loop;
2387
2388 -- STEP 1 (c): generate the remaining loops to cover others choice
2389 -- We don't need to generate loops over empty gaps, but if there is
2390 -- a single empty range we must analyze the expression for semantics
2391
59e9bc0b 2392 if Present (Others_Assoc) then
70482933 2393 declare
6951cbc9
EB
2394 First : Boolean := True;
2395 Dup_Expr : Node_Id;
70482933
RK
2396
2397 begin
2398 for J in 0 .. Nb_Choices loop
70482933
RK
2399 if J = 0 then
2400 Low := Aggr_Low;
2401 else
2402 Low := Add (1, To => Table (J).Choice_Hi);
2403 end if;
2404
2405 if J = Nb_Choices then
2406 High := Aggr_High;
2407 else
2408 High := Add (-1, To => Table (J + 1).Choice_Lo);
2409 end if;
2410
fbf5a39b 2411 -- If this is an expansion within an init proc, make
c84700e7
ES
2412 -- sure that discriminant references are replaced by
2413 -- the corresponding discriminal.
2414
2415 if Inside_Init_Proc then
2416 if Is_Entity_Name (Low)
2417 and then Ekind (Entity (Low)) = E_Discriminant
2418 then
2419 Set_Entity (Low, Discriminal (Entity (Low)));
2420 end if;
2421
2422 if Is_Entity_Name (High)
2423 and then Ekind (Entity (High)) = E_Discriminant
2424 then
2425 Set_Entity (High, Discriminal (Entity (High)));
2426 end if;
2427 end if;
2428
70482933
RK
2429 if First
2430 or else not Empty_Range (Low, High)
2431 then
2432 First := False;
6951cbc9
EB
2433
2434 -- Duplicate the expression in case we will be generating
2435 -- several loops. As a result the expression is no longer
2436 -- shared between the loops and is reevaluated for each
2437 -- such loop.
2438
2439 Expr := Get_Assoc_Expr (Others_Assoc);
2440 Dup_Expr := New_Copy_Tree (Expr);
898edf75 2441 Copy_Parent (To => Dup_Expr, From => Expr);
6951cbc9
EB
2442
2443 Set_Loop_Actions (Others_Assoc, New_List);
70482933 2444 Append_List
6951cbc9 2445 (Gen_Loop (Low, High, Dup_Expr), To => New_Code);
70482933
RK
2446 end if;
2447 end loop;
2448 end;
2449 end if;
2450
2451 -- STEP 2: Process positional components
2452
2453 else
2454 -- STEP 2 (a): Generate the assignments for each positional element
2455 -- Note that here we have to use Aggr_L rather than Aggr_Low because
2456 -- Aggr_L is analyzed and Add wants an analyzed expression.
2457
2458 Expr := First (Expressions (N));
2459 Nb_Elements := -1;
70482933
RK
2460 while Present (Expr) loop
2461 Nb_Elements := Nb_Elements + 1;
2462 Append_List (Gen_Assign (Add (Nb_Elements, To => Aggr_L), Expr),
2463 To => New_Code);
2464 Next (Expr);
2465 end loop;
2466
02a82539 2467 -- STEP 2 (b): Generate final loop if an others choice is present.
70482933
RK
2468 -- Here Nb_Elements gives the offset of the last positional element.
2469
2470 if Present (Component_Associations (N)) then
2471 Assoc := Last (Component_Associations (N));
70482933 2472
02a82539 2473 if Nkind (Assoc) = N_Iterated_Component_Association then
81e68a19 2474 -- Ada 2022: generate a loop to have a proper scope for
02a82539
ES
2475 -- the identifier that typically appears in the expression.
2476 -- The lower bound of the loop is the position after all
2477 -- previous positional components.
6e937c1c 2478
02a82539
ES
2479 Append_List (Gen_Loop (Add (Nb_Elements + 1, To => Aggr_L),
2480 Aggr_High,
2481 Expression (Assoc)),
2482 To => New_Code);
2483 else
2484 -- Ada 2005 (AI-287)
2485
2486 Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
2487 Aggr_High,
2488 Get_Assoc_Expr (Assoc)),
2489 To => New_Code);
2490 end if;
70482933
RK
2491 end if;
2492 end if;
2493
2494 return New_Code;
2495 end Build_Array_Aggr_Code;
2496
2497 ----------------------------
2498 -- Build_Record_Aggr_Code --
2499 ----------------------------
2500
2501 function Build_Record_Aggr_Code
f7e6fc47
RD
2502 (N : Node_Id;
2503 Typ : Entity_Id;
2504 Lhs : Node_Id) return List_Id
70482933
RK
2505 is
2506 Loc : constant Source_Ptr := Sloc (N);
2507 L : constant List_Id := New_List;
70482933
RK
2508 N_Typ : constant Entity_Id := Etype (N);
2509
2510 Comp : Node_Id;
2511 Instr : Node_Id;
2512 Ref : Node_Id;
0f95b178 2513 Target : Entity_Id;
70482933
RK
2514 Comp_Type : Entity_Id;
2515 Selector : Entity_Id;
2516 Comp_Expr : Node_Id;
70482933
RK
2517 Expr_Q : Node_Id;
2518
70482933
RK
2519 -- If this is an internal aggregate, the External_Final_List is an
2520 -- expression for the controller record of the enclosing type.
3b9fa2df 2521
70482933
RK
2522 -- If the current aggregate has several controlled components, this
2523 -- expression will appear in several calls to attach to the finali-
2524 -- zation list, and it must not be shared.
2525
70482933
RK
2526 Ancestor_Is_Expression : Boolean := False;
2527 Ancestor_Is_Subtype_Mark : Boolean := False;
2528
2529 Init_Typ : Entity_Id := Empty;
5277cab6 2530
df3e68b1
HK
2531 Finalization_Done : Boolean := False;
2532 -- True if Generate_Finalization_Actions has already been called; calls
0f95b178 2533 -- after the first do nothing.
70482933 2534
70482933 2535 function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id;
3b9fa2df
ES
2536 -- Returns the value that the given discriminant of an ancestor type
2537 -- should receive (in the absence of a conflict with the value provided
2538 -- by an ancestor part of an extension aggregate).
70482933
RK
2539
2540 procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id);
3b9fa2df
ES
2541 -- Check that each of the discriminant values defined by the ancestor
2542 -- part of an extension aggregate match the corresponding values
2543 -- provided by either an association of the aggregate or by the
2544 -- constraint imposed by a parent type (RM95-4.3.2(8)).
70482933 2545
d8f7b976
ES
2546 function Compatible_Int_Bounds
2547 (Agg_Bounds : Node_Id;
2548 Typ_Bounds : Node_Id) return Boolean;
2549 -- Return true if Agg_Bounds are equal or within Typ_Bounds. It is
2550 -- assumed that both bounds are integer ranges.
2551
df3e68b1 2552 procedure Generate_Finalization_Actions;
0f95b178
JM
2553 -- Deal with the various controlled type data structure initializations
2554 -- (but only if it hasn't been done already).
d8f7b976
ES
2555
2556 function Get_Constraint_Association (T : Entity_Id) return Node_Id;
2557 -- Returns the first discriminant association in the constraint
2558 -- associated with T, if any, otherwise returns Empty.
2559
71129dde
AC
2560 function Get_Explicit_Discriminant_Value (D : Entity_Id) return Node_Id;
2561 -- If the ancestor part is an unconstrained type and further ancestors
2562 -- do not provide discriminants for it, check aggregate components for
2563 -- values of the discriminants.
2564
3e582869
AC
2565 procedure Init_Hidden_Discriminants (Typ : Entity_Id; List : List_Id);
2566 -- If Typ is derived, and constrains discriminants of the parent type,
2567 -- these discriminants are not components of the aggregate, and must be
2feb1f84
AC
2568 -- initialized. The assignments are appended to List. The same is done
2569 -- if Typ derives fron an already constrained subtype of a discriminated
2570 -- parent type.
3e582869 2571
71129dde
AC
2572 procedure Init_Stored_Discriminants;
2573 -- If the type is derived and has inherited discriminants, generate
2574 -- explicit assignments for each, using the store constraint of the
2575 -- type. Note that both visible and stored discriminants must be
2576 -- initialized in case the derived type has some renamed and some
2577 -- constrained discriminants.
2578
2579 procedure Init_Visible_Discriminants;
2580 -- If type has discriminants, retrieve their values from aggregate,
2581 -- and generate explicit assignments for each. This does not include
2582 -- discriminants inherited from ancestor, which are handled above.
2583 -- The type of the aggregate is a subtype created ealier using the
2584 -- given values of the discriminant components of the aggregate.
aab45d22 2585
937e9676
AC
2586 procedure Initialize_Ctrl_Record_Component
2587 (Rec_Comp : Node_Id;
2588 Comp_Typ : Entity_Id;
2589 Init_Expr : Node_Id;
2590 Stmts : List_Id);
2591 -- Perform the initialization of controlled record component Rec_Comp.
2592 -- Comp_Typ is the component type. Init_Expr is the initialization
2593 -- expression for the record component. Hook-related declarations are
2594 -- inserted prior to aggregate N using Insert_Action. All remaining
2595 -- generated code is added to list Stmts.
2596
2597 procedure Initialize_Record_Component
2598 (Rec_Comp : Node_Id;
2599 Comp_Typ : Entity_Id;
2600 Init_Expr : Node_Id;
2601 Stmts : List_Id);
2602 -- Perform the initialization of record component Rec_Comp. Comp_Typ
2603 -- is the component type. Init_Expr is the initialization expression
2604 -- of the record component. All generated code is added to list Stmts.
2605
d8f7b976
ES
2606 function Is_Int_Range_Bounds (Bounds : Node_Id) return Boolean;
2607 -- Check whether Bounds is a range node and its lower and higher bounds
2608 -- are integers literals.
7b9d0d69 2609
937e9676
AC
2610 function Replace_Type (Expr : Node_Id) return Traverse_Result;
2611 -- If the aggregate contains a self-reference, traverse each expression
2612 -- to replace a possible self-reference with a reference to the proper
2613 -- component of the target of the assignment.
2614
2615 function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result;
2616 -- If default expression of a component mentions a discriminant of the
2617 -- type, it must be rewritten as the discriminant of the target object.
2618
2619 ---------------------------------
2620 -- Ancestor_Discriminant_Value --
2621 ---------------------------------
70482933
RK
2622
2623 function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id is
2624 Assoc : Node_Id;
2625 Assoc_Elmt : Elmt_Id;
2626 Aggr_Comp : Entity_Id;
2627 Corresp_Disc : Entity_Id;
2628 Current_Typ : Entity_Id := Base_Type (Typ);
2629 Parent_Typ : Entity_Id;
2630 Parent_Disc : Entity_Id;
2631 Save_Assoc : Node_Id := Empty;
2632
2633 begin
3b9fa2df
ES
2634 -- First check any discriminant associations to see if any of them
2635 -- provide a value for the discriminant.
70482933
RK
2636
2637 if Present (Discriminant_Specifications (Parent (Current_Typ))) then
2638 Assoc := First (Component_Associations (N));
2639 while Present (Assoc) loop
2640 Aggr_Comp := Entity (First (Choices (Assoc)));
2641
2642 if Ekind (Aggr_Comp) = E_Discriminant then
2643 Save_Assoc := Expression (Assoc);
2644
2645 Corresp_Disc := Corresponding_Discriminant (Aggr_Comp);
2646 while Present (Corresp_Disc) loop
3b9fa2df
ES
2647
2648 -- If found a corresponding discriminant then return the
2649 -- value given in the aggregate. (Note: this is not
2650 -- correct in the presence of side effects. ???)
70482933
RK
2651
2652 if Disc = Corresp_Disc then
2653 return Duplicate_Subexpr (Expression (Assoc));
2654 end if;
fbf5a39b 2655
ffcfb997 2656 Corresp_Disc := Corresponding_Discriminant (Corresp_Disc);
70482933
RK
2657 end loop;
2658 end if;
2659
2660 Next (Assoc);
2661 end loop;
2662 end if;
2663
2664 -- No match found in aggregate, so chain up parent types to find
2665 -- a constraint that defines the value of the discriminant.
2666
2667 Parent_Typ := Etype (Current_Typ);
2668 while Current_Typ /= Parent_Typ loop
9013065b
AC
2669 if Has_Discriminants (Parent_Typ)
2670 and then not Has_Unknown_Discriminants (Parent_Typ)
2671 then
70482933
RK
2672 Parent_Disc := First_Discriminant (Parent_Typ);
2673
2674 -- We either get the association from the subtype indication
2675 -- of the type definition itself, or from the discriminant
2676 -- constraint associated with the type entity (which is
2677 -- preferable, but it's not always present ???)
2678
aff557c7 2679 if Is_Empty_Elmt_List (Discriminant_Constraint (Current_Typ))
70482933
RK
2680 then
2681 Assoc := Get_Constraint_Association (Current_Typ);
2682 Assoc_Elmt := No_Elmt;
2683 else
2684 Assoc_Elmt :=
2685 First_Elmt (Discriminant_Constraint (Current_Typ));
2686 Assoc := Node (Assoc_Elmt);
2687 end if;
2688
2689 -- Traverse the discriminants of the parent type looking
2690 -- for one that corresponds.
2691
2692 while Present (Parent_Disc) and then Present (Assoc) loop
2693 Corresp_Disc := Parent_Disc;
2694 while Present (Corresp_Disc)
2695 and then Disc /= Corresp_Disc
2696 loop
ffcfb997 2697 Corresp_Disc := Corresponding_Discriminant (Corresp_Disc);
70482933
RK
2698 end loop;
2699
2700 if Disc = Corresp_Disc then
2701 if Nkind (Assoc) = N_Discriminant_Association then
2702 Assoc := Expression (Assoc);
2703 end if;
2704
e80f0cb0
RD
2705 -- If the located association directly denotes
2706 -- a discriminant, then use the value of a saved
2707 -- association of the aggregate. This is an approach
2708 -- used to handle certain cases involving multiple
2709 -- discriminants mapped to a single discriminant of
2710 -- a descendant. It's not clear how to locate the
2711 -- appropriate discriminant value for such cases. ???
70482933
RK
2712
2713 if Is_Entity_Name (Assoc)
2714 and then Ekind (Entity (Assoc)) = E_Discriminant
2715 then
2716 Assoc := Save_Assoc;
2717 end if;
2718
2719 return Duplicate_Subexpr (Assoc);
2720 end if;
2721
2722 Next_Discriminant (Parent_Disc);
2723
2724 if No (Assoc_Elmt) then
2725 Next (Assoc);
ffcfb997 2726
70482933
RK
2727 else
2728 Next_Elmt (Assoc_Elmt);
ffcfb997 2729
70482933
RK
2730 if Present (Assoc_Elmt) then
2731 Assoc := Node (Assoc_Elmt);
2732 else
2733 Assoc := Empty;
2734 end if;
2735 end if;
2736 end loop;
2737 end if;
2738
2739 Current_Typ := Parent_Typ;
2740 Parent_Typ := Etype (Current_Typ);
2741 end loop;
2742
2743 -- In some cases there's no ancestor value to locate (such as
2744 -- when an ancestor part given by an expression defines the
2745 -- discriminant value).
2746
2747 return Empty;
2748 end Ancestor_Discriminant_Value;
2749
2750 ----------------------------------
2751 -- Check_Ancestor_Discriminants --
2752 ----------------------------------
2753
2754 procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id) is
5277cab6 2755 Discr : Entity_Id;
70482933
RK
2756 Disc_Value : Node_Id;
2757 Cond : Node_Id;
2758
2759 begin
5277cab6 2760 Discr := First_Discriminant (Base_Type (Anc_Typ));
70482933
RK
2761 while Present (Discr) loop
2762 Disc_Value := Ancestor_Discriminant_Value (Discr);
2763
2764 if Present (Disc_Value) then
2765 Cond := Make_Op_Ne (Loc,
ffcfb997 2766 Left_Opnd =>
70482933
RK
2767 Make_Selected_Component (Loc,
2768 Prefix => New_Copy_Tree (Target),
2769 Selector_Name => New_Occurrence_Of (Discr, Loc)),
2770 Right_Opnd => Disc_Value);
2771
07fc65c4
GB
2772 Append_To (L,
2773 Make_Raise_Constraint_Error (Loc,
2774 Condition => Cond,
2775 Reason => CE_Discriminant_Check_Failed));
70482933
RK
2776 end if;
2777
2778 Next_Discriminant (Discr);
2779 end loop;
2780 end Check_Ancestor_Discriminants;
2781
d8f7b976
ES
2782 ---------------------------
2783 -- Compatible_Int_Bounds --
2784 ---------------------------
2785
2786 function Compatible_Int_Bounds
2787 (Agg_Bounds : Node_Id;
2788 Typ_Bounds : Node_Id) return Boolean
2789 is
2790 Agg_Lo : constant Uint := Intval (Low_Bound (Agg_Bounds));
2791 Agg_Hi : constant Uint := Intval (High_Bound (Agg_Bounds));
2792 Typ_Lo : constant Uint := Intval (Low_Bound (Typ_Bounds));
2793 Typ_Hi : constant Uint := Intval (High_Bound (Typ_Bounds));
2794 begin
2795 return Typ_Lo <= Agg_Lo and then Agg_Hi <= Typ_Hi;
2796 end Compatible_Int_Bounds;
2797
937e9676
AC
2798 -----------------------------------
2799 -- Generate_Finalization_Actions --
2800 -----------------------------------
2801
2802 procedure Generate_Finalization_Actions is
2803 begin
2804 -- Do the work only the first time this is called
2805
2806 if Finalization_Done then
2807 return;
2808 end if;
2809
2810 Finalization_Done := True;
2811
2812 -- Determine the external finalization list. It is either the
2813 -- finalization list of the outer scope or the one coming from an
2814 -- outer aggregate. When the target is not a temporary, the proper
2815 -- scope is the scope of the target rather than the potentially
2816 -- transient current scope.
2817
2818 if Is_Controlled (Typ) and then Ancestor_Is_Subtype_Mark then
2819 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
2820 Set_Assignment_OK (Ref);
2821
2822 Append_To (L,
2823 Make_Procedure_Call_Statement (Loc,
2824 Name =>
2825 New_Occurrence_Of
2826 (Find_Prim_Op (Init_Typ, Name_Initialize), Loc),
2827 Parameter_Associations => New_List (New_Copy_Tree (Ref))));
2828 end if;
2829 end Generate_Finalization_Actions;
2830
70482933
RK
2831 --------------------------------
2832 -- Get_Constraint_Association --
2833 --------------------------------
2834
2835 function Get_Constraint_Association (T : Entity_Id) return Node_Id is
2c17ca0a
AC
2836 Indic : Node_Id;
2837 Typ : Entity_Id;
70482933
RK
2838
2839 begin
2c17ca0a
AC
2840 Typ := T;
2841
598a56c0
ES
2842 -- If type is private, get constraint from full view. This was
2843 -- previously done in an instance context, but is needed whenever
2844 -- the ancestor part has a discriminant, possibly inherited through
2845 -- multiple derivations.
2c17ca0a 2846
598a56c0 2847 if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
2c17ca0a
AC
2848 Typ := Full_View (Typ);
2849 end if;
2850
2851 Indic := Subtype_Indication (Type_Definition (Parent (Typ)));
2852
598a56c0 2853 -- Verify that the subtype indication carries a constraint
70482933
RK
2854
2855 if Nkind (Indic) = N_Subtype_Indication
2856 and then Present (Constraint (Indic))
2857 then
2858 return First (Constraints (Constraint (Indic)));
2859 end if;
2860
2861 return Empty;
2862 end Get_Constraint_Association;
2863
aab45d22
AC
2864 -------------------------------------
2865 -- Get_Explicit_Discriminant_Value --
2866 -------------------------------------
2867
7893514c
RD
2868 function Get_Explicit_Discriminant_Value
2869 (D : Entity_Id) return Node_Id
aab45d22
AC
2870 is
2871 Assoc : Node_Id;
2872 Choice : Node_Id;
2873 Val : Node_Id;
2874
2875 begin
2876 -- The aggregate has been normalized and all associations have a
2877 -- single choice.
2878
2879 Assoc := First (Component_Associations (N));
2880 while Present (Assoc) loop
2881 Choice := First (Choices (Assoc));
7893514c 2882
aab45d22
AC
2883 if Chars (Choice) = Chars (D) then
2884 Val := Expression (Assoc);
2885 Remove (Assoc);
2886 return Val;
2887 end if;
2888
2889 Next (Assoc);
2890 end loop;
2891
2892 return Empty;
2893 end Get_Explicit_Discriminant_Value;
2894
3e582869
AC
2895 -------------------------------
2896 -- Init_Hidden_Discriminants --
2897 -------------------------------
2898
2899 procedure Init_Hidden_Discriminants (Typ : Entity_Id; List : List_Id) is
a25e72b5
AC
2900 function Is_Completely_Hidden_Discriminant
2901 (Discr : Entity_Id) return Boolean;
2902 -- Determine whether Discr is a completely hidden discriminant of
2903 -- type Typ.
2904
2905 ---------------------------------------
2906 -- Is_Completely_Hidden_Discriminant --
2907 ---------------------------------------
2908
2909 function Is_Completely_Hidden_Discriminant
2910 (Discr : Entity_Id) return Boolean
2911 is
2912 Item : Entity_Id;
2913
2914 begin
2915 -- Use First/Next_Entity as First/Next_Discriminant do not yield
2916 -- completely hidden discriminants.
2917
2918 Item := First_Entity (Typ);
2919 while Present (Item) loop
2920 if Ekind (Item) = E_Discriminant
2921 and then Is_Completely_Hidden (Item)
2922 and then Chars (Original_Record_Component (Item)) =
2923 Chars (Discr)
2924 then
2925 return True;
2926 end if;
2927
2928 Next_Entity (Item);
2929 end loop;
2930
2931 return False;
2932 end Is_Completely_Hidden_Discriminant;
2933
2934 -- Local variables
2935
2936 Base_Typ : Entity_Id;
2937 Discr : Entity_Id;
2938 Discr_Constr : Elmt_Id;
2939 Discr_Init : Node_Id;
2940 Discr_Val : Node_Id;
ddce04b8 2941 In_Aggr_Type : Boolean;
a25e72b5
AC
2942 Par_Typ : Entity_Id;
2943
2944 -- Start of processing for Init_Hidden_Discriminants
3e582869
AC
2945
2946 begin
7b536495
AC
2947 -- The constraints on the hidden discriminants, if present, are kept
2948 -- in the Stored_Constraint list of the type itself, or in that of
ddce04b8
AC
2949 -- the base type. If not in the constraints of the aggregate itself,
2950 -- we examine ancestors to find discriminants that are not renamed
2951 -- by other discriminants but constrained explicitly.
2952
2953 In_Aggr_Type := True;
2feb1f84 2954
a25e72b5
AC
2955 Base_Typ := Base_Type (Typ);
2956 while Is_Derived_Type (Base_Typ)
596f7139 2957 and then
a25e72b5 2958 (Present (Stored_Constraint (Base_Typ))
596f7139
AC
2959 or else
2960 (In_Aggr_Type and then Present (Stored_Constraint (Typ))))
3e582869 2961 loop
a25e72b5 2962 Par_Typ := Etype (Base_Typ);
7b536495 2963
a25e72b5 2964 if not Has_Discriminants (Par_Typ) then
2feb1f84
AC
2965 return;
2966 end if;
3e582869 2967
a25e72b5 2968 Discr := First_Discriminant (Par_Typ);
2feb1f84 2969
bdc193ba 2970 -- We know that one of the stored-constraint lists is present
2feb1f84 2971
a25e72b5
AC
2972 if Present (Stored_Constraint (Base_Typ)) then
2973 Discr_Constr := First_Elmt (Stored_Constraint (Base_Typ));
bdc193ba
AC
2974
2975 -- For private extension, stored constraint may be on full view
2976
a25e72b5
AC
2977 elsif Is_Private_Type (Base_Typ)
2978 and then Present (Full_View (Base_Typ))
2979 and then Present (Stored_Constraint (Full_View (Base_Typ)))
bdc193ba 2980 then
a25e72b5
AC
2981 Discr_Constr :=
2982 First_Elmt (Stored_Constraint (Full_View (Base_Typ)));
bdc193ba 2983
f056076f
BD
2984 -- Otherwise, no discriminant to process
2985
2feb1f84 2986 else
f056076f 2987 Discr_Constr := No_Elmt;
2feb1f84
AC
2988 end if;
2989
a25e72b5
AC
2990 while Present (Discr) and then Present (Discr_Constr) loop
2991 Discr_Val := Node (Discr_Constr);
2992
2993 -- The parent discriminant is renamed in the derived type,
2994 -- nothing to initialize.
3e582869 2995
a25e72b5
AC
2996 -- type Deriv_Typ (Discr : ...)
2997 -- is new Parent_Typ (Discr => Discr);
3e582869 2998
a25e72b5
AC
2999 if Is_Entity_Name (Discr_Val)
3000 and then Ekind (Entity (Discr_Val)) = E_Discriminant
3e582869 3001 then
a25e72b5
AC
3002 null;
3003
3004 -- When the parent discriminant is constrained at the type
3005 -- extension level, it does not appear in the derived type.
3006
3007 -- type Deriv_Typ (Discr : ...)
3008 -- is new Parent_Typ (Discr => Discr,
3009 -- Hidden_Discr => Expression);
3e582869 3010
a25e72b5
AC
3011 elsif Is_Completely_Hidden_Discriminant (Discr) then
3012 null;
3013
3014 -- Otherwise initialize the discriminant
3015
3016 else
3017 Discr_Init :=
3e582869 3018 Make_OK_Assignment_Statement (Loc,
a25e72b5
AC
3019 Name =>
3020 Make_Selected_Component (Loc,
3021 Prefix => New_Copy_Tree (Target),
3022 Selector_Name => New_Occurrence_Of (Discr, Loc)),
3023 Expression => New_Copy_Tree (Discr_Val));
3e582869 3024
a25e72b5 3025 Append_To (List, Discr_Init);
3e582869
AC
3026 end if;
3027
a25e72b5
AC
3028 Next_Elmt (Discr_Constr);
3029 Next_Discriminant (Discr);
3e582869
AC
3030 end loop;
3031
ddce04b8 3032 In_Aggr_Type := False;
a25e72b5 3033 Base_Typ := Base_Type (Par_Typ);
3e582869
AC
3034 end loop;
3035 end Init_Hidden_Discriminants;
3036
71129dde
AC
3037 --------------------------------
3038 -- Init_Visible_Discriminants --
3039 --------------------------------
3040
3041 procedure Init_Visible_Discriminants is
3042 Discriminant : Entity_Id;
3043 Discriminant_Value : Node_Id;
3044
3045 begin
3046 Discriminant := First_Discriminant (Typ);
3047 while Present (Discriminant) loop
3048 Comp_Expr :=
3049 Make_Selected_Component (Loc,
3050 Prefix => New_Copy_Tree (Target),
3051 Selector_Name => New_Occurrence_Of (Discriminant, Loc));
3052
3053 Discriminant_Value :=
3054 Get_Discriminant_Value
3055 (Discriminant, Typ, Discriminant_Constraint (N_Typ));
3056
3057 Instr :=
3058 Make_OK_Assignment_Statement (Loc,
3059 Name => Comp_Expr,
3060 Expression => New_Copy_Tree (Discriminant_Value));
3061
71129dde
AC
3062 Append_To (L, Instr);
3063
3064 Next_Discriminant (Discriminant);
3065 end loop;
3066 end Init_Visible_Discriminants;
3067
3068 -------------------------------
3069 -- Init_Stored_Discriminants --
3070 -------------------------------
3071
3072 procedure Init_Stored_Discriminants is
3073 Discriminant : Entity_Id;
3074 Discriminant_Value : Node_Id;
3075
3076 begin
3077 Discriminant := First_Stored_Discriminant (Typ);
3078 while Present (Discriminant) loop
3079 Comp_Expr :=
3080 Make_Selected_Component (Loc,
3081 Prefix => New_Copy_Tree (Target),
3082 Selector_Name => New_Occurrence_Of (Discriminant, Loc));
3083
3084 Discriminant_Value :=
3085 Get_Discriminant_Value
3086 (Discriminant, N_Typ, Discriminant_Constraint (N_Typ));
3087
3088 Instr :=
3089 Make_OK_Assignment_Statement (Loc,
3090 Name => Comp_Expr,
3091 Expression => New_Copy_Tree (Discriminant_Value));
3092
71129dde
AC
3093 Append_To (L, Instr);
3094
3095 Next_Stored_Discriminant (Discriminant);
3096 end loop;
3097 end Init_Stored_Discriminants;
3098
937e9676
AC
3099 --------------------------------------
3100 -- Initialize_Ctrl_Record_Component --
3101 --------------------------------------
d8f7b976 3102
937e9676
AC
3103 procedure Initialize_Ctrl_Record_Component
3104 (Rec_Comp : Node_Id;
3105 Comp_Typ : Entity_Id;
3106 Init_Expr : Node_Id;
3107 Stmts : List_Id)
3108 is
3109 Fin_Call : Node_Id;
3110 Hook_Clear : Node_Id;
d8f7b976 3111
937e9676
AC
3112 In_Place_Expansion : Boolean;
3113 -- Flag set when a nonlimited controlled function call requires
3114 -- in-place expansion.
0f95b178 3115
7b9d0d69 3116 begin
937e9676
AC
3117 -- Perform a preliminary analysis and resolution to determine what
3118 -- the initialization expression denotes. Unanalyzed function calls
3119 -- may appear as identifiers or indexed components.
3120
4a08c95c
AC
3121 if Nkind (Init_Expr) in N_Function_Call
3122 | N_Identifier
3123 | N_Indexed_Component
937e9676
AC
3124 and then not Analyzed (Init_Expr)
3125 then
3126 Preanalyze_And_Resolve (Init_Expr, Comp_Typ);
5277cab6
ES
3127 end if;
3128
937e9676
AC
3129 In_Place_Expansion :=
3130 Nkind (Init_Expr) = N_Function_Call
02db8169 3131 and then not Is_Build_In_Place_Result_Type (Comp_Typ);
7b9d0d69 3132
937e9676
AC
3133 -- The initialization expression is a controlled function call.
3134 -- Perform in-place removal of side effects to avoid creating a
3135 -- transient scope.
7b9d0d69 3136
937e9676
AC
3137 -- This in-place expansion is not performed for limited transient
3138 -- objects because the initialization is already done in place.
df3e68b1 3139
937e9676
AC
3140 if In_Place_Expansion then
3141
3142 -- Suppress the removal of side effects by general analysis
3143 -- because this behavior is emulated here. This avoids the
3144 -- generation of a transient scope, which leads to out-of-order
3145 -- adjustment and finalization.
3146
3147 Set_No_Side_Effect_Removal (Init_Expr);
3148
3149 -- Install all hook-related declarations and prepare the clean up
02db8169
HK
3150 -- statements. The generated code follows the initialization order
3151 -- of individual components and discriminants, rather than being
3152 -- inserted prior to the aggregate. This ensures that a transient
3153 -- component which mentions a discriminant has proper visibility
3154 -- of the discriminant.
937e9676
AC
3155
3156 Process_Transient_Component
3157 (Loc => Loc,
3158 Comp_Typ => Comp_Typ,
3159 Init_Expr => Init_Expr,
3160 Fin_Call => Fin_Call,
3161 Hook_Clear => Hook_Clear,
02db8169 3162 Stmts => Stmts);
7b9d0d69 3163 end if;
7b9d0d69 3164
937e9676
AC
3165 -- Use the noncontrolled component initialization circuitry to
3166 -- assign the result of the function call to the record component.
3167 -- This also performs tag adjustment and [deep] adjustment of the
3168 -- record component.
3169
3170 Initialize_Record_Component
3171 (Rec_Comp => Rec_Comp,
3172 Comp_Typ => Comp_Typ,
3173 Init_Expr => Init_Expr,
3174 Stmts => Stmts);
3175
3176 -- At this point the record component is fully initialized. Complete
3177 -- the processing of the controlled record component by finalizing
3178 -- the transient function result.
3179
3180 if In_Place_Expansion then
3181 Process_Transient_Component_Completion
3182 (Loc => Loc,
3183 Aggr => N,
3184 Fin_Call => Fin_Call,
3185 Hook_Clear => Hook_Clear,
3186 Stmts => Stmts);
3187 end if;
3188 end Initialize_Ctrl_Record_Component;
f2abc637 3189
937e9676
AC
3190 ---------------------------------
3191 -- Initialize_Record_Component --
3192 ---------------------------------
0f95b178 3193
937e9676
AC
3194 procedure Initialize_Record_Component
3195 (Rec_Comp : Node_Id;
3196 Comp_Typ : Entity_Id;
3197 Init_Expr : Node_Id;
3198 Stmts : List_Id)
3199 is
bb072d1c
AC
3200 Exceptions_OK : constant Boolean :=
3201 not Restriction_Active (No_Exception_Propagation);
3202
3203 Finalization_OK : constant Boolean := Needs_Finalization (Comp_Typ);
3204
937e9676 3205 Full_Typ : constant Entity_Id := Underlying_Type (Comp_Typ);
2168d7cc 3206 Adj_Call : Node_Id;
bb072d1c 3207 Blk_Stmts : List_Id;
937e9676 3208 Init_Stmt : Node_Id;
f2abc637 3209
f2abc637 3210 begin
bb072d1c
AC
3211 -- Protect the initialization statements from aborts. Generate:
3212
3213 -- Abort_Defer;
3214
3215 if Finalization_OK and Abort_Allowed then
3216 if Exceptions_OK then
3217 Blk_Stmts := New_List;
3218 else
3219 Blk_Stmts := Stmts;
3220 end if;
3221
3222 Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
3223
3224 -- Otherwise aborts are not allowed. All generated code is added
3225 -- directly to the input list.
3226
3227 else
3228 Blk_Stmts := Stmts;
3229 end if;
3230
937e9676
AC
3231 -- Initialize the record component. Generate:
3232
3233 -- Rec_Comp := Init_Expr;
3234
3235 -- Note that the initialization expression is NOT replicated because
3236 -- only a single component may be initialized by it.
3237
3238 Init_Stmt :=
3239 Make_OK_Assignment_Statement (Loc,
3240 Name => New_Copy_Tree (Rec_Comp),
3241 Expression => Init_Expr);
3242 Set_No_Ctrl_Actions (Init_Stmt);
3243
bb072d1c 3244 Append_To (Blk_Stmts, Init_Stmt);
937e9676
AC
3245
3246 -- Adjust the tag due to a possible view conversion. Generate:
3247
3248 -- Rec_Comp._tag := Full_TypeP;
3249
3250 if Tagged_Type_Expansion and then Is_Tagged_Type (Comp_Typ) then
bb072d1c 3251 Append_To (Blk_Stmts,
937e9676
AC
3252 Make_OK_Assignment_Statement (Loc,
3253 Name =>
3254 Make_Selected_Component (Loc,
3255 Prefix => New_Copy_Tree (Rec_Comp),
3256 Selector_Name =>
3257 New_Occurrence_Of
3258 (First_Tag_Component (Full_Typ), Loc)),
3259
3260 Expression =>
3261 Unchecked_Convert_To (RTE (RE_Tag),
3262 New_Occurrence_Of
3263 (Node (First_Elmt (Access_Disp_Table (Full_Typ))),
3264 Loc))));
3265 end if;
3266
3267 -- Adjust the component. Generate:
3268
3269 -- [Deep_]Adjust (Rec_Comp);
3270
d4dfb005
BD
3271 if Finalization_OK
3272 and then not Is_Limited_Type (Comp_Typ)
3273 and then not Is_Build_In_Place_Function_Call (Init_Expr)
3274 then
2168d7cc 3275 Adj_Call :=
937e9676
AC
3276 Make_Adjust_Call
3277 (Obj_Ref => New_Copy_Tree (Rec_Comp),
2168d7cc
AC
3278 Typ => Comp_Typ);
3279
3280 -- Guard against a missing [Deep_]Adjust when the component type
3281 -- was not properly frozen.
3282
3283 if Present (Adj_Call) then
3284 Append_To (Blk_Stmts, Adj_Call);
3285 end if;
f2abc637 3286 end if;
bb072d1c
AC
3287
3288 -- Complete the protection of the initialization statements
3289
3290 if Finalization_OK and Abort_Allowed then
3291
3292 -- Wrap the initialization statements in a block to catch a
3293 -- potential exception. Generate:
3294
3295 -- begin
3296 -- Abort_Defer;
3297 -- Rec_Comp := Init_Expr;
3298 -- Rec_Comp._tag := Full_TypP;
3299 -- [Deep_]Adjust (Rec_Comp);
3300 -- at end
3301 -- Abort_Undefer_Direct;
3302 -- end;
3303
3304 if Exceptions_OK then
3305 Append_To (Stmts,
3306 Build_Abort_Undefer_Block (Loc,
3307 Stmts => Blk_Stmts,
3308 Context => N));
3309
3310 -- Otherwise exceptions are not propagated. Generate:
3311
3312 -- Abort_Defer;
3313 -- Rec_Comp := Init_Expr;
3314 -- Rec_Comp._tag := Full_TypP;
3315 -- [Deep_]Adjust (Rec_Comp);
3316 -- Abort_Undefer;
3317
3318 else
3319 Append_To (Blk_Stmts,
3320 Build_Runtime_Call (Loc, RE_Abort_Undefer));
3321 end if;
3322 end if;
937e9676 3323 end Initialize_Record_Component;
b3f5eef0 3324
937e9676
AC
3325 -------------------------
3326 -- Is_Int_Range_Bounds --
3327 -------------------------
3328
3329 function Is_Int_Range_Bounds (Bounds : Node_Id) return Boolean is
3330 begin
3331 return Nkind (Bounds) = N_Range
3332 and then Nkind (Low_Bound (Bounds)) = N_Integer_Literal
3333 and then Nkind (High_Bound (Bounds)) = N_Integer_Literal;
3334 end Is_Int_Range_Bounds;
f2abc637 3335
0f95b178
JM
3336 ------------------
3337 -- Replace_Type --
3338 ------------------
3339
3340 function Replace_Type (Expr : Node_Id) return Traverse_Result is
3341 begin
acf63f8c
ES
3342 -- Note regarding the Root_Type test below: Aggregate components for
3343 -- self-referential types include attribute references to the current
3344 -- instance, of the form: Typ'access, etc.. These references are
3345 -- rewritten as references to the target of the aggregate: the
3346 -- left-hand side of an assignment, the entity in a declaration,
3347 -- or a temporary. Without this test, we would improperly extended
3348 -- this rewriting to attribute references whose prefix was not the
3349 -- type of the aggregate.
3350
0f95b178 3351 if Nkind (Expr) = N_Attribute_Reference
acf63f8c 3352 and then Is_Entity_Name (Prefix (Expr))
0f95b178 3353 and then Is_Type (Entity (Prefix (Expr)))
acf63f8c 3354 and then Root_Type (Etype (N)) = Root_Type (Entity (Prefix (Expr)))
0f95b178
JM
3355 then
3356 if Is_Entity_Name (Lhs) then
304757d2 3357 Rewrite (Prefix (Expr), New_Occurrence_Of (Entity (Lhs), Loc));
0f95b178
JM
3358
3359 else
3360 Rewrite (Expr,
3361 Make_Attribute_Reference (Loc,
3362 Attribute_Name => Name_Unrestricted_Access,
3363 Prefix => New_Copy_Tree (Lhs)));
3364 Set_Analyzed (Parent (Expr), False);
3365 end if;
3366 end if;
3367
3368 return OK;
3369 end Replace_Type;
3370
937e9676
AC
3371 --------------------------
3372 -- Rewrite_Discriminant --
3373 --------------------------
3374
3375 function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result is
3376 begin
3377 if Is_Entity_Name (Expr)
3378 and then Present (Entity (Expr))
3379 and then Ekind (Entity (Expr)) = E_In_Parameter
3380 and then Present (Discriminal_Link (Entity (Expr)))
3381 and then Scope (Discriminal_Link (Entity (Expr))) =
3382 Base_Type (Etype (N))
3383 then
3384 Rewrite (Expr,
3385 Make_Selected_Component (Loc,
3386 Prefix => New_Copy_Tree (Lhs),
3387 Selector_Name => Make_Identifier (Loc, Chars (Expr))));
b8411279
ES
3388
3389 -- The generated code will be reanalyzed, but if the reference
3390 -- to the discriminant appears within an already analyzed
3391 -- expression (e.g. a conditional) we must set its proper entity
3392 -- now. Context is an initialization procedure.
3393
3394 Analyze (Expr);
937e9676
AC
3395 end if;
3396
3397 return OK;
3398 end Rewrite_Discriminant;
0f95b178 3399
f2abc637
AC
3400 procedure Replace_Discriminants is
3401 new Traverse_Proc (Rewrite_Discriminant);
3402
937e9676
AC
3403 procedure Replace_Self_Reference is
3404 new Traverse_Proc (Replace_Type);
3405
70482933
RK
3406 -- Start of processing for Build_Record_Aggr_Code
3407
3408 begin
0f95b178
JM
3409 if Has_Self_Reference (N) then
3410 Replace_Self_Reference (N);
3411 end if;
3412
3413 -- If the target of the aggregate is class-wide, we must convert it
3414 -- to the actual type of the aggregate, so that the proper components
3415 -- are visible. We know already that the types are compatible.
3416
3417 if Present (Etype (Lhs))
26a43556 3418 and then Is_Class_Wide_Type (Etype (Lhs))
0f95b178
JM
3419 then
3420 Target := Unchecked_Convert_To (Typ, Lhs);
3421 else
3422 Target := Lhs;
3423 end if;
3424
3b9fa2df
ES
3425 -- Deal with the ancestor part of extension aggregates or with the
3426 -- discriminants of the root type.
70482933
RK
3427
3428 if Nkind (N) = N_Extension_Aggregate then
3429 declare
df3e68b1 3430 Ancestor : constant Node_Id := Ancestor_Part (N);
2168d7cc 3431 Adj_Call : Node_Id;
df3e68b1 3432 Assign : List_Id;
70482933
RK
3433
3434 begin
70482933 3435 -- If the ancestor part is a subtype mark "T", we generate
fbf5a39b 3436
df3e68b1
HK
3437 -- init-proc (T (tmp)); if T is constrained and
3438 -- init-proc (S (tmp)); where S applies an appropriate
3439 -- constraint if T is unconstrained
70482933 3440
df3e68b1
HK
3441 if Is_Entity_Name (Ancestor)
3442 and then Is_Type (Entity (Ancestor))
3443 then
70482933
RK
3444 Ancestor_Is_Subtype_Mark := True;
3445
df3e68b1
HK
3446 if Is_Constrained (Entity (Ancestor)) then
3447 Init_Typ := Entity (Ancestor);
70482933 3448
3b9fa2df
ES
3449 -- For an ancestor part given by an unconstrained type mark,
3450 -- create a subtype constrained by appropriate corresponding
3451 -- discriminant values coming from either associations of the
3452 -- aggregate or a constraint on a parent type. The subtype will
3453 -- be used to generate the correct default value for the
3454 -- ancestor part.
70482933 3455
df3e68b1 3456 elsif Has_Discriminants (Entity (Ancestor)) then
70482933 3457 declare
df3e68b1 3458 Anc_Typ : constant Entity_Id := Entity (Ancestor);
fbf5a39b
AC
3459 Anc_Constr : constant List_Id := New_List;
3460 Discrim : Entity_Id;
70482933
RK
3461 Disc_Value : Node_Id;
3462 New_Indic : Node_Id;
3463 Subt_Decl : Node_Id;
fbf5a39b 3464
70482933 3465 begin
fbf5a39b 3466 Discrim := First_Discriminant (Anc_Typ);
70482933
RK
3467 while Present (Discrim) loop
3468 Disc_Value := Ancestor_Discriminant_Value (Discrim);
aab45d22
AC
3469
3470 -- If no usable discriminant in ancestors, check
3471 -- whether aggregate has an explicit value for it.
3472
3473 if No (Disc_Value) then
3474 Disc_Value :=
3475 Get_Explicit_Discriminant_Value (Discrim);
3476 end if;
3477
70482933
RK
3478 Append_To (Anc_Constr, Disc_Value);
3479 Next_Discriminant (Discrim);
3480 end loop;
3481
3482 New_Indic :=
3483 Make_Subtype_Indication (Loc,
3484 Subtype_Mark => New_Occurrence_Of (Anc_Typ, Loc),
3485 Constraint =>
3486 Make_Index_Or_Discriminant_Constraint (Loc,
3487 Constraints => Anc_Constr));
3488
3489 Init_Typ := Create_Itype (Ekind (Anc_Typ), N);
3490
3491 Subt_Decl :=
3492 Make_Subtype_Declaration (Loc,
3493 Defining_Identifier => Init_Typ,
3494 Subtype_Indication => New_Indic);
3495
3b9fa2df
ES
3496 -- Itypes must be analyzed with checks off Declaration
3497 -- must have a parent for proper handling of subsidiary
3498 -- actions.
70482933 3499
07fc65c4 3500 Set_Parent (Subt_Decl, N);
70482933
RK
3501 Analyze (Subt_Decl, Suppress => All_Checks);
3502 end;
3503 end if;
3504
3505 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
3506 Set_Assignment_OK (Ref);
3507
64425dff 3508 if not Is_Interface (Init_Typ) then
3bb3f6d6
AC
3509 Append_List_To (L,
3510 Build_Initialization_Call (Loc,
3511 Id_Ref => Ref,
3512 Typ => Init_Typ,
3513 In_Init_Proc => Within_Init_Proc,
3514 With_Default_Init => Has_Default_Init_Comps (N)
3515 or else
3516 Has_Task (Base_Type (Init_Typ))));
3517
df3e68b1
HK
3518 if Is_Constrained (Entity (Ancestor))
3519 and then Has_Discriminants (Entity (Ancestor))
3bb3f6d6 3520 then
df3e68b1 3521 Check_Ancestor_Discriminants (Entity (Ancestor));
3bb3f6d6 3522 end if;
f7937111
GD
3523
3524 -- If ancestor type has Default_Initialization_Condition,
3525 -- add a DIC check after the ancestor object is initialized
3526 -- by default.
3527
3528 if Has_DIC (Entity (Ancestor))
3529 and then Present (DIC_Procedure (Entity (Ancestor)))
3530 then
3531 Append_To (L,
3532 Build_DIC_Call
3533 (Loc, New_Copy_Tree (Ref), Entity (Ancestor)));
3534 end if;
70482933
RK
3535 end if;
3536
11795185
JM
3537 -- Handle calls to C++ constructors
3538
df3e68b1
HK
3539 elsif Is_CPP_Constructor_Call (Ancestor) then
3540 Init_Typ := Etype (Ancestor);
11795185
JM
3541 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
3542 Set_Assignment_OK (Ref);
3543
3544 Append_List_To (L,
3545 Build_Initialization_Call (Loc,
3546 Id_Ref => Ref,
3547 Typ => Init_Typ,
3548 In_Init_Proc => Within_Init_Proc,
3549 With_Default_Init => Has_Default_Init_Comps (N),
df3e68b1 3550 Constructor_Ref => Ancestor));
11795185 3551
c5ee5ad2
BD
3552 -- Ada 2005 (AI-287): If the ancestor part is an aggregate of
3553 -- limited type, a recursive call expands the ancestor. Note that
3554 -- in the limited case, the ancestor part must be either a
d4dfb005
BD
3555 -- function call (possibly qualified) or aggregate (definitely
3556 -- qualified).
65356e64 3557
df3e68b1 3558 elsif Is_Limited_Type (Etype (Ancestor))
4a08c95c
AC
3559 and then Nkind (Unqualify (Ancestor)) in
3560 N_Aggregate | N_Extension_Aggregate
c5ee5ad2 3561 then
65356e64
AC
3562 Ancestor_Is_Expression := True;
3563
21d7ef70 3564 -- Set up finalization data for enclosing record, because
3b9fa2df
ES
3565 -- controlled subcomponents of the ancestor part will be
3566 -- attached to it.
3567
df3e68b1 3568 Generate_Finalization_Actions;
3b9fa2df 3569
7b9d0d69 3570 Append_List_To (L,
f7e6fc47
RD
3571 Build_Record_Aggr_Code
3572 (N => Unqualify (Ancestor),
3573 Typ => Etype (Unqualify (Ancestor)),
3574 Lhs => Target));
65356e64 3575
70482933 3576 -- If the ancestor part is an expression "E", we generate
3b9fa2df 3577
df3e68b1 3578 -- T (tmp) := E;
3b9fa2df 3579
c5ee5ad2
BD
3580 -- In Ada 2005, this includes the case of a (possibly qualified)
3581 -- limited function call. The assignment will turn into a
3b9fa2df 3582 -- build-in-place function call (for further details, see
c5ee5ad2 3583 -- Make_Build_In_Place_Call_In_Assignment).
70482933
RK
3584
3585 else
3586 Ancestor_Is_Expression := True;
df3e68b1 3587 Init_Typ := Etype (Ancestor);
70482933 3588
7b9d0d69
ES
3589 -- If the ancestor part is an aggregate, force its full
3590 -- expansion, which was delayed.
3591
4a08c95c
AC
3592 if Nkind (Unqualify (Ancestor)) in
3593 N_Aggregate | N_Extension_Aggregate
7b9d0d69 3594 then
df3e68b1
HK
3595 Set_Analyzed (Ancestor, False);
3596 Set_Analyzed (Expression (Ancestor), False);
7b9d0d69
ES
3597 end if;
3598
3599 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
3600 Set_Assignment_OK (Ref);
3601
376e7d14
AC
3602 -- Make the assignment without usual controlled actions, since
3603 -- we only want to Adjust afterwards, but not to Finalize
3604 -- beforehand. Add manual Adjust when necessary.
7b9d0d69
ES
3605
3606 Assign := New_List (
3607 Make_OK_Assignment_Statement (Loc,
3608 Name => Ref,
df3e68b1 3609 Expression => Ancestor));
7b9d0d69
ES
3610 Set_No_Ctrl_Actions (First (Assign));
3611
3612 -- Assign the tag now to make sure that the dispatching call in
535a8637
AC
3613 -- the subsequent deep_adjust works properly (unless
3614 -- Tagged_Type_Expansion where tags are implicit).
70482933 3615
1f110335 3616 if Tagged_Type_Expansion then
70482933
RK
3617 Instr :=
3618 Make_OK_Assignment_Statement (Loc,
ffcfb997 3619 Name =>
70482933 3620 Make_Selected_Component (Loc,
ffcfb997 3621 Prefix => New_Copy_Tree (Target),
a9d8907c 3622 Selector_Name =>
e4494292 3623 New_Occurrence_Of
a9d8907c 3624 (First_Tag_Component (Base_Type (Typ)), Loc)),
70482933
RK
3625
3626 Expression =>
3627 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 3628 New_Occurrence_Of
a9d8907c
JM
3629 (Node (First_Elmt
3630 (Access_Disp_Table (Base_Type (Typ)))),
3631 Loc)));
70482933
RK
3632
3633 Set_Assignment_OK (Name (Instr));
7b9d0d69 3634 Append_To (Assign, Instr);
0f95b178
JM
3635
3636 -- Ada 2005 (AI-251): If tagged type has progenitors we must
3637 -- also initialize tags of the secondary dispatch tables.
3638
ce2b6ba5 3639 if Has_Interfaces (Base_Type (Typ)) then
0f95b178 3640 Init_Secondary_Tags
ed323421
AC
3641 (Typ => Base_Type (Typ),
3642 Target => Target,
3643 Stmts_List => Assign,
fe683ef6 3644 Init_Tags_List => Assign);
0f95b178 3645 end if;
70482933
RK
3646 end if;
3647
7b9d0d69 3648 -- Call Adjust manually
70482933 3649
df3e68b1
HK
3650 if Needs_Finalization (Etype (Ancestor))
3651 and then not Is_Limited_Type (Etype (Ancestor))
d4dfb005 3652 and then not Is_Build_In_Place_Function_Call (Ancestor)
3b9fa2df 3653 then
2168d7cc 3654 Adj_Call :=
37368818
RD
3655 Make_Adjust_Call
3656 (Obj_Ref => New_Copy_Tree (Ref),
2168d7cc
AC
3657 Typ => Etype (Ancestor));
3658
3659 -- Guard against a missing [Deep_]Adjust when the ancestor
3660 -- type was not properly frozen.
3661
3662 if Present (Adj_Call) then
3663 Append_To (Assign, Adj_Call);
3664 end if;
70482933
RK
3665 end if;
3666
70482933 3667 Append_To (L,
7b9d0d69 3668 Make_Unsuppress_Block (Loc, Name_Discriminant_Check, Assign));
70482933
RK
3669
3670 if Has_Discriminants (Init_Typ) then
3671 Check_Ancestor_Discriminants (Init_Typ);
3672 end if;
3673 end if;
d4dfb005
BD
3674
3675 pragma Assert (Nkind (N) = N_Extension_Aggregate);
3676 pragma Assert
3677 (not (Ancestor_Is_Expression and Ancestor_Is_Subtype_Mark));
70482933
RK
3678 end;
3679
376e7d14
AC
3680 -- Generate assignments of hidden discriminants. If the base type is
3681 -- an unchecked union, the discriminants are unknown to the back-end
3682 -- and absent from a value of the type, so assignments for them are
3683 -- not emitted.
3e582869
AC
3684
3685 if Has_Discriminants (Typ)
3686 and then not Is_Unchecked_Union (Base_Type (Typ))
3687 then
3688 Init_Hidden_Discriminants (Typ, L);
3689 end if;
3690
fbf5a39b
AC
3691 -- Normal case (not an extension aggregate)
3692
70482933
RK
3693 else
3694 -- Generate the discriminant expressions, component by component.
3695 -- If the base type is an unchecked union, the discriminants are
3696 -- unknown to the back-end and absent from a value of the type, so
3697 -- assignments for them are not emitted.
3698
3699 if Has_Discriminants (Typ)
3700 and then not Is_Unchecked_Union (Base_Type (Typ))
3701 then
3e582869 3702 Init_Hidden_Discriminants (Typ, L);
d8f7b976
ES
3703
3704 -- Generate discriminant init values for the visible discriminants
70482933 3705
71129dde 3706 Init_Visible_Discriminants;
70482933 3707
71129dde
AC
3708 if Is_Derived_Type (N_Typ) then
3709 Init_Stored_Discriminants;
3710 end if;
70482933
RK
3711 end if;
3712 end if;
3713
28541488
JM
3714 -- For CPP types we generate an implicit call to the C++ default
3715 -- constructor to ensure the proper initialization of the _Tag
3716 -- component.
3717
36a66365 3718 if Is_CPP_Class (Root_Type (Typ)) and then CPP_Num_Prims (Typ) > 0 then
cefce34c 3719 Invoke_Constructor : declare
15f0f591 3720 CPP_Parent : constant Entity_Id := Enclosing_CPP_Parent (Typ);
cefce34c
JM
3721
3722 procedure Invoke_IC_Proc (T : Entity_Id);
3723 -- Recursive routine used to climb to parents. Required because
3724 -- parents must be initialized before descendants to ensure
3725 -- propagation of inherited C++ slots.
3726
3727 --------------------
3728 -- Invoke_IC_Proc --
3729 --------------------
3730
3731 procedure Invoke_IC_Proc (T : Entity_Id) is
3732 begin
3733 -- Avoid generating extra calls. Initialization required
3734 -- only for types defined from the level of derivation of
3735 -- type of the constructor and the type of the aggregate.
3736
3737 if T = CPP_Parent then
3738 return;
3739 end if;
3740
3741 Invoke_IC_Proc (Etype (T));
3742
3743 -- Generate call to the IC routine
3744
3745 if Present (CPP_Init_Proc (T)) then
3746 Append_To (L,
3747 Make_Procedure_Call_Statement (Loc,
ffcfb997 3748 Name => New_Occurrence_Of (CPP_Init_Proc (T), Loc)));
cefce34c
JM
3749 end if;
3750 end Invoke_IC_Proc;
3751
3752 -- Start of processing for Invoke_Constructor
3753
3754 begin
3755 -- Implicit invocation of the C++ constructor
3756
3757 if Nkind (N) = N_Aggregate then
3758 Append_To (L,
3759 Make_Procedure_Call_Statement (Loc,
37368818
RD
3760 Name =>
3761 New_Occurrence_Of (Base_Init_Proc (CPP_Parent), Loc),
cefce34c
JM
3762 Parameter_Associations => New_List (
3763 Unchecked_Convert_To (CPP_Parent,
3764 New_Copy_Tree (Lhs)))));
3765 end if;
3766
3767 Invoke_IC_Proc (Typ);
3768 end Invoke_Constructor;
28541488
JM
3769 end if;
3770
70482933
RK
3771 -- Generate the assignments, component by component
3772
3773 -- tmp.comp1 := Expr1_From_Aggr;
3774 -- tmp.comp2 := Expr2_From_Aggr;
3775 -- ....
3776
3777 Comp := First (Component_Associations (N));
3778 while Present (Comp) loop
b7e429ab 3779 Selector := Entity (First (Choices (Comp)));
70482933 3780
236fecbf
JM
3781 -- C++ constructors
3782
3783 if Is_CPP_Constructor_Call (Expression (Comp)) then
3784 Append_List_To (L,
3785 Build_Initialization_Call (Loc,
37368818
RD
3786 Id_Ref =>
3787 Make_Selected_Component (Loc,
3788 Prefix => New_Copy_Tree (Target),
3789 Selector_Name => New_Occurrence_Of (Selector, Loc)),
1c612f29
RD
3790 Typ => Etype (Selector),
3791 Enclos_Type => Typ,
236fecbf 3792 With_Default_Init => True,
1c612f29 3793 Constructor_Ref => Expression (Comp)));
236fecbf 3794
3b9fa2df 3795 -- Ada 2005 (AI-287): For each default-initialized component generate
52739835 3796 -- a call to the corresponding IP subprogram if available.
65356e64 3797
236fecbf 3798 elsif Box_Present (Comp)
52739835 3799 and then Has_Non_Null_Base_Init_Proc (Etype (Selector))
65356e64 3800 then
5277cab6 3801 if Ekind (Selector) /= E_Discriminant then
df3e68b1 3802 Generate_Finalization_Actions;
5277cab6
ES
3803 end if;
3804
0ab80019
AC
3805 -- Ada 2005 (AI-287): If the component type has tasks then
3806 -- generate the activation chain and master entities (except
3807 -- in case of an allocator because in that case these entities
3808 -- are generated by Build_Task_Allocate_Block_With_Init_Stmts).
c45b6ae0
AC
3809
3810 declare
91b1417d 3811 Ctype : constant Entity_Id := Etype (Selector);
1c612f29
RD
3812 Inside_Allocator : Boolean := False;
3813 P : Node_Id := Parent (N);
c45b6ae0
AC
3814
3815 begin
3816 if Is_Task_Type (Ctype) or else Has_Task (Ctype) then
3817 while Present (P) loop
3818 if Nkind (P) = N_Allocator then
3819 Inside_Allocator := True;
3820 exit;
3821 end if;
3822
3823 P := Parent (P);
3824 end loop;
3825
3826 if not Inside_Init_Proc and not Inside_Allocator then
3827 Build_Activation_Chain_Entity (N);
c45b6ae0
AC
3828 end if;
3829 end if;
3830 end;
3831
65356e64
AC
3832 Append_List_To (L,
3833 Build_Initialization_Call (Loc,
1c612f29
RD
3834 Id_Ref => Make_Selected_Component (Loc,
3835 Prefix => New_Copy_Tree (Target),
3836 Selector_Name =>
3837 New_Occurrence_Of (Selector, Loc)),
3838 Typ => Etype (Selector),
3839 Enclos_Type => Typ,
c45b6ae0 3840 With_Default_Init => True));
65356e64 3841
7b9d0d69 3842 -- Prepare for component assignment
fbf5a39b 3843
236fecbf 3844 elsif Ekind (Selector) /= E_Discriminant
70482933
RK
3845 or else Nkind (N) = N_Extension_Aggregate
3846 then
7b9d0d69 3847 -- All the discriminants have now been assigned
3b9fa2df 3848
7b9d0d69
ES
3849 -- This is now a good moment to initialize and attach all the
3850 -- controllers. Their position may depend on the discriminants.
3851
5277cab6 3852 if Ekind (Selector) /= E_Discriminant then
df3e68b1 3853 Generate_Finalization_Actions;
7b9d0d69
ES
3854 end if;
3855
38171f43 3856 Comp_Type := Underlying_Type (Etype (Selector));
70482933
RK
3857 Comp_Expr :=
3858 Make_Selected_Component (Loc,
3859 Prefix => New_Copy_Tree (Target),
3860 Selector_Name => New_Occurrence_Of (Selector, Loc));
3861
3862 if Nkind (Expression (Comp)) = N_Qualified_Expression then
3863 Expr_Q := Expression (Expression (Comp));
3864 else
3865 Expr_Q := Expression (Comp);
3866 end if;
3867
7b9d0d69
ES
3868 -- Now either create the assignment or generate the code for the
3869 -- inner aggregate top-down.
fbf5a39b 3870
70482933 3871 if Is_Delayed_Aggregate (Expr_Q) then
d8f7b976
ES
3872
3873 -- We have the following case of aggregate nesting inside
3874 -- an object declaration:
3875
3876 -- type Arr_Typ is array (Integer range <>) of ...;
3b9fa2df 3877
d8f7b976
ES
3878 -- type Rec_Typ (...) is record
3879 -- Obj_Arr_Typ : Arr_Typ (A .. B);
3880 -- end record;
3b9fa2df 3881
d8f7b976
ES
3882 -- Obj_Rec_Typ : Rec_Typ := (...,
3883 -- Obj_Arr_Typ => (X => (...), Y => (...)));
3884
3885 -- The length of the ranges of the aggregate and Obj_Add_Typ
3886 -- are equal (B - A = Y - X), but they do not coincide (X /=
3887 -- A and B /= Y). This case requires array sliding which is
3888 -- performed in the following manner:
3889
3890 -- subtype Arr_Sub is Arr_Typ (X .. Y);
3891 -- Temp : Arr_Sub;
3892 -- Temp (X) := (...);
3893 -- ...
3894 -- Temp (Y) := (...);
3895 -- Obj_Rec_Typ.Obj_Arr_Typ := Temp;
3896
5277cab6 3897 if Ekind (Comp_Type) = E_Array_Subtype
d8f7b976
ES
3898 and then Is_Int_Range_Bounds (Aggregate_Bounds (Expr_Q))
3899 and then Is_Int_Range_Bounds (First_Index (Comp_Type))
3900 and then not
5277cab6
ES
3901 Compatible_Int_Bounds
3902 (Agg_Bounds => Aggregate_Bounds (Expr_Q),
3903 Typ_Bounds => First_Index (Comp_Type))
d8f7b976 3904 then
5277cab6
ES
3905 -- Create the array subtype with bounds equal to those of
3906 -- the corresponding aggregate.
d8f7b976 3907
5277cab6 3908 declare
191fcb3a 3909 SubE : constant Entity_Id := Make_Temporary (Loc, 'T');
d8f7b976
ES
3910
3911 SubD : constant Node_Id :=
15f0f591
AC
3912 Make_Subtype_Declaration (Loc,
3913 Defining_Identifier => SubE,
3914 Subtype_Indication =>
3915 Make_Subtype_Indication (Loc,
3916 Subtype_Mark =>
e4494292 3917 New_Occurrence_Of (Etype (Comp_Type), Loc),
15f0f591
AC
3918 Constraint =>
3919 Make_Index_Or_Discriminant_Constraint
3920 (Loc,
3921 Constraints => New_List (
3922 New_Copy_Tree
3923 (Aggregate_Bounds (Expr_Q))))));
d8f7b976
ES
3924
3925 -- Create a temporary array of the above subtype which
3926 -- will be used to capture the aggregate assignments.
3927
faf387e1 3928 TmpE : constant Entity_Id := Make_Temporary (Loc, 'A', N);
d8f7b976
ES
3929
3930 TmpD : constant Node_Id :=
15f0f591
AC
3931 Make_Object_Declaration (Loc,
3932 Defining_Identifier => TmpE,
e4494292 3933 Object_Definition => New_Occurrence_Of (SubE, Loc));
d8f7b976
ES
3934
3935 begin
3936 Set_No_Initialization (TmpD);
3937 Append_To (L, SubD);
3938 Append_To (L, TmpD);
3939
5277cab6 3940 -- Expand aggregate into assignments to the temp array
d8f7b976
ES
3941
3942 Append_List_To (L,
3943 Late_Expansion (Expr_Q, Comp_Type,
e4494292 3944 New_Occurrence_Of (TmpE, Loc)));
d8f7b976
ES
3945
3946 -- Slide
3947
3948 Append_To (L,
3949 Make_Assignment_Statement (Loc,
3950 Name => New_Copy_Tree (Comp_Expr),
e4494292 3951 Expression => New_Occurrence_Of (TmpE, Loc)));
d8f7b976
ES
3952 end;
3953
3954 -- Normal case (sliding not required)
3955
3956 else
3957 Append_List_To (L,
df3e68b1 3958 Late_Expansion (Expr_Q, Comp_Type, Comp_Expr));
d8f7b976 3959 end if;
fbf5a39b 3960
5277cab6
ES
3961 -- Expr_Q is not delayed aggregate
3962
70482933 3963 else
f2abc637
AC
3964 if Has_Discriminants (Typ) then
3965 Replace_Discriminants (Expr_Q);
b3f5eef0
AC
3966
3967 -- If the component is an array type that depends on
3968 -- discriminants, and the expression is a single Others
3969 -- clause, create an explicit subtype for it because the
3970 -- backend has troubles recovering the actual bounds.
3971
3972 if Nkind (Expr_Q) = N_Aggregate
3973 and then Is_Array_Type (Comp_Type)
3974 and then Present (Component_Associations (Expr_Q))
3975 then
3976 declare
3977 Assoc : constant Node_Id :=
45ec05e1 3978 First (Component_Associations (Expr_Q));
b3f5eef0
AC
3979 Decl : Node_Id;
3980
3981 begin
45ec05e1 3982 if Nkind (First (Choices (Assoc))) = N_Others_Choice
b3f5eef0
AC
3983 then
3984 Decl :=
3985 Build_Actual_Subtype_Of_Component
3986 (Comp_Type, Comp_Expr);
3987
3988 -- If the component type does not in fact depend on
3989 -- discriminants, the subtype declaration is empty.
3990
3991 if Present (Decl) then
3992 Append_To (L, Decl);
3993 Set_Etype (Comp_Expr, Defining_Entity (Decl));
3994 end if;
3995 end if;
3996 end;
3997 end if;
f2abc637
AC
3998 end if;
3999
c63a2ad6 4000 if Modify_Tree_For_C
a1e1820b
AC
4001 and then Nkind (Expr_Q) = N_Aggregate
4002 and then Is_Array_Type (Etype (Expr_Q))
4003 and then Present (First_Index (Etype (Expr_Q)))
4004 then
4005 declare
0c5c46a9 4006 Expr_Q_Type : constant Entity_Id := Etype (Expr_Q);
a1e1820b
AC
4007 begin
4008 Append_List_To (L,
4009 Build_Array_Aggr_Code
4010 (N => Expr_Q,
4011 Ctype => Component_Type (Expr_Q_Type),
4012 Index => First_Index (Expr_Q_Type),
4013 Into => Comp_Expr,
937e9676
AC
4014 Scalar_Comp =>
4015 Is_Scalar_Type (Component_Type (Expr_Q_Type))));
a1e1820b
AC
4016 end;
4017
4018 else
937e9676
AC
4019 -- Handle an initialization expression of a controlled type
4020 -- in case it denotes a function call. In general such a
4021 -- scenario will produce a transient scope, but this will
4022 -- lead to wrong order of initialization, adjustment, and
4023 -- finalization in the context of aggregates.
4024
4025 -- Target.Comp := Ctrl_Func_Call;
4026
4027 -- begin -- scope
4028 -- Trans_Obj : ... := Ctrl_Func_Call; -- object
4029 -- Target.Comp := Trans_Obj;
4030 -- Finalize (Trans_Obj);
4031 -- end
4032 -- Target.Comp._tag := ...;
4033 -- Adjust (Target.Comp);
4034
4035 -- In the example above, the call to Finalize occurs too
4036 -- early and as a result it may leave the record component
4037 -- in a bad state. Finalization of the transient object
4038 -- should really happen after adjustment.
4039
4040 -- To avoid this scenario, perform in-place side-effect
4041 -- removal of the function call. This eliminates the
4042 -- transient property of the function result and ensures
4043 -- correct order of actions.
4044
4045 -- Res : ... := Ctrl_Func_Call;
4046 -- Target.Comp := Res;
4047 -- Target.Comp._tag := ...;
4048 -- Adjust (Target.Comp);
4049 -- Finalize (Res);
4050
4051 if Needs_Finalization (Comp_Type)
4052 and then Nkind (Expr_Q) /= N_Aggregate
4053 then
4054 Initialize_Ctrl_Record_Component
4055 (Rec_Comp => Comp_Expr,
4056 Comp_Typ => Etype (Selector),
4057 Init_Expr => Expr_Q,
4058 Stmts => L);
70482933 4059
937e9676 4060 -- Otherwise perform single component initialization
70482933 4061
937e9676
AC
4062 else
4063 Initialize_Record_Component
4064 (Rec_Comp => Comp_Expr,
4065 Comp_Typ => Etype (Selector),
4066 Init_Expr => Expr_Q,
4067 Stmts => L);
4068 end if;
70482933
RK
4069 end if;
4070 end if;
fbf5a39b 4071
37368818 4072 -- comment would be good here ???
fbf5a39b
AC
4073
4074 elsif Ekind (Selector) = E_Discriminant
4075 and then Nkind (N) /= N_Extension_Aggregate
4076 and then Nkind (Parent (N)) = N_Component_Association
4077 and then Is_Constrained (Typ)
4078 then
4079 -- We must check that the discriminant value imposed by the
4080 -- context is the same as the value given in the subaggregate,
4081 -- because after the expansion into assignments there is no
4082 -- record on which to perform a regular discriminant check.
4083
4084 declare
4085 D_Val : Elmt_Id;
4086 Disc : Entity_Id;
4087
4088 begin
4089 D_Val := First_Elmt (Discriminant_Constraint (Typ));
4090 Disc := First_Discriminant (Typ);
fbf5a39b
AC
4091 while Chars (Disc) /= Chars (Selector) loop
4092 Next_Discriminant (Disc);
4093 Next_Elmt (D_Val);
4094 end loop;
4095
4096 pragma Assert (Present (D_Val));
4097
0f95b178
JM
4098 -- This check cannot performed for components that are
4099 -- constrained by a current instance, because this is not a
4100 -- value that can be compared with the actual constraint.
4101
4102 if Nkind (Node (D_Val)) /= N_Attribute_Reference
4103 or else not Is_Entity_Name (Prefix (Node (D_Val)))
4104 or else not Is_Type (Entity (Prefix (Node (D_Val))))
4105 then
4106 Append_To (L,
4107 Make_Raise_Constraint_Error (Loc,
4108 Condition =>
4109 Make_Op_Ne (Loc,
37368818 4110 Left_Opnd => New_Copy_Tree (Node (D_Val)),
0f95b178 4111 Right_Opnd => Expression (Comp)),
37368818 4112 Reason => CE_Discriminant_Check_Failed));
0f95b178
JM
4113
4114 else
3b9fa2df
ES
4115 -- Find self-reference in previous discriminant assignment,
4116 -- and replace with proper expression.
0f95b178
JM
4117
4118 declare
4119 Ass : Node_Id;
4120
4121 begin
4122 Ass := First (L);
4123 while Present (Ass) loop
4124 if Nkind (Ass) = N_Assignment_Statement
4125 and then Nkind (Name (Ass)) = N_Selected_Component
4126 and then Chars (Selector_Name (Name (Ass))) =
36a66365 4127 Chars (Disc)
0f95b178
JM
4128 then
4129 Set_Expression
4130 (Ass, New_Copy_Tree (Expression (Comp)));
4131 exit;
4132 end if;
4133 Next (Ass);
4134 end loop;
4135 end;
4136 end if;
fbf5a39b 4137 end;
70482933
RK
4138 end if;
4139
f7937111
GD
4140 -- If the component association was specified with a box and the
4141 -- component type has a Default_Initial_Condition, then generate
4142 -- a call to the DIC procedure.
4143
4144 if Has_DIC (Etype (Selector))
4145 and then Was_Default_Init_Box_Association (Comp)
4146 and then Present (DIC_Procedure (Etype (Selector)))
4147 then
4148 Append_To (L,
4149 Build_DIC_Call (Loc,
4150 Make_Selected_Component (Loc,
4151 Prefix => New_Copy_Tree (Target),
4152 Selector_Name => New_Occurrence_Of (Selector, Loc)),
4153 Etype (Selector)));
4154 end if;
4155
70482933
RK
4156 Next (Comp);
4157 end loop;
4158
bdc193ba
AC
4159 -- If the type is tagged, the tag needs to be initialized (unless we
4160 -- are in VM-mode where tags are implicit). It is done late in the
4161 -- initialization process because in some cases, we call the init
4162 -- proc of an ancestor which will not leave out the right tag.
70482933
RK
4163
4164 if Ancestor_Is_Expression then
4165 null;
4166
28541488
JM
4167 -- For CPP types we generated a call to the C++ default constructor
4168 -- before the components have been initialized to ensure the proper
4169 -- initialization of the _Tag component (see above).
4170
4171 elsif Is_CPP_Class (Typ) then
4172 null;
4173
1f110335 4174 elsif Is_Tagged_Type (Typ) and then Tagged_Type_Expansion then
70482933
RK
4175 Instr :=
4176 Make_OK_Assignment_Statement (Loc,
4177 Name =>
4178 Make_Selected_Component (Loc,
c5ee5ad2 4179 Prefix => New_Copy_Tree (Target),
70482933 4180 Selector_Name =>
e4494292 4181 New_Occurrence_Of
a9d8907c 4182 (First_Tag_Component (Base_Type (Typ)), Loc)),
70482933
RK
4183
4184 Expression =>
4185 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 4186 New_Occurrence_Of
a9d8907c
JM
4187 (Node (First_Elmt (Access_Disp_Table (Base_Type (Typ)))),
4188 Loc)));
70482933
RK
4189
4190 Append_To (L, Instr);
c5ee5ad2 4191
bdc193ba 4192 -- Ada 2005 (AI-251): If the tagged type has been derived from an
c5ee5ad2
BD
4193 -- abstract interfaces we must also initialize the tags of the
4194 -- secondary dispatch tables.
4195
ce2b6ba5 4196 if Has_Interfaces (Base_Type (Typ)) then
c5ee5ad2 4197 Init_Secondary_Tags
ed323421
AC
4198 (Typ => Base_Type (Typ),
4199 Target => Target,
4200 Stmts_List => L,
fe683ef6 4201 Init_Tags_List => L);
c5ee5ad2 4202 end if;
70482933
RK
4203 end if;
4204
7b9d0d69
ES
4205 -- If the controllers have not been initialized yet (by lack of non-
4206 -- discriminant components), let's do it now.
70482933 4207
df3e68b1 4208 Generate_Finalization_Actions;
70482933 4209
7b9d0d69 4210 return L;
70482933
RK
4211 end Build_Record_Aggr_Code;
4212
4213 -------------------------------
4214 -- Convert_Aggr_In_Allocator --
4215 -------------------------------
4216
fa57ac97
ES
4217 procedure Convert_Aggr_In_Allocator
4218 (Alloc : Node_Id;
4219 Decl : Node_Id;
4220 Aggr : Node_Id)
4221 is
70482933
RK
4222 Loc : constant Source_Ptr := Sloc (Aggr);
4223 Typ : constant Entity_Id := Etype (Aggr);
4224 Temp : constant Entity_Id := Defining_Identifier (Decl);
fbf5a39b
AC
4225
4226 Occ : constant Node_Id :=
15f0f591 4227 Unchecked_Convert_To (Typ,
e4494292 4228 Make_Explicit_Dereference (Loc, New_Occurrence_Of (Temp, Loc)));
70482933 4229
70482933 4230 begin
6f639c98
ES
4231 if Is_Array_Type (Typ) then
4232 Convert_Array_Aggr_In_Allocator (Decl, Aggr, Occ);
4233
4234 elsif Has_Default_Init_Comps (Aggr) then
c45b6ae0
AC
4235 declare
4236 L : constant List_Id := New_List;
4237 Init_Stmts : List_Id;
4238
4239 begin
df3e68b1 4240 Init_Stmts := Late_Expansion (Aggr, Typ, Occ);
c45b6ae0 4241
0f95b178
JM
4242 if Has_Task (Typ) then
4243 Build_Task_Allocate_Block_With_Init_Stmts (L, Aggr, Init_Stmts);
fa57ac97 4244 Insert_Actions (Alloc, L);
0f95b178 4245 else
fa57ac97 4246 Insert_Actions (Alloc, Init_Stmts);
0f95b178 4247 end if;
c45b6ae0
AC
4248 end;
4249
4250 else
df3e68b1 4251 Insert_Actions (Alloc, Late_Expansion (Aggr, Typ, Occ));
c45b6ae0 4252 end if;
70482933
RK
4253 end Convert_Aggr_In_Allocator;
4254
4255 --------------------------------
4256 -- Convert_Aggr_In_Assignment --
4257 --------------------------------
4258
4259 procedure Convert_Aggr_In_Assignment (N : Node_Id) is
3b9fa2df
ES
4260 Aggr : Node_Id := Expression (N);
4261 Typ : constant Entity_Id := Etype (Aggr);
4262 Occ : constant Node_Id := New_Copy_Tree (Name (N));
70482933
RK
4263
4264 begin
4265 if Nkind (Aggr) = N_Qualified_Expression then
4266 Aggr := Expression (Aggr);
4267 end if;
4268
df3e68b1 4269 Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ));
70482933
RK
4270 end Convert_Aggr_In_Assignment;
4271
4272 ---------------------------------
4273 -- Convert_Aggr_In_Object_Decl --
4274 ---------------------------------
4275
4276 procedure Convert_Aggr_In_Object_Decl (N : Node_Id) is
4277 Obj : constant Entity_Id := Defining_Identifier (N);
fbf5a39b 4278 Aggr : Node_Id := Expression (N);
70482933
RK
4279 Loc : constant Source_Ptr := Sloc (Aggr);
4280 Typ : constant Entity_Id := Etype (Aggr);
4281 Occ : constant Node_Id := New_Occurrence_Of (Obj, Loc);
4282
fff7a6d9
AC
4283 Has_Transient_Scope : Boolean := False;
4284
fbf5a39b
AC
4285 function Discriminants_Ok return Boolean;
4286 -- If the object type is constrained, the discriminants in the
4287 -- aggregate must be checked against the discriminants of the subtype.
4288 -- This cannot be done using Apply_Discriminant_Checks because after
4289 -- expansion there is no aggregate left to check.
4290
4291 ----------------------
4292 -- Discriminants_Ok --
4293 ----------------------
4294
4295 function Discriminants_Ok return Boolean is
4296 Cond : Node_Id := Empty;
4297 Check : Node_Id;
4298 D : Entity_Id;
4299 Disc1 : Elmt_Id;
4300 Disc2 : Elmt_Id;
4301 Val1 : Node_Id;
4302 Val2 : Node_Id;
4303
4304 begin
4305 D := First_Discriminant (Typ);
4306 Disc1 := First_Elmt (Discriminant_Constraint (Typ));
4307 Disc2 := First_Elmt (Discriminant_Constraint (Etype (Obj)));
fbf5a39b
AC
4308 while Present (Disc1) and then Present (Disc2) loop
4309 Val1 := Node (Disc1);
4310 Val2 := Node (Disc2);
4311
4312 if not Is_OK_Static_Expression (Val1)
4313 or else not Is_OK_Static_Expression (Val2)
4314 then
4315 Check := Make_Op_Ne (Loc,
4316 Left_Opnd => Duplicate_Subexpr (Val1),
4317 Right_Opnd => Duplicate_Subexpr (Val2));
4318
4319 if No (Cond) then
4320 Cond := Check;
4321
4322 else
4323 Cond := Make_Or_Else (Loc,
4324 Left_Opnd => Cond,
4325 Right_Opnd => Check);
4326 end if;
4327
4328 elsif Expr_Value (Val1) /= Expr_Value (Val2) then
4329 Apply_Compile_Time_Constraint_Error (Aggr,
324ac540 4330 Msg => "incorrect value for discriminant&??",
fbf5a39b
AC
4331 Reason => CE_Discriminant_Check_Failed,
4332 Ent => D);
4333 return False;
4334 end if;
4335
4336 Next_Discriminant (D);
4337 Next_Elmt (Disc1);
4338 Next_Elmt (Disc2);
4339 end loop;
4340
d940c627 4341 -- If any discriminant constraint is nonstatic, emit a check
fbf5a39b
AC
4342
4343 if Present (Cond) then
4344 Insert_Action (N,
4345 Make_Raise_Constraint_Error (Loc,
4346 Condition => Cond,
ef1c0511 4347 Reason => CE_Discriminant_Check_Failed));
fbf5a39b
AC
4348 end if;
4349
4350 return True;
4351 end Discriminants_Ok;
4352
4353 -- Start of processing for Convert_Aggr_In_Object_Decl
4354
70482933
RK
4355 begin
4356 Set_Assignment_OK (Occ);
4357
4358 if Nkind (Aggr) = N_Qualified_Expression then
4359 Aggr := Expression (Aggr);
4360 end if;
4361
fbf5a39b
AC
4362 if Has_Discriminants (Typ)
4363 and then Typ /= Etype (Obj)
4364 and then Is_Constrained (Etype (Obj))
4365 and then not Discriminants_Ok
4366 then
4367 return;
4368 end if;
4369
0f95b178
JM
4370 -- If the context is an extended return statement, it has its own
4371 -- finalization machinery (i.e. works like a transient scope) and
4372 -- we do not want to create an additional one, because objects on
4373 -- the finalization list of the return must be moved to the caller's
4374 -- finalization list to complete the return.
4375
fff7a6d9 4376 -- Similarly if the aggregate is limited, it is built in place, and the
3b9fa2df
ES
4377 -- controlled components are not assigned to intermediate temporaries
4378 -- so there is no need for a transient scope in this case either.
4379
0f95b178
JM
4380 if Requires_Transient_Scope (Typ)
4381 and then Ekind (Current_Scope) /= E_Return_Statement
3b9fa2df 4382 and then not Is_Limited_Type (Typ)
0f95b178 4383 then
6560f851 4384 Establish_Transient_Scope (Aggr, Manage_Sec_Stack => False);
fff7a6d9 4385 Has_Transient_Scope := True;
6f5c2c4b 4386 end if;
02217452 4387
6f5c2c4b 4388 declare
fff7a6d9
AC
4389 Stmts : constant List_Id := Late_Expansion (Aggr, Typ, Occ);
4390 Stmt : Node_Id;
4391 Param : Node_Id;
4392
6f5c2c4b 4393 begin
fff7a6d9
AC
4394 -- If Obj is already frozen or if N is wrapped in a transient scope,
4395 -- Stmts do not need to be saved in Initialization_Statements since
4396 -- there is no freezing issue.
4397
4398 if Is_Frozen (Obj) or else Has_Transient_Scope then
4399 Insert_Actions_After (N, Stmts);
4400 else
4401 Stmt := Make_Compound_Statement (Sloc (N), Actions => Stmts);
4402 Insert_Action_After (N, Stmt);
4403
4404 -- Insert_Action_After may freeze Obj in which case we should
4405 -- remove the compound statement just created and simply insert
4406 -- Stmts after N.
4407
4408 if Is_Frozen (Obj) then
4409 Remove (Stmt);
4410 Insert_Actions_After (N, Stmts);
4411 else
4412 Set_Initialization_Statements (Obj, Stmt);
4413 end if;
4414 end if;
4415
4416 -- If Typ has controlled components and a call to a Slice_Assign
4417 -- procedure is part of the initialization statements, then we
4418 -- need to initialize the array component since Slice_Assign will
4419 -- need to adjust it.
4420
4421 if Has_Controlled_Component (Typ) then
4422 Stmt := First (Stmts);
4423
4424 while Present (Stmt) loop
4425 if Nkind (Stmt) = N_Procedure_Call_Statement
4426 and then Get_TSS_Name (Entity (Name (Stmt)))
4427 = TSS_Slice_Assign
4428 then
4429 Param := First (Parameter_Associations (Stmt));
4430 Insert_Actions
4431 (Stmt,
4432 Build_Initialization_Call
4433 (Sloc (N), New_Copy_Tree (Param), Etype (Param)));
4434 end if;
4435
4436 Next (Stmt);
4437 end loop;
4438 end if;
6f5c2c4b 4439 end;
6560f851 4440
70482933 4441 Set_No_Initialization (N);
a671959b
ES
4442
4443 -- After expansion the expression can be removed from the declaration
4444 -- except if the object is class-wide, in which case the aggregate
4445 -- provides the actual type.
4446
4447 if not Is_Class_Wide_Type (Etype (Obj)) then
4448 Set_Expression (N, Empty);
4449 end if;
4450
07fc65c4 4451 Initialize_Discriminants (N, Typ);
70482933
RK
4452 end Convert_Aggr_In_Object_Decl;
4453
6f639c98 4454 -------------------------------------
3b9fa2df 4455 -- Convert_Array_Aggr_In_Allocator --
6f639c98
ES
4456 -------------------------------------
4457
4458 procedure Convert_Array_Aggr_In_Allocator
4459 (Decl : Node_Id;
4460 Aggr : Node_Id;
4461 Target : Node_Id)
4462 is
6f639c98
ES
4463 Typ : constant Entity_Id := Etype (Aggr);
4464 Ctyp : constant Entity_Id := Component_Type (Typ);
2fedcc18
EB
4465 Aggr_Code : List_Id;
4466 New_Aggr : Node_Id;
6f639c98
ES
4467
4468 begin
2fedcc18
EB
4469 -- The target is an explicit dereference of the allocated object
4470
4471 -- If the assignment can be done directly by the back end, then
4472 -- reset Set_Expansion_Delayed and do not expand further.
4473
4474 if not CodePeer_Mode
4475 and then not Modify_Tree_For_C
4476 and then Aggr_Assignment_OK_For_Backend (Aggr)
4477 then
4478 New_Aggr := New_Copy_Tree (Aggr);
4479 Set_Expansion_Delayed (New_Aggr, False);
4480
4481 Aggr_Code :=
4482 New_List (
4483 Make_OK_Assignment_Statement (Sloc (New_Aggr),
4484 Name => Target,
4485 Expression => New_Aggr));
6f639c98 4486
2fedcc18
EB
4487 -- Or else, generate component assignments to it, as for an aggregate
4488 -- that appears on the right-hand side of an assignment statement.
4489
4490 else
4491 Aggr_Code :=
4492 Build_Array_Aggr_Code (Aggr,
4493 Ctype => Ctyp,
4494 Index => First_Index (Typ),
4495 Into => Target,
4496 Scalar_Comp => Is_Scalar_Type (Ctyp));
4497 end if;
6f639c98
ES
4498
4499 Insert_Actions_After (Decl, Aggr_Code);
4500 end Convert_Array_Aggr_In_Allocator;
4501
4ff5aa0c
AC
4502 ------------------------
4503 -- In_Place_Assign_OK --
4504 ------------------------
4505
a80b1eb7
EB
4506 function In_Place_Assign_OK
4507 (N : Node_Id;
4508 Target_Object : Entity_Id := Empty) return Boolean
4509 is
4ff5aa0c
AC
4510 Is_Array : constant Boolean := Is_Array_Type (Etype (N));
4511
a80b1eb7 4512 Aggr_In : Node_Id;
7c4f3267 4513 Aggr_Bounds : Range_Nodes;
a80b1eb7 4514 Obj_In : Node_Id;
7c4f3267 4515 Obj_Bounds : Range_Nodes;
a80b1eb7
EB
4516 Parent_Kind : Node_Kind;
4517 Parent_Node : Node_Id;
4ff5aa0c
AC
4518
4519 function Safe_Aggregate (Aggr : Node_Id) return Boolean;
4520 -- Check recursively that each component of a (sub)aggregate does not
4521 -- depend on the variable being assigned to.
4522
4523 function Safe_Component (Expr : Node_Id) return Boolean;
a80b1eb7
EB
4524 -- Verify that an expression cannot depend on the target being assigned
4525 -- to. Return true for compile-time known values, stand-alone objects,
4526 -- parameters passed by copy, calls to functions that return by copy,
4527 -- selected components thereof only if the aggregate's type is an array,
4528 -- indexed components and slices thereof only if the aggregate's type is
4529 -- a record, and simple expressions involving only these as operands.
4530 -- This is OK whatever the target because, for a component to overlap
4531 -- with the target, it must be either a direct reference to a component
4532 -- of the target, in which case there must be a matching selection or
4533 -- indexation or slicing, or an indirect reference to such a component,
4534 -- which is excluded by the above condition. Additionally, if the target
4535 -- is statically known, return true for arbitrarily nested selections,
4536 -- indexations or slicings, provided that their ultimate prefix is not
4537 -- the target itself.
4ff5aa0c
AC
4538
4539 --------------------
4540 -- Safe_Aggregate --
4541 --------------------
4542
4543 function Safe_Aggregate (Aggr : Node_Id) return Boolean is
4544 Expr : Node_Id;
4545
4546 begin
4547 if Nkind (Parent (Aggr)) = N_Iterated_Component_Association then
4548 return False;
4549 end if;
4550
4551 if Present (Expressions (Aggr)) then
4552 Expr := First (Expressions (Aggr));
4553 while Present (Expr) loop
4554 if Nkind (Expr) = N_Aggregate then
4555 if not Safe_Aggregate (Expr) then
4556 return False;
4557 end if;
4558
4559 elsif not Safe_Component (Expr) then
4560 return False;
4561 end if;
4562
4563 Next (Expr);
4564 end loop;
4565 end if;
4566
4567 if Present (Component_Associations (Aggr)) then
4568 Expr := First (Component_Associations (Aggr));
4569 while Present (Expr) loop
4570 if Nkind (Expression (Expr)) = N_Aggregate then
4571 if not Safe_Aggregate (Expression (Expr)) then
4572 return False;
4573 end if;
4574
bc1146e5
HK
4575 -- If association has a box, no way to determine yet whether
4576 -- default can be assigned in place.
4ff5aa0c
AC
4577
4578 elsif Box_Present (Expr) then
4579 return False;
4580
4581 elsif not Safe_Component (Expression (Expr)) then
4582 return False;
4583 end if;
4584
4585 Next (Expr);
4586 end loop;
4587 end if;
4588
4589 return True;
4590 end Safe_Aggregate;
4591
4592 --------------------
4593 -- Safe_Component --
4594 --------------------
4595
4596 function Safe_Component (Expr : Node_Id) return Boolean is
4597 Comp : Node_Id := Expr;
4598
a80b1eb7
EB
4599 function Check_Component (C : Node_Id; T_OK : Boolean) return Boolean;
4600 -- Do the recursive traversal, after copy. If T_OK is True, return
4601 -- True for a stand-alone object only if the target is statically
4602 -- known and distinct from the object. At the top level, we start
4603 -- with T_OK set to False and set it to True at a deeper level only
4604 -- if we cannot disambiguate the component here without statically
4605 -- knowing the target. Note that this is not optimal, we should do
4606 -- something along the lines of Denotes_Same_Prefix for that.
4ff5aa0c
AC
4607
4608 ---------------------
4609 -- Check_Component --
4610 ---------------------
4611
a80b1eb7
EB
4612 function Check_Component (C : Node_Id; T_OK : Boolean) return Boolean
4613 is
4614
4615 function SDO (E : Entity_Id) return Uint;
4616 -- Return the Scope Depth Of the enclosing dynamic scope of E
4617
4618 ---------
4619 -- SDO --
4620 ---------
4621
4622 function SDO (E : Entity_Id) return Uint is
4623 begin
4624 return Scope_Depth (Enclosing_Dynamic_Scope (E));
4625 end SDO;
4626
4627 -- Start of processing for Check_Component
4628
4ff5aa0c 4629 begin
a80b1eb7 4630 if Is_Overloaded (C) then
4ff5aa0c 4631 return False;
a80b1eb7
EB
4632
4633 elsif Compile_Time_Known_Value (C) then
4634 return True;
4ff5aa0c
AC
4635 end if;
4636
a80b1eb7
EB
4637 case Nkind (C) is
4638 when N_Attribute_Reference =>
4639 return Check_Component (Prefix (C), T_OK);
4640
4641 when N_Function_Call =>
4642 if Nkind (Name (C)) = N_Explicit_Dereference then
4643 return not Returns_By_Ref (Etype (Name (C)));
4644 else
4645 return not Returns_By_Ref (Entity (Name (C)));
4646 end if;
4647
4648 when N_Indexed_Component | N_Slice =>
4649 -- In a target record, these operations cannot determine
4650 -- alone a component so we can recurse whatever the target.
4651 return Check_Component (Prefix (C), T_OK or else Is_Array);
4652
4653 when N_Selected_Component =>
4654 -- In a target array, this operation cannot determine alone
4655 -- a component so we can recurse whatever the target.
4656 return
4657 Check_Component (Prefix (C), T_OK or else not Is_Array);
4658
4659 when N_Type_Conversion | N_Unchecked_Type_Conversion =>
4660 return Check_Component (Expression (C), T_OK);
4ff5aa0c 4661
a80b1eb7
EB
4662 when N_Binary_Op =>
4663 return Check_Component (Left_Opnd (C), T_OK)
4664 and then Check_Component (Right_Opnd (C), T_OK);
4ff5aa0c 4665
a80b1eb7
EB
4666 when N_Unary_Op =>
4667 return Check_Component (Right_Opnd (C), T_OK);
4ff5aa0c 4668
a80b1eb7
EB
4669 when others =>
4670 if Is_Entity_Name (C) and then Is_Object (Entity (C)) then
4671 -- Case of a formal parameter component. It's either
4672 -- trivial if passed by copy or very annoying if not,
4673 -- because in the latter case it's almost equivalent
4674 -- to a dereference, so the path-based disambiguation
4675 -- logic is totally off and we always need the target.
4ff5aa0c 4676
a80b1eb7
EB
4677 if Is_Formal (Entity (C)) then
4678
4679 -- If it is passed by copy, then this is safe
4680
4681 if Mechanism (Entity (C)) = By_Copy then
4682 return True;
4683
4684 -- Otherwise, this is safe if the target is present
4685 -- and is at least as deeply nested as the component.
4686
4687 else
4688 return Present (Target_Object)
4689 and then not Is_Formal (Target_Object)
4690 and then SDO (Target_Object) >= SDO (Entity (C));
4691 end if;
4692
4693 -- For a renamed object, recurse
4694
4695 elsif Present (Renamed_Object (Entity (C))) then
4696 return
4697 Check_Component (Renamed_Object (Entity (C)), T_OK);
4698
4699 -- If this is safe whatever the target, we are done
4700
4701 elsif not T_OK then
4702 return True;
4703
4704 -- If there is no target or the component is the target,
4705 -- this is not safe.
4706
4707 elsif No (Target_Object)
4708 or else Entity (C) = Target_Object
4709 then
4710 return False;
4711
4712 -- Case of a formal parameter target. This is safe if it
4713 -- is at most as deeply nested as the component.
4714
4715 elsif Is_Formal (Target_Object) then
4716 return SDO (Target_Object) <= SDO (Entity (C));
4717
4718 -- For distinct stand-alone objects, this is safe
4719
4720 else
4721 return True;
4722 end if;
4ff5aa0c 4723
a80b1eb7 4724 -- For anything else than an object, this is not safe
4ff5aa0c 4725
a80b1eb7
EB
4726 else
4727 return False;
4728 end if;
4729 end case;
4ff5aa0c
AC
4730 end Check_Component;
4731
4732 -- Start of processing for Safe_Component
4733
4734 begin
4735 -- If the component appears in an association that may correspond
4736 -- to more than one element, it is not analyzed before expansion
4737 -- into assignments, to avoid side effects. We analyze, but do not
4738 -- resolve the copy, to obtain sufficient entity information for
4739 -- the checks that follow. If component is overloaded we assume
4740 -- an unsafe function call.
4741
4742 if not Analyzed (Comp) then
4743 if Is_Overloaded (Expr) then
4744 return False;
4ff5aa0c
AC
4745
4746 elsif Nkind (Expr) = N_Allocator then
4747
4748 -- For now, too complex to analyze
4749
4750 return False;
4751
bc1146e5
HK
4752 elsif Nkind (Parent (Expr)) = N_Iterated_Component_Association then
4753
4754 -- Ditto for iterated component associations, which in general
4755 -- require an enclosing loop and involve nonstatic expressions.
4ff5aa0c
AC
4756
4757 return False;
4758 end if;
4759
4760 Comp := New_Copy_Tree (Expr);
4761 Set_Parent (Comp, Parent (Expr));
4762 Analyze (Comp);
4763 end if;
4764
4765 if Nkind (Comp) = N_Aggregate then
4766 return Safe_Aggregate (Comp);
4767 else
a80b1eb7 4768 return Check_Component (Comp, False);
4ff5aa0c
AC
4769 end if;
4770 end Safe_Component;
4771
4772 -- Start of processing for In_Place_Assign_OK
4773
4774 begin
e67df677 4775 -- By-copy semantic cannot be guaranteed for controlled objects
4ff5aa0c 4776
e67df677 4777 if Needs_Finalization (Etype (N)) then
4ff5aa0c 4778 return False;
a80b1eb7 4779 end if;
4ff5aa0c 4780
a80b1eb7
EB
4781 Parent_Node := Parent (N);
4782 Parent_Kind := Nkind (Parent_Node);
4ff5aa0c 4783
a80b1eb7
EB
4784 if Parent_Kind = N_Qualified_Expression then
4785 Parent_Node := Parent (Parent_Node);
4786 Parent_Kind := Nkind (Parent_Node);
4787 end if;
4ff5aa0c 4788
a80b1eb7
EB
4789 -- On assignment, sliding can take place, so we cannot do the
4790 -- assignment in place unless the bounds of the aggregate are
4791 -- statically equal to those of the target.
4ff5aa0c 4792
a80b1eb7
EB
4793 -- If the aggregate is given by an others choice, the bounds are
4794 -- derived from the left-hand side, and the assignment is safe if
4795 -- the expression is.
4ff5aa0c 4796
a80b1eb7
EB
4797 if Is_Array
4798 and then Present (Component_Associations (N))
4799 and then not Is_Others_Aggregate (N)
4800 then
4ff5aa0c
AC
4801 Aggr_In := First_Index (Etype (N));
4802
d0e9248d
EB
4803 -- Context is an assignment
4804
a80b1eb7
EB
4805 if Parent_Kind = N_Assignment_Statement then
4806 Obj_In := First_Index (Etype (Name (Parent_Node)));
4ff5aa0c 4807
d0e9248d
EB
4808 -- Context is an allocator. Check the bounds of the aggregate against
4809 -- those of the designated type, except in the case where the type is
4810 -- unconstrained (and then we can directly return true, see below).
4811
4812 else pragma Assert (Parent_Kind = N_Allocator);
4813 declare
4814 Desig_Typ : constant Entity_Id :=
4815 Designated_Type (Etype (Parent_Node));
4816 begin
4817 if not Is_Constrained (Desig_Typ) then
4818 return True;
4819 end if;
4ff5aa0c 4820
d0e9248d
EB
4821 Obj_In := First_Index (Desig_Typ);
4822 end;
4ff5aa0c
AC
4823 end if;
4824
4825 while Present (Aggr_In) loop
7c4f3267
BD
4826 Aggr_Bounds := Get_Index_Bounds (Aggr_In);
4827 Obj_Bounds := Get_Index_Bounds (Obj_In);
4ff5aa0c 4828
a80b1eb7
EB
4829 -- We require static bounds for the target and a static matching
4830 -- of low bound for the aggregate.
4831
7c4f3267
BD
4832 if not Compile_Time_Known_Value (Obj_Bounds.First)
4833 or else not Compile_Time_Known_Value (Obj_Bounds.Last)
4834 or else not Compile_Time_Known_Value (Aggr_Bounds.First)
4835 or else Expr_Value (Aggr_Bounds.First) /=
4836 Expr_Value (Obj_Bounds.First)
4ff5aa0c
AC
4837 then
4838 return False;
4839
4840 -- For an assignment statement we require static matching of
4841 -- bounds. Ditto for an allocator whose qualified expression
4842 -- is a constrained type. If the expression in the allocator
4843 -- is an unconstrained array, we accept an upper bound that
4844 -- is not static, to allow for nonstatic expressions of the
4845 -- base type. Clearly there are further possibilities (with
4846 -- diminishing returns) for safely building arrays in place
4847 -- here.
4848
a80b1eb7
EB
4849 elsif Parent_Kind = N_Assignment_Statement
4850 or else Is_Constrained (Etype (Parent_Node))
4ff5aa0c 4851 then
7c4f3267
BD
4852 if not Compile_Time_Known_Value (Aggr_Bounds.Last)
4853 or else Expr_Value (Aggr_Bounds.Last) /=
4854 Expr_Value (Obj_Bounds.Last)
4ff5aa0c
AC
4855 then
4856 return False;
4857 end if;
4858 end if;
4859
4860 Next_Index (Aggr_In);
4861 Next_Index (Obj_In);
4862 end loop;
4863 end if;
4864
a80b1eb7
EB
4865 -- Now check the component values themselves, except for an allocator
4866 -- for which the target is newly allocated memory.
4ff5aa0c 4867
a80b1eb7
EB
4868 if Parent_Kind = N_Allocator then
4869 return True;
4870 else
4871 return Safe_Aggregate (N);
4872 end if;
4ff5aa0c
AC
4873 end In_Place_Assign_OK;
4874
70482933
RK
4875 ----------------------------
4876 -- Convert_To_Assignments --
4877 ----------------------------
4878
4879 procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id) is
4880 Loc : constant Source_Ptr := Sloc (N);
39f346aa 4881 T : Entity_Id;
70482933
RK
4882 Temp : Entity_Id;
4883
f29afe5f 4884 Aggr_Code : List_Id;
fbf5a39b
AC
4885 Instr : Node_Id;
4886 Target_Expr : Node_Id;
4887 Parent_Kind : Node_Kind;
4888 Unc_Decl : Boolean := False;
4889 Parent_Node : Node_Id;
70482933
RK
4890
4891 begin
4a08c95c 4892 pragma Assert (Nkind (N) in N_Aggregate | N_Extension_Aggregate);
fa57ac97
ES
4893 pragma Assert (not Is_Static_Dispatch_Table_Aggregate (N));
4894 pragma Assert (Is_Record_Type (Typ));
4895
70482933
RK
4896 Parent_Node := Parent (N);
4897 Parent_Kind := Nkind (Parent_Node);
4898
4899 if Parent_Kind = N_Qualified_Expression then
d4dfb005 4900 -- Check if we are in an unconstrained declaration because in this
70482933 4901 -- case the current delayed expansion mechanism doesn't work when
d4dfb005 4902 -- the declared object size depends on the initializing expr.
70482933 4903
937e9676
AC
4904 Parent_Node := Parent (Parent_Node);
4905 Parent_Kind := Nkind (Parent_Node);
fbf5a39b 4906
937e9676
AC
4907 if Parent_Kind = N_Object_Declaration then
4908 Unc_Decl :=
4909 not Is_Entity_Name (Object_Definition (Parent_Node))
d4dfb005 4910 or else (Nkind (N) = N_Aggregate
3fc40cd7
PMR
4911 and then
4912 Has_Discriminants
4913 (Entity (Object_Definition (Parent_Node))))
937e9676
AC
4914 or else Is_Class_Wide_Type
4915 (Entity (Object_Definition (Parent_Node)));
4916 end if;
70482933
RK
4917 end if;
4918
3b9fa2df
ES
4919 -- Just set the Delay flag in the cases where the transformation will be
4920 -- done top down from above.
fbf5a39b 4921
f037632e 4922 if
fa57ac97 4923 -- Internal aggregate (transformed when expanding the parent)
0f95b178 4924
f037632e
BD
4925 Parent_Kind in
4926 N_Aggregate | N_Extension_Aggregate | N_Component_Association
0f95b178 4927
fa57ac97 4928 -- Allocator (see Convert_Aggr_In_Allocator)
70482933 4929
fa57ac97 4930 or else Parent_Kind = N_Allocator
0f95b178 4931
fa57ac97
ES
4932 -- Object declaration (see Convert_Aggr_In_Object_Decl)
4933
4934 or else (Parent_Kind = N_Object_Declaration and then not Unc_Decl)
4935
4936 -- Safe assignment (see Convert_Aggr_Assignments). So far only the
4937 -- assignments in init procs are taken into account.
4938
4939 or else (Parent_Kind = N_Assignment_Statement
4940 and then Inside_Init_Proc)
4941
bdc193ba
AC
4942 -- (Ada 2005) An inherently limited type in a return statement, which
4943 -- will be handled in a build-in-place fashion, and may be rewritten
4944 -- as an extended return and have its own finalization machinery.
4945 -- In the case of a simple return, the aggregate needs to be delayed
4946 -- until the scope for the return statement has been created, so
4947 -- that any finalization chain will be associated with that scope.
4948 -- For extended returns, we delay expansion to avoid the creation
4949 -- of an unwanted transient scope that could result in premature
a9bbfbd0 4950 -- finalization of the return object (which is built in place
bdc193ba 4951 -- within the caller's scope).
fa57ac97 4952
d4dfb005 4953 or else Is_Build_In_Place_Aggregate_Return (N)
70482933
RK
4954 then
4955 Set_Expansion_Delayed (N);
4956 return;
4957 end if;
4958
a9bbfbd0
AC
4959 -- Otherwise, if a transient scope is required, create it now. If we
4960 -- are within an initialization procedure do not create such, because
4961 -- the target of the assignment must not be declared within a local
4962 -- block, and because cleanup will take place on return from the
4963 -- initialization procedure.
937e9676 4964
a9bbfbd0
AC
4965 -- Should the condition be more restrictive ???
4966
4967 if Requires_Transient_Scope (Typ) and then not Inside_Init_Proc then
6560f851 4968 Establish_Transient_Scope (N, Manage_Sec_Stack => False);
70482933
RK
4969 end if;
4970
bc1146e5
HK
4971 -- If the aggregate is nonlimited, create a temporary, since aggregates
4972 -- have "by copy" semantics. If it is limited and context is an
4ff5aa0c
AC
4973 -- assignment, this is a subaggregate for an enclosing aggregate being
4974 -- expanded. It must be built in place, so use target of the current
4975 -- assignment.
70482933 4976
3b9fa2df 4977 if Is_Limited_Type (Typ)
e67df677 4978 and then Parent_Kind = N_Assignment_Statement
3b9fa2df 4979 then
e67df677
EB
4980 Target_Expr := New_Copy_Tree (Name (Parent_Node));
4981 Insert_Actions (Parent_Node,
df3e68b1 4982 Build_Record_Aggr_Code (N, Typ, Target_Expr));
e67df677 4983 Rewrite (Parent_Node, Make_Null_Statement (Loc));
70482933 4984
a80b1eb7
EB
4985 -- Do not declare a temporary to initialize an aggregate assigned to
4986 -- a target when in-place assignment is possible, i.e. preserving the
4ff5aa0c
AC
4987 -- by-copy semantic of aggregates. This avoids large stack usage and
4988 -- generates more efficient code.
e64ac631 4989
e67df677 4990 elsif Parent_Kind = N_Assignment_Statement
a80b1eb7 4991 and then In_Place_Assign_OK (N, Get_Base_Object (Name (Parent_Node)))
e64ac631 4992 then
e67df677
EB
4993 declare
4994 Lhs : constant Node_Id := Name (Parent_Node);
4995 begin
4996 -- Apply discriminant check if required
4997
4998 if Has_Discriminants (Etype (N)) then
4999 Apply_Discriminant_Check (N, Etype (Lhs), Lhs);
5000 end if;
5001
5002 -- The check just above may have replaced the aggregate with a CE
5003
4a08c95c 5004 if Nkind (N) in N_Aggregate | N_Extension_Aggregate then
e67df677
EB
5005 Target_Expr := New_Copy_Tree (Lhs);
5006 Insert_Actions (Parent_Node,
5007 Build_Record_Aggr_Code (N, Typ, Target_Expr));
5008 Rewrite (Parent_Node, Make_Null_Statement (Loc));
5009 end if;
5010 end;
e64ac631 5011
3b9fa2df 5012 else
faf387e1 5013 Temp := Make_Temporary (Loc, 'A', N);
70482933 5014
39f346aa
ES
5015 -- If the type inherits unknown discriminants, use the view with
5016 -- known discriminants if available.
5017
5018 if Has_Unknown_Discriminants (Typ)
36a66365 5019 and then Present (Underlying_Record_View (Typ))
39f346aa
ES
5020 then
5021 T := Underlying_Record_View (Typ);
5022 else
5023 T := Typ;
5024 end if;
5025
3b9fa2df
ES
5026 Instr :=
5027 Make_Object_Declaration (Loc,
5028 Defining_Identifier => Temp,
39f346aa 5029 Object_Definition => New_Occurrence_Of (T, Loc));
3b9fa2df
ES
5030
5031 Set_No_Initialization (Instr);
5032 Insert_Action (N, Instr);
39f346aa 5033 Initialize_Discriminants (Instr, T);
f29afe5f 5034
3b9fa2df 5035 Target_Expr := New_Occurrence_Of (Temp, Loc);
f29afe5f
AC
5036 Aggr_Code := Build_Record_Aggr_Code (N, T, Target_Expr);
5037
5038 -- Save the last assignment statement associated with the aggregate
5039 -- when building a controlled object. This reference is utilized by
5040 -- the finalization machinery when marking an object as successfully
5041 -- initialized.
5042
5043 if Needs_Finalization (T) then
5044 Set_Last_Aggregate_Assignment (Temp, Last (Aggr_Code));
5045 end if;
5046
5047 Insert_Actions (N, Aggr_Code);
3b9fa2df 5048 Rewrite (N, New_Occurrence_Of (Temp, Loc));
39f346aa 5049 Analyze_And_Resolve (N, T);
3b9fa2df 5050 end if;
70482933
RK
5051 end Convert_To_Assignments;
5052
07fc65c4
GB
5053 ---------------------------
5054 -- Convert_To_Positional --
5055 ---------------------------
5056
5057 procedure Convert_To_Positional
c42006e9
AC
5058 (N : Node_Id;
5059 Handle_Bit_Packed : Boolean := False)
07fc65c4 5060 is
c42006e9 5061 Typ : constant Entity_Id := Etype (N);
b748c3d1 5062 Dims : constant Nat := Number_Dimensions (Typ);
eaf6e63a 5063 Max_Others_Replicate : constant Nat := Max_Aggregate_Size (N);
07fc65c4 5064
0f95b178
JM
5065 Static_Components : Boolean := True;
5066
5067 procedure Check_Static_Components;
3b9fa2df
ES
5068 -- Check whether all components of the aggregate are compile-time known
5069 -- values, and can be passed as is to the back-end without further
5070 -- expansion.
0f95b178 5071
fbf5a39b 5072 function Flatten
b748c3d1
EB
5073 (N : Node_Id;
5074 Dims : Nat;
5075 Ix : Node_Id;
5076 Ixb : Node_Id) return Boolean;
c2ba82ad
EB
5077 -- Convert the aggregate into a purely positional form if possible after
5078 -- checking that the bounds of all dimensions are known to be static.
fbf5a39b 5079
b748c3d1
EB
5080 function Is_Flat (N : Node_Id; Dims : Nat) return Boolean;
5081 -- Return True if the aggregate N is flat (which is not trivial in the
5082 -- case of multidimensional aggregates).
fbf5a39b 5083
b748c3d1 5084 function Is_Static_Element (N : Node_Id; Dims : Nat) return Boolean;
f1e2bf65
EB
5085 -- Return True if N, an element of a component association list, i.e.
5086 -- N_Component_Association or N_Iterated_Component_Association, has a
5087 -- compile-time known value and can be passed as is to the back-end
5088 -- without further expansion.
5089 -- An Iterated_Component_Association is treated as nonstatic in most
5090 -- cases for now, so there are possibilities for optimization.
5091
0f95b178
JM
5092 -----------------------------
5093 -- Check_Static_Components --
5094 -----------------------------
5095
bdc193ba
AC
5096 -- Could use some comments in this body ???
5097
0f95b178 5098 procedure Check_Static_Components is
f1e2bf65
EB
5099 Assoc : Node_Id;
5100 Expr : Node_Id;
0f95b178
JM
5101
5102 begin
5103 Static_Components := True;
5104
5105 if Nkind (N) = N_String_Literal then
5106 null;
5107
5108 elsif Present (Expressions (N)) then
5109 Expr := First (Expressions (N));
5110 while Present (Expr) loop
5111 if Nkind (Expr) /= N_Aggregate
5112 or else not Compile_Time_Known_Aggregate (Expr)
5113 or else Expansion_Delayed (Expr)
5114 then
5115 Static_Components := False;
5116 exit;
5117 end if;
5118
5119 Next (Expr);
5120 end loop;
5121 end if;
5122
5123 if Nkind (N) = N_Aggregate
21d7ef70 5124 and then Present (Component_Associations (N))
0f95b178 5125 then
f1e2bf65
EB
5126 Assoc := First (Component_Associations (N));
5127 while Present (Assoc) loop
b748c3d1 5128 if not Is_Static_Element (Assoc, Dims) then
0f95b178
JM
5129 Static_Components := False;
5130 exit;
5131 end if;
5132
f1e2bf65 5133 Next (Assoc);
0f95b178
JM
5134 end loop;
5135 end if;
5136 end Check_Static_Components;
5137
fbf5a39b
AC
5138 -------------
5139 -- Flatten --
5140 -------------
5141
5142 function Flatten
b748c3d1
EB
5143 (N : Node_Id;
5144 Dims : Nat;
5145 Ix : Node_Id;
5146 Ixb : Node_Id) return Boolean
fbf5a39b
AC
5147 is
5148 Loc : constant Source_Ptr := Sloc (N);
5149 Blo : constant Node_Id := Type_Low_Bound (Etype (Ixb));
5150 Lo : constant Node_Id := Type_Low_Bound (Etype (Ix));
5151 Hi : constant Node_Id := Type_High_Bound (Etype (Ix));
fbf5a39b 5152
b748c3d1
EB
5153 function Cannot_Flatten_Next_Aggr (Expr : Node_Id) return Boolean;
5154 -- Return true if Expr is an aggregate for the next dimension that
5155 -- cannot be recursively flattened.
5156
5157 ------------------------------
5158 -- Cannot_Flatten_Next_Aggr --
5159 ------------------------------
5160
5161 function Cannot_Flatten_Next_Aggr (Expr : Node_Id) return Boolean is
5162 begin
5163 return Nkind (Expr) = N_Aggregate
5164 and then Present (Next_Index (Ix))
5165 and then not
5166 Flatten (Expr, Dims - 1, Next_Index (Ix), Next_Index (Ixb));
5167 end Cannot_Flatten_Next_Aggr;
5168
5169 -- Local variables
5170
5171 Lov : Uint;
5172 Hiv : Uint;
5173 Others_Present : Boolean;
5174
5175 -- Start of processing for Flatten
3f5a8fee 5176
6e937c1c 5177 begin
fbf5a39b
AC
5178 if Nkind (Original_Node (N)) = N_String_Literal then
5179 return True;
5180 end if;
07fc65c4 5181
0f95b178
JM
5182 if not Compile_Time_Known_Value (Lo)
5183 or else not Compile_Time_Known_Value (Hi)
5184 then
5185 return False;
5186 end if;
07fc65c4 5187
fbf5a39b
AC
5188 Lov := Expr_Value (Lo);
5189 Hiv := Expr_Value (Hi);
07fc65c4 5190
3f5a8fee
AC
5191 -- Check if there is an others choice
5192
b748c3d1
EB
5193 Others_Present := False;
5194
3f5a8fee
AC
5195 if Present (Component_Associations (N)) then
5196 declare
5197 Assoc : Node_Id;
5198 Choice : Node_Id;
5199
5200 begin
5201 Assoc := First (Component_Associations (N));
5202 while Present (Assoc) loop
9f8d1e5c
AC
5203
5204 -- If this is a box association, flattening is in general
5205 -- not possible because at this point we cannot tell if the
5206 -- default is static or even exists.
5207
5208 if Box_Present (Assoc) then
5209 return False;
00f45f30
AC
5210
5211 elsif Nkind (Assoc) = N_Iterated_Component_Association then
5212 return False;
9f8d1e5c
AC
5213 end if;
5214
00f45f30 5215 Choice := First (Choice_List (Assoc));
3f5a8fee
AC
5216
5217 while Present (Choice) loop
5218 if Nkind (Choice) = N_Others_Choice then
5219 Others_Present := True;
5220 end if;
5221
5222 Next (Choice);
5223 end loop;
5224
5225 Next (Assoc);
5226 end loop;
5227 end;
5228 end if;
5229
5230 -- If the low bound is not known at compile time and others is not
5231 -- present we can proceed since the bounds can be obtained from the
5232 -- aggregate.
5233
fbf5a39b 5234 if Hiv < Lov
36a66365 5235 or else (not Compile_Time_Known_Value (Blo) and then Others_Present)
fbf5a39b
AC
5236 then
5237 return False;
5238 end if;
07fc65c4 5239
3b9fa2df
ES
5240 -- Determine if set of alternatives is suitable for conversion and
5241 -- build an array containing the values in sequence.
07fc65c4 5242
fbf5a39b
AC
5243 declare
5244 Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
5245 of Node_Id := (others => Empty);
5246 -- The values in the aggregate sorted appropriately
07fc65c4 5247
fbf5a39b
AC
5248 Vlist : List_Id;
5249 -- Same data as Vals in list form
07fc65c4 5250
fbf5a39b
AC
5251 Rep_Count : Nat;
5252 -- Used to validate Max_Others_Replicate limit
07fc65c4 5253
841dd0f5 5254 Elmt : Node_Id;
b748c3d1 5255 Expr : Node_Id;
841dd0f5
AC
5256 Num : Int := UI_To_Int (Lov);
5257 Choice_Index : Int;
5258 Choice : Node_Id;
5259 Lo, Hi : Node_Id;
07fc65c4 5260
fbf5a39b
AC
5261 begin
5262 if Present (Expressions (N)) then
5263 Elmt := First (Expressions (N));
fbf5a39b 5264 while Present (Elmt) loop
b748c3d1
EB
5265 -- In the case of a multidimensional array, check that the
5266 -- aggregate can be recursively flattened.
5267
5268 if Cannot_Flatten_Next_Aggr (Elmt) then
fbf5a39b
AC
5269 return False;
5270 end if;
07fc65c4 5271
f537fc00 5272 -- Duplicate expression for each index it covers
1541ede1
ES
5273
5274 Vals (Num) := New_Copy_Tree (Elmt);
fbf5a39b 5275 Num := Num + 1;
07fc65c4 5276
fbf5a39b
AC
5277 Next (Elmt);
5278 end loop;
5279 end if;
07fc65c4 5280
fbf5a39b
AC
5281 if No (Component_Associations (N)) then
5282 return True;
5283 end if;
07fc65c4 5284
fbf5a39b 5285 Elmt := First (Component_Associations (N));
07fc65c4 5286
b748c3d1
EB
5287 Component_Loop : while Present (Elmt) loop
5288 Expr := Expression (Elmt);
5289
5290 -- In the case of a multidimensional array, check that the
5291 -- aggregate can be recursively flattened.
5292
5293 if Cannot_Flatten_Next_Aggr (Expr) then
fbf5a39b
AC
5294 return False;
5295 end if;
07fc65c4 5296
00f45f30 5297 Choice := First (Choice_List (Elmt));
fbf5a39b
AC
5298 Choice_Loop : while Present (Choice) loop
5299
5300 -- If we have an others choice, fill in the missing elements
5301 -- subject to the limit established by Max_Others_Replicate.
5302
5303 if Nkind (Choice) = N_Others_Choice then
5304 Rep_Count := 0;
5305
64a87aa5
EB
5306 -- If the expression involves a construct that generates
5307 -- a loop, we must generate individual assignments and
5308 -- no flattening is possible.
5309
b748c3d1 5310 if Nkind (Expr) = N_Quantified_Expression then
1f6237e3
ES
5311 return False;
5312 end if;
5313
fbf5a39b
AC
5314 for J in Vals'Range loop
5315 if No (Vals (J)) then
b748c3d1 5316 Vals (J) := New_Copy_Tree (Expr);
fbf5a39b
AC
5317 Rep_Count := Rep_Count + 1;
5318
5319 -- Check for maximum others replication. Note that
5320 -- we skip this test if either of the restrictions
b748c3d1 5321 -- No_Implicit_Loops or No_Elaboration_Code is
8926d369
AC
5322 -- active, if this is a preelaborable unit or
5323 -- a predefined unit, or if the unit must be
5324 -- placed in data memory. This also ensures that
d9819bbd
AC
5325 -- predefined units get the same level of constant
5326 -- folding in Ada 95 and Ada 2005, where their
5327 -- categorization has changed.
fbf5a39b
AC
5328
5329 declare
5330 P : constant Entity_Id :=
89beb653 5331 Cunit_Entity (Current_Sem_Unit);
fbf5a39b
AC
5332
5333 begin
f1e2bf65
EB
5334 -- Check if duplication is always OK and, if so,
5335 -- continue processing.
7f4c1903 5336
b748c3d1
EB
5337 if Restriction_Active (No_Implicit_Loops) then
5338 null;
5339
5340 -- If duplication is not always OK, continue
5341 -- only if either the element is static or is
5342 -- an aggregate (we already know it is OK).
5343
5344 elsif not Is_Static_Element (Elmt, Dims)
5345 and then Nkind (Expr) /= N_Aggregate
5346 then
5347 return False;
5348
5349 -- Check if duplication is OK for elaboration
5350 -- purposes and, if so, continue processing.
5351
5352 elsif Restriction_Active (No_Elaboration_Code)
d9819bbd
AC
5353 or else
5354 (Ekind (Current_Scope) = E_Package
b748c3d1
EB
5355 and then
5356 Static_Elaboration_Desired (Current_Scope))
fbf5a39b
AC
5357 or else Is_Preelaborated (P)
5358 or else (Ekind (P) = E_Package_Body
5359 and then
b748c3d1 5360 Is_Preelaborated (Spec_Entity (P)))
7f4c1903 5361 or else
8ab31c0c 5362 Is_Predefined_Unit (Get_Source_Unit (P))
fbf5a39b
AC
5363 then
5364 null;
6e937c1c 5365
b748c3d1
EB
5366 -- Otherwise, check that the replication count
5367 -- is not too high.
7f4c1903 5368
b748c3d1 5369 elsif Rep_Count > Max_Others_Replicate then
f1e2bf65 5370 return False;
fbf5a39b
AC
5371 end if;
5372 end;
5373 end if;
5374 end loop;
07fc65c4 5375
861e589e
ES
5376 if Rep_Count = 0
5377 and then Warn_On_Redundant_Constructs
5378 then
5379 Error_Msg_N ("there are no others?r?", Elmt);
5380 end if;
5381
fbf5a39b 5382 exit Component_Loop;
07fc65c4 5383
deeb1604 5384 -- Case of a subtype mark, identifier or expanded name
07fc65c4 5385
deeb1604 5386 elsif Is_Entity_Name (Choice)
fbf5a39b
AC
5387 and then Is_Type (Entity (Choice))
5388 then
5389 Lo := Type_Low_Bound (Etype (Choice));
5390 Hi := Type_High_Bound (Etype (Choice));
07fc65c4 5391
fbf5a39b 5392 -- Case of subtype indication
07fc65c4 5393
fbf5a39b
AC
5394 elsif Nkind (Choice) = N_Subtype_Indication then
5395 Lo := Low_Bound (Range_Expression (Constraint (Choice)));
5396 Hi := High_Bound (Range_Expression (Constraint (Choice)));
5397
5398 -- Case of a range
5399
5400 elsif Nkind (Choice) = N_Range then
5401 Lo := Low_Bound (Choice);
5402 Hi := High_Bound (Choice);
5403
5404 -- Normal subexpression case
5405
5406 else pragma Assert (Nkind (Choice) in N_Subexpr);
5407 if not Compile_Time_Known_Value (Choice) then
5408 return False;
5409
5410 else
841dd0f5 5411 Choice_Index := UI_To_Int (Expr_Value (Choice));
bdc193ba 5412
841dd0f5 5413 if Choice_Index in Vals'Range then
b748c3d1 5414 Vals (Choice_Index) := New_Copy_Tree (Expr);
841dd0f5
AC
5415 goto Continue;
5416
bdc193ba
AC
5417 -- Choice is statically out-of-range, will be
5418 -- rewritten to raise Constraint_Error.
841dd0f5 5419
bdc193ba 5420 else
841dd0f5
AC
5421 return False;
5422 end if;
07fc65c4 5423 end if;
fbf5a39b
AC
5424 end if;
5425
64425dff 5426 -- Range cases merge with Lo,Hi set
fbf5a39b
AC
5427
5428 if not Compile_Time_Known_Value (Lo)
5429 or else
5430 not Compile_Time_Known_Value (Hi)
5431 then
5432 return False;
bdc193ba 5433
fbf5a39b
AC
5434 else
5435 for J in UI_To_Int (Expr_Value (Lo)) ..
5436 UI_To_Int (Expr_Value (Hi))
5437 loop
b748c3d1 5438 Vals (J) := New_Copy_Tree (Expr);
fbf5a39b
AC
5439 end loop;
5440 end if;
07fc65c4 5441
fbf5a39b
AC
5442 <<Continue>>
5443 Next (Choice);
5444 end loop Choice_Loop;
07fc65c4 5445
fbf5a39b
AC
5446 Next (Elmt);
5447 end loop Component_Loop;
07fc65c4 5448
fbf5a39b 5449 -- If we get here the conversion is possible
07fc65c4 5450
fbf5a39b
AC
5451 Vlist := New_List;
5452 for J in Vals'Range loop
5453 Append (Vals (J), Vlist);
5454 end loop;
07fc65c4 5455
fbf5a39b
AC
5456 Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
5457 Set_Aggregate_Bounds (N, Aggregate_Bounds (Original_Node (N)));
5458 return True;
5459 end;
5460 end Flatten;
07fc65c4 5461
fbf5a39b
AC
5462 -------------
5463 -- Is_Flat --
5464 -------------
07fc65c4 5465
b748c3d1 5466 function Is_Flat (N : Node_Id; Dims : Nat) return Boolean is
fbf5a39b 5467 Elmt : Node_Id;
07fc65c4 5468
fbf5a39b
AC
5469 begin
5470 if Dims = 0 then
5471 return True;
07fc65c4 5472
fbf5a39b
AC
5473 elsif Nkind (N) = N_Aggregate then
5474 if Present (Component_Associations (N)) then
5475 return False;
07fc65c4 5476
fbf5a39b
AC
5477 else
5478 Elmt := First (Expressions (N));
fbf5a39b
AC
5479 while Present (Elmt) loop
5480 if not Is_Flat (Elmt, Dims - 1) then
5481 return False;
07fc65c4 5482 end if;
07fc65c4 5483
fbf5a39b
AC
5484 Next (Elmt);
5485 end loop;
07fc65c4 5486
fbf5a39b
AC
5487 return True;
5488 end if;
5489 else
5490 return True;
5491 end if;
5492 end Is_Flat;
07fc65c4 5493
f1e2bf65
EB
5494 -------------------------
5495 -- Is_Static_Element --
5496 -------------------------
5497
b748c3d1 5498 function Is_Static_Element (N : Node_Id; Dims : Nat) return Boolean is
f1e2bf65
EB
5499 Expr : constant Node_Id := Expression (N);
5500
5501 begin
b748c3d1 5502 -- In most cases the interesting expressions are unambiguously static
f1e2bf65 5503
b748c3d1 5504 if Compile_Time_Known_Value (Expr) then
f1e2bf65
EB
5505 return True;
5506
5507 elsif Nkind (N) = N_Iterated_Component_Association then
5508 return False;
5509
5510 elsif Nkind (Expr) = N_Aggregate
5511 and then Compile_Time_Known_Aggregate (Expr)
5512 and then not Expansion_Delayed (Expr)
5513 then
5514 return True;
5515
b748c3d1
EB
5516 -- However, one may write static expressions that are syntactically
5517 -- ambiguous, so preanalyze the expression before checking it again,
5518 -- but only at the innermost level for a multidimensional array.
5519
5520 elsif Dims = 1 then
5521 Preanalyze_And_Resolve (Expr, Component_Type (Typ));
5522 return Compile_Time_Known_Value (Expr);
5523
f1e2bf65
EB
5524 else
5525 return False;
5526 end if;
5527 end Is_Static_Element;
5528
fbf5a39b 5529 -- Start of processing for Convert_To_Positional
07fc65c4 5530
fbf5a39b 5531 begin
6031f544
AC
5532 -- Only convert to positional when generating C in case of an
5533 -- object declaration, this is the only case where aggregates are
5534 -- supported in C.
5535
9f51b855 5536 if Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
6031f544
AC
5537 return;
5538 end if;
5539
0ab80019 5540 -- Ada 2005 (AI-287): Do not convert in case of default initialized
c45b6ae0
AC
5541 -- components because in this case will need to call the corresponding
5542 -- IP procedure.
5543
5544 if Has_Default_Init_Comps (N) then
5545 return;
5546 end if;
5547
d7db3f4f
ES
5548 -- A subaggregate may have been flattened but is not known to be
5549 -- Compile_Time_Known. Set that flag in cases that cannot require
5550 -- elaboration code, so that the aggregate can be used as the
5551 -- initial value of a thread-local variable.
5552
b748c3d1 5553 if Is_Flat (N, Dims) then
2a1838cd
EB
5554 if Static_Array_Aggregate (N) then
5555 Set_Compile_Time_Known_Aggregate (N);
d7db3f4f
ES
5556 end if;
5557
fbf5a39b
AC
5558 return;
5559 end if;
5560
36a66365 5561 if Is_Bit_Packed_Array (Typ) and then not Handle_Bit_Packed then
fbf5a39b
AC
5562 return;
5563 end if;
07fc65c4 5564
3b9fa2df
ES
5565 -- Do not convert to positional if controlled components are involved
5566 -- since these require special processing
07fc65c4 5567
fbf5a39b
AC
5568 if Has_Controlled_Component (Typ) then
5569 return;
5570 end if;
07fc65c4 5571
0f95b178
JM
5572 Check_Static_Components;
5573
5574 -- If the size is known, or all the components are static, try to
5575 -- build a fully positional aggregate.
5576
21d7ef70 5577 -- The size of the type may not be known for an aggregate with
0f95b178
JM
5578 -- discriminated array components, but if the components are static
5579 -- it is still possible to verify statically that the length is
5580 -- compatible with the upper bound of the type, and therefore it is
5581 -- worth flattening such aggregates as well.
5582
eaf6e63a 5583 if Aggr_Size_OK (N)
b748c3d1
EB
5584 and then
5585 Flatten (N, Dims, First_Index (Typ), First_Index (Base_Type (Typ)))
643a0839 5586 then
0f95b178
JM
5587 if Static_Components then
5588 Set_Compile_Time_Known_Aggregate (N);
5589 Set_Expansion_Delayed (N, False);
5590 end if;
5591
07fc65c4 5592 Analyze_And_Resolve (N, Typ);
fbf5a39b 5593 end if;
d9819bbd 5594
d74716b3 5595 -- If Static_Elaboration_Desired has been specified, diagnose aggregates
e6807723
AC
5596 -- that will still require initialization code.
5597
d9819bbd
AC
5598 if (Ekind (Current_Scope) = E_Package
5599 and then Static_Elaboration_Desired (Current_Scope))
5600 and then Nkind (Parent (N)) = N_Object_Declaration
5601 then
5602 declare
5603 Expr : Node_Id;
5604
5605 begin
e6807723 5606 if Nkind (N) = N_Aggregate and then Present (Expressions (N)) then
d9819bbd
AC
5607 Expr := First (Expressions (N));
5608 while Present (Expr) loop
c2ba82ad 5609 if not Compile_Time_Known_Value (Expr) then
8926d369 5610 Error_Msg_N
21d7ef70 5611 ("non-static object requires elaboration code??", N);
d9819bbd
AC
5612 exit;
5613 end if;
8926d369 5614
d9819bbd
AC
5615 Next (Expr);
5616 end loop;
5617
5618 if Present (Component_Associations (N)) then
324ac540 5619 Error_Msg_N ("object requires elaboration code??", N);
d9819bbd
AC
5620 end if;
5621 end if;
5622 end;
5623 end if;
07fc65c4
GB
5624 end Convert_To_Positional;
5625
70482933
RK
5626 ----------------------------
5627 -- Expand_Array_Aggregate --
5628 ----------------------------
5629
5630 -- Array aggregate expansion proceeds as follows:
5631
5632 -- 1. If requested we generate code to perform all the array aggregate
5633 -- bound checks, specifically
5634
5635 -- (a) Check that the index range defined by aggregate bounds is
5636 -- compatible with corresponding index subtype.
5637
5638 -- (b) If an others choice is present check that no aggregate
5639 -- index is outside the bounds of the index constraint.
5640
5641 -- (c) For multidimensional arrays make sure that all subaggregates
5642 -- corresponding to the same dimension have the same bounds.
5643
fbf5a39b 5644 -- 2. Check for packed array aggregate which can be converted to a
b465ef6f 5645 -- constant so that the aggregate disappears completely.
fbf5a39b
AC
5646
5647 -- 3. Check case of nested aggregate. Generally nested aggregates are
5648 -- handled during the processing of the parent aggregate.
5649
5650 -- 4. Check if the aggregate can be statically processed. If this is the
70482933
RK
5651 -- case pass it as is to Gigi. Note that a necessary condition for
5652 -- static processing is that the aggregate be fully positional.
5653
bc1146e5 5654 -- 5. If in-place aggregate expansion is possible (i.e. no need to create
70482933
RK
5655 -- a temporary) then mark the aggregate as such and return. Otherwise
5656 -- create a new temporary and generate the appropriate initialization
5657 -- code.
5658
5659 procedure Expand_Array_Aggregate (N : Node_Id) is
5660 Loc : constant Source_Ptr := Sloc (N);
5661
5662 Typ : constant Entity_Id := Etype (N);
5663 Ctyp : constant Entity_Id := Component_Type (Typ);
07fc65c4 5664 -- Typ is the correct constrained array subtype of the aggregate
70482933
RK
5665 -- Ctyp is the corresponding component type.
5666
5667 Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
3cf3e5c6 5668 -- Number of aggregate index dimensions
70482933
RK
5669
5670 Aggr_Low : array (1 .. Aggr_Dimension) of Node_Id;
5671 Aggr_High : array (1 .. Aggr_Dimension) of Node_Id;
3cf3e5c6 5672 -- Low and High bounds of the constraint for each aggregate index
70482933
RK
5673
5674 Aggr_Index_Typ : array (1 .. Aggr_Dimension) of Entity_Id;
3cf3e5c6 5675 -- The type of each index
70482933 5676
ac43e11e 5677 In_Place_Assign_OK_For_Declaration : Boolean := False;
bc1146e5 5678 -- True if we are to generate an in-place assignment for a declaration
ac43e11e 5679
70482933
RK
5680 Maybe_In_Place_OK : Boolean;
5681 -- If the type is neither controlled nor packed and the aggregate
5682 -- is the expression in an assignment, assignment in place may be
5683 -- possible, provided other conditions are met on the LHS.
5684
07fc65c4 5685 Others_Present : array (1 .. Aggr_Dimension) of Boolean :=
15f0f591 5686 (others => False);
d74716b3
AC
5687 -- If Others_Present (J) is True, then there is an others choice in one
5688 -- of the subaggregates of N at dimension J.
70482933
RK
5689
5690 procedure Build_Constrained_Type (Positional : Boolean);
5691 -- If the subtype is not static or unconstrained, build a constrained
5692 -- type using the computable sizes of the aggregate and its sub-
5693 -- aggregates.
5694
7c4f3267 5695 procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id);
70482933
RK
5696 -- Checks that the bounds of Aggr_Bounds are within the bounds defined
5697 -- by Index_Bounds.
5698
5699 procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos);
d74716b3
AC
5700 -- Checks that in a multidimensional array aggregate all subaggregates
5701 -- corresponding to the same dimension have the same bounds. Sub_Aggr is
5702 -- an array subaggregate. Dim is the dimension corresponding to the
5703 -- subaggregate.
70482933
RK
5704
5705 procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos);
d74716b3
AC
5706 -- Computes the values of array Others_Present. Sub_Aggr is the array
5707 -- subaggregate we start the computation from. Dim is the dimension
5708 -- corresponding to the subaggregate.
70482933 5709
70482933 5710 procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
d74716b3 5711 -- Checks that if an others choice is present in any subaggregate, no
70482933 5712 -- aggregate index is outside the bounds of the index constraint.
d74716b3
AC
5713 -- Sub_Aggr is an array subaggregate. Dim is the dimension corresponding
5714 -- to the subaggregate.
70482933 5715
8da337c5
AC
5716 function Safe_Left_Hand_Side (N : Node_Id) return Boolean;
5717 -- In addition to Maybe_In_Place_OK, in order for an aggregate to be
5718 -- built directly into the target of the assignment it must be free
6537318f 5719 -- of side effects. N is the LHS of an assignment.
8da337c5 5720
70482933
RK
5721 ----------------------------
5722 -- Build_Constrained_Type --
5723 ----------------------------
5724
5725 procedure Build_Constrained_Type (Positional : Boolean) is
fbf5a39b 5726 Loc : constant Source_Ptr := Sloc (N);
191fcb3a 5727 Agg_Type : constant Entity_Id := Make_Temporary (Loc, 'A');
fbf5a39b
AC
5728 Comp : Node_Id;
5729 Decl : Node_Id;
5730 Typ : constant Entity_Id := Etype (N);
deeb1604 5731 Indexes : constant List_Id := New_List;
b3143037 5732 Num : Nat;
fbf5a39b 5733 Sub_Agg : Node_Id;
70482933
RK
5734
5735 begin
70482933
RK
5736 -- If the aggregate is purely positional, all its subaggregates
5737 -- have the same size. We collect the dimensions from the first
5738 -- subaggregate at each level.
5739
5740 if Positional then
5741 Sub_Agg := N;
5742
5743 for D in 1 .. Number_Dimensions (Typ) loop
5277cab6 5744 Sub_Agg := First (Expressions (Sub_Agg));
70482933 5745
5277cab6 5746 Comp := Sub_Agg;
70482933 5747 Num := 0;
70482933
RK
5748 while Present (Comp) loop
5749 Num := Num + 1;
5750 Next (Comp);
5751 end loop;
5752
deeb1604 5753 Append_To (Indexes,
70482933 5754 Make_Range (Loc,
37368818 5755 Low_Bound => Make_Integer_Literal (Loc, 1),
191fcb3a 5756 High_Bound => Make_Integer_Literal (Loc, Num)));
70482933
RK
5757 end loop;
5758
5759 else
3b9fa2df
ES
5760 -- We know the aggregate type is unconstrained and the aggregate
5761 -- is not processable by the back end, therefore not necessarily
5762 -- positional. Retrieve each dimension bounds (computed earlier).
70482933
RK
5763
5764 for D in 1 .. Number_Dimensions (Typ) loop
37368818 5765 Append_To (Indexes,
70482933 5766 Make_Range (Loc,
37368818
RD
5767 Low_Bound => Aggr_Low (D),
5768 High_Bound => Aggr_High (D)));
70482933
RK
5769 end loop;
5770 end if;
5771
5772 Decl :=
5773 Make_Full_Type_Declaration (Loc,
5774 Defining_Identifier => Agg_Type,
bdc193ba 5775 Type_Definition =>
70482933 5776 Make_Constrained_Array_Definition (Loc,
deeb1604
AC
5777 Discrete_Subtype_Definitions => Indexes,
5778 Component_Definition =>
a397db96 5779 Make_Component_Definition (Loc,
deeb1604 5780 Aliased_Present => False,
a397db96
AC
5781 Subtype_Indication =>
5782 New_Occurrence_Of (Component_Type (Typ), Loc))));
70482933
RK
5783
5784 Insert_Action (N, Decl);
5785 Analyze (Decl);
5786 Set_Etype (N, Agg_Type);
5787 Set_Is_Itype (Agg_Type);
5788 Freeze_Itype (Agg_Type, N);
5789 end Build_Constrained_Type;
5790
5791 ------------------
5792 -- Check_Bounds --
5793 ------------------
5794
7c4f3267
BD
5795 procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id) is
5796 Aggr_Bounds : constant Range_Nodes :=
5797 Get_Index_Bounds (Aggr_Bounds_Node);
5798 Ind_Bounds : constant Range_Nodes :=
5799 Get_Index_Bounds (Index_Bounds_Node);
70482933 5800
7c4f3267 5801 Cond : Node_Id := Empty;
70482933
RK
5802
5803 begin
70482933 5804 -- Generate the following test:
bdc193ba 5805
70482933 5806 -- [constraint_error when
7c4f3267
BD
5807 -- Aggr_Bounds.First <= Aggr_Bounds.Last and then
5808 -- (Aggr_Bounds.First < Ind_Bounds.First
5809 -- or else Aggr_Bounds.Last > Ind_Bounds.Last)]
3b9fa2df 5810
641d3093 5811 -- As an optimization try to see if some tests are trivially vacuous
70482933
RK
5812 -- because we are comparing an expression against itself.
5813
7c4f3267
BD
5814 if Aggr_Bounds.First = Ind_Bounds.First
5815 and then Aggr_Bounds.Last = Ind_Bounds.Last
5816 then
70482933
RK
5817 Cond := Empty;
5818
7c4f3267 5819 elsif Aggr_Bounds.Last = Ind_Bounds.Last then
70482933
RK
5820 Cond :=
5821 Make_Op_Lt (Loc,
7c4f3267
BD
5822 Left_Opnd =>
5823 Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
5824 Right_Opnd =>
5825 Duplicate_Subexpr_Move_Checks (Ind_Bounds.First));
70482933 5826
7c4f3267 5827 elsif Aggr_Bounds.First = Ind_Bounds.First then
70482933
RK
5828 Cond :=
5829 Make_Op_Gt (Loc,
7c4f3267
BD
5830 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Bounds.Last),
5831 Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Bounds.Last));
70482933
RK
5832
5833 else
5834 Cond :=
5835 Make_Or_Else (Loc,
5836 Left_Opnd =>
5837 Make_Op_Lt (Loc,
7c4f3267
BD
5838 Left_Opnd =>
5839 Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
5840 Right_Opnd =>
5841 Duplicate_Subexpr_Move_Checks (Ind_Bounds.First)),
70482933
RK
5842
5843 Right_Opnd =>
5844 Make_Op_Gt (Loc,
7c4f3267
BD
5845 Left_Opnd => Duplicate_Subexpr (Aggr_Bounds.Last),
5846 Right_Opnd => Duplicate_Subexpr (Ind_Bounds.Last)));
70482933
RK
5847 end if;
5848
5849 if Present (Cond) then
5850 Cond :=
5851 Make_And_Then (Loc,
5852 Left_Opnd =>
5853 Make_Op_Le (Loc,
7c4f3267
BD
5854 Left_Opnd =>
5855 Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
5856 Right_Opnd =>
5857 Duplicate_Subexpr_Move_Checks (Aggr_Bounds.Last)),
70482933
RK
5858
5859 Right_Opnd => Cond);
5860
5861 Set_Analyzed (Left_Opnd (Left_Opnd (Cond)), False);
5862 Set_Analyzed (Right_Opnd (Left_Opnd (Cond)), False);
5863 Insert_Action (N,
07fc65c4
GB
5864 Make_Raise_Constraint_Error (Loc,
5865 Condition => Cond,
8fdafe44 5866 Reason => CE_Range_Check_Failed));
70482933
RK
5867 end if;
5868 end Check_Bounds;
5869
5870 ----------------------------
5871 -- Check_Same_Aggr_Bounds --
5872 ----------------------------
5873
5874 procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos) is
5875 Sub_Lo : constant Node_Id := Low_Bound (Aggregate_Bounds (Sub_Aggr));
5876 Sub_Hi : constant Node_Id := High_Bound (Aggregate_Bounds (Sub_Aggr));
d74716b3 5877 -- The bounds of this specific subaggregate
70482933
RK
5878
5879 Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
5880 Aggr_Hi : constant Node_Id := Aggr_High (Dim);
5881 -- The bounds of the aggregate for this dimension
5882
5883 Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
3cf3e5c6 5884 -- The index type for this dimension.xxx
70482933 5885
fbf5a39b 5886 Cond : Node_Id := Empty;
fbf5a39b
AC
5887 Assoc : Node_Id;
5888 Expr : Node_Id;
70482933
RK
5889
5890 begin
5891 -- If index checks are on generate the test
3b9fa2df 5892
70482933
RK
5893 -- [constraint_error when
5894 -- Aggr_Lo /= Sub_Lo or else Aggr_Hi /= Sub_Hi]
3b9fa2df 5895
70482933
RK
5896 -- As an optimization try to see if some tests are trivially vacuos
5897 -- because we are comparing an expression against itself. Also for
5898 -- the first dimension the test is trivially vacuous because there
5899 -- is just one aggregate for dimension 1.
5900
5901 if Index_Checks_Suppressed (Ind_Typ) then
5902 Cond := Empty;
5903
bdc193ba 5904 elsif Dim = 1 or else (Aggr_Lo = Sub_Lo and then Aggr_Hi = Sub_Hi)
70482933
RK
5905 then
5906 Cond := Empty;
5907
5908 elsif Aggr_Hi = Sub_Hi then
5909 Cond :=
5910 Make_Op_Ne (Loc,
fbf5a39b
AC
5911 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5912 Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo));
70482933
RK
5913
5914 elsif Aggr_Lo = Sub_Lo then
5915 Cond :=
5916 Make_Op_Ne (Loc,
fbf5a39b
AC
5917 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
5918 Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Hi));
70482933
RK
5919
5920 else
5921 Cond :=
5922 Make_Or_Else (Loc,
5923 Left_Opnd =>
5924 Make_Op_Ne (Loc,
fbf5a39b
AC
5925 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5926 Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo)),
70482933
RK
5927
5928 Right_Opnd =>
5929 Make_Op_Ne (Loc,
5930 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
5931 Right_Opnd => Duplicate_Subexpr (Sub_Hi)));
5932 end if;
5933
5934 if Present (Cond) then
5935 Insert_Action (N,
07fc65c4
GB
5936 Make_Raise_Constraint_Error (Loc,
5937 Condition => Cond,
5938 Reason => CE_Length_Check_Failed));
70482933
RK
5939 end if;
5940
d74716b3 5941 -- Now look inside the subaggregate to see if there is more work
70482933
RK
5942
5943 if Dim < Aggr_Dimension then
5944
5945 -- Process positional components
5946
5947 if Present (Expressions (Sub_Aggr)) then
5948 Expr := First (Expressions (Sub_Aggr));
5949 while Present (Expr) loop
5950 Check_Same_Aggr_Bounds (Expr, Dim + 1);
5951 Next (Expr);
5952 end loop;
5953 end if;
5954
5955 -- Process component associations
5956
5957 if Present (Component_Associations (Sub_Aggr)) then
5958 Assoc := First (Component_Associations (Sub_Aggr));
5959 while Present (Assoc) loop
5960 Expr := Expression (Assoc);
5961 Check_Same_Aggr_Bounds (Expr, Dim + 1);
5962 Next (Assoc);
5963 end loop;
5964 end if;
5965 end if;
5966 end Check_Same_Aggr_Bounds;
5967
5968 ----------------------------
5969 -- Compute_Others_Present --
5970 ----------------------------
5971
5972 procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos) is
fbf5a39b
AC
5973 Assoc : Node_Id;
5974 Expr : Node_Id;
70482933
RK
5975
5976 begin
5977 if Present (Component_Associations (Sub_Aggr)) then
5978 Assoc := Last (Component_Associations (Sub_Aggr));
07fc65c4 5979
00f45f30 5980 if Nkind (First (Choice_List (Assoc))) = N_Others_Choice then
70482933 5981 Others_Present (Dim) := True;
e84d25c9
ES
5982
5983 -- An others_clause may be superfluous if previous components
5984 -- cover the full given range of a constrained array. In such
5985 -- a case an others_clause does not contribute any additional
5986 -- components and has not been analyzed. We analyze it now to
5987 -- detect type errors in the expression, even though no code
5988 -- will be generated for it.
5989
5990 if Dim = Aggr_Dimension
5991 and then Nkind (Assoc) /= N_Iterated_Component_Association
5992 and then not Analyzed (Expression (Assoc))
5993 and then not Box_Present (Assoc)
5994 then
5995 Preanalyze_And_Resolve (Expression (Assoc), Ctyp);
5996 end if;
70482933
RK
5997 end if;
5998 end if;
5999
d74716b3 6000 -- Now look inside the subaggregate to see if there is more work
70482933
RK
6001
6002 if Dim < Aggr_Dimension then
6003
6004 -- Process positional components
6005
6006 if Present (Expressions (Sub_Aggr)) then
6007 Expr := First (Expressions (Sub_Aggr));
6008 while Present (Expr) loop
6009 Compute_Others_Present (Expr, Dim + 1);
6010 Next (Expr);
6011 end loop;
6012 end if;
6013
6014 -- Process component associations
6015
6016 if Present (Component_Associations (Sub_Aggr)) then
6017 Assoc := First (Component_Associations (Sub_Aggr));
6018 while Present (Assoc) loop
6019 Expr := Expression (Assoc);
6020 Compute_Others_Present (Expr, Dim + 1);
6021 Next (Assoc);
6022 end loop;
6023 end if;
6024 end if;
6025 end Compute_Others_Present;
6026
70482933
RK
6027 ------------------
6028 -- Others_Check --
6029 ------------------
6030
6031 procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos) is
6032 Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
6033 Aggr_Hi : constant Node_Id := Aggr_High (Dim);
3cf3e5c6 6034 -- The bounds of the aggregate for this dimension
70482933
RK
6035
6036 Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
3cf3e5c6 6037 -- The index type for this dimension
70482933
RK
6038
6039 Need_To_Check : Boolean := False;
6040
6041 Choices_Lo : Node_Id := Empty;
6042 Choices_Hi : Node_Id := Empty;
d74716b3 6043 -- The lowest and highest discrete choices for a named subaggregate
70482933
RK
6044
6045 Nb_Choices : Int := -1;
d74716b3 6046 -- The number of discrete non-others choices in this subaggregate
70482933
RK
6047
6048 Nb_Elements : Uint := Uint_0;
6049 -- The number of elements in a positional aggregate
6050
6051 Cond : Node_Id := Empty;
6052
6053 Assoc : Node_Id;
6054 Choice : Node_Id;
6055 Expr : Node_Id;
6056
6057 begin
6058 -- Check if we have an others choice. If we do make sure that this
d74716b3 6059 -- subaggregate contains at least one element in addition to the
70482933
RK
6060 -- others choice.
6061
6062 if Range_Checks_Suppressed (Ind_Typ) then
6063 Need_To_Check := False;
6064
6065 elsif Present (Expressions (Sub_Aggr))
6066 and then Present (Component_Associations (Sub_Aggr))
6067 then
6068 Need_To_Check := True;
6069
6070 elsif Present (Component_Associations (Sub_Aggr)) then
6071 Assoc := Last (Component_Associations (Sub_Aggr));
6072
00f45f30 6073 if Nkind (First (Choice_List (Assoc))) /= N_Others_Choice then
70482933
RK
6074 Need_To_Check := False;
6075
6076 else
3b9fa2df
ES
6077 -- Count the number of discrete choices. Start with -1 because
6078 -- the others choice does not count.
70482933 6079
bdc193ba
AC
6080 -- Is there some reason we do not use List_Length here ???
6081
70482933
RK
6082 Nb_Choices := -1;
6083 Assoc := First (Component_Associations (Sub_Aggr));
6084 while Present (Assoc) loop
00f45f30 6085 Choice := First (Choice_List (Assoc));
70482933
RK
6086 while Present (Choice) loop
6087 Nb_Choices := Nb_Choices + 1;
6088 Next (Choice);
6089 end loop;
6090
6091 Next (Assoc);
6092 end loop;
6093
6094 -- If there is only an others choice nothing to do
6095
6096 Need_To_Check := (Nb_Choices > 0);
6097 end if;
6098
6099 else
6100 Need_To_Check := False;
6101 end if;
6102
d74716b3 6103 -- If we are dealing with a positional subaggregate with an others
3b9fa2df 6104 -- choice then compute the number or positional elements.
70482933
RK
6105
6106 if Need_To_Check and then Present (Expressions (Sub_Aggr)) then
6107 Expr := First (Expressions (Sub_Aggr));
6108 Nb_Elements := Uint_0;
6109 while Present (Expr) loop
6110 Nb_Elements := Nb_Elements + 1;
6111 Next (Expr);
6112 end loop;
6113
6114 -- If the aggregate contains discrete choices and an others choice
6115 -- compute the smallest and largest discrete choice values.
6116
6117 elsif Need_To_Check then
6118 Compute_Choices_Lo_And_Choices_Hi : declare
07fc65c4 6119
70482933
RK
6120 Table : Case_Table_Type (1 .. Nb_Choices);
6121 -- Used to sort all the different choice values
6122
07fc65c4 6123 J : Pos := 1;
70482933
RK
6124
6125 begin
6126 Assoc := First (Component_Associations (Sub_Aggr));
6127 while Present (Assoc) loop
00f45f30 6128 Choice := First (Choice_List (Assoc));
70482933
RK
6129 while Present (Choice) loop
6130 if Nkind (Choice) = N_Others_Choice then
6131 exit;
6132 end if;
6133
7c4f3267
BD
6134 declare
6135 Bounds : constant Range_Nodes :=
6136 Get_Index_Bounds (Choice);
6137 begin
6138 Table (J).Choice_Lo := Bounds.First;
6139 Table (J).Choice_Hi := Bounds.Last;
6140 end;
70482933 6141
07fc65c4 6142 J := J + 1;
70482933
RK
6143 Next (Choice);
6144 end loop;
6145
6146 Next (Assoc);
6147 end loop;
6148
6149 -- Sort the discrete choices
6150
6151 Sort_Case_Table (Table);
6152
6153 Choices_Lo := Table (1).Choice_Lo;
6154 Choices_Hi := Table (Nb_Choices).Choice_Hi;
6155 end Compute_Choices_Lo_And_Choices_Hi;
6156 end if;
6157
d74716b3 6158 -- If no others choice in this subaggregate, or the aggregate
70482933
RK
6159 -- comprises only an others choice, nothing to do.
6160
6161 if not Need_To_Check then
6162 Cond := Empty;
6163
3b9fa2df
ES
6164 -- If we are dealing with an aggregate containing an others choice
6165 -- and positional components, we generate the following test:
6166
70482933
RK
6167 -- if Ind_Typ'Pos (Aggr_Lo) + (Nb_Elements - 1) >
6168 -- Ind_Typ'Pos (Aggr_Hi)
6169 -- then
6170 -- raise Constraint_Error;
6171 -- end if;
6172
6a987d78
EB
6173 -- in the general case, but the following simpler test:
6174
6175 -- [constraint_error when
6176 -- Aggr_Lo + (Nb_Elements - 1) > Aggr_Hi];
6177
6178 -- instead if the index type is a signed integer.
6179
70482933 6180 elsif Nb_Elements > Uint_0 then
6a987d78
EB
6181 if Nb_Elements = Uint_1 then
6182 Cond :=
6183 Make_Op_Gt (Loc,
6184 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
6185 Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi));
6186
6187 elsif Is_Signed_Integer_Type (Ind_Typ) then
6188 Cond :=
6189 Make_Op_Gt (Loc,
6190 Left_Opnd =>
6191 Make_Op_Add (Loc,
6192 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
6193 Right_Opnd =>
6194 Make_Integer_Literal (Loc, Nb_Elements - 1)),
6195 Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi));
70482933 6196
6a987d78
EB
6197 else
6198 Cond :=
6199 Make_Op_Gt (Loc,
6200 Left_Opnd =>
6201 Make_Op_Add (Loc,
6202 Left_Opnd =>
6203 Make_Attribute_Reference (Loc,
6204 Prefix => New_Occurrence_Of (Ind_Typ, Loc),
6205 Attribute_Name => Name_Pos,
6206 Expressions =>
6207 New_List
6208 (Duplicate_Subexpr_Move_Checks (Aggr_Lo))),
6209 Right_Opnd => Make_Integer_Literal (Loc, Nb_Elements - 1)),
6210
6211 Right_Opnd =>
6212 Make_Attribute_Reference (Loc,
6213 Prefix => New_Occurrence_Of (Ind_Typ, Loc),
6214 Attribute_Name => Name_Pos,
6215 Expressions => New_List (
6216 Duplicate_Subexpr_Move_Checks (Aggr_Hi))));
6217 end if;
70482933 6218
3b9fa2df
ES
6219 -- If we are dealing with an aggregate containing an others choice
6220 -- and discrete choices we generate the following test:
6221
70482933
RK
6222 -- [constraint_error when
6223 -- Choices_Lo < Aggr_Lo or else Choices_Hi > Aggr_Hi];
6224
6225 else
6226 Cond :=
6227 Make_Or_Else (Loc,
6228 Left_Opnd =>
6229 Make_Op_Lt (Loc,
bdc193ba
AC
6230 Left_Opnd => Duplicate_Subexpr_Move_Checks (Choices_Lo),
6231 Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo)),
70482933
RK
6232
6233 Right_Opnd =>
6234 Make_Op_Gt (Loc,
bdc193ba
AC
6235 Left_Opnd => Duplicate_Subexpr (Choices_Hi),
6236 Right_Opnd => Duplicate_Subexpr (Aggr_Hi)));
70482933
RK
6237 end if;
6238
6239 if Present (Cond) then
6240 Insert_Action (N,
07fc65c4
GB
6241 Make_Raise_Constraint_Error (Loc,
6242 Condition => Cond,
6243 Reason => CE_Length_Check_Failed));
641d3093
TQ
6244 -- Questionable reason code, shouldn't that be a
6245 -- CE_Range_Check_Failed ???
70482933
RK
6246 end if;
6247
d74716b3 6248 -- Now look inside the subaggregate to see if there is more work
70482933
RK
6249
6250 if Dim < Aggr_Dimension then
6251
6252 -- Process positional components
6253
6254 if Present (Expressions (Sub_Aggr)) then
6255 Expr := First (Expressions (Sub_Aggr));
6256 while Present (Expr) loop
6257 Others_Check (Expr, Dim + 1);
6258 Next (Expr);
6259 end loop;
6260 end if;
6261
6262 -- Process component associations
6263
6264 if Present (Component_Associations (Sub_Aggr)) then
6265 Assoc := First (Component_Associations (Sub_Aggr));
6266 while Present (Assoc) loop
6267 Expr := Expression (Assoc);
6268 Others_Check (Expr, Dim + 1);
6269 Next (Assoc);
6270 end loop;
6271 end if;
6272 end if;
6273 end Others_Check;
6274
8da337c5
AC
6275 -------------------------
6276 -- Safe_Left_Hand_Side --
6277 -------------------------
6278
6279 function Safe_Left_Hand_Side (N : Node_Id) return Boolean is
deeb1604
AC
6280 function Is_Safe_Index (Indx : Node_Id) return Boolean;
6281 -- If the left-hand side includes an indexed component, check that
d74716b3 6282 -- the indexes are free of side effects.
deeb1604
AC
6283
6284 -------------------
6285 -- Is_Safe_Index --
6286 -------------------
6287
6288 function Is_Safe_Index (Indx : Node_Id) return Boolean is
6289 begin
6290 if Is_Entity_Name (Indx) then
6291 return True;
6292
6293 elsif Nkind (Indx) = N_Integer_Literal then
6294 return True;
6295
6296 elsif Nkind (Indx) = N_Function_Call
6297 and then Is_Entity_Name (Name (Indx))
36a66365 6298 and then Has_Pragma_Pure_Function (Entity (Name (Indx)))
deeb1604
AC
6299 then
6300 return True;
6301
6302 elsif Nkind (Indx) = N_Type_Conversion
6303 and then Is_Safe_Index (Expression (Indx))
6304 then
6305 return True;
6306
6307 else
6308 return False;
6309 end if;
6310 end Is_Safe_Index;
6311
6312 -- Start of processing for Safe_Left_Hand_Side
6313
8da337c5
AC
6314 begin
6315 if Is_Entity_Name (N) then
6316 return True;
6317
4a08c95c 6318 elsif Nkind (N) in N_Explicit_Dereference | N_Selected_Component
8da337c5
AC
6319 and then Safe_Left_Hand_Side (Prefix (N))
6320 then
6321 return True;
6322
6323 elsif Nkind (N) = N_Indexed_Component
6324 and then Safe_Left_Hand_Side (Prefix (N))
36a66365 6325 and then Is_Safe_Index (First (Expressions (N)))
8da337c5
AC
6326 then
6327 return True;
deeb1604
AC
6328
6329 elsif Nkind (N) = N_Unchecked_Type_Conversion then
6330 return Safe_Left_Hand_Side (Expression (N));
6331
8da337c5
AC
6332 else
6333 return False;
6334 end if;
6335 end Safe_Left_Hand_Side;
6336
6337 -- Local variables
70482933
RK
6338
6339 Tmp : Entity_Id;
fbf5a39b 6340 -- Holds the temporary aggregate value
70482933
RK
6341
6342 Tmp_Decl : Node_Id;
fbf5a39b 6343 -- Holds the declaration of Tmp
70482933
RK
6344
6345 Aggr_Code : List_Id;
6346 Parent_Node : Node_Id;
6347 Parent_Kind : Node_Kind;
6348
6349 -- Start of processing for Expand_Array_Aggregate
6350
6351 begin
6352 -- Do not touch the special aggregates of attributes used for Asm calls
6353
6354 if Is_RTE (Ctyp, RE_Asm_Input_Operand)
6355 or else Is_RTE (Ctyp, RE_Asm_Output_Operand)
6356 then
6357 return;
4a1bfefb
AC
6358
6359 -- Do not expand an aggregate for an array type which contains tasks if
6360 -- the aggregate is associated with an unexpanded return statement of a
6361 -- build-in-place function. The aggregate is expanded when the related
6362 -- return statement (rewritten into an extended return) is processed.
6363 -- This delay ensures that any temporaries and initialization code
6364 -- generated for the aggregate appear in the proper return block and
6365 -- use the correct _chain and _master.
6366
6367 elsif Has_Task (Base_Type (Etype (N)))
6368 and then Nkind (Parent (N)) = N_Simple_Return_Statement
6369 and then Is_Build_In_Place_Function
6370 (Return_Applies_To (Return_Statement_Entity (Parent (N))))
6371 then
6372 return;
f5655e4a
AC
6373
6374 -- Do not attempt expansion if error already detected. We may reach this
6375 -- point in spite of previous errors when compiling with -gnatq, to
6376 -- force all possible errors (this is the usual ACATS mode).
6377
6378 elsif Error_Posted (N) then
6379 return;
70482933
RK
6380 end if;
6381
07fc65c4 6382 -- If the semantic analyzer has determined that aggregate N will raise
e7c0dd39 6383 -- Constraint_Error at run time, then the aggregate node has been
07fc65c4
GB
6384 -- replaced with an N_Raise_Constraint_Error node and we should
6385 -- never get here.
70482933
RK
6386
6387 pragma Assert (not Raises_Constraint_Error (N));
6388
3cf3e5c6 6389 -- STEP 1a
fbf5a39b
AC
6390
6391 -- Check that the index range defined by aggregate bounds is
6392 -- compatible with corresponding index subtype.
70482933
RK
6393
6394 Index_Compatibility_Check : declare
6395 Aggr_Index_Range : Node_Id := First_Index (Typ);
6396 -- The current aggregate index range
6397
6398 Index_Constraint : Node_Id := First_Index (Etype (Typ));
6399 -- The corresponding index constraint against which we have to
6400 -- check the above aggregate index range.
6401
6402 begin
6403 Compute_Others_Present (N, 1);
6404
6405 for J in 1 .. Aggr_Dimension loop
bdc193ba
AC
6406 -- There is no need to emit a check if an others choice is present
6407 -- for this array aggregate dimension since in this case one of
d74716b3 6408 -- N's subaggregates has taken its bounds from the context and
bdc193ba 6409 -- these bounds must have been checked already. In addition all
d74716b3
AC
6410 -- subaggregates corresponding to the same dimension must all have
6411 -- the same bounds (checked in (c) below).
70482933
RK
6412
6413 if not Range_Checks_Suppressed (Etype (Index_Constraint))
6414 and then not Others_Present (J)
6415 then
3b9fa2df
ES
6416 -- We don't use Checks.Apply_Range_Check here because it emits
6417 -- a spurious check. Namely it checks that the range defined by
d74716b3 6418 -- the aggregate bounds is nonempty. But we know this already
3b9fa2df 6419 -- if we get here.
70482933
RK
6420
6421 Check_Bounds (Aggr_Index_Range, Index_Constraint);
6422 end if;
6423
3b9fa2df
ES
6424 -- Save the low and high bounds of the aggregate index as well as
6425 -- the index type for later use in checks (b) and (c) below.
70482933
RK
6426
6427 Aggr_Low (J) := Low_Bound (Aggr_Index_Range);
6428 Aggr_High (J) := High_Bound (Aggr_Index_Range);
6429
6430 Aggr_Index_Typ (J) := Etype (Index_Constraint);
6431
6432 Next_Index (Aggr_Index_Range);
6433 Next_Index (Index_Constraint);
6434 end loop;
6435 end Index_Compatibility_Check;
6436
3cf3e5c6 6437 -- STEP 1b
fbf5a39b 6438
3b9fa2df
ES
6439 -- If an others choice is present check that no aggregate index is
6440 -- outside the bounds of the index constraint.
70482933
RK
6441
6442 Others_Check (N, 1);
6443
3cf3e5c6 6444 -- STEP 1c
fbf5a39b
AC
6445
6446 -- For multidimensional arrays make sure that all subaggregates
6447 -- corresponding to the same dimension have the same bounds.
70482933
RK
6448
6449 if Aggr_Dimension > 1 then
6450 Check_Same_Aggr_Bounds (N, 1);
6451 end if;
6452
688a9b51
RD
6453 -- STEP 1d
6454
6455 -- If we have a default component value, or simple initialization is
6456 -- required for the component type, then we replace <> in component
6457 -- associations by the required default value.
6458
6459 declare
6460 Default_Val : Node_Id;
6461 Assoc : Node_Id;
6462
6463 begin
6464 if (Present (Default_Aspect_Component_Value (Typ))
6465 or else Needs_Simple_Initialization (Ctyp))
6466 and then Present (Component_Associations (N))
6467 then
6468 Assoc := First (Component_Associations (N));
6469 while Present (Assoc) loop
6470 if Nkind (Assoc) = N_Component_Association
6471 and then Box_Present (Assoc)
6472 then
6473 Set_Box_Present (Assoc, False);
6474
6475 if Present (Default_Aspect_Component_Value (Typ)) then
6476 Default_Val := Default_Aspect_Component_Value (Typ);
6477 else
6478 Default_Val := Get_Simple_Init_Val (Ctyp, N);
6479 end if;
6480
6481 Set_Expression (Assoc, New_Copy_Tree (Default_Val));
6482 Analyze_And_Resolve (Expression (Assoc), Ctyp);
6483 end if;
6484
6485 Next (Assoc);
6486 end loop;
6487 end if;
6488 end;
6489
3cf3e5c6 6490 -- STEP 2
70482933 6491
3b9fa2df
ES
6492 -- Here we test for is packed array aggregate that we can handle at
6493 -- compile time. If so, return with transformation done. Note that we do
6494 -- this even if the aggregate is nested, because once we have done this
a90bd866 6495 -- processing, there is no more nested aggregate.
fbf5a39b
AC
6496
6497 if Packed_Array_Aggregate_Handled (N) then
6498 return;
6499 end if;
6500
6501 -- At this point we try to convert to positional form
70482933 6502
c42006e9 6503 Convert_To_Positional (N);
70482933 6504
23a9215f 6505 -- If the result is no longer an aggregate (e.g. it may be a string
fbf5a39b
AC
6506 -- literal, or a temporary which has the needed value), then we are
6507 -- done, since there is no longer a nested aggregate.
6508
70482933
RK
6509 if Nkind (N) /= N_Aggregate then
6510 return;
6511
5eeeed5e
AC
6512 -- We are also done if the result is an analyzed aggregate, indicating
6513 -- that Convert_To_Positional succeeded and reanalyzed the rewritten
6514 -- aggregate.
fbf5a39b 6515
dc67cfea 6516 elsif Analyzed (N) and then Is_Rewrite_Substitution (N) then
70482933
RK
6517 return;
6518 end if;
6519
fa57ac97
ES
6520 -- If all aggregate components are compile-time known and the aggregate
6521 -- has been flattened, nothing left to do. The same occurs if the
b465ef6f 6522 -- aggregate is used to initialize the components of a statically
fa57ac97 6523 -- allocated dispatch table.
0f95b178 6524
fa57ac97
ES
6525 if Compile_Time_Known_Aggregate (N)
6526 or else Is_Static_Dispatch_Table_Aggregate (N)
6527 then
0f95b178
JM
6528 Set_Expansion_Delayed (N, False);
6529 return;
6530 end if;
6531
fbf5a39b
AC
6532 -- Now see if back end processing is possible
6533
70482933
RK
6534 if Backend_Processing_Possible (N) then
6535
6536 -- If the aggregate is static but the constraints are not, build
6537 -- a static subtype for the aggregate, so that Gigi can place it
6538 -- in static memory. Perform an unchecked_conversion to the non-
6539 -- static type imposed by the context.
6540
6541 declare
6542 Itype : constant Entity_Id := Etype (N);
6543 Index : Node_Id;
6544 Needs_Type : Boolean := False;
6545
6546 begin
6547 Index := First_Index (Itype);
70482933 6548 while Present (Index) loop
edab6088 6549 if not Is_OK_Static_Subtype (Etype (Index)) then
70482933
RK
6550 Needs_Type := True;
6551 exit;
6552 else
6553 Next_Index (Index);
6554 end if;
6555 end loop;
6556
6557 if Needs_Type then
6558 Build_Constrained_Type (Positional => True);
6559 Rewrite (N, Unchecked_Convert_To (Itype, N));
6560 Analyze (N);
6561 end if;
6562 end;
6563
6564 return;
6565 end if;
6566
3cf3e5c6 6567 -- STEP 3
fbf5a39b 6568
5ed4ba15
AC
6569 -- Delay expansion for nested aggregates: it will be taken care of when
6570 -- the parent aggregate is expanded.
70482933
RK
6571
6572 Parent_Node := Parent (N);
6573 Parent_Kind := Nkind (Parent_Node);
6574
6575 if Parent_Kind = N_Qualified_Expression then
6576 Parent_Node := Parent (Parent_Node);
6577 Parent_Kind := Nkind (Parent_Node);
6578 end if;
6579
6580 if Parent_Kind = N_Aggregate
6581 or else Parent_Kind = N_Extension_Aggregate
6582 or else Parent_Kind = N_Component_Association
6583 or else (Parent_Kind = N_Object_Declaration
048e5cef 6584 and then Needs_Finalization (Typ))
70482933
RK
6585 or else (Parent_Kind = N_Assignment_Statement
6586 and then Inside_Init_Proc)
6587 then
2a1838cd
EB
6588 Set_Expansion_Delayed (N, not Static_Array_Aggregate (N));
6589 return;
70482933
RK
6590 end if;
6591
3cf3e5c6 6592 -- STEP 4
70482933 6593
bc1146e5 6594 -- Check whether in-place aggregate expansion is possible
70482933
RK
6595
6596 -- For object declarations we build the aggregate in place, unless
d2a60e59 6597 -- the array is bit-packed.
70482933
RK
6598
6599 -- For assignments we do the assignment in place if all the component
d2a60e59
ES
6600 -- associations have compile-time known values, or are default-
6601 -- initialized limited components, e.g. tasks. For other cases we
f037632e
BD
6602 -- create a temporary. A full analysis for safety of in-place assignment
6603 -- is delicate.
70482933 6604
6f639c98
ES
6605 -- For allocators we assign to the designated object in place if the
6606 -- aggregate meets the same conditions as other in-place assignments.
6607 -- In this case the aggregate may not come from source but was created
6608 -- for default initialization, e.g. with Initialize_Scalars.
6609
70482933 6610 if Requires_Transient_Scope (Typ) then
6560f851 6611 Establish_Transient_Scope (N, Manage_Sec_Stack => False);
70482933
RK
6612 end if;
6613
92a68a04 6614 -- An array of limited components is built in place
d2a60e59
ES
6615
6616 if Is_Limited_Type (Typ) then
6617 Maybe_In_Place_OK := True;
6618
6619 elsif Has_Default_Init_Comps (N) then
c45b6ae0 6620 Maybe_In_Place_OK := False;
6f639c98
ES
6621
6622 elsif Is_Bit_Packed_Array (Typ)
6623 or else Has_Controlled_Component (Typ)
6624 then
6625 Maybe_In_Place_OK := False;
6626
a80b1eb7 6627 elsif Parent_Kind = N_Assignment_Statement then
c45b6ae0 6628 Maybe_In_Place_OK :=
a80b1eb7 6629 In_Place_Assign_OK (N, Get_Base_Object (Name (Parent_Node)));
6f639c98 6630
a80b1eb7
EB
6631 elsif Parent_Kind = N_Allocator then
6632 Maybe_In_Place_OK := In_Place_Assign_OK (N);
6633
6634 else
6635 Maybe_In_Place_OK := False;
c45b6ae0 6636 end if;
70482933 6637
36c73552
AC
6638 -- If this is an array of tasks, it will be expanded into build-in-place
6639 -- assignments. Build an activation chain for the tasks now.
a38ff9b1
ES
6640
6641 if Has_Task (Etype (N)) then
6642 Build_Activation_Chain_Entity (N);
6643 end if;
6644
cf6956bb 6645 -- Perform in-place expansion of aggregate in an object declaration.
f3d42000
AC
6646 -- Note: actions generated for the aggregate will be captured in an
6647 -- expression-with-actions statement so that they can be transferred
6648 -- to freeze actions later if there is an address clause for the
6649 -- object. (Note: we don't use a block statement because this would
6650 -- cause generated freeze nodes to be elaborated in the wrong scope).
cf6956bb 6651
d2a60e59
ES
6652 -- Arrays of limited components must be built in place. The code
6653 -- previously excluded controlled components but this is an old
6654 -- oversight: the rules in 7.6 (17) are clear.
5ed4ba15 6655
d4e4e88a 6656 if Comes_From_Source (Parent_Node)
3386e3ae
AC
6657 and then Parent_Kind = N_Object_Declaration
6658 and then Present (Expression (Parent_Node))
6659 and then not
6660 Must_Slide (Etype (Defining_Identifier (Parent_Node)), Typ)
3386e3ae 6661 and then not Is_Bit_Packed_Array (Typ)
70482933 6662 then
ac43e11e 6663 In_Place_Assign_OK_For_Declaration := True;
5ed4ba15
AC
6664 Tmp := Defining_Identifier (Parent_Node);
6665 Set_No_Initialization (Parent_Node);
6666 Set_Expression (Parent_Node, Empty);
70482933 6667
ac43e11e
AC
6668 -- Set kind and type of the entity, for use in the analysis
6669 -- of the subsequent assignments. If the nominal type is not
70482933
RK
6670 -- constrained, build a subtype from the known bounds of the
6671 -- aggregate. If the declaration has a subtype mark, use it,
6672 -- otherwise use the itype of the aggregate.
6673
2e02ab86 6674 Mutate_Ekind (Tmp, E_Variable);
ac43e11e 6675
70482933
RK
6676 if not Is_Constrained (Typ) then
6677 Build_Constrained_Type (Positional => False);
ac43e11e 6678
5ed4ba15
AC
6679 elsif Is_Entity_Name (Object_Definition (Parent_Node))
6680 and then Is_Constrained (Entity (Object_Definition (Parent_Node)))
70482933 6681 then
5ed4ba15 6682 Set_Etype (Tmp, Entity (Object_Definition (Parent_Node)));
ac43e11e 6683
70482933
RK
6684 else
6685 Set_Size_Known_At_Compile_Time (Typ, False);
6686 Set_Etype (Tmp, Typ);
6687 end if;
6688
a80b1eb7 6689 elsif Maybe_In_Place_OK and then Parent_Kind = N_Allocator then
6f639c98
ES
6690 Set_Expansion_Delayed (N);
6691 return;
6692
d2a60e59
ES
6693 -- Limited arrays in return statements are expanded when
6694 -- enclosing construct is expanded.
6695
6696 elsif Maybe_In_Place_OK
a80b1eb7 6697 and then Parent_Kind = N_Simple_Return_Statement
d2a60e59
ES
6698 then
6699 Set_Expansion_Delayed (N);
6700 return;
6701
6537318f
ES
6702 -- In the remaining cases the aggregate appears in the RHS of an
6703 -- assignment, which may be part of the expansion of an object
6704 -- delaration. If the aggregate is an actual in a call, itself
6705 -- possibly in a RHS, building it in the target is not possible.
6f639c98 6706
70482933 6707 elsif Maybe_In_Place_OK
6537318f 6708 and then Nkind (Parent_Node) not in N_Subprogram_Call
a80b1eb7 6709 and then Safe_Left_Hand_Side (Name (Parent_Node))
70482933 6710 then
a80b1eb7 6711 Tmp := Name (Parent_Node);
70482933
RK
6712
6713 if Etype (Tmp) /= Etype (N) then
6714 Apply_Length_Check (N, Etype (Tmp));
fbf5a39b
AC
6715
6716 if Nkind (N) = N_Raise_Constraint_Error then
6717
6718 -- Static error, nothing further to expand
6719
6720 return;
6721 end if;
70482933
RK
6722 end if;
6723
36a66365
AC
6724 -- If a slice assignment has an aggregate with a single others_choice,
6725 -- the assignment can be done in place even if bounds are not static,
6726 -- by converting it into a loop over the discrete range of the slice.
6727
70482933 6728 elsif Maybe_In_Place_OK
a80b1eb7 6729 and then Nkind (Name (Parent_Node)) = N_Slice
36a66365 6730 and then Is_Others_Aggregate (N)
70482933 6731 then
a80b1eb7 6732 Tmp := Name (Parent_Node);
70482933 6733
36a66365
AC
6734 -- Set type of aggregate to be type of lhs in assignment, in order
6735 -- to suppress redundant length checks.
6736
6737 Set_Etype (N, Etype (Tmp));
70482933 6738
fbf5a39b
AC
6739 -- Step 5
6740
bc1146e5 6741 -- In-place aggregate expansion is not possible
fbf5a39b 6742
70482933 6743 else
07fc65c4 6744 Maybe_In_Place_OK := False;
faf387e1 6745 Tmp := Make_Temporary (Loc, 'A', N);
70482933 6746 Tmp_Decl :=
bdc193ba
AC
6747 Make_Object_Declaration (Loc,
6748 Defining_Identifier => Tmp,
6749 Object_Definition => New_Occurrence_Of (Typ, Loc));
70482933 6750 Set_No_Initialization (Tmp_Decl, True);
0ffbef9f 6751 Set_Warnings_Off (Tmp);
70482933
RK
6752
6753 -- If we are within a loop, the temporary will be pushed on the
6560f851
HK
6754 -- stack at each iteration. If the aggregate is the expression
6755 -- for an allocator, it will be immediately copied to the heap
6756 -- and can be reclaimed at once. We create a transient scope
6757 -- around the aggregate for this purpose.
70482933
RK
6758
6759 if Ekind (Current_Scope) = E_Loop
a80b1eb7 6760 and then Parent_Kind = N_Allocator
70482933 6761 then
6560f851 6762 Establish_Transient_Scope (N, Manage_Sec_Stack => False);
70482933
RK
6763 end if;
6764
6765 Insert_Action (N, Tmp_Decl);
6766 end if;
6767
36c73552
AC
6768 -- Construct and insert the aggregate code. We can safely suppress index
6769 -- checks because this code is guaranteed not to raise CE on index
6770 -- checks. However we should *not* suppress all checks.
70482933 6771
07fc65c4
GB
6772 declare
6773 Target : Node_Id;
6774
6775 begin
6776 if Nkind (Tmp) = N_Defining_Identifier then
e4494292 6777 Target := New_Occurrence_Of (Tmp, Loc);
07fc65c4
GB
6778
6779 else
d2a60e59
ES
6780 if Has_Default_Init_Comps (N)
6781 and then not Maybe_In_Place_OK
6782 then
0ab80019 6783 -- Ada 2005 (AI-287): This case has not been analyzed???
c45b6ae0 6784
9bc856dd 6785 raise Program_Error;
c45b6ae0
AC
6786 end if;
6787
0da2c8ac 6788 -- Name in assignment is explicit dereference
07fc65c4
GB
6789
6790 Target := New_Copy (Tmp);
6791 end if;
6792
bc1146e5 6793 -- If we are to generate an in-place assignment for a declaration or
ac43e11e
AC
6794 -- an assignment statement, and the assignment can be done directly
6795 -- by the back end, then do not expand further.
6796
bc1146e5 6797 -- ??? We can also do that if in-place expansion is not possible but
ac43e11e
AC
6798 -- then we could go into an infinite recursion.
6799
6800 if (In_Place_Assign_OK_For_Declaration or else Maybe_In_Place_OK)
a1e1820b 6801 and then not CodePeer_Mode
c63a2ad6 6802 and then not Modify_Tree_For_C
ac43e11e 6803 and then not Possible_Bit_Aligned_Component (Target)
6b6bce61 6804 and then not Is_Possibly_Unaligned_Slice (Target)
ac43e11e
AC
6805 and then Aggr_Assignment_OK_For_Backend (N)
6806 then
6807 if Maybe_In_Place_OK then
6808 return;
6809 end if;
6810
6811 Aggr_Code :=
6812 New_List (
6813 Make_Assignment_Statement (Loc,
6814 Name => Target,
683af98c 6815 Expression => New_Copy_Tree (N)));
ac43e11e 6816
d6e8719d 6817 else
ac43e11e
AC
6818 Aggr_Code :=
6819 Build_Array_Aggr_Code (N,
6820 Ctype => Ctyp,
6821 Index => First_Index (Typ),
6822 Into => Target,
6823 Scalar_Comp => Is_Scalar_Type (Ctyp));
6824 end if;
4ac2bbbd
AC
6825
6826 -- Save the last assignment statement associated with the aggregate
6827 -- when building a controlled object. This reference is utilized by
6828 -- the finalization machinery when marking an object as successfully
6829 -- initialized.
6830
6831 if Needs_Finalization (Typ)
6832 and then Is_Entity_Name (Target)
6833 and then Present (Entity (Target))
4a08c95c 6834 and then Ekind (Entity (Target)) in E_Constant | E_Variable
4ac2bbbd
AC
6835 then
6836 Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
6837 end if;
07fc65c4 6838 end;
70482933 6839
6782b1ef
AC
6840 -- If the aggregate is the expression in a declaration, the expanded
6841 -- code must be inserted after it. The defining entity might not come
6842 -- from source if this is part of an inlined body, but the declaration
6843 -- itself will.
fff7a6d9 6844 -- The test below looks very specialized and kludgy???
6782b1ef
AC
6845
6846 if Comes_From_Source (Tmp)
6847 or else
6848 (Nkind (Parent (N)) = N_Object_Declaration
6849 and then Comes_From_Source (Parent (N))
6850 and then Tmp = Defining_Entity (Parent (N)))
6851 then
fff7a6d9 6852 if Parent_Kind /= N_Object_Declaration or else Is_Frozen (Tmp) then
cf6956bb 6853 Insert_Actions_After (Parent_Node, Aggr_Code);
fff7a6d9
AC
6854 else
6855 declare
6856 Comp_Stmt : constant Node_Id :=
6857 Make_Compound_Statement
6858 (Sloc (Parent_Node), Actions => Aggr_Code);
6859 begin
6860 Insert_Action_After (Parent_Node, Comp_Stmt);
6861 Set_Initialization_Statements (Tmp, Comp_Stmt);
6862 end;
6863 end if;
70482933
RK
6864 else
6865 Insert_Actions (N, Aggr_Code);
6866 end if;
6867
07fc65c4
GB
6868 -- If the aggregate has been assigned in place, remove the original
6869 -- assignment.
6870
a80b1eb7
EB
6871 if Parent_Kind = N_Assignment_Statement and then Maybe_In_Place_OK then
6872 Rewrite (Parent_Node, Make_Null_Statement (Loc));
70482933 6873
a80b1eb7
EB
6874 -- Or else, if a temporary was created, replace the aggregate with it
6875
6876 elsif Parent_Kind /= N_Object_Declaration
6877 or else Tmp /= Defining_Identifier (Parent_Node)
70482933
RK
6878 then
6879 Rewrite (N, New_Occurrence_Of (Tmp, Loc));
6880 Analyze_And_Resolve (N, Typ);
6881 end if;
6882 end Expand_Array_Aggregate;
6883
6884 ------------------------
6885 -- Expand_N_Aggregate --
6886 ------------------------
6887
6888 procedure Expand_N_Aggregate (N : Node_Id) is
74580e1b 6889 T : constant Entity_Id := Etype (N);
70482933 6890 begin
354c3840
AC
6891 -- Record aggregate case
6892
74580e1b
PT
6893 if Is_Record_Type (T)
6894 and then not Is_Private_Type (T)
fe3463cc 6895 then
70482933 6896 Expand_Record_Aggregate (N);
354c3840 6897
74580e1b 6898 elsif Has_Aspect (T, Aspect_Aggregate) then
745f5698
ES
6899 Expand_Container_Aggregate (N);
6900
354c3840
AC
6901 -- Array aggregate case
6902
70482933 6903 else
354c3840
AC
6904 -- A special case, if we have a string subtype with bounds 1 .. N,
6905 -- where N is known at compile time, and the aggregate is of the
49eef89f
AC
6906 -- form (others => 'x'), with a single choice and no expressions,
6907 -- and N is less than 80 (an arbitrary limit for now), then replace
6908 -- the aggregate by the equivalent string literal (but do not mark
a90bd866 6909 -- it as static since it is not).
354c3840
AC
6910
6911 -- Note: this entire circuit is redundant with respect to code in
6912 -- Expand_Array_Aggregate that collapses others choices to positional
6913 -- form, but there are two problems with that circuit:
6914
6915 -- a) It is limited to very small cases due to ill-understood
b465ef6f 6916 -- interactions with bootstrapping. That limit is removed by
354c3840
AC
6917 -- use of the No_Implicit_Loops restriction.
6918
77a40ec1 6919 -- b) It incorrectly ends up with the resulting expressions being
354c3840
AC
6920 -- considered static when they are not. For example, the
6921 -- following test should fail:
6922
6923 -- pragma Restrictions (No_Implicit_Loops);
6924 -- package NonSOthers4 is
6925 -- B : constant String (1 .. 6) := (others => 'A');
6926 -- DH : constant String (1 .. 8) := B & "BB";
6927 -- X : Integer;
6928 -- pragma Export (C, X, Link_Name => DH);
6929 -- end;
6930
6931 -- But it succeeds (DH looks static to pragma Export)
6932
a90bd866 6933 -- To be sorted out ???
354c3840
AC
6934
6935 if Present (Component_Associations (N)) then
6936 declare
6937 CA : constant Node_Id := First (Component_Associations (N));
6938 MX : constant := 80;
6939
6940 begin
00f45f30 6941 if Nkind (First (Choice_List (CA))) = N_Others_Choice
354c3840 6942 and then Nkind (Expression (CA)) = N_Character_Literal
49eef89f 6943 and then No (Expressions (N))
354c3840
AC
6944 then
6945 declare
74580e1b
PT
6946 X : constant Node_Id := First_Index (T);
6947 EC : constant Node_Id := Expression (CA);
6948 CV : constant Uint := Char_Literal_Value (EC);
6949 CC : constant Int := UI_To_Int (CV);
354c3840
AC
6950
6951 begin
6952 if Nkind (X) = N_Range
6953 and then Compile_Time_Known_Value (Low_Bound (X))
6954 and then Expr_Value (Low_Bound (X)) = 1
6955 and then Compile_Time_Known_Value (High_Bound (X))
6956 then
6957 declare
6958 Hi : constant Uint := Expr_Value (High_Bound (X));
6959
6960 begin
6961 if Hi <= MX then
6962 Start_String;
6963
6964 for J in 1 .. UI_To_Int (Hi) loop
6965 Store_String_Char (Char_Code (CC));
6966 end loop;
6967
6968 Rewrite (N,
6969 Make_String_Literal (Sloc (N),
6970 Strval => End_String));
6971
6972 if CC >= Int (2 ** 16) then
6973 Set_Has_Wide_Wide_Character (N);
6974 elsif CC >= Int (2 ** 8) then
6975 Set_Has_Wide_Character (N);
6976 end if;
6977
6978 Analyze_And_Resolve (N, T);
6979 Set_Is_Static_Expression (N, False);
6980 return;
6981 end if;
6982 end;
6983 end if;
6984 end;
6985 end if;
6986 end;
6987 end if;
6988
6989 -- Not that special case, so normal expansion of array aggregate
6990
70482933
RK
6991 Expand_Array_Aggregate (N);
6992 end if;
bdc193ba 6993
fbf5a39b
AC
6994 exception
6995 when RE_Not_Available =>
6996 return;
70482933
RK
6997 end Expand_N_Aggregate;
6998
745f5698
ES
6999 --------------------------------
7000 -- Expand_Container_Aggregate --
7001 --------------------------------
7002
7003 procedure Expand_Container_Aggregate (N : Node_Id) is
ce59f39f
GD
7004 Loc : constant Source_Ptr := Sloc (N);
7005 Typ : constant Entity_Id := Etype (N);
7006 Asp : constant Node_Id := Find_Value_Of_Aspect (Typ, Aspect_Aggregate);
745f5698
ES
7007
7008 Empty_Subp : Node_Id := Empty;
7009 Add_Named_Subp : Node_Id := Empty;
7010 Add_Unnamed_Subp : Node_Id := Empty;
7011 New_Indexed_Subp : Node_Id := Empty;
7012 Assign_Indexed_Subp : Node_Id := Empty;
7013
ce59f39f
GD
7014 Aggr_Code : constant List_Id := New_List;
7015 Temp : constant Entity_Id := Make_Temporary (Loc, 'C', N);
745f5698 7016
4f6ebe2a 7017 Comp : Node_Id;
745f5698 7018 Decl : Node_Id;
08c8883f 7019 Default : Node_Id;
ce59f39f 7020 Init_Stat : Node_Id;
08c8883f
ES
7021 Siz : Int;
7022
13112239
ES
7023 -- The following are used when the size of the aggregate is not
7024 -- static and requires a dynamic evaluation.
7025 Siz_Decl : Node_Id;
7026 Siz_Exp : Node_Id := Empty;
7027 Count_Type : Entity_Id;
7028
08c8883f
ES
7029 function Aggregate_Size return Int;
7030 -- Compute number of entries in aggregate, including choices
13112239 7031 -- that cover a range or subtype, as well as iterated constructs.
08c8883f 7032 -- Return -1 if the size is not known statically, in which case
13112239
ES
7033 -- allocate a default size for the aggregate, or build an expression
7034 -- to estimate the size dynamically.
7035
7036 function Build_Siz_Exp (Comp : Node_Id) return Int;
7037 -- When the aggregate contains a single Iterated_Component_Association
7038 -- or Element_Association with non-static bounds, build an expression
7039 -- to be used as the allocated size of the container. This may be an
7040 -- overestimate if a filter is present, but is a safe approximation.
ce59f39f 7041
7a21651f
ES
7042 procedure Expand_Iterated_Component (Comp : Node_Id);
7043 -- Handle iterated_component_association and iterated_Element
7044 -- association by generating a loop over the specified range,
7045 -- given either by a loop parameter specification or an iterator
7046 -- specification.
7047
08c8883f
ES
7048 --------------------
7049 -- Aggregate_Size --
7050 --------------------
7051
7052 function Aggregate_Size return Int is
7053 Comp : Node_Id;
7054 Choice : Node_Id;
7055 Lo, Hi : Node_Id;
7056 Siz : Int := 0;
7057
7058 procedure Add_Range_Size;
13112239
ES
7059 -- Compute number of components specified by a component association
7060 -- given by a range or subtype name.
7061
7062 --------------------
7063 -- Add_Range_Size --
7064 --------------------
08c8883f
ES
7065
7066 procedure Add_Range_Size is
7067 begin
13112239
ES
7068 -- The bounds of the discrete range are integers or enumeration
7069 -- literals
7070
08c8883f
ES
7071 if Nkind (Lo) = N_Integer_Literal then
7072 Siz := Siz + UI_To_Int (Intval (Hi))
13112239
ES
7073 - UI_To_Int (Intval (Lo)) + 1;
7074 else
7075 Siz := Siz + UI_To_Int (Enumeration_Pos (Hi))
7076 - UI_To_Int (Enumeration_Pos (Lo)) + 1;
08c8883f
ES
7077 end if;
7078 end Add_Range_Size;
7079
7080 begin
13112239
ES
7081 -- Aggregate is either all positional or all named.
7082
08c8883f
ES
7083 if Present (Expressions (N)) then
7084 Siz := List_Length (Expressions (N));
7085 end if;
7086
7087 if Present (Component_Associations (N)) then
7088 Comp := First (Component_Associations (N));
13112239
ES
7089 -- If there is a single component association it can be
7090 -- an iterated component with dynamic bounds or an element
7091 -- iterator over an iterable object. If it is an array
7092 -- we can use the attribute Length to get its size;
7093 -- for a predefined container the function Length plays
7094 -- the same role. There is no available mechanism for
7095 -- user-defined containers. For now we treat all of these
7096 -- as dynamic.
7097
7098 if List_Length (Component_Associations (N)) = 1
7099 and then Nkind (Comp) in N_Iterated_Component_Association |
7100 N_Iterated_Element_Association
7101 then
7102 return Build_Siz_Exp (Comp);
daaf0179
ES
7103 end if;
7104
13112239
ES
7105 -- Otherwise all associations must specify static sizes.
7106
08c8883f
ES
7107 while Present (Comp) loop
7108 Choice := First (Choice_List (Comp));
7109
7110 while Present (Choice) loop
7111 Analyze (Choice);
7112
7113 if Nkind (Choice) = N_Range then
7114 Lo := Low_Bound (Choice);
7115 Hi := High_Bound (Choice);
13112239 7116 Add_Range_Size;
08c8883f
ES
7117
7118 elsif Is_Entity_Name (Choice)
7119 and then Is_Type (Entity (Choice))
7120 then
7121 Lo := Type_Low_Bound (Entity (Choice));
7122 Hi := Type_High_Bound (Entity (Choice));
13112239 7123 Add_Range_Size;
08c8883f
ES
7124
7125 Rewrite (Choice,
7126 Make_Range (Loc,
7127 New_Copy_Tree (Lo),
7128 New_Copy_Tree (Hi)));
7129
7130 else
7131 -- Single choice (syntax excludes a subtype
7132 -- indication).
7133
7134 Siz := Siz + 1;
7135 end if;
7136
7137 Next (Choice);
7138 end loop;
7139 Next (Comp);
7140 end loop;
7141 end if;
7142
7143 return Siz;
7144 end Aggregate_Size;
7145
13112239
ES
7146 -------------------
7147 -- Build_Siz_Exp --
7148 -------------------
7149
7150 function Build_Siz_Exp (Comp : Node_Id) return Int is
7151 Lo, Hi : Node_Id;
7152 begin
7153 if Nkind (Comp) = N_Range then
7154 Lo := Low_Bound (Comp);
7155 Hi := High_Bound (Comp);
7156 Analyze (Lo);
7157 Analyze (Hi);
7158
7159 -- Compute static size when possible.
7160
7161 if Is_Static_Expression (Lo)
7162 and then Is_Static_Expression (Hi)
7163 then
7164 if Nkind (Lo) = N_Integer_Literal then
7165 Siz := UI_To_Int (Intval (Hi)) - UI_To_Int (Intval (Lo)) + 1;
7166 else
7167 Siz := UI_To_Int (Enumeration_Pos (Hi))
7168 - UI_To_Int (Enumeration_Pos (Lo)) + 1;
7169 end if;
7170 return Siz;
7171
7172 else
7173 Siz_Exp :=
7174 Make_Op_Add (Sloc (Comp),
7175 Left_Opnd =>
7176 Make_Op_Subtract (Sloc (Comp),
7177 Left_Opnd => New_Copy_Tree (Hi),
7178 Right_Opnd => New_Copy_Tree (Lo)),
7179 Right_Opnd =>
7180 Make_Integer_Literal (Loc, 1));
7181 return -1;
7182 end if;
7183
7184 elsif Nkind (Comp) = N_Iterated_Component_Association then
7185 return Build_Siz_Exp (First (Discrete_Choices (Comp)));
7186
7187 elsif Nkind (Comp) = N_Iterated_Element_Association then
4463d6ee 7188 return -1; -- ??? build expression for size of the domain
13112239
ES
7189
7190 else
7191 return -1;
7192 end if;
7193 end Build_Siz_Exp;
7194
4f6ebe2a
ES
7195 -------------------------------
7196 -- Expand_Iterated_Component --
7197 -------------------------------
7198
7199 procedure Expand_Iterated_Component (Comp : Node_Id) is
7200 Expr : constant Node_Id := Expression (Comp);
4f6ebe2a 7201
c0bab60b
ES
7202 Key_Expr : Node_Id := Empty;
7203 Loop_Id : Entity_Id;
4f6ebe2a
ES
7204 L_Range : Node_Id;
7205 L_Iteration_Scheme : Node_Id;
7206 Loop_Stat : Node_Id;
f3f1debe 7207 Params : List_Id;
4f6ebe2a
ES
7208 Stats : List_Id;
7209
7210 begin
c0bab60b
ES
7211 if Nkind (Comp) = N_Iterated_Element_Association then
7212 Key_Expr := Key_Expression (Comp);
7213
7214 -- We create a new entity as loop identifier in all cases,
7215 -- as is done for generated loops elsewhere, as the loop
7216 -- structure has been previously analyzed.
7217
7218 if Present (Iterator_Specification (Comp)) then
7219
7220 -- Either an Iterator_Specification of a Loop_Parameter_
7221 -- Specification is present.
7222
7223 L_Iteration_Scheme :=
7224 Make_Iteration_Scheme (Loc,
7225 Iterator_Specification => Iterator_Specification (Comp));
7226 Loop_Id :=
7227 Make_Defining_Identifier (Loc,
7228 Chars => Chars (Defining_Identifier
7229 (Iterator_Specification (Comp))));
7230 Set_Defining_Identifier
7231 (Iterator_Specification (L_Iteration_Scheme), Loop_Id);
7232
7233 else
7234 L_Iteration_Scheme :=
7235 Make_Iteration_Scheme (Loc,
7236 Loop_Parameter_Specification =>
7237 Loop_Parameter_Specification (Comp));
7238 Loop_Id :=
f3f1debe
ES
7239 Make_Defining_Identifier (Loc,
7240 Chars => Chars (Defining_Identifier
7241 (Loop_Parameter_Specification (Comp))));
c0bab60b 7242 Set_Defining_Identifier
f3f1debe
ES
7243 (Loop_Parameter_Specification
7244 (L_Iteration_Scheme), Loop_Id);
c0bab60b 7245 end if;
f3f1debe 7246 else
c0bab60b 7247
f3f1debe 7248 -- Iterated_Component_Association.
8092c199 7249
c0bab60b
ES
7250 Loop_Id :=
7251 Make_Defining_Identifier (Loc,
7252 Chars => Chars (Defining_Identifier (Comp)));
7253
f3f1debe
ES
7254 if Present (Iterator_Specification (Comp)) then
7255 L_Iteration_Scheme :=
7256 Make_Iteration_Scheme (Loc,
7257 Iterator_Specification => Iterator_Specification (Comp));
7258
7259 else
7260 -- Loop_Parameter_Specifcation is parsed with a choice list.
7261 -- where the range is the first (and only) choice.
7262
7263 L_Range := Relocate_Node (First (Discrete_Choices (Comp)));
7264
7265 L_Iteration_Scheme :=
7266 Make_Iteration_Scheme (Loc,
7267 Loop_Parameter_Specification =>
7268 Make_Loop_Parameter_Specification (Loc,
7269 Defining_Identifier => Loop_Id,
7270 Discrete_Subtype_Definition => L_Range));
7271 end if;
8092c199 7272 end if;
4f6ebe2a 7273
0b4034c0
GD
7274 -- Build insertion statement. For a positional aggregate, only the
7275 -- expression is needed. For a named aggregate, the loop variable,
7276 -- whose type is that of the key, is an additional parameter for
7277 -- the insertion operation.
c0bab60b
ES
7278 -- If a Key_Expression is present, it serves as the additional
7279 -- parameter. Otherwise the key is given by the loop parameter
7280 -- itself.
4f6ebe2a 7281
13112239
ES
7282 if Present (Add_Unnamed_Subp)
7283 and then No (Add_Named_Subp)
7284 then
4f6ebe2a
ES
7285 Stats := New_List
7286 (Make_Procedure_Call_Statement (Loc,
0b4034c0
GD
7287 Name => New_Occurrence_Of (Entity (Add_Unnamed_Subp), Loc),
7288 Parameter_Associations =>
7289 New_List (New_Occurrence_Of (Temp, Loc),
4f6ebe2a
ES
7290 New_Copy_Tree (Expr))));
7291 else
c0bab60b
ES
7292 -- Named or indexed aggregate, for which a key is present,
7293 -- possibly with a specified key_expression.
7294
7295 if Present (Key_Expr) then
f3f1debe
ES
7296 Params := New_List (New_Occurrence_Of (Temp, Loc),
7297 New_Copy_Tree (Key_Expr),
7298 New_Copy_Tree (Expr));
c0bab60b 7299 else
f3f1debe
ES
7300 Params := New_List (New_Occurrence_Of (Temp, Loc),
7301 New_Occurrence_Of (Loop_Id, Loc),
7302 New_Copy_Tree (Expr));
c0bab60b 7303 end if;
f3f1debe
ES
7304
7305 Stats := New_List
7306 (Make_Procedure_Call_Statement (Loc,
7307 Name => New_Occurrence_Of (Entity (Add_Named_Subp), Loc),
7308 Parameter_Associations => Params));
4f6ebe2a
ES
7309 end if;
7310
7311 Loop_Stat := Make_Implicit_Loop_Statement
7312 (Node => N,
7313 Identifier => Empty,
7314 Iteration_Scheme => L_Iteration_Scheme,
7315 Statements => Stats);
7316 Append (Loop_Stat, Aggr_Code);
7a21651f 7317
4f6ebe2a
ES
7318 end Expand_Iterated_Component;
7319
08c8883f
ES
7320 -- Start of processing for Expand_Container_Aggregate
7321
745f5698
ES
7322 begin
7323 Parse_Aspect_Aggregate (Asp,
7324 Empty_Subp, Add_Named_Subp, Add_Unnamed_Subp,
7325 New_Indexed_Subp, Assign_Indexed_Subp);
08c8883f
ES
7326
7327 -- The constructor for bounded containers is a function with
7328 -- a parameter that sets the size of the container. If the
13112239
ES
7329 -- size cannot be determined statically we use a default value
7330 -- or a dynamic expression.
08c8883f
ES
7331
7332 Siz := Aggregate_Size;
7a21651f 7333
08c8883f
ES
7334 if Ekind (Entity (Empty_Subp)) = E_Function
7335 and then Present (First_Formal (Entity (Empty_Subp)))
7336 then
7337 Default := Default_Value (First_Formal (Entity (Empty_Subp)));
13112239
ES
7338
7339 -- If aggregate size is not static, we can use default value
7340 -- of formal parameter for allocation. We assume that this
08c8883f 7341 -- (implementation-dependent) value is static, even though
13112239
ES
7342 -- the AI does not require it.
7343
7344 -- Create declaration for size: a constant literal in the simple
7345 -- case, an expression if iterated component associations may be
7346 -- involved, the default otherwise.
08c8883f 7347
13112239
ES
7348 Count_Type := Etype (First_Formal (Entity (Empty_Subp)));
7349 if Siz = -1 then
7350 if No (Siz_Exp) then
7351 Siz := UI_To_Int (Intval (Default));
7352 Siz_Exp := Make_Integer_Literal (Loc, Siz);
7353
7354 else
7355 Siz_Exp := Make_Type_Conversion (Loc,
7356 Subtype_Mark =>
7357 New_Occurrence_Of (Count_Type, Loc),
7358 Expression => Siz_Exp);
7359 end if;
7360
7361 else
7362 Siz_Exp := Make_Integer_Literal (Loc, Siz);
08c8883f
ES
7363 end if;
7364
13112239
ES
7365 Siz_Decl := Make_Object_Declaration (Loc,
7366 Defining_Identifier => Make_Temporary (Loc, 'S', N),
7367 Object_Definition =>
7368 New_Occurrence_Of (Count_Type, Loc),
7369 Expression => Siz_Exp);
7370 Append (Siz_Decl, Aggr_Code);
7371
7372 if Nkind (Siz_Exp) = N_Integer_Literal then
7373 Init_Stat :=
7374 Make_Object_Declaration (Loc,
7375 Defining_Identifier => Temp,
7376 Object_Definition => New_Occurrence_Of (Typ, Loc),
7377 Expression => Make_Function_Call (Loc,
7378 Name => New_Occurrence_Of (Entity (Empty_Subp), Loc),
7379 Parameter_Associations =>
7380 New_List
7381 (New_Occurrence_Of
7382 (Defining_Identifier (Siz_Decl), Loc))));
7383
7384 else
7385 Init_Stat :=
7386 Make_Object_Declaration (Loc,
7387 Defining_Identifier => Temp,
7388 Object_Definition => New_Occurrence_Of (Typ, Loc),
7389 Expression => Make_Function_Call (Loc,
7390 Name =>
7391 New_Occurrence_Of (Entity (New_Indexed_Subp), Loc),
7392 Parameter_Associations =>
7393 New_List (
7394 Make_Integer_Literal (Loc, 1),
7395 New_Occurrence_Of
7396 (Defining_Identifier (Siz_Decl), Loc))));
7397 end if;
08c8883f
ES
7398
7399 Append (Init_Stat, Aggr_Code);
7400
13112239
ES
7401 -- Size is dynamic: Create declaration for object, and intitialize
7402 -- with a call to the null container, or an assignment to it.
08c8883f
ES
7403
7404 else
7405 Decl :=
7406 Make_Object_Declaration (Loc,
7407 Defining_Identifier => Temp,
7408 Object_Definition => New_Occurrence_Of (Typ, Loc));
7409
7410 Insert_Action (N, Decl);
13112239
ES
7411
7412 -- The Empty entity is either a parameterless function, or
7413 -- a constant.
7414
08c8883f
ES
7415 if Ekind (Entity (Empty_Subp)) = E_Function then
7416 Init_Stat := Make_Assignment_Statement (Loc,
7417 Name => New_Occurrence_Of (Temp, Loc),
7418 Expression => Make_Function_Call (Loc,
7419 Name => New_Occurrence_Of (Entity (Empty_Subp), Loc)));
13112239 7420
08c8883f
ES
7421 else
7422 Init_Stat := Make_Assignment_Statement (Loc,
7423 Name => New_Occurrence_Of (Temp, Loc),
7424 Expression => New_Occurrence_Of (Entity (Empty_Subp), Loc));
7425 end if;
7426
7427 Append (Init_Stat, Aggr_Code);
7428 end if;
745f5698 7429
7a21651f
ES
7430 ---------------------------
7431 -- Positional aggregate --
7432 ---------------------------
745f5698 7433
08c8883f
ES
7434 -- If the aggregate is positional the aspect must include
7435 -- an Add_Unnamed subprogram.
7436
13112239 7437 if Present (Add_Unnamed_Subp) then
4f6ebe2a
ES
7438 if Present (Expressions (N)) then
7439 declare
7440 Insert : constant Entity_Id := Entity (Add_Unnamed_Subp);
7441 Comp : Node_Id;
7442 Stat : Node_Id;
7443
7444 begin
7445 Comp := First (Expressions (N));
7446 while Present (Comp) loop
7447 Stat := Make_Procedure_Call_Statement (Loc,
7448 Name => New_Occurrence_Of (Insert, Loc),
7449 Parameter_Associations =>
7450 New_List (New_Occurrence_Of (Temp, Loc),
0b4034c0 7451 New_Copy_Tree (Comp)));
4f6ebe2a
ES
7452 Append (Stat, Aggr_Code);
7453 Next (Comp);
7454 end loop;
7455 end;
7456 end if;
7457
13112239
ES
7458 -- Indexed aggregates are handled below. Unnamed aggregates
7459 -- such as sets may include iterated component associations.
4f6ebe2a 7460
13112239
ES
7461 if No (New_Indexed_Subp) then
7462 Comp := First (Component_Associations (N));
7463 while Present (Comp) loop
7464 if Nkind (Comp) = N_Iterated_Component_Association then
7465 Expand_Iterated_Component (Comp);
7466 end if;
7467 Next (Comp);
7468 end loop;
7469 end if;
4f6ebe2a 7470
7a21651f
ES
7471 ---------------------
7472 -- Named_Aggregate --
7473 ---------------------
7474
4f6ebe2a 7475 elsif Present (Add_Named_Subp) then
ce59f39f 7476 declare
4f6ebe2a 7477 Insert : constant Entity_Id := Entity (Add_Named_Subp);
ce59f39f 7478 Stat : Node_Id;
4f6ebe2a 7479 Key : Node_Id;
ce59f39f 7480 begin
4f6ebe2a
ES
7481 Comp := First (Component_Associations (N));
7482
0b4034c0 7483 -- Each component association may contain several choices;
4f6ebe2a
ES
7484 -- generate an insertion statement for each.
7485
ce59f39f 7486 while Present (Comp) loop
c0bab60b
ES
7487 if Nkind (Comp) in N_Iterated_Component_Association
7488 | N_Iterated_Element_Association
7489 then
4f6ebe2a
ES
7490 Expand_Iterated_Component (Comp);
7491 else
7492 Key := First (Choices (Comp));
7493
7494 while Present (Key) loop
7495 Stat := Make_Procedure_Call_Statement (Loc,
7496 Name => New_Occurrence_Of (Insert, Loc),
7497 Parameter_Associations =>
7498 New_List (New_Occurrence_Of (Temp, Loc),
0b4034c0
GD
7499 New_Copy_Tree (Key),
7500 New_Copy_Tree (Expression (Comp))));
4f6ebe2a
ES
7501 Append (Stat, Aggr_Code);
7502
7503 Next (Key);
7504 end loop;
7505 end if;
7506
ce59f39f
GD
7507 Next (Comp);
7508 end loop;
7509 end;
08c8883f 7510 end if;
7a21651f
ES
7511
7512 -----------------------
7513 -- Indexed_Aggregate --
7514 -----------------------
7515
08c8883f
ES
7516 -- For an indexed aggregate there must be an Assigned_Indexeed
7517 -- subprogram. Note that unlike array aggregates, a container
7518 -- aggregate must be fully positional or fully indexed. In the
7519 -- first case the expansion has already taken place.
13112239
ES
7520 -- TBA: the keys for an indexed aggregate must provide a dense
7521 -- range with no repetitions.
08c8883f
ES
7522
7523 if Present (Assign_Indexed_Subp)
7524 and then Present (Component_Associations (N))
7525 then
7a21651f
ES
7526 declare
7527 Insert : constant Entity_Id := Entity (Assign_Indexed_Subp);
7528 Index_Type : constant Entity_Id :=
7529 Etype (Next_Formal (First_Formal (Insert)));
7530
7a21651f
ES
7531 function Expand_Range_Component
7532 (Rng : Node_Id;
7533 Expr : Node_Id) return Node_Id;
7534 -- Transform a component assoication with a range into an
7535 -- explicit loop. If the choice is a subtype name, it is
7536 -- rewritten as a range with the corresponding bounds, which
7537 -- are known to be static.
7538
7539 Comp : Node_Id;
7540 Index : Node_Id;
7541 Pos : Int := 0;
7542 Stat : Node_Id;
7543 Key : Node_Id;
7a21651f
ES
7544
7545 -----------------------------
7546 -- Expand_Raange_Component --
7547 -----------------------------
7548
7549 function Expand_Range_Component
7550 (Rng : Node_Id;
7551 Expr : Node_Id) return Node_Id
7552 is
7553 Loop_Id : constant Entity_Id :=
7554 Make_Temporary (Loc, 'T');
7555
7556 L_Iteration_Scheme : Node_Id;
7557 Stats : List_Id;
7558
7559 begin
7560 L_Iteration_Scheme :=
7561 Make_Iteration_Scheme (Loc,
7562 Loop_Parameter_Specification =>
7563 Make_Loop_Parameter_Specification (Loc,
7564 Defining_Identifier => Loop_Id,
7565 Discrete_Subtype_Definition => New_Copy_Tree (Rng)));
7566
7567 Stats := New_List
7568 (Make_Procedure_Call_Statement (Loc,
7569 Name =>
7570 New_Occurrence_Of (Entity (Assign_Indexed_Subp), Loc),
7571 Parameter_Associations =>
7572 New_List (New_Occurrence_Of (Temp, Loc),
7573 New_Occurrence_Of (Loop_Id, Loc),
7574 New_Copy_Tree (Expr))));
7575
7576 return Make_Implicit_Loop_Statement
7577 (Node => N,
7578 Identifier => Empty,
7579 Iteration_Scheme => L_Iteration_Scheme,
7580 Statements => Stats);
7581 end Expand_Range_Component;
7582
7a21651f 7583 begin
08c8883f 7584 if Siz > 0 then
7a21651f
ES
7585
7586 -- Modify the call to the constructor to allocate the
7587 -- required size for the aggregwte : call the provided
7588 -- constructor rather than the Empty aggregate.
7589
7590 Index := Make_Op_Add (Loc,
7591 Left_Opnd => New_Copy_Tree (Type_Low_Bound (Index_Type)),
08c8883f 7592 Right_Opnd => Make_Integer_Literal (Loc, Siz - 1));
7a21651f
ES
7593
7594 Set_Expression (Init_Stat,
7595 Make_Function_Call (Loc,
7596 Name =>
7597 New_Occurrence_Of (Entity (New_Indexed_Subp), Loc),
7598 Parameter_Associations =>
7599 New_List (
7600 New_Copy_Tree (Type_Low_Bound (Index_Type)),
7601 Index)));
7602 end if;
7603
7604 if Present (Expressions (N)) then
7605 Comp := First (Expressions (N));
7606
7607 while Present (Comp) loop
7608
7609 -- Compute index position for successive components
7610 -- in the list of expressions, and use the indexed
7611 -- assignment procedure for each.
7612
7613 Index := Make_Op_Add (Loc,
7614 Left_Opnd => Type_Low_Bound (Index_Type),
7615 Right_Opnd => Make_Integer_Literal (Loc, Pos));
7616
7617 Stat := Make_Procedure_Call_Statement (Loc,
7618 Name => New_Occurrence_Of (Insert, Loc),
7619 Parameter_Associations =>
7620 New_List (New_Occurrence_Of (Temp, Loc),
7621 Index,
7622 New_Copy_Tree (Comp)));
7623
7624 Pos := Pos + 1;
7625
7626 Append (Stat, Aggr_Code);
7627 Next (Comp);
7628 end loop;
7629 end if;
7630
7631 if Present (Component_Associations (N)) then
7632 Comp := First (Component_Associations (N));
7633
7634 -- The choice may be a static value, or a range with
7635 -- static bounds.
7636
7637 while Present (Comp) loop
7638 if Nkind (Comp) = N_Component_Association then
7639 Key := First (Choices (Comp));
7640 while Present (Key) loop
7641
7642 -- If the expression is a box, the corresponding
7643 -- component (s) is left uninitialized.
7644
7645 if Box_Present (Comp) then
7646 goto Next_Key;
7647
7648 elsif Nkind (Key) = N_Range then
7649
7650 -- Create loop for tne specified range,
7651 -- with copies of the expression.
7652
7653 Stat :=
7654 Expand_Range_Component (Key, Expression (Comp));
7655
7656 else
7657 Stat := Make_Procedure_Call_Statement (Loc,
7658 Name => New_Occurrence_Of
7659 (Entity (Assign_Indexed_Subp), Loc),
7660 Parameter_Associations =>
7661 New_List (New_Occurrence_Of (Temp, Loc),
7662 New_Copy_Tree (Key),
7663 New_Copy_Tree (Expression (Comp))));
7664 end if;
7665
7666 Append (Stat, Aggr_Code);
7667
7668 <<Next_Key>>
7669 Next (Key);
7670 end loop;
08c8883f 7671
7a21651f 7672 else
08c8883f
ES
7673 -- Iterated component association. Discard
7674 -- positional insertion procedure.
7675
7676 Add_Named_Subp := Assign_Indexed_Subp;
7677 Add_Unnamed_Subp := Empty;
7678 Expand_Iterated_Component (Comp);
7a21651f 7679 end if;
08c8883f 7680
7a21651f
ES
7681 Next (Comp);
7682 end loop;
7683 end if;
7684 end;
ce59f39f 7685 end if;
4f6ebe2a 7686
ce59f39f
GD
7687 Insert_Actions (N, Aggr_Code);
7688 Rewrite (N, New_Occurrence_Of (Temp, Loc));
7689 Analyze_And_Resolve (N, Typ);
745f5698
ES
7690 end Expand_Container_Aggregate;
7691
9eb8d5b4
AC
7692 ------------------------------
7693 -- Expand_N_Delta_Aggregate --
7694 ------------------------------
7695
7696 procedure Expand_N_Delta_Aggregate (N : Node_Id) is
9313a26a 7697 Loc : constant Source_Ptr := Sloc (N);
c78efe92 7698 Typ : constant Entity_Id := Etype (Expression (N));
9eb8d5b4
AC
7699 Decl : Node_Id;
7700
7701 begin
9313a26a
AC
7702 Decl :=
7703 Make_Object_Declaration (Loc,
7704 Defining_Identifier => Make_Temporary (Loc, 'T'),
7705 Object_Definition => New_Occurrence_Of (Typ, Loc),
7706 Expression => New_Copy_Tree (Expression (N)));
9eb8d5b4
AC
7707
7708 if Is_Array_Type (Etype (N)) then
7709 Expand_Delta_Array_Aggregate (N, New_List (Decl));
7710 else
7711 Expand_Delta_Record_Aggregate (N, New_List (Decl));
7712 end if;
7713 end Expand_N_Delta_Aggregate;
7714
7715 ----------------------------------
7716 -- Expand_Delta_Array_Aggregate --
7717 ----------------------------------
7718
7719 procedure Expand_Delta_Array_Aggregate (N : Node_Id; Deltas : List_Id) is
9313a26a
AC
7720 Loc : constant Source_Ptr := Sloc (N);
7721 Temp : constant Entity_Id := Defining_Identifier (First (Deltas));
7722 Assoc : Node_Id;
7723
9eb8d5b4
AC
7724 function Generate_Loop (C : Node_Id) return Node_Id;
7725 -- Generate a loop containing individual component assignments for
7726 -- choices that are ranges, subtype indications, subtype names, and
7727 -- iterated component associations.
7728
9313a26a
AC
7729 -------------------
7730 -- Generate_Loop --
7731 -------------------
7732
9eb8d5b4
AC
7733 function Generate_Loop (C : Node_Id) return Node_Id is
7734 Sl : constant Source_Ptr := Sloc (C);
7735 Ix : Entity_Id;
7736
7737 begin
7738 if Nkind (Parent (C)) = N_Iterated_Component_Association then
7739 Ix :=
7740 Make_Defining_Identifier (Loc,
7741 Chars => (Chars (Defining_Identifier (Parent (C)))));
7742 else
7743 Ix := Make_Temporary (Sl, 'I');
7744 end if;
7745
7746 return
7747 Make_Loop_Statement (Loc,
9313a26a
AC
7748 Iteration_Scheme =>
7749 Make_Iteration_Scheme (Sl,
7750 Loop_Parameter_Specification =>
7751 Make_Loop_Parameter_Specification (Sl,
7752 Defining_Identifier => Ix,
7753 Discrete_Subtype_Definition => New_Copy_Tree (C))),
7754
7755 Statements => New_List (
7756 Make_Assignment_Statement (Sl,
7757 Name =>
7758 Make_Indexed_Component (Sl,
9eb8d5b4
AC
7759 Prefix => New_Occurrence_Of (Temp, Sl),
7760 Expressions => New_List (New_Occurrence_Of (Ix, Sl))),
9313a26a
AC
7761 Expression => New_Copy_Tree (Expression (Assoc)))),
7762 End_Label => Empty);
9eb8d5b4
AC
7763 end Generate_Loop;
7764
9313a26a
AC
7765 -- Local variables
7766
7767 Choice : Node_Id;
7768
7769 -- Start of processing for Expand_Delta_Array_Aggregate
7770
9eb8d5b4
AC
7771 begin
7772 Assoc := First (Component_Associations (N));
7773 while Present (Assoc) loop
7774 Choice := First (Choice_List (Assoc));
7775 if Nkind (Assoc) = N_Iterated_Component_Association then
7776 while Present (Choice) loop
7777 Append_To (Deltas, Generate_Loop (Choice));
7778 Next (Choice);
7779 end loop;
7780
7781 else
7782 while Present (Choice) loop
7783
7784 -- Choice can be given by a range, a subtype indication, a
7785 -- subtype name, a scalar value, or an entity.
7786
7787 if Nkind (Choice) = N_Range
7788 or else (Is_Entity_Name (Choice)
9313a26a 7789 and then Is_Type (Entity (Choice)))
9eb8d5b4
AC
7790 then
7791 Append_To (Deltas, Generate_Loop (Choice));
7792
7793 elsif Nkind (Choice) = N_Subtype_Indication then
7794 Append_To (Deltas,
7795 Generate_Loop (Range_Expression (Constraint (Choice))));
7796
7797 else
7798 Append_To (Deltas,
9313a26a
AC
7799 Make_Assignment_Statement (Sloc (Choice),
7800 Name =>
7801 Make_Indexed_Component (Sloc (Choice),
7802 Prefix => New_Occurrence_Of (Temp, Loc),
7803 Expressions => New_List (New_Copy_Tree (Choice))),
7804 Expression => New_Copy_Tree (Expression (Assoc))));
9eb8d5b4
AC
7805 end if;
7806
7807 Next (Choice);
7808 end loop;
7809 end if;
7810
7811 Next (Assoc);
7812 end loop;
7813
7814 Insert_Actions (N, Deltas);
7815 Rewrite (N, New_Occurrence_Of (Temp, Loc));
7816 end Expand_Delta_Array_Aggregate;
7817
7818 -----------------------------------
7819 -- Expand_Delta_Record_Aggregate --
7820 -----------------------------------
7821
7822 procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id) is
7823 Loc : constant Source_Ptr := Sloc (N);
7824 Temp : constant Entity_Id := Defining_Identifier (First (Deltas));
7825 Assoc : Node_Id;
7826 Choice : Node_Id;
7827
7828 begin
7829 Assoc := First (Component_Associations (N));
7830
7831 while Present (Assoc) loop
7832 Choice := First (Choice_List (Assoc));
7833 while Present (Choice) loop
7834 Append_To (Deltas,
9313a26a
AC
7835 Make_Assignment_Statement (Sloc (Choice),
7836 Name =>
7837 Make_Selected_Component (Sloc (Choice),
7838 Prefix => New_Occurrence_Of (Temp, Loc),
7839 Selector_Name => Make_Identifier (Loc, Chars (Choice))),
7840 Expression => New_Copy_Tree (Expression (Assoc))));
9eb8d5b4
AC
7841 Next (Choice);
7842 end loop;
7843
7844 Next (Assoc);
7845 end loop;
7846
7847 Insert_Actions (N, Deltas);
7848 Rewrite (N, New_Occurrence_Of (Temp, Loc));
7849 end Expand_Delta_Record_Aggregate;
7850
70482933
RK
7851 ----------------------------------
7852 -- Expand_N_Extension_Aggregate --
7853 ----------------------------------
7854
7855 -- If the ancestor part is an expression, add a component association for
7856 -- the parent field. If the type of the ancestor part is not the direct
d4dfb005
BD
7857 -- parent of the expected type, build recursively the needed ancestors.
7858 -- If the ancestor part is a subtype_mark, replace aggregate with a
7859 -- declaration for a temporary of the expected type, followed by
7860 -- individual assignments to the given components.
70482933
RK
7861
7862 procedure Expand_N_Extension_Aggregate (N : Node_Id) is
70482933 7863 A : constant Node_Id := Ancestor_Part (N);
3fc40cd7 7864 Loc : constant Source_Ptr := Sloc (N);
70482933
RK
7865 Typ : constant Entity_Id := Etype (N);
7866
7867 begin
fbf5a39b 7868 -- If the ancestor is a subtype mark, an init proc must be called
70482933
RK
7869 -- on the resulting object which thus has to be materialized in
7870 -- the front-end
7871
7872 if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
7873 Convert_To_Assignments (N, Typ);
7874
7875 -- The extension aggregate is transformed into a record aggregate
7876 -- of the following form (c1 and c2 are inherited components)
7877
7878 -- (Exp with c3 => a, c4 => b)
0877856b 7879 -- ==> (c1 => Exp.c1, c2 => Exp.c2, c3 => a, c4 => b)
70482933
RK
7880
7881 else
7882 Set_Etype (N, Typ);
7883
1f110335 7884 if Tagged_Type_Expansion then
70482933 7885 Expand_Record_Aggregate (N,
a9d8907c
JM
7886 Orig_Tag =>
7887 New_Occurrence_Of
7888 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc),
70482933 7889 Parent_Expr => A);
5c34e9cd
AC
7890
7891 -- No tag is needed in the case of a VM
7892
0f95b178 7893 else
5c34e9cd 7894 Expand_Record_Aggregate (N, Parent_Expr => A);
70482933
RK
7895 end if;
7896 end if;
fbf5a39b
AC
7897
7898 exception
7899 when RE_Not_Available =>
7900 return;
70482933
RK
7901 end Expand_N_Extension_Aggregate;
7902
7903 -----------------------------
7904 -- Expand_Record_Aggregate --
7905 -----------------------------
7906
7907 procedure Expand_Record_Aggregate
7908 (N : Node_Id;
7909 Orig_Tag : Node_Id := Empty;
7910 Parent_Expr : Node_Id := Empty)
7911 is
fbf5a39b
AC
7912 Loc : constant Source_Ptr := Sloc (N);
7913 Comps : constant List_Id := Component_Associations (N);
7914 Typ : constant Entity_Id := Etype (N);
7915 Base_Typ : constant Entity_Id := Base_Type (Typ);
70482933 7916
0f95b178
JM
7917 Static_Components : Boolean := True;
7918 -- Flag to indicate whether all components are compile-time known,
7919 -- and the aggregate can be constructed statically and handled by
d4dfb005 7920 -- the back-end. Set to False by Component_OK_For_Backend.
70482933 7921
54740d7d
AC
7922 procedure Build_Back_End_Aggregate;
7923 -- Build a proper aggregate to be handled by the back-end
7924
f6205414
AC
7925 function Compile_Time_Known_Composite_Value (N : Node_Id) return Boolean;
7926 -- Returns true if N is an expression of composite type which can be
7927 -- fully evaluated at compile time without raising constraint error.
7928 -- Such expressions can be passed as is to Gigi without any expansion.
7929 --
7930 -- This returns true for N_Aggregate with Compile_Time_Known_Aggregate
7931 -- set and constants whose expression is such an aggregate, recursively.
7932
d4dfb005 7933 function Component_OK_For_Backend return Boolean;
b465ef6f 7934 -- Check for presence of a component which makes it impossible for the
0f95b178
JM
7935 -- backend to process the aggregate, thus requiring the use of a series
7936 -- of assignment statements. Cases checked for are a nested aggregate
7937 -- needing Late_Expansion, the presence of a tagged component which may
7938 -- need tag adjustment, and a bit unaligned component reference.
4a76b687
ES
7939 --
7940 -- We also force expansion into assignments if a component is of a
7941 -- mutable type (including a private type with discriminants) because
7942 -- in that case the size of the component to be copied may be smaller
7943 -- than the side of the target, and there is no simple way for gigi
7944 -- to compute the size of the object to be copied.
7945 --
7946 -- NOTE: This is part of the ongoing work to define precisely the
7947 -- interface between front-end and back-end handling of aggregates.
7948 -- In general it is desirable to pass aggregates as they are to gigi,
7949 -- in order to minimize elaboration code. This is one case where the
7950 -- semantics of Ada complicate the analysis and lead to anomalies in
7951 -- the gcc back-end if the aggregate is not expanded into assignments.
d4dfb005
BD
7952 --
7953 -- NOTE: This sets the global Static_Components to False in most, but
7954 -- not all, cases when it returns False.
70482933 7955
9b7924dd
AC
7956 function Has_Per_Object_Constraint (L : List_Id) return Boolean;
7957 -- Return True if any element of L has Has_Per_Object_Constraint set.
7958 -- L should be the Choices component of an N_Component_Association.
7959
57a8057a
AC
7960 function Has_Visible_Private_Ancestor (Id : E) return Boolean;
7961 -- If any ancestor of the current type is private, the aggregate
b465ef6f 7962 -- cannot be built in place. We cannot rely on Has_Private_Ancestor,
57a8057a
AC
7963 -- because it will not be set when type and its parent are in the
7964 -- same scope, and the parent component needs expansion.
7965
7966 function Top_Level_Aggregate (N : Node_Id) return Node_Id;
7967 -- For nested aggregates return the ultimate enclosing aggregate; for
7968 -- non-nested aggregates return N.
7969
54740d7d
AC
7970 ------------------------------
7971 -- Build_Back_End_Aggregate --
7972 ------------------------------
f6205414 7973
54740d7d 7974 procedure Build_Back_End_Aggregate is
4f94fa11
AC
7975 Comp : Entity_Id;
7976 New_Comp : Node_Id;
7977 Tag_Value : Node_Id;
57a8057a
AC
7978
7979 begin
0f95b178
JM
7980 if Nkind (N) = N_Aggregate then
7981
3b9fa2df
ES
7982 -- If the aggregate is static and can be handled by the back-end,
7983 -- nothing left to do.
0f95b178
JM
7984
7985 if Static_Components then
7986 Set_Compile_Time_Known_Aggregate (N);
7987 Set_Expansion_Delayed (N, False);
7988 end if;
7989 end if;
7990
07fc65c4 7991 -- If no discriminants, nothing special to do
70482933 7992
07fc65c4 7993 if not Has_Discriminants (Typ) then
70482933
RK
7994 null;
7995
07fc65c4
GB
7996 -- Case of discriminants present
7997
70482933
RK
7998 elsif Is_Derived_Type (Typ) then
7999
138fc6f1
HK
8000 -- For untagged types, non-stored discriminants are replaced with
8001 -- stored discriminants, which are the ones that gigi uses to
8002 -- describe the type and its components.
70482933 8003
07fc65c4 8004 Generate_Aggregate_For_Derived_Type : declare
fbf5a39b 8005 procedure Prepend_Stored_Values (T : Entity_Id);
3b9fa2df
ES
8006 -- Scan the list of stored discriminants of the type, and add
8007 -- their values to the aggregate being built.
07fc65c4
GB
8008
8009 ---------------------------
fbf5a39b 8010 -- Prepend_Stored_Values --
07fc65c4
GB
8011 ---------------------------
8012
fbf5a39b 8013 procedure Prepend_Stored_Values (T : Entity_Id) is
54740d7d
AC
8014 Discr : Entity_Id;
8015 First_Comp : Node_Id := Empty;
8016
07fc65c4 8017 begin
54740d7d
AC
8018 Discr := First_Stored_Discriminant (T);
8019 while Present (Discr) loop
07fc65c4
GB
8020 New_Comp :=
8021 Make_Component_Association (Loc,
138fc6f1 8022 Choices => New_List (
54740d7d 8023 New_Occurrence_Of (Discr, Loc)),
07fc65c4 8024 Expression =>
bdc193ba
AC
8025 New_Copy_Tree
8026 (Get_Discriminant_Value
54740d7d 8027 (Discr,
07fc65c4
GB
8028 Typ,
8029 Discriminant_Constraint (Typ))));
8030
8031 if No (First_Comp) then
8032 Prepend_To (Component_Associations (N), New_Comp);
8033 else
8034 Insert_After (First_Comp, New_Comp);
8035 end if;
8036
8037 First_Comp := New_Comp;
54740d7d 8038 Next_Stored_Discriminant (Discr);
07fc65c4 8039 end loop;
fbf5a39b 8040 end Prepend_Stored_Values;
07fc65c4 8041
54740d7d
AC
8042 -- Local variables
8043
8044 Constraints : constant List_Id := New_List;
8045
8046 Discr : Entity_Id;
8047 Decl : Node_Id;
8048 Num_Disc : Nat := 0;
81a0f4a3 8049 Num_Stor : Nat := 0;
54740d7d 8050
07fc65c4 8051 -- Start of processing for Generate_Aggregate_For_Derived_Type
70482933
RK
8052
8053 begin
3b9fa2df 8054 -- Remove the associations for the discriminant of derived type
70482933 8055
54740d7d
AC
8056 declare
8057 First_Comp : Node_Id;
70482933 8058
54740d7d
AC
8059 begin
8060 First_Comp := First (Component_Associations (N));
8061 while Present (First_Comp) loop
8062 Comp := First_Comp;
8063 Next (First_Comp);
8064
8065 if Ekind (Entity (First (Choices (Comp)))) =
8066 E_Discriminant
8067 then
8068 Remove (Comp);
8069 Num_Disc := Num_Disc + 1;
8070 end if;
8071 end loop;
8072 end;
70482933 8073
fbf5a39b
AC
8074 -- Insert stored discriminant associations in the correct
8075 -- order. If there are more stored discriminants than new
3b9fa2df
ES
8076 -- discriminants, there is at least one new discriminant that
8077 -- constrains more than one of the stored discriminants. In
8078 -- this case we need to construct a proper subtype of the
8079 -- parent type, in order to supply values to all the
fbf5a39b
AC
8080 -- components. Otherwise there is one-one correspondence
8081 -- between the constraints and the stored discriminants.
70482933 8082
54740d7d
AC
8083 Discr := First_Stored_Discriminant (Base_Type (Typ));
8084 while Present (Discr) loop
81a0f4a3 8085 Num_Stor := Num_Stor + 1;
54740d7d 8086 Next_Stored_Discriminant (Discr);
70482933 8087 end loop;
07fc65c4 8088
fbf5a39b 8089 -- Case of more stored discriminants than new discriminants
07fc65c4 8090
81a0f4a3 8091 if Num_Stor > Num_Disc then
07fc65c4 8092
3b9fa2df
ES
8093 -- Create a proper subtype of the parent type, which is the
8094 -- proper implementation type for the aggregate, and convert
8095 -- it to the intended target type.
07fc65c4 8096
54740d7d
AC
8097 Discr := First_Stored_Discriminant (Base_Type (Typ));
8098 while Present (Discr) loop
07fc65c4 8099 New_Comp :=
37368818
RD
8100 New_Copy_Tree
8101 (Get_Discriminant_Value
54740d7d 8102 (Discr,
bdc193ba
AC
8103 Typ,
8104 Discriminant_Constraint (Typ)));
138fc6f1 8105
07fc65c4 8106 Append (New_Comp, Constraints);
54740d7d 8107 Next_Stored_Discriminant (Discr);
07fc65c4
GB
8108 end loop;
8109
8110 Decl :=
8111 Make_Subtype_Declaration (Loc,
191fcb3a 8112 Defining_Identifier => Make_Temporary (Loc, 'T'),
bdc193ba 8113 Subtype_Indication =>
07fc65c4
GB
8114 Make_Subtype_Indication (Loc,
8115 Subtype_Mark =>
8116 New_Occurrence_Of (Etype (Base_Type (Typ)), Loc),
bdc193ba 8117 Constraint =>
07fc65c4
GB
8118 Make_Index_Or_Discriminant_Constraint
8119 (Loc, Constraints)));
8120
8121 Insert_Action (N, Decl);
fbf5a39b 8122 Prepend_Stored_Values (Base_Type (Typ));
07fc65c4
GB
8123
8124 Set_Etype (N, Defining_Identifier (Decl));
8125 Set_Analyzed (N);
8126
8127 Rewrite (N, Unchecked_Convert_To (Typ, N));
8128 Analyze (N);
8129
8130 -- Case where we do not have fewer new discriminants than
3b9fa2df
ES
8131 -- stored discriminants, so in this case we can simply use the
8132 -- stored discriminants of the subtype.
07fc65c4
GB
8133
8134 else
fbf5a39b 8135 Prepend_Stored_Values (Typ);
07fc65c4
GB
8136 end if;
8137 end Generate_Aggregate_For_Derived_Type;
70482933
RK
8138 end if;
8139
8140 if Is_Tagged_Type (Typ) then
8141
22243c12 8142 -- In the tagged case, _parent and _tag component must be created
70482933 8143
22243c12
RD
8144 -- Reset Null_Present unconditionally. Tagged records always have
8145 -- at least one field (the tag or the parent).
70482933
RK
8146
8147 Set_Null_Record_Present (N, False);
8148
8149 -- When the current aggregate comes from the expansion of an
8150 -- extension aggregate, the parent expr is replaced by an
22243c12 8151 -- aggregate formed by selected components of this expr.
70482933 8152
36a66365 8153 if Present (Parent_Expr) and then Is_Empty_List (Comps) then
5277cab6 8154 Comp := First_Component_Or_Discriminant (Typ);
70482933
RK
8155 while Present (Comp) loop
8156
70482933
RK
8157 -- Skip all expander-generated components
8158
bdc193ba 8159 if not Comes_From_Source (Original_Record_Component (Comp))
70482933
RK
8160 then
8161 null;
8162
8163 else
8164 New_Comp :=
8165 Make_Selected_Component (Loc,
bdc193ba 8166 Prefix =>
70482933
RK
8167 Unchecked_Convert_To (Typ,
8168 Duplicate_Subexpr (Parent_Expr, True)),
70482933
RK
8169 Selector_Name => New_Occurrence_Of (Comp, Loc));
8170
8171 Append_To (Comps,
8172 Make_Component_Association (Loc,
54740d7d
AC
8173 Choices => New_List (
8174 New_Occurrence_Of (Comp, Loc)),
37368818 8175 Expression => New_Comp));
70482933
RK
8176
8177 Analyze_And_Resolve (New_Comp, Etype (Comp));
8178 end if;
8179
5277cab6 8180 Next_Component_Or_Discriminant (Comp);
70482933
RK
8181 end loop;
8182 end if;
8183
8184 -- Compute the value for the Tag now, if the type is a root it
8185 -- will be included in the aggregate right away, otherwise it will
22243c12 8186 -- be propagated to the parent aggregate.
70482933
RK
8187
8188 if Present (Orig_Tag) then
8189 Tag_Value := Orig_Tag;
54740d7d 8190
1f110335 8191 elsif not Tagged_Type_Expansion then
70482933 8192 Tag_Value := Empty;
54740d7d 8193
70482933 8194 else
a9d8907c
JM
8195 Tag_Value :=
8196 New_Occurrence_Of
8197 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
70482933
RK
8198 end if;
8199
8200 -- For a derived type, an aggregate for the parent is formed with
8201 -- all the inherited components.
8202
8203 if Is_Derived_Type (Typ) then
70482933
RK
8204 declare
8205 First_Comp : Node_Id;
8206 Parent_Comps : List_Id;
8207 Parent_Aggr : Node_Id;
8208 Parent_Name : Node_Id;
8209
8210 begin
8211 -- Remove the inherited component association from the
8212 -- aggregate and store them in the parent aggregate
8213
54740d7d 8214 First_Comp := First (Component_Associations (N));
70482933 8215 Parent_Comps := New_List;
70482933 8216 while Present (First_Comp)
36a66365
AC
8217 and then
8218 Scope (Original_Record_Component
8219 (Entity (First (Choices (First_Comp))))) /=
8220 Base_Typ
70482933
RK
8221 loop
8222 Comp := First_Comp;
8223 Next (First_Comp);
8224 Remove (Comp);
8225 Append (Comp, Parent_Comps);
8226 end loop;
8227
36a66365
AC
8228 Parent_Aggr :=
8229 Make_Aggregate (Loc,
8230 Component_Associations => Parent_Comps);
70482933
RK
8231 Set_Etype (Parent_Aggr, Etype (Base_Type (Typ)));
8232
8233 -- Find the _parent component
8234
8235 Comp := First_Component (Typ);
8236 while Chars (Comp) /= Name_uParent loop
99859ea7 8237 Next_Component (Comp);
70482933
RK
8238 end loop;
8239
8240 Parent_Name := New_Occurrence_Of (Comp, Loc);
8241
8242 -- Insert the parent aggregate
8243
8244 Prepend_To (Component_Associations (N),
8245 Make_Component_Association (Loc,
8246 Choices => New_List (Parent_Name),
8247 Expression => Parent_Aggr));
8248
8249 -- Expand recursively the parent propagating the right Tag
8250
22243c12
RD
8251 Expand_Record_Aggregate
8252 (Parent_Aggr, Tag_Value, Parent_Expr);
1b6897ce
AC
8253
8254 -- The ancestor part may be a nested aggregate that has
8255 -- delayed expansion: recheck now.
8256
d4dfb005 8257 if not Component_OK_For_Backend then
1b6897ce
AC
8258 Convert_To_Assignments (N, Typ);
8259 end if;
70482933
RK
8260 end;
8261
8262 -- For a root type, the tag component is added (unless compiling
0f95b178 8263 -- for the VMs, where tags are implicit).
70482933 8264
1f110335 8265 elsif Tagged_Type_Expansion then
70482933
RK
8266 declare
8267 Tag_Name : constant Node_Id :=
138fc6f1
HK
8268 New_Occurrence_Of
8269 (First_Tag_Component (Typ), Loc);
70482933
RK
8270 Typ_Tag : constant Entity_Id := RTE (RE_Tag);
8271 Conv_Node : constant Node_Id :=
138fc6f1 8272 Unchecked_Convert_To (Typ_Tag, Tag_Value);
70482933
RK
8273
8274 begin
8275 Set_Etype (Conv_Node, Typ_Tag);
8276 Prepend_To (Component_Associations (N),
8277 Make_Component_Association (Loc,
8278 Choices => New_List (Tag_Name),
8279 Expression => Conv_Node));
8280 end;
8281 end if;
8282 end if;
54740d7d
AC
8283 end Build_Back_End_Aggregate;
8284
8285 ----------------------------------------
8286 -- Compile_Time_Known_Composite_Value --
8287 ----------------------------------------
8288
8289 function Compile_Time_Known_Composite_Value
8290 (N : Node_Id) return Boolean
8291 is
8292 begin
8293 -- If we have an entity name, then see if it is the name of a
8294 -- constant and if so, test the corresponding constant value.
8295
8296 if Is_Entity_Name (N) then
8297 declare
8298 E : constant Entity_Id := Entity (N);
8299 V : Node_Id;
8300 begin
8301 if Ekind (E) /= E_Constant then
8302 return False;
8303 else
8304 V := Constant_Value (E);
8305 return Present (V)
8306 and then Compile_Time_Known_Composite_Value (V);
8307 end if;
8308 end;
8309
8310 -- We have a value, see if it is compile time known
8311
8312 else
8313 if Nkind (N) = N_Aggregate then
8314 return Compile_Time_Known_Aggregate (N);
8315 end if;
8316
8317 -- All other types of values are not known at compile time
8318
8319 return False;
8320 end if;
8321
8322 end Compile_Time_Known_Composite_Value;
8323
d4dfb005
BD
8324 ------------------------------
8325 -- Component_OK_For_Backend --
8326 ------------------------------
54740d7d 8327
d4dfb005 8328 function Component_OK_For_Backend return Boolean is
54740d7d
AC
8329 C : Node_Id;
8330 Expr_Q : Node_Id;
8331
8332 begin
8333 if No (Comps) then
d4dfb005 8334 return True;
54740d7d
AC
8335 end if;
8336
8337 C := First (Comps);
8338 while Present (C) loop
8339
8340 -- If the component has box initialization, expansion is needed
8341 -- and component is not ready for backend.
8342
8343 if Box_Present (C) then
d4dfb005 8344 return False;
54740d7d
AC
8345 end if;
8346
8347 if Nkind (Expression (C)) = N_Qualified_Expression then
8348 Expr_Q := Expression (Expression (C));
8349 else
8350 Expr_Q := Expression (C);
8351 end if;
8352
f4c26077
ES
8353 -- Return False for array components whose bounds raise
8354 -- constraint error.
8355
8356 declare
61770974 8357 Comp : constant Entity_Id := First (Choices (C));
f4c26077
ES
8358 Indx : Node_Id;
8359
8360 begin
f4c26077
ES
8361 if Present (Etype (Comp))
8362 and then Is_Array_Type (Etype (Comp))
8363 then
8364 Indx := First_Index (Etype (Comp));
f4c26077 8365 while Present (Indx) loop
61770974
HK
8366 if Nkind (Type_Low_Bound (Etype (Indx))) =
8367 N_Raise_Constraint_Error
8368 or else Nkind (Type_High_Bound (Etype (Indx))) =
8369 N_Raise_Constraint_Error
f4c26077
ES
8370 then
8371 return False;
8372 end if;
8373
99859ea7 8374 Next_Index (Indx);
f4c26077
ES
8375 end loop;
8376 end if;
8377 end;
8378
d4dfb005 8379 -- Return False if the aggregate has any associations for tagged
54740d7d
AC
8380 -- components that may require tag adjustment.
8381
8382 -- These are cases where the source expression may have a tag that
8383 -- could differ from the component tag (e.g., can occur for type
8384 -- conversions and formal parameters). (Tag adjustment not needed
8385 -- if Tagged_Type_Expansion because object tags are implicit in
8386 -- the machine.)
8387
8388 if Is_Tagged_Type (Etype (Expr_Q))
61770974
HK
8389 and then
8390 (Nkind (Expr_Q) = N_Type_Conversion
8391 or else
8392 (Is_Entity_Name (Expr_Q)
bb6a856b 8393 and then Is_Formal (Entity (Expr_Q))))
54740d7d
AC
8394 and then Tagged_Type_Expansion
8395 then
8396 Static_Components := False;
d4dfb005 8397 return False;
54740d7d
AC
8398
8399 elsif Is_Delayed_Aggregate (Expr_Q) then
8400 Static_Components := False;
d4dfb005 8401 return False;
54740d7d 8402
1f6237e3
ES
8403 elsif Nkind (Expr_Q) = N_Quantified_Expression then
8404 Static_Components := False;
8405 return False;
8406
54740d7d
AC
8407 elsif Possible_Bit_Aligned_Component (Expr_Q) then
8408 Static_Components := False;
d4dfb005 8409 return False;
54740d7d
AC
8410
8411 elsif Modify_Tree_For_C
8412 and then Nkind (C) = N_Component_Association
8413 and then Has_Per_Object_Constraint (Choices (C))
8414 then
8415 Static_Components := False;
d4dfb005 8416 return False;
54740d7d
AC
8417
8418 elsif Modify_Tree_For_C
8419 and then Nkind (Expr_Q) = N_Identifier
8420 and then Is_Array_Type (Etype (Expr_Q))
8421 then
8422 Static_Components := False;
d4dfb005 8423 return False;
b276ab7a
AC
8424
8425 elsif Modify_Tree_For_C
8426 and then Nkind (Expr_Q) = N_Type_Conversion
8427 and then Is_Array_Type (Etype (Expr_Q))
8428 then
8429 Static_Components := False;
d4dfb005 8430 return False;
54740d7d
AC
8431 end if;
8432
8433 if Is_Elementary_Type (Etype (Expr_Q)) then
8434 if not Compile_Time_Known_Value (Expr_Q) then
8435 Static_Components := False;
8436 end if;
8437
8438 elsif not Compile_Time_Known_Composite_Value (Expr_Q) then
8439 Static_Components := False;
8440
8441 if Is_Private_Type (Etype (Expr_Q))
8442 and then Has_Discriminants (Etype (Expr_Q))
8443 then
d4dfb005 8444 return False;
54740d7d
AC
8445 end if;
8446 end if;
8447
8448 Next (C);
8449 end loop;
8450
d4dfb005
BD
8451 return True;
8452 end Component_OK_For_Backend;
54740d7d
AC
8453
8454 -------------------------------
8455 -- Has_Per_Object_Constraint --
8456 -------------------------------
8457
8458 function Has_Per_Object_Constraint (L : List_Id) return Boolean is
8459 N : Node_Id := First (L);
8460 begin
8461 while Present (N) loop
8462 if Is_Entity_Name (N)
8463 and then Present (Entity (N))
8464 and then Has_Per_Object_Constraint (Entity (N))
8465 then
8466 return True;
8467 end if;
8468
8469 Next (N);
8470 end loop;
8471
8472 return False;
8473 end Has_Per_Object_Constraint;
8474
8475 -----------------------------------
8476 -- Has_Visible_Private_Ancestor --
8477 -----------------------------------
8478
8479 function Has_Visible_Private_Ancestor (Id : E) return Boolean is
8480 R : constant Entity_Id := Root_Type (Id);
8481 T1 : Entity_Id := Id;
8482
8483 begin
8484 loop
8485 if Is_Private_Type (T1) then
8486 return True;
8487
8488 elsif T1 = R then
8489 return False;
8490
8491 else
8492 T1 := Etype (T1);
8493 end if;
8494 end loop;
8495 end Has_Visible_Private_Ancestor;
4f94fa11
AC
8496
8497 -------------------------
8498 -- Top_Level_Aggregate --
8499 -------------------------
8500
8501 function Top_Level_Aggregate (N : Node_Id) return Node_Id is
8502 Aggr : Node_Id;
8503
8504 begin
8505 Aggr := N;
8506 while Present (Parent (Aggr))
4a08c95c
AC
8507 and then Nkind (Parent (Aggr)) in
8508 N_Aggregate | N_Component_Association
4f94fa11
AC
8509 loop
8510 Aggr := Parent (Aggr);
8511 end loop;
8512
8513 return Aggr;
8514 end Top_Level_Aggregate;
8515
8516 -- Local variables
8517
8518 Top_Level_Aggr : constant Node_Id := Top_Level_Aggregate (N);
8519
8520 -- Start of processing for Expand_Record_Aggregate
8521
8522 begin
b120ca61 8523 -- If the aggregate is to be assigned to a full access variable, we have
4f94fa11
AC
8524 -- to prevent a piecemeal assignment even if the aggregate is to be
8525 -- expanded. We create a temporary for the aggregate, and assign the
8526 -- temporary instead, so that the back end can generate an atomic move
8527 -- for it.
8528
b120ca61 8529 if Is_Full_Access_Aggregate (N) then
4f94fa11
AC
8530 return;
8531
8532 -- No special management required for aggregates used to initialize
8533 -- statically allocated dispatch tables
8534
8535 elsif Is_Static_Dispatch_Table_Aggregate (N) then
8536 return;
e1dfbb03
SB
8537
8538 -- Case pattern aggregates need to remain as aggregates
8539
8540 elsif Is_Case_Choice_Pattern (N) then
8541 return;
70482933 8542 end if;
0f95b178 8543
8973b987 8544 -- If the pragma Aggregate_Individually_Assign is set, always convert to
efc00a88
PB
8545 -- assignments.
8546
8547 if Aggregate_Individually_Assign then
8548 Convert_To_Assignments (N, Typ);
8549
4f94fa11
AC
8550 -- Ada 2005 (AI-318-2): We need to convert to assignments if components
8551 -- are build-in-place function calls. The assignments will each turn
8552 -- into a build-in-place function call. If components are all static,
d4dfb005 8553 -- we can pass the aggregate to the back end regardless of limitedness.
4f94fa11
AC
8554
8555 -- Extension aggregates, aggregates in extended return statements, and
8556 -- aggregates for C++ imported types must be expanded.
8557
efc00a88 8558 elsif Ada_Version >= Ada_2005 and then Is_Limited_View (Typ) then
4a08c95c
AC
8559 if Nkind (Parent (N)) not in
8560 N_Component_Association | N_Object_Declaration
4f94fa11
AC
8561 then
8562 Convert_To_Assignments (N, Typ);
8563
8564 elsif Nkind (N) = N_Extension_Aggregate
8565 or else Convention (Typ) = Convention_CPP
8566 then
8567 Convert_To_Assignments (N, Typ);
8568
8569 elsif not Size_Known_At_Compile_Time (Typ)
d4dfb005 8570 or else not Component_OK_For_Backend
4f94fa11
AC
8571 or else not Static_Components
8572 then
8573 Convert_To_Assignments (N, Typ);
8574
8575 -- In all other cases, build a proper aggregate to be handled by
23a9215f 8576 -- the back-end.
4f94fa11
AC
8577
8578 else
54740d7d 8579 Build_Back_End_Aggregate;
4f94fa11
AC
8580 end if;
8581
8582 -- Gigi doesn't properly handle temporaries of variable size so we
8583 -- generate it in the front-end
8584
8585 elsif not Size_Known_At_Compile_Time (Typ)
8586 and then Tagged_Type_Expansion
8587 then
8588 Convert_To_Assignments (N, Typ);
8589
8590 -- An aggregate used to initialize a controlled object must be turned
8591 -- into component assignments as the components themselves may require
8592 -- finalization actions such as adjustment.
8593
8594 elsif Needs_Finalization (Typ) then
8595 Convert_To_Assignments (N, Typ);
8596
8597 -- Ada 2005 (AI-287): In case of default initialized components we
8598 -- convert the aggregate into assignments.
8599
8600 elsif Has_Default_Init_Comps (N) then
8601 Convert_To_Assignments (N, Typ);
8602
8603 -- Check components
8604
d4dfb005 8605 elsif not Component_OK_For_Backend then
4f94fa11
AC
8606 Convert_To_Assignments (N, Typ);
8607
8608 -- If an ancestor is private, some components are not inherited and we
8609 -- cannot expand into a record aggregate.
8610
8611 elsif Has_Visible_Private_Ancestor (Typ) then
8612 Convert_To_Assignments (N, Typ);
8613
8614 -- ??? The following was done to compile fxacc00.ads in the ACVCs. Gigi
8615 -- is not able to handle the aggregate for Late_Request.
8616
8617 elsif Is_Tagged_Type (Typ) and then Has_Discriminants (Typ) then
8618 Convert_To_Assignments (N, Typ);
8619
8620 -- If the tagged types covers interface types we need to initialize all
8621 -- hidden components containing pointers to secondary dispatch tables.
8622
8623 elsif Is_Tagged_Type (Typ) and then Has_Interfaces (Typ) then
8624 Convert_To_Assignments (N, Typ);
8625
8626 -- If some components are mutable, the size of the aggregate component
8627 -- may be distinct from the default size of the type component, so
8628 -- we need to expand to insure that the back-end copies the proper
8629 -- size of the data. However, if the aggregate is the initial value of
8630 -- a constant, the target is immutable and might be built statically
8631 -- if components are appropriate.
8632
8633 elsif Has_Mutable_Components (Typ)
8634 and then
8635 (Nkind (Parent (Top_Level_Aggr)) /= N_Object_Declaration
8636 or else not Constant_Present (Parent (Top_Level_Aggr))
8637 or else not Static_Components)
8638 then
8639 Convert_To_Assignments (N, Typ);
8640
8641 -- If the type involved has bit aligned components, then we are not sure
8642 -- that the back end can handle this case correctly.
8643
8644 elsif Type_May_Have_Bit_Aligned_Components (Typ) then
8645 Convert_To_Assignments (N, Typ);
8646
8647 -- When generating C, only generate an aggregate when declaring objects
8648 -- since C does not support aggregates in e.g. assignment statements.
8649
9f51b855 8650 elsif Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
4f94fa11
AC
8651 Convert_To_Assignments (N, Typ);
8652
8653 -- In all other cases, build a proper aggregate to be handled by gigi
8654
8655 else
54740d7d 8656 Build_Back_End_Aggregate;
4f94fa11 8657 end if;
70482933
RK
8658 end Expand_Record_Aggregate;
8659
a80b1eb7
EB
8660 ---------------------
8661 -- Get_Base_Object --
8662 ---------------------
8663
8664 function Get_Base_Object (N : Node_Id) return Entity_Id is
8665 R : Node_Id;
8666
8667 begin
8668 R := Get_Referenced_Object (N);
8669
4a08c95c 8670 while Nkind (R) in N_Indexed_Component | N_Selected_Component | N_Slice
a80b1eb7
EB
8671 loop
8672 R := Get_Referenced_Object (Prefix (R));
8673 end loop;
8674
8675 if Is_Entity_Name (R) and then Is_Object (Entity (R)) then
8676 return Entity (R);
8677 else
8678 return Empty;
8679 end if;
8680 end Get_Base_Object;
8681
65356e64
AC
8682 ----------------------------
8683 -- Has_Default_Init_Comps --
8684 ----------------------------
8685
8686 function Has_Default_Init_Comps (N : Node_Id) return Boolean is
d05ef0ab
AC
8687 Comps : constant List_Id := Component_Associations (N);
8688 C : Node_Id;
c45b6ae0 8689 Expr : Node_Id;
bdc193ba 8690
65356e64 8691 begin
4a08c95c 8692 pragma Assert (Nkind (N) in N_Aggregate | N_Extension_Aggregate);
c45b6ae0 8693
65356e64
AC
8694 if No (Comps) then
8695 return False;
8696 end if;
8697
c5ee5ad2
BD
8698 if Has_Self_Reference (N) then
8699 return True;
8700 end if;
8701
c45b6ae0
AC
8702 -- Check if any direct component has default initialized components
8703
65356e64
AC
8704 C := First (Comps);
8705 while Present (C) loop
8706 if Box_Present (C) then
8707 return True;
8708 end if;
8709
8710 Next (C);
8711 end loop;
c45b6ae0
AC
8712
8713 -- Recursive call in case of aggregate expression
8714
8715 C := First (Comps);
8716 while Present (C) loop
8717 Expr := Expression (C);
8718
8719 if Present (Expr)
4a08c95c 8720 and then Nkind (Expr) in N_Aggregate | N_Extension_Aggregate
c45b6ae0
AC
8721 and then Has_Default_Init_Comps (Expr)
8722 then
8723 return True;
8724 end if;
8725
8726 Next (C);
8727 end loop;
8728
65356e64
AC
8729 return False;
8730 end Has_Default_Init_Comps;
8731
3fc40cd7
PMR
8732 ----------------------------------------
8733 -- Is_Build_In_Place_Aggregate_Return --
8734 ----------------------------------------
8735
8736 function Is_Build_In_Place_Aggregate_Return (N : Node_Id) return Boolean is
8737 P : Node_Id := Parent (N);
8738
8739 begin
8740 while Nkind (P) = N_Qualified_Expression loop
8741 P := Parent (P);
8742 end loop;
8743
8744 if Nkind (P) = N_Simple_Return_Statement then
8745 null;
8746
8747 elsif Nkind (Parent (P)) = N_Extended_Return_Statement then
8748 P := Parent (P);
8749
8750 else
8751 return False;
8752 end if;
8753
8754 return
8755 Is_Build_In_Place_Function
8756 (Return_Applies_To (Return_Statement_Entity (P)));
8757 end Is_Build_In_Place_Aggregate_Return;
8758
70482933
RK
8759 --------------------------
8760 -- Is_Delayed_Aggregate --
8761 --------------------------
8762
8763 function Is_Delayed_Aggregate (N : Node_Id) return Boolean is
fbf5a39b 8764 Node : Node_Id := N;
70482933 8765 Kind : Node_Kind := Nkind (Node);
fbf5a39b 8766
70482933
RK
8767 begin
8768 if Kind = N_Qualified_Expression then
8769 Node := Expression (Node);
8770 Kind := Nkind (Node);
8771 end if;
8772
4a08c95c 8773 if Kind not in N_Aggregate | N_Extension_Aggregate then
70482933
RK
8774 return False;
8775 else
8776 return Expansion_Delayed (Node);
8777 end if;
8778 end Is_Delayed_Aggregate;
8779
9f51b855
JM
8780 --------------------------------
8781 -- Is_CCG_Supported_Aggregate --
8782 --------------------------------
6031f544 8783
9f51b855
JM
8784 function Is_CCG_Supported_Aggregate
8785 (N : Node_Id) return Boolean
8786 is
4ff5aa0c 8787 P : Node_Id := Parent (N);
2401c98f 8788
6031f544 8789 begin
bc1146e5
HK
8790 -- Aggregates are not supported for nonstandard rep clauses, since they
8791 -- may lead to extra padding fields in CCG.
4ff5aa0c 8792
3bcf8298 8793 if Is_Record_Type (Etype (N))
4ff5aa0c
AC
8794 and then Has_Non_Standard_Rep (Etype (N))
8795 then
8796 return False;
8797 end if;
6031f544 8798
4ff5aa0c 8799 while Present (P) and then Nkind (P) = N_Aggregate loop
6031f544
AC
8800 P := Parent (P);
8801 end loop;
8802
d2d56bba 8803 -- Check cases where aggregates are supported by the CCG backend
9f51b855 8804
4ff5aa0c 8805 if Nkind (P) = N_Object_Declaration then
d2d56bba
JM
8806 declare
8807 P_Typ : constant Entity_Id := Etype (Defining_Identifier (P));
9f51b855 8808
d2d56bba
JM
8809 begin
8810 if Is_Record_Type (P_Typ) then
8811 return True;
8812 else
8813 return Compile_Time_Known_Bounds (P_Typ);
8814 end if;
8815 end;
8816
8817 elsif Nkind (P) = N_Qualified_Expression then
8818 if Nkind (Parent (P)) = N_Object_Declaration then
8819 declare
8820 P_Typ : constant Entity_Id :=
8821 Etype (Defining_Identifier (Parent (P)));
8822 begin
8823 if Is_Record_Type (P_Typ) then
8824 return True;
8825 else
8826 return Compile_Time_Known_Bounds (P_Typ);
8827 end if;
8828 end;
8829
8830 elsif Nkind (Parent (P)) = N_Allocator then
8831 return True;
8832 end if;
9f51b855
JM
8833 end if;
8834
6031f544 8835 return False;
9f51b855 8836 end Is_CCG_Supported_Aggregate;
6031f544 8837
fa57ac97
ES
8838 ----------------------------------------
8839 -- Is_Static_Dispatch_Table_Aggregate --
8840 ----------------------------------------
8841
8842 function Is_Static_Dispatch_Table_Aggregate (N : Node_Id) return Boolean is
8843 Typ : constant Entity_Id := Base_Type (Etype (N));
8844
8845 begin
6214b83b 8846 return Building_Static_Dispatch_Tables
1f110335 8847 and then Tagged_Type_Expansion
fa57ac97
ES
8848
8849 -- Avoid circularity when rebuilding the compiler
8850
3477e0b2
PT
8851 and then not Is_RTU (Cunit_Entity (Get_Source_Unit (N)), Ada_Tags)
8852 and then (Is_RTE (Typ, RE_Dispatch_Table_Wrapper)
fa57ac97 8853 or else
3477e0b2 8854 Is_RTE (Typ, RE_Address_Array)
fa57ac97 8855 or else
3477e0b2 8856 Is_RTE (Typ, RE_Type_Specific_Data)
fa57ac97 8857 or else
3477e0b2 8858 Is_RTE (Typ, RE_Tag_Table)
fa57ac97 8859 or else
3477e0b2 8860 Is_RTE (Typ, RE_Object_Specific_Data)
c7cb99f8 8861 or else
3477e0b2 8862 Is_RTE (Typ, RE_Interface_Data)
fa57ac97 8863 or else
3477e0b2 8864 Is_RTE (Typ, RE_Interfaces_Array)
fa57ac97 8865 or else
3477e0b2 8866 Is_RTE (Typ, RE_Interface_Data_Element));
fa57ac97
ES
8867 end Is_Static_Dispatch_Table_Aggregate;
8868
dc3af7e2
AC
8869 -----------------------------
8870 -- Is_Two_Dim_Packed_Array --
8871 -----------------------------
8872
8873 function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean is
8874 C : constant Int := UI_To_Int (Component_Size (Typ));
8875 begin
8876 return Number_Dimensions (Typ) = 2
8877 and then Is_Bit_Packed_Array (Typ)
2791be24 8878 and then (C = 1 or else C = 2 or else C = 4);
dc3af7e2
AC
8879 end Is_Two_Dim_Packed_Array;
8880
70482933
RK
8881 --------------------
8882 -- Late_Expansion --
8883 --------------------
8884
8885 function Late_Expansion
8886 (N : Node_Id;
8887 Typ : Entity_Id;
df3e68b1 8888 Target : Node_Id) return List_Id
9bc856dd 8889 is
f29afe5f 8890 Aggr_Code : List_Id;
b748c3d1 8891 New_Aggr : Node_Id;
f29afe5f 8892
70482933 8893 begin
b748c3d1
EB
8894 if Is_Array_Type (Typ) then
8895 -- If the assignment can be done directly by the back end, then
8896 -- reset Set_Expansion_Delayed and do not expand further.
8897
8898 if not CodePeer_Mode
8899 and then not Modify_Tree_For_C
8900 and then not Possible_Bit_Aligned_Component (Target)
8901 and then not Is_Possibly_Unaligned_Slice (Target)
8902 and then Aggr_Assignment_OK_For_Backend (N)
8903 then
8904 New_Aggr := New_Copy_Tree (N);
8905 Set_Expansion_Delayed (New_Aggr, False);
8906
8907 Aggr_Code :=
8908 New_List (
8909 Make_OK_Assignment_Statement (Sloc (New_Aggr),
8910 Name => Target,
8911 Expression => New_Aggr));
8912
8913 -- Or else, generate component assignments to it
8914
8915 else
8916 Aggr_Code :=
8917 Build_Array_Aggr_Code
8918 (N => N,
8919 Ctype => Component_Type (Typ),
8920 Index => First_Index (Typ),
8921 Into => Target,
8922 Scalar_Comp => Is_Scalar_Type (Component_Type (Typ)),
8923 Indexes => No_List);
8924 end if;
6031f544 8925
f3bf0d9a
HK
8926 -- Directly or indirectly (e.g. access protected procedure) a record
8927
8928 else
6031f544 8929 Aggr_Code := Build_Record_Aggr_Code (N, Typ, Target);
70482933 8930 end if;
4ac2bbbd
AC
8931
8932 -- Save the last assignment statement associated with the aggregate
8933 -- when building a controlled object. This reference is utilized by
8934 -- the finalization machinery when marking an object as successfully
8935 -- initialized.
8936
8937 if Needs_Finalization (Typ)
8938 and then Is_Entity_Name (Target)
8939 and then Present (Entity (Target))
4a08c95c 8940 and then Ekind (Entity (Target)) in E_Constant | E_Variable
4ac2bbbd
AC
8941 then
8942 Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
8943 end if;
8944
8945 return Aggr_Code;
70482933
RK
8946 end Late_Expansion;
8947
8948 ----------------------------------
8949 -- Make_OK_Assignment_Statement --
8950 ----------------------------------
8951
8952 function Make_OK_Assignment_Statement
8953 (Sloc : Source_Ptr;
8954 Name : Node_Id;
0f95b178 8955 Expression : Node_Id) return Node_Id
70482933
RK
8956 is
8957 begin
8958 Set_Assignment_OK (Name);
8959 return Make_Assignment_Statement (Sloc, Name, Expression);
8960 end Make_OK_Assignment_Statement;
8961
c42006e9
AC
8962 ------------------------
8963 -- Max_Aggregate_Size --
8964 ------------------------
8965
8966 function Max_Aggregate_Size
eaf6e63a
BD
8967 (N : Node_Id;
8968 Default_Size : Nat := 5000) return Nat
8969 is
eaf6e63a
BD
8970 function Use_Small_Size (N : Node_Id) return Boolean;
8971 -- True if we should return a very small size, which means large
8972 -- aggregates will be implemented as a loop when possible (potentially
8973 -- transformed to memset calls).
8974
8975 function Aggr_Context (N : Node_Id) return Node_Id;
8976 -- Return the context in which the aggregate appears, not counting
8977 -- qualified expressions and similar.
8978
bcc15039
PT
8979 ------------------
8980 -- Aggr_Context --
8981 ------------------
8982
eaf6e63a
BD
8983 function Aggr_Context (N : Node_Id) return Node_Id is
8984 Result : Node_Id := Parent (N);
8985 begin
4a08c95c
AC
8986 if Nkind (Result) in N_Qualified_Expression
8987 | N_Type_Conversion
8988 | N_Unchecked_Type_Conversion
8989 | N_If_Expression
8990 | N_Case_Expression
8991 | N_Component_Association
8992 | N_Aggregate
eaf6e63a
BD
8993 then
8994 Result := Aggr_Context (Result);
8995 end if;
8996
8997 return Result;
8998 end Aggr_Context;
8999
bcc15039
PT
9000 --------------------
9001 -- Use_Small_Size --
9002 --------------------
9003
eaf6e63a
BD
9004 function Use_Small_Size (N : Node_Id) return Boolean is
9005 C : constant Node_Id := Aggr_Context (N);
9006 -- The decision depends on the context in which the aggregate occurs,
9007 -- and for variable declarations, whether we are nested inside a
9008 -- subprogram.
9009 begin
9010 case Nkind (C) is
9011 -- True for assignment statements and similar
9012
9013 when N_Assignment_Statement
9014 | N_Simple_Return_Statement
9015 | N_Allocator
9016 | N_Attribute_Reference
9017 =>
9018 return True;
9019
9020 -- True for nested variable declarations. False for library level
9021 -- variables, and for constants (whether or not nested).
9022
9023 when N_Object_Declaration =>
9024 return not Constant_Present (C)
9025 and then Ekind (Current_Scope) in Subprogram_Kind;
9026
9027 -- False for all other contexts
9028
9029 when others =>
9030 return False;
9031 end case;
9032 end Use_Small_Size;
9033
bcc15039
PT
9034 -- Local variables
9035
9036 Typ : constant Entity_Id := Etype (N);
9037
eaf6e63a
BD
9038 -- Start of processing for Max_Aggregate_Size
9039
c42006e9 9040 begin
bcc15039
PT
9041 -- We use a small limit in CodePeer mode where we favor loops instead of
9042 -- thousands of single assignments (from large aggregates).
c42006e9
AC
9043
9044 -- We also increase the limit to 2**24 (about 16 million) if
9045 -- Restrictions (No_Elaboration_Code) or Restrictions
9046 -- (No_Implicit_Loops) is specified, since in either case we are at risk
9047 -- of declaring the program illegal because of this limit. We also
9048 -- increase the limit when Static_Elaboration_Desired, given that this
9049 -- means that objects are intended to be placed in data memory.
9050
9051 -- Same if the aggregate is for a packed two-dimensional array, because
9052 -- if components are static it is much more efficient to construct a
9053 -- one-dimensional equivalent array with static components.
9054
9055 if CodePeer_Mode then
9056 return 100;
9057 elsif Restriction_Active (No_Elaboration_Code)
9058 or else Restriction_Active (No_Implicit_Loops)
9059 or else Is_Two_Dim_Packed_Array (Typ)
9060 or else (Ekind (Current_Scope) = E_Package
9061 and then Static_Elaboration_Desired (Current_Scope))
9062 then
9063 return 2 ** 24;
eaf6e63a 9064 elsif Use_Small_Size (N) then
152f64c2 9065 return 64;
c42006e9 9066 end if;
eaf6e63a
BD
9067
9068 return Default_Size;
c42006e9
AC
9069 end Max_Aggregate_Size;
9070
70482933
RK
9071 -----------------------
9072 -- Number_Of_Choices --
9073 -----------------------
9074
9075 function Number_Of_Choices (N : Node_Id) return Nat is
9076 Assoc : Node_Id;
9077 Choice : Node_Id;
9078
9079 Nb_Choices : Nat := 0;
9080
9081 begin
9082 if Present (Expressions (N)) then
9083 return 0;
9084 end if;
9085
9086 Assoc := First (Component_Associations (N));
9087 while Present (Assoc) loop
00f45f30 9088 Choice := First (Choice_List (Assoc));
70482933 9089 while Present (Choice) loop
70482933
RK
9090 if Nkind (Choice) /= N_Others_Choice then
9091 Nb_Choices := Nb_Choices + 1;
9092 end if;
9093
9094 Next (Choice);
9095 end loop;
9096
9097 Next (Assoc);
9098 end loop;
9099
9100 return Nb_Choices;
9101 end Number_Of_Choices;
9102
07fc65c4
GB
9103 ------------------------------------
9104 -- Packed_Array_Aggregate_Handled --
9105 ------------------------------------
9106
9107 -- The current version of this procedure will handle at compile time
9108 -- any array aggregate that meets these conditions:
9109
5eeeed5e 9110 -- One and two dimensional, bit packed
07fc65c4
GB
9111 -- Underlying packed type is modular type
9112 -- Bounds are within 32-bit Int range
9113 -- All bounds and values are static
9114
a39a553e
AC
9115 -- Note: for now, in the 2-D case, we only handle component sizes of
9116 -- 1, 2, 4 (cases where an integral number of elements occupies a byte).
9117
07fc65c4
GB
9118 function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean is
9119 Loc : constant Source_Ptr := Sloc (N);
9120 Typ : constant Entity_Id := Etype (N);
9121 Ctyp : constant Entity_Id := Component_Type (Typ);
9122
9123 Not_Handled : exception;
9124 -- Exception raised if this aggregate cannot be handled
9125
9126 begin
5eeeed5e 9127 -- Handle one- or two dimensional bit packed array
07fc65c4
GB
9128
9129 if not Is_Bit_Packed_Array (Typ)
5eeeed5e 9130 or else Number_Dimensions (Typ) > 2
07fc65c4
GB
9131 then
9132 return False;
9133 end if;
9134
5eeeed5e 9135 -- If two-dimensional, check whether it can be folded, and transformed
8ca597af
RD
9136 -- into a one-dimensional aggregate for the Packed_Array_Impl_Type of
9137 -- the original type.
5eeeed5e
AC
9138
9139 if Number_Dimensions (Typ) = 2 then
9140 return Two_Dim_Packed_Array_Handled (N);
9141 end if;
9142
8ca597af 9143 if not Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)) then
5eeeed5e
AC
9144 return False;
9145 end if;
9146
78326189 9147 if not Is_Scalar_Type (Ctyp) then
0f95b178
JM
9148 return False;
9149 end if;
9150
07fc65c4
GB
9151 declare
9152 Csiz : constant Nat := UI_To_Int (Component_Size (Typ));
9153
07fc65c4 9154 function Get_Component_Val (N : Node_Id) return Uint;
3b9fa2df
ES
9155 -- Given a expression value N of the component type Ctyp, returns a
9156 -- value of Csiz (component size) bits representing this value. If
d940c627 9157 -- the value is nonstatic or any other reason exists why the value
3b9fa2df 9158 -- cannot be returned, then Not_Handled is raised.
07fc65c4
GB
9159
9160 -----------------------
9161 -- Get_Component_Val --
9162 -----------------------
9163
9164 function Get_Component_Val (N : Node_Id) return Uint is
9165 Val : Uint;
9166
9167 begin
9168 -- We have to analyze the expression here before doing any further
9169 -- processing here. The analysis of such expressions is deferred
9170 -- till expansion to prevent some problems of premature analysis.
9171
9172 Analyze_And_Resolve (N, Ctyp);
9173
3b9fa2df
ES
9174 -- Must have a compile time value. String literals have to be
9175 -- converted into temporaries as well, because they cannot easily
9176 -- be converted into their bit representation.
07fc65c4 9177
6b6fcd3e
AC
9178 if not Compile_Time_Known_Value (N)
9179 or else Nkind (N) = N_String_Literal
9180 then
07fc65c4
GB
9181 raise Not_Handled;
9182 end if;
9183
9184 Val := Expr_Rep_Value (N);
9185
9186 -- Adjust for bias, and strip proper number of bits
9187
9188 if Has_Biased_Representation (Ctyp) then
9189 Val := Val - Expr_Value (Type_Low_Bound (Ctyp));
9190 end if;
9191
9192 return Val mod Uint_2 ** Csiz;
9193 end Get_Component_Val;
9194
7c4f3267
BD
9195 Bounds : constant Range_Nodes := Get_Index_Bounds (First_Index (Typ));
9196
07fc65c4
GB
9197 -- Here we know we have a one dimensional bit packed array
9198
9199 begin
07fc65c4
GB
9200 -- Cannot do anything if bounds are dynamic
9201
7c4f3267
BD
9202 if not (Compile_Time_Known_Value (Bounds.First)
9203 and then
9204 Compile_Time_Known_Value (Bounds.Last))
07fc65c4
GB
9205 then
9206 return False;
9207 end if;
9208
7c4f3267
BD
9209 declare
9210 Bounds_Vals : Range_Values;
9211 -- Compile-time known values of bounds
9212 begin
9213 -- Or are silly out of range of int bounds
07fc65c4 9214
7c4f3267
BD
9215 Bounds_Vals.First := Expr_Value (Bounds.First);
9216 Bounds_Vals.Last := Expr_Value (Bounds.Last);
07fc65c4 9217
7c4f3267
BD
9218 if not UI_Is_In_Int_Range (Bounds_Vals.First)
9219 or else
9220 not UI_Is_In_Int_Range (Bounds_Vals.Last)
9221 then
9222 return False;
9223 end if;
07fc65c4 9224
7c4f3267
BD
9225 -- At this stage we have a suitable aggregate for handling at
9226 -- compile time. The only remaining checks are that the values of
9227 -- expressions in the aggregate are compile-time known (checks are
9228 -- performed by Get_Component_Val), and that any subtypes or
9229 -- ranges are statically known.
07fc65c4 9230
7c4f3267
BD
9231 -- If the aggregate is not fully positional at this stage, then
9232 -- convert it to positional form. Either this will fail, in which
9233 -- case we can do nothing, or it will succeed, in which case we
9234 -- have succeeded in handling the aggregate and transforming it
9235 -- into a modular value, or it will stay an aggregate, in which
9236 -- case we have failed to create a packed value for it.
07fc65c4 9237
7c4f3267
BD
9238 if Present (Component_Associations (N)) then
9239 Convert_To_Positional (N, Handle_Bit_Packed => True);
9240 return Nkind (N) /= N_Aggregate;
9241 end if;
07fc65c4 9242
7c4f3267 9243 -- Otherwise we are all positional, so convert to proper value
07fc65c4 9244
7c4f3267
BD
9245 declare
9246 Len : constant Nat :=
9247 Int'Max (0, UI_To_Int (Bounds_Vals.Last) -
9248 UI_To_Int (Bounds_Vals.First) + 1);
9249 -- The length of the array (number of elements)
07fc65c4 9250
7c4f3267
BD
9251 Aggregate_Val : Uint;
9252 -- Value of aggregate. The value is set in the low order bits
9253 -- of this value. For the little-endian case, the values are
9254 -- stored from low-order to high-order and for the big-endian
9255 -- case the values are stored from high order to low order.
9256 -- Note that gigi will take care of the conversions to left
9257 -- justify the value in the big endian case (because of left
9258 -- justified modular type processing), so we do not have to
9259 -- worry about that here.
07fc65c4 9260
7c4f3267
BD
9261 Lit : Node_Id;
9262 -- Integer literal for resulting constructed value
07fc65c4 9263
7c4f3267
BD
9264 Shift : Nat;
9265 -- Shift count from low order for next value
07fc65c4 9266
7c4f3267
BD
9267 Incr : Int;
9268 -- Shift increment for loop
07fc65c4 9269
7c4f3267
BD
9270 Expr : Node_Id;
9271 -- Next expression from positional parameters of aggregate
c9a6b38f 9272
7c4f3267
BD
9273 Left_Justified : Boolean;
9274 -- Set True if we are filling the high order bits of the target
9275 -- value (i.e. the value is left justified).
07fc65c4 9276
7c4f3267
BD
9277 begin
9278 -- For little endian, we fill up the low order bits of the
9279 -- target value. For big endian we fill up the high order bits
9280 -- of the target value (which is a left justified modular
9281 -- value).
68f640f2 9282
7c4f3267 9283 Left_Justified := Bytes_Big_Endian;
c9a6b38f 9284
7c4f3267 9285 -- Switch justification if using -gnatd8
c9a6b38f 9286
7c4f3267
BD
9287 if Debug_Flag_8 then
9288 Left_Justified := not Left_Justified;
9289 end if;
c9a6b38f 9290
7c4f3267 9291 -- Switch justfification if reverse storage order
c9a6b38f 9292
7c4f3267
BD
9293 if Reverse_Storage_Order (Base_Type (Typ)) then
9294 Left_Justified := not Left_Justified;
9295 end if;
07fc65c4 9296
7c4f3267
BD
9297 if Left_Justified then
9298 Shift := Csiz * (Len - 1);
9299 Incr := -Csiz;
9300 else
9301 Shift := 0;
9302 Incr := +Csiz;
9303 end if;
07fc65c4 9304
7c4f3267 9305 -- Loop to set the values
fbf5a39b 9306
7c4f3267
BD
9307 if Len = 0 then
9308 Aggregate_Val := Uint_0;
9309 else
9310 Expr := First (Expressions (N));
9311 Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;
9312
9313 for J in 2 .. Len loop
9314 Shift := Shift + Incr;
9315 Next (Expr);
9316 Aggregate_Val :=
9317 Aggregate_Val +
9318 Get_Component_Val (Expr) * Uint_2 ** Shift;
9319 end loop;
9320 end if;
07fc65c4 9321
7c4f3267 9322 -- Now we can rewrite with the proper value
07fc65c4 9323
7c4f3267
BD
9324 Lit := Make_Integer_Literal (Loc, Intval => Aggregate_Val);
9325 Set_Print_In_Hex (Lit);
07fc65c4 9326
7c4f3267
BD
9327 -- Construct the expression using this literal. Note that it
9328 -- is important to qualify the literal with its proper modular
9329 -- type since universal integer does not have the required
9330 -- range and also this is a left justified modular type,
9331 -- which is important in the big-endian case.
07fc65c4 9332
7c4f3267
BD
9333 Rewrite (N,
9334 Unchecked_Convert_To (Typ,
9335 Make_Qualified_Expression (Loc,
9336 Subtype_Mark =>
9337 New_Occurrence_Of (Packed_Array_Impl_Type (Typ), Loc),
9338 Expression => Lit)));
07fc65c4 9339
7c4f3267
BD
9340 Analyze_And_Resolve (N, Typ);
9341 return True;
9342 end;
07fc65c4
GB
9343 end;
9344 end;
9345
9346 exception
9347 when Not_Handled =>
9348 return False;
9349 end Packed_Array_Aggregate_Handled;
9350
fbf5a39b
AC
9351 ----------------------------
9352 -- Has_Mutable_Components --
9353 ----------------------------
9354
9355 function Has_Mutable_Components (Typ : Entity_Id) return Boolean is
9356 Comp : Entity_Id;
bee475e2 9357 Ctyp : Entity_Id;
fbf5a39b
AC
9358
9359 begin
9360 Comp := First_Component (Typ);
fbf5a39b 9361 while Present (Comp) loop
bee475e2
EB
9362 Ctyp := Underlying_Type (Etype (Comp));
9363 if Is_Record_Type (Ctyp)
9364 and then Has_Discriminants (Ctyp)
9365 and then not Is_Constrained (Ctyp)
fbf5a39b
AC
9366 then
9367 return True;
9368 end if;
9369
9370 Next_Component (Comp);
9371 end loop;
9372
9373 return False;
9374 end Has_Mutable_Components;
9375
07fc65c4
GB
9376 ------------------------------
9377 -- Initialize_Discriminants --
9378 ------------------------------
9379
9380 procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id) is
9381 Loc : constant Source_Ptr := Sloc (N);
9382 Bas : constant Entity_Id := Base_Type (Typ);
9383 Par : constant Entity_Id := Etype (Bas);
9384 Decl : constant Node_Id := Parent (Par);
9385 Ref : Node_Id;
9386
9387 begin
9388 if Is_Tagged_Type (Bas)
9389 and then Is_Derived_Type (Bas)
9390 and then Has_Discriminants (Par)
9391 and then Has_Discriminants (Bas)
9392 and then Number_Discriminants (Bas) /= Number_Discriminants (Par)
9393 and then Nkind (Decl) = N_Full_Type_Declaration
9394 and then Nkind (Type_Definition (Decl)) = N_Record_Definition
36a66365
AC
9395 and then
9396 Present (Variant_Part (Component_List (Type_Definition (Decl))))
07fc65c4
GB
9397 and then Nkind (N) /= N_Extension_Aggregate
9398 then
9399
fbf5a39b 9400 -- Call init proc to set discriminants.
07fc65c4
GB
9401 -- There should eventually be a special procedure for this ???
9402
e4494292 9403 Ref := New_Occurrence_Of (Defining_Identifier (N), Loc);
07fc65c4
GB
9404 Insert_Actions_After (N,
9405 Build_Initialization_Call (Sloc (N), Ref, Typ));
9406 end if;
9407 end Initialize_Discriminants;
9408
3cf3e5c6
AC
9409 ----------------
9410 -- Must_Slide --
9411 ----------------
9412
9413 function Must_Slide
9414 (Obj_Type : Entity_Id;
9415 Typ : Entity_Id) return Boolean
9416 is
3cf3e5c6 9417 begin
3b9fa2df
ES
9418 -- No sliding if the type of the object is not established yet, if it is
9419 -- an unconstrained type whose actual subtype comes from the aggregate,
9420 -- or if the two types are identical.
3cf3e5c6
AC
9421
9422 if not Is_Array_Type (Obj_Type) then
9423 return False;
9424
9425 elsif not Is_Constrained (Obj_Type) then
9426 return False;
9427
9428 elsif Typ = Obj_Type then
9429 return False;
9430
9431 else
9432 -- Sliding can only occur along the first dimension
9433
7c4f3267
BD
9434 declare
9435 Bounds1 : constant Range_Nodes :=
9436 Get_Index_Bounds (First_Index (Typ));
9437 Bounds2 : constant Range_Nodes :=
9438 Get_Index_Bounds (First_Index (Obj_Type));
3cf3e5c6 9439
7c4f3267
BD
9440 begin
9441 if not Is_OK_Static_Expression (Bounds1.First) or else
9442 not Is_OK_Static_Expression (Bounds2.First) or else
9443 not Is_OK_Static_Expression (Bounds1.Last) or else
9444 not Is_OK_Static_Expression (Bounds2.Last)
9445 then
9446 return False;
9447 else
9448 return Expr_Value (Bounds1.First) /= Expr_Value (Bounds2.First)
9449 or else
9450 Expr_Value (Bounds1.Last) /= Expr_Value (Bounds2.Last);
9451 end if;
9452 end;
3cf3e5c6
AC
9453 end if;
9454 end Must_Slide;
9455
937e9676
AC
9456 ---------------------------------
9457 -- Process_Transient_Component --
9458 ---------------------------------
5eeeed5e 9459
937e9676
AC
9460 procedure Process_Transient_Component
9461 (Loc : Source_Ptr;
9462 Comp_Typ : Entity_Id;
9463 Init_Expr : Node_Id;
9464 Fin_Call : out Node_Id;
9465 Hook_Clear : out Node_Id;
9466 Aggr : Node_Id := Empty;
9467 Stmts : List_Id := No_List)
9468 is
9469 procedure Add_Item (Item : Node_Id);
9470 -- Insert arbitrary node Item into the tree depending on the values of
9471 -- Aggr and Stmts.
5eeeed5e 9472
937e9676
AC
9473 --------------
9474 -- Add_Item --
9475 --------------
5eeeed5e 9476
937e9676
AC
9477 procedure Add_Item (Item : Node_Id) is
9478 begin
9479 if Present (Aggr) then
9480 Insert_Action (Aggr, Item);
9481 else
9482 pragma Assert (Present (Stmts));
9483 Append_To (Stmts, Item);
9484 end if;
9485 end Add_Item;
9486
9487 -- Local variables
9488
9489 Hook_Assign : Node_Id;
9490 Hook_Decl : Node_Id;
9491 Ptr_Decl : Node_Id;
9492 Res_Decl : Node_Id;
9493 Res_Id : Entity_Id;
9494 Res_Typ : Entity_Id;
9495
9496 -- Start of processing for Process_Transient_Component
5eeeed5e
AC
9497
9498 begin
937e9676
AC
9499 -- Add the access type, which provides a reference to the function
9500 -- result. Generate:
5eeeed5e 9501
937e9676 9502 -- type Res_Typ is access all Comp_Typ;
5eeeed5e 9503
937e9676 9504 Res_Typ := Make_Temporary (Loc, 'A');
2e02ab86 9505 Mutate_Ekind (Res_Typ, E_General_Access_Type);
937e9676 9506 Set_Directly_Designated_Type (Res_Typ, Comp_Typ);
5eeeed5e 9507
937e9676
AC
9508 Add_Item
9509 (Make_Full_Type_Declaration (Loc,
9510 Defining_Identifier => Res_Typ,
9511 Type_Definition =>
9512 Make_Access_To_Object_Definition (Loc,
9513 All_Present => True,
9514 Subtype_Indication => New_Occurrence_Of (Comp_Typ, Loc))));
5eeeed5e 9515
937e9676
AC
9516 -- Add the temporary which captures the result of the function call.
9517 -- Generate:
5eeeed5e 9518
937e9676 9519 -- Res : constant Res_Typ := Init_Expr'Reference;
5eeeed5e 9520
937e9676
AC
9521 -- Note that this temporary is effectively a transient object because
9522 -- its lifetime is bounded by the current array or record component.
5eeeed5e 9523
937e9676 9524 Res_Id := Make_Temporary (Loc, 'R');
2e02ab86 9525 Mutate_Ekind (Res_Id, E_Constant);
937e9676 9526 Set_Etype (Res_Id, Res_Typ);
5eeeed5e 9527
937e9676
AC
9528 -- Mark the transient object as successfully processed to avoid double
9529 -- finalization.
5eeeed5e 9530
937e9676 9531 Set_Is_Finalized_Transient (Res_Id);
5eeeed5e 9532
937e9676
AC
9533 -- Signal the general finalization machinery that this transient object
9534 -- should not be considered for finalization actions because its cleanup
9535 -- will be performed by Process_Transient_Component_Completion.
5eeeed5e 9536
937e9676 9537 Set_Is_Ignored_Transient (Res_Id);
5eeeed5e 9538
937e9676
AC
9539 Res_Decl :=
9540 Make_Object_Declaration (Loc,
9541 Defining_Identifier => Res_Id,
9542 Constant_Present => True,
9543 Object_Definition => New_Occurrence_Of (Res_Typ, Loc),
9544 Expression =>
9545 Make_Reference (Loc, New_Copy_Tree (Init_Expr)));
5eeeed5e 9546
937e9676 9547 Add_Item (Res_Decl);
5eeeed5e 9548
937e9676
AC
9549 -- Construct all pieces necessary to hook and finalize the transient
9550 -- result.
5eeeed5e 9551
937e9676
AC
9552 Build_Transient_Object_Statements
9553 (Obj_Decl => Res_Decl,
9554 Fin_Call => Fin_Call,
9555 Hook_Assign => Hook_Assign,
9556 Hook_Clear => Hook_Clear,
9557 Hook_Decl => Hook_Decl,
9558 Ptr_Decl => Ptr_Decl);
5eeeed5e 9559
937e9676
AC
9560 -- Add the access type which provides a reference to the transient
9561 -- result. Generate:
5eeeed5e 9562
937e9676 9563 -- type Ptr_Typ is access all Comp_Typ;
5eeeed5e 9564
937e9676 9565 Add_Item (Ptr_Decl);
5eeeed5e 9566
937e9676
AC
9567 -- Add the temporary which acts as a hook to the transient result.
9568 -- Generate:
5eeeed5e 9569
937e9676 9570 -- Hook : Ptr_Typ := null;
5eeeed5e 9571
937e9676 9572 Add_Item (Hook_Decl);
5eeeed5e 9573
937e9676 9574 -- Attach the transient result to the hook. Generate:
5eeeed5e 9575
937e9676 9576 -- Hook := Ptr_Typ (Res);
5eeeed5e 9577
937e9676 9578 Add_Item (Hook_Assign);
5eeeed5e 9579
937e9676
AC
9580 -- The original initialization expression now references the value of
9581 -- the temporary function result. Generate:
5eeeed5e 9582
937e9676 9583 -- Res.all
5eeeed5e 9584
937e9676
AC
9585 Rewrite (Init_Expr,
9586 Make_Explicit_Dereference (Loc,
9587 Prefix => New_Occurrence_Of (Res_Id, Loc)));
9588 end Process_Transient_Component;
5eeeed5e 9589
937e9676
AC
9590 --------------------------------------------
9591 -- Process_Transient_Component_Completion --
9592 --------------------------------------------
5eeeed5e 9593
937e9676
AC
9594 procedure Process_Transient_Component_Completion
9595 (Loc : Source_Ptr;
9596 Aggr : Node_Id;
9597 Fin_Call : Node_Id;
9598 Hook_Clear : Node_Id;
9599 Stmts : List_Id)
9600 is
9601 Exceptions_OK : constant Boolean :=
9602 not Restriction_Active (No_Exception_Propagation);
5eeeed5e 9603
937e9676 9604 begin
937e9676 9605 pragma Assert (Present (Hook_Clear));
5eeeed5e 9606
937e9676 9607 -- Generate the following code if exception propagation is allowed:
5eeeed5e 9608
937e9676
AC
9609 -- declare
9610 -- Abort : constant Boolean := Triggered_By_Abort;
9611 -- <or>
9612 -- Abort : constant Boolean := False; -- no abort
5eeeed5e 9613
937e9676
AC
9614 -- E : Exception_Occurrence;
9615 -- Raised : Boolean := False;
5eeeed5e 9616
937e9676
AC
9617 -- begin
9618 -- [Abort_Defer;]
5eeeed5e 9619
937e9676
AC
9620 -- begin
9621 -- Hook := null;
9622 -- [Deep_]Finalize (Res.all);
5eeeed5e 9623
937e9676
AC
9624 -- exception
9625 -- when others =>
9626 -- if not Raised then
9627 -- Raised := True;
9628 -- Save_Occurrence (E,
9629 -- Get_Curent_Excep.all.all);
9630 -- end if;
9631 -- end;
5eeeed5e 9632
937e9676 9633 -- [Abort_Undefer;]
5eeeed5e 9634
937e9676
AC
9635 -- if Raised and then not Abort then
9636 -- Raise_From_Controlled_Operation (E);
9637 -- end if;
9638 -- end;
9639
9640 if Exceptions_OK then
9641 Abort_And_Exception : declare
9642 Blk_Decls : constant List_Id := New_List;
9643 Blk_Stmts : constant List_Id := New_List;
2168d7cc 9644 Fin_Stmts : constant List_Id := New_List;
937e9676
AC
9645
9646 Fin_Data : Finalization_Exception_Data;
9647
9648 begin
9649 -- Create the declarations of the two flags and the exception
9650 -- occurrence.
9651
9652 Build_Object_Declarations (Fin_Data, Blk_Decls, Loc);
9653
9654 -- Generate:
9655 -- Abort_Defer;
9656
9657 if Abort_Allowed then
9658 Append_To (Blk_Stmts,
9659 Build_Runtime_Call (Loc, RE_Abort_Defer));
9660 end if;
9661
9662 -- Wrap the hook clear and the finalization call in order to trap
9663 -- a potential exception.
9664
2168d7cc
AC
9665 Append_To (Fin_Stmts, Hook_Clear);
9666
9667 if Present (Fin_Call) then
9668 Append_To (Fin_Stmts, Fin_Call);
9669 end if;
9670
937e9676
AC
9671 Append_To (Blk_Stmts,
9672 Make_Block_Statement (Loc,
9673 Handled_Statement_Sequence =>
9674 Make_Handled_Sequence_Of_Statements (Loc,
2168d7cc 9675 Statements => Fin_Stmts,
937e9676
AC
9676 Exception_Handlers => New_List (
9677 Build_Exception_Handler (Fin_Data)))));
9678
9679 -- Generate:
9680 -- Abort_Undefer;
9681
9682 if Abort_Allowed then
9683 Append_To (Blk_Stmts,
9684 Build_Runtime_Call (Loc, RE_Abort_Undefer));
9685 end if;
9686
9687 -- Reraise the potential exception with a proper "upgrade" to
9688 -- Program_Error if needed.
9689
9690 Append_To (Blk_Stmts, Build_Raise_Statement (Fin_Data));
9691
9692 -- Wrap everything in a block
9693
9694 Append_To (Stmts,
9695 Make_Block_Statement (Loc,
9696 Declarations => Blk_Decls,
9697 Handled_Statement_Sequence =>
9698 Make_Handled_Sequence_Of_Statements (Loc,
9699 Statements => Blk_Stmts)));
9700 end Abort_And_Exception;
9701
9702 -- Generate the following code if exception propagation is not allowed
9703 -- and aborts are allowed:
9704
9705 -- begin
9706 -- Abort_Defer;
9707 -- Hook := null;
9708 -- [Deep_]Finalize (Res.all);
9709 -- at end
bb072d1c 9710 -- Abort_Undefer_Direct;
937e9676
AC
9711 -- end;
9712
9713 elsif Abort_Allowed then
9714 Abort_Only : declare
9715 Blk_Stmts : constant List_Id := New_List;
9716
937e9676
AC
9717 begin
9718 Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
9719 Append_To (Blk_Stmts, Hook_Clear);
2168d7cc
AC
9720
9721 if Present (Fin_Call) then
9722 Append_To (Blk_Stmts, Fin_Call);
9723 end if;
937e9676 9724
bb072d1c
AC
9725 Append_To (Stmts,
9726 Build_Abort_Undefer_Block (Loc,
9727 Stmts => Blk_Stmts,
9728 Context => Aggr));
937e9676
AC
9729 end Abort_Only;
9730
9731 -- Otherwise generate:
9732
9733 -- Hook := null;
9734 -- [Deep_]Finalize (Res.all);
9735
9736 else
9737 Append_To (Stmts, Hook_Clear);
2168d7cc
AC
9738
9739 if Present (Fin_Call) then
9740 Append_To (Stmts, Fin_Call);
9741 end if;
937e9676
AC
9742 end if;
9743 end Process_Transient_Component_Completion;
5eeeed5e 9744
70482933
RK
9745 ---------------------
9746 -- Sort_Case_Table --
9747 ---------------------
9748
9749 procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
fbf5a39b
AC
9750 L : constant Int := Case_Table'First;
9751 U : constant Int := Case_Table'Last;
70482933
RK
9752 K : Int;
9753 J : Int;
9754 T : Case_Bounds;
9755
9756 begin
9757 K := L;
70482933
RK
9758 while K /= U loop
9759 T := Case_Table (K + 1);
70482933 9760
5277cab6 9761 J := K + 1;
70482933
RK
9762 while J /= L
9763 and then Expr_Value (Case_Table (J - 1).Choice_Lo) >
9764 Expr_Value (T.Choice_Lo)
9765 loop
9766 Case_Table (J) := Case_Table (J - 1);
9767 J := J - 1;
9768 end loop;
9769
9770 Case_Table (J) := T;
9771 K := K + 1;
9772 end loop;
9773 end Sort_Case_Table;
9774
0f95b178
JM
9775 ----------------------------
9776 -- Static_Array_Aggregate --
9777 ----------------------------
9778
9779 function Static_Array_Aggregate (N : Node_Id) return Boolean is
2401c98f
HK
9780 function Is_Static_Component (Nod : Node_Id) return Boolean;
9781 -- Return True if Nod has a compile-time known value and can be passed
9782 -- as is to the back-end without further expansion.
2a1838cd
EB
9783
9784 ---------------------------
9785 -- Is_Static_Component --
9786 ---------------------------
9787
2401c98f 9788 function Is_Static_Component (Nod : Node_Id) return Boolean is
2a1838cd 9789 begin
4a08c95c 9790 if Nkind (Nod) in N_Integer_Literal | N_Real_Literal then
2a1838cd
EB
9791 return True;
9792
2401c98f
HK
9793 elsif Is_Entity_Name (Nod)
9794 and then Present (Entity (Nod))
9795 and then Ekind (Entity (Nod)) = E_Enumeration_Literal
2a1838cd
EB
9796 then
9797 return True;
9798
2401c98f
HK
9799 elsif Nkind (Nod) = N_Aggregate
9800 and then Compile_Time_Known_Aggregate (Nod)
2a1838cd
EB
9801 then
9802 return True;
9803
9804 else
9805 return False;
9806 end if;
9807 end Is_Static_Component;
9808
2401c98f
HK
9809 -- Local variables
9810
9811 Bounds : constant Node_Id := Aggregate_Bounds (N);
9812 Typ : constant Entity_Id := Etype (N);
0f95b178 9813
2401c98f
HK
9814 Agg : Node_Id;
9815 Expr : Node_Id;
9816 Lo : Node_Id;
9817 Hi : Node_Id;
0f95b178 9818
2a1838cd
EB
9819 -- Start of processing for Static_Array_Aggregate
9820
0f95b178 9821 begin
2a1838cd 9822 if Is_Packed (Typ) or else Has_Discriminants (Component_Type (Typ)) then
0f95b178
JM
9823 return False;
9824 end if;
9825
9826 if Present (Bounds)
9827 and then Nkind (Bounds) = N_Range
9828 and then Nkind (Low_Bound (Bounds)) = N_Integer_Literal
9829 and then Nkind (High_Bound (Bounds)) = N_Integer_Literal
9830 then
9831 Lo := Low_Bound (Bounds);
9832 Hi := High_Bound (Bounds);
9833
9834 if No (Component_Associations (N)) then
9835
2a1838cd 9836 -- Verify that all components are static
0f95b178
JM
9837
9838 Expr := First (Expressions (N));
9839 while Present (Expr) loop
2a1838cd 9840 if not Is_Static_Component (Expr) then
0f95b178
JM
9841 return False;
9842 end if;
9843
9844 Next (Expr);
9845 end loop;
9846
9847 return True;
9848
9849 else
9850 -- We allow only a single named association, either a static
9851 -- range or an others_clause, with a static expression.
9852
9853 Expr := First (Component_Associations (N));
9854
9855 if Present (Expressions (N)) then
9856 return False;
9857
9858 elsif Present (Next (Expr)) then
9859 return False;
9860
00f45f30 9861 elsif Present (Next (First (Choice_List (Expr)))) then
0f95b178
JM
9862 return False;
9863
9864 else
d7f94401
AC
9865 -- The aggregate is static if all components are literals,
9866 -- or else all its components are static aggregates for the
fc534c1c
ES
9867 -- component type. We also limit the size of a static aggregate
9868 -- to prevent runaway static expressions.
0f95b178 9869
2a1838cd 9870 if not Is_Static_Component (Expression (Expr)) then
0f95b178 9871 return False;
6a2e4f0b 9872 end if;
fc534c1c 9873
eaf6e63a 9874 if not Aggr_Size_OK (N) then
fc534c1c 9875 return False;
0f95b178
JM
9876 end if;
9877
9878 -- Create a positional aggregate with the right number of
9879 -- copies of the expression.
9880
9881 Agg := Make_Aggregate (Sloc (N), New_List, No_List);
9882
9883 for I in UI_To_Int (Intval (Lo)) .. UI_To_Int (Intval (Hi))
9884 loop
37368818 9885 Append_To (Expressions (Agg), New_Copy (Expression (Expr)));
597d7158 9886
9b4b0a1a
GD
9887 -- The copied expression must be analyzed and resolved.
9888 -- Besides setting the type, this ensures that static
9889 -- expressions are appropriately marked as such.
597d7158 9890
9b4b0a1a
GD
9891 Analyze_And_Resolve
9892 (Last (Expressions (Agg)), Component_Type (Typ));
0f95b178
JM
9893 end loop;
9894
9895 Set_Aggregate_Bounds (Agg, Bounds);
9896 Set_Etype (Agg, Typ);
9897 Set_Analyzed (Agg);
9898 Rewrite (N, Agg);
9899 Set_Compile_Time_Known_Aggregate (N);
9900
9901 return True;
9902 end if;
9903 end if;
9904
9905 else
9906 return False;
9907 end if;
9908 end Static_Array_Aggregate;
9b4b0a1a 9909
937e9676
AC
9910 ----------------------------------
9911 -- Two_Dim_Packed_Array_Handled --
9912 ----------------------------------
9913
9914 function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean is
9915 Loc : constant Source_Ptr := Sloc (N);
9916 Typ : constant Entity_Id := Etype (N);
9917 Ctyp : constant Entity_Id := Component_Type (Typ);
9918 Comp_Size : constant Int := UI_To_Int (Component_Size (Typ));
9919 Packed_Array : constant Entity_Id :=
9920 Packed_Array_Impl_Type (Base_Type (Typ));
9921
9922 One_Comp : Node_Id;
9923 -- Expression in original aggregate
9924
9925 One_Dim : Node_Id;
9926 -- One-dimensional subaggregate
9927
9928 begin
9929
9930 -- For now, only deal with cases where an integral number of elements
9931 -- fit in a single byte. This includes the most common boolean case.
9932
9933 if not (Comp_Size = 1 or else
9934 Comp_Size = 2 or else
9935 Comp_Size = 4)
9936 then
9937 return False;
9938 end if;
9939
c42006e9 9940 Convert_To_Positional (N, Handle_Bit_Packed => True);
937e9676
AC
9941
9942 -- Verify that all components are static
9943
9944 if Nkind (N) = N_Aggregate
9945 and then Compile_Time_Known_Aggregate (N)
9946 then
9947 null;
9948
9949 -- The aggregate may have been reanalyzed and converted already
9950
9951 elsif Nkind (N) /= N_Aggregate then
9952 return True;
9953
9954 -- If component associations remain, the aggregate is not static
9955
9956 elsif Present (Component_Associations (N)) then
9957 return False;
9958
9959 else
9960 One_Dim := First (Expressions (N));
9961 while Present (One_Dim) loop
9962 if Present (Component_Associations (One_Dim)) then
9963 return False;
9964 end if;
9965
9966 One_Comp := First (Expressions (One_Dim));
9967 while Present (One_Comp) loop
9968 if not Is_OK_Static_Expression (One_Comp) then
9969 return False;
9970 end if;
9971
9972 Next (One_Comp);
9973 end loop;
9974
9975 Next (One_Dim);
9976 end loop;
9977 end if;
9978
9979 -- Two-dimensional aggregate is now fully positional so pack one
9980 -- dimension to create a static one-dimensional array, and rewrite
9981 -- as an unchecked conversion to the original type.
9982
9983 declare
9984 Byte_Size : constant Int := UI_To_Int (Component_Size (Packed_Array));
9985 -- The packed array type is a byte array
9986
9987 Packed_Num : Nat;
9988 -- Number of components accumulated in current byte
9989
9990 Comps : List_Id;
9991 -- Assembled list of packed values for equivalent aggregate
9992
9993 Comp_Val : Uint;
9994 -- Integer value of component
9995
9996 Incr : Int;
9997 -- Step size for packing
9998
9999 Init_Shift : Int;
10000 -- Endian-dependent start position for packing
10001
10002 Shift : Int;
10003 -- Current insertion position
10004
10005 Val : Int;
10006 -- Component of packed array being assembled
10007
10008 begin
10009 Comps := New_List;
10010 Val := 0;
10011 Packed_Num := 0;
10012
64ac53f4 10013 -- Account for endianness. See corresponding comment in
937e9676
AC
10014 -- Packed_Array_Aggregate_Handled concerning the following.
10015
10016 if Bytes_Big_Endian
10017 xor Debug_Flag_8
10018 xor Reverse_Storage_Order (Base_Type (Typ))
10019 then
10020 Init_Shift := Byte_Size - Comp_Size;
10021 Incr := -Comp_Size;
10022 else
10023 Init_Shift := 0;
10024 Incr := +Comp_Size;
10025 end if;
10026
10027 -- Iterate over each subaggregate
10028
10029 Shift := Init_Shift;
10030 One_Dim := First (Expressions (N));
10031 while Present (One_Dim) loop
10032 One_Comp := First (Expressions (One_Dim));
10033 while Present (One_Comp) loop
10034 if Packed_Num = Byte_Size / Comp_Size then
10035
10036 -- Byte is complete, add to list of expressions
10037
10038 Append (Make_Integer_Literal (Sloc (One_Dim), Val), Comps);
10039 Val := 0;
10040 Shift := Init_Shift;
10041 Packed_Num := 0;
10042
10043 else
10044 Comp_Val := Expr_Rep_Value (One_Comp);
10045
10046 -- Adjust for bias, and strip proper number of bits
10047
10048 if Has_Biased_Representation (Ctyp) then
10049 Comp_Val := Comp_Val - Expr_Value (Type_Low_Bound (Ctyp));
10050 end if;
10051
10052 Comp_Val := Comp_Val mod Uint_2 ** Comp_Size;
10053 Val := UI_To_Int (Val + Comp_Val * Uint_2 ** Shift);
10054 Shift := Shift + Incr;
99859ea7 10055 Next (One_Comp);
937e9676
AC
10056 Packed_Num := Packed_Num + 1;
10057 end if;
10058 end loop;
10059
99859ea7 10060 Next (One_Dim);
937e9676
AC
10061 end loop;
10062
10063 if Packed_Num > 0 then
10064
10065 -- Add final incomplete byte if present
10066
10067 Append (Make_Integer_Literal (Sloc (One_Dim), Val), Comps);
10068 end if;
10069
10070 Rewrite (N,
10071 Unchecked_Convert_To (Typ,
10072 Make_Qualified_Expression (Loc,
10073 Subtype_Mark => New_Occurrence_Of (Packed_Array, Loc),
10074 Expression => Make_Aggregate (Loc, Expressions => Comps))));
10075 Analyze_And_Resolve (N);
10076 return True;
10077 end;
10078 end Two_Dim_Packed_Array_Handled;
10079
70482933 10080end Exp_Aggr;
This page took 7.693691 seconds and 5 git commands to generate.