OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [exp_aggr.adb] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                             E X P _ A G G R                              --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2005, Free Software Foundation, Inc.         --
10
--                                                                          --
11
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12
-- terms of the  GNU General Public License as published  by the Free Soft- --
13
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17
-- for  more details.  You should have  received  a copy of the GNU General --
18
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20
-- Boston, MA 02110-1301, USA.                                              --
21
--                                                                          --
22
-- GNAT was originally developed  by the GNAT team at  New York University. --
23
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
24
--                                                                          --
25
------------------------------------------------------------------------------
26
 
27
with Atree;    use Atree;
28
with Checks;   use Checks;
29
with Debug;    use Debug;
30
with Einfo;    use Einfo;
31
with Elists;   use Elists;
32
with Expander; use Expander;
33
with Exp_Util; use Exp_Util;
34
with Exp_Ch3;  use Exp_Ch3;
35
with Exp_Ch7;  use Exp_Ch7;
36
with Exp_Ch9;  use Exp_Ch9;
37
with Exp_Tss;  use Exp_Tss;
38
with Freeze;   use Freeze;
39
with Hostparm; use Hostparm;
40
with Itypes;   use Itypes;
41
with Lib;      use Lib;
42
with Nmake;    use Nmake;
43
with Nlists;   use Nlists;
44
with Restrict; use Restrict;
45
with Rident;   use Rident;
46
with Rtsfind;  use Rtsfind;
47
with Ttypes;   use Ttypes;
48
with Sem;      use Sem;
49
with Sem_Ch3;  use Sem_Ch3;
50
with Sem_Eval; use Sem_Eval;
51
with Sem_Res;  use Sem_Res;
52
with Sem_Util; use Sem_Util;
53
with Sinfo;    use Sinfo;
54
with Snames;   use Snames;
55
with Stand;    use Stand;
56
with Tbuild;   use Tbuild;
57
with Uintp;    use Uintp;
58
 
59
package body Exp_Aggr is
60
 
61
   type Case_Bounds is record
62
     Choice_Lo   : Node_Id;
63
     Choice_Hi   : Node_Id;
64
     Choice_Node : Node_Id;
65
   end record;
66
 
67
   type Case_Table_Type is array (Nat range <>) of Case_Bounds;
68
   --  Table type used by Check_Case_Choices procedure
69
 
70
   function Must_Slide
71
     (Obj_Type : Entity_Id;
72
      Typ      : Entity_Id) return Boolean;
73
   --  A static array aggregate in an object declaration can in most cases be
74
   --  expanded in place. The one exception is when the aggregate is given
75
   --  with component associations that specify different bounds from those of
76
   --  the type definition in the object declaration. In this pathological
77
   --  case the aggregate must slide, and we must introduce an intermediate
78
   --  temporary to hold it.
79
   --
80
   --  The same holds in an assignment to one-dimensional array of arrays,
81
   --  when a component may be given with bounds that differ from those of the
82
   --  component type.
83
 
84
   procedure Sort_Case_Table (Case_Table : in out Case_Table_Type);
85
   --  Sort the Case Table using the Lower Bound of each Choice as the key.
86
   --  A simple insertion sort is used since the number of choices in a case
87
   --  statement of variant part will usually be small and probably in near
88
   --  sorted order.
89
 
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
 
94
   ------------------------------------------------------
95
   -- Local subprograms for Record Aggregate Expansion --
96
   ------------------------------------------------------
97
 
98
   procedure Expand_Record_Aggregate
99
     (N           : Node_Id;
100
      Orig_Tag    : Node_Id := Empty;
101
      Parent_Expr : Node_Id := Empty);
102
   --  This is the top level procedure for record aggregate expansion.
103
   --  Expansion for record aggregates needs expand aggregates for tagged
104
   --  record types. Specifically Expand_Record_Aggregate adds the Tag
105
   --  field in front of the Component_Association list that was created
106
   --  during resolution by Resolve_Record_Aggregate.
107
   --
108
   --    N is the record aggregate node.
109
   --    Orig_Tag is the value of the Tag that has to be provided for this
110
   --      specific aggregate. It carries the tag corresponding to the type
111
   --      of the outermost aggregate during the recursive expansion
112
   --    Parent_Expr is the ancestor part of the original extension
113
   --      aggregate
114
 
115
   procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
116
   --  N is an N_Aggregate of a N_Extension_Aggregate. Typ is the type of
117
   --  the aggregate. Transform the given aggregate into a sequence of
118
   --  assignments component per component.
119
 
120
   function Build_Record_Aggr_Code
121
     (N                             : Node_Id;
122
      Typ                           : Entity_Id;
123
      Target                        : Node_Id;
124
      Flist                         : Node_Id   := Empty;
125
      Obj                           : Entity_Id := Empty;
126
      Is_Limited_Ancestor_Expansion : Boolean   := False) return List_Id;
127
   --  N is an N_Aggregate or a N_Extension_Aggregate. Typ is the type of the
128
   --  aggregate. Target is an expression containing the location on which the
129
   --  component by component assignments will take place. Returns the list of
130
   --  assignments plus all other adjustments needed for tagged and controlled
131
   --  types. Flist is an expression representing the finalization list on
132
   --  which to attach the controlled components if any. Obj is present in the
133
   --  object declaration and dynamic allocation cases, it contains an entity
134
   --  that allows to know if the value being created needs to be attached to
135
   --  the final list in case of pragma finalize_Storage_Only.
136
   --
137
   --  Is_Limited_Ancestor_Expansion indicates that the function has been
138
   --  called recursively to expand the limited ancestor to avoid copying it.
139
 
140
   function Has_Mutable_Components (Typ : Entity_Id) return Boolean;
141
   --  Return true if one of the component is of a discriminated type with
142
   --  defaults. An aggregate for a type with mutable components must be
143
   --  expanded into individual assignments.
144
 
145
   procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id);
146
   --  If the type of the aggregate is a type extension with renamed discrimi-
147
   --  nants, we must initialize the hidden discriminants of the parent.
148
   --  Otherwise, the target object must not be initialized. The discriminants
149
   --  are initialized by calling the initialization procedure for the type.
150
   --  This is incorrect if the initialization of other components has any
151
   --  side effects. We restrict this call to the case where the parent type
152
   --  has a variant part, because this is the only case where the hidden
153
   --  discriminants are accessed, namely when calling discriminant checking
154
   --  functions of the parent type, and when applying a stream attribute to
155
   --  an object of the derived type.
156
 
157
   -----------------------------------------------------
158
   -- Local Subprograms for Array Aggregate Expansion --
159
   -----------------------------------------------------
160
 
161
   function Aggr_Size_OK (Typ : Entity_Id) return Boolean;
162
   --  Very large static aggregates present problems to the back-end, and
163
   --  are transformed into assignments and loops. This function verifies
164
   --  that the total number of components of an aggregate is acceptable
165
   --  for transformation into a purely positional static form. It is called
166
   --  prior to calling Flatten.
167
 
168
   procedure Convert_Array_Aggr_In_Allocator
169
     (Decl   : Node_Id;
170
      Aggr   : Node_Id;
171
      Target : Node_Id);
172
   --  If the aggregate appears within an allocator and can be expanded in
173
   --  place, this routine generates the individual assignments to components
174
   --  of the designated object. This is an optimization over the general
175
   --  case, where a temporary is first created on the stack and then used to
176
   --  construct the allocated object on the heap.
177
 
178
   procedure Convert_To_Positional
179
     (N                    : Node_Id;
180
      Max_Others_Replicate : Nat     := 5;
181
      Handle_Bit_Packed    : Boolean := False);
182
   --  If possible, convert named notation to positional notation. This
183
   --  conversion is possible only in some static cases. If the conversion is
184
   --  possible, then N is rewritten with the analyzed converted aggregate.
185
   --  The parameter Max_Others_Replicate controls the maximum number of
186
   --  values corresponding to an others choice that will be converted to
187
   --  positional notation (the default of 5 is the normal limit, and reflects
188
   --  the fact that normally the loop is better than a lot of separate
189
   --  assignments). Note that this limit gets overridden in any case if
190
   --  either of the restrictions No_Elaboration_Code or No_Implicit_Loops is
191
   --  set. The parameter Handle_Bit_Packed is usually set False (since we do
192
   --  not expect the back end to handle bit packed arrays, so the normal case
193
   --  of conversion is pointless), but in the special case of a call from
194
   --  Packed_Array_Aggregate_Handled, we set this parameter to True, since
195
   --  these are cases we handle in there.
196
 
197
   procedure Expand_Array_Aggregate (N : Node_Id);
198
   --  This is the top-level routine to perform array aggregate expansion.
199
   --  N is the N_Aggregate node to be expanded.
200
 
201
   function Backend_Processing_Possible (N : Node_Id) return Boolean;
202
   --  This function checks if array aggregate N can be processed directly
203
   --  by Gigi. If this is the case True is returned.
204
 
205
   function Build_Array_Aggr_Code
206
     (N           : Node_Id;
207
      Ctype       : Entity_Id;
208
      Index       : Node_Id;
209
      Into        : Node_Id;
210
      Scalar_Comp : Boolean;
211
      Indices     : List_Id := No_List;
212
      Flist       : Node_Id := Empty) return List_Id;
213
   --  This recursive routine returns a list of statements containing the
214
   --  loops and assignments that are needed for the expansion of the array
215
   --  aggregate N.
216
   --
217
   --    N is the (sub-)aggregate node to be expanded into code. This node
218
   --    has been fully analyzed, and its Etype is properly set.
219
   --
220
   --    Index is the index node corresponding to the array sub-aggregate N.
221
   --
222
   --    Into is the target expression into which we are copying the aggregate.
223
   --    Note that this node may not have been analyzed yet, and so the Etype
224
   --    field may not be set.
225
   --
226
   --    Scalar_Comp is True if the component type of the aggregate is scalar.
227
   --
228
   --    Indices is the current list of expressions used to index the
229
   --    object we are writing into.
230
   --
231
   --    Flist is an expression representing the finalization list on which
232
   --    to attach the controlled components if any.
233
 
234
   function Number_Of_Choices (N : Node_Id) return Nat;
235
   --  Returns the number of discrete choices (not including the others choice
236
   --  if present) contained in (sub-)aggregate N.
237
 
238
   function Late_Expansion
239
     (N      : Node_Id;
240
      Typ    : Entity_Id;
241
      Target : Node_Id;
242
      Flist  : Node_Id := Empty;
243
      Obj    : Entity_Id := Empty) return List_Id;
244
   --  N is a nested (record or array) aggregate that has been marked with
245
   --  'Delay_Expansion'. Typ is the expected type of the aggregate and Target
246
   --  is a (duplicable) expression that will hold the result of the aggregate
247
   --  expansion. Flist is the finalization list to be used to attach
248
   --  controlled components. 'Obj' when non empty, carries the original
249
   --  object being initialized in order to know if it needs to be attached to
250
   --  the previous parameter which may not be the case in the case where
251
   --  Finalize_Storage_Only is set. Basically this procedure is used to
252
   --  implement top-down expansions of nested aggregates. This is necessary
253
   --  for avoiding temporaries at each level as well as for propagating the
254
   --  right internal finalization list.
255
 
256
   function Make_OK_Assignment_Statement
257
     (Sloc       : Source_Ptr;
258
      Name       : Node_Id;
259
      Expression : Node_Id) return Node_Id;
260
   --  This is like Make_Assignment_Statement, except that Assignment_OK
261
   --  is set in the left operand. All assignments built by this unit
262
   --  use this routine. This is needed to deal with assignments to
263
   --  initialized constants that are done in place.
264
 
265
   function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean;
266
   --  Given an array aggregate, this function handles the case of a packed
267
   --  array aggregate with all constant values, where the aggregate can be
268
   --  evaluated at compile time. If this is possible, then N is rewritten
269
   --  to be its proper compile time value with all the components properly
270
   --  assembled. The expression is analyzed and resolved and True is
271
   --  returned. If this transformation is not possible, N is unchanged
272
   --  and False is returned
273
 
274
   function Safe_Slice_Assignment (N : Node_Id) return Boolean;
275
   --  If a slice assignment has an aggregate with a single others_choice,
276
   --  the assignment can be done in place even if bounds are not static,
277
   --  by converting it into a loop over the discrete range of the slice.
278
 
279
   ------------------
280
   -- Aggr_Size_OK --
281
   ------------------
282
 
283
   function Aggr_Size_OK (Typ : Entity_Id) return Boolean is
284
      Lo   : Node_Id;
285
      Hi   : Node_Id;
286
      Indx : Node_Id;
287
      Siz  : Int;
288
      Lov  : Uint;
289
      Hiv  : Uint;
290
 
291
      --  The following constant determines the maximum size of an
292
      --  aggregate produced by converting named to positional
293
      --  notation (e.g. from others clauses). This avoids running
294
      --  away with attempts to convert huge aggregates, which hit
295
      --  memory limits in the backend.
296
 
297
      --  The normal limit is 5000, but we increase this limit to
298
      --  2**24 (about 16 million) if Restrictions (No_Elaboration_Code)
299
      --  or Restrictions (No_Implicit_Loops) is specified, since in
300
      --  either case, we are at risk of declaring the program illegal
301
      --  because of this limit.
302
 
303
      Max_Aggr_Size : constant Nat :=
304
                        5000 + (2 ** 24 - 5000) *
305
                          Boolean'Pos
306
                            (Restriction_Active (No_Elaboration_Code)
307
                               or else
308
                             Restriction_Active (No_Implicit_Loops));
309
 
310
      function Component_Count (T : Entity_Id) return Int;
311
      --  The limit is applied to the total number of components that the
312
      --  aggregate will have, which is the number of static expressions
313
      --  that will appear in the flattened array. This requires a recursive
314
      --  computation of the the number of scalar components of the structure.
315
 
316
      ---------------------
317
      -- Component_Count --
318
      ---------------------
319
 
320
      function Component_Count (T : Entity_Id) return Int is
321
         Res  : Int := 0;
322
         Comp : Entity_Id;
323
 
324
      begin
325
         if Is_Scalar_Type (T) then
326
            return 1;
327
 
328
         elsif Is_Record_Type (T) then
329
            Comp := First_Component (T);
330
            while Present (Comp) loop
331
               Res := Res + Component_Count (Etype (Comp));
332
               Next_Component (Comp);
333
            end loop;
334
 
335
            return Res;
336
 
337
         elsif Is_Array_Type (T) then
338
            declare
339
               Lo : constant Node_Id :=
340
                      Type_Low_Bound (Etype (First_Index (T)));
341
               Hi : constant Node_Id :=
342
                      Type_High_Bound (Etype (First_Index (T)));
343
 
344
               Siz  : constant Int := Component_Count (Component_Type (T));
345
 
346
            begin
347
               if not Compile_Time_Known_Value (Lo)
348
                 or else not Compile_Time_Known_Value (Hi)
349
               then
350
                  return 0;
351
               else
352
                  return
353
                    Siz * UI_To_Int (Expr_Value (Hi) - Expr_Value (Lo) + 1);
354
               end if;
355
            end;
356
 
357
         else
358
            --  Can only be a null for an access type
359
 
360
            return 1;
361
         end if;
362
      end Component_Count;
363
 
364
   --  Start of processing for Aggr_Size_OK
365
 
366
   begin
367
      Siz  := Component_Count (Component_Type (Typ));
368
      Indx := First_Index (Typ);
369
 
370
      while Present (Indx) loop
371
         Lo  := Type_Low_Bound (Etype (Indx));
372
         Hi  := Type_High_Bound (Etype (Indx));
373
 
374
         --  Bounds need to be known at compile time
375
 
376
         if not Compile_Time_Known_Value (Lo)
377
           or else not Compile_Time_Known_Value (Hi)
378
         then
379
            return False;
380
         end if;
381
 
382
         Lov := Expr_Value (Lo);
383
         Hiv := Expr_Value (Hi);
384
 
385
         --  A flat array is always safe
386
 
387
         if Hiv < Lov then
388
            return True;
389
         end if;
390
 
391
         declare
392
            Rng : constant Uint := Hiv - Lov + 1;
393
 
394
         begin
395
            --  Check if size is too large
396
 
397
            if not UI_Is_In_Int_Range (Rng) then
398
               return False;
399
            end if;
400
 
401
            Siz := Siz * UI_To_Int (Rng);
402
         end;
403
 
404
         if Siz <= 0
405
           or else Siz > Max_Aggr_Size
406
         then
407
            return False;
408
         end if;
409
 
410
         --  Bounds must be in integer range, for later array construction
411
 
412
         if not UI_Is_In_Int_Range (Lov)
413
             or else
414
            not UI_Is_In_Int_Range (Hiv)
415
         then
416
            return False;
417
         end if;
418
 
419
         Next_Index (Indx);
420
      end loop;
421
 
422
      return True;
423
   end Aggr_Size_OK;
424
 
425
   ---------------------------------
426
   -- Backend_Processing_Possible --
427
   ---------------------------------
428
 
429
   --  Backend processing by Gigi/gcc is possible only if all the following
430
   --  conditions are met:
431
 
432
   --    1. N is fully positional
433
 
434
   --    2. N is not a bit-packed array aggregate;
435
 
436
   --    3. The size of N's array type must be known at compile time. Note
437
   --       that this implies that the component size is also known
438
 
439
   --    4. The array type of N does not follow the Fortran layout convention
440
   --       or if it does it must be 1 dimensional.
441
 
442
   --    5. The array component type is tagged, which may necessitate
443
   --       reassignment of proper tags.
444
 
445
   --    6. The array component type might have unaligned bit components
446
 
447
   function Backend_Processing_Possible (N : Node_Id) return Boolean is
448
      Typ : constant Entity_Id := Etype (N);
449
      --  Typ is the correct constrained array subtype of the aggregate
450
 
451
      function Static_Check (N : Node_Id; Index : Node_Id) return Boolean;
452
      --  Recursively checks that N is fully positional, returns true if so
453
 
454
      ------------------
455
      -- Static_Check --
456
      ------------------
457
 
458
      function Static_Check (N : Node_Id; Index : Node_Id) return Boolean is
459
         Expr : Node_Id;
460
 
461
      begin
462
         --  Check for component associations
463
 
464
         if Present (Component_Associations (N)) then
465
            return False;
466
         end if;
467
 
468
         --  Recurse to check subaggregates, which may appear in qualified
469
         --  expressions. If delayed, the front-end will have to expand.
470
 
471
         Expr := First (Expressions (N));
472
 
473
         while Present (Expr) loop
474
 
475
            if Is_Delayed_Aggregate (Expr) then
476
               return False;
477
            end if;
478
 
479
            if Present (Next_Index (Index))
480
               and then not Static_Check (Expr, Next_Index (Index))
481
            then
482
               return False;
483
            end if;
484
 
485
            Next (Expr);
486
         end loop;
487
 
488
         return True;
489
      end Static_Check;
490
 
491
   --  Start of processing for Backend_Processing_Possible
492
 
493
   begin
494
      --  Checks 2 (array must not be bit packed)
495
 
496
      if Is_Bit_Packed_Array (Typ) then
497
         return False;
498
      end if;
499
 
500
      --  Checks 4 (array must not be multi-dimensional Fortran case)
501
 
502
      if Convention (Typ) = Convention_Fortran
503
        and then Number_Dimensions (Typ) > 1
504
      then
505
         return False;
506
      end if;
507
 
508
      --  Checks 3 (size of array must be known at compile time)
509
 
510
      if not Size_Known_At_Compile_Time (Typ) then
511
         return False;
512
      end if;
513
 
514
      --  Checks 1 (aggregate must be fully positional)
515
 
516
      if not Static_Check (N, First_Index (Typ)) then
517
         return False;
518
      end if;
519
 
520
      --  Checks 5 (if the component type is tagged, then we may need
521
      --    to do tag adjustments; perhaps this should be refined to check for
522
      --    any component associations that actually need tag adjustment,
523
      --    along the lines of the test that is carried out in
524
      --    Has_Delayed_Nested_Aggregate_Or_Tagged_Comps for record aggregates
525
      --    with tagged components, but not clear whether it's worthwhile ???;
526
      --    in the case of the JVM, object tags are handled implicitly)
527
 
528
      if Is_Tagged_Type (Component_Type (Typ)) and then not Java_VM then
529
         return False;
530
      end if;
531
 
532
      --  Checks 6 (component type must not have bit aligned components)
533
 
534
      if Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)) then
535
         return False;
536
      end if;
537
 
538
      --  Backend processing is possible
539
 
540
      Set_Compile_Time_Known_Aggregate (N, True);
541
      Set_Size_Known_At_Compile_Time (Etype (N), True);
542
      return True;
543
   end Backend_Processing_Possible;
544
 
545
   ---------------------------
546
   -- Build_Array_Aggr_Code --
547
   ---------------------------
548
 
549
   --  The code that we generate from a one dimensional aggregate is
550
 
551
   --  1. If the sub-aggregate contains discrete choices we
552
 
553
   --     (a) Sort the discrete choices
554
 
555
   --     (b) Otherwise for each discrete choice that specifies a range we
556
   --         emit a loop. If a range specifies a maximum of three values, or
557
   --         we are dealing with an expression we emit a sequence of
558
   --         assignments instead of a loop.
559
 
560
   --     (c) Generate the remaining loops to cover the others choice if any
561
 
562
   --  2. If the aggregate contains positional elements we
563
 
564
   --     (a) translate the positional elements in a series of assignments
565
 
566
   --     (b) Generate a final loop to cover the others choice if any.
567
   --         Note that this final loop has to be a while loop since the case
568
 
569
   --             L : Integer := Integer'Last;
570
   --             H : Integer := Integer'Last;
571
   --             A : array (L .. H) := (1, others =>0);
572
 
573
   --         cannot be handled by a for loop. Thus for the following
574
 
575
   --             array (L .. H) := (.. positional elements.., others =>E);
576
 
577
   --         we always generate something like:
578
 
579
   --             J : Index_Type := Index_Of_Last_Positional_Element;
580
   --             while J < H loop
581
   --                J := Index_Base'Succ (J)
582
   --                Tmp (J) := E;
583
   --             end loop;
584
 
585
   function Build_Array_Aggr_Code
586
     (N           : Node_Id;
587
      Ctype       : Entity_Id;
588
      Index       : Node_Id;
589
      Into        : Node_Id;
590
      Scalar_Comp : Boolean;
591
      Indices     : List_Id := No_List;
592
      Flist       : Node_Id := Empty) return List_Id
593
   is
594
      Loc          : constant Source_Ptr := Sloc (N);
595
      Index_Base   : constant Entity_Id  := Base_Type (Etype (Index));
596
      Index_Base_L : constant Node_Id := Type_Low_Bound (Index_Base);
597
      Index_Base_H : constant Node_Id := Type_High_Bound (Index_Base);
598
 
599
      function Add (Val : Int; To : Node_Id) return Node_Id;
600
      --  Returns an expression where Val is added to expression To, unless
601
      --  To+Val is provably out of To's base type range. To must be an
602
      --  already analyzed expression.
603
 
604
      function Empty_Range (L, H : Node_Id) return Boolean;
605
      --  Returns True if the range defined by L .. H is certainly empty
606
 
607
      function Equal (L, H : Node_Id) return Boolean;
608
      --  Returns True if L = H for sure
609
 
610
      function Index_Base_Name return Node_Id;
611
      --  Returns a new reference to the index type name
612
 
613
      function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id;
614
      --  Ind must be a side-effect free expression. If the input aggregate
615
      --  N to Build_Loop contains no sub-aggregates, then this function
616
      --  returns the assignment statement:
617
      --
618
      --     Into (Indices, Ind) := Expr;
619
      --
620
      --  Otherwise we call Build_Code recursively
621
      --
622
      --  Ada 2005 (AI-287): In case of default initialized component, Expr
623
      --  is empty and we generate a call to the corresponding IP subprogram.
624
 
625
      function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
626
      --  Nodes L and H must be side-effect free expressions.
627
      --  If the input aggregate N to Build_Loop contains no sub-aggregates,
628
      --  This routine returns the for loop statement
629
      --
630
      --     for J in Index_Base'(L) .. Index_Base'(H) loop
631
      --        Into (Indices, J) := Expr;
632
      --     end loop;
633
      --
634
      --  Otherwise we call Build_Code recursively.
635
      --  As an optimization if the loop covers 3 or less scalar elements we
636
      --  generate a sequence of assignments.
637
 
638
      function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id;
639
      --  Nodes L and H must be side-effect free expressions.
640
      --  If the input aggregate N to Build_Loop contains no sub-aggregates,
641
      --  This routine returns the while loop statement
642
      --
643
      --     J : Index_Base := L;
644
      --     while J < H loop
645
      --        J := Index_Base'Succ (J);
646
      --        Into (Indices, J) := Expr;
647
      --     end loop;
648
      --
649
      --  Otherwise we call Build_Code recursively
650
 
651
      function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean;
652
      function Local_Expr_Value               (E : Node_Id) return Uint;
653
      --  These two Local routines are used to replace the corresponding ones
654
      --  in sem_eval because while processing the bounds of an aggregate with
655
      --  discrete choices whose index type is an enumeration, we build static
656
      --  expressions not recognized by Compile_Time_Known_Value as such since
657
      --  they have not yet been analyzed and resolved. All the expressions in
658
      --  question are things like Index_Base_Name'Val (Const) which we can
659
      --  easily recognize as being constant.
660
 
661
      ---------
662
      -- Add --
663
      ---------
664
 
665
      function Add (Val : Int; To : Node_Id) return Node_Id is
666
         Expr_Pos : Node_Id;
667
         Expr     : Node_Id;
668
         To_Pos   : Node_Id;
669
         U_To     : Uint;
670
         U_Val    : constant Uint := UI_From_Int (Val);
671
 
672
      begin
673
         --  Note: do not try to optimize the case of Val = 0, because
674
         --  we need to build a new node with the proper Sloc value anyway.
675
 
676
         --  First test if we can do constant folding
677
 
678
         if Local_Compile_Time_Known_Value (To) then
