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