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