679
            U_To := Local_Expr_Value (To) + Val;
680
 
681
            --  Determine if our constant is outside the range of the index.
682
            --  If so return an Empty node. This empty node will be caught
683
            --  by Empty_Range below.
684
 
685
            if Compile_Time_Known_Value (Index_Base_L)
686
              and then U_To < Expr_Value (Index_Base_L)
687
            then
688
               return Empty;
689
 
690
            elsif Compile_Time_Known_Value (Index_Base_H)
691
              and then U_To > Expr_Value (Index_Base_H)
692
            then
693
               return Empty;
694
            end if;
695
 
696
            Expr_Pos := Make_Integer_Literal (Loc, U_To);
697
            Set_Is_Static_Expression (Expr_Pos);
698
 
699
            if not Is_Enumeration_Type (Index_Base) then
700
               Expr := Expr_Pos;
701
 
702
            --  If we are dealing with enumeration return
703
            --     Index_Base'Val (Expr_Pos)
704
 
705
            else
706
               Expr :=
707
                 Make_Attribute_Reference
708
                   (Loc,
709
                    Prefix         => Index_Base_Name,
710
                    Attribute_Name => Name_Val,
711
                    Expressions    => New_List (Expr_Pos));
712
            end if;
713
 
714
            return Expr;
715
         end if;
716
 
717
         --  If we are here no constant folding possible
718
 
719
         if not Is_Enumeration_Type (Index_Base) then
720
            Expr :=
721
              Make_Op_Add (Loc,
722
                           Left_Opnd  => Duplicate_Subexpr (To),
723
                           Right_Opnd => Make_Integer_Literal (Loc, U_Val));
724
 
725
         --  If we are dealing with enumeration return
726
         --    Index_Base'Val (Index_Base'Pos (To) + Val)
727
 
728
         else
729
            To_Pos :=
730
              Make_Attribute_Reference
731
                (Loc,
732
                 Prefix         => Index_Base_Name,
733
                 Attribute_Name => Name_Pos,
734
                 Expressions    => New_List (Duplicate_Subexpr (To)));
735
 
736
            Expr_Pos :=
737
              Make_Op_Add (Loc,
738
                           Left_Opnd  => To_Pos,
739
                           Right_Opnd => Make_Integer_Literal (Loc, U_Val));
740
 
741
            Expr :=
742
              Make_Attribute_Reference
743
                (Loc,
744
                 Prefix         => Index_Base_Name,
745
                 Attribute_Name => Name_Val,
746
                 Expressions    => New_List (Expr_Pos));
747
         end if;
748
 
749
         return Expr;
750
      end Add;
751
 
752
      -----------------
753
      -- Empty_Range --
754
      -----------------
755
 
756
      function Empty_Range (L, H : Node_Id) return Boolean is
757
         Is_Empty : Boolean := False;
758
         Low      : Node_Id;
759
         High     : Node_Id;
760
 
761
      begin
762
         --  First check if L or H were already detected as overflowing the
763
         --  index base range type by function Add above. If this is so Add
764
         --  returns the empty node.
765
 
766
         if No (L) or else No (H) then
767
            return True;
768
         end if;
769
 
770
         for J in 1 .. 3 loop
771
            case J is
772
 
773
               --  L > H    range is empty
774
 
775
               when 1 =>
776
                  Low  := L;
777
                  High := H;
778
 
779
               --  B_L > H  range must be empty
780
 
781
               when 2 =>
782
                  Low  := Index_Base_L;
783
                  High := H;
784
 
785
               --  L > B_H  range must be empty
786
 
787
               when 3 =>
788
                  Low  := L;
789
                  High := Index_Base_H;
790
            end case;
791
 
792
            if Local_Compile_Time_Known_Value (Low)
793
              and then Local_Compile_Time_Known_Value (High)
794
            then
795
               Is_Empty :=
796
                 UI_Gt (Local_Expr_Value (Low), Local_Expr_Value (High));
797
            end if;
798
 
799
            exit when Is_Empty;
800
         end loop;
801
 
802
         return Is_Empty;
803
      end Empty_Range;
804
 
805
      -----------
806
      -- Equal --
807
      -----------
808
 
809
      function Equal (L, H : Node_Id) return Boolean is
810
      begin
811
         if L = H then
812
            return True;
813
 
814
         elsif Local_Compile_Time_Known_Value (L)
815
           and then Local_Compile_Time_Known_Value (H)
816
         then
817
            return UI_Eq (Local_Expr_Value (L), Local_Expr_Value (H));
818
         end if;
819
 
820
         return False;
821
      end Equal;
822
 
823
      ----------------
824
      -- Gen_Assign --
825
      ----------------
826
 
827
      function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id is
828
         L : constant List_Id := New_List;
829
         F : Entity_Id;
830
         A : Node_Id;
831
 
832
         New_Indices  : List_Id;
833
         Indexed_Comp : Node_Id;
834
         Expr_Q       : Node_Id;
835
         Comp_Type    : Entity_Id := Empty;
836
 
837
         function Add_Loop_Actions (Lis : List_Id) return List_Id;
838
         --  Collect insert_actions generated in the construction of a
839
         --  loop, and prepend them to the sequence of assignments to
840
         --  complete the eventual body of the loop.
841
 
842
         ----------------------
843
         -- Add_Loop_Actions --
844
         ----------------------
845
 
846
         function Add_Loop_Actions (Lis : List_Id) return List_Id is
847
            Res : List_Id;
848
 
849
         begin
850
            --  Ada 2005 (AI-287): Do nothing else in case of default
851
            --  initialized component.
852
 
853
            if not Present (Expr) then
854
               return Lis;
855
 
856
            elsif Nkind (Parent (Expr)) = N_Component_Association
857
              and then Present (Loop_Actions (Parent (Expr)))
858
            then
859
               Append_List (Lis, Loop_Actions (Parent (Expr)));
860
               Res := Loop_Actions (Parent (Expr));
861
               Set_Loop_Actions (Parent (Expr), No_List);
862
               return Res;
863
 
864
            else
865
               return Lis;
866
            end if;
867
         end Add_Loop_Actions;
868
 
869
      --  Start of processing for Gen_Assign
870
 
871
      begin
872
         if No (Indices) then
873
            New_Indices := New_List;
874
         else
875
            New_Indices := New_Copy_List_Tree (Indices);
876
         end if;
877
 
878
         Append_To (New_Indices, Ind);
879
 
880
         if Present (Flist) then
881
            F := New_Copy_Tree (Flist);
882
 
883
         elsif Present (Etype (N)) and then Controlled_Type (Etype (N)) then
884
            if Is_Entity_Name (Into)
885
              and then Present (Scope (Entity (Into)))
886
            then
887
               F := Find_Final_List (Scope (Entity (Into)));
888
            else
889
               F := Find_Final_List (Current_Scope);
890
            end if;
891
         else
892
            F := Empty;
893
         end if;
894
 
895
         if Present (Next_Index (Index)) then
896
            return
897
              Add_Loop_Actions (
898
                Build_Array_Aggr_Code
899
                  (N           => Expr,
900
                   Ctype       => Ctype,
901
                   Index       => Next_Index (Index),
902
                   Into        => Into,
903
                   Scalar_Comp => Scalar_Comp,
904
                   Indices     => New_Indices,
905
                   Flist       => F));
906
         end if;
907
 
908
         --  If we get here then we are at a bottom-level (sub-)aggregate
909
 
910
         Indexed_Comp :=
911
           Checks_Off
912
             (Make_Indexed_Component (Loc,
913
                Prefix      => New_Copy_Tree (Into),
914
                Expressions => New_Indices));
915
 
916
         Set_Assignment_OK (Indexed_Comp);
917
 
918
         --  Ada 2005 (AI-287): In case of default initialized component, Expr
919
         --  is not present (and therefore we also initialize Expr_Q to empty).
920
 
921
         if not Present (Expr) then
922
            Expr_Q := Empty;
923
         elsif Nkind (Expr) = N_Qualified_Expression then
924
            Expr_Q := Expression (Expr);
925
         else
926
            Expr_Q := Expr;
927
         end if;
928
 
929
         if Present (Etype (N))
930
           and then Etype (N) /= Any_Composite
931
         then
932
            Comp_Type := Component_Type (Etype (N));
933
            pragma Assert (Comp_Type = Ctype); --  AI-287
934
 
935
         elsif Present (Next (First (New_Indices))) then
936
 
937
            --  Ada 2005 (AI-287): Do nothing in case of default initialized
938
            --  component because we have received the component type in
939
            --  the formal parameter Ctype.
940
 
941
            --  ??? Some assert pragmas have been added to check if this new
942
            --      formal can be used to replace this code in all cases.
943
 
944
            if Present (Expr) then
945
 
946
               --  This is a multidimensional array. Recover the component
947
               --  type from the outermost aggregate, because subaggregates
948
               --  do not have an assigned type.
949
 
950
               declare
951
                  P : Node_Id := Parent (Expr);
952
 
953
               begin
954
                  while Present (P) loop
955
                     if Nkind (P) = N_Aggregate
956
                       and then Present (Etype (P))
957
                     then
958
                        Comp_Type := Component_Type (Etype (P));
959
                        exit;
960
 
961
                     else
962
                        P := Parent (P);
963
                     end if;
964
                  end loop;
965
 
966
                  pragma Assert (Comp_Type = Ctype); --  AI-287
967
               end;
968
            end if;
969
         end if;
970
 
971
         --  Ada 2005 (AI-287): We only analyze the expression in case of non-
972
         --  default initialized components (otherwise Expr_Q is not present).
973
 
974
         if Present (Expr_Q)
975
           and then (Nkind (Expr_Q) = N_Aggregate
976
                     or else Nkind (Expr_Q) = N_Extension_Aggregate)
977
         then
978
            --  At this stage the Expression may not have been
979
            --  analyzed yet because the array aggregate code has not
980
            --  been updated to use the Expansion_Delayed flag and
981
            --  avoid analysis altogether to solve the same problem
982
            --  (see Resolve_Aggr_Expr). So let us do the analysis of
983
            --  non-array aggregates now in order to get the value of
984
            --  Expansion_Delayed flag for the inner aggregate ???
985
 
986
            if Present (Comp_Type) and then not Is_Array_Type (Comp_Type) then
987
               Analyze_And_Resolve (Expr_Q, Comp_Type);
988
            end if;
989
 
990
            if Is_Delayed_Aggregate (Expr_Q) then
991
 
992
               --  This is either a subaggregate of a multidimentional array,
993
               --  or a component of an array type whose component type is
994
               --  also an array. In the latter case, the expression may have
995
               --  component associations that provide different bounds from
996
               --  those of the component type, and sliding must occur. Instead
997
               --  of decomposing the current aggregate assignment, force the
998
               --  re-analysis of the assignment, so that a temporary will be
999
               --  generated in the usual fashion, and sliding will take place.
1000
 
1001
               if Nkind (Parent (N)) = N_Assignment_Statement
1002
                 and then Is_Array_Type (Comp_Type)
1003
                 and then Present (Component_Associations (Expr_Q))
1004
                 and then Must_Slide (Comp_Type, Etype (Expr_Q))
1005
               then
1006
                  Set_Expansion_Delayed (Expr_Q, False);
1007
                  Set_Analyzed (Expr_Q, False);
1008
 
1009
               else
1010
                  return
1011
                    Add_Loop_Actions (
1012
                      Late_Expansion (
1013
                        Expr_Q, Etype (Expr_Q), Indexed_Comp, F));
1014
               end if;
1015
            end if;
1016
         end if;
1017
 
1018
         --  Ada 2005 (AI-287): In case of default initialized component, call
1019
         --  the initialization subprogram associated with the component type.
1020
 
1021
         if not Present (Expr) then
1022
 
1023
            if Present (Base_Init_Proc (Etype (Ctype)))
1024
              or else Has_Task (Base_Type (Ctype))
1025
            then
1026
               Append_List_To (L,
1027
                 Build_Initialization_Call (Loc,
1028
                   Id_Ref            => Indexed_Comp,
1029
                   Typ               => Ctype,
1030
                   With_Default_Init => True));
1031
            end if;
1032
 
1033
         else
1034
            --  Now generate the assignment with no associated controlled
1035
            --  actions since the target of the assignment may not have
1036
            --  been initialized, it is not possible to Finalize it as
1037
            --  expected by normal controlled assignment. The rest of the
1038
            --  controlled actions are done manually with the proper
1039
            --  finalization list coming from the context.
1040
 
1041
            A :=
1042
              Make_OK_Assignment_Statement (Loc,
1043
                Name       => Indexed_Comp,
1044
                Expression => New_Copy_Tree (Expr));
1045
 
1046
            if Present (Comp_Type) and then Controlled_Type (Comp_Type) then
1047
               Set_No_Ctrl_Actions (A);
1048
 
1049
               --  If this is an aggregate for an array of arrays, each
1050
               --  subaggregate will be expanded as well, and even with
1051
               --  No_Ctrl_Actions the assignments of inner components will
1052
               --  require attachment in their assignments to temporaries.
1053
               --  These temporaries must be finalized for each subaggregate,
1054
               --  to prevent multiple attachments of the same temporary
1055
               --  location to same finalization chain (and consequently
1056
               --  circular lists). To ensure that finalization takes place
1057
               --  for each subaggregate we wrap the assignment in a block.
1058
 
1059
               if Is_Array_Type (Comp_Type)
1060
                 and then Nkind (Expr) = N_Aggregate
1061
               then
1062
                  A :=
1063
                    Make_Block_Statement (Loc,
1064
                      Handled_Statement_Sequence =>
1065
                        Make_Handled_Sequence_Of_Statements (Loc,
1066
                           Statements => New_List (A)));
1067
               end if;
1068
            end if;
1069
 
1070
            Append_To (L, A);
1071
 
1072
            --  Adjust the tag if tagged (because of possible view
1073
            --  conversions), unless compiling for the Java VM
1074
            --  where tags are implicit.
1075
 
1076
            if Present (Comp_Type)
1077
              and then Is_Tagged_Type (Comp_Type)
1078
              and then not Java_VM
1079
            then
1080
               A :=
1081
                 Make_OK_Assignment_Statement (Loc,
1082
                   Name =>
1083
                     Make_Selected_Component (Loc,
1084
                       Prefix =>  New_Copy_Tree (Indexed_Comp),
1085
                       Selector_Name =>
1086
                         New_Reference_To
1087
                           (First_Tag_Component (Comp_Type), Loc)),
1088
 
1089
                   Expression =>
1090
                     Unchecked_Convert_To (RTE (RE_Tag),
1091
                       New_Reference_To
1092
                         (Node (First_Elmt (Access_Disp_Table (Comp_Type))),
1093
                          Loc)));
1094
 
1095
               Append_To (L, A);
1096
            end if;
1097
 
1098
            --  Adjust and Attach the component to the proper final list
1099
            --  which can be the controller of the outer record object or
1100
            --  the final list associated with the scope
1101
 
1102
            if Present (Comp_Type)  and then Controlled_Type (Comp_Type) then
1103
               Append_List_To (L,
1104
                 Make_Adjust_Call (
1105
                   Ref         => New_Copy_Tree (Indexed_Comp),
1106
                   Typ         => Comp_Type,
1107
                   Flist_Ref   => F,
1108
                   With_Attach => Make_Integer_Literal (Loc, 1)));
1109
            end if;
1110
         end if;
1111
 
1112
         return Add_Loop_Actions (L);
1113
      end Gen_Assign;
1114
 
1115
      --------------
1116
      -- Gen_Loop --
1117
      --------------
1118
 
1119
      function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is
1120
         L_J : Node_Id;
1121
 
1122
         L_Range : Node_Id;
1123
         --  Index_Base'(L) .. Index_Base'(H)
1124
 
1125
         L_Iteration_Scheme : Node_Id;
1126
         --  L_J in Index_Base'(L) .. Index_Base'(H)
1127
 
1128
         L_Body : List_Id;
1129
         --  The statements to execute in the loop
1130
 
1131
         S : constant List_Id := New_List;
1132
         --  List of statements
1133
 
1134
         Tcopy : Node_Id;
1135
         --  Copy of expression tree, used for checking purposes
1136
 
1137
      begin
1138
         --  If loop bounds define an empty range return the null statement
1139
 
1140
         if Empty_Range (L, H) then
1141
            Append_To (S, Make_Null_Statement (Loc));
1142
 
1143
            --  Ada 2005 (AI-287): Nothing else need to be done in case of
1144
            --  default initialized component.
1145
 
1146
            if not Present (Expr) then
1147
               null;
1148
 
1149
            else
1150
               --  The expression must be type-checked even though no component
1151
               --  of the aggregate will have this value. This is done only for
1152
               --  actual components of the array, not for subaggregates. Do
1153
               --  the check on a copy, because the expression may be shared
1154
               --  among several choices, some of which might be non-null.
1155
 
1156
               if Present (Etype (N))
1157
                 and then Is_Array_Type (Etype (N))
1158
                 and then No (Next_Index (Index))
1159
               then
1160
                  Expander_Mode_Save_And_Set (False);
1161
                  Tcopy := New_Copy_Tree (Expr);
1162
                  Set_Parent (Tcopy, N);
1163
                  Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
1164
                  Expander_Mode_Restore;
1165
               end if;
1166
            end if;
1167
 
1168
            return S;
1169
 
1170
         --  If loop bounds are the same then generate an assignment
1171
 
1172
         elsif Equal (L, H) then
1173
            return Gen_Assign (New_Copy_Tree (L), Expr);
1174
 
1175
         --  If H - L <= 2 then generate a sequence of assignments
1176
         --  when we are processing the bottom most aggregate and it contains
1177
         --  scalar components.
1178
 
1179
         elsif No (Next_Index (Index))
1180
           and then Scalar_Comp
1181
           and then Local_Compile_Time_Known_Value (L)
1182
           and then Local_Compile_Time_Known_Value (H)
1183
           and then Local_Expr_Value (H) - Local_Expr_Value (L) <= 2
1184
         then
1185
 
1186
            Append_List_To (S, Gen_Assign (New_Copy_Tree (L), Expr));
1187
            Append_List_To (S, Gen_Assign (Add (1, To => L), Expr));
1188
 
1189
            if Local_Expr_Value (H) - Local_Expr_Value (L) = 2 then
1190
               Append_List_To (S, Gen_Assign (Add (2, To => L), Expr));
1191
            end if;
1192
 
1193
            return S;
1194
         end if;
1195
 
1196
         --  Otherwise construct the loop, starting with the loop index L_J
1197
 
1198
         L_J := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
1199
 
1200
         --  Construct "L .. H"
1201
 
1202
         L_Range :=
1203
           Make_Range
1204
             (Loc,
1205
              Low_Bound  => Make_Qualified_Expression
1206
                              (Loc,
1207
                               Subtype_Mark => Index_Base_Name,
1208
                               Expression   => L),
1209
              High_Bound => Make_Qualified_Expression
1210
                              (Loc,
1211
                               Subtype_Mark => Index_Base_Name,
1212
                               Expression => H));
1213
 
1214
         --  Construct "for L_J in Index_Base range L .. H"
1215
 
1216
         L_Iteration_Scheme :=
1217
           Make_Iteration_Scheme
1218
             (Loc,
1219
              Loop_Parameter_Specification =>
1220
                Make_Loop_Parameter_Specification
1221
                  (Loc,
1222
                   Defining_Identifier         => L_J,
1223
                   Discrete_Subtype_Definition => L_Range));
1224
 
1225
         --  Construct the statements to execute in the loop body
1226
 
1227
         L_Body := Gen_Assign (New_Reference_To (L_J, Loc), Expr);
1228
 
1229
         --  Construct the final loop
1230
 
1231
         Append_To (S, Make_Implicit_Loop_Statement
1232
                         (Node             => N,
1233
                          Identifier       => Empty,
1234
                          Iteration_Scheme => L_Iteration_Scheme,
1235
                          Statements       => L_Body));
1236
 
1237
         return S;
1238
      end Gen_Loop;
1239
 
1240
      ---------------
1241
      -- Gen_While --
1242
      ---------------
1243
 
1244
      --  The code built is
1245
 
1246
      --     W_J : Index_Base := L;
1247
      --     while W_J < H loop
1248
      --        W_J := Index_Base'Succ (W);
1249
      --        L_Body;
1250
      --     end loop;
1251
 
1252
      function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
1253
         W_J : Node_Id;
1254
 
1255
         W_Decl : Node_Id;
1256
         --  W_J : Base_Type := L;
1257
 
1258
         W_Iteration_Scheme : Node_Id;
1259
         --  while W_J < H
1260
 
1261
         W_Index_Succ : Node_Id;
1262
         --  Index_Base'Succ (J)
1263
 
1264
         W_Increment : Node_Id;
1265
         --  W_J := Index_Base'Succ (W)
1266
 
1267
         W_Body : constant List_Id := New_List;
1268
         --  The statements to execute in the loop
1269
 
1270
         S : constant List_Id := New_List;
1271
         --  list of statement
1272
 
1273
      begin
1274
         --  If loop bounds define an empty range or are equal return null
1275
 
1276
         if Empty_Range (L, H) or else Equal (L, H) then
1277
            Append_To (S, Make_Null_Statement (Loc));
1278
            return S;
1279
         end if;
1280
 
1281
         --  Build the decl of W_J
1282
 
1283
         W_J    := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
1284
         W_Decl :=
1285
           Make_Object_Declaration
1286
             (Loc,
1287
              Defining_Identifier => W_J,
1288
              Object_Definition   => Index_Base_Name,
1289
              Expression          => L);
1290
 
1291
         --  Theoretically we should do a New_Copy_Tree (L) here, but we know
1292
         --  that in this particular case L is a fresh Expr generated by
1293
         --  Add which we are the only ones to use.
1294
 
1295
         Append_To (S, W_Decl);
1296
 
1297
         --  Construct " while W_J < H"
1298
 
1299
         W_Iteration_Scheme :=
1300
           Make_Iteration_Scheme
1301
             (Loc,
1302
              Condition => Make_Op_Lt
1303
                             (Loc,
1304
                              Left_Opnd  => New_Reference_To (W_J, Loc),
1305
                              Right_Opnd => New_Copy_Tree (H)));
1306
 
1307
         --  Construct the statements to execute in the loop body
1308
 
1309
         W_Index_Succ :=
1310
           Make_Attribute_Reference
1311
             (Loc,
1312
              Prefix         => Index_Base_Name,
1313
              Attribute_Name => Name_Succ,
1314
              Expressions    => New_List (New_Reference_To (W_J, Loc)));
1315
 
1316
         W_Increment  :=
1317
           Make_OK_Assignment_Statement
1318
             (Loc,
1319
              Name       => New_Reference_To (W_J, Loc),
1320
              Expression => W_Index_Succ);
1321
 
1322
         Append_To (W_Body, W_Increment);
1323
         Append_List_To (W_Body,
1324
           Gen_Assign (New_Reference_To (W_J, Loc), Expr));
1325
 
1326
         --  Construct the final loop
1327
 
1328
         Append_To (S, Make_Implicit_Loop_Statement
1329
                         (Node             => N,
1330
                          Identifier       => Empty,
1331
                          Iteration_Scheme => W_Iteration_Scheme,
1332
                          Statements       => W_Body));
1333
 
1334
         return S;
1335
      end Gen_While;
1336
 
1337
      ---------------------
1338
      -- Index_Base_Name --
1339
      ---------------------
1340
 
1341
      function Index_Base_Name return Node_Id is
1342
      begin
1343
         return New_Reference_To (Index_Base, Sloc (N));
1344
      end Index_Base_Name;
1345
 
1346
      ------------------------------------
1347
      -- Local_Compile_Time_Known_Value --
1348
      ------------------------------------
1349
 
1350
      function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean is
1351
      begin
1352
         return Compile_Time_Known_Value (E)
1353
           or else
1354
             (Nkind (E) = N_Attribute_Reference
1355
               and then Attribute_Name (E) = Name_Val
1356
               and then Compile_Time_Known_Value (First (Expressions (E))));
1357
      end Local_Compile_Time_Known_Value;
1358
 
1359
      ----------------------
1360
      -- Local_Expr_Value --
1361
      ----------------------
1362
 
1363
      function Local_Expr_Value (E : Node_Id) return Uint is
1364
      begin
1365
         if Compile_Time_Known_Value (E) then
1366
            return Expr_Value (E);
1367
         else
1368
            return Expr_Value (First (Expressions (E)));
1369
         end if;
1370
      end Local_Expr_Value;
1371
 
1372
      --  Build_Array_Aggr_Code Variables
1373
 
1374
      Assoc  : Node_Id;
1375
      Choice : Node_Id;
1376
      Expr   : Node_Id;
1377
      Typ    : Entity_Id;
1378
 
1379
      Others_Expr         : Node_Id := Empty;
1380
      Others_Mbox_Present : Boolean := False;
1381
 
1382
      Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
1383
      Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
1384
      --  The aggregate bounds of this specific sub-aggregate. Note that if
1385
      --  the code generated by Build_Array_Aggr_Code is executed then these
1386
      --  bounds are OK. Otherwise a Constraint_Error would have been raised.
1387
 
1388
      Aggr_Low  : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_L);
1389
      Aggr_High : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_H);
1390
      --  After Duplicate_Subexpr these are side-effect free
1391
 
1392
      Low        : Node_Id;
1393
      High       : Node_Id;
1394
 
1395
      Nb_Choices : Nat := 0;
1396
      Table      : Case_Table_Type (1 .. Number_Of_Choices (N));
1397
      --  Used to sort all the different choice values
1398
 
1399
      Nb_Elements : Int;
1400
      --  Number of elements in the positional aggregate
1401
 
1402
      New_Code : constant List_Id := New_List;
1403
 
1404
   --  Start of processing for Build_Array_Aggr_Code
1405
 
1406
   begin
1407
      --  First before we start, a special case. if we have a bit packed
1408
      --  array represented as a modular type, then clear the value to
1409
      --  zero first, to ensure that unused bits are properly cleared.
1410
 
1411
      Typ := Etype (N);
1412
 
1413
      if Present (Typ)
1414
        and then Is_Bit_Packed_Array (Typ)
1415
        and then Is_Modular_Integer_Type (Packed_Array_Type (Typ))
1416
      then
1417
         Append_To (New_Code,
1418
           Make_Assignment_Statement (Loc,
1419
             Name => New_Copy_Tree (Into),
1420
             Expression =>
1421
               Unchecked_Convert_To (Typ,
1422
                 Make_Integer_Literal (Loc, Uint_0))));
1423
      end if;
1424
 
1425
      --  We can skip this
1426
      --  STEP 1: Process component associations
1427
      --  For those associations that may generate a loop, initialize
1428
      --  Loop_Actions to collect inserted actions that may be crated.
1429
 
1430
      if No (Expressions (N)) then
1431
 
1432
         --  STEP 1 (a): Sort the discrete choices
1433
 
1434
         Assoc := First (Component_Associations (N));
1435
         while Present (Assoc) loop
1436
            Choice := First (Choices (Assoc));
1437
            while Present (Choice) loop
1438
               if Nkind (Choice) = N_Others_Choice then
1439
                  Set_Loop_Actions (Assoc, New_List);
1440
 
1441
                  if Box_Present (Assoc) then
1442
                     Others_Mbox_Present := True;
1443
                  else
1444
                     Others_Expr := Expression (Assoc);
1445
                  end if;
1446
                  exit;
1447
               end if;
1448
 
1449
               Get_Index_Bounds (Choice, Low, High);
1450
 
1451
               if Low /= High then
1452
                  Set_Loop_Actions (Assoc, New_List);
1453
               end if;
1454
 
1455
               Nb_Choices := Nb_Choices + 1;
1456
               if Box_Present (Assoc) then
1457
                  Table (Nb_Choices) := (Choice_Lo   => Low,
1458
                                         Choice_Hi   => High,
1459
                                         Choice_Node => Empty);
1460
               else
1461
                  Table (Nb_Choices) := (Choice_Lo   => Low,
1462
                                         Choice_Hi   => High,
1463
                                         Choice_Node => Expression (Assoc));
1464
               end if;
1465
               Next (Choice);
1466
            end loop;
1467
 
1468
            Next (Assoc);
1469
         end loop;
1470
 
1471
         --  If there is more than one set of choices these must be static
1472
         --  and we can therefore sort them. Remember that Nb_Choices does not
1473
         --  account for an others choice.
1474
 
1475
         if Nb_Choices > 1 then
1476
            Sort_Case_Table (Table);
1477
         end if;
1478
 
1479
         --  STEP 1 (b):  take care of the whole set of discrete choices
1480
 
1481
         for J in 1 .. Nb_Choices loop
1482
            Low  := Table (J).Choice_Lo;
1483
            High := Table (J).Choice_Hi;
1484
            Expr := Table (J).Choice_Node;
1485
            Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
1486
         end loop;
1487
 
1488
         --  STEP 1 (c): generate the remaining loops to cover others choice
1489
         --  We don't need to generate loops over empty gaps, but if there is
1490
         --  a single empty range we must analyze the expression for semantics
1491
 
1492
         if Present (Others_Expr) or else Others_Mbox_Present then
1493
            declare
1494
               First : Boolean := True;
1495
 
1496
            begin
1497
               for J in 0 .. Nb_Choices loop
1498
                  if J = 0 then
1499
                     Low := Aggr_Low;
1500
                  else
1501
                     Low := Add (1, To => Table (J).Choice_Hi);
1502
                  end if;
1503
 
1504
                  if J = Nb_Choices then
1505
                     High := Aggr_High;
1506
                  else
1507
                     High := Add (-1, To => Table (J + 1).Choice_Lo);
1508
                  end if;
1509
 
1510
                  --  If this is an expansion within an init proc, make
1511
                  --  sure that discriminant references are replaced by
1512
                  --  the corresponding discriminal.
1513
 
1514
                  if Inside_Init_Proc then
1515
                     if Is_Entity_Name (Low)
1516
                       and then Ekind (Entity (Low)) = E_Discriminant
1517
                     then
1518
                        Set_Entity (Low, Discriminal (Entity (Low)));
1519
                     end if;
1520
 
1521
                     if Is_Entity_Name (High)
1522
                       and then Ekind (Entity (High)) = E_Discriminant
1523
                     then
1524
                        Set_Entity (High, Discriminal (Entity (High)));
1525
                     end if;
1526
                  end if;
1527
 
1528
                  if First
1529
                    or else not Empty_Range (Low, High)
1530
                  then
1531
                     First := False;
1532
                     Append_List
1533
                       (Gen_Loop (Low, High, Others_Expr), To => New_Code);
1534
                  end if;
1535
               end loop;
1536
            end;
1537
         end if;
1538
 
1539
      --  STEP 2: Process positional components
1540
 
1541
      else
1542
         --  STEP 2 (a): Generate the assignments for each positional element
1543
         --  Note that here we have to use Aggr_L rather than Aggr_Low because
1544
         --  Aggr_L is analyzed and Add wants an analyzed expression.
1545
 
1546
         Expr        := First (Expressions (N));
1547
         Nb_Elements := -1;
1548
 
1549
         while Present (Expr) loop
1550
            Nb_Elements := Nb_Elements + 1;
1551
            Append_List (Gen_Assign (Add (Nb_Elements, To => Aggr_L), Expr),
1552
                         To => New_Code);
1553
            Next (Expr);
1554
         end loop;
1555
 
1556
         --  STEP 2 (b): Generate final loop if an others choice is present
1557
         --  Here Nb_Elements gives the offset of the last positional element.
1558
 
1559
         if Present (Component_Associations (N)) then
1560
            Assoc := Last (Component_Associations (N));
1561
 
1562
            --  Ada 2005 (AI-287)
1563
 
1564
            if Box_Present (Assoc) then
1565
               Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
1566
                                       Aggr_High,
1567
                                       Empty),
1568
                            To => New_Code);
1569
            else
1570
               Expr  := Expression (Assoc);
1571
 
1572
               Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
1573
                                       Aggr_High,
1574
                                       Expr), --  AI-287
1575
                            To => New_Code);
1576
            end if;
1577
         end if;
1578
      end if;
1579
 
1580
      return New_Code;
1581
   end Build_Array_Aggr_Code;
1582
 
1583
   ----------------------------
1584
   -- Build_Record_Aggr_Code --
1585
   ----------------------------
1586
 
1587
   function Build_Record_Aggr_Code
1588
     (N                             : Node_Id;
1589
      Typ                           : Entity_Id;
1590
      Target                        : Node_Id;
1591
      Flist                         : Node_Id   := Empty;
1592
      Obj                           : Entity_Id := Empty;
1593
      Is_Limited_Ancestor_Expansion : Boolean   := False) return List_Id
1594
   is
1595
      Loc     : constant Source_Ptr := Sloc (N);
1596
      L       : constant List_Id    := New_List;
1597
      N_Typ   : constant Entity_Id  := Etype (N);
1598
 
1599
      Comp      : Node_Id;
1600
      Instr     : Node_Id;
1601
      Ref       : Node_Id;
1602
      F         : Node_Id;
1603
      Comp_Type : Entity_Id;
1604
      Selector  : Entity_Id;
1605
      Comp_Expr : Node_Id;
1606
      Expr_Q    : Node_Id;
1607
 
1608
      Internal_Final_List : Node_Id;
1609
 
1610
      --  If this is an internal aggregate, the External_Final_List is an
1611
      --  expression for the controller record of the enclosing type.
1612
      --  If the current aggregate has several controlled components, this
1613
      --  expression will appear in several calls to attach to the finali-
1614
      --  zation list, and it must not be shared.
1615
 
1616
      External_Final_List      : Node_Id;
1617
      Ancestor_Is_Expression   : Boolean := False;
1618
      Ancestor_Is_Subtype_Mark : Boolean := False;
1619
 
1620
      Init_Typ : Entity_Id := Empty;
1621
      Attach   : Node_Id;
1622
      Ctrl_Stuff_Done : Boolean := False;
1623
 
1624
      function Get_Constraint_Association (T : Entity_Id) return Node_Id;
1625
      --  Returns the first discriminant association in the constraint
1626
      --  associated with T, if any, otherwise returns Empty.
1627
 
1628
      function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id;
1629
      --  Returns the value that the given discriminant of an ancestor
1630
      --  type should receive (in the absence of a conflict with the
1631
      --  value provided by an ancestor part of an extension aggregate).
1632
 
1633
      procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id);
1634
      --  Check that each of the discriminant values defined by the
1635
      --  ancestor part of an extension aggregate match the corresponding
1636
      --  values provided by either an association of the aggregate or
1637
      --  by the constraint imposed by a parent type (RM95-4.3.2(8)).
1638
 
1639
      function Init_Controller
1640
        (Target  : Node_Id;
1641
         Typ     : Entity_Id;
1642
         F       : Node_Id;
1643
         Attach  : Node_Id;
1644
         Init_Pr : Boolean) return List_Id;
1645
      --  returns the list of statements necessary to initialize the internal
1646
      --  controller of the (possible) ancestor typ into target and attach
1647
      --  it to finalization list F. Init_Pr conditions the call to the
1648
      --  init proc since it may already be done due to ancestor initialization
1649
 
1650
      procedure Gen_Ctrl_Actions_For_Aggr;
1651
      --  Deal with the various controlled type data structure
1652
      --  initializations
1653
 
1654
      ---------------------------------
1655
      -- Ancestor_Discriminant_Value --
1656
      ---------------------------------
1657
 
1658
      function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id is
1659
         Assoc        : Node_Id;
1660
         Assoc_Elmt   : Elmt_Id;
1661
         Aggr_Comp    : Entity_Id;
1662
         Corresp_Disc : Entity_Id;
1663
         Current_Typ  : Entity_Id := Base_Type (Typ);
1664
         Parent_Typ   : Entity_Id;
1665
         Parent_Disc  : Entity_Id;
1666
         Save_Assoc   : Node_Id := Empty;
1667
 
1668
      begin
1669
         --  First check any discriminant associations to see if
1670
         --  any of them provide a value for the discriminant.
1671
 
1672
         if Present (Discriminant_Specifications (Parent (Current_Typ))) then
1673
            Assoc := First (Component_Associations (N));
1674
            while Present (Assoc) loop
1675
               Aggr_Comp := Entity (First (Choices (Assoc)));
1676
 
1677
               if Ekind (Aggr_Comp) = E_Discriminant then
1678
                  Save_Assoc := Expression (Assoc);
1679
 
1680
                  Corresp_Disc := Corresponding_Discriminant (Aggr_Comp);
1681
                  while Present (Corresp_Disc) loop
1682
                     --  If found a corresponding discriminant then return
1683
                     --  the value given in the aggregate. (Note: this is
1684
                     --  not correct in the presence of side effects. ???)
1685
 
1686
                     if Disc = Corresp_Disc then
1687
                        return Duplicate_Subexpr (Expression (Assoc));
1688
                     end if;
1689
 
1690
                     Corresp_Disc :=
1691
                       Corresponding_Discriminant (Corresp_Disc);
1692
                  end loop;
1693
               end if;
1694
 
1695
               Next (Assoc);
1696
            end loop;
1697
         end if;
1698
 
1699
         --  No match found in aggregate, so chain up parent types to find
1700
         --  a constraint that defines the value of the discriminant.
1701
 
1702
         Parent_Typ := Etype (Current_Typ);
1703
         while Current_Typ /= Parent_Typ loop
1704
            if Has_Discriminants (Parent_Typ) then
1705
               Parent_Disc := First_Discriminant (Parent_Typ);
1706
 
1707
               --  We either get the association from the subtype indication
1708
               --  of the type definition itself, or from the discriminant
1709
               --  constraint associated with the type entity (which is
1710
               --  preferable, but it's not always present ???)
1711
 
1712
               if Is_Empty_Elmt_List (
1713
                 Discriminant_Constraint (Current_Typ))
1714
               then
1715
                  Assoc := Get_Constraint_Association (Current_Typ);
1716
                  Assoc_Elmt := No_Elmt;
1717
               else
1718
                  Assoc_Elmt :=
1719
                    First_Elmt (Discriminant_Constraint (Current_Typ));
1720
                  Assoc := Node (Assoc_Elmt);
1721
               end if;
1722
 
1723
               --  Traverse the discriminants of the parent type looking
1724
               --  for one that corresponds.
1725
 
1726
               while Present (Parent_Disc) and then Present (Assoc) loop
1727
                  Corresp_Disc := Parent_Disc;
1728
                  while Present (Corresp_Disc)
1729
                    and then Disc /= Corresp_Disc
1730
                  loop
1731
                     Corresp_Disc :=
1732
                       Corresponding_Discriminant (Corresp_Disc);
1733
                  end loop;
1734
 
1735
                  if Disc = Corresp_Disc then
1736
                     if Nkind (Assoc) = N_Discriminant_Association then
1737
                        Assoc := Expression (Assoc);
1738
                     end if;
1739
 
1740
                     --  If the located association directly denotes
1741
                     --  a discriminant, then use the value of a saved
1742
                     --  association of the aggregate. This is a kludge
1743
                     --  to handle certain cases involving multiple
1744
                     --  discriminants mapped to a single discriminant
1745
                     --  of a descendant. It's not clear how to locate the
1746
                     --  appropriate discriminant value for such cases. ???
1747
 
1748
                     if Is_Entity_Name (Assoc)
1749
                       and then Ekind (Entity (Assoc)) = E_Discriminant
1750
                     then
1751
                        Assoc := Save_Assoc;
1752
                     end if;
1753
 
1754
                     return Duplicate_Subexpr (Assoc);
1755
                  end if;
1756
 
1757
                  Next_Discriminant (Parent_Disc);
1758
 
1759
                  if No (Assoc_Elmt) then
1760
                     Next (Assoc);
1761
                  else
1762
                     Next_Elmt (Assoc_Elmt);
1763
                     if Present (Assoc_Elmt) then
1764
                        Assoc := Node (Assoc_Elmt);
1765
                     else
1766
                        Assoc := Empty;
1767
                     end if;
1768
                  end if;
1769
               end loop;
1770
            end if;
1771
 
1772
            Current_Typ := Parent_Typ;
1773
            Parent_Typ := Etype (Current_Typ);
1774
         end loop;
1775
 
1776
         --  In some cases there's no ancestor value to locate (such as
1777
         --  when an ancestor part given by an expression defines the
1778
         --  discriminant value).
1779
 
1780
         return Empty;
1781
      end Ancestor_Discriminant_Value;
1782
 
1783
      ----------------------------------
1784
      -- Check_Ancestor_Discriminants --
1785
      ----------------------------------
1786
 
1787
      procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id) is
1788
         Discr      : Entity_Id := First_Discriminant (Base_Type (Anc_Typ));
1789
         Disc_Value : Node_Id;
1790
         Cond       : Node_Id;
1791
 
1792
      begin
1793
         while Present (Discr) loop
1794
            Disc_Value := Ancestor_Discriminant_Value (Discr);
1795
 
1796
            if Present (Disc_Value) then
1797
               Cond := Make_Op_Ne (Loc,
1798
                 Left_Opnd =>
1799
                   Make_Selected_Component (Loc,
1800
                     Prefix        => New_Copy_Tree (Target),
1801
                     Selector_Name => New_Occurrence_Of (Discr, Loc)),
1802
                 Right_Opnd => Disc_Value);
1803
 
1804
               Append_To (L,
1805
                 Make_Raise_Constraint_Error (Loc,
1806
                   Condition => Cond,
1807
                   Reason    => CE_Discriminant_Check_Failed));
1808
            end if;
1809
 
1810
            Next_Discriminant (Discr);
1811
         end loop;
1812
      end Check_Ancestor_Discriminants;
1813
 
1814
      --------------------------------
1815
      -- Get_Constraint_Association --
1816
      --------------------------------
1817
 
1818
      function Get_Constraint_Association (T : Entity_Id) return Node_Id is
1819
         Typ_Def : constant Node_Id := Type_Definition (Parent (T));
1820
         Indic   : constant Node_Id := Subtype_Indication (Typ_Def);
1821
 
1822
      begin
1823
         --  ??? Also need to cover case of a type mark denoting a subtype
1824
         --  with constraint.
1825
 
1826
         if Nkind (Indic) = N_Subtype_Indication
1827
           and then Present (Constraint (Indic))
1828
         then
1829
            return First (Constraints (Constraint (Indic)));
1830
         end if;
1831
 
1832
         return Empty;
1833
      end Get_Constraint_Association;
1834
 
1835
      ---------------------
1836
      -- Init_controller --
1837
      ---------------------
1838
 
1839
      function Init_Controller
1840
        (Target  : Node_Id;
1841
         Typ     : Entity_Id;
1842
         F       : Node_Id;
1843
         Attach  : Node_Id;
1844
         Init_Pr : Boolean) return List_Id
1845
      is
1846
         L   : constant List_Id := New_List;
1847
         Ref : Node_Id;
1848
         RC  : RE_Id;
1849
 
1850
      begin
1851
         --  Generate:
1852
         --     init-proc (target._controller);
1853
         --     initialize (target._controller);
1854
         --     Attach_to_Final_List (target._controller, F);
1855
 
1856
         Ref :=
1857
           Make_Selected_Component (Loc,
1858
             Prefix        => Convert_To (Typ, New_Copy_Tree (Target)),
1859
             Selector_Name => Make_Identifier (Loc, Name_uController));
1860
         Set_Assignment_OK (Ref);
1861
 
1862
         --  Ada 2005 (AI-287): Give support to default initialization of
1863
         --  limited types and components.
1864
 
1865
         if (Nkind (Target) = N_Identifier
1866
              and then Present (Etype (Target))
1867
              and then Is_Limited_Type (Etype (Target)))
1868
           or else
1869
            (Nkind (Target) = N_Selected_Component
1870
              and then Present (Etype (Selector_Name (Target)))
1871
              and then Is_Limited_Type (Etype (Selector_Name (Target))))
1872
           or else
1873
            (Nkind (Target) = N_Unchecked_Type_Conversion
1874
              and then Present (Etype (Target))
1875
              and then Is_Limited_Type (Etype (Target)))
1876
           or else
1877
            (Nkind (Target) = N_Unchecked_Expression
1878
              and then Nkind (Expression (Target)) = N_Indexed_Component
1879
              and then Present (Etype (Prefix (Expression (Target))))
1880
              and then Is_Limited_Type (Etype (Prefix (Expression (Target)))))
1881
         then
1882
            RC := RE_Limited_Record_Controller;
1883
         else
1884
            RC := RE_Record_Controller;
1885
         end if;
1886
 
1887
         if Init_Pr then
1888
            Append_List_To (L,
1889
              Build_Initialization_Call (Loc,
1890
                Id_Ref       => Ref,
1891
                Typ          => RTE (RC),
1892
                In_Init_Proc => Within_Init_Proc));
1893
         end if;
1894
 
1895
         Append_To (L,
1896
           Make_Procedure_Call_Statement (Loc,
1897
             Name =>
1898
               New_Reference_To (
1899
                 Find_Prim_Op (RTE (RC), Name_Initialize), Loc),
1900
             Parameter_Associations =>
1901
               New_List (New_Copy_Tree (Ref))));
1902
 
1903
         Append_To (L,
1904
           Make_Attach_Call (
1905
             Obj_Ref     => New_Copy_Tree (Ref),
1906
             Flist_Ref   => F,
1907
             With_Attach => Attach));
1908
 
1909
         return L;
1910
      end Init_Controller;
1911
 
1912
      -------------------------------
1913
      -- Gen_Ctrl_Actions_For_Aggr --
1914
      -------------------------------
1915
 
1916
      procedure Gen_Ctrl_Actions_For_Aggr is
1917
      begin
1918
         if Present (Obj)
1919
          and then Finalize_Storage_Only (Typ)
1920
          and then (Is_Library_Level_Entity (Obj)
1921
            or else Entity (Constant_Value (RTE (RE_Garbage_Collected))) =
1922
                                                              Standard_True)
1923
         then
1924
            Attach := Make_Integer_Literal (Loc, 0);
1925
 
1926
         elsif Nkind (Parent (N)) = N_Qualified_Expression
1927
           and then Nkind (Parent (Parent (N))) = N_Allocator
1928
         then
1929
            Attach := Make_Integer_Literal (Loc, 2);
1930
 
1931
         else
1932
            Attach := Make_Integer_Literal (Loc, 1);
1933
         end if;
1934
 
1935
         --  Determine the external finalization list. It is either the
1936
         --  finalization list of the outer-scope or the one coming from
1937
         --  an outer aggregate.  When the target is not a temporary, the
1938
         --  proper scope is the scope of the target rather than the
1939
         --  potentially transient current scope.
1940
 
1941
         if Controlled_Type (Typ) then
1942
            if Present (Flist) then
1943
               External_Final_List := New_Copy_Tree (Flist);
1944
 
1945
            elsif Is_Entity_Name (Target)
1946
              and then Present (Scope (Entity (Target)))
1947
            then
1948
               External_Final_List
1949
                 := Find_Final_List (Scope (Entity (Target)));
1950
 
1951
            else
1952
               External_Final_List := Find_Final_List (Current_Scope);
1953
            end if;
1954
 
1955
         else
1956
            External_Final_List := Empty;
1957
         end if;
1958
 
1959
         --  Initialize and attach the outer object in the is_controlled case
1960
 
1961
         if Is_Controlled (Typ) then
1962
            if Ancestor_Is_Subtype_Mark then
1963
               Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
1964
               Set_Assignment_OK (Ref);
1965
               Append_To (L,
1966
                 Make_Procedure_Call_Statement (Loc,
1967
                   Name =>
1968
                     New_Reference_To
1969
                       (Find_Prim_Op (Init_Typ, Name_Initialize), Loc),
1970
                   Parameter_Associations => New_List (New_Copy_Tree (Ref))));
1971
            end if;
1972
 
1973
            if not Has_Controlled_Component (Typ) then
1974
               Ref := New_Copy_Tree (Target);
1975
               Set_Assignment_OK (Ref);
1976
               Append_To (L,
1977
                 Make_Attach_Call (
1978
                   Obj_Ref     => Ref,
1979
                   Flist_Ref   => New_Copy_Tree (External_Final_List),
1980
                   With_Attach => Attach));
1981
            end if;
1982
         end if;
1983
 
1984
         --  In the Has_Controlled component case, all the intermediate
1985
         --  controllers must be initialized
1986
 
1987
         if Has_Controlled_Component (Typ)
1988
           and not Is_Limited_Ancestor_Expansion
1989
         then
1990
            declare
1991
               Inner_Typ : Entity_Id;
1992
               Outer_Typ : Entity_Id;
1993
               At_Root   : Boolean;
1994
 
1995
            begin
1996
 
1997
               Outer_Typ := Base_Type (Typ);
1998
 
1999
               --  Find outer type with a controller
2000
 
2001
               while Outer_Typ /= Init_Typ
2002
                 and then not Has_New_Controlled_Component (Outer_Typ)
2003
               loop
2004
                  Outer_Typ := Etype (Outer_Typ);
2005
               end loop;
2006
 
2007
               --  Attach it to the outer record controller to the
2008
               --  external final list
2009
 
2010
               if Outer_Typ = Init_Typ then
2011
                  Append_List_To (L,
2012
                    Init_Controller (
2013
                      Target  => Target,
2014
                      Typ     => Outer_Typ,
2015
                      F       => External_Final_List,
2016
                      Attach  => Attach,
2017
                      Init_Pr => False));
2018
 
2019
                  At_Root   := True;
2020
                  Inner_Typ := Init_Typ;
2021
 
2022
               else
2023
                  Append_List_To (L,
2024
                    Init_Controller (
2025
                      Target  => Target,
2026
                      Typ     => Outer_Typ,
2027
                      F       => External_Final_List,
2028
                      Attach  => Attach,
2029
                      Init_Pr => True));
2030
 
2031
                  Inner_Typ := Etype (Outer_Typ);
2032
                  At_Root   :=
2033
                    not Is_Tagged_Type (Typ) or else Inner_Typ = Outer_Typ;
2034
               end if;
2035
 
2036
               --  The outer object has to be attached as well
2037
 
2038
               if Is_Controlled (Typ) then
2039
                  Ref := New_Copy_Tree (Target);
2040
                  Set_Assignment_OK (Ref);
2041
                  Append_To (L,
2042
                    Make_Attach_Call (
2043
                      Obj_Ref     => Ref,
2044
                      Flist_Ref   => New_Copy_Tree (External_Final_List),
2045
                      With_Attach => New_Copy_Tree (Attach)));
2046
               end if;
2047
 
2048
               --  Initialize the internal controllers for tagged types with
2049
               --  more than one controller.
2050
 
2051
               while not At_Root and then Inner_Typ /= Init_Typ loop
2052
                  if Has_New_Controlled_Component (Inner_Typ) then
2053
                     F :=
2054
                       Make_Selected_Component (Loc,
2055
                         Prefix =>
2056
                           Convert_To (Outer_Typ, New_Copy_Tree (Target)),
2057
                         Selector_Name =>
2058
                           Make_Identifier (Loc, Name_uController));
2059
                     F :=
2060
                       Make_Selected_Component (Loc,
2061
                         Prefix => F,
2062
                         Selector_Name => Make_Identifier (Loc, Name_F));
2063
 
2064
                     Append_List_To (L,
2065
                       Init_Controller (
2066
                         Target  => Target,
2067
                         Typ     => Inner_Typ,
2068
                         F       => F,
2069
                         Attach  => Make_Integer_Literal (Loc, 1),
2070
                         Init_Pr => True));
2071
                     Outer_Typ := Inner_Typ;
2072
                  end if;
2073
 
2074
                  --  Stop at the root
2075
 
2076
                  At_Root := Inner_Typ = Etype (Inner_Typ);
2077
                  Inner_Typ := Etype (Inner_Typ);
2078
               end loop;
2079
 
2080
               --  If not done yet attach the controller of the ancestor part
2081
 
2082
               if Outer_Typ /= Init_Typ
2083
                 and then Inner_Typ = Init_Typ
2084
                 and then Has_Controlled_Component (Init_Typ)
2085
               then
2086
                  F :=
2087
                    Make_Selected_Component (Loc,
2088
                      Prefix => Convert_To (Outer_Typ, New_Copy_Tree (Target)),
2089
                      Selector_Name =>
2090
                        Make_Identifier (Loc, Name_uController));
2091
                  F :=
2092
                    Make_Selected_Component (Loc,
2093
                      Prefix => F,
2094
                      Selector_Name => Make_Identifier (Loc, Name_F));
2095
 
2096
                  Attach := Make_Integer_Literal (Loc, 1);
2097
                  Append_List_To (L,
2098
                    Init_Controller (
2099
                      Target  => Target,
2100
                      Typ     => Init_Typ,
2101
                      F       => F,
2102
                      Attach  => Attach,
2103
                      Init_Pr => Ancestor_Is_Expression));
2104
               end if;
2105
            end;
2106
         end if;
2107
      end Gen_Ctrl_Actions_For_Aggr;
2108
 
2109
   --  Start of processing for Build_Record_Aggr_Code
2110
 
2111
   begin
2112
      --  Deal with the ancestor part of extension aggregates
2113
      --  or with the discriminants of the root type
2114
 
2115
      if Nkind (N) = N_Extension_Aggregate then
2116
         declare
2117
            A : constant Node_Id := Ancestor_Part (N);
2118
            Assign : List_Id;
2119
 
2120
         begin
2121
            --  If the ancestor part is a subtype mark "T", we generate
2122
 
2123
            --     init-proc (T(tmp));  if T is constrained and
2124
            --     init-proc (S(tmp));  where S applies an appropriate
2125
            --                           constraint if T is unconstrained
2126
 
2127
            if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
2128
               Ancestor_Is_Subtype_Mark := True;
2129
 
2130
               if Is_Constrained (Entity (A)) then
2131
                  Init_Typ := Entity (A);
2132
 
2133
               --  For an ancestor part given by an unconstrained type
2134
               --  mark, create a subtype constrained by appropriate
2135
               --  corresponding discriminant values coming from either
2136
               --  associations of the aggregate or a constraint on
2137
               --  a parent type. The subtype will be used to generate
2138
               --  the correct default value for the ancestor part.
2139
 
2140
               elsif Has_Discriminants (Entity (A)) then
2141
                  declare
2142
                     Anc_Typ    : constant Entity_Id := Entity (A);
2143
                     Anc_Constr : constant List_Id   := New_List;
2144
                     Discrim    : Entity_Id;
2145
                     Disc_Value : Node_Id;
2146
                     New_Indic  : Node_Id;
2147
                     Subt_Decl  : Node_Id;
2148
 
2149
                  begin
2150
                     Discrim := First_Discriminant (Anc_Typ);
2151
                     while Present (Discrim) loop
2152
                        Disc_Value := Ancestor_Discriminant_Value (Discrim);
2153
                        Append_To (Anc_Constr, Disc_Value);
2154
                        Next_Discriminant (Discrim);
2155
                     end loop;
2156
 
2157
                     New_Indic :=
2158
                       Make_Subtype_Indication (Loc,
2159
                         Subtype_Mark => New_Occurrence_Of (Anc_Typ, Loc),
2160
                         Constraint   =>
2161
                           Make_Index_Or_Discriminant_Constraint (Loc,
2162
                             Constraints => Anc_Constr));
2163
 
2164
                     Init_Typ := Create_Itype (Ekind (Anc_Typ), N);
2165
 
2166
                     Subt_Decl :=
2167
                       Make_Subtype_Declaration (Loc,
2168
                         Defining_Identifier => Init_Typ,
2169
                         Subtype_Indication  => New_Indic);
2170
 
2171
                     --  Itypes must be analyzed with checks off
2172
                     --  Declaration must have a parent for proper
2173
                     --  handling of subsidiary actions.
2174
 
2175
                     Set_Parent (Subt_Decl, N);
2176
                     Analyze (Subt_Decl, Suppress => All_Checks);
2177
                  end;
2178
               end if;
2179
 
2180
               Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
2181
               Set_Assignment_OK (Ref);
2182
 
2183
               if Has_Default_Init_Comps (N)
2184
                 or else Has_Task (Base_Type (Init_Typ))
2185
               then
2186
                  Append_List_To (L,
2187
                    Build_Initialization_Call (Loc,
2188
                      Id_Ref       => Ref,
2189
                      Typ          => Init_Typ,
2190
                      In_Init_Proc => Within_Init_Proc,
2191
                      With_Default_Init => True));
2192
               else
2193
                  Append_List_To (L,
2194
                    Build_Initialization_Call (Loc,
2195
                      Id_Ref       => Ref,
2196
                      Typ          => Init_Typ,
2197
                      In_Init_Proc => Within_Init_Proc));
2198
               end if;
2199
 
2200
               if Is_Constrained (Entity (A))
2201
                 and then Has_Discriminants (Entity (A))
2202
               then
2203
                  Check_Ancestor_Discriminants (Entity (A));
2204
               end if;
2205
 
2206
            --  Ada 2005 (AI-287): If the ancestor part is a limited type,
2207
            --  a recursive call expands the ancestor.
2208
 
2209
            elsif Is_Limited_Type (Etype (A)) then
2210
               Ancestor_Is_Expression := True;
2211
 
2212
               Append_List_To (L,
2213
                  Build_Record_Aggr_Code (
2214
                    N                             => Expression (A),
2215
                    Typ                           => Etype (Expression (A)),
2216
                    Target                        => Target,
2217
                    Flist                         => Flist,
2218
                    Obj                           => Obj,
2219
                    Is_Limited_Ancestor_Expansion => True));
2220
 
2221
            --  If the ancestor part is an expression "E", we generate
2222
            --     T(tmp) := E;
2223
 
2224
            else
2225
               Ancestor_Is_Expression := True;
2226
               Init_Typ := Etype (A);
2227
 
2228
               --  If the ancestor part is an aggregate, force its full
2229
               --  expansion, which was delayed.
2230
 
2231
               if Nkind (A) = N_Qualified_Expression
2232
                 and then (Nkind (Expression (A)) = N_Aggregate
2233
                             or else
2234
                           Nkind (Expression (A)) = N_Extension_Aggregate)
2235
               then
2236
                  Set_Analyzed (A, False);
2237
                  Set_Analyzed (Expression (A), False);
2238
               end if;
2239
 
2240
               Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
2241
               Set_Assignment_OK (Ref);
2242
 
2243
               --  Make the assignment without usual controlled actions since
2244
               --  we only want the post adjust but not the pre finalize here
2245
               --  Add manual adjust when necessary
2246
 
2247
               Assign := New_List (
2248
                 Make_OK_Assignment_Statement (Loc,
2249
                   Name       => Ref,
2250
                   Expression => A));
2251
               Set_No_Ctrl_Actions (First (Assign));
2252
 
2253
               --  Assign the tag now to make sure that the dispatching call in
2254
               --  the subsequent deep_adjust works properly (unless Java_VM,
2255
               --  where tags are implicit).
2256
 
2257
               if not Java_VM then
2258
                  Instr :=
2259
                    Make_OK_Assignment_Statement (Loc,
2260
                      Name =>
2261
                        Make_Selected_Component (Loc,
2262
                          Prefix => New_Copy_Tree (Target),
2263
                          Selector_Name =>
2264
                            New_Reference_To
2265
                              (First_Tag_Component (Base_Type (Typ)), Loc)),
2266
 
2267
                      Expression =>
2268
                        Unchecked_Convert_To (RTE (RE_Tag),
2269
                          New_Reference_To
2270
                            (Node (First_Elmt
2271
                               (Access_Disp_Table (Base_Type (Typ)))),
2272
                             Loc)));
2273
 
2274
                  Set_Assignment_OK (Name (Instr));
2275
                  Append_To (Assign, Instr);
2276
               end if;
2277
 
2278
               --  Call Adjust manually
2279
 
2280
               if Controlled_Type (Etype (A)) then
2281
                  Append_List_To (Assign,
2282
                    Make_Adjust_Call (
2283
                      Ref         => New_Copy_Tree (Ref),
2284
                      Typ         => Etype (A),
2285
                      Flist_Ref   => New_Reference_To (
2286
                        RTE (RE_Global_Final_List), Loc),
2287
                      With_Attach => Make_Integer_Literal (Loc, 0)));
2288
               end if;
2289
 
2290
               Append_To (L,
2291
                 Make_Unsuppress_Block (Loc, Name_Discriminant_Check, Assign));
2292
 
2293
               if Has_Discriminants (Init_Typ) then
2294
                  Check_Ancestor_Discriminants (Init_Typ);
2295
               end if;
2296
            end if;
2297
         end;
2298
 
2299
      --  Normal case (not an extension aggregate)
2300
 
2301
      else
2302
         --  Generate the discriminant expressions, component by component.
2303
         --  If the base type is an unchecked union, the discriminants are
2304
         --  unknown to the back-end and absent from a value of the type, so
2305
         --  assignments for them are not emitted.
2306
 
2307
         if Has_Discriminants (Typ)
2308
           and then not Is_Unchecked_Union (Base_Type (Typ))
2309
         then
2310
            --  ??? The discriminants of the object not inherited in the type
2311
            --  of the object should be initialized here
2312
 
2313
            null;
2314
 
2315
            --  Generate discriminant init values
2316
 
2317
            declare
2318
               Discriminant : Entity_Id;
2319
               Discriminant_Value : Node_Id;
2320
 
2321
            begin
2322
               Discriminant := First_Stored_Discriminant (Typ);
2323
 
2324
               while Present (Discriminant) loop
2325
 
2326
                  Comp_Expr :=
2327
                    Make_Selected_Component (Loc,
2328
                      Prefix        => New_Copy_Tree (Target),
2329
                      Selector_Name => New_Occurrence_Of (Discriminant, Loc));
2330
 
2331
                  Discriminant_Value :=
2332
                    Get_Discriminant_Value (
2333
                      Discriminant,
2334
                      N_Typ,
2335
                      Discriminant_Constraint (N_Typ));
2336
 
2337
                  Instr :=
2338
                    Make_OK_Assignment_Statement (Loc,
2339
                      Name       => Comp_Expr,
2340
                      Expression => New_Copy_Tree (Discriminant_Value));
2341
 
2342
                  Set_No_Ctrl_Actions (Instr);
2343
                  Append_To (L, Instr);
2344
 
2345
                  Next_Stored_Discriminant (Discriminant);
2346
               end loop;
2347
            end;
2348
         end if;
2349
      end if;
2350
 
2351
      --  Generate the assignments, component by component
2352
 
2353
      --    tmp.comp1 := Expr1_From_Aggr;
2354
      --    tmp.comp2 := Expr2_From_Aggr;
2355
      --    ....
2356
 
2357
      Comp := First (Component_Associations (N));
2358
      while Present (Comp) loop
2359
         Selector := Entity (First (Choices (Comp)));
2360
 
2361
         --  Ada 2005 (AI-287): Default initialization of a limited component
2362
 
2363
         if Box_Present (Comp)
2364
            and then Is_Limited_Type (Etype (Selector))
2365
         then
2366
            --  Ada 2005 (AI-287): If the component type has tasks then
2367
            --  generate the activation chain and master entities (except
2368
            --  in case of an allocator because in that case these entities
2369
            --  are generated by Build_Task_Allocate_Block_With_Init_Stmts).
2370
 
2371
            declare
2372
               Ctype            : constant Entity_Id := Etype (Selector);
2373
               Inside_Allocator : Boolean   := False;
2374
               P                : Node_Id   := Parent (N);
2375
 
2376
            begin
2377
               if Is_Task_Type (Ctype) or else Has_Task (Ctype) then
2378
                  while Present (P) loop
2379
                     if Nkind (P) = N_Allocator then
2380
                        Inside_Allocator := True;
2381
                        exit;
2382
                     end if;
2383
 
2384
                     P := Parent (P);
2385
                  end loop;
2386
 
2387
                  if not Inside_Init_Proc and not Inside_Allocator then
2388
                     Build_Activation_Chain_Entity (N);
2389
                  end if;
2390
               end if;
2391
            end;
2392
 
2393
            Append_List_To (L,
2394
              Build_Initialization_Call (Loc,
2395
                Id_Ref => Make_Selected_Component (Loc,
2396
                            Prefix => New_Copy_Tree (Target),
2397
                            Selector_Name => New_Occurrence_Of (Selector,
2398
                                                                   Loc)),
2399
                Typ    => Etype (Selector),
2400
                With_Default_Init => True));
2401
 
2402
            goto Next_Comp;
2403
         end if;
2404
 
2405
         --  Prepare for component assignment
2406
 
2407
         if Ekind (Selector) /= E_Discriminant
2408
           or else Nkind (N) = N_Extension_Aggregate
2409
         then
2410
 
2411
            --  All the discriminants have now been assigned
2412
            --  This is now a good moment to initialize and attach all the
2413
            --  controllers. Their position may depend on the discriminants.
2414
 
2415
            if Ekind (Selector) /= E_Discriminant
2416
              and then not Ctrl_Stuff_Done
2417
            then
2418
               Gen_Ctrl_Actions_For_Aggr;
2419
               Ctrl_Stuff_Done := True;
2420
            end if;
2421
 
2422
            Comp_Type := Etype (Selector);
2423
            Comp_Expr :=
2424
              Make_Selected_Component (Loc,
2425
                Prefix        => New_Copy_Tree (Target),
2426
                Selector_Name => New_Occurrence_Of (Selector, Loc));
2427
 
2428
            if Nkind (Expression (Comp)) = N_Qualified_Expression then
2429
               Expr_Q := Expression (Expression (Comp));
2430
            else
2431
               Expr_Q := Expression (Comp);
2432
            end if;
2433
 
2434
            --  The controller is the one of the parent type defining
2435
            --  the component (in case of inherited components).
2436
 
2437
            if Controlled_Type (Comp_Type) then
2438
               Internal_Final_List :=
2439
                 Make_Selected_Component (Loc,
2440
                   Prefix => Convert_To (
2441
                     Scope (Original_Record_Component (Selector)),
2442
                     New_Copy_Tree (Target)),
2443
                   Selector_Name =>
2444
                     Make_Identifier (Loc, Name_uController));
2445
 
2446
               Internal_Final_List :=
2447
                 Make_Selected_Component (Loc,
2448
                   Prefix => Internal_Final_List,
2449
                   Selector_Name => Make_Identifier (Loc, Name_F));
2450
 
2451
               --  The internal final list can be part of a constant object
2452
 
2453
               Set_Assignment_OK (Internal_Final_List);
2454
 
2455
            else
2456
               Internal_Final_List := Empty;
2457
            end if;
2458
 
2459
            --  Now either create the assignment or generate the code for the
2460
            --  inner aggregate top-down.
2461
 
2462
            if Is_Delayed_Aggregate (Expr_Q) then
2463
               Append_List_To (L,
2464
                 Late_Expansion (Expr_Q, Comp_Type, Comp_Expr,
2465
                   Internal_Final_List));
2466
 
2467
            else
2468
               Instr :=
2469
                 Make_OK_Assignment_Statement (Loc,
2470
                   Name       => Comp_Expr,
2471
                   Expression => Expression (Comp));
2472
 
2473
               Set_No_Ctrl_Actions (Instr);
2474
               Append_To (L, Instr);
2475
 
2476
               --  Adjust the tag if tagged (because of possible view
2477
               --  conversions), unless compiling for the Java VM
2478
               --  where tags are implicit.
2479
 
2480
               --    tmp.comp._tag := comp_typ'tag;
2481
 
2482
               if Is_Tagged_Type (Comp_Type) and then not Java_VM then
2483
                  Instr :=
2484
                    Make_OK_Assignment_Statement (Loc,
2485
                      Name =>
2486
                        Make_Selected_Component (Loc,
2487
                          Prefix =>  New_Copy_Tree (Comp_Expr),
2488
                          Selector_Name =>
2489
                            New_Reference_To
2490
                              (First_Tag_Component (Comp_Type), Loc)),
2491
 
2492
                      Expression =>
2493
                        Unchecked_Convert_To (RTE (RE_Tag),
2494
                          New_Reference_To
2495
                            (Node (First_Elmt (Access_Disp_Table (Comp_Type))),
2496
                             Loc)));
2497
 
2498
                  Append_To (L, Instr);
2499
               end if;
2500
 
2501
               --  Adjust and Attach the component to the proper controller
2502
               --     Adjust (tmp.comp);
2503
               --     Attach_To_Final_List (tmp.comp,
2504
               --       comp_typ (tmp)._record_controller.f)
2505
 
2506
               if Controlled_Type (Comp_Type) then
2507
                  Append_List_To (L,
2508
                    Make_Adjust_Call (
2509
                      Ref         => New_Copy_Tree (Comp_Expr),
2510
                      Typ         => Comp_Type,
2511
                      Flist_Ref   => Internal_Final_List,
2512
                      With_Attach => Make_Integer_Literal (Loc, 1)));
2513
               end if;
2514
            end if;
2515
 
2516
         --  ???
2517
 
2518
         elsif Ekind (Selector) = E_Discriminant
2519
           and then Nkind (N) /= N_Extension_Aggregate
2520
           and then Nkind (Parent (N)) = N_Component_Association
2521
           and then Is_Constrained (Typ)
2522
         then
2523
            --  We must check that the discriminant value imposed by the
2524
            --  context is the same as the value given in the subaggregate,
2525
            --  because after the expansion into assignments there is no
2526
            --  record on which to perform a regular discriminant check.
2527
 
2528
            declare
2529
               D_Val : Elmt_Id;
2530
               Disc  : Entity_Id;
2531
 
2532
            begin
2533
               D_Val := First_Elmt (Discriminant_Constraint (Typ));
2534
               Disc  := First_Discriminant (Typ);
2535
 
2536
               while Chars (Disc) /= Chars (Selector) loop
2537
                  Next_Discriminant (Disc);
2538
                  Next_Elmt (D_Val);
2539
               end loop;
2540
 
2541
               pragma Assert (Present (D_Val));
2542
 
2543
               Append_To (L,
2544
               Make_Raise_Constraint_Error (Loc,
2545
                 Condition =>
2546
                   Make_Op_Ne (Loc,
2547
                     Left_Opnd => New_Copy_Tree (Node (D_Val)),
2548
                     Right_Opnd => Expression (Comp)),
2549
                 Reason => CE_Discriminant_Check_Failed));
2550
            end;
2551
         end if;
2552
 
2553
         <<Next_Comp>>
2554
 
2555
         Next (Comp);
2556
      end loop;
2557
 
2558
      --  If the type is tagged, the tag needs to be initialized (unless
2559
      --  compiling for the Java VM where tags are implicit). It is done
2560
      --  late in the initialization process because in some cases, we call
2561
      --  the init proc of an ancestor which will not leave out the right tag
2562
 
2563
      if Ancestor_Is_Expression then
2564
         null;
2565
 
2566
      elsif Is_Tagged_Type (Typ) and then not Java_VM then
2567
         Instr :=
2568
           Make_OK_Assignment_Statement (Loc,
2569
             Name =>
2570
               Make_Selected_Component (Loc,
2571
                  Prefix => New_Copy_Tree (Target),
2572
                 Selector_Name =>
2573
                   New_Reference_To
2574
                     (First_Tag_Component (Base_Type (Typ)), Loc)),
2575
 
2576
             Expression =>
2577
               Unchecked_Convert_To (RTE (RE_Tag),
2578
                 New_Reference_To
2579
                   (Node (First_Elmt (Access_Disp_Table (Base_Type (Typ)))),
2580
                    Loc)));
2581
 
2582
         Append_To (L, Instr);
2583
      end if;
2584
 
2585
      --  If the controllers have not been initialized yet (by lack of non-
2586
      --  discriminant components), let's do it now.
2587
 
2588
      if not Ctrl_Stuff_Done then
2589
         Gen_Ctrl_Actions_For_Aggr;
2590
         Ctrl_Stuff_Done := True;
2591
      end if;
2592
 
2593
      return L;
2594
   end Build_Record_Aggr_Code;
2595
 
2596
   -------------------------------
2597
   -- Convert_Aggr_In_Allocator --
2598
   -------------------------------
2599
 
2600
   procedure Convert_Aggr_In_Allocator (Decl, Aggr : Node_Id) is
2601
      Loc  : constant Source_Ptr := Sloc (Aggr);
2602
      Typ  : constant Entity_Id  := Etype (Aggr);
2603
      Temp : constant Entity_Id  := Defining_Identifier (Decl);
2604
 
2605
      Occ  : constant Node_Id :=
2606
               Unchecked_Convert_To (Typ,
2607
                 Make_Explicit_Dereference (Loc,
2608
                   New_Reference_To (Temp, Loc)));
2609
 
2610
      Access_Type : constant Entity_Id := Etype (Temp);
2611
 
2612
   begin
2613
      if Is_Array_Type (Typ) then
2614
         Convert_Array_Aggr_In_Allocator (Decl, Aggr, Occ);
2615
 
2616
      elsif Has_Default_Init_Comps (Aggr) then
2617
         declare
2618
            L          : constant List_Id := New_List;
2619
            Init_Stmts : List_Id;
2620
 
2621
         begin
2622
            Init_Stmts := Late_Expansion (Aggr, Typ, Occ,
2623
                            Find_Final_List (Access_Type),
2624
                            Associated_Final_Chain (Base_Type (Access_Type)));
2625
 
2626
            Build_Task_Allocate_Block_With_Init_Stmts (L, Aggr, Init_Stmts);
2627
            Insert_Actions_After (Decl, L);
2628
         end;
2629
 
2630
      else
2631
         Insert_Actions_After (Decl,
2632
           Late_Expansion (Aggr, Typ, Occ,
2633
             Find_Final_List (Access_Type),
2634
             Associated_Final_Chain (Base_Type (Access_Type))));
2635
      end if;
2636
   end Convert_Aggr_In_Allocator;
2637
 
2638
   --------------------------------
2639
   -- Convert_Aggr_In_Assignment --
2640
   --------------------------------
2641
 
2642
   procedure Convert_Aggr_In_Assignment (N : Node_Id) is
2643
      Aggr : Node_Id             := Expression (N);
2644
      Typ  : constant Entity_Id  := Etype (Aggr);
2645
      Occ  : constant Node_Id    := New_Copy_Tree (Name (N));
2646
 
2647
   begin
2648
      if Nkind (Aggr) = N_Qualified_Expression then
2649
         Aggr := Expression (Aggr);
2650
      end if;
2651
 
2652
      Insert_Actions_After (N,
2653
        Late_Expansion (Aggr, Typ, Occ,
2654
          Find_Final_List (Typ, New_Copy_Tree (Occ))));
2655
   end Convert_Aggr_In_Assignment;
2656
 
2657
   ---------------------------------
2658
   -- Convert_Aggr_In_Object_Decl --
2659
   ---------------------------------
2660
 
2661
   procedure Convert_Aggr_In_Object_Decl (N : Node_Id) is
2662
      Obj  : constant Entity_Id  := Defining_Identifier (N);
2663
      Aggr : Node_Id             := Expression (N);
2664
      Loc  : constant Source_Ptr := Sloc (Aggr);
2665
      Typ  : constant Entity_Id  := Etype (Aggr);
2666
      Occ  : constant Node_Id    := New_Occurrence_Of (Obj, Loc);
2667
 
2668
      function Discriminants_Ok return Boolean;
2669
      --  If the object type is constrained, the discriminants in the
2670
      --  aggregate must be checked against the discriminants of the subtype.
2671
      --  This cannot be done using Apply_Discriminant_Checks because after
2672
      --  expansion there is no aggregate left to check.
2673
 
2674
      ----------------------
2675
      -- Discriminants_Ok --
2676
      ----------------------
2677
 
2678
      function Discriminants_Ok return Boolean is
2679
         Cond  : Node_Id := Empty;
2680
         Check : Node_Id;
2681
         D     : Entity_Id;
2682
         Disc1 : Elmt_Id;
2683
         Disc2 : Elmt_Id;
2684
         Val1  : Node_Id;
2685
         Val2  : Node_Id;
2686
 
2687
      begin
2688
         D := First_Discriminant (Typ);
2689
         Disc1 := First_Elmt (Discriminant_Constraint (Typ));
2690
         Disc2 := First_Elmt (Discriminant_Constraint (Etype (Obj)));
2691
 
2692
         while Present (Disc1) and then Present (Disc2) loop
2693
            Val1 := Node (Disc1);
2694
            Val2 := Node (Disc2);
2695
 
2696
            if not Is_OK_Static_Expression (Val1)
2697
              or else not Is_OK_Static_Expression (Val2)
2698
            then
2699
               Check := Make_Op_Ne (Loc,
2700
                 Left_Opnd  => Duplicate_Subexpr (Val1),
2701
                 Right_Opnd => Duplicate_Subexpr (Val2));
2702
 
2703
               if No (Cond) then
2704
                  Cond := Check;
2705
 
2706
               else
2707
                  Cond := Make_Or_Else (Loc,
2708
                    Left_Opnd => Cond,
2709
                    Right_Opnd => Check);
2710
               end if;
2711
 
2712
            elsif Expr_Value (Val1) /= Expr_Value (Val2) then
2713
               Apply_Compile_Time_Constraint_Error (Aggr,
2714
                 Msg    => "incorrect value for discriminant&?",
2715
                 Reason => CE_Discriminant_Check_Failed,
2716
                 Ent    => D);
2717
               return False;
2718
            end if;
2719
 
2720
            Next_Discriminant (D);
2721
            Next_Elmt (Disc1);
2722
            Next_Elmt (Disc2);
2723
         end loop;
2724
 
2725
         --  If any discriminant constraint is non-static, emit a check
2726
 
2727
         if Present (Cond) then
2728
            Insert_Action (N,
2729
              Make_Raise_Constraint_Error (Loc,
2730
                Condition => Cond,
2731
                Reason => CE_Discriminant_Check_Failed));
2732
         end if;
2733
 
2734
         return True;
2735
      end Discriminants_Ok;
2736
 
2737
   --  Start of processing for Convert_Aggr_In_Object_Decl
2738
 
2739
   begin
2740
      Set_Assignment_OK (Occ);
2741
 
2742
      if Nkind (Aggr) = N_Qualified_Expression then
2743
         Aggr := Expression (Aggr);
2744
      end if;
2745
 
2746
      if Has_Discriminants (Typ)
2747
        and then Typ /= Etype (Obj)
2748
        and then Is_Constrained (Etype (Obj))
2749
        and then not Discriminants_Ok
2750
      then
2751
         return;
2752
      end if;
2753
 
2754
      if Requires_Transient_Scope (Typ) then
2755
         Establish_Transient_Scope (Aggr, Sec_Stack =>
2756
           Is_Controlled (Typ) or else Has_Controlled_Component (Typ));
2757
      end if;
2758
 
2759
      Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ, Obj => Obj));
2760
      Set_No_Initialization (N);
2761
      Initialize_Discriminants (N, Typ);
2762
   end Convert_Aggr_In_Object_Decl;
2763
 
2764
   -------------------------------------
2765
   -- Convert_array_Aggr_In_Allocator --
2766
   -------------------------------------
2767
 
2768
   procedure Convert_Array_Aggr_In_Allocator
2769
     (Decl   : Node_Id;
2770
      Aggr   : Node_Id;
2771
      Target : Node_Id)
2772
   is
2773
      Aggr_Code : List_Id;
2774
      Typ       : constant Entity_Id := Etype (Aggr);
2775
      Ctyp      : constant Entity_Id := Component_Type (Typ);
2776
 
2777
   begin
2778
      --  The target is an explicit dereference of the allocated object.
2779
      --  Generate component assignments to it, as for an aggregate that
2780
      --  appears on the right-hand side of an assignment statement.
2781
 
2782
      Aggr_Code :=
2783
        Build_Array_Aggr_Code (Aggr,
2784
          Ctype       => Ctyp,
2785
          Index       => First_Index (Typ),
2786
          Into        => Target,
2787
          Scalar_Comp => Is_Scalar_Type (Ctyp));
2788
 
2789
      Insert_Actions_After (Decl, Aggr_Code);
2790
   end Convert_Array_Aggr_In_Allocator;
2791
 
2792
   ----------------------------
2793
   -- Convert_To_Assignments --
2794
   ----------------------------
2795
 
2796
   procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id) is
2797
      Loc  : constant Source_Ptr := Sloc (N);
2798
      Temp : Entity_Id;
2799
 
2800
      Instr       : Node_Id;
2801
      Target_Expr : Node_Id;
2802
      Parent_Kind : Node_Kind;
2803
      Unc_Decl    : Boolean := False;
2804
      Parent_Node : Node_Id;
2805
 
2806
   begin
2807
      Parent_Node := Parent (N);
2808
      Parent_Kind := Nkind (Parent_Node);
2809
 
2810
      if Parent_Kind = N_Qualified_Expression then
2811
 
2812
         --  Check if we are in a unconstrained declaration because in this
2813
         --  case the current delayed expansion mechanism doesn't work when
2814
         --  the declared object size depend on the initializing expr.
2815
 
2816
         begin
2817
            Parent_Node := Parent (Parent_Node);
2818
            Parent_Kind := Nkind (Parent_Node);
2819
 
2820
            if Parent_Kind = N_Object_Declaration then
2821
               Unc_Decl :=
2822
                 not Is_Entity_Name (Object_Definition (Parent_Node))
2823
                   or else Has_Discriminants
2824
                             (Entity (Object_Definition (Parent_Node)))
2825
                   or else Is_Class_Wide_Type
2826
                             (Entity (Object_Definition (Parent_Node)));
2827
            end if;
2828
         end;
2829
      end if;
2830
 
2831
      --  Just set the Delay flag in the following cases where the
2832
      --  transformation will be done top down from above
2833
 
2834
      --    - internal aggregate (transformed when expanding the parent)
2835
      --    - allocators  (see Convert_Aggr_In_Allocator)
2836
      --    - object decl (see Convert_Aggr_In_Object_Decl)
2837
      --    - safe assignments (see Convert_Aggr_Assignments)
2838
      --      so far only the assignments in the init procs are taken
2839
      --      into account
2840
 
2841
      if Parent_Kind = N_Aggregate
2842
        or else Parent_Kind = N_Extension_Aggregate
2843
        or else Parent_Kind = N_Component_Association
2844
        or else Parent_Kind = N_Allocator
2845
        or else (Parent_Kind = N_Object_Declaration and then not Unc_Decl)
2846
        or else (Parent_Kind = N_Assignment_Statement
2847
                  and then Inside_Init_Proc)
2848
      then
2849
         Set_Expansion_Delayed (N);
2850
         return;
2851
      end if;
2852
 
2853
      if Requires_Transient_Scope (Typ) then
2854
         Establish_Transient_Scope (N, Sec_Stack =>
2855
              Is_Controlled (Typ) or else Has_Controlled_Component (Typ));
2856
      end if;
2857
 
2858
      --  Create the temporary
2859
 
2860
      Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
2861
 
2862
      Instr :=
2863
        Make_Object_Declaration (Loc,
2864
          Defining_Identifier => Temp,
2865
          Object_Definition => New_Occurrence_Of (Typ, Loc));
2866
 
2867
      Set_No_Initialization (Instr);
2868
      Insert_Action (N, Instr);
2869
      Initialize_Discriminants (Instr, Typ);
2870
      Target_Expr := New_Occurrence_Of (Temp, Loc);
2871
 
2872
      Insert_Actions (N, Build_Record_Aggr_Code (N, Typ, Target_Expr));
2873
      Rewrite (N, New_Occurrence_Of (Temp, Loc));
2874
      Analyze_And_Resolve (N, Typ);
2875
   end Convert_To_Assignments;
2876
 
2877
   ---------------------------
2878
   -- Convert_To_Positional --
2879
   ---------------------------
2880
 
2881
   procedure Convert_To_Positional
2882
     (N                    : Node_Id;
2883
      Max_Others_Replicate : Nat     := 5;
2884
      Handle_Bit_Packed    : Boolean := False)
2885
   is
2886
      Typ : constant Entity_Id := Etype (N);
2887
 
2888
      function Flatten
2889
        (N   : Node_Id;
2890
         Ix  : Node_Id;
2891
         Ixb : Node_Id) return Boolean;
2892
      --  Convert the aggregate into a purely positional form if possible.
2893
      --  On entry the bounds of all dimensions are known to be static,
2894
      --  and the total number of components is safe enough to expand.
2895
 
2896
      function Is_Flat (N : Node_Id; Dims : Int) return Boolean;
2897
      --  Return True iff the array N is flat (which is not rivial
2898
      --  in the case of multidimensionsl aggregates).
2899
 
2900
      -------------
2901
      -- Flatten --
2902
      -------------
2903
 
2904
      function Flatten
2905
        (N   : Node_Id;
2906
         Ix  : Node_Id;
2907
         Ixb : Node_Id) return Boolean
2908
      is
2909
         Loc : constant Source_Ptr := Sloc (N);
2910
         Blo : constant Node_Id    := Type_Low_Bound (Etype (Ixb));
2911
         Lo  : constant Node_Id    := Type_Low_Bound (Etype (Ix));
2912
         Hi  : constant Node_Id    := Type_High_Bound (Etype (Ix));
2913
         Lov : Uint;
2914
         Hiv : Uint;
2915
 
2916
      begin
2917
         if Nkind (Original_Node (N)) = N_String_Literal then
2918
            return True;
2919
         end if;
2920
 
2921
         --  Only handle bounds starting at the base type low bound
2922
         --  for now since the compiler isn't able to handle different low
2923
         --  bounds yet. Case such as new String'(3..5 => ' ') will get
2924
         --  the wrong bounds, though it seems that the aggregate should
2925
         --  retain the bounds set on its Etype (see C64103E and CC1311B).
2926
 
2927
         Lov := Expr_Value (Lo);
2928
         Hiv := Expr_Value (Hi);
2929
 
2930
         if Hiv < Lov
2931
           or else not Compile_Time_Known_Value (Blo)
2932
           or else (Lov /= Expr_Value (Blo))
2933
         then
2934
            return False;
2935
         end if;
2936
 
2937
         --  Determine if set of alternatives is suitable for conversion
2938
         --  and build an array containing the values in sequence.
2939
 
2940
         declare
2941
            Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
2942
                     of Node_Id := (others => Empty);
2943
            --  The values in the aggregate sorted appropriately
2944
 
2945
            Vlist : List_Id;
2946
            --  Same data as Vals in list form
2947
 
2948
            Rep_Count : Nat;
2949
            --  Used to validate Max_Others_Replicate limit
2950
 
2951
            Elmt   : Node_Id;
2952
            Num    : Int := UI_To_Int (Lov);
2953
            Choice : Node_Id;
2954
            Lo, Hi : Node_Id;
2955
 
2956
         begin
2957
            if Present (Expressions (N)) then
2958
               Elmt := First (Expressions (N));
2959
 
2960
               while Present (Elmt) loop
2961
                  if Nkind (Elmt) = N_Aggregate
2962
                    and then Present (Next_Index (Ix))
2963
                    and then
2964
                         not Flatten (Elmt, Next_Index (Ix), Next_Index (Ixb))
2965
                  then
2966
                     return False;
2967
                  end if;
2968
 
2969
                  Vals (Num) := Relocate_Node (Elmt);
2970
                  Num := Num + 1;
2971
 
2972
                  Next (Elmt);
2973
               end loop;
2974
            end if;
2975
 
2976
            if No (Component_Associations (N)) then
2977
               return True;
2978
            end if;
2979
 
2980
            Elmt := First (Component_Associations (N));
2981
 
2982
            if Nkind (Expression (Elmt)) = N_Aggregate then
2983
               if Present (Next_Index (Ix))
2984
                 and then
2985
                   not Flatten
2986
                        (Expression (Elmt), Next_Index (Ix), Next_Index (Ixb))
2987
               then
2988
                  return False;
2989
               end if;
2990
            end if;
2991
 
2992
            Component_Loop : while Present (Elmt) loop
2993
               Choice := First (Choices (Elmt));
2994
               Choice_Loop : while Present (Choice) loop
2995
 
2996
                  --  If we have an others choice, fill in the missing elements
2997
                  --  subject to the limit established by Max_Others_Replicate.
2998
 
2999
                  if Nkind (Choice) = N_Others_Choice then
3000
                     Rep_Count := 0;
3001
 
3002
                     for J in Vals'Range loop
3003
                        if No (Vals (J)) then
3004
                           Vals (J) := New_Copy_Tree (Expression (Elmt));
3005
                           Rep_Count := Rep_Count + 1;
3006
 
3007
                           --  Check for maximum others replication. Note that
3008
                           --  we skip this test if either of the restrictions
3009
                           --  No_Elaboration_Code or No_Implicit_Loops is
3010
                           --  active, or if this is a preelaborable unit.
3011
 
3012
                           declare
3013
                              P : constant Entity_Id :=
3014
                                    Cunit_Entity (Current_Sem_Unit);
3015
 
3016
                           begin
3017
                              if Restriction_Active (No_Elaboration_Code)
3018
                                or else Restriction_Active (No_Implicit_Loops)
3019
                                or else Is_Preelaborated (P)
3020
                                or else (Ekind (P) = E_Package_Body
3021
                                          and then
3022
                                            Is_Preelaborated (Spec_Entity (P)))
3023
                              then
3024
                                 null;
3025
 
3026
                              elsif Rep_Count > Max_Others_Replicate then
3027
                                 return False;
3028
                              end if;
3029
                           end;
3030
                        end if;
3031
                     end loop;
3032
 
3033
                     exit Component_Loop;
3034
 
3035
                  --  Case of a subtype mark
3036
 
3037
                  elsif Nkind (Choice) = N_Identifier
3038
                    and then Is_Type (Entity (Choice))
3039
                  then
3040
                     Lo := Type_Low_Bound  (Etype (Choice));
3041
                     Hi := Type_High_Bound (Etype (Choice));
3042
 
3043
                  --  Case of subtype indication
3044
 
3045
                  elsif Nkind (Choice) = N_Subtype_Indication then
3046
                     Lo := Low_Bound  (Range_Expression (Constraint (Choice)));
3047
                     Hi := High_Bound (Range_Expression (Constraint (Choice)));
3048
 
3049
                  --  Case of a range
3050
 
3051
                  elsif Nkind (Choice) = N_Range then
3052
                     Lo := Low_Bound (Choice);
3053
                     Hi := High_Bound (Choice);
3054
 
3055
                  --  Normal subexpression case
3056
 
3057
                  else pragma Assert (Nkind (Choice) in N_Subexpr);
3058
                     if not Compile_Time_Known_Value (Choice) then
3059
                        return False;
3060
 
3061
                     else
3062
                        Vals (UI_To_Int (Expr_Value (Choice))) :=
3063
                          New_Copy_Tree (Expression (Elmt));
3064
                        goto Continue;
3065
                     end if;
3066
                  end if;
3067
 
3068
                  --  Range cases merge with Lo,Hi said
3069
 
3070
                  if not Compile_Time_Known_Value (Lo)
3071
                       or else
3072
                     not Compile_Time_Known_Value (Hi)
3073
                  then
3074
                     return False;
3075
                  else
3076
                     for J in UI_To_Int (Expr_Value (Lo)) ..
3077
                              UI_To_Int (Expr_Value (Hi))
3078
                     loop
3079
                        Vals (J) := New_Copy_Tree (Expression (Elmt));
3080
                     end loop;
3081
                  end if;
3082
 
3083
               <<Continue>>
3084
                  Next (Choice);
3085
               end loop Choice_Loop;
3086
 
3087
               Next (Elmt);
3088
            end loop Component_Loop;
3089
 
3090
            --  If we get here the conversion is possible
3091
 
3092
            Vlist := New_List;
3093
            for J in Vals'Range loop
3094
               Append (Vals (J), Vlist);
3095
            end loop;
3096
 
3097
            Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
3098
            Set_Aggregate_Bounds (N, Aggregate_Bounds (Original_Node (N)));
3099
            return True;
3100
         end;
3101
      end Flatten;
3102
 
3103
      -------------
3104
      -- Is_Flat --
3105
      -------------
3106
 
3107
      function Is_Flat (N : Node_Id; Dims : Int) return Boolean is
3108
         Elmt : Node_Id;
3109
 
3110
      begin
3111
         if Dims = 0 then
3112
            return True;
3113
 
3114
         elsif Nkind (N) = N_Aggregate then
3115
            if Present (Component_Associations (N)) then
3116
               return False;
3117
 
3118
            else
3119
               Elmt := First (Expressions (N));
3120
 
3121
               while Present (Elmt) loop
3122
                  if not Is_Flat (Elmt, Dims - 1) then
3123
                     return False;
3124
                  end if;
3125
 
3126
                  Next (Elmt);
3127
               end loop;
3128
 
3129
               return True;
3130
            end if;
3131
         else
3132
            return True;
3133
         end if;
3134
      end Is_Flat;
3135
 
3136
   --  Start of processing for Convert_To_Positional
3137
 
3138
   begin
3139
      --  Ada 2005 (AI-287): Do not convert in case of default initialized
3140
      --  components because in this case will need to call the corresponding
3141
      --  IP procedure.
3142
 
3143
      if Has_Default_Init_Comps (N) then
3144
         return;
3145
      end if;
3146
 
3147
      if Is_Flat (N, Number_Dimensions (Typ)) then
3148
         return;
3149
      end if;
3150
 
3151
      if Is_Bit_Packed_Array (Typ)
3152
        and then not Handle_Bit_Packed
3153
      then
3154
         return;
3155
      end if;
3156
 
3157
      --  Do not convert to positional if controlled components are
3158
      --  involved since these require special processing
3159
 
3160
      if Has_Controlled_Component (Typ) then
3161
         return;
3162
      end if;
3163
 
3164
      if Aggr_Size_OK (Typ)
3165
        and then
3166
          Flatten (N, First_Index (Typ), First_Index (Base_Type (Typ)))
3167
      then
3168
         Analyze_And_Resolve (N, Typ);
3169
      end if;
3170
   end Convert_To_Positional;
3171
 
3172
   ----------------------------
3173
   -- Expand_Array_Aggregate --
3174
   ----------------------------
3175
 
3176
   --  Array aggregate expansion proceeds as follows:
3177
 
3178
   --  1. If requested we generate code to perform all the array aggregate
3179
   --     bound checks, specifically
3180
 
3181
   --         (a) Check that the index range defined by aggregate bounds is
3182
   --             compatible with corresponding index subtype.
3183
 
3184
   --         (b) If an others choice is present check that no aggregate
3185
   --             index is outside the bounds of the index constraint.
3186
 
3187
   --         (c) For multidimensional arrays make sure that all subaggregates
3188
   --             corresponding to the same dimension have the same bounds.
3189
 
3190
   --  2. Check for packed array aggregate which can be converted to a
3191
   --     constant so that the aggregate disappeares completely.
3192
 
3193
   --  3. Check case of nested aggregate. Generally nested aggregates are
3194
   --     handled during the processing of the parent aggregate.
3195
 
3196
   --  4. Check if the aggregate can be statically processed. If this is the
3197
   --     case pass it as is to Gigi. Note that a necessary condition for
3198
   --     static processing is that the aggregate be fully positional.
3199
 
3200
   --  5. If in place aggregate expansion is possible (i.e. no need to create
3201
   --     a temporary) then mark the aggregate as such and return. Otherwise
3202
   --     create a new temporary and generate the appropriate initialization
3203
   --     code.
3204
 
3205
   procedure Expand_Array_Aggregate (N : Node_Id) is
3206
      Loc : constant Source_Ptr := Sloc (N);
3207
 
3208
      Typ  : constant Entity_Id := Etype (N);
3209
      Ctyp : constant Entity_Id := Component_Type (Typ);
3210
      --  Typ is the correct constrained array subtype of the aggregate
3211
      --  Ctyp is the corresponding component type.
3212
 
3213
      Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
3214
      --  Number of aggregate index dimensions
3215
 
3216
      Aggr_Low  : array (1 .. Aggr_Dimension) of Node_Id;
3217
      Aggr_High : array (1 .. Aggr_Dimension) of Node_Id;
3218
      --  Low and High bounds of the constraint for each aggregate index
3219
 
3220
      Aggr_Index_Typ : array (1 .. Aggr_Dimension) of Entity_Id;
3221
      --  The type of each index
3222
 
3223
      Maybe_In_Place_OK : Boolean;
3224
      --  If the type is neither controlled nor packed and the aggregate
3225
      --  is the expression in an assignment, assignment in place may be
3226
      --  possible, provided other conditions are met on the LHS.
3227
 
3228
      Others_Present : array (1 .. Aggr_Dimension) of Boolean :=
3229
                         (others => False);
3230
      --  If Others_Present (J) is True, then there is an others choice
3231
      --  in one of the sub-aggregates of N at dimension J.
3232
 
3233
      procedure Build_Constrained_Type (Positional : Boolean);
3234
      --  If the subtype is not static or unconstrained, build a constrained
3235
      --  type using the computable sizes of the aggregate and its sub-
3236
      --  aggregates.
3237
 
3238
      procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id);
3239
      --  Checks that the bounds of Aggr_Bounds are within the bounds defined
3240
      --  by Index_Bounds.
3241
 
3242
      procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos);
3243
      --  Checks that in a multi-dimensional array aggregate all subaggregates
3244
      --  corresponding to the same dimension have the same bounds.
3245
      --  Sub_Aggr is an array sub-aggregate. Dim is the dimension
3246
      --  corresponding to the sub-aggregate.
3247
 
3248
      procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos);
3249
      --  Computes the values of array Others_Present. Sub_Aggr is the
3250
      --  array sub-aggregate we start the computation from. Dim is the
3251
      --  dimension corresponding to the sub-aggregate.
3252
 
3253
      function Has_Address_Clause (D : Node_Id) return Boolean;
3254
      --  If the aggregate is the expression in an object declaration, it
3255
      --  cannot be expanded in place. This function does a lookahead in the
3256
      --  current declarative part to find an address clause for the object
3257
      --  being declared.
3258
 
3259
      function In_Place_Assign_OK return Boolean;
3260
      --  Simple predicate to determine whether an aggregate assignment can
3261
      --  be done in place, because none of the new values can depend on the
3262
      --  components of the target of the assignment.
3263
 
3264
      procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
3265
      --  Checks that if an others choice is present in any sub-aggregate no
3266
      --  aggregate index is outside the bounds of the index constraint.
3267
      --  Sub_Aggr is an array sub-aggregate. Dim is the dimension
3268
      --  corresponding to the sub-aggregate.
3269
 
3270
      ----------------------------
3271
      -- Build_Constrained_Type --
3272
      ----------------------------
3273
 
3274
      procedure Build_Constrained_Type (Positional : Boolean) is
3275
         Loc      : constant Source_Ptr := Sloc (N);
3276
         Agg_Type : Entity_Id;
3277
         Comp     : Node_Id;
3278
         Decl     : Node_Id;
3279
         Typ      : constant Entity_Id := Etype (N);
3280
         Indices  : constant List_Id   := New_List;
3281
         Num      : Int;
3282
         Sub_Agg  : Node_Id;
3283
 
3284
      begin
3285
         Agg_Type :=
3286
           Make_Defining_Identifier (
3287
             Loc, New_Internal_Name ('A'));
3288
 
3289
         --  If the aggregate is purely positional, all its subaggregates
3290
         --  have the same size. We collect the dimensions from the first
3291
         --  subaggregate at each level.
3292
 
3293
         if Positional then
3294
            Sub_Agg := N;
3295
 
3296
            for D in 1 .. Number_Dimensions (Typ) loop
3297
               Comp := First (Expressions (Sub_Agg));
3298
 
3299
               Sub_Agg := Comp;
3300
               Num := 0;
3301
 
3302
               while Present (Comp) loop
3303
                  Num := Num + 1;
3304
                  Next (Comp);
3305
               end loop;
3306
 
3307
               Append (
3308
                 Make_Range (Loc,
3309
                   Low_Bound => Make_Integer_Literal (Loc, 1),
3310
                   High_Bound =>
3311
                          Make_Integer_Literal (Loc, Num)),
3312
                 Indices);
3313
            end loop;
3314
 
3315
         else
3316
            --  We know the aggregate type is unconstrained and the
3317
            --  aggregate is not processable by the back end, therefore
3318
            --  not necessarily positional. Retrieve the bounds of each
3319
            --  dimension as computed earlier.
3320
 
3321
            for D in 1 .. Number_Dimensions (Typ) loop
3322
               Append (
3323
                 Make_Range (Loc,
3324
                    Low_Bound  => Aggr_Low  (D),
3325
                    High_Bound => Aggr_High (D)),
3326
                 Indices);
3327
            end loop;
3328
         end if;
3329
 
3330
         Decl :=
3331
           Make_Full_Type_Declaration (Loc,
3332
               Defining_Identifier => Agg_Type,
3333
               Type_Definition =>
3334
                 Make_Constrained_Array_Definition (Loc,
3335
                   Discrete_Subtype_Definitions => Indices,
3336
                   Component_Definition =>
3337
                     Make_Component_Definition (Loc,
3338
                       Aliased_Present => False,
3339
                       Subtype_Indication =>
3340
                         New_Occurrence_Of (Component_Type (Typ), Loc))));
3341
 
3342
         Insert_Action (N, Decl);
3343
         Analyze (Decl);
3344
         Set_Etype (N, Agg_Type);
3345
         Set_Is_Itype (Agg_Type);
3346
         Freeze_Itype (Agg_Type, N);
3347
      end Build_Constrained_Type;
3348
 
3349
      ------------------
3350
      -- Check_Bounds --
3351
      ------------------
3352
 
3353
      procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id) is
3354
         Aggr_Lo : Node_Id;
3355
         Aggr_Hi : Node_Id;
3356
 
3357
         Ind_Lo  : Node_Id;
3358
         Ind_Hi  : Node_Id;
3359
 
3360
         Cond    : Node_Id := Empty;
3361
 
3362
      begin
3363
         Get_Index_Bounds (Aggr_Bounds, Aggr_Lo, Aggr_Hi);
3364
         Get_Index_Bounds (Index_Bounds, Ind_Lo, Ind_Hi);
3365
 
3366
         --  Generate the following test:
3367
         --
3368
         --    [constraint_error when
3369
         --      Aggr_Lo <= Aggr_Hi and then
3370
         --        (Aggr_Lo < Ind_Lo or else Aggr_Hi > Ind_Hi)]
3371
         --
3372
         --  As an optimization try to see if some tests are trivially vacuos
3373
         --  because we are comparing an expression against itself.
3374
 
3375
         if Aggr_Lo = Ind_Lo and then Aggr_Hi = Ind_Hi then
3376
            Cond := Empty;
3377
 
3378
         elsif Aggr_Hi = Ind_Hi then
3379
            Cond :=
3380
              Make_Op_Lt (Loc,
3381
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
3382
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo));
3383
 
3384
         elsif Aggr_Lo = Ind_Lo then
3385
            Cond :=
3386
              Make_Op_Gt (Loc,
3387
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
3388
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Hi));
3389
 
3390
         else
3391
            Cond :=
3392
              Make_Or_Else (Loc,
3393
                Left_Opnd =>
3394
                  Make_Op_Lt (Loc,
3395
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
3396
                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo)),
3397
 
3398
                Right_Opnd =>
3399
                  Make_Op_Gt (Loc,
3400
                    Left_Opnd  => Duplicate_Subexpr (Aggr_Hi),
3401
                    Right_Opnd => Duplicate_Subexpr (Ind_Hi)));
3402
         end if;
3403
 
3404
         if Present (Cond) then
3405
            Cond :=
3406
              Make_And_Then (Loc,
3407
                Left_Opnd =>
3408
                  Make_Op_Le (Loc,
3409
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
3410
                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi)),
3411
 
3412
                Right_Opnd => Cond);
3413
 
3414
            Set_Analyzed (Left_Opnd  (Left_Opnd (Cond)), False);
3415
            Set_Analyzed (Right_Opnd (Left_Opnd (Cond)), False);
3416
            Insert_Action (N,
3417
              Make_Raise_Constraint_Error (Loc,
3418
                Condition => Cond,
3419
                Reason    => CE_Length_Check_Failed));
3420
         end if;
3421
      end Check_Bounds;
3422
 
3423
      ----------------------------
3424
      -- Check_Same_Aggr_Bounds --
3425
      ----------------------------
3426
 
3427
      procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos) is
3428
         Sub_Lo : constant Node_Id := Low_Bound (Aggregate_Bounds (Sub_Aggr));
3429
         Sub_Hi : constant Node_Id := High_Bound (Aggregate_Bounds (Sub_Aggr));
3430
         --  The bounds of this specific sub-aggregate
3431
 
3432
         Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
3433
         Aggr_Hi : constant Node_Id := Aggr_High (Dim);
3434
         --  The bounds of the aggregate for this dimension
3435
 
3436
         Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
3437
         --  The index type for this dimension.xxx
3438
 
3439
         Cond  : Node_Id := Empty;
3440
 
3441
         Assoc : Node_Id;
3442
         Expr  : Node_Id;
3443
 
3444
      begin
3445
         --  If index checks are on generate the test
3446
         --
3447
         --    [constraint_error when
3448
         --      Aggr_Lo /= Sub_Lo or else Aggr_Hi /= Sub_Hi]
3449
         --
3450
         --  As an optimization try to see if some tests are trivially vacuos
3451
         --  because we are comparing an expression against itself. Also for
3452
         --  the first dimension the test is trivially vacuous because there
3453
         --  is just one aggregate for dimension 1.
3454
 
3455
         if Index_Checks_Suppressed (Ind_Typ) then
3456
            Cond := Empty;
3457
 
3458
         elsif Dim = 1
3459
           or else (Aggr_Lo = Sub_Lo and then Aggr_Hi = Sub_Hi)
3460
         then
3461
            Cond := Empty;
3462
 
3463
         elsif Aggr_Hi = Sub_Hi then
3464
            Cond :=
3465
              Make_Op_Ne (Loc,
3466
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
3467
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo));
3468
 
3469
         elsif Aggr_Lo = Sub_Lo then
3470
            Cond :=
3471
              Make_Op_Ne (Loc,
3472
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
3473
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Hi));
3474
 
3475
         else
3476
            Cond :=
3477
              Make_Or_Else (Loc,
3478
                Left_Opnd =>
3479
                  Make_Op_Ne (Loc,
3480
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
3481
                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo)),
3482
 
3483
                Right_Opnd =>
3484
                  Make_Op_Ne (Loc,
3485
                    Left_Opnd  => Duplicate_Subexpr (Aggr_Hi),
3486
                    Right_Opnd => Duplicate_Subexpr (Sub_Hi)));
3487
         end if;
3488
 
3489
         if Present (Cond) then
3490
            Insert_Action (N,
3491
              Make_Raise_Constraint_Error (Loc,
3492
                Condition => Cond,
3493
                Reason    => CE_Length_Check_Failed));
3494
         end if;
3495
 
3496
         --  Now look inside the sub-aggregate to see if there is more work
3497
 
3498
         if Dim < Aggr_Dimension then
3499
 
3500
            --  Process positional components
3501
 
3502
            if Present (Expressions (Sub_Aggr)) then
3503
               Expr := First (Expressions (Sub_Aggr));
3504
               while Present (Expr) loop
3505
                  Check_Same_Aggr_Bounds (Expr, Dim + 1);
3506
                  Next (Expr);
3507
               end loop;
3508
            end if;
3509
 
3510
            --  Process component associations
3511
 
3512
            if Present (Component_Associations (Sub_Aggr)) then
3513
               Assoc := First (Component_Associations (Sub_Aggr));
3514
               while Present (Assoc) loop
3515
                  Expr := Expression (Assoc);
3516
                  Check_Same_Aggr_Bounds (Expr, Dim + 1);
3517
                  Next (Assoc);
3518
               end loop;
3519
            end if;
3520
         end if;
3521
      end Check_Same_Aggr_Bounds;
3522
 
3523
      ----------------------------
3524
      -- Compute_Others_Present --
3525
      ----------------------------
3526
 
3527
      procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos) is
3528
         Assoc : Node_Id;
3529
         Expr  : Node_Id;
3530
 
3531
      begin
3532
         if Present (Component_Associations (Sub_Aggr)) then
3533
            Assoc := Last (Component_Associations (Sub_Aggr));
3534
 
3535
            if Nkind (First (Choices (Assoc))) = N_Others_Choice then
3536
               Others_Present (Dim) := True;
3537
            end if;
3538
         end if;
3539
 
3540
         --  Now look inside the sub-aggregate to see if there is more work
3541
 
3542
         if Dim < Aggr_Dimension then
3543
 
3544
            --  Process positional components
3545
 
3546
            if Present (Expressions (Sub_Aggr)) then
3547
               Expr := First (Expressions (Sub_Aggr));
3548
               while Present (Expr) loop
3549
                  Compute_Others_Present (Expr, Dim + 1);
3550
                  Next (Expr);
3551
               end loop;
3552
            end if;
3553
 
3554
            --  Process component associations
3555
 
3556
            if Present (Component_Associations (Sub_Aggr)) then
3557
               Assoc := First (Component_Associations (Sub_Aggr));
3558
               while Present (Assoc) loop
3559
                  Expr := Expression (Assoc);
3560
                  Compute_Others_Present (Expr, Dim + 1);
3561
                  Next (Assoc);
3562
               end loop;
3563
            end if;
3564
         end if;
3565
      end Compute_Others_Present;
3566
 
3567
      ------------------------
3568
      -- Has_Address_Clause --
3569
      ------------------------
3570
 
3571
      function Has_Address_Clause (D : Node_Id) return Boolean is
3572
         Id   : constant Entity_Id := Defining_Identifier (D);
3573
         Decl : Node_Id := Next (D);
3574
 
3575
      begin
3576
         while Present (Decl) loop
3577
            if Nkind (Decl) = N_At_Clause
3578
               and then Chars (Identifier (Decl)) = Chars (Id)
3579
            then
3580
               return True;
3581
 
3582
            elsif Nkind (Decl) = N_Attribute_Definition_Clause
3583
               and then Chars (Decl) = Name_Address
3584
               and then Chars (Name (Decl)) = Chars (Id)
3585
            then
3586
               return True;
3587
            end if;
3588
 
3589
            Next (Decl);
3590
         end loop;
3591
 
3592
         return False;
3593
      end Has_Address_Clause;
3594
 
3595
      ------------------------
3596
      -- In_Place_Assign_OK --
3597
      ------------------------
3598
 
3599
      function In_Place_Assign_OK return Boolean is
3600
         Aggr_In : Node_Id;
3601
         Aggr_Lo : Node_Id;
3602
         Aggr_Hi : Node_Id;
3603
         Obj_In  : Node_Id;
3604
         Obj_Lo  : Node_Id;
3605
         Obj_Hi  : Node_Id;
3606
 
3607
         function Is_Others_Aggregate (Aggr : Node_Id) return Boolean;
3608
         --   Aggregates that consist of a single Others choice are safe
3609
         --  if the single expression is.
3610
 
3611
         function Safe_Aggregate (Aggr : Node_Id) return Boolean;
3612
         --  Check recursively that each component of a (sub)aggregate does
3613
         --  not depend on the variable being assigned to.
3614
 
3615
         function Safe_Component (Expr : Node_Id) return Boolean;
3616
         --  Verify that an expression cannot depend on the variable being
3617
         --  assigned to. Room for improvement here (but less than before).
3618
 
3619
         -------------------------
3620
         -- Is_Others_Aggregate --
3621
         -------------------------
3622
 
3623
         function Is_Others_Aggregate (Aggr : Node_Id) return Boolean is
3624
         begin
3625
            return No (Expressions (Aggr))
3626
              and then Nkind
3627
                (First (Choices (First (Component_Associations (Aggr)))))
3628
                  = N_Others_Choice;
3629
         end Is_Others_Aggregate;
3630
 
3631
         --------------------
3632
         -- Safe_Aggregate --
3633
         --------------------
3634
 
3635
         function Safe_Aggregate (Aggr : Node_Id) return Boolean is
3636
            Expr : Node_Id;
3637
 
3638
         begin
3639
            if Present (Expressions (Aggr)) then
3640
               Expr := First (Expressions (Aggr));
3641
 
3642
               while Present (Expr) loop
3643
                  if Nkind (Expr) = N_Aggregate then
3644
                     if not Safe_Aggregate (Expr) then
3645
                        return False;
3646
                     end if;
3647
 
3648
                  elsif not Safe_Component (Expr) then
3649
                     return False;
3650
                  end if;
3651
 
3652
                  Next (Expr);
3653
               end loop;
3654
            end if;
3655
 
3656
            if Present (Component_Associations (Aggr)) then
3657
               Expr := First (Component_Associations (Aggr));
3658
 
3659
               while Present (Expr) loop
3660
                  if Nkind (Expression (Expr)) = N_Aggregate then
3661
                     if not Safe_Aggregate (Expression (Expr)) then
3662
                        return False;
3663
                     end if;
3664
 
3665
                  elsif not Safe_Component (Expression (Expr)) then
3666
                     return False;
3667
                  end if;
3668
 
3669
                  Next (Expr);
3670
               end loop;
3671
            end if;
3672
 
3673
            return True;
3674
         end Safe_Aggregate;
3675
 
3676
         --------------------
3677
         -- Safe_Component --
3678
         --------------------
3679
 
3680
         function Safe_Component (Expr : Node_Id) return Boolean is
3681
            Comp : Node_Id := Expr;
3682
 
3683
            function Check_Component (Comp : Node_Id) return Boolean;
3684
            --  Do the recursive traversal, after copy
3685
 
3686
            ---------------------
3687
            -- Check_Component --
3688
            ---------------------
3689
 
3690
            function Check_Component (Comp : Node_Id) return Boolean is
3691
            begin
3692
               if Is_Overloaded (Comp) then
3693
                  return False;
3694
               end if;
3695
 
3696
               return Compile_Time_Known_Value (Comp)
3697
 
3698
                 or else (Is_Entity_Name (Comp)
3699
                           and then  Present (Entity (Comp))
3700
                           and then No (Renamed_Object (Entity (Comp))))
3701
 
3702
                 or else (Nkind (Comp) = N_Attribute_Reference
3703
                           and then Check_Component (Prefix (Comp)))
3704
 
3705
                 or else (Nkind (Comp) in N_Binary_Op
3706
                           and then Check_Component (Left_Opnd  (Comp))
3707
                           and then Check_Component (Right_Opnd (Comp)))
3708
 
3709
                 or else (Nkind (Comp) in N_Unary_Op
3710
                           and then Check_Component (Right_Opnd (Comp)))
3711
 
3712
                 or else (Nkind (Comp) = N_Selected_Component
3713
                           and then Check_Component (Prefix (Comp)))
3714
 
3715
                 or else (Nkind (Comp) = N_Unchecked_Type_Conversion
3716
                           and then Check_Component (Expression (Comp)));
3717
            end Check_Component;
3718
 
3719
         --  Start of processing for Safe_Component
3720
 
3721
         begin
3722
            --  If the component appears in an association that may
3723
            --  correspond to more than one element, it is not analyzed
3724
            --  before the expansion into assignments, to avoid side effects.
3725
            --  We analyze, but do not resolve the copy, to obtain sufficient
3726
            --  entity information for the checks that follow. If component is
3727
            --  overloaded we assume an unsafe function call.
3728
 
3729
            if not Analyzed (Comp) then
3730
               if Is_Overloaded (Expr) then
3731
                  return False;
3732
 
3733
               elsif Nkind (Expr) = N_Aggregate
3734
                  and then not Is_Others_Aggregate (Expr)
3735
               then
3736
                  return False;
3737
 
3738
               elsif Nkind (Expr) = N_Allocator then
3739
 
3740
                  --  For now, too complex to analyze
3741
 
3742
                  return False;
3743
               end if;
3744
 
3745
               Comp := New_Copy_Tree (Expr);
3746
               Set_Parent (Comp, Parent (Expr));
3747
               Analyze (Comp);
3748
            end if;
3749
 
3750
            if Nkind (Comp) = N_Aggregate then
3751
               return Safe_Aggregate (Comp);
3752
            else
3753
               return Check_Component (Comp);
3754
            end if;
3755
         end Safe_Component;
3756
 
3757
      --  Start of processing for In_Place_Assign_OK
3758
 
3759
      begin
3760
         if Present (Component_Associations (N)) then
3761
 
3762
            --  On assignment, sliding can take place, so we cannot do the
3763
            --  assignment in place unless the bounds of the aggregate are
3764
            --  statically equal to those of the target.
3765
 
3766
            --  If the aggregate is given by an others choice, the bounds
3767
            --  are derived from the left-hand side, and the assignment is
3768
            --  safe if the expression is.
3769
 
3770
            if Is_Others_Aggregate (N) then
3771
               return
3772
                 Safe_Component
3773
                  (Expression (First (Component_Associations (N))));
3774
            end if;
3775
 
3776
            Aggr_In := First_Index (Etype (N));
3777
            if Nkind (Parent (N)) = N_Assignment_Statement then
3778
               Obj_In  := First_Index (Etype (Name (Parent (N))));
3779
 
3780
            else
3781
               --  Context is an allocator. Check bounds of aggregate
3782
               --  against given type in qualified expression.
3783
 
3784
               pragma Assert (Nkind (Parent (Parent (N))) = N_Allocator);
3785
               Obj_In :=
3786
                 First_Index (Etype (Entity (Subtype_Mark (Parent (N)))));
3787
            end if;
3788
 
3789
            while Present (Aggr_In) loop
3790
               Get_Index_Bounds (Aggr_In, Aggr_Lo, Aggr_Hi);
3791
               Get_Index_Bounds (Obj_In, Obj_Lo, Obj_Hi);
3792
 
3793
               if not Compile_Time_Known_Value (Aggr_Lo)
3794
                 or else not Compile_Time_Known_Value (Aggr_Hi)
3795
                 or else not Compile_Time_Known_Value (Obj_Lo)
3796
                 or else not Compile_Time_Known_Value (Obj_Hi)
3797
                 or else Expr_Value (Aggr_Lo) /= Expr_Value (Obj_Lo)
3798
                 or else Expr_Value (Aggr_Hi) /= Expr_Value (Obj_Hi)
3799
               then
3800
                  return False;
3801
               end if;
3802
 
3803
               Next_Index (Aggr_In);
3804
               Next_Index (Obj_In);
3805
            end loop;
3806
         end if;
3807
 
3808
         --  Now check the component values themselves
3809
 
3810
         return Safe_Aggregate (N);
3811
      end In_Place_Assign_OK;
3812
 
3813
      ------------------
3814
      -- Others_Check --
3815
      ------------------
3816
 
3817
      procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos) is
3818
         Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
3819
         Aggr_Hi : constant Node_Id := Aggr_High (Dim);
3820
         --  The bounds of the aggregate for this dimension
3821
 
3822
         Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
3823
         --  The index type for this dimension
3824
 
3825
         Need_To_Check : Boolean := False;
3826
 
3827
         Choices_Lo : Node_Id := Empty;
3828
         Choices_Hi : Node_Id := Empty;
3829
         --  The lowest and highest discrete choices for a named sub-aggregate
3830
 
3831
         Nb_Choices : Int := -1;
3832
         --  The number of discrete non-others choices in this sub-aggregate
3833
 
3834
         Nb_Elements : Uint := Uint_0;
3835
         --  The number of elements in a positional aggregate
3836
 
3837
         Cond : Node_Id := Empty;
3838
 
3839
         Assoc  : Node_Id;
3840
         Choice : Node_Id;
3841
         Expr   : Node_Id;
3842
 
3843
      begin
3844
         --  Check if we have an others choice. If we do make sure that this
3845
         --  sub-aggregate contains at least one element in addition to the
3846
         --  others choice.
3847
 
3848
         if Range_Checks_Suppressed (Ind_Typ) then
3849
            Need_To_Check := False;
3850
 
3851
         elsif Present (Expressions (Sub_Aggr))
3852
           and then Present (Component_Associations (Sub_Aggr))
3853
         then
3854
            Need_To_Check := True;
3855
 
3856
         elsif Present (Component_Associations (Sub_Aggr)) then
3857
            Assoc := Last (Component_Associations (Sub_Aggr));
3858
 
3859
            if Nkind (First (Choices (Assoc))) /= N_Others_Choice then
3860
               Need_To_Check := False;
3861
 
3862
            else
3863
               --  Count the number of discrete choices. Start with -1
3864
               --  because the others choice does not count.
3865
 
3866
               Nb_Choices := -1;
3867
               Assoc := First (Component_Associations (Sub_Aggr));
3868
               while Present (Assoc) loop
3869
                  Choice := First (Choices (Assoc));
3870
                  while Present (Choice) loop
3871
                     Nb_Choices := Nb_Choices + 1;
3872
                     Next (Choice);
3873
                  end loop;
3874
 
3875
                  Next (Assoc);
3876
               end loop;
3877
 
3878
               --  If there is only an others choice nothing to do
3879
 
3880
               Need_To_Check := (Nb_Choices > 0);
3881
            end if;
3882
 
3883
         else
3884
            Need_To_Check := False;
3885
         end if;
3886
 
3887
         --  If we are dealing with a positional sub-aggregate with an
3888
         --  others choice then compute the number or positional elements.
3889
 
3890
         if Need_To_Check and then Present (Expressions (Sub_Aggr)) then
3891
            Expr := First (Expressions (Sub_Aggr));
3892
            Nb_Elements := Uint_0;
3893
            while Present (Expr) loop
3894
               Nb_Elements := Nb_Elements + 1;
3895
               Next (Expr);
3896
            end loop;
3897
 
3898
         --  If the aggregate contains discrete choices and an others choice
3899
         --  compute the smallest and largest discrete choice values.
3900
 
3901
         elsif Need_To_Check then
3902
            Compute_Choices_Lo_And_Choices_Hi : declare
3903
 
3904
               Table : Case_Table_Type (1 .. Nb_Choices);
3905
               --  Used to sort all the different choice values
3906
 
3907
               J    : Pos := 1;
3908
               Low  : Node_Id;
3909
               High : Node_Id;
3910
 
3911
            begin
3912
               Assoc := First (Component_Associations (Sub_Aggr));
3913
               while Present (Assoc) loop
3914
                  Choice := First (Choices (Assoc));
3915
                  while Present (Choice) loop
3916
                     if Nkind (Choice) = N_Others_Choice then
3917
                        exit;
3918
                     end if;
3919
 
3920
                     Get_Index_Bounds (Choice, Low, High);
3921
                     Table (J).Choice_Lo := Low;
3922
                     Table (J).Choice_Hi := High;
3923
 
3924
                     J := J + 1;
3925
                     Next (Choice);
3926
                  end loop;
3927
 
3928
                  Next (Assoc);
3929
               end loop;
3930
 
3931
               --  Sort the discrete choices
3932
 
3933
               Sort_Case_Table (Table);
3934
 
3935
               Choices_Lo := Table (1).Choice_Lo;
3936
               Choices_Hi := Table (Nb_Choices).Choice_Hi;
3937
            end Compute_Choices_Lo_And_Choices_Hi;
3938
         end if;
3939
 
3940
         --  If no others choice in this sub-aggregate, or the aggregate
3941
         --  comprises only an others choice, nothing to do.
3942
 
3943
         if not Need_To_Check then
3944
            Cond := Empty;
3945
 
3946
         --  If we are dealing with an aggregate containing an others
3947
         --  choice and positional components, we generate the following test:
3948
         --
3949
         --    if Ind_Typ'Pos (Aggr_Lo) + (Nb_Elements - 1) >
3950
         --            Ind_Typ'Pos (Aggr_Hi)
3951
         --    then
3952
         --       raise Constraint_Error;
3953
         --    end if;
3954
 
3955
         elsif Nb_Elements > Uint_0 then
3956
            Cond :=
3957
              Make_Op_Gt (Loc,
3958
                Left_Opnd  =>
3959
                  Make_Op_Add (Loc,
3960
                    Left_Opnd  =>
3961
                      Make_Attribute_Reference (Loc,
3962
                        Prefix         => New_Reference_To (Ind_Typ, Loc),
3963
                        Attribute_Name => Name_Pos,
3964
                        Expressions    =>
3965
                          New_List
3966
                            (Duplicate_Subexpr_Move_Checks (Aggr_Lo))),
3967
                    Right_Opnd => Make_Integer_Literal (Loc, Nb_Elements - 1)),
3968
 
3969
                Right_Opnd =>
3970
                  Make_Attribute_Reference (Loc,
3971
                    Prefix         => New_Reference_To (Ind_Typ, Loc),
3972
                    Attribute_Name => Name_Pos,
3973
                    Expressions    => New_List (
3974
                      Duplicate_Subexpr_Move_Checks (Aggr_Hi))));
3975
 
3976
         --  If we are dealing with an aggregate containing an others
3977
         --  choice and discrete choices we generate the following test:
3978
         --
3979
         --    [constraint_error when
3980
         --      Choices_Lo < Aggr_Lo or else Choices_Hi > Aggr_Hi];
3981
 
3982
         else
3983
            Cond :=
3984
              Make_Or_Else (Loc,
3985
                Left_Opnd =>
3986
                  Make_Op_Lt (Loc,
3987
                    Left_Opnd  =>
3988
                      Duplicate_Subexpr_Move_Checks (Choices_Lo),
3989
                    Right_Opnd =>
3990
                      Duplicate_Subexpr_Move_Checks (Aggr_Lo)),
3991
 
3992
                Right_Opnd =>
3993
                  Make_Op_Gt (Loc,
3994
                    Left_Opnd  =>
3995
                      Duplicate_Subexpr (Choices_Hi),
3996
                    Right_Opnd =>
3997
                      Duplicate_Subexpr (Aggr_Hi)));
3998
         end if;
3999
 
4000
         if Present (Cond) then
4001
            Insert_Action (N,
4002
              Make_Raise_Constraint_Error (Loc,
4003
                Condition => Cond,
4004
                Reason    => CE_Length_Check_Failed));
4005
         end if;
4006
 
4007
         --  Now look inside the sub-aggregate to see if there is more work
4008
 
4009
         if Dim < Aggr_Dimension then
4010
 
4011
            --  Process positional components
4012
 
4013
            if Present (Expressions (Sub_Aggr)) then
4014
               Expr := First (Expressions (Sub_Aggr));
4015
               while Present (Expr) loop
4016
                  Others_Check (Expr, Dim + 1);
4017
                  Next (Expr);
4018
               end loop;
4019
            end if;
4020
 
4021
            --  Process component associations
4022
 
4023
            if Present (Component_Associations (Sub_Aggr)) then
4024
               Assoc := First (Component_Associations (Sub_Aggr));
4025
               while Present (Assoc) loop
4026
                  Expr := Expression (Assoc);
4027
                  Others_Check (Expr, Dim + 1);
4028
                  Next (Assoc);
4029
               end loop;
4030
            end if;
4031
         end if;
4032
      end Others_Check;
4033
 
4034
      --  Remaining Expand_Array_Aggregate variables
4035
 
4036
      Tmp : Entity_Id;
4037
      --  Holds the temporary aggregate value
4038
 
4039
      Tmp_Decl : Node_Id;
4040
      --  Holds the declaration of Tmp
4041
 
4042
      Aggr_Code   : List_Id;
4043
      Parent_Node : Node_Id;
4044
      Parent_Kind : Node_Kind;
4045
 
4046
   --  Start of processing for Expand_Array_Aggregate
4047
 
4048
   begin
4049
      --  Do not touch the special aggregates of attributes used for Asm calls
4050
 
4051
      if Is_RTE (Ctyp, RE_Asm_Input_Operand)
4052
        or else Is_RTE (Ctyp, RE_Asm_Output_Operand)
4053
      then
4054
         return;
4055
      end if;
4056
 
4057
      --  If the semantic analyzer has determined that aggregate N will raise
4058
      --  Constraint_Error at run-time, then the aggregate node has been
4059
      --  replaced with an N_Raise_Constraint_Error node and we should
4060
      --  never get here.
4061
 
4062
      pragma Assert (not Raises_Constraint_Error (N));
4063
 
4064
      --  STEP 1a
4065
 
4066
      --  Check that the index range defined by aggregate bounds is
4067
      --  compatible with corresponding index subtype.
4068
 
4069
      Index_Compatibility_Check : declare
4070
         Aggr_Index_Range : Node_Id := First_Index (Typ);
4071
         --  The current aggregate index range
4072
 
4073
         Index_Constraint : Node_Id := First_Index (Etype (Typ));
4074
         --  The corresponding index constraint against which we have to
4075
         --  check the above aggregate index range.
4076
 
4077
      begin
4078
         Compute_Others_Present (N, 1);
4079
 
4080
         for J in 1 .. Aggr_Dimension loop
4081
            --  There is no need to emit a check if an others choice is
4082
            --  present for this array aggregate dimension since in this
4083
            --  case one of N's sub-aggregates has taken its bounds from the
4084
            --  context and these bounds must have been checked already. In
4085
            --  addition all sub-aggregates corresponding to the same
4086
            --  dimension must all have the same bounds (checked in (c) below).
4087
 
4088
            if not Range_Checks_Suppressed (Etype (Index_Constraint))
4089
              and then not Others_Present (J)
4090
            then
4091
               --  We don't use Checks.Apply_Range_Check here because it
4092
               --  emits a spurious check. Namely it checks that the range
4093
               --  defined by the aggregate bounds is non empty. But we know
4094
               --  this already if we get here.
4095
 
4096
               Check_Bounds (Aggr_Index_Range, Index_Constraint);
4097
            end if;
4098
 
4099
            --  Save the low and high bounds of the aggregate index as well
4100
            --  as the index type for later use in checks (b) and (c) below.
4101
 
4102
            Aggr_Low  (J) := Low_Bound (Aggr_Index_Range);
4103
            Aggr_High (J) := High_Bound (Aggr_Index_Range);
4104
 
4105
            Aggr_Index_Typ (J) := Etype (Index_Constraint);
4106
 
4107
            Next_Index (Aggr_Index_Range);
4108
            Next_Index (Index_Constraint);
4109
         end loop;
4110
      end Index_Compatibility_Check;
4111
 
4112
      --  STEP 1b
4113
 
4114
      --  If an others choice is present check that no aggregate
4115
      --  index is outside the bounds of the index constraint.
4116
 
4117
      Others_Check (N, 1);
4118
 
4119
      --  STEP 1c
4120
 
4121
      --  For multidimensional arrays make sure that all subaggregates
4122
      --  corresponding to the same dimension have the same bounds.
4123
 
4124
      if Aggr_Dimension > 1 then
4125
         Check_Same_Aggr_Bounds (N, 1);
4126
      end if;
4127
 
4128
      --  STEP 2
4129
 
4130
      --  Here we test for is packed array aggregate that we can handle
4131
      --  at compile time. If so, return with transformation done. Note
4132
      --  that we do this even if the aggregate is nested, because once
4133
      --  we have done this processing, there is no more nested aggregate!
4134
 
4135
      if Packed_Array_Aggregate_Handled (N) then
4136
         return;
4137
      end if;
4138
 
4139
      --  At this point we try to convert to positional form
4140
 
4141
      Convert_To_Positional (N);
4142
 
4143
      --  if the result is no longer an aggregate (e.g. it may be a string
4144
      --  literal, or a temporary which has the needed value), then we are
4145
      --  done, since there is no longer a nested aggregate.
4146
 
4147
      if Nkind (N) /= N_Aggregate then
4148
         return;
4149
 
4150
      --  We are also done if the result is an analyzed aggregate
4151
      --  This case could use more comments ???
4152
 
4153
      elsif Analyzed (N)
4154
        and then N /= Original_Node (N)
4155
      then
4156
         return;
4157
      end if;
4158
 
4159
      --  Now see if back end processing is possible
4160
 
4161
      if Backend_Processing_Possible (N) then
4162
 
4163
         --  If the aggregate is static but the constraints are not, build
4164
         --  a static subtype for the aggregate, so that Gigi can place it
4165
         --  in static memory. Perform an unchecked_conversion to the non-
4166
         --  static type imposed by the context.
4167
 
4168
         declare
4169
            Itype      : constant Entity_Id := Etype (N);
4170
            Index      : Node_Id;
4171
            Needs_Type : Boolean := False;
4172
 
4173
         begin
4174
            Index := First_Index (Itype);
4175
 
4176
            while Present (Index) loop
4177
               if not Is_Static_Subtype (Etype (Index)) then
4178
                  Needs_Type := True;
4179
                  exit;
4180
               else
4181
                  Next_Index (Index);
4182
               end if;
4183
            end loop;
4184
 
4185
            if Needs_Type then
4186
               Build_Constrained_Type (Positional => True);
4187
               Rewrite (N, Unchecked_Convert_To (Itype, N));
4188
               Analyze (N);
4189
            end if;
4190
         end;
4191
 
4192
         return;
4193
      end if;
4194
 
4195
      --  STEP 3
4196
 
4197
      --  Delay expansion for nested aggregates it will be taken care of
4198
      --  when the parent aggregate is expanded
4199
 
4200
      Parent_Node := Parent (N);
4201
      Parent_Kind := Nkind (Parent_Node);
4202
 
4203
      if Parent_Kind = N_Qualified_Expression then
4204
         Parent_Node := Parent (Parent_Node);
4205
         Parent_Kind := Nkind (Parent_Node);
4206
      end if;
4207
 
4208
      if Parent_Kind = N_Aggregate
4209
        or else Parent_Kind = N_Extension_Aggregate
4210
        or else Parent_Kind = N_Component_Association
4211
        or else (Parent_Kind = N_Object_Declaration
4212
                  and then Controlled_Type (Typ))
4213
        or else (Parent_Kind = N_Assignment_Statement
4214
                  and then Inside_Init_Proc)
4215
      then
4216
         Set_Expansion_Delayed (N);
4217
         return;
4218
      end if;
4219
 
4220
      --  STEP 4
4221
 
4222
      --  Look if in place aggregate expansion is possible
4223
 
4224
      --  For object declarations we build the aggregate in place, unless
4225
      --  the array is bit-packed or the component is controlled.
4226
 
4227
      --  For assignments we do the assignment in place if all the component
4228
      --  associations have compile-time known values. For other cases we
4229
      --  create a temporary. The analysis for safety of on-line assignment
4230
      --  is delicate, i.e. we don't know how to do it fully yet ???
4231
 
4232
      --  For allocators we assign to the designated object in place if the
4233
      --  aggregate meets the same conditions as other in-place assignments.
4234
      --  In this case the aggregate may not come from source but was created
4235
      --  for default initialization, e.g. with Initialize_Scalars.
4236
 
4237
      if Requires_Transient_Scope (Typ) then
4238
         Establish_Transient_Scope
4239
           (N, Sec_Stack => Has_Controlled_Component (Typ));
4240
      end if;
4241
 
4242
      if Has_Default_Init_Comps (N) then
4243
         Maybe_In_Place_OK := False;
4244
 
4245
      elsif Is_Bit_Packed_Array (Typ)
4246
        or else Has_Controlled_Component (Typ)
4247
      then
4248
         Maybe_In_Place_OK := False;
4249
 
4250
      else
4251
         Maybe_In_Place_OK :=
4252
          (Nkind (Parent (N)) = N_Assignment_Statement
4253
             and then Comes_From_Source (N)
4254
             and then In_Place_Assign_OK)
4255
 
4256
          or else
4257
            (Nkind (Parent (Parent (N))) = N_Allocator
4258
              and then In_Place_Assign_OK);
4259
      end if;
4260
 
4261
      if not Has_Default_Init_Comps (N)
4262
         and then Comes_From_Source (Parent (N))
4263
         and then Nkind (Parent (N)) = N_Object_Declaration
4264
         and then not
4265
           Must_Slide (Etype (Defining_Identifier (Parent (N))), Typ)
4266
         and then N = Expression (Parent (N))
4267
         and then not Is_Bit_Packed_Array (Typ)
4268
         and then not Has_Controlled_Component (Typ)
4269
         and then not Has_Address_Clause (Parent (N))
4270
      then
4271
         Tmp := Defining_Identifier (Parent (N));
4272
         Set_No_Initialization (Parent (N));
4273
         Set_Expression (Parent (N), Empty);
4274
 
4275
         --  Set the type of the entity, for use in the analysis of the
4276
         --  subsequent indexed assignments. If the nominal type is not
4277
         --  constrained, build a subtype from the known bounds of the
4278
         --  aggregate. If the declaration has a subtype mark, use it,
4279
         --  otherwise use the itype of the aggregate.
4280
 
4281
         if not Is_Constrained (Typ) then
4282
            Build_Constrained_Type (Positional => False);
4283
         elsif Is_Entity_Name (Object_Definition (Parent (N)))
4284
           and then Is_Constrained (Entity (Object_Definition (Parent (N))))
4285
         then
4286
            Set_Etype (Tmp, Entity (Object_Definition (Parent (N))));
4287
         else
4288
            Set_Size_Known_At_Compile_Time (Typ, False);
4289
            Set_Etype (Tmp, Typ);
4290
         end if;
4291
 
4292
      elsif Maybe_In_Place_OK
4293
        and then Nkind (Parent (N)) = N_Qualified_Expression
4294
        and then Nkind (Parent (Parent (N))) = N_Allocator
4295
      then
4296
         Set_Expansion_Delayed (N);
4297
         return;
4298
 
4299
      --  In the remaining cases  the aggregate is the RHS of an assignment
4300
 
4301
      elsif Maybe_In_Place_OK
4302
        and then Is_Entity_Name (Name (Parent (N)))
4303
      then
4304
         Tmp := Entity (Name (Parent (N)));
4305
 
4306
         if Etype (Tmp) /= Etype (N) then
4307
            Apply_Length_Check (N, Etype (Tmp));
4308
 
4309
            if Nkind (N) = N_Raise_Constraint_Error then
4310
 
4311
               --  Static error, nothing further to expand
4312
 
4313
               return;
4314
            end if;
4315
         end if;
4316
 
4317
      elsif Maybe_In_Place_OK
4318
        and then Nkind (Name (Parent (N))) = N_Explicit_Dereference
4319
        and then Is_Entity_Name (Prefix (Name (Parent (N))))
4320
      then
4321
         Tmp := Name (Parent (N));
4322
 
4323
         if Etype (Tmp) /= Etype (N) then
4324
            Apply_Length_Check (N, Etype (Tmp));
4325
         end if;
4326
 
4327
      elsif Maybe_In_Place_OK
4328
        and then Nkind (Name (Parent (N))) = N_Slice
4329
        and then Safe_Slice_Assignment (N)
4330
      then
4331
         --  Safe_Slice_Assignment rewrites assignment as a loop
4332
 
4333
         return;
4334
 
4335
      --  Step 5
4336
 
4337
      --  In place aggregate expansion is not possible
4338
 
4339
      else
4340
         Maybe_In_Place_OK := False;
4341
         Tmp := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
4342
         Tmp_Decl :=
4343
           Make_Object_Declaration
4344
             (Loc,
4345
              Defining_Identifier => Tmp,
4346
              Object_Definition   => New_Occurrence_Of (Typ, Loc));
4347
         Set_No_Initialization (Tmp_Decl, True);
4348
 
4349
         --  If we are within a loop, the temporary will be pushed on the
4350
         --  stack at each iteration. If the aggregate is the expression for
4351
         --  an allocator, it will be immediately copied to the heap and can
4352
         --  be reclaimed at once. We create a transient scope around the
4353
         --  aggregate for this purpose.
4354
 
4355
         if Ekind (Current_Scope) = E_Loop
4356
           and then Nkind (Parent (Parent (N))) = N_Allocator
4357
         then
4358
            Establish_Transient_Scope (N, False);
4359
         end if;
4360
 
4361
         Insert_Action (N, Tmp_Decl);
4362
      end if;
4363
 
4364
      --  Construct and insert the aggregate code. We can safely suppress
4365
      --  index checks because this code is guaranteed not to raise CE
4366
      --  on index checks. However we should *not* suppress all checks.
4367
 
4368
      declare
4369
         Target : Node_Id;
4370
 
4371
      begin
4372
         if Nkind (Tmp) = N_Defining_Identifier then
4373
            Target := New_Reference_To (Tmp, Loc);
4374
 
4375
         else
4376
 
4377
            if Has_Default_Init_Comps (N) then
4378
 
4379
               --  Ada 2005 (AI-287): This case has not been analyzed???
4380
 
4381
               raise Program_Error;
4382
            end if;
4383
 
4384
            --  Name in assignment is explicit dereference
4385
 
4386
            Target := New_Copy (Tmp);
4387
         end if;
4388
 
4389
         Aggr_Code :=
4390
           Build_Array_Aggr_Code (N,
4391
             Ctype       => Ctyp,
4392
             Index       => First_Index (Typ),
4393
             Into        => Target,
4394
             Scalar_Comp => Is_Scalar_Type (Ctyp));
4395
      end;
4396
 
4397
      if Comes_From_Source (Tmp) then
4398
         Insert_Actions_After (Parent (N), Aggr_Code);
4399
 
4400
      else
4401
         Insert_Actions (N, Aggr_Code);
4402
      end if;
4403
 
4404
      --  If the aggregate has been assigned in place, remove the original
4405
      --  assignment.
4406
 
4407
      if Nkind (Parent (N)) = N_Assignment_Statement
4408
        and then Maybe_In_Place_OK
4409
      then
4410
         Rewrite (Parent (N), Make_Null_Statement (Loc));
4411
 
4412
      elsif Nkind (Parent (N)) /= N_Object_Declaration
4413
        or else Tmp /= Defining_Identifier (Parent (N))
4414
      then
4415
         Rewrite (N, New_Occurrence_Of (Tmp, Loc));
4416
         Analyze_And_Resolve (N, Typ);
4417
      end if;
4418
   end Expand_Array_Aggregate;
4419
 
4420
   ------------------------
4421
   -- Expand_N_Aggregate --
4422
   ------------------------
4423
 
4424
   procedure Expand_N_Aggregate (N : Node_Id) is
4425
   begin
4426
      if Is_Record_Type (Etype (N)) then
4427
         Expand_Record_Aggregate (N);
4428
      else
4429
         Expand_Array_Aggregate (N);
4430
      end if;
4431
 
4432
   exception
4433
      when RE_Not_Available =>
4434
         return;
4435
   end Expand_N_Aggregate;
4436
 
4437
   ----------------------------------
4438
   -- Expand_N_Extension_Aggregate --
4439
   ----------------------------------
4440
 
4441
   --  If the ancestor part is an expression, add a component association for
4442
   --  the parent field. If the type of the ancestor part is not the direct
4443
   --  parent of the expected type,  build recursively the needed ancestors.
4444
   --  If the ancestor part is a subtype_mark, replace aggregate with a decla-
4445
   --  ration for a temporary of the expected type, followed by individual
4446
   --  assignments to the given components.
4447
 
4448
   procedure Expand_N_Extension_Aggregate (N : Node_Id) is
4449
      Loc : constant Source_Ptr := Sloc  (N);
4450
      A   : constant Node_Id    := Ancestor_Part (N);
4451
      Typ : constant Entity_Id  := Etype (N);
4452
 
4453
   begin
4454
      --  If the ancestor is a subtype mark, an init proc must be called
4455
      --  on the resulting object which thus has to be materialized in
4456
      --  the front-end
4457
 
4458
      if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
4459
         Convert_To_Assignments (N, Typ);
4460
 
4461
      --  The extension aggregate is transformed into a record aggregate
4462
      --  of the following form (c1 and c2 are inherited components)
4463
 
4464
      --   (Exp with c3 => a, c4 => b)
4465
      --      ==> (c1 => Exp.c1, c2 => Exp.c2, c1 => a, c2 => b)
4466
 
4467
      else
4468
         Set_Etype (N, Typ);
4469
 
4470
         --  No tag is needed in the case of Java_VM
4471
 
4472
         if Java_VM then
4473
            Expand_Record_Aggregate (N,
4474
              Parent_Expr => A);
4475
         else
4476
            Expand_Record_Aggregate (N,
4477
              Orig_Tag    =>
4478
                New_Occurrence_Of
4479
                  (Node (First_Elmt (Access_Disp_Table (Typ))), Loc),
4480
              Parent_Expr => A);
4481
         end if;
4482
      end if;
4483
 
4484
   exception
4485
      when RE_Not_Available =>
4486
         return;
4487
   end Expand_N_Extension_Aggregate;
4488
 
4489
   -----------------------------
4490
   -- Expand_Record_Aggregate --
4491
   -----------------------------
4492
 
4493
   procedure Expand_Record_Aggregate
4494
     (N           : Node_Id;
4495
      Orig_Tag    : Node_Id := Empty;
4496
      Parent_Expr : Node_Id := Empty)
4497
   is
4498
      Loc      : constant Source_Ptr := Sloc  (N);
4499
      Comps    : constant List_Id    := Component_Associations (N);
4500
      Typ      : constant Entity_Id  := Etype (N);
4501
      Base_Typ : constant Entity_Id  := Base_Type (Typ);
4502
 
4503
      function Has_Delayed_Nested_Aggregate_Or_Tagged_Comps return Boolean;
4504
      --  Checks the presence of a nested aggregate which needs Late_Expansion
4505
      --  or the presence of tagged components which may need tag adjustment.
4506
 
4507
      --------------------------------------------------
4508
      -- Has_Delayed_Nested_Aggregate_Or_Tagged_Comps --
4509
      --------------------------------------------------
4510
 
4511
      function Has_Delayed_Nested_Aggregate_Or_Tagged_Comps return Boolean is
4512
         C      : Node_Id;
4513
         Expr_Q : Node_Id;
4514
 
4515
      begin
4516
         if No (Comps) then
4517
            return False;
4518
         end if;
4519
 
4520
         C := First (Comps);
4521
         while Present (C) loop
4522
            if Nkind (Expression (C)) = N_Qualified_Expression then
4523
               Expr_Q := Expression (Expression (C));
4524
            else
4525
               Expr_Q := Expression (C);
4526
            end if;
4527
 
4528
            --  Return true if the aggregate has any associations for
4529
            --  tagged components that may require tag adjustment.
4530
            --  These are cases where the source expression may have
4531
            --  a tag that could differ from the component tag (e.g.,
4532
            --  can occur for type conversions and formal parameters).
4533
            --  (Tag adjustment is not needed if Java_VM because object
4534
            --  tags are implicit in the JVM.)
4535
 
4536
            if Is_Tagged_Type (Etype (Expr_Q))
4537
              and then (Nkind (Expr_Q) = N_Type_Conversion
4538
                or else (Is_Entity_Name (Expr_Q)
4539
                          and then Ekind (Entity (Expr_Q)) in Formal_Kind))
4540
              and then not Java_VM
4541
            then
4542
               return True;
4543
            end if;
4544
 
4545
            if Is_Delayed_Aggregate (Expr_Q) then
4546
               return True;
4547
            end if;
4548
 
4549
            Next (C);
4550
         end loop;
4551
 
4552
         return False;
4553
      end Has_Delayed_Nested_Aggregate_Or_Tagged_Comps;
4554
 
4555
      --  Remaining Expand_Record_Aggregate variables
4556
 
4557
      Tag_Value : Node_Id;
4558
      Comp      : Entity_Id;
4559
      New_Comp  : Node_Id;
4560
 
4561
   --  Start of processing for Expand_Record_Aggregate
4562
 
4563
   begin
4564
      --  If the aggregate is to be assigned to an atomic variable, we
4565
      --  have to prevent a piecemeal assignment even if the aggregate
4566
      --  is to be expanded. We create a temporary for the aggregate, and
4567
      --  assign the temporary instead, so that the back end can generate
4568
      --  an atomic move for it.
4569
 
4570
      if Is_Atomic (Typ)
4571
        and then (Nkind (Parent (N)) = N_Object_Declaration
4572
                    or else Nkind (Parent (N)) = N_Assignment_Statement)
4573
        and then Comes_From_Source (Parent (N))
4574
      then
4575
         Expand_Atomic_Aggregate (N, Typ);
4576
         return;
4577
      end if;
4578
 
4579
      --  Gigi doesn't handle properly temporaries of variable size
4580
      --  so we generate it in the front-end
4581
 
4582
      if not Size_Known_At_Compile_Time (Typ) then
4583
         Convert_To_Assignments (N, Typ);
4584
 
4585
      --  Temporaries for controlled aggregates need to be attached to a
4586
      --  final chain in order to be properly finalized, so it has to
4587
      --  be created in the front-end
4588
 
4589
      elsif Is_Controlled (Typ)
4590
        or else Has_Controlled_Component (Base_Type (Typ))
4591
      then
4592
         Convert_To_Assignments (N, Typ);
4593
 
4594
         --  Ada 2005 (AI-287): In case of default initialized components we
4595
         --  convert the aggregate into assignments.
4596
 
4597
      elsif Has_Default_Init_Comps (N) then
4598
         Convert_To_Assignments (N, Typ);
4599
 
4600
      elsif Has_Delayed_Nested_Aggregate_Or_Tagged_Comps then
4601
         Convert_To_Assignments (N, Typ);
4602
 
4603
      --  If an ancestor is private, some components are not inherited and
4604
      --  we cannot expand into a record aggregate
4605
 
4606
      elsif Has_Private_Ancestor (Typ) then
4607
         Convert_To_Assignments (N, Typ);
4608
 
4609
      --  ??? The following was done to compile fxacc00.ads in the ACVCs. Gigi
4610
      --  is not able to handle the aggregate for Late_Request.
4611
 
4612
      elsif Is_Tagged_Type (Typ) and then Has_Discriminants (Typ) then
4613
         Convert_To_Assignments (N, Typ);
4614
 
4615
      --  If some components are mutable, the size of the aggregate component
4616
      --  may be disctinct from the default size of the type component, so
4617
      --  we need to expand to insure that the back-end copies the proper
4618
      --  size of the data.
4619
 
4620
      elsif Has_Mutable_Components (Typ) then
4621
         Convert_To_Assignments (N, Typ);
4622
 
4623
      --  If the type involved has any non-bit aligned components, then
4624
      --  we are not sure that the back end can handle this case correctly.
4625
 
4626
      elsif Type_May_Have_Bit_Aligned_Components (Typ) then
4627
         Convert_To_Assignments (N, Typ);
4628
 
4629
      --  In all other cases we generate a proper aggregate that
4630
      --  can be handled by gigi.
4631
 
4632
      else
4633
         --  If no discriminants, nothing special to do
4634
 
4635
         if not Has_Discriminants (Typ) then
4636
            null;
4637
 
4638
         --  Case of discriminants present
4639
 
4640
         elsif Is_Derived_Type (Typ) then
4641
 
4642
            --  For untagged types,  non-stored discriminants are replaced
4643
            --  with stored discriminants, which are the ones that gigi uses
4644
            --  to describe the type and its components.
4645
 
4646
            Generate_Aggregate_For_Derived_Type : declare
4647
               Constraints  : constant List_Id := New_List;
4648
               First_Comp   : Node_Id;
4649
               Discriminant : Entity_Id;
4650
               Decl         : Node_Id;
4651
               Num_Disc     : Int := 0;
4652
               Num_Gird     : Int := 0;
4653
 
4654
               procedure Prepend_Stored_Values (T : Entity_Id);
4655
               --  Scan the list of stored discriminants of the type, and
4656
               --  add their values to the aggregate being built.
4657
 
4658
               ---------------------------
4659
               -- Prepend_Stored_Values --
4660
               ---------------------------
4661
 
4662
               procedure Prepend_Stored_Values (T : Entity_Id) is
4663
               begin
4664
                  Discriminant := First_Stored_Discriminant (T);
4665
 
4666
                  while Present (Discriminant) loop
4667
                     New_Comp :=
4668
                       Make_Component_Association (Loc,
4669
                         Choices    =>
4670
                           New_List (New_Occurrence_Of (Discriminant, Loc)),
4671
 
4672
                         Expression =>
4673
                           New_Copy_Tree (
4674
                             Get_Discriminant_Value (
4675
                                 Discriminant,
4676
                                 Typ,
4677
                                 Discriminant_Constraint (Typ))));
4678
 
4679
                     if No (First_Comp) then
4680
                        Prepend_To (Component_Associations (N), New_Comp);
4681
                     else
4682
                        Insert_After (First_Comp, New_Comp);
4683
                     end if;
4684
 
4685
                     First_Comp := New_Comp;
4686
                     Next_Stored_Discriminant (Discriminant);
4687
                  end loop;
4688
               end Prepend_Stored_Values;
4689
 
4690
            --  Start of processing for Generate_Aggregate_For_Derived_Type
4691
 
4692
            begin
4693
               --  Remove the associations for the  discriminant of
4694
               --  the derived type.
4695
 
4696
               First_Comp := First (Component_Associations (N));
4697
 
4698
               while Present (First_Comp) loop
4699
                  Comp := First_Comp;
4700
                  Next (First_Comp);
4701
 
4702
                  if Ekind (Entity (First (Choices (Comp)))) =
4703
                    E_Discriminant
4704
                  then
4705
                     Remove (Comp);
4706
                     Num_Disc := Num_Disc + 1;
4707
                  end if;
4708
               end loop;
4709
 
4710
               --  Insert stored discriminant associations in the correct
4711
               --  order. If there are more stored discriminants than new
4712
               --  discriminants, there is at least one new discriminant
4713
               --  that constrains more than one of the stored discriminants.
4714
               --  In this case we need to construct a proper subtype of
4715
               --  the parent type, in order to supply values to all the
4716
               --  components. Otherwise there is one-one correspondence
4717
               --  between the constraints and the stored discriminants.
4718
 
4719
               First_Comp := Empty;
4720
 
4721
               Discriminant := First_Stored_Discriminant (Base_Type (Typ));
4722
 
4723
               while Present (Discriminant) loop
4724
                  Num_Gird := Num_Gird + 1;
4725
                  Next_Stored_Discriminant (Discriminant);
4726
               end loop;
4727
 
4728
               --  Case of more stored discriminants than new discriminants
4729
 
4730
               if Num_Gird > Num_Disc then
4731
 
4732
                  --  Create a proper subtype of the parent type, which is
4733
                  --  the proper implementation type for the aggregate, and
4734
                  --  convert it to the intended target type.
4735
 
4736
                  Discriminant := First_Stored_Discriminant (Base_Type (Typ));
4737
 
4738
                  while Present (Discriminant) loop
4739
                     New_Comp :=
4740
                       New_Copy_Tree (
4741
                         Get_Discriminant_Value (
4742
                             Discriminant,
4743
                             Typ,
4744
                             Discriminant_Constraint (Typ)));
4745
                     Append (New_Comp, Constraints);
4746
                     Next_Stored_Discriminant (Discriminant);
4747
                  end loop;
4748
 
4749
                  Decl :=
4750
                    Make_Subtype_Declaration (Loc,
4751
                      Defining_Identifier =>
4752
                         Make_Defining_Identifier (Loc,
4753
                            New_Internal_Name ('T')),
4754
                      Subtype_Indication =>
4755
                        Make_Subtype_Indication (Loc,
4756
                          Subtype_Mark =>
4757
                            New_Occurrence_Of (Etype (Base_Type (Typ)), Loc),
4758
                          Constraint =>
4759
                            Make_Index_Or_Discriminant_Constraint
4760
                              (Loc, Constraints)));
4761
 
4762
                  Insert_Action (N, Decl);
4763
                  Prepend_Stored_Values (Base_Type (Typ));
4764
 
4765
                  Set_Etype (N, Defining_Identifier (Decl));
4766
                  Set_Analyzed (N);
4767
 
4768
                  Rewrite (N, Unchecked_Convert_To (Typ, N));
4769
                  Analyze (N);
4770
 
4771
               --  Case where we do not have fewer new discriminants than
4772
               --  stored discriminants, so in this case we can simply
4773
               --  use the stored discriminants of the subtype.
4774
 
4775
               else
4776
                  Prepend_Stored_Values (Typ);
4777
               end if;
4778
            end Generate_Aggregate_For_Derived_Type;
4779
         end if;
4780
 
4781
         if Is_Tagged_Type (Typ) then
4782
 
4783
            --  The tagged case, _parent and _tag component must be created
4784
 
4785
            --  Reset null_present unconditionally. tagged records always have
4786
            --  at least one field (the tag or the parent)
4787
 
4788
            Set_Null_Record_Present (N, False);
4789
 
4790
            --  When the current aggregate comes from the expansion of an
4791
            --  extension aggregate, the parent expr is replaced by an
4792
            --  aggregate formed by selected components of this expr
4793
 
4794
            if Present (Parent_Expr)
4795
              and then Is_Empty_List (Comps)
4796
            then
4797
               Comp := First_Entity (Typ);
4798
               while Present (Comp) loop
4799
 
4800
                  --  Skip all entities that aren't discriminants or components
4801
 
4802
                  if Ekind (Comp) /= E_Discriminant
4803
                    and then Ekind (Comp) /= E_Component
4804
                  then
4805
                     null;
4806
 
4807
                  --  Skip all expander-generated components
4808
 
4809
                  elsif
4810
                    not Comes_From_Source (Original_Record_Component (Comp))
4811
                  then
4812
                     null;
4813
 
4814
                  else
4815
                     New_Comp :=
4816
                       Make_Selected_Component (Loc,
4817
                         Prefix =>
4818
                           Unchecked_Convert_To (Typ,
4819
                             Duplicate_Subexpr (Parent_Expr, True)),
4820
 
4821
                         Selector_Name => New_Occurrence_Of (Comp, Loc));
4822
 
4823
                     Append_To (Comps,
4824
                       Make_Component_Association (Loc,
4825
                         Choices    =>
4826
                           New_List (New_Occurrence_Of (Comp, Loc)),
4827
                         Expression =>
4828
                           New_Comp));
4829
 
4830
                     Analyze_And_Resolve (New_Comp, Etype (Comp));
4831
                  end if;
4832
 
4833
                  Next_Entity (Comp);
4834
               end loop;
4835
            end if;
4836
 
4837
            --  Compute the value for the Tag now, if the type is a root it
4838
            --  will be included in the aggregate right away, otherwise it will
4839
            --  be propagated to the parent aggregate
4840
 
4841
            if Present (Orig_Tag) then
4842
               Tag_Value := Orig_Tag;
4843
            elsif Java_VM then
4844
               Tag_Value := Empty;
4845
            else
4846
               Tag_Value :=
4847
                 New_Occurrence_Of
4848
                   (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
4849
            end if;
4850
 
4851
            --  For a derived type, an aggregate for the parent is formed with
4852
            --  all the inherited components.
4853
 
4854
            if Is_Derived_Type (Typ) then
4855
 
4856
               declare
4857
                  First_Comp   : Node_Id;
4858
                  Parent_Comps : List_Id;
4859
                  Parent_Aggr  : Node_Id;
4860
                  Parent_Name  : Node_Id;
4861
 
4862
               begin
4863
                  --  Remove the inherited component association from the
4864
                  --  aggregate and store them in the parent aggregate
4865
 
4866
                  First_Comp := First (Component_Associations (N));
4867
                  Parent_Comps := New_List;
4868
 
4869
                  while Present (First_Comp)
4870
                    and then Scope (Original_Record_Component (
4871
                            Entity (First (Choices (First_Comp))))) /= Base_Typ
4872
                  loop
4873
                     Comp := First_Comp;
4874
                     Next (First_Comp);
4875
                     Remove (Comp);
4876
                     Append (Comp, Parent_Comps);
4877
                  end loop;
4878
 
4879
                  Parent_Aggr := Make_Aggregate (Loc,
4880
                    Component_Associations => Parent_Comps);
4881
                  Set_Etype (Parent_Aggr, Etype (Base_Type (Typ)));
4882
 
4883
                  --  Find the _parent component
4884
 
4885
                  Comp := First_Component (Typ);
4886
                  while Chars (Comp) /= Name_uParent loop
4887
                     Comp := Next_Component (Comp);
4888
                  end loop;
4889
 
4890
                  Parent_Name := New_Occurrence_Of (Comp, Loc);
4891
 
4892
                  --  Insert the parent aggregate
4893
 
4894
                  Prepend_To (Component_Associations (N),
4895
                    Make_Component_Association (Loc,
4896
                      Choices    => New_List (Parent_Name),
4897
                      Expression => Parent_Aggr));
4898
 
4899
                  --  Expand recursively the parent propagating the right Tag
4900
 
4901
                  Expand_Record_Aggregate (
4902
                    Parent_Aggr, Tag_Value, Parent_Expr);
4903
               end;
4904
 
4905
            --  For a root type, the tag component is added (unless compiling
4906
            --  for the Java VM, where tags are implicit).
4907
 
4908
            elsif not Java_VM then
4909
               declare
4910
                  Tag_Name  : constant Node_Id :=
4911
                                New_Occurrence_Of
4912
                                  (First_Tag_Component (Typ), Loc);
4913
                  Typ_Tag   : constant Entity_Id := RTE (RE_Tag);
4914
                  Conv_Node : constant Node_Id :=
4915
                                Unchecked_Convert_To (Typ_Tag, Tag_Value);
4916
 
4917
               begin
4918
                  Set_Etype (Conv_Node, Typ_Tag);
4919
                  Prepend_To (Component_Associations (N),
4920
                    Make_Component_Association (Loc,
4921
                      Choices    => New_List (Tag_Name),
4922
                      Expression => Conv_Node));
4923
               end;
4924
            end if;
4925
         end if;
4926
      end if;
4927
   end Expand_Record_Aggregate;
4928
 
4929
   ----------------------------
4930
   -- Has_Default_Init_Comps --
4931
   ----------------------------
4932
 
4933
   function Has_Default_Init_Comps (N : Node_Id) return Boolean is
4934
      Comps : constant List_Id := Component_Associations (N);
4935
      C     : Node_Id;
4936
      Expr  : Node_Id;
4937
   begin
4938
      pragma Assert (Nkind (N) = N_Aggregate
4939
         or else Nkind (N) = N_Extension_Aggregate);
4940
 
4941
      if No (Comps) then
4942
         return False;
4943
      end if;
4944
 
4945
      --  Check if any direct component has default initialized components
4946
 
4947
      C := First (Comps);
4948
      while Present (C) loop
4949
         if Box_Present (C) then
4950
            return True;
4951
         end if;
4952
 
4953
         Next (C);
4954
      end loop;
4955
 
4956
      --  Recursive call in case of aggregate expression
4957
 
4958
      C := First (Comps);
4959
      while Present (C) loop
4960
         Expr := Expression (C);
4961
 
4962
         if Present (Expr)
4963
           and then (Nkind (Expr) = N_Aggregate
4964
                     or else Nkind (Expr) = N_Extension_Aggregate)
4965
           and then Has_Default_Init_Comps (Expr)
4966
         then
4967
            return True;
4968
         end if;
4969
 
4970
         Next (C);
4971
      end loop;
4972
 
4973
      return False;
4974
   end Has_Default_Init_Comps;
4975
 
4976
   --------------------------
4977
   -- Is_Delayed_Aggregate --
4978
   --------------------------
4979
 
4980
   function Is_Delayed_Aggregate (N : Node_Id) return Boolean is
4981
      Node : Node_Id   := N;
4982
      Kind : Node_Kind := Nkind (Node);
4983
 
4984
   begin
4985
      if Kind = N_Qualified_Expression then
4986
         Node := Expression (Node);
4987
         Kind := Nkind (Node);
4988
      end if;
4989
 
4990
      if Kind /= N_Aggregate and then Kind /= N_Extension_Aggregate then
4991
         return False;
4992
      else
4993
         return Expansion_Delayed (Node);
4994
      end if;
4995
   end Is_Delayed_Aggregate;
4996
 
4997
   --------------------
4998
   -- Late_Expansion --
4999
   --------------------
5000
 
5001
   function Late_Expansion
5002
     (N      : Node_Id;
5003
      Typ    : Entity_Id;
5004
      Target : Node_Id;
5005
      Flist  : Node_Id   := Empty;
5006
      Obj    : Entity_Id := Empty) return List_Id
5007
   is
5008
   begin
5009
      if Is_Record_Type (Etype (N)) then
5010
         return Build_Record_Aggr_Code (N, Typ, Target, Flist, Obj);
5011
 
5012
      else pragma Assert (Is_Array_Type (Etype (N)));
5013
         return
5014
           Build_Array_Aggr_Code
5015
             (N           => N,
5016
              Ctype       => Component_Type (Etype (N)),
5017
              Index       => First_Index (Typ),
5018
              Into        => Target,
5019
              Scalar_Comp => Is_Scalar_Type (Component_Type (Typ)),
5020
              Indices     => No_List,
5021
              Flist       => Flist);
5022
      end if;
5023
   end Late_Expansion;
5024
 
5025
   ----------------------------------
5026
   -- Make_OK_Assignment_Statement --
5027
   ----------------------------------
5028
 
5029
   function Make_OK_Assignment_Statement
5030
     (Sloc       : Source_Ptr;
5031
      Name       : Node_Id;
5032
      Expression : Node_Id) return Node_Id
5033
   is
5034
   begin
5035
      Set_Assignment_OK (Name);
5036
      return Make_Assignment_Statement (Sloc, Name, Expression);
5037
   end Make_OK_Assignment_Statement;
5038
 
5039
   -----------------------
5040
   -- Number_Of_Choices --
5041
   -----------------------
5042
 
5043
   function Number_Of_Choices (N : Node_Id) return Nat is
5044
      Assoc  : Node_Id;
5045
      Choice : Node_Id;
5046
 
5047
      Nb_Choices : Nat := 0;
5048
 
5049
   begin
5050
      if Present (Expressions (N)) then
5051
         return 0;
5052
      end if;
5053
 
5054
      Assoc := First (Component_Associations (N));
5055
      while Present (Assoc) loop
5056
 
5057
         Choice := First (Choices (Assoc));
5058
         while Present (Choice) loop
5059
 
5060
            if Nkind (Choice) /= N_Others_Choice then
5061
               Nb_Choices := Nb_Choices + 1;
5062
            end if;
5063
 
5064
            Next (Choice);
5065
         end loop;
5066
 
5067
         Next (Assoc);
5068
      end loop;
5069
 
5070
      return Nb_Choices;
5071
   end Number_Of_Choices;
5072
 
5073
   ------------------------------------
5074
   -- Packed_Array_Aggregate_Handled --
5075
   ------------------------------------
5076
 
5077
   --  The current version of this procedure will handle at compile time
5078
   --  any array aggregate that meets these conditions:
5079
 
5080
   --    One dimensional, bit packed
5081
   --    Underlying packed type is modular type
5082
   --    Bounds are within 32-bit Int range
5083
   --    All bounds and values are static
5084
 
5085
   function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean is
5086
      Loc  : constant Source_Ptr := Sloc (N);
5087
      Typ  : constant Entity_Id  := Etype (N);
5088
      Ctyp : constant Entity_Id  := Component_Type (Typ);
5089
 
5090
      Not_Handled : exception;
5091
      --  Exception raised if this aggregate cannot be handled
5092
 
5093
   begin
5094
      --  For now, handle only one dimensional bit packed arrays
5095
 
5096
      if not Is_Bit_Packed_Array (Typ)
5097
        or else Number_Dimensions (Typ) > 1
5098
        or else not Is_Modular_Integer_Type (Packed_Array_Type (Typ))
5099
      then
5100
         return False;
5101
      end if;
5102
 
5103
      declare
5104
         Csiz  : constant Nat := UI_To_Int (Component_Size (Typ));
5105
 
5106
         Lo : Node_Id;
5107
         Hi : Node_Id;
5108
         --  Bounds of index type
5109
 
5110
         Lob : Uint;
5111
         Hib : Uint;
5112
         --  Values of bounds if compile time known
5113
 
5114
         function Get_Component_Val (N : Node_Id) return Uint;
5115
         --  Given a expression value N of the component type Ctyp, returns
5116
         --  A value of Csiz (component size) bits representing this value.
5117
         --  If the value is non-static or any other reason exists why the
5118
         --  value cannot be returned, then Not_Handled is raised.
5119
 
5120
         -----------------------
5121
         -- Get_Component_Val --
5122
         -----------------------
5123
 
5124
         function Get_Component_Val (N : Node_Id) return Uint is
5125
            Val  : Uint;
5126
 
5127
         begin
5128
            --  We have to analyze the expression here before doing any further
5129
            --  processing here. The analysis of such expressions is deferred
5130
            --  till expansion to prevent some problems of premature analysis.
5131
 
5132
            Analyze_And_Resolve (N, Ctyp);
5133
 
5134
            --  Must have a compile time value. String literals have to
5135
            --  be converted into temporaries as well, because they cannot
5136
            --  easily be converted into their bit representation.
5137
 
5138
            if not Compile_Time_Known_Value (N)
5139
              or else Nkind (N) = N_String_Literal
5140
            then
5141
               raise Not_Handled;
5142
            end if;
5143
 
5144
            Val := Expr_Rep_Value (N);
5145
 
5146
            --  Adjust for bias, and strip proper number of bits
5147
 
5148
            if Has_Biased_Representation (Ctyp) then
5149
               Val := Val - Expr_Value (Type_Low_Bound (Ctyp));
5150
            end if;
5151
 
5152
            return Val mod Uint_2 ** Csiz;
5153
         end Get_Component_Val;
5154
 
5155
      --  Here we know we have a one dimensional bit packed array
5156
 
5157
      begin
5158
         Get_Index_Bounds (First_Index (Typ), Lo, Hi);
5159
 
5160
         --  Cannot do anything if bounds are dynamic
5161
 
5162
         if not Compile_Time_Known_Value (Lo)
5163
              or else
5164
            not Compile_Time_Known_Value (Hi)
5165
         then
5166
            return False;
5167
         end if;
5168
 
5169
         --  Or are silly out of range of int bounds
5170
 
5171
         Lob := Expr_Value (Lo);
5172
         Hib := Expr_Value (Hi);
5173
 
5174
         if not UI_Is_In_Int_Range (Lob)
5175
              or else
5176
            not UI_Is_In_Int_Range (Hib)
5177
         then
5178
            return False;
5179
         end if;
5180
 
5181
         --  At this stage we have a suitable aggregate for handling
5182
         --  at compile time (the only remaining checks, are that the
5183
         --  values of expressions in the aggregate are compile time
5184
         --  known (check performed by Get_Component_Val), and that
5185
         --  any subtypes or ranges are statically known.
5186
 
5187
         --  If the aggregate is not fully positional at this stage,
5188
         --  then convert it to positional form. Either this will fail,
5189
         --  in which case we can do nothing, or it will succeed, in
5190
         --  which case we have succeeded in handling the aggregate,
5191
         --  or it will stay an aggregate, in which case we have failed
5192
         --  to handle this case.
5193
 
5194
         if Present (Component_Associations (N)) then
5195
            Convert_To_Positional
5196
             (N, Max_Others_Replicate => 64, Handle_Bit_Packed => True);
5197
            return Nkind (N) /= N_Aggregate;
5198
         end if;
5199
 
5200
         --  Otherwise we are all positional, so convert to proper value
5201
 
5202
         declare
5203
            Lov : constant Int := UI_To_Int (Lob);
5204
            Hiv : constant Int := UI_To_Int (Hib);
5205
 
5206
            Len : constant Nat := Int'Max (0, Hiv - Lov + 1);
5207
            --  The length of the array (number of elements)
5208
 
5209
            Aggregate_Val : Uint;
5210
            --  Value of aggregate. The value is set in the low order
5211
            --  bits of this value. For the little-endian case, the
5212
            --  values are stored from low-order to high-order and
5213
            --  for the big-endian case the values are stored from
5214
            --  high-order to low-order. Note that gigi will take care
5215
            --  of the conversions to left justify the value in the big
5216
            --  endian case (because of left justified modular type
5217
            --  processing), so we do not have to worry about that here.
5218
 
5219
            Lit : Node_Id;
5220
            --  Integer literal for resulting constructed value
5221
 
5222
            Shift : Nat;
5223
            --  Shift count from low order for next value
5224
 
5225
            Incr : Int;
5226
            --  Shift increment for loop
5227
 
5228
            Expr : Node_Id;
5229
            --  Next expression from positional parameters of aggregate
5230
 
5231
         begin
5232
            --  For little endian, we fill up the low order bits of the
5233
            --  target value. For big endian we fill up the high order
5234
            --  bits of the target value (which is a left justified
5235
            --  modular value).
5236
 
5237
            if Bytes_Big_Endian xor Debug_Flag_8 then
5238
               Shift := Csiz * (Len - 1);
5239
               Incr  := -Csiz;
5240
            else
5241
               Shift := 0;
5242
               Incr  := +Csiz;
5243
            end if;
5244
 
5245
            --  Loop to set the values
5246
 
5247
            if Len = 0 then
5248
               Aggregate_Val := Uint_0;
5249
            else
5250
               Expr := First (Expressions (N));
5251
               Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;
5252
 
5253
               for J in 2 .. Len loop
5254
                  Shift := Shift + Incr;
5255
                  Next (Expr);
5256
                  Aggregate_Val :=
5257
                    Aggregate_Val + Get_Component_Val (Expr) * Uint_2 ** Shift;
5258
               end loop;
5259
            end if;
5260
 
5261
            --  Now we can rewrite with the proper value
5262
 
5263
            Lit :=
5264
              Make_Integer_Literal (Loc,
5265
                Intval => Aggregate_Val);
5266
            Set_Print_In_Hex (Lit);
5267
 
5268
            --  Construct the expression using this literal. Note that it is
5269
            --  important to qualify the literal with its proper modular type
5270
            --  since universal integer does not have the required range and
5271
            --  also this is a left justified modular type, which is important
5272
            --  in the big-endian case.
5273
 
5274
            Rewrite (N,
5275
              Unchecked_Convert_To (Typ,
5276
                Make_Qualified_Expression (Loc,
5277
                  Subtype_Mark =>
5278
                    New_Occurrence_Of (Packed_Array_Type (Typ), Loc),
5279
                  Expression   => Lit)));
5280
 
5281
            Analyze_And_Resolve (N, Typ);
5282
            return True;
5283
         end;
5284
      end;
5285
 
5286
   exception
5287
      when Not_Handled =>
5288
         return False;
5289
   end Packed_Array_Aggregate_Handled;
5290
 
5291
   ----------------------------
5292
   -- Has_Mutable_Components --
5293
   ----------------------------
5294
 
5295
   function Has_Mutable_Components (Typ : Entity_Id) return Boolean is
5296
      Comp : Entity_Id;
5297
 
5298
   begin
5299
      Comp := First_Component (Typ);
5300
 
5301
      while Present (Comp) loop
5302
         if Is_Record_Type (Etype (Comp))
5303
           and then Has_Discriminants (Etype (Comp))
5304
           and then not Is_Constrained (Etype (Comp))
5305
         then
5306
            return True;
5307
         end if;
5308
 
5309
         Next_Component (Comp);
5310
      end loop;
5311
 
5312
      return False;
5313
   end Has_Mutable_Components;
5314
 
5315
   ------------------------------
5316
   -- Initialize_Discriminants --
5317
   ------------------------------
5318
 
5319
   procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id) is
5320
      Loc  : constant Source_Ptr := Sloc (N);
5321
      Bas  : constant Entity_Id  := Base_Type (Typ);
5322
      Par  : constant Entity_Id  := Etype (Bas);
5323
      Decl : constant Node_Id    := Parent (Par);
5324
      Ref  : Node_Id;
5325
 
5326
   begin
5327
      if Is_Tagged_Type (Bas)
5328
        and then Is_Derived_Type (Bas)
5329
        and then Has_Discriminants (Par)
5330
        and then Has_Discriminants (Bas)
5331
        and then Number_Discriminants (Bas) /= Number_Discriminants (Par)
5332
        and then Nkind (Decl) = N_Full_Type_Declaration
5333
        and then Nkind (Type_Definition (Decl)) = N_Record_Definition
5334
        and then Present
5335
          (Variant_Part (Component_List (Type_Definition (Decl))))
5336
        and then Nkind (N) /= N_Extension_Aggregate
5337
      then
5338
 
5339
         --   Call init proc to set discriminants.
5340
         --   There should eventually be a special procedure for this ???
5341
 
5342
         Ref := New_Reference_To (Defining_Identifier (N), Loc);
5343
         Insert_Actions_After (N,
5344
           Build_Initialization_Call (Sloc (N), Ref, Typ));
5345
      end if;
5346
   end Initialize_Discriminants;
5347
 
5348
   ----------------
5349
   -- Must_Slide --
5350
   ----------------
5351
 
5352
   function Must_Slide
5353
     (Obj_Type : Entity_Id;
5354
      Typ      : Entity_Id) return Boolean
5355
   is
5356
      L1, L2, H1, H2 : Node_Id;
5357
   begin
5358
      --  No sliding if the type of the object is not established yet, if
5359
      --  it is an unconstrained type whose actual subtype comes from the
5360
      --  aggregate, or if the two types are identical.
5361
 
5362
      if not Is_Array_Type (Obj_Type) then
5363
         return False;
5364
 
5365
      elsif not Is_Constrained (Obj_Type) then
5366
         return False;
5367
 
5368
      elsif Typ = Obj_Type then
5369
         return False;
5370
 
5371
      else
5372
         --  Sliding can only occur along the first dimension
5373
 
5374
         Get_Index_Bounds (First_Index (Typ), L1, H1);
5375
         Get_Index_Bounds (First_Index (Obj_Type), L2, H2);
5376
 
5377
         if not Is_Static_Expression (L1)
5378
           or else not Is_Static_Expression (L2)
5379
           or else not Is_Static_Expression (H1)
5380
           or else not Is_Static_Expression (H2)
5381
         then
5382
            return False;
5383
         else
5384
            return Expr_Value (L1) /= Expr_Value (L2)
5385
              or else Expr_Value (H1) /= Expr_Value (H2);
5386
         end if;
5387
      end if;
5388
   end Must_Slide;
5389
 
5390
   ---------------------------
5391
   -- Safe_Slice_Assignment --
5392
   ---------------------------
5393
 
5394
   function Safe_Slice_Assignment (N : Node_Id) return Boolean is
5395
      Loc        : constant Source_Ptr := Sloc (Parent (N));
5396
      Pref       : constant Node_Id    := Prefix (Name (Parent (N)));
5397
      Range_Node : constant Node_Id    := Discrete_Range (Name (Parent (N)));
5398
      Expr       : Node_Id;
5399
      L_J        : Entity_Id;
5400
      L_Iter     : Node_Id;
5401
      L_Body     : Node_Id;
5402
      Stat       : Node_Id;
5403
 
5404
   begin
5405
      --  Generate: for J in Range loop Pref (J) := Expr; end loop;
5406
 
5407
      if Comes_From_Source (N)
5408
        and then No (Expressions (N))
5409
        and then Nkind (First (Choices (First (Component_Associations (N)))))
5410
                   = N_Others_Choice
5411
      then
5412
         Expr :=
5413
           Expression (First (Component_Associations (N)));
5414
         L_J := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
5415
 
5416
         L_Iter :=
5417
           Make_Iteration_Scheme (Loc,
5418
             Loop_Parameter_Specification =>
5419
               Make_Loop_Parameter_Specification
5420
                 (Loc,
5421
                  Defining_Identifier         => L_J,
5422
                  Discrete_Subtype_Definition => Relocate_Node (Range_Node)));
5423
 
5424
         L_Body :=
5425
           Make_Assignment_Statement (Loc,
5426
              Name =>
5427
                Make_Indexed_Component (Loc,
5428
                  Prefix      => Relocate_Node (Pref),
5429
                  Expressions => New_List (New_Occurrence_Of (L_J, Loc))),
5430
               Expression => Relocate_Node (Expr));
5431
 
5432
         --  Construct the final loop
5433
 
5434
         Stat :=
5435
           Make_Implicit_Loop_Statement
5436
             (Node             => Parent (N),
5437
              Identifier       => Empty,
5438
              Iteration_Scheme => L_Iter,
5439
              Statements       => New_List (L_Body));
5440
 
5441
         --  Set type of aggregate to be type of lhs in assignment,
5442
         --  to suppress redundant length checks.
5443
 
5444
         Set_Etype (N, Etype (Name (Parent (N))));
5445
 
5446
         Rewrite (Parent (N), Stat);
5447
         Analyze (Parent (N));
5448
         return True;
5449
 
5450
      else
5451
         return False;
5452
      end if;
5453
   end Safe_Slice_Assignment;
5454
 
5455
   ---------------------
5456
   -- Sort_Case_Table --
5457
   ---------------------
5458
 
5459
   procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
5460
      L : constant Int := Case_Table'First;
5461
      U : constant Int := Case_Table'Last;
5462
      K : Int;
5463
      J : Int;
5464
      T : Case_Bounds;
5465
 
5466
   begin
5467
      K := L;
5468
 
5469
      while K /= U loop
5470
         T := Case_Table (K + 1);
5471
         J := K + 1;
5472
 
5473
         while J /= L
5474
           and then Expr_Value (Case_Table (J - 1).Choice_Lo) >
5475
                    Expr_Value (T.Choice_Lo)
5476
         loop
5477
            Case_Table (J) := Case_Table (J - 1);
5478
            J := J - 1;
5479
         end loop;
5480
 
5481
         Case_Table (J) := T;
5482
         K := K + 1;
5483
      end loop;
5484
   end Sort_Case_Table;
5485
 
5486
end Exp_Aggr;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.