[multiple changes]
[platform/upstream/gcc.git] / gcc / ada / exp_ch3.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              E X P _ C H 3                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2004 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,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, 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 Einfo;    use Einfo;
30 with Elists;   use Elists;
31 with Errout;   use Errout;
32 with Exp_Aggr; use Exp_Aggr;
33 with Exp_Ch4;  use Exp_Ch4;
34 with Exp_Ch7;  use Exp_Ch7;
35 with Exp_Ch9;  use Exp_Ch9;
36 with Exp_Ch11; use Exp_Ch11;
37 with Exp_Disp; use Exp_Disp;
38 with Exp_Dist; use Exp_Dist;
39 with Exp_Smem; use Exp_Smem;
40 with Exp_Strm; use Exp_Strm;
41 with Exp_Tss;  use Exp_Tss;
42 with Exp_Util; use Exp_Util;
43 with Freeze;   use Freeze;
44 with Hostparm; use Hostparm;
45 with Nlists;   use Nlists;
46 with Nmake;    use Nmake;
47 with Opt;      use Opt;
48 with Restrict; use Restrict;
49 with Rtsfind;  use Rtsfind;
50 with Sem;      use Sem;
51 with Sem_Ch3;  use Sem_Ch3;
52 with Sem_Ch8;  use Sem_Ch8;
53 with Sem_Eval; use Sem_Eval;
54 with Sem_Mech; use Sem_Mech;
55 with Sem_Res;  use Sem_Res;
56 with Sem_Util; use Sem_Util;
57 with Sinfo;    use Sinfo;
58 with Stand;    use Stand;
59 with Stringt;  use Stringt;
60 with Snames;   use Snames;
61 with Tbuild;   use Tbuild;
62 with Ttypes;   use Ttypes;
63 with Uintp;    use Uintp;
64 with Validsw;  use Validsw;
65
66 package body Exp_Ch3 is
67
68    -----------------------
69    -- Local Subprograms --
70    -----------------------
71
72    procedure Adjust_Discriminants (Rtype : Entity_Id);
73    --  This is used when freezing a record type. It attempts to construct
74    --  more restrictive subtypes for discriminants so that the max size of
75    --  the record can be calculated more accurately. See the body of this
76    --  procedure for details.
77
78    procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id);
79    --  Build initialization procedure for given array type. Nod is a node
80    --  used for attachment of any actions required in its construction.
81    --  It also supplies the source location used for the procedure.
82
83    procedure Build_Class_Wide_Master (T : Entity_Id);
84    --  for access to class-wide limited types we must build a task master
85    --  because some subsequent extension may add a task component. To avoid
86    --  bringing in the tasking run-time whenever an access-to-class-wide
87    --  limited type is used, we use the soft-link mechanism and add a level
88    --  of indirection to calls to routines that manipulate Master_Ids.
89
90    function Build_Discriminant_Formals
91      (Rec_Id : Entity_Id;
92       Use_Dl : Boolean)
93       return   List_Id;
94    --  This function uses the discriminants of a type to build a list of
95    --  formal parameters, used in the following function. If the flag Use_Dl
96    --  is set, the list is built using the already defined discriminals
97    --  of the type. Otherwise new identifiers are created, with the source
98    --  names of the discriminants.
99
100    procedure Build_Master_Renaming (N : Node_Id; T : Entity_Id);
101    --  If the designated type of an access type is a task type or contains
102    --  tasks, we make sure that a _Master variable is declared in the current
103    --  scope, and then declare a renaming for it:
104    --
105    --    atypeM : Master_Id renames _Master;
106    --
107    --  where atyp is the name of the access type. This declaration is
108    --  used when an allocator for the access type is expanded. The node N
109    --  is the full declaration of the designated type that contains tasks.
110    --  The renaming declaration is inserted before N, and after the Master
111    --  declaration.
112
113    procedure Build_Record_Init_Proc (N : Node_Id; Pe : Entity_Id);
114    --  Build record initialization procedure. N is the type declaration
115    --  node, and Pe is the corresponding entity for the record type.
116
117    procedure Build_Variant_Record_Equality (Typ  : Entity_Id);
118    --  Create An Equality function for the non-tagged variant record 'Typ'
119    --  and attach it to the TSS list
120
121    procedure Check_Stream_Attributes (Typ : Entity_Id);
122    --  Check that if a limited extension has a parent with user-defined
123    --  stream attributes, any limited component of the extension also has
124    --  the corresponding user-defined stream attributes.
125
126    procedure Expand_Tagged_Root (T : Entity_Id);
127    --  Add a field _Tag at the beginning of the record. This field carries
128    --  the value of the access to the Dispatch table. This procedure is only
129    --  called on root (non CPP_Class) types, the _Tag field being inherited
130    --  by the descendants.
131
132    procedure Expand_Record_Controller (T : Entity_Id);
133    --  T must be a record type that Has_Controlled_Component. Add a field
134    --  _controller of type Record_Controller or Limited_Record_Controller
135    --  in the record T.
136
137    procedure Freeze_Array_Type (N : Node_Id);
138    --  Freeze an array type. Deals with building the initialization procedure,
139    --  creating the packed array type for a packed array and also with the
140    --  creation of the controlling procedures for the controlled case. The
141    --  argument N is the N_Freeze_Entity node for the type.
142
143    procedure Freeze_Enumeration_Type (N : Node_Id);
144    --  Freeze enumeration type with non-standard representation. Builds the
145    --  array and function needed to convert between enumeration pos and
146    --  enumeration representation values. N is the N_Freeze_Entity node
147    --  for the type.
148
149    procedure Freeze_Record_Type (N : Node_Id);
150    --  Freeze record type. Builds all necessary discriminant checking
151    --  and other ancillary functions, and builds dispatch tables where
152    --  needed. The argument N is the N_Freeze_Entity node. This processing
153    --  applies only to E_Record_Type entities, not to class wide types,
154    --  record subtypes, or private types.
155
156    procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id);
157    --  Treat user-defined stream operations as renaming_as_body if the
158    --  subprogram they rename is not frozen when the type is frozen.
159
160    function Init_Formals (Typ : Entity_Id) return List_Id;
161    --  This function builds the list of formals for an initialization routine.
162    --  The first formal is always _Init with the given type. For task value
163    --  record types and types containing tasks, three additional formals are
164    --  added:
165    --
166    --    _Master    : Master_Id
167    --    _Chain     : in out Activation_Chain
168    --    _Task_Name : String
169    --
170    --  The caller must append additional entries for discriminants if required.
171
172    function In_Runtime (E : Entity_Id) return Boolean;
173    --  Check if E is defined in the RTL (in a child of Ada or System). Used
174    --  to avoid to bring in the overhead of _Input, _Output for tagged types.
175
176    function Make_Eq_Case (Node : Node_Id; CL : Node_Id) return List_Id;
177    --  Building block for variant record equality. Defined to share the
178    --  code between the tagged and non-tagged case. Given a Component_List
179    --  node CL, it generates an 'if' followed by a 'case' statement that
180    --  compares all components of local temporaries named X and Y (that
181    --  are declared as formals at some upper level). Node provides the
182    --  Sloc to be used for the generated code.
183
184    function Make_Eq_If (Node : Node_Id; L : List_Id) return Node_Id;
185    --  Building block for variant record equality. Defined to share the
186    --  code between the tagged and non-tagged case. Given the list of
187    --  components (or discriminants) L, it generates a return statement
188    --  that compares all components of local temporaries named X and Y
189    --  (that are declared as formals at some upper level). Node provides
190    --  the Sloc to be used for the generated code.
191
192    procedure Make_Predefined_Primitive_Specs
193      (Tag_Typ     : Entity_Id;
194       Predef_List : out List_Id;
195       Renamed_Eq  : out Node_Id);
196    --  Create a list with the specs of the predefined primitive operations.
197    --  The following entries are present for all tagged types, and provide
198    --  the results of the corresponding attribute applied to the object.
199    --  Dispatching is required in general, since the result of the attribute
200    --  will vary with the actual object subtype.
201    --
202    --     _alignment     provides result of 'Alignment attribute
203    --     _size          provides result of 'Size attribute
204    --     typSR          provides result of 'Read attribute
205    --     typSW          provides result of 'Write attribute
206    --     typSI          provides result of 'Input attribute
207    --     typSO          provides result of 'Output attribute
208    --
209    --  The following entries are additionally present for non-limited
210    --  tagged types, and implement additional dispatching operations
211    --  for predefined operations:
212    --
213    --     _equality      implements "=" operator
214    --     _assign        implements assignment operation
215    --     typDF          implements deep finalization
216    --     typDA          implements deep adust
217    --
218    --  The latter two are empty procedures unless the type contains some
219    --  controlled components that require finalization actions (the deep
220    --  in the name refers to the fact that the action applies to components).
221    --
222    --  The list is returned in Predef_List. The Parameter Renamed_Eq
223    --  either returns the value Empty, or else the defining unit name
224    --  for the predefined equality function in the case where the type
225    --  has a primitive operation that is a renaming of predefined equality
226    --  (but only if there is also an overriding user-defined equality
227    --  function). The returned Renamed_Eq will be passed to the
228    --  corresponding parameter of Predefined_Primitive_Bodies.
229
230    function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean;
231    --  returns True if there are representation clauses for type T that
232    --  are not inherited. If the result is false, the init_proc and the
233    --  discriminant_checking functions of the parent can be reused by
234    --  a derived type.
235
236    function Predef_Spec_Or_Body
237      (Loc      : Source_Ptr;
238       Tag_Typ  : Entity_Id;
239       Name     : Name_Id;
240       Profile  : List_Id;
241       Ret_Type : Entity_Id := Empty;
242       For_Body : Boolean   := False)
243       return     Node_Id;
244    --  This function generates the appropriate expansion for a predefined
245    --  primitive operation specified by its name, parameter profile and
246    --  return type (Empty means this is a procedure). If For_Body is false,
247    --  then the returned node is a subprogram declaration. If For_Body is
248    --  true, then the returned node is a empty subprogram body containing
249    --  no declarations and no statements.
250
251    function Predef_Stream_Attr_Spec
252      (Loc      : Source_Ptr;
253       Tag_Typ  : Entity_Id;
254       Name     : TSS_Name_Type;
255       For_Body : Boolean := False)
256       return     Node_Id;
257    --  Specialized version of Predef_Spec_Or_Body that apply to read, write,
258    --  input and output attribute whose specs are constructed in Exp_Strm.
259
260    function Predef_Deep_Spec
261      (Loc      : Source_Ptr;
262       Tag_Typ  : Entity_Id;
263       Name     : TSS_Name_Type;
264       For_Body : Boolean := False)
265       return     Node_Id;
266    --  Specialized version of Predef_Spec_Or_Body that apply to _deep_adjust
267    --  and _deep_finalize
268
269    function Predefined_Primitive_Bodies
270      (Tag_Typ    : Entity_Id;
271       Renamed_Eq : Node_Id)
272       return       List_Id;
273    --  Create the bodies of the predefined primitives that are described in
274    --  Predefined_Primitive_Specs. When not empty, Renamed_Eq must denote
275    --  the defining unit name of the type's predefined equality as returned
276    --  by Make_Predefined_Primitive_Specs.
277
278    function Predefined_Primitive_Freeze (Tag_Typ : Entity_Id) return List_Id;
279    --  Freeze entities of all predefined primitive operations. This is needed
280    --  because the bodies of these operations do not normally do any freezeing.
281
282    --------------------------
283    -- Adjust_Discriminants --
284    --------------------------
285
286    --  This procedure attempts to define subtypes for discriminants that
287    --  are more restrictive than those declared. Such a replacement is
288    --  possible if we can demonstrate that values outside the restricted
289    --  range would cause constraint errors in any case. The advantage of
290    --  restricting the discriminant types in this way is tha the maximum
291    --  size of the variant record can be calculated more conservatively.
292
293    --  An example of a situation in which we can perform this type of
294    --  restriction is the following:
295
296    --    subtype B is range 1 .. 10;
297    --    type Q is array (B range <>) of Integer;
298
299    --    type V (N : Natural) is record
300    --       C : Q (1 .. N);
301    --    end record;
302
303    --  In this situation, we can restrict the upper bound of N to 10, since
304    --  any larger value would cause a constraint error in any case.
305
306    --  There are many situations in which such restriction is possible, but
307    --  for now, we just look for cases like the above, where the component
308    --  in question is a one dimensional array whose upper bound is one of
309    --  the record discriminants. Also the component must not be part of
310    --  any variant part, since then the component does not always exist.
311
312    procedure Adjust_Discriminants (Rtype : Entity_Id) is
313       Loc   : constant Source_Ptr := Sloc (Rtype);
314       Comp  : Entity_Id;
315       Ctyp  : Entity_Id;
316       Ityp  : Entity_Id;
317       Lo    : Node_Id;
318       Hi    : Node_Id;
319       P     : Node_Id;
320       Loval : Uint;
321       Discr : Entity_Id;
322       Dtyp  : Entity_Id;
323       Dhi   : Node_Id;
324       Dhiv  : Uint;
325       Ahi   : Node_Id;
326       Ahiv  : Uint;
327       Tnn   : Entity_Id;
328
329    begin
330       Comp := First_Component (Rtype);
331       while Present (Comp) loop
332
333          --  If our parent is a variant, quit, we do not look at components
334          --  that are in variant parts, because they may not always exist.
335
336          P := Parent (Comp);   -- component declaration
337          P := Parent (P);      -- component list
338
339          exit when Nkind (Parent (P)) = N_Variant;
340
341          --  We are looking for a one dimensional array type
342
343          Ctyp := Etype (Comp);
344
345          if not Is_Array_Type (Ctyp)
346            or else Number_Dimensions (Ctyp) > 1
347          then
348             goto Continue;
349          end if;
350
351          --  The lower bound must be constant, and the upper bound is a
352          --  discriminant (which is a discriminant of the current record).
353
354          Ityp := Etype (First_Index (Ctyp));
355          Lo := Type_Low_Bound (Ityp);
356          Hi := Type_High_Bound (Ityp);
357
358          if not Compile_Time_Known_Value (Lo)
359            or else Nkind (Hi) /= N_Identifier
360            or else No (Entity (Hi))
361            or else Ekind (Entity (Hi)) /= E_Discriminant
362          then
363             goto Continue;
364          end if;
365
366          --  We have an array with appropriate bounds
367
368          Loval := Expr_Value (Lo);
369          Discr := Entity (Hi);
370          Dtyp  := Etype (Discr);
371
372          --  See if the discriminant has a known upper bound
373
374          Dhi := Type_High_Bound (Dtyp);
375
376          if not Compile_Time_Known_Value (Dhi) then
377             goto Continue;
378          end if;
379
380          Dhiv := Expr_Value (Dhi);
381
382          --  See if base type of component array has known upper bound
383
384          Ahi := Type_High_Bound (Etype (First_Index (Base_Type (Ctyp))));
385
386          if not Compile_Time_Known_Value (Ahi) then
387             goto Continue;
388          end if;
389
390          Ahiv := Expr_Value (Ahi);
391
392          --  The condition for doing the restriction is that the high bound
393          --  of the discriminant is greater than the low bound of the array,
394          --  and is also greater than the high bound of the base type index.
395
396          if Dhiv > Loval and then Dhiv > Ahiv then
397
398             --  We can reset the upper bound of the discriminant type to
399             --  whichever is larger, the low bound of the component, or
400             --  the high bound of the base type array index.
401
402             --  We build a subtype that is declared as
403
404             --     subtype Tnn is discr_type range discr_type'First .. max;
405
406             --  And insert this declaration into the tree. The type of the
407             --  discriminant is then reset to this more restricted subtype.
408
409             Tnn := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
410
411             Insert_Action (Declaration_Node (Rtype),
412               Make_Subtype_Declaration (Loc,
413                 Defining_Identifier => Tnn,
414                 Subtype_Indication =>
415                   Make_Subtype_Indication (Loc,
416                     Subtype_Mark => New_Occurrence_Of (Dtyp, Loc),
417                     Constraint   =>
418                       Make_Range_Constraint (Loc,
419                         Range_Expression =>
420                           Make_Range (Loc,
421                             Low_Bound =>
422                               Make_Attribute_Reference (Loc,
423                                 Attribute_Name => Name_First,
424                                 Prefix => New_Occurrence_Of (Dtyp, Loc)),
425                             High_Bound =>
426                               Make_Integer_Literal (Loc,
427                                 Intval => UI_Max (Loval, Ahiv)))))));
428
429             Set_Etype (Discr, Tnn);
430          end if;
431
432       <<Continue>>
433          Next_Component (Comp);
434       end loop;
435    end Adjust_Discriminants;
436
437    ---------------------------
438    -- Build_Array_Init_Proc --
439    ---------------------------
440
441    procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id) is
442       Loc        : constant Source_Ptr := Sloc (Nod);
443       Comp_Type  : constant Entity_Id  := Component_Type (A_Type);
444       Index_List : List_Id;
445       Proc_Id    : Entity_Id;
446       Body_Stmts : List_Id;
447
448       function Init_Component return List_Id;
449       --  Create one statement to initialize one array component, designated
450       --  by a full set of indices.
451
452       function Init_One_Dimension (N : Int) return List_Id;
453       --  Create loop to initialize one dimension of the array. The single
454       --  statement in the loop body initializes the inner dimensions if any,
455       --  or else the single component. Note that this procedure is called
456       --  recursively, with N being the dimension to be initialized. A call
457       --  with N greater than the number of dimensions simply generates the
458       --  component initialization, terminating the recursion.
459
460       --------------------
461       -- Init_Component --
462       --------------------
463
464       function Init_Component return List_Id is
465          Comp : Node_Id;
466
467       begin
468          Comp :=
469            Make_Indexed_Component (Loc,
470              Prefix => Make_Identifier (Loc, Name_uInit),
471              Expressions => Index_List);
472
473          if Needs_Simple_Initialization (Comp_Type) then
474             Set_Assignment_OK (Comp);
475             return New_List (
476               Make_Assignment_Statement (Loc,
477                 Name => Comp,
478                 Expression => Get_Simple_Init_Val (Comp_Type, Loc)));
479
480          else
481             return
482               Build_Initialization_Call (Loc, Comp, Comp_Type, True, A_Type);
483          end if;
484       end Init_Component;
485
486       ------------------------
487       -- Init_One_Dimension --
488       ------------------------
489
490       function Init_One_Dimension (N : Int) return List_Id is
491          Index      : Entity_Id;
492
493       begin
494          --  If the component does not need initializing, then there is nothing
495          --  to do here, so we return a null body. This occurs when generating
496          --  the dummy Init_Proc needed for Initialize_Scalars processing.
497
498          if not Has_Non_Null_Base_Init_Proc (Comp_Type)
499            and then not Needs_Simple_Initialization (Comp_Type)
500            and then not Has_Task (Comp_Type)
501          then
502             return New_List (Make_Null_Statement (Loc));
503
504          --  If all dimensions dealt with, we simply initialize the component
505
506          elsif N > Number_Dimensions (A_Type) then
507             return Init_Component;
508
509          --  Here we generate the required loop
510
511          else
512             Index :=
513               Make_Defining_Identifier (Loc, New_External_Name ('J', N));
514
515             Append (New_Reference_To (Index, Loc), Index_List);
516
517             return New_List (
518               Make_Implicit_Loop_Statement (Nod,
519                 Identifier => Empty,
520                 Iteration_Scheme =>
521                   Make_Iteration_Scheme (Loc,
522                     Loop_Parameter_Specification =>
523                       Make_Loop_Parameter_Specification (Loc,
524                         Defining_Identifier => Index,
525                         Discrete_Subtype_Definition =>
526                           Make_Attribute_Reference (Loc,
527                             Prefix => Make_Identifier (Loc, Name_uInit),
528                             Attribute_Name  => Name_Range,
529                             Expressions => New_List (
530                               Make_Integer_Literal (Loc, N))))),
531                 Statements =>  Init_One_Dimension (N + 1)));
532          end if;
533       end Init_One_Dimension;
534
535    --  Start of processing for Build_Array_Init_Proc
536
537    begin
538       if Suppress_Init_Proc (A_Type) then
539          return;
540       end if;
541
542       Index_List := New_List;
543
544       --  We need an initialization procedure if any of the following is true:
545
546       --    1. The component type has an initialization procedure
547       --    2. The component type needs simple initialization
548       --    3. Tasks are present
549       --    4. The type is marked as a publc entity
550
551       --  The reason for the public entity test is to deal properly with the
552       --  Initialize_Scalars pragma. This pragma can be set in the client and
553       --  not in the declaring package, this means the client will make a call
554       --  to the initialization procedure (because one of conditions 1-3 must
555       --  apply in this case), and we must generate a procedure (even if it is
556       --  null) to satisfy the call in this case.
557
558       --  Exception: do not build an array init_proc for a type whose root type
559       --  is Standard.String or Standard.Wide_String, since there is no place
560       --  to put the code, and in any case we handle initialization of such
561       --  types (in the Initialize_Scalars case, that's the only time the issue
562       --  arises) in a special manner anyway which does not need an init_proc.
563
564       if Has_Non_Null_Base_Init_Proc (Comp_Type)
565         or else Needs_Simple_Initialization (Comp_Type)
566         or else Has_Task (Comp_Type)
567         or else (not Restrictions (No_Initialize_Scalars)
568                    and then Is_Public (A_Type)
569                    and then Root_Type (A_Type) /= Standard_String
570                    and then Root_Type (A_Type) /= Standard_Wide_String)
571       then
572          Proc_Id :=
573            Make_Defining_Identifier (Loc, Make_Init_Proc_Name (A_Type));
574
575          Body_Stmts := Init_One_Dimension (1);
576
577          Discard_Node (
578            Make_Subprogram_Body (Loc,
579              Specification =>
580                Make_Procedure_Specification (Loc,
581                  Defining_Unit_Name => Proc_Id,
582                  Parameter_Specifications => Init_Formals (A_Type)),
583              Declarations => New_List,
584              Handled_Statement_Sequence =>
585                Make_Handled_Sequence_Of_Statements (Loc,
586                  Statements => Body_Stmts)));
587
588          Set_Ekind          (Proc_Id, E_Procedure);
589          Set_Is_Public      (Proc_Id, Is_Public (A_Type));
590          Set_Is_Internal    (Proc_Id);
591          Set_Has_Completion (Proc_Id);
592
593          if not Debug_Generated_Code then
594             Set_Debug_Info_Off (Proc_Id);
595          end if;
596
597          --  Set inlined unless controlled stuff or tasks around, in which
598          --  case we do not want to inline, because nested stuff may cause
599          --  difficulties in interunit inlining, and furthermore there is
600          --  in any case no point in inlining such complex init procs.
601
602          if not Has_Task (Proc_Id)
603            and then not Controlled_Type (Proc_Id)
604          then
605             Set_Is_Inlined (Proc_Id);
606          end if;
607
608          --  Associate Init_Proc with type, and determine if the procedure
609          --  is null (happens because of the Initialize_Scalars pragma case,
610          --  where we have to generate a null procedure in case it is called
611          --  by a client with Initialize_Scalars set). Such procedures have
612          --  to be generated, but do not have to be called, so we mark them
613          --  as null to suppress the call.
614
615          Set_Init_Proc (A_Type, Proc_Id);
616
617          if List_Length (Body_Stmts) = 1
618            and then Nkind (First (Body_Stmts)) = N_Null_Statement
619          then
620             Set_Is_Null_Init_Proc (Proc_Id);
621          end if;
622       end if;
623    end Build_Array_Init_Proc;
624
625    -----------------------------
626    -- Build_Class_Wide_Master --
627    -----------------------------
628
629    procedure Build_Class_Wide_Master (T : Entity_Id) is
630       Loc  : constant Source_Ptr := Sloc (T);
631       M_Id : Entity_Id;
632       Decl : Node_Id;
633       P    : Node_Id;
634
635    begin
636       --  Nothing to do if there is no task hierarchy.
637
638       if Restrictions (No_Task_Hierarchy) then
639          return;
640       end if;
641
642       --  Nothing to do if we already built a master entity for this scope
643
644       if not Has_Master_Entity (Scope (T)) then
645          --  first build the master entity
646          --    _Master : constant Master_Id := Current_Master.all;
647          --  and insert it just before the current declaration
648
649          Decl :=
650            Make_Object_Declaration (Loc,
651              Defining_Identifier =>
652                Make_Defining_Identifier (Loc, Name_uMaster),
653              Constant_Present => True,
654              Object_Definition => New_Reference_To (Standard_Integer, Loc),
655              Expression =>
656                Make_Explicit_Dereference (Loc,
657                  New_Reference_To (RTE (RE_Current_Master), Loc)));
658
659          P := Parent (T);
660          Insert_Before (P, Decl);
661          Analyze (Decl);
662          Set_Has_Master_Entity (Scope (T));
663
664          --  Now mark the containing scope as a task master
665
666          while Nkind (P) /= N_Compilation_Unit loop
667             P := Parent (P);
668
669             --  If we fall off the top, we are at the outer level, and the
670             --  environment task is our effective master, so nothing to mark.
671
672             if Nkind (P) = N_Task_Body
673               or else Nkind (P) = N_Block_Statement
674               or else Nkind (P) = N_Subprogram_Body
675             then
676                Set_Is_Task_Master (P, True);
677                exit;
678             end if;
679          end loop;
680       end if;
681
682       --  Now define the renaming of the master_id.
683
684       M_Id :=
685         Make_Defining_Identifier (Loc,
686           New_External_Name (Chars (T), 'M'));
687
688       Decl :=
689         Make_Object_Renaming_Declaration (Loc,
690           Defining_Identifier => M_Id,
691           Subtype_Mark => New_Reference_To (Standard_Integer, Loc),
692           Name => Make_Identifier (Loc, Name_uMaster));
693       Insert_Before (Parent (T), Decl);
694       Analyze (Decl);
695
696       Set_Master_Id (T, M_Id);
697
698    exception
699       when RE_Not_Available =>
700          return;
701    end Build_Class_Wide_Master;
702
703    --------------------------------
704    -- Build_Discr_Checking_Funcs --
705    --------------------------------
706
707    procedure Build_Discr_Checking_Funcs (N : Node_Id) is
708       Rec_Id            : Entity_Id;
709       Loc               : Source_Ptr;
710       Enclosing_Func_Id : Entity_Id;
711       Sequence          : Nat     := 1;
712       Type_Def          : Node_Id;
713       V                 : Node_Id;
714
715       function Build_Case_Statement
716         (Case_Id : Entity_Id;
717          Variant : Node_Id)
718          return    Node_Id;
719       --  Build a case statement containing only two alternatives. The
720       --  first alternative corresponds exactly to the discrete choices
721       --  given on the variant with contains the components that we are
722       --  generating the checks for. If the discriminant is one of these
723       --  return False. The second alternative is an OTHERS choice that
724       --  will return True indicating the discriminant did not match.
725
726       function Build_Dcheck_Function
727         (Case_Id : Entity_Id;
728          Variant : Node_Id)
729          return    Entity_Id;
730       --  Build the discriminant checking function for a given variant
731
732       procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id);
733       --  Builds the discriminant checking function for each variant of the
734       --  given variant part of the record type.
735
736       --------------------------
737       -- Build_Case_Statement --
738       --------------------------
739
740       function Build_Case_Statement
741         (Case_Id : Entity_Id;
742          Variant : Node_Id)
743          return    Node_Id
744       is
745          Alt_List       : constant List_Id := New_List;
746          Actuals_List   : List_Id;
747          Case_Node      : Node_Id;
748          Case_Alt_Node  : Node_Id;
749          Choice         : Node_Id;
750          Choice_List    : List_Id;
751          D              : Entity_Id;
752          Return_Node    : Node_Id;
753
754       begin
755          Case_Node := New_Node (N_Case_Statement, Loc);
756
757          --  Replace the discriminant which controls the variant, with the
758          --  name of the formal of the checking function.
759
760          Set_Expression (Case_Node,
761            Make_Identifier (Loc, Chars (Case_Id)));
762
763          Choice := First (Discrete_Choices (Variant));
764
765          if Nkind (Choice) = N_Others_Choice then
766             Choice_List := New_Copy_List (Others_Discrete_Choices (Choice));
767          else
768             Choice_List := New_Copy_List (Discrete_Choices (Variant));
769          end if;
770
771          if not Is_Empty_List (Choice_List) then
772             Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
773             Set_Discrete_Choices (Case_Alt_Node, Choice_List);
774
775             --  In case this is a nested variant, we need to return the result
776             --  of the discriminant checking function for the immediately
777             --  enclosing variant.
778
779             if Present (Enclosing_Func_Id) then
780                Actuals_List := New_List;
781
782                D := First_Discriminant (Rec_Id);
783                while Present (D) loop
784                   Append (Make_Identifier (Loc, Chars (D)), Actuals_List);
785                   Next_Discriminant (D);
786                end loop;
787
788                Return_Node :=
789                  Make_Return_Statement (Loc,
790                    Expression =>
791                      Make_Function_Call (Loc,
792                        Name =>
793                          New_Reference_To (Enclosing_Func_Id,  Loc),
794                        Parameter_Associations =>
795                          Actuals_List));
796
797             else
798                Return_Node :=
799                  Make_Return_Statement (Loc,
800                    Expression =>
801                      New_Reference_To (Standard_False, Loc));
802             end if;
803
804             Set_Statements (Case_Alt_Node, New_List (Return_Node));
805             Append (Case_Alt_Node, Alt_List);
806          end if;
807
808          Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
809          Choice_List := New_List (New_Node (N_Others_Choice, Loc));
810          Set_Discrete_Choices (Case_Alt_Node, Choice_List);
811
812          Return_Node :=
813            Make_Return_Statement (Loc,
814              Expression =>
815                New_Reference_To (Standard_True, Loc));
816
817          Set_Statements (Case_Alt_Node, New_List (Return_Node));
818          Append (Case_Alt_Node, Alt_List);
819
820          Set_Alternatives (Case_Node, Alt_List);
821          return Case_Node;
822       end Build_Case_Statement;
823
824       ---------------------------
825       -- Build_Dcheck_Function --
826       ---------------------------
827
828       function Build_Dcheck_Function
829         (Case_Id : Entity_Id;
830          Variant : Node_Id)
831          return    Entity_Id
832       is
833          Body_Node           : Node_Id;
834          Func_Id             : Entity_Id;
835          Parameter_List      : List_Id;
836          Spec_Node           : Node_Id;
837
838       begin
839          Body_Node := New_Node (N_Subprogram_Body, Loc);
840          Sequence := Sequence + 1;
841
842          Func_Id :=
843            Make_Defining_Identifier (Loc,
844              Chars => New_External_Name (Chars (Rec_Id), 'D', Sequence));
845
846          Spec_Node := New_Node (N_Function_Specification, Loc);
847          Set_Defining_Unit_Name (Spec_Node, Func_Id);
848
849          Parameter_List := Build_Discriminant_Formals (Rec_Id, False);
850
851          Set_Parameter_Specifications (Spec_Node, Parameter_List);
852          Set_Subtype_Mark (Spec_Node,
853                            New_Reference_To (Standard_Boolean,  Loc));
854          Set_Specification (Body_Node, Spec_Node);
855          Set_Declarations (Body_Node, New_List);
856
857          Set_Handled_Statement_Sequence (Body_Node,
858            Make_Handled_Sequence_Of_Statements (Loc,
859              Statements => New_List (
860                Build_Case_Statement (Case_Id, Variant))));
861
862          Set_Ekind       (Func_Id, E_Function);
863          Set_Mechanism   (Func_Id, Default_Mechanism);
864          Set_Is_Inlined  (Func_Id, True);
865          Set_Is_Pure     (Func_Id, True);
866          Set_Is_Public   (Func_Id, Is_Public (Rec_Id));
867          Set_Is_Internal (Func_Id, True);
868
869          if not Debug_Generated_Code then
870             Set_Debug_Info_Off (Func_Id);
871          end if;
872
873          Analyze (Body_Node);
874
875          Append_Freeze_Action (Rec_Id, Body_Node);
876          Set_Dcheck_Function (Variant, Func_Id);
877          return Func_Id;
878       end Build_Dcheck_Function;
879
880       ----------------------------
881       -- Build_Dcheck_Functions --
882       ----------------------------
883
884       procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id) is
885          Component_List_Node : Node_Id;
886          Decl                : Entity_Id;
887          Discr_Name          : Entity_Id;
888          Func_Id             : Entity_Id;
889          Variant             : Node_Id;
890          Saved_Enclosing_Func_Id : Entity_Id;
891
892       begin
893          --  Build the discriminant checking function for each variant, label
894          --  all components of that variant with the function's name.
895
896          Discr_Name := Entity (Name (Variant_Part_Node));
897          Variant := First_Non_Pragma (Variants (Variant_Part_Node));
898
899          while Present (Variant) loop
900             Func_Id := Build_Dcheck_Function (Discr_Name, Variant);
901             Component_List_Node := Component_List (Variant);
902
903             if not Null_Present (Component_List_Node) then
904                Decl :=
905                  First_Non_Pragma (Component_Items (Component_List_Node));
906
907                while Present (Decl) loop
908                   Set_Discriminant_Checking_Func
909                     (Defining_Identifier (Decl), Func_Id);
910
911                   Next_Non_Pragma (Decl);
912                end loop;
913
914                if Present (Variant_Part (Component_List_Node)) then
915                   Saved_Enclosing_Func_Id := Enclosing_Func_Id;
916                   Enclosing_Func_Id := Func_Id;
917                   Build_Dcheck_Functions (Variant_Part (Component_List_Node));
918                   Enclosing_Func_Id := Saved_Enclosing_Func_Id;
919                end if;
920             end if;
921
922             Next_Non_Pragma (Variant);
923          end loop;
924       end Build_Dcheck_Functions;
925
926    --  Start of processing for Build_Discr_Checking_Funcs
927
928    begin
929       --  Only build if not done already
930
931       if not Discr_Check_Funcs_Built (N) then
932          Type_Def := Type_Definition (N);
933
934          if Nkind (Type_Def) = N_Record_Definition then
935             if No (Component_List (Type_Def)) then   -- null record.
936                return;
937             else
938                V := Variant_Part (Component_List (Type_Def));
939             end if;
940
941          else pragma Assert (Nkind (Type_Def) = N_Derived_Type_Definition);
942             if No (Component_List (Record_Extension_Part (Type_Def))) then
943                return;
944             else
945                V := Variant_Part
946                       (Component_List (Record_Extension_Part (Type_Def)));
947             end if;
948          end if;
949
950          Rec_Id := Defining_Identifier (N);
951
952          if Present (V) and then not Is_Unchecked_Union (Rec_Id) then
953             Loc := Sloc (N);
954             Enclosing_Func_Id := Empty;
955             Build_Dcheck_Functions (V);
956          end if;
957
958          Set_Discr_Check_Funcs_Built (N);
959       end if;
960    end Build_Discr_Checking_Funcs;
961
962    --------------------------------
963    -- Build_Discriminant_Formals --
964    --------------------------------
965
966    function Build_Discriminant_Formals
967      (Rec_Id : Entity_Id;
968       Use_Dl : Boolean)
969       return   List_Id
970    is
971       Loc             : Source_Ptr       := Sloc (Rec_Id);
972       Parameter_List  : constant List_Id := New_List;
973       D               : Entity_Id;
974       Formal          : Entity_Id;
975       Param_Spec_Node : Node_Id;
976
977    begin
978       if Has_Discriminants (Rec_Id) then
979          D := First_Discriminant (Rec_Id);
980          while Present (D) loop
981             Loc := Sloc (D);
982
983             if Use_Dl then
984                Formal := Discriminal (D);
985             else
986                Formal := Make_Defining_Identifier (Loc, Chars (D));
987             end if;
988
989             Param_Spec_Node :=
990               Make_Parameter_Specification (Loc,
991                   Defining_Identifier => Formal,
992                 Parameter_Type =>
993                   New_Reference_To (Etype (D), Loc));
994             Append (Param_Spec_Node, Parameter_List);
995             Next_Discriminant (D);
996          end loop;
997       end if;
998
999       return Parameter_List;
1000    end Build_Discriminant_Formals;
1001
1002    -------------------------------
1003    -- Build_Initialization_Call --
1004    -------------------------------
1005
1006    --  References to a discriminant inside the record type declaration
1007    --  can appear either in the subtype_indication to constrain a
1008    --  record or an array, or as part of a larger expression given for
1009    --  the initial value of a component. In both of these cases N appears
1010    --  in the record initialization procedure and needs to be replaced by
1011    --  the formal parameter of the initialization procedure which
1012    --  corresponds to that discriminant.
1013
1014    --  In the example below, references to discriminants D1 and D2 in proc_1
1015    --  are replaced by references to formals with the same name
1016    --  (discriminals)
1017
1018    --  A similar replacement is done for calls to any record
1019    --  initialization procedure for any components that are themselves
1020    --  of a record type.
1021
1022    --  type R (D1, D2 : Integer) is record
1023    --     X : Integer := F * D1;
1024    --     Y : Integer := F * D2;
1025    --  end record;
1026
1027    --  procedure proc_1 (Out_2 : out R; D1 : Integer; D2 : Integer) is
1028    --  begin
1029    --     Out_2.D1 := D1;
1030    --     Out_2.D2 := D2;
1031    --     Out_2.X := F * D1;
1032    --     Out_2.Y := F * D2;
1033    --  end;
1034
1035    function Build_Initialization_Call
1036      (Loc               : Source_Ptr;
1037       Id_Ref            : Node_Id;
1038       Typ               : Entity_Id;
1039       In_Init_Proc      : Boolean := False;
1040       Enclos_Type       : Entity_Id := Empty;
1041       Discr_Map         : Elist_Id := New_Elmt_List;
1042       With_Default_Init : Boolean := False)
1043       return              List_Id
1044    is
1045       First_Arg      : Node_Id;
1046       Args           : List_Id;
1047       Decls          : List_Id;
1048       Decl           : Node_Id;
1049       Discr          : Entity_Id;
1050       Arg            : Node_Id;
1051       Proc           : constant Entity_Id := Base_Init_Proc (Typ);
1052       Init_Type      : constant Entity_Id := Etype (First_Formal (Proc));
1053       Full_Init_Type : constant Entity_Id := Underlying_Type (Init_Type);
1054       Res            : constant List_Id   := New_List;
1055       Full_Type      : Entity_Id := Typ;
1056       Controller_Typ : Entity_Id;
1057
1058    begin
1059       --  Nothing to do if the Init_Proc is null, unless Initialize_Sclalars
1060       --  is active (in which case we make the call anyway, since in the
1061       --  actual compiled client it may be non null).
1062
1063       if Is_Null_Init_Proc (Proc) and then not Init_Or_Norm_Scalars then
1064          return Empty_List;
1065       end if;
1066
1067       --  Go to full view if private type. In the case of successive
1068       --  private derivations, this can require more than one step.
1069
1070       while Is_Private_Type (Full_Type)
1071         and then Present (Full_View (Full_Type))
1072       loop
1073          Full_Type := Full_View (Full_Type);
1074       end loop;
1075
1076       --  If Typ is derived, the procedure is the initialization procedure for
1077       --  the root type. Wrap the argument in an conversion to make it type
1078       --  honest. Actually it isn't quite type honest, because there can be
1079       --  conflicts of views in the private type case. That is why we set
1080       --  Conversion_OK in the conversion node.
1081       if (Is_Record_Type (Typ)
1082            or else Is_Array_Type (Typ)
1083            or else Is_Private_Type (Typ))
1084         and then Init_Type /= Base_Type (Typ)
1085       then
1086          First_Arg := OK_Convert_To (Etype (Init_Type), Id_Ref);
1087          Set_Etype (First_Arg, Init_Type);
1088
1089       else
1090          First_Arg := Id_Ref;
1091       end if;
1092
1093       Args := New_List (Convert_Concurrent (First_Arg, Typ));
1094
1095       --  In the tasks case, add _Master as the value of the _Master parameter
1096       --  and _Chain as the value of the _Chain parameter. At the outer level,
1097       --  these will be variables holding the corresponding values obtained
1098       --  from GNARL. At inner levels, they will be the parameters passed down
1099       --  through the outer routines.
1100
1101       if Has_Task (Full_Type) then
1102          if Restrictions (No_Task_Hierarchy) then
1103
1104             --  See comments in System.Tasking.Initialization.Init_RTS
1105             --  for the value 3 (should be rtsfindable constant ???)
1106
1107             Append_To (Args, Make_Integer_Literal (Loc, 3));
1108          else
1109             Append_To (Args, Make_Identifier (Loc, Name_uMaster));
1110          end if;
1111
1112          Append_To (Args, Make_Identifier (Loc, Name_uChain));
1113
1114          --  Ada0Y (AI-287): In case of default initialized components
1115          --  with tasks, we generate a null string actual parameter.
1116          --  This is just a workaround that must be improved later???
1117
1118          if With_Default_Init then
1119             declare
1120                S           : String_Id;
1121                Null_String : Node_Id;
1122             begin
1123                Start_String;
1124                S := End_String;
1125                Null_String := Make_String_Literal (Loc, Strval => S);
1126                Append_To (Args, Null_String);
1127             end;
1128          else
1129             Decls := Build_Task_Image_Decls (Loc, Id_Ref, Enclos_Type);
1130             Decl  := Last (Decls);
1131
1132             Append_To (Args,
1133               New_Occurrence_Of (Defining_Identifier (Decl), Loc));
1134             Append_List (Decls, Res);
1135          end if;
1136
1137       else
1138          Decls := No_List;
1139          Decl  := Empty;
1140       end if;
1141
1142       --  Add discriminant values if discriminants are present
1143
1144       if Has_Discriminants (Full_Init_Type) then
1145          Discr := First_Discriminant (Full_Init_Type);
1146
1147          while Present (Discr) loop
1148
1149             --  If this is a discriminated concurrent type, the init_proc
1150             --  for the corresponding record is being called. Use that
1151             --  type directly to find the discriminant value, to handle
1152             --  properly intervening renamed discriminants.
1153
1154             declare
1155                T : Entity_Id := Full_Type;
1156
1157             begin
1158                if Is_Protected_Type (T) then
1159                   T := Corresponding_Record_Type (T);
1160
1161                elsif Is_Private_Type (T)
1162                  and then Present (Underlying_Full_View (T))
1163                  and then Is_Protected_Type (Underlying_Full_View (T))
1164                then
1165                   T := Corresponding_Record_Type (Underlying_Full_View (T));
1166                end if;
1167
1168                Arg :=
1169                  Get_Discriminant_Value (
1170                    Discr,
1171                    T,
1172                    Discriminant_Constraint (Full_Type));
1173             end;
1174
1175             if In_Init_Proc then
1176
1177                --  Replace any possible references to the discriminant in the
1178                --  call to the record initialization procedure with references
1179                --  to the appropriate formal parameter.
1180
1181                if Nkind (Arg) = N_Identifier
1182                   and then Ekind (Entity (Arg)) = E_Discriminant
1183                then
1184                   Arg := New_Reference_To (Discriminal (Entity (Arg)), Loc);
1185
1186                --  Case of access discriminants. We replace the reference
1187                --  to the type by a reference to the actual object
1188
1189                elsif Nkind (Arg) = N_Attribute_Reference
1190                  and then Is_Access_Type (Etype (Arg))
1191                  and then Is_Entity_Name (Prefix (Arg))
1192                  and then Is_Type (Entity (Prefix (Arg)))
1193                then
1194                   Arg :=
1195                     Make_Attribute_Reference (Loc,
1196                       Prefix         => New_Copy (Prefix (Id_Ref)),
1197                       Attribute_Name => Name_Unrestricted_Access);
1198
1199                --  Otherwise make a copy of the default expression. Note
1200                --  that we use the current Sloc for this, because we do not
1201                --  want the call to appear to be at the declaration point.
1202                --  Within the expression, replace discriminants with their
1203                --  discriminals.
1204
1205                else
1206                   Arg :=
1207                     New_Copy_Tree (Arg, Map => Discr_Map, New_Sloc => Loc);
1208                end if;
1209
1210             else
1211                if Is_Constrained (Full_Type) then
1212                   Arg := Duplicate_Subexpr_No_Checks (Arg);
1213                else
1214                   --  The constraints come from the discriminant default
1215                   --  exps, they must be reevaluated, so we use New_Copy_Tree
1216                   --  but we ensure the proper Sloc (for any embedded calls).
1217
1218                   Arg := New_Copy_Tree (Arg, New_Sloc => Loc);
1219                end if;
1220             end if;
1221
1222             --  Ada0Y (AI-287) In case of default initialized components, we
1223             --  need to generate the corresponding selected component node
1224             --  to access the discriminant value. In other cases this is not
1225             --  required because we are inside the init proc and we use the
1226             --  corresponding formal.
1227
1228             if With_Default_Init
1229               and then Nkind (Id_Ref) = N_Selected_Component
1230             then
1231                Append_To (Args,
1232                  Make_Selected_Component (Loc,
1233                    Prefix => New_Copy_Tree (Prefix (Id_Ref)),
1234                    Selector_Name => Arg));
1235             else
1236                Append_To (Args, Arg);
1237             end if;
1238
1239             Next_Discriminant (Discr);
1240          end loop;
1241       end if;
1242
1243       --  If this is a call to initialize the parent component of a derived
1244       --  tagged type, indicate that the tag should not be set in the parent.
1245
1246       if Is_Tagged_Type (Full_Init_Type)
1247         and then not Is_CPP_Class (Full_Init_Type)
1248         and then Nkind (Id_Ref) = N_Selected_Component
1249         and then Chars (Selector_Name (Id_Ref)) = Name_uParent
1250       then
1251          Append_To (Args, New_Occurrence_Of (Standard_False, Loc));
1252       end if;
1253
1254       Append_To (Res,
1255         Make_Procedure_Call_Statement (Loc,
1256           Name => New_Occurrence_Of (Proc, Loc),
1257           Parameter_Associations => Args));
1258
1259       if Controlled_Type (Typ)
1260         and then Nkind (Id_Ref) = N_Selected_Component
1261       then
1262          if Chars (Selector_Name (Id_Ref)) /= Name_uParent then
1263             Append_List_To (Res,
1264               Make_Init_Call (
1265                 Ref         => New_Copy_Tree (First_Arg),
1266                 Typ         => Typ,
1267                 Flist_Ref   =>
1268                   Find_Final_List (Typ, New_Copy_Tree (First_Arg)),
1269                 With_Attach => Make_Integer_Literal (Loc, 1)));
1270
1271          --  If the enclosing type is an extension with new controlled
1272          --  components, it has his own record controller. If the parent
1273          --  also had a record controller, attach it to the new one.
1274          --  Build_Init_Statements relies on the fact that in this specific
1275          --  case the last statement of the result is the attach call to
1276          --  the controller. If this is changed, it must be synchronized.
1277
1278          elsif Present (Enclos_Type)
1279            and then Has_New_Controlled_Component (Enclos_Type)
1280            and then Has_Controlled_Component (Typ)
1281          then
1282             if Is_Return_By_Reference_Type (Typ) then
1283                Controller_Typ := RTE (RE_Limited_Record_Controller);
1284             else
1285                Controller_Typ := RTE (RE_Record_Controller);
1286             end if;
1287
1288             Append_List_To (Res,
1289               Make_Init_Call (
1290                 Ref       =>
1291                   Make_Selected_Component (Loc,
1292                     Prefix        => New_Copy_Tree (First_Arg),
1293                     Selector_Name => Make_Identifier (Loc, Name_uController)),
1294                 Typ       => Controller_Typ,
1295                 Flist_Ref => Find_Final_List (Typ, New_Copy_Tree (First_Arg)),
1296                 With_Attach => Make_Integer_Literal (Loc, 1)));
1297          end if;
1298       end if;
1299
1300       return Res;
1301
1302    exception
1303       when RE_Not_Available =>
1304          return Empty_List;
1305    end Build_Initialization_Call;
1306
1307    ---------------------------
1308    -- Build_Master_Renaming --
1309    ---------------------------
1310
1311    procedure Build_Master_Renaming (N : Node_Id; T : Entity_Id) is
1312       Loc  : constant Source_Ptr := Sloc (N);
1313       M_Id : Entity_Id;
1314       Decl : Node_Id;
1315
1316    begin
1317       --  Nothing to do if there is no task hierarchy.
1318
1319       if Restrictions (No_Task_Hierarchy) then
1320          return;
1321       end if;
1322
1323       M_Id :=
1324         Make_Defining_Identifier (Loc,
1325           New_External_Name (Chars (T), 'M'));
1326
1327       Decl :=
1328         Make_Object_Renaming_Declaration (Loc,
1329           Defining_Identifier => M_Id,
1330           Subtype_Mark => New_Reference_To (RTE (RE_Master_Id), Loc),
1331           Name => Make_Identifier (Loc, Name_uMaster));
1332       Insert_Before (N, Decl);
1333       Analyze (Decl);
1334
1335       Set_Master_Id (T, M_Id);
1336
1337    exception
1338       when RE_Not_Available =>
1339          return;
1340    end Build_Master_Renaming;
1341
1342    ----------------------------
1343    -- Build_Record_Init_Proc --
1344    ----------------------------
1345
1346    procedure Build_Record_Init_Proc (N : Node_Id; Pe : Entity_Id) is
1347       Loc         : Source_Ptr := Sloc (N);
1348       Discr_Map   : constant Elist_Id := New_Elmt_List;
1349       Proc_Id     : Entity_Id;
1350       Rec_Type    : Entity_Id;
1351       Set_Tag     : Entity_Id := Empty;
1352
1353       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id;
1354       --  Build a assignment statement node which assigns to record
1355       --  component its default expression if defined. The left hand side
1356       --  of the assignment is marked Assignment_OK so that initialization
1357       --  of limited private records works correctly, Return also the
1358       --  adjustment call for controlled objects
1359
1360       procedure Build_Discriminant_Assignments (Statement_List : List_Id);
1361       --  If the record has discriminants, adds assignment statements to
1362       --  statement list to initialize the discriminant values from the
1363       --  arguments of the initialization procedure.
1364
1365       function Build_Init_Statements (Comp_List : Node_Id) return List_Id;
1366       --  Build a list representing a sequence of statements which initialize
1367       --  components of the given component list. This may involve building
1368       --  case statements for the variant parts.
1369
1370       function Build_Init_Call_Thru
1371         (Parameters : List_Id)
1372          return       List_Id;
1373       --  Given a non-tagged type-derivation that declares discriminants,
1374       --  such as
1375       --
1376       --  type R (R1, R2 : Integer) is record ... end record;
1377       --
1378       --  type D (D1 : Integer) is new R (1, D1);
1379       --
1380       --  we make the _init_proc of D be
1381       --
1382       --       procedure _init_proc(X : D; D1 : Integer) is
1383       --       begin
1384       --          _init_proc( R(X), 1, D1);
1385       --       end _init_proc;
1386       --
1387       --  This function builds the call statement in this _init_proc.
1388
1389       procedure Build_Init_Procedure;
1390       --  Build the tree corresponding to the procedure specification and body
1391       --  of the initialization procedure (by calling all the preceding
1392       --  auxiliary routines), and install it as the _init TSS.
1393
1394       procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id);
1395       --  Add range checks to components of disciminated records. S is a
1396       --  subtype indication of a record component. Check_List is a list
1397       --  to which the check actions are appended.
1398
1399       function Component_Needs_Simple_Initialization
1400         (T    : Entity_Id)
1401          return Boolean;
1402       --  Determines if a component needs simple initialization, given its
1403       --  type T. This is the same as Needs_Simple_Initialization except
1404       --  for the following differences. The types Tag and Vtable_Ptr,
1405       --  which are access types which would normally require simple
1406       --  initialization to null, do not require initialization as
1407       --  components, since they are explicitly initialized by other
1408       --  means. The other relaxation is for packed bit arrays that are
1409       --  associated with a modular type, which in some cases require
1410       --  zero initialization to properly support comparisons, except
1411       --  that comparison of such components always involves an explicit
1412       --  selection of only the component's specific bits (whether or not
1413       --  there are adjacent components or gaps), so zero initialization
1414       --  is never needed for components.
1415
1416       procedure Constrain_Array
1417         (SI         : Node_Id;
1418          Check_List : List_Id);
1419       --  Called from Build_Record_Checks.
1420       --  Apply a list of index constraints to an unconstrained array type.
1421       --  The first parameter is the entity for the resulting subtype.
1422       --  Check_List is a list to which the check actions are appended.
1423
1424       procedure Constrain_Index
1425         (Index      : Node_Id;
1426          S          : Node_Id;
1427          Check_List : List_Id);
1428       --  Called from Build_Record_Checks.
1429       --  Process an index constraint in a constrained array declaration.
1430       --  The constraint can be a subtype name, or a range with or without
1431       --  an explicit subtype mark. The index is the corresponding index of the
1432       --  unconstrained array. S is the range expression. Check_List is a list
1433       --  to which the check actions are appended.
1434
1435       function Parent_Subtype_Renaming_Discrims return Boolean;
1436       --  Returns True for base types N that rename discriminants, else False
1437
1438       function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean;
1439       --  Determines whether a record initialization procedure needs to be
1440       --  generated for the given record type.
1441
1442       ----------------------
1443       -- Build_Assignment --
1444       ----------------------
1445
1446       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id is
1447          Exp  : Node_Id := N;
1448          Lhs  : Node_Id;
1449          Typ  : constant Entity_Id := Underlying_Type (Etype (Id));
1450          Kind : Node_Kind := Nkind (N);
1451          Res  : List_Id;
1452
1453       begin
1454          Loc := Sloc (N);
1455          Lhs :=
1456            Make_Selected_Component (Loc,
1457              Prefix => Make_Identifier (Loc, Name_uInit),
1458              Selector_Name => New_Occurrence_Of (Id, Loc));
1459          Set_Assignment_OK (Lhs);
1460
1461          --  Case of an access attribute applied to the current
1462          --  instance. Replace the reference to the type by a
1463          --  reference to the actual object. (Note that this
1464          --  handles the case of the top level of the expression
1465          --  being given by such an attribute, but doesn't cover
1466          --  uses nested within an initial value expression.
1467          --  Nested uses are unlikely to occur in practice,
1468          --  but theoretically possible. It's not clear how
1469          --  to handle them without fully traversing the
1470          --  expression. ???)
1471
1472          if Kind = N_Attribute_Reference
1473            and then (Attribute_Name (N) = Name_Unchecked_Access
1474                        or else
1475                      Attribute_Name (N) = Name_Unrestricted_Access)
1476            and then Is_Entity_Name (Prefix (N))
1477            and then Is_Type (Entity (Prefix (N)))
1478            and then Entity (Prefix (N)) = Rec_Type
1479          then
1480             Exp :=
1481               Make_Attribute_Reference (Loc,
1482                 Prefix         => Make_Identifier (Loc, Name_uInit),
1483                 Attribute_Name => Name_Unrestricted_Access);
1484          end if;
1485
1486          --  For a derived type the default value is copied from the component
1487          --  declaration of the parent. In the analysis of the init_proc for
1488          --  the parent the default value may have been expanded into a local
1489          --  variable, which is of course not usable here. We must copy the
1490          --  original expression and reanalyze.
1491
1492          if Nkind (Exp) = N_Identifier
1493            and then not Comes_From_Source (Exp)
1494            and then Analyzed (Exp)
1495            and then not In_Open_Scopes (Scope (Entity (Exp)))
1496            and then Nkind (Original_Node (Exp)) = N_Aggregate
1497          then
1498             Exp := New_Copy_Tree (Original_Node (Exp));
1499          end if;
1500
1501          Res := New_List (
1502            Make_Assignment_Statement (Loc,
1503              Name       => Lhs,
1504              Expression => Exp));
1505
1506          Set_No_Ctrl_Actions (First (Res));
1507
1508          --  Adjust the tag if tagged (because of possible view conversions).
1509          --  Suppress the tag adjustment when Java_VM because JVM tags are
1510          --  represented implicitly in objects.
1511
1512          if Is_Tagged_Type (Typ) and then not Java_VM then
1513             Append_To (Res,
1514               Make_Assignment_Statement (Loc,
1515                 Name =>
1516                   Make_Selected_Component (Loc,
1517                     Prefix =>  New_Copy_Tree (Lhs),
1518                     Selector_Name =>
1519                       New_Reference_To (Tag_Component (Typ), Loc)),
1520
1521                 Expression =>
1522                   Unchecked_Convert_To (RTE (RE_Tag),
1523                     New_Reference_To (Access_Disp_Table (Typ), Loc))));
1524          end if;
1525
1526          --  Adjust the component if controlled except if it is an
1527          --  aggregate that will be expanded inline
1528
1529          if Kind = N_Qualified_Expression then
1530             Kind := Nkind (Expression (N));
1531          end if;
1532
1533          if Controlled_Type (Typ)
1534          and then not (Kind = N_Aggregate or else Kind = N_Extension_Aggregate)
1535          then
1536             Append_List_To (Res,
1537               Make_Adjust_Call (
1538                Ref          => New_Copy_Tree (Lhs),
1539                Typ          => Etype (Id),
1540                Flist_Ref    =>
1541                  Find_Final_List (Etype (Id), New_Copy_Tree (Lhs)),
1542                With_Attach  => Make_Integer_Literal (Loc, 1)));
1543          end if;
1544
1545          return Res;
1546
1547       exception
1548          when RE_Not_Available =>
1549             return Empty_List;
1550       end Build_Assignment;
1551
1552       ------------------------------------
1553       -- Build_Discriminant_Assignments --
1554       ------------------------------------
1555
1556       procedure Build_Discriminant_Assignments (Statement_List : List_Id) is
1557          D         : Entity_Id;
1558          Is_Tagged : constant Boolean := Is_Tagged_Type (Rec_Type);
1559
1560       begin
1561          if Has_Discriminants (Rec_Type)
1562            and then not Is_Unchecked_Union (Rec_Type)
1563          then
1564             D := First_Discriminant (Rec_Type);
1565
1566             while Present (D) loop
1567                --  Don't generate the assignment for discriminants in derived
1568                --  tagged types if the discriminant is a renaming of some
1569                --  ancestor discriminant.  This initialization will be done
1570                --  when initializing the _parent field of the derived record.
1571
1572                if Is_Tagged and then
1573                  Present (Corresponding_Discriminant (D))
1574                then
1575                   null;
1576
1577                else
1578                   Loc := Sloc (D);
1579                   Append_List_To (Statement_List,
1580                     Build_Assignment (D,
1581                       New_Reference_To (Discriminal (D), Loc)));
1582                end if;
1583
1584                Next_Discriminant (D);
1585             end loop;
1586          end if;
1587       end Build_Discriminant_Assignments;
1588
1589       --------------------------
1590       -- Build_Init_Call_Thru --
1591       --------------------------
1592
1593       function Build_Init_Call_Thru
1594         (Parameters     : List_Id)
1595          return           List_Id
1596       is
1597          Parent_Proc    : constant Entity_Id :=
1598                             Base_Init_Proc (Etype (Rec_Type));
1599
1600          Parent_Type    : constant Entity_Id :=
1601                             Etype (First_Formal (Parent_Proc));
1602
1603          Uparent_Type   : constant Entity_Id :=
1604                             Underlying_Type (Parent_Type);
1605
1606          First_Discr_Param : Node_Id;
1607
1608          Parent_Discr : Entity_Id;
1609          First_Arg    : Node_Id;
1610          Args         : List_Id;
1611          Arg          : Node_Id;
1612          Res          : List_Id;
1613
1614       begin
1615          --  First argument (_Init) is the object to be initialized.
1616          --  ??? not sure where to get a reasonable Loc for First_Arg
1617
1618          First_Arg :=
1619            OK_Convert_To (Parent_Type,
1620              New_Reference_To (Defining_Identifier (First (Parameters)), Loc));
1621
1622          Set_Etype (First_Arg, Parent_Type);
1623
1624          Args := New_List (Convert_Concurrent (First_Arg, Rec_Type));
1625
1626          --  In the tasks case,
1627          --    add _Master as the value of the _Master parameter
1628          --    add _Chain as the value of the _Chain parameter.
1629          --    add _Task_Name as the value of the _Task_Name parameter.
1630          --  At the outer level, these will be variables holding the
1631          --  corresponding values obtained from GNARL or the expander.
1632          --
1633          --  At inner levels, they will be the parameters passed down through
1634          --  the outer routines.
1635
1636          First_Discr_Param := Next (First (Parameters));
1637
1638          if Has_Task (Rec_Type) then
1639             if Restrictions (No_Task_Hierarchy) then
1640
1641                --  See comments in System.Tasking.Initialization.Init_RTS
1642                --  for the value 3.
1643
1644                Append_To (Args, Make_Integer_Literal (Loc, 3));
1645             else
1646                Append_To (Args, Make_Identifier (Loc, Name_uMaster));
1647             end if;
1648
1649             Append_To (Args, Make_Identifier (Loc, Name_uChain));
1650             Append_To (Args, Make_Identifier (Loc, Name_uTask_Name));
1651             First_Discr_Param := Next (Next (Next (First_Discr_Param)));
1652          end if;
1653
1654          --  Append discriminant values
1655
1656          if Has_Discriminants (Uparent_Type) then
1657             pragma Assert (not Is_Tagged_Type (Uparent_Type));
1658
1659             Parent_Discr := First_Discriminant (Uparent_Type);
1660             while Present (Parent_Discr) loop
1661
1662                --  Get the initial value for this discriminant
1663                --  ??? needs to be cleaned up to use parent_Discr_Constr
1664                --  directly.
1665
1666                declare
1667                   Discr_Value : Elmt_Id :=
1668                                   First_Elmt
1669                                     (Stored_Constraint (Rec_Type));
1670
1671                   Discr       : Entity_Id :=
1672                                   First_Stored_Discriminant (Uparent_Type);
1673                begin
1674                   while Original_Record_Component (Parent_Discr) /= Discr loop
1675                      Next_Stored_Discriminant (Discr);
1676                      Next_Elmt (Discr_Value);
1677                   end loop;
1678
1679                   Arg := Node (Discr_Value);
1680                end;
1681
1682                --  Append it to the list
1683
1684                if Nkind (Arg) = N_Identifier
1685                   and then Ekind (Entity (Arg)) = E_Discriminant
1686                then
1687                   Append_To (Args,
1688                     New_Reference_To (Discriminal (Entity (Arg)), Loc));
1689
1690                --  Case of access discriminants. We replace the reference
1691                --  to the type by a reference to the actual object
1692
1693 --     ??? why is this code deleted without comment
1694
1695 --               elsif Nkind (Arg) = N_Attribute_Reference
1696 --                 and then Is_Entity_Name (Prefix (Arg))
1697 --                 and then Is_Type (Entity (Prefix (Arg)))
1698 --               then
1699 --                  Append_To (Args,
1700 --                    Make_Attribute_Reference (Loc,
1701 --                      Prefix         => New_Copy (Prefix (Id_Ref)),
1702 --                      Attribute_Name => Name_Unrestricted_Access));
1703
1704                else
1705                   Append_To (Args, New_Copy (Arg));
1706                end if;
1707
1708                Next_Discriminant (Parent_Discr);
1709             end loop;
1710          end if;
1711
1712          Res :=
1713             New_List (
1714               Make_Procedure_Call_Statement (Loc,
1715                 Name => New_Occurrence_Of (Parent_Proc, Loc),
1716                 Parameter_Associations => Args));
1717
1718          return Res;
1719       end Build_Init_Call_Thru;
1720
1721       --------------------------
1722       -- Build_Init_Procedure --
1723       --------------------------
1724
1725       procedure Build_Init_Procedure is
1726          Body_Node             : Node_Id;
1727          Handled_Stmt_Node     : Node_Id;
1728          Parameters            : List_Id;
1729          Proc_Spec_Node        : Node_Id;
1730          Body_Stmts            : List_Id;
1731          Record_Extension_Node : Node_Id;
1732          Init_Tag              : Node_Id;
1733
1734       begin
1735          Body_Stmts := New_List;
1736          Body_Node := New_Node (N_Subprogram_Body, Loc);
1737
1738          Proc_Id :=
1739            Make_Defining_Identifier (Loc,
1740              Chars => Make_Init_Proc_Name (Rec_Type));
1741          Set_Ekind (Proc_Id, E_Procedure);
1742
1743          Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
1744          Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);
1745
1746          Parameters := Init_Formals (Rec_Type);
1747          Append_List_To (Parameters,
1748            Build_Discriminant_Formals (Rec_Type, True));
1749
1750          --  For tagged types, we add a flag to indicate whether the routine
1751          --  is called to initialize a parent component in the init_proc of
1752          --  a type extension. If the flag is false, we do not set the tag
1753          --  because it has been set already in the extension.
1754
1755          if Is_Tagged_Type (Rec_Type)
1756            and then not Is_CPP_Class (Rec_Type)
1757          then
1758             Set_Tag :=
1759                   Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1760
1761             Append_To (Parameters,
1762               Make_Parameter_Specification (Loc,
1763                 Defining_Identifier => Set_Tag,
1764                 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
1765                 Expression => New_Occurrence_Of (Standard_True, Loc)));
1766          end if;
1767
1768          Set_Parameter_Specifications (Proc_Spec_Node, Parameters);
1769          Set_Specification (Body_Node, Proc_Spec_Node);
1770          Set_Declarations (Body_Node, New_List);
1771
1772          if Parent_Subtype_Renaming_Discrims then
1773
1774             --  N is a Derived_Type_Definition that renames the parameters
1775             --  of the ancestor type.  We init it by expanding our discrims
1776             --  and call the ancestor _init_proc with a type-converted object
1777
1778             Append_List_To (Body_Stmts,
1779               Build_Init_Call_Thru (Parameters));
1780
1781          elsif Nkind (Type_Definition (N)) = N_Record_Definition then
1782             Build_Discriminant_Assignments (Body_Stmts);
1783
1784             if not Null_Present (Type_Definition (N)) then
1785                Append_List_To (Body_Stmts,
1786                  Build_Init_Statements (
1787                    Component_List (Type_Definition (N))));
1788             end if;
1789
1790          else
1791             --  N is a Derived_Type_Definition with a possible non-empty
1792             --  extension. The initialization of a type extension consists
1793             --  in the initialization of the components in the extension.
1794
1795             Build_Discriminant_Assignments (Body_Stmts);
1796
1797             Record_Extension_Node :=
1798               Record_Extension_Part (Type_Definition (N));
1799
1800             if not Null_Present (Record_Extension_Node) then
1801                declare
1802                   Stmts : constant List_Id :=
1803                             Build_Init_Statements (
1804                               Component_List (Record_Extension_Node));
1805
1806                begin
1807                   --  The parent field must be initialized first because
1808                   --  the offset of the new discriminants may depend on it
1809
1810                   Prepend_To (Body_Stmts, Remove_Head (Stmts));
1811                   Append_List_To (Body_Stmts, Stmts);
1812                end;
1813             end if;
1814          end if;
1815
1816          --  Add here the assignment to instantiate the Tag
1817
1818          --  The assignement corresponds to the code:
1819
1820          --     _Init._Tag := Typ'Tag;
1821
1822          --  Suppress the tag assignment when Java_VM because JVM tags are
1823          --  represented implicitly in objects.
1824
1825          if Is_Tagged_Type (Rec_Type)
1826            and then not Is_CPP_Class (Rec_Type)
1827            and then not Java_VM
1828          then
1829             Init_Tag :=
1830               Make_Assignment_Statement (Loc,
1831                 Name =>
1832                   Make_Selected_Component (Loc,
1833                     Prefix => Make_Identifier (Loc, Name_uInit),
1834                     Selector_Name =>
1835                       New_Reference_To (Tag_Component (Rec_Type), Loc)),
1836
1837                 Expression =>
1838                   New_Reference_To (Access_Disp_Table (Rec_Type), Loc));
1839
1840             --  The tag must be inserted before the assignments to other
1841             --  components,  because the initial value of the component may
1842             --  depend ot the tag (eg. through a dispatching operation on
1843             --  an access to the current type). The tag assignment is not done
1844             --  when initializing the parent component of a type extension,
1845             --  because in that case the tag is set in the extension.
1846             --  Extensions of imported C++ classes add a final complication,
1847             --  because we cannot inhibit tag setting in the constructor for
1848             --  the parent. In that case we insert the tag initialization
1849             --  after the calls to initialize the parent.
1850
1851             Init_Tag :=
1852               Make_If_Statement (Loc,
1853                 Condition => New_Occurrence_Of (Set_Tag, Loc),
1854                 Then_Statements => New_List (Init_Tag));
1855
1856             if not Is_CPP_Class (Etype (Rec_Type)) then
1857                Prepend_To (Body_Stmts, Init_Tag);
1858
1859             else
1860                declare
1861                   Nod : Node_Id := First (Body_Stmts);
1862
1863                begin
1864                   --  We assume the first init_proc call is for the parent
1865
1866                   while Present (Next (Nod))
1867                     and then (Nkind (Nod) /= N_Procedure_Call_Statement
1868                                or else not Is_Init_Proc (Name (Nod)))
1869                   loop
1870                      Nod := Next (Nod);
1871                   end loop;
1872
1873                   Insert_After (Nod, Init_Tag);
1874                end;
1875             end if;
1876          end if;
1877
1878          Handled_Stmt_Node := New_Node (N_Handled_Sequence_Of_Statements, Loc);
1879          Set_Statements (Handled_Stmt_Node, Body_Stmts);
1880          Set_Exception_Handlers (Handled_Stmt_Node, No_List);
1881          Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);
1882
1883          if not Debug_Generated_Code then
1884             Set_Debug_Info_Off (Proc_Id);
1885          end if;
1886
1887          --  Associate Init_Proc with type, and determine if the procedure
1888          --  is null (happens because of the Initialize_Scalars pragma case,
1889          --  where we have to generate a null procedure in case it is called
1890          --  by a client with Initialize_Scalars set). Such procedures have
1891          --  to be generated, but do not have to be called, so we mark them
1892          --  as null to suppress the call.
1893
1894          Set_Init_Proc (Rec_Type, Proc_Id);
1895
1896          if List_Length (Body_Stmts) = 1
1897            and then Nkind (First (Body_Stmts)) = N_Null_Statement
1898          then
1899             Set_Is_Null_Init_Proc (Proc_Id);
1900          end if;
1901       end Build_Init_Procedure;
1902
1903       ---------------------------
1904       -- Build_Init_Statements --
1905       ---------------------------
1906
1907       function Build_Init_Statements (Comp_List : Node_Id) return List_Id is
1908          Check_List     : constant List_Id := New_List;
1909          Alt_List       : List_Id;
1910          Statement_List : List_Id;
1911          Stmts          : List_Id;
1912
1913          Per_Object_Constraint_Components : Boolean;
1914
1915          Decl     : Node_Id;
1916          Variant  : Node_Id;
1917
1918          Id  : Entity_Id;
1919          Typ : Entity_Id;
1920
1921       begin
1922          if Null_Present (Comp_List) then
1923             return New_List (Make_Null_Statement (Loc));
1924          end if;
1925
1926          Statement_List := New_List;
1927
1928          --  Loop through components, skipping pragmas, in 2 steps. The first
1929          --  step deals with regular components. The second step deals with
1930          --  components have per object constraints, and no explicit initia-
1931          --  lization.
1932
1933          Per_Object_Constraint_Components := False;
1934
1935          --  First step : regular components.
1936
1937          Decl := First_Non_Pragma (Component_Items (Comp_List));
1938          while Present (Decl) loop
1939             Loc := Sloc (Decl);
1940             Build_Record_Checks
1941               (Subtype_Indication (Component_Definition (Decl)), Check_List);
1942
1943             Id := Defining_Identifier (Decl);
1944             Typ := Etype (Id);
1945
1946             if Has_Per_Object_Constraint (Id)
1947               and then No (Expression (Decl))
1948             then
1949                --  Skip processing for now and ask for a second pass
1950
1951                Per_Object_Constraint_Components := True;
1952
1953             else
1954                --  Case of explicit initialization
1955
1956                if Present (Expression (Decl)) then
1957                   Stmts := Build_Assignment (Id, Expression (Decl));
1958
1959                --  Case of composite component with its own Init_Proc
1960
1961                elsif Has_Non_Null_Base_Init_Proc (Typ) then
1962                   Stmts :=
1963                     Build_Initialization_Call
1964                       (Loc,
1965                        Make_Selected_Component (Loc,
1966                          Prefix => Make_Identifier (Loc, Name_uInit),
1967                          Selector_Name => New_Occurrence_Of (Id, Loc)),
1968                        Typ,
1969                        True,
1970                        Rec_Type,
1971                        Discr_Map => Discr_Map);
1972
1973                --  Case of component needing simple initialization
1974
1975                elsif Component_Needs_Simple_Initialization (Typ) then
1976                   Stmts :=
1977                     Build_Assignment (Id, Get_Simple_Init_Val (Typ, Loc));
1978
1979                --  Nothing needed for this case
1980
1981                else
1982                   Stmts := No_List;
1983                end if;
1984
1985                if Present (Check_List) then
1986                   Append_List_To (Statement_List, Check_List);
1987                end if;
1988
1989                if Present (Stmts) then
1990
1991                   --  Add the initialization of the record controller before
1992                   --  the _Parent field is attached to it when the attachment
1993                   --  can occur. It does not work to simply initialize the
1994                   --  controller first: it must be initialized after the parent
1995                   --  if the parent holds discriminants that can be used
1996                   --  to compute the offset of the controller. We assume here
1997                   --  that the last statement of the initialization call is the
1998                   --  attachement of the parent (see Build_Initialization_Call)
1999
2000                   if Chars (Id) = Name_uController
2001                     and then Rec_Type /= Etype (Rec_Type)
2002                     and then Has_Controlled_Component (Etype (Rec_Type))
2003                     and then Has_New_Controlled_Component (Rec_Type)
2004                   then
2005                      Insert_List_Before (Last (Statement_List), Stmts);
2006                   else
2007                      Append_List_To (Statement_List, Stmts);
2008                   end if;
2009                end if;
2010             end if;
2011
2012             Next_Non_Pragma (Decl);
2013          end loop;
2014
2015          if Per_Object_Constraint_Components then
2016
2017             --  Second pass: components with per-object constraints
2018
2019             Decl := First_Non_Pragma (Component_Items (Comp_List));
2020
2021             while Present (Decl) loop
2022                Loc := Sloc (Decl);
2023                Id := Defining_Identifier (Decl);
2024                Typ := Etype (Id);
2025
2026                if Has_Per_Object_Constraint (Id)
2027                  and then No (Expression (Decl))
2028                then
2029                   if Has_Non_Null_Base_Init_Proc (Typ) then
2030                      Append_List_To (Statement_List,
2031                        Build_Initialization_Call (Loc,
2032                          Make_Selected_Component (Loc,
2033                            Prefix => Make_Identifier (Loc, Name_uInit),
2034                            Selector_Name => New_Occurrence_Of (Id, Loc)),
2035                          Typ, True, Rec_Type, Discr_Map => Discr_Map));
2036
2037                   elsif Component_Needs_Simple_Initialization (Typ) then
2038                      Append_List_To (Statement_List,
2039                        Build_Assignment (Id, Get_Simple_Init_Val (Typ, Loc)));
2040                   end if;
2041                end if;
2042
2043                Next_Non_Pragma (Decl);
2044             end loop;
2045          end if;
2046
2047          --  Process the variant part
2048
2049          if Present (Variant_Part (Comp_List)) then
2050             Alt_List := New_List;
2051             Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
2052
2053             while Present (Variant) loop
2054                Loc := Sloc (Variant);
2055                Append_To (Alt_List,
2056                  Make_Case_Statement_Alternative (Loc,
2057                    Discrete_Choices =>
2058                      New_Copy_List (Discrete_Choices (Variant)),
2059                    Statements =>
2060                      Build_Init_Statements (Component_List (Variant))));
2061
2062                Next_Non_Pragma (Variant);
2063             end loop;
2064
2065             --  The expression of the case statement which is a reference
2066             --  to one of the discriminants is replaced by the appropriate
2067             --  formal parameter of the initialization procedure.
2068
2069             Append_To (Statement_List,
2070               Make_Case_Statement (Loc,
2071                 Expression =>
2072                   New_Reference_To (Discriminal (
2073                     Entity (Name (Variant_Part (Comp_List)))), Loc),
2074                 Alternatives => Alt_List));
2075          end if;
2076
2077          --  For a task record type, add the task create call and calls
2078          --  to bind any interrupt (signal) entries.
2079
2080          if Is_Task_Record_Type (Rec_Type) then
2081             Append_To (Statement_List, Make_Task_Create_Call (Rec_Type));
2082
2083             declare
2084                Task_Type : constant Entity_Id :=
2085                              Corresponding_Concurrent_Type (Rec_Type);
2086                Task_Decl : constant Node_Id := Parent (Task_Type);
2087                Task_Def  : constant Node_Id := Task_Definition (Task_Decl);
2088                Vis_Decl  : Node_Id;
2089                Ent       : Entity_Id;
2090
2091             begin
2092                if Present (Task_Def) then
2093                   Vis_Decl := First (Visible_Declarations (Task_Def));
2094                   while Present (Vis_Decl) loop
2095                      Loc := Sloc (Vis_Decl);
2096
2097                      if Nkind (Vis_Decl) = N_Attribute_Definition_Clause then
2098                         if Get_Attribute_Id (Chars (Vis_Decl)) =
2099                                                        Attribute_Address
2100                         then
2101                            Ent := Entity (Name (Vis_Decl));
2102
2103                            if Ekind (Ent) = E_Entry then
2104                               Append_To (Statement_List,
2105                                 Make_Procedure_Call_Statement (Loc,
2106                                   Name => New_Reference_To (
2107                                     RTE (RE_Bind_Interrupt_To_Entry), Loc),
2108                                   Parameter_Associations => New_List (
2109                                     Make_Selected_Component (Loc,
2110                                       Prefix =>
2111                                         Make_Identifier (Loc, Name_uInit),
2112                                       Selector_Name =>
2113                                         Make_Identifier (Loc, Name_uTask_Id)),
2114                                     Entry_Index_Expression (
2115                                       Loc, Ent, Empty, Task_Type),
2116                                     Expression (Vis_Decl))));
2117                            end if;
2118                         end if;
2119                      end if;
2120
2121                      Next (Vis_Decl);
2122                   end loop;
2123                end if;
2124             end;
2125          end if;
2126
2127          --  For a protected type, add statements generated by
2128          --  Make_Initialize_Protection.
2129
2130          if Is_Protected_Record_Type (Rec_Type) then
2131             Append_List_To (Statement_List,
2132               Make_Initialize_Protection (Rec_Type));
2133          end if;
2134
2135          --  If no initializations when generated for component declarations
2136          --  corresponding to this Statement_List, append a null statement
2137          --  to the Statement_List to make it a valid Ada tree.
2138
2139          if Is_Empty_List (Statement_List) then
2140             Append (New_Node (N_Null_Statement, Loc), Statement_List);
2141          end if;
2142
2143          return Statement_List;
2144
2145       exception
2146          when RE_Not_Available =>
2147          return Empty_List;
2148       end Build_Init_Statements;
2149
2150       -------------------------
2151       -- Build_Record_Checks --
2152       -------------------------
2153
2154       procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id) is
2155          Subtype_Mark_Id : Entity_Id;
2156
2157       begin
2158          if Nkind (S) = N_Subtype_Indication then
2159             Find_Type (Subtype_Mark (S));
2160             Subtype_Mark_Id := Entity (Subtype_Mark (S));
2161
2162             --  Remaining processing depends on type
2163
2164             case Ekind (Subtype_Mark_Id) is
2165
2166                when Array_Kind =>
2167                   Constrain_Array (S, Check_List);
2168
2169                when others =>
2170                   null;
2171             end case;
2172          end if;
2173       end Build_Record_Checks;
2174
2175       -------------------------------------------
2176       -- Component_Needs_Simple_Initialization --
2177       -------------------------------------------
2178
2179       function Component_Needs_Simple_Initialization
2180         (T    : Entity_Id)
2181          return Boolean
2182       is
2183       begin
2184          return
2185            Needs_Simple_Initialization (T)
2186              and then not Is_RTE (T, RE_Tag)
2187              and then not Is_RTE (T, RE_Vtable_Ptr)
2188              and then not Is_Bit_Packed_Array (T);
2189       end Component_Needs_Simple_Initialization;
2190
2191       ---------------------
2192       -- Constrain_Array --
2193       ---------------------
2194
2195       procedure Constrain_Array
2196         (SI          : Node_Id;
2197          Check_List  : List_Id)
2198       is
2199          C                     : constant Node_Id := Constraint (SI);
2200          Number_Of_Constraints : Nat := 0;
2201          Index                 : Node_Id;
2202          S, T                  : Entity_Id;
2203
2204       begin
2205          T := Entity (Subtype_Mark (SI));
2206
2207          if Ekind (T) in Access_Kind then
2208             T := Designated_Type (T);
2209          end if;
2210
2211          S := First (Constraints (C));
2212
2213          while Present (S) loop
2214             Number_Of_Constraints := Number_Of_Constraints + 1;
2215             Next (S);
2216          end loop;
2217
2218          --  In either case, the index constraint must provide a discrete
2219          --  range for each index of the array type and the type of each
2220          --  discrete range must be the same as that of the corresponding
2221          --  index. (RM 3.6.1)
2222
2223          S := First (Constraints (C));
2224          Index := First_Index (T);
2225          Analyze (Index);
2226
2227          --  Apply constraints to each index type
2228
2229          for J in 1 .. Number_Of_Constraints loop
2230             Constrain_Index (Index, S, Check_List);
2231             Next (Index);
2232             Next (S);
2233          end loop;
2234
2235       end Constrain_Array;
2236
2237       ---------------------
2238       -- Constrain_Index --
2239       ---------------------
2240
2241       procedure Constrain_Index
2242         (Index        : Node_Id;
2243          S            : Node_Id;
2244          Check_List   : List_Id)
2245       is
2246          T : constant Entity_Id := Etype (Index);
2247
2248       begin
2249          if Nkind (S) = N_Range then
2250             Process_Range_Expr_In_Decl (S, T, Check_List);
2251          end if;
2252       end Constrain_Index;
2253
2254       --------------------------------------
2255       -- Parent_Subtype_Renaming_Discrims --
2256       --------------------------------------
2257
2258       function Parent_Subtype_Renaming_Discrims return Boolean is
2259          De : Entity_Id;
2260          Dp : Entity_Id;
2261
2262       begin
2263          if Base_Type (Pe) /= Pe then
2264             return False;
2265          end if;
2266
2267          if Etype (Pe) = Pe
2268            or else not Has_Discriminants (Pe)
2269            or else Is_Constrained (Pe)
2270            or else Is_Tagged_Type (Pe)
2271          then
2272             return False;
2273          end if;
2274
2275          --  If there are no explicit stored discriminants we have inherited
2276          --  the root type discriminants so far, so no renamings occurred.
2277
2278          if First_Discriminant (Pe) = First_Stored_Discriminant (Pe) then
2279             return False;
2280          end if;
2281
2282          --  Check if we have done some trivial renaming of the parent
2283          --  discriminants, i.e. someting like
2284          --
2285          --    type DT (X1,X2: int) is new PT (X1,X2);
2286
2287          De := First_Discriminant (Pe);
2288          Dp := First_Discriminant (Etype (Pe));
2289
2290          while Present (De) loop
2291             pragma Assert (Present (Dp));
2292
2293             if Corresponding_Discriminant (De) /= Dp then
2294                return True;
2295             end if;
2296
2297             Next_Discriminant (De);
2298             Next_Discriminant (Dp);
2299          end loop;
2300
2301          return Present (Dp);
2302       end Parent_Subtype_Renaming_Discrims;
2303
2304       ------------------------
2305       -- Requires_Init_Proc --
2306       ------------------------
2307
2308       function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean is
2309          Comp_Decl : Node_Id;
2310          Id        : Entity_Id;
2311          Typ       : Entity_Id;
2312
2313       begin
2314          --  Definitely do not need one if specifically suppressed
2315
2316          if Suppress_Init_Proc (Rec_Id) then
2317             return False;
2318          end if;
2319
2320          --  Otherwise we need to generate an initialization procedure if
2321          --  Is_CPP_Class is False and at least one of the following applies:
2322
2323          --  1. Discriminants are present, since they need to be initialized
2324          --     with the appropriate discriminant constraint expressions.
2325          --     However, the discriminant of an unchecked union does not
2326          --     count, since the discriminant is not present.
2327
2328          --  2. The type is a tagged type, since the implicit Tag component
2329          --     needs to be initialized with a pointer to the dispatch table.
2330
2331          --  3. The type contains tasks
2332
2333          --  4. One or more components has an initial value
2334
2335          --  5. One or more components is for a type which itself requires
2336          --     an initialization procedure.
2337
2338          --  6. One or more components is a type that requires simple
2339          --     initialization (see Needs_Simple_Initialization), except
2340          --     that types Tag and Vtable_Ptr are excluded, since fields
2341          --     of these types are initialized by other means.
2342
2343          --  7. The type is the record type built for a task type (since at
2344          --     the very least, Create_Task must be called)
2345
2346          --  8. The type is the record type built for a protected type (since
2347          --     at least Initialize_Protection must be called)
2348
2349          --  9. The type is marked as a public entity. The reason we add this
2350          --     case (even if none of the above apply) is to properly handle
2351          --     Initialize_Scalars. If a package is compiled without an IS
2352          --     pragma, and the client is compiled with an IS pragma, then
2353          --     the client will think an initialization procedure is present
2354          --     and call it, when in fact no such procedure is required, but
2355          --     since the call is generated, there had better be a routine
2356          --     at the other end of the call, even if it does nothing!)
2357
2358          --  Note: the reason we exclude the CPP_Class case is ???
2359
2360          if Is_CPP_Class (Rec_Id) then
2361             return False;
2362
2363          elsif not Restrictions (No_Initialize_Scalars)
2364            and then Is_Public (Rec_Id)
2365          then
2366             return True;
2367
2368          elsif (Has_Discriminants (Rec_Id)
2369                   and then not Is_Unchecked_Union (Rec_Id))
2370            or else Is_Tagged_Type (Rec_Id)
2371            or else Is_Concurrent_Record_Type (Rec_Id)
2372            or else Has_Task (Rec_Id)
2373          then
2374             return True;
2375          end if;
2376
2377          Id := First_Component (Rec_Id);
2378
2379          while Present (Id) loop
2380             Comp_Decl := Parent (Id);
2381             Typ := Etype (Id);
2382
2383             if Present (Expression (Comp_Decl))
2384               or else Has_Non_Null_Base_Init_Proc (Typ)
2385               or else Component_Needs_Simple_Initialization (Typ)
2386             then
2387                return True;
2388             end if;
2389
2390             Next_Component (Id);
2391          end loop;
2392
2393          return False;
2394       end Requires_Init_Proc;
2395
2396    --  Start of processing for Build_Record_Init_Proc
2397
2398    begin
2399       Rec_Type := Defining_Identifier (N);
2400
2401       --  This may be full declaration of a private type, in which case
2402       --  the visible entity is a record, and the private entity has been
2403       --  exchanged with it in the private part of the current package.
2404       --  The initialization procedure is built for the record type, which
2405       --  is retrievable from the private entity.
2406
2407       if Is_Incomplete_Or_Private_Type (Rec_Type) then
2408          Rec_Type := Underlying_Type (Rec_Type);
2409       end if;
2410
2411       --  If there are discriminants, build the discriminant map to replace
2412       --  discriminants by their discriminals in complex bound expressions.
2413       --  These only arise for the corresponding records of protected types.
2414
2415       if Is_Concurrent_Record_Type (Rec_Type)
2416         and then Has_Discriminants (Rec_Type)
2417       then
2418          declare
2419             Disc : Entity_Id;
2420
2421          begin
2422             Disc := First_Discriminant (Rec_Type);
2423
2424             while Present (Disc) loop
2425                Append_Elmt (Disc, Discr_Map);
2426                Append_Elmt (Discriminal (Disc), Discr_Map);
2427                Next_Discriminant (Disc);
2428             end loop;
2429          end;
2430       end if;
2431
2432       --  Derived types that have no type extension can use the initialization
2433       --  procedure of their parent and do not need a procedure of their own.
2434       --  This is only correct if there are no representation clauses for the
2435       --  type or its parent, and if the parent has in fact been frozen so
2436       --  that its initialization procedure exists.
2437
2438       if Is_Derived_Type (Rec_Type)
2439         and then not Is_Tagged_Type (Rec_Type)
2440         and then not Has_New_Non_Standard_Rep (Rec_Type)
2441         and then not Parent_Subtype_Renaming_Discrims
2442         and then Has_Non_Null_Base_Init_Proc (Etype (Rec_Type))
2443       then
2444          Copy_TSS (Base_Init_Proc (Etype (Rec_Type)), Rec_Type);
2445
2446       --  Otherwise if we need an initialization procedure, then build one,
2447       --  mark it as public and inlinable and as having a completion.
2448
2449       elsif Requires_Init_Proc (Rec_Type) then
2450          Build_Init_Procedure;
2451          Set_Is_Public (Proc_Id, Is_Public (Pe));
2452
2453          --  The initialization of protected records is not worth inlining.
2454          --  In addition, when compiled for another unit for inlining purposes,
2455          --  it may make reference to entities that have not been elaborated
2456          --  yet. The initialization of controlled records contains a nested
2457          --  clean-up procedure that makes it impractical to inline as well,
2458          --  and leads to undefined symbols if inlined in a different unit.
2459          --  Similar considerations apply to task types.
2460
2461          if not Is_Concurrent_Type (Rec_Type)
2462            and then not Has_Task (Rec_Type)
2463            and then not Controlled_Type (Rec_Type)
2464          then
2465             Set_Is_Inlined  (Proc_Id);
2466          end if;
2467
2468          Set_Is_Internal    (Proc_Id);
2469          Set_Has_Completion (Proc_Id);
2470
2471          if not Debug_Generated_Code then
2472             Set_Debug_Info_Off (Proc_Id);
2473          end if;
2474       end if;
2475    end Build_Record_Init_Proc;
2476
2477    ------------------------------------
2478    -- Build_Variant_Record_Equality --
2479    ------------------------------------
2480
2481    --  Generates:
2482    --
2483    --    function _Equality (X, Y : T) return Boolean is
2484    --    begin
2485    --       --  Compare discriminants
2486
2487    --       if False or else X.D1 /= Y.D1 or else X.D2 /= Y.D2 then
2488    --          return False;
2489    --       end if;
2490
2491    --       --  Compare components
2492
2493    --       if False or else X.C1 /= Y.C1 or else X.C2 /= Y.C2 then
2494    --          return False;
2495    --       end if;
2496
2497    --       --  Compare variant part
2498
2499    --       case X.D1 is
2500    --          when V1 =>
2501    --             if False or else X.C2 /= Y.C2 or else X.C3 /= Y.C3 then
2502    --                return False;
2503    --             end if;
2504    --          ...
2505    --          when Vn =>
2506    --             if False or else X.Cn /= Y.Cn then
2507    --                return False;
2508    --             end if;
2509    --       end case;
2510    --       return True;
2511    --    end _Equality;
2512
2513    procedure Build_Variant_Record_Equality (Typ : Entity_Id) is
2514       Loc   : constant Source_Ptr := Sloc (Typ);
2515
2516       F : constant Entity_Id :=
2517             Make_Defining_Identifier (Loc,
2518               Chars => Make_TSS_Name (Typ, TSS_Composite_Equality));
2519
2520       X : constant Entity_Id :=
2521            Make_Defining_Identifier (Loc,
2522              Chars => Name_X);
2523
2524       Y : constant Entity_Id :=
2525             Make_Defining_Identifier (Loc,
2526               Chars => Name_Y);
2527
2528       Def   : constant Node_Id := Parent (Typ);
2529       Comps : constant Node_Id := Component_List (Type_Definition (Def));
2530       Stmts : constant List_Id := New_List;
2531
2532    begin
2533       if Is_Derived_Type (Typ)
2534         and then not Has_New_Non_Standard_Rep (Typ)
2535       then
2536          declare
2537             Parent_Eq : constant Entity_Id :=
2538                           TSS (Root_Type (Typ), TSS_Composite_Equality);
2539
2540          begin
2541             if Present (Parent_Eq) then
2542                Copy_TSS (Parent_Eq, Typ);
2543                return;
2544             end if;
2545          end;
2546       end if;
2547
2548       Discard_Node (
2549         Make_Subprogram_Body (Loc,
2550           Specification =>
2551             Make_Function_Specification (Loc,
2552               Defining_Unit_Name       => F,
2553               Parameter_Specifications => New_List (
2554                 Make_Parameter_Specification (Loc,
2555                   Defining_Identifier => X,
2556                   Parameter_Type      => New_Reference_To (Typ, Loc)),
2557
2558                 Make_Parameter_Specification (Loc,
2559                   Defining_Identifier => Y,
2560                   Parameter_Type      => New_Reference_To (Typ, Loc))),
2561
2562               Subtype_Mark => New_Reference_To (Standard_Boolean, Loc)),
2563
2564           Declarations               => New_List,
2565           Handled_Statement_Sequence =>
2566             Make_Handled_Sequence_Of_Statements (Loc,
2567               Statements => Stmts)));
2568
2569       --  For unchecked union case, raise program error. This will only
2570       --  happen in the case of dynamic dispatching for a tagged type,
2571       --  since in the static cases it is a compile time error.
2572
2573       if Has_Unchecked_Union (Typ) then
2574          Append_To (Stmts,
2575            Make_Raise_Program_Error (Loc,
2576              Reason => PE_Unchecked_Union_Restriction));
2577       else
2578          Append_To (Stmts,
2579            Make_Eq_If (Typ,
2580              Discriminant_Specifications (Def)));
2581          Append_List_To (Stmts,
2582            Make_Eq_Case (Typ, Comps));
2583       end if;
2584
2585       Append_To (Stmts,
2586         Make_Return_Statement (Loc,
2587           Expression => New_Reference_To (Standard_True, Loc)));
2588
2589       Set_TSS (Typ, F);
2590       Set_Is_Pure (F);
2591
2592       if not Debug_Generated_Code then
2593          Set_Debug_Info_Off (F);
2594       end if;
2595    end Build_Variant_Record_Equality;
2596
2597    -----------------------------
2598    -- Check_Stream_Attributes --
2599    -----------------------------
2600
2601    procedure Check_Stream_Attributes (Typ : Entity_Id) is
2602       Comp      : Entity_Id;
2603       Par       : constant Entity_Id := Root_Type (Base_Type (Typ));
2604       Par_Read  : constant Boolean   := Present (TSS (Par, TSS_Stream_Read));
2605       Par_Write : constant Boolean   := Present (TSS (Par, TSS_Stream_Write));
2606
2607    begin
2608       if Par_Read or else Par_Write then
2609          Comp := First_Component (Typ);
2610          while Present (Comp) loop
2611             if Comes_From_Source (Comp)
2612               and then  Original_Record_Component (Comp) = Comp
2613               and then Is_Limited_Type (Etype (Comp))
2614             then
2615                if (Par_Read and then
2616                      No (TSS (Base_Type (Etype (Comp)), TSS_Stream_Read)))
2617                  or else
2618                   (Par_Write and then
2619                      No (TSS (Base_Type (Etype (Comp)), TSS_Stream_Write)))
2620                then
2621                   Error_Msg_N
2622                     ("|component must have Stream attribute",
2623                        Parent (Comp));
2624                end if;
2625             end if;
2626
2627             Next_Component (Comp);
2628          end loop;
2629       end if;
2630    end Check_Stream_Attributes;
2631
2632    ---------------------------
2633    -- Expand_Derived_Record --
2634    ---------------------------
2635
2636    --  Add a field _parent at the beginning of the record extension. This is
2637    --  used to implement inheritance. Here are some examples of expansion:
2638
2639    --  1. no discriminants
2640    --      type T2 is new T1 with null record;
2641    --   gives
2642    --      type T2 is new T1 with record
2643    --        _Parent : T1;
2644    --      end record;
2645
2646    --  2. renamed discriminants
2647    --    type T2 (B, C : Int) is new T1 (A => B) with record
2648    --       _Parent : T1 (A => B);
2649    --       D : Int;
2650    --    end;
2651
2652    --  3. inherited discriminants
2653    --    type T2 is new T1 with record -- discriminant A inherited
2654    --       _Parent : T1 (A);
2655    --       D : Int;
2656    --    end;
2657
2658    procedure Expand_Derived_Record (T : Entity_Id; Def : Node_Id) is
2659       Indic        : constant Node_Id    := Subtype_Indication (Def);
2660       Loc          : constant Source_Ptr := Sloc (Def);
2661       Rec_Ext_Part : Node_Id             := Record_Extension_Part (Def);
2662       Par_Subtype  : Entity_Id;
2663       Comp_List    : Node_Id;
2664       Comp_Decl    : Node_Id;
2665       Parent_N     : Node_Id;
2666       D            : Entity_Id;
2667       List_Constr  : constant List_Id    := New_List;
2668
2669    begin
2670       --  Expand_Tagged_Extension is called directly from the semantics, so
2671       --  we must check to see whether expansion is active before proceeding
2672
2673       if not Expander_Active then
2674          return;
2675       end if;
2676
2677       --  This may be a derivation of an untagged private type whose full
2678       --  view is tagged, in which case the Derived_Type_Definition has no
2679       --  extension part. Build an empty one now.
2680
2681       if No (Rec_Ext_Part) then
2682          Rec_Ext_Part :=
2683            Make_Record_Definition (Loc,
2684              End_Label      => Empty,
2685              Component_List => Empty,
2686              Null_Present   => True);
2687
2688          Set_Record_Extension_Part (Def, Rec_Ext_Part);
2689          Mark_Rewrite_Insertion (Rec_Ext_Part);
2690       end if;
2691
2692       Comp_List := Component_List (Rec_Ext_Part);
2693
2694       Parent_N := Make_Defining_Identifier (Loc, Name_uParent);
2695
2696       --  If the derived type inherits its discriminants the type of the
2697       --  _parent field must be constrained by the inherited discriminants
2698
2699       if Has_Discriminants (T)
2700         and then Nkind (Indic) /= N_Subtype_Indication
2701         and then not Is_Constrained (Entity (Indic))
2702       then
2703          D := First_Discriminant (T);
2704          while Present (D) loop
2705             Append_To (List_Constr, New_Occurrence_Of (D, Loc));
2706             Next_Discriminant (D);
2707          end loop;
2708
2709          Par_Subtype :=
2710            Process_Subtype (
2711              Make_Subtype_Indication (Loc,
2712                Subtype_Mark => New_Reference_To (Entity (Indic), Loc),
2713                Constraint   =>
2714                  Make_Index_Or_Discriminant_Constraint (Loc,
2715                    Constraints => List_Constr)),
2716              Def);
2717
2718       --  Otherwise the original subtype_indication is just what is needed
2719
2720       else
2721          Par_Subtype := Process_Subtype (New_Copy_Tree (Indic), Def);
2722       end if;
2723
2724       Set_Parent_Subtype (T, Par_Subtype);
2725
2726       Comp_Decl :=
2727         Make_Component_Declaration (Loc,
2728           Defining_Identifier => Parent_N,
2729           Component_Definition =>
2730             Make_Component_Definition (Loc,
2731               Aliased_Present => False,
2732               Subtype_Indication => New_Reference_To (Par_Subtype, Loc)));
2733
2734       if Null_Present (Rec_Ext_Part) then
2735          Set_Component_List (Rec_Ext_Part,
2736            Make_Component_List (Loc,
2737              Component_Items => New_List (Comp_Decl),
2738              Variant_Part => Empty,
2739              Null_Present => False));
2740          Set_Null_Present (Rec_Ext_Part, False);
2741
2742       elsif Null_Present (Comp_List)
2743         or else Is_Empty_List (Component_Items (Comp_List))
2744       then
2745          Set_Component_Items (Comp_List, New_List (Comp_Decl));
2746          Set_Null_Present (Comp_List, False);
2747
2748       else
2749          Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
2750       end if;
2751
2752       Analyze (Comp_Decl);
2753    end Expand_Derived_Record;
2754
2755    ------------------------------------
2756    -- Expand_N_Full_Type_Declaration --
2757    ------------------------------------
2758
2759    procedure Expand_N_Full_Type_Declaration (N : Node_Id) is
2760       Def_Id : constant Entity_Id := Defining_Identifier (N);
2761       B_Id   : constant Entity_Id := Base_Type (Def_Id);
2762       Par_Id : Entity_Id;
2763       FN     : Node_Id;
2764
2765    begin
2766       if Is_Access_Type (Def_Id) then
2767
2768          --  Anonymous access types are created for the components of the
2769          --  record parameter for an entry declaration.  No master is created
2770          --  for such a type.
2771
2772          if Has_Task (Designated_Type (Def_Id))
2773            and then Comes_From_Source (N)
2774          then
2775             Build_Master_Entity (Def_Id);
2776             Build_Master_Renaming (Parent (Def_Id), Def_Id);
2777
2778          --  Create a class-wide master because a Master_Id must be generated
2779          --  for access-to-limited-class-wide types, whose root may be extended
2780          --  with task components.
2781
2782          elsif Is_Class_Wide_Type (Designated_Type (Def_Id))
2783            and then Is_Limited_Type (Designated_Type (Def_Id))
2784            and then Tasking_Allowed
2785
2786             --  Don't create a class-wide master for types whose convention is
2787             --  Java since these types cannot embed Ada tasks anyway. Note that
2788             --  the following test cannot catch the following case:
2789             --
2790             --      package java.lang.Object is
2791             --         type Typ is tagged limited private;
2792             --         type Ref is access all Typ'Class;
2793             --      private
2794             --         type Typ is tagged limited ...;
2795             --         pragma Convention (Typ, Java)
2796             --      end;
2797             --
2798             --  Because the convention appears after we have done the
2799             --  processing for type Ref.
2800
2801            and then Convention (Designated_Type (Def_Id)) /= Convention_Java
2802          then
2803             Build_Class_Wide_Master (Def_Id);
2804
2805          elsif Ekind (Def_Id) = E_Access_Protected_Subprogram_Type then
2806             Expand_Access_Protected_Subprogram_Type (N);
2807          end if;
2808
2809       elsif Has_Task (Def_Id) then
2810          Expand_Previous_Access_Type (Def_Id);
2811       end if;
2812
2813       Par_Id := Etype (B_Id);
2814
2815       --  The parent type is private then we need to inherit
2816       --  any TSS operations from the full view.
2817
2818       if Ekind (Par_Id) in Private_Kind
2819         and then Present (Full_View (Par_Id))
2820       then
2821          Par_Id := Base_Type (Full_View (Par_Id));
2822       end if;
2823
2824       if Nkind (Type_Definition (Original_Node (N)))
2825          = N_Derived_Type_Definition
2826         and then not Is_Tagged_Type (Def_Id)
2827         and then Present (Freeze_Node (Par_Id))
2828         and then Present (TSS_Elist (Freeze_Node (Par_Id)))
2829       then
2830          Ensure_Freeze_Node (B_Id);
2831          FN :=  Freeze_Node (B_Id);
2832
2833          if No (TSS_Elist (FN)) then
2834             Set_TSS_Elist (FN, New_Elmt_List);
2835          end if;
2836
2837          declare
2838             T_E   : constant Elist_Id := TSS_Elist (FN);
2839             Elmt  : Elmt_Id;
2840
2841          begin
2842             Elmt  := First_Elmt (TSS_Elist (Freeze_Node (Par_Id)));
2843
2844             while Present (Elmt) loop
2845                if Chars (Node (Elmt)) /= Name_uInit then
2846                   Append_Elmt (Node (Elmt), T_E);
2847                end if;
2848
2849                Next_Elmt (Elmt);
2850             end loop;
2851
2852             --  If the derived type itself is private with a full view,
2853             --  then associate the full view with the inherited TSS_Elist
2854             --  as well.
2855
2856             if Ekind (B_Id) in Private_Kind
2857               and then Present (Full_View (B_Id))
2858             then
2859                Ensure_Freeze_Node (Base_Type (Full_View (B_Id)));
2860                Set_TSS_Elist
2861                  (Freeze_Node (Base_Type (Full_View (B_Id))), TSS_Elist (FN));
2862             end if;
2863          end;
2864       end if;
2865    end Expand_N_Full_Type_Declaration;
2866
2867    ---------------------------------
2868    -- Expand_N_Object_Declaration --
2869    ---------------------------------
2870
2871    --  First we do special processing for objects of a tagged type where this
2872    --  is the point at which the type is frozen. The creation of the dispatch
2873    --  table and the initialization procedure have to be deferred to this
2874    --  point, since we reference previously declared primitive subprograms.
2875
2876    --  For all types, we call an initialization procedure if there is one
2877
2878    procedure Expand_N_Object_Declaration (N : Node_Id) is
2879       Def_Id  : constant Entity_Id  := Defining_Identifier (N);
2880       Typ     : constant Entity_Id  := Etype (Def_Id);
2881       Loc     : constant Source_Ptr := Sloc (N);
2882       Expr    : constant Node_Id    := Expression (N);
2883       New_Ref : Node_Id;
2884       Id_Ref  : Node_Id;
2885       Expr_Q  : Node_Id;
2886
2887    begin
2888       --  Don't do anything for deferred constants. All proper actions will
2889       --  be expanded during the full declaration.
2890
2891       if No (Expr) and Constant_Present (N) then
2892          return;
2893       end if;
2894
2895       --  Make shared memory routines for shared passive variable
2896
2897       if Is_Shared_Passive (Def_Id) then
2898          Make_Shared_Var_Procs (N);
2899       end if;
2900
2901       --  If tasks being declared, make sure we have an activation chain
2902       --  defined for the tasks (has no effect if we already have one), and
2903       --  also that a Master variable is established and that the appropriate
2904       --  enclosing construct is established as a task master.
2905
2906       if Has_Task (Typ) then
2907          Build_Activation_Chain_Entity (N);
2908          Build_Master_Entity (Def_Id);
2909       end if;
2910
2911       --  Default initialization required, and no expression present
2912
2913       if No (Expr) then
2914
2915          --  Expand Initialize call for controlled objects.  One may wonder why
2916          --  the Initialize Call is not done in the regular Init procedure
2917          --  attached to the record type. That's because the init procedure is
2918          --  recursively called on each component, including _Parent, thus the
2919          --  Init call for a controlled object would generate not only one
2920          --  Initialize call as it is required but one for each ancestor of
2921          --  its type. This processing is suppressed if No_Initialization set.
2922
2923          if not Controlled_Type (Typ)
2924            or else No_Initialization (N)
2925          then
2926             null;
2927
2928          elsif not Abort_Allowed
2929            or else not Comes_From_Source (N)
2930          then
2931             Insert_Actions_After (N,
2932               Make_Init_Call (
2933                 Ref         => New_Occurrence_Of (Def_Id, Loc),
2934                 Typ         => Base_Type (Typ),
2935                 Flist_Ref   => Find_Final_List (Def_Id),
2936                 With_Attach => Make_Integer_Literal (Loc, 1)));
2937
2938          --  Abort allowed
2939
2940          else
2941             --  We need to protect the initialize call
2942
2943             --  begin
2944             --     Defer_Abort.all;
2945             --     Initialize (...);
2946             --  at end
2947             --     Undefer_Abort.all;
2948             --  end;
2949
2950             --  ??? this won't protect the initialize call for controlled
2951             --  components which are part of the init proc, so this block
2952             --  should probably also contain the call to _init_proc but this
2953             --  requires some code reorganization...
2954
2955             declare
2956                L   : constant List_Id :=
2957                       Make_Init_Call (
2958                         Ref         => New_Occurrence_Of (Def_Id, Loc),
2959                         Typ         => Base_Type (Typ),
2960                         Flist_Ref   => Find_Final_List (Def_Id),
2961                         With_Attach => Make_Integer_Literal (Loc, 1));
2962
2963                Blk : constant Node_Id :=
2964                  Make_Block_Statement (Loc,
2965                    Handled_Statement_Sequence =>
2966                      Make_Handled_Sequence_Of_Statements (Loc, L));
2967
2968             begin
2969                Prepend_To (L, Build_Runtime_Call (Loc, RE_Abort_Defer));
2970                Set_At_End_Proc (Handled_Statement_Sequence (Blk),
2971                  New_Occurrence_Of (RTE (RE_Abort_Undefer_Direct), Loc));
2972                Insert_Actions_After (N, New_List (Blk));
2973                Expand_At_End_Handler
2974                  (Handled_Statement_Sequence (Blk), Entity (Identifier (Blk)));
2975             end;
2976          end if;
2977
2978          --  Call type initialization procedure if there is one. We build the
2979          --  call and put it immediately after the object declaration, so that
2980          --  it will be expanded in the usual manner. Note that this will
2981          --  result in proper handling of defaulted discriminants. The call
2982          --  to the Init_Proc is suppressed if No_Initialization is set.
2983
2984          if Has_Non_Null_Base_Init_Proc (Typ)
2985            and then not No_Initialization (N)
2986          then
2987             --  The call to the initialization procedure does NOT freeze
2988             --  the object being initialized. This is because the call is
2989             --  not a source level call. This works fine, because the only
2990             --  possible statements depending on freeze status that can
2991             --  appear after the _Init call are rep clauses which can
2992             --  safely appear after actual references to the object.
2993
2994             Id_Ref := New_Reference_To (Def_Id, Loc);
2995             Set_Must_Not_Freeze (Id_Ref);
2996             Set_Assignment_OK (Id_Ref);
2997
2998             Insert_Actions_After (N,
2999               Build_Initialization_Call (Loc, Id_Ref, Typ));
3000
3001          --  If simple initialization is required, then set an appropriate
3002          --  simple initialization expression in place. This special
3003          --  initialization is required even though No_Init_Flag is present.
3004
3005          elsif Needs_Simple_Initialization (Typ) then
3006             Set_No_Initialization (N, False);
3007             Set_Expression (N, Get_Simple_Init_Val (Typ, Loc));
3008             Analyze_And_Resolve (Expression (N), Typ);
3009          end if;
3010
3011       --  Explicit initialization present
3012
3013       else
3014          --  Obtain actual expression from qualified expression
3015
3016          if Nkind (Expr) = N_Qualified_Expression then
3017             Expr_Q := Expression (Expr);
3018          else
3019             Expr_Q := Expr;
3020          end if;
3021
3022          --  When we have the appropriate type of aggregate in the
3023          --  expression (it has been determined during analysis of the
3024          --  aggregate by setting the delay flag), let's perform in
3025          --  place assignment and thus avoid creating a temporary.
3026
3027          if Is_Delayed_Aggregate (Expr_Q) then
3028             Convert_Aggr_In_Object_Decl (N);
3029
3030          else
3031             --  In most cases, we must check that the initial value meets
3032             --  any constraint imposed by the declared type. However, there
3033             --  is one very important exception to this rule. If the entity
3034             --  has an unconstrained nominal subtype, then it acquired its
3035             --  constraints from the expression in the first place, and not
3036             --  only does this mean that the constraint check is not needed,
3037             --  but an attempt to perform the constraint check can
3038             --  cause order of elaboration problems.
3039
3040             if not Is_Constr_Subt_For_U_Nominal (Typ) then
3041
3042                --  If this is an allocator for an aggregate that has been
3043                --  allocated in place, delay checks until assignments are
3044                --  made, because the discriminants are not initialized.
3045
3046                if Nkind (Expr) = N_Allocator
3047                  and then No_Initialization (Expr)
3048                then
3049                   null;
3050                else
3051                   Apply_Constraint_Check (Expr, Typ);
3052                end if;
3053             end if;
3054
3055             --  If the type is controlled we attach the object to the final
3056             --  list and adjust the target after the copy. This
3057
3058             if Controlled_Type (Typ) then
3059                declare
3060                   Flist : Node_Id;
3061                   F     : Entity_Id;
3062
3063                begin
3064                   --  Attach the result to a dummy final list which will never
3065                   --  be finalized if Delay_Finalize_Attachis set. It is
3066                   --  important to attach to a dummy final list rather than
3067                   --  not attaching at all in order to reset the pointers
3068                   --  coming from the initial value. Equivalent code exists
3069                   --  in the sec-stack case in Exp_Ch4.Expand_N_Allocator.
3070
3071                   if Delay_Finalize_Attach (N) then
3072                      F :=
3073                        Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
3074                      Insert_Action (N,
3075                        Make_Object_Declaration (Loc,
3076                          Defining_Identifier => F,
3077                          Object_Definition   =>
3078                            New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
3079
3080                      Flist := New_Reference_To (F, Loc);
3081
3082                   else
3083                      Flist := Find_Final_List (Def_Id);
3084                   end if;
3085
3086                   Insert_Actions_After (N,
3087                     Make_Adjust_Call (
3088                       Ref          => New_Reference_To (Def_Id, Loc),
3089                       Typ          => Base_Type (Typ),
3090                       Flist_Ref    => Flist,
3091                       With_Attach  => Make_Integer_Literal (Loc, 1)));
3092                end;
3093             end if;
3094
3095             --  For tagged types, when an init value is given, the tag has
3096             --  to be re-initialized separately in order to avoid the
3097             --  propagation of a wrong tag coming from a view conversion
3098             --  unless the type is class wide (in this case the tag comes
3099             --  from the init value). Suppress the tag assignment when
3100             --  Java_VM because JVM tags are represented implicitly
3101             --  in objects. Ditto for types that are CPP_CLASS.
3102
3103             if Is_Tagged_Type (Typ)
3104               and then not Is_Class_Wide_Type (Typ)
3105               and then not Is_CPP_Class (Typ)
3106               and then not Java_VM
3107             then
3108                --  The re-assignment of the tag has to be done even if
3109                --  the object is a constant
3110
3111                New_Ref :=
3112                  Make_Selected_Component (Loc,
3113                     Prefix => New_Reference_To (Def_Id, Loc),
3114                     Selector_Name =>
3115                       New_Reference_To (Tag_Component (Typ), Loc));
3116
3117                Set_Assignment_OK (New_Ref);
3118
3119                Insert_After (N,
3120                  Make_Assignment_Statement (Loc,
3121                    Name => New_Ref,
3122                    Expression =>
3123                      Unchecked_Convert_To (RTE (RE_Tag),
3124                        New_Reference_To
3125                          (Access_Disp_Table (Base_Type (Typ)), Loc))));
3126
3127             --  For discrete types, set the Is_Known_Valid flag if the
3128             --  initializing value is known to be valid.
3129
3130             elsif Is_Discrete_Type (Typ)
3131               and then Expr_Known_Valid (Expr)
3132             then
3133                Set_Is_Known_Valid (Def_Id);
3134
3135             --  For access types set the Is_Known_Non_Null flag if the
3136             --  initializing value is known to be non-null. We can also
3137             --  set Can_Never_Be_Null if this is a constant.
3138
3139             elsif Is_Access_Type (Typ)
3140               and then Known_Non_Null (Expr)
3141             then
3142                Set_Is_Known_Non_Null (Def_Id);
3143
3144                if Constant_Present (N) then
3145                   Set_Can_Never_Be_Null (Def_Id);
3146                end if;
3147             end if;
3148
3149             --  If validity checking on copies, validate initial expression
3150
3151             if Validity_Checks_On
3152                and then Validity_Check_Copies
3153             then
3154                Ensure_Valid (Expr);
3155                Set_Is_Known_Valid (Def_Id);
3156             end if;
3157          end if;
3158
3159          if Is_Possibly_Unaligned_Slice (Expr) then
3160
3161             --  Make a separate assignment that will be expanded into a
3162             --  loop, to bypass back-end problems with misaligned arrays.
3163
3164             declare
3165                Stat : constant Node_Id :=
3166                        Make_Assignment_Statement (Loc,
3167                          Name => New_Reference_To (Def_Id, Loc),
3168                          Expression => Relocate_Node (Expr));
3169
3170             begin
3171                Set_Expression (N, Empty);
3172                Set_No_Initialization (N);
3173                Set_Assignment_OK (Name (Stat));
3174                Insert_After (N, Stat);
3175                Analyze (Stat);
3176             end;
3177          end if;
3178       end if;
3179
3180       --  For array type, check for size too large
3181       --  We really need this for record types too???
3182
3183       if Is_Array_Type (Typ) then
3184          Apply_Array_Size_Check (N, Typ);
3185       end if;
3186
3187    exception
3188       when RE_Not_Available =>
3189          return;
3190    end Expand_N_Object_Declaration;
3191
3192    ---------------------------------
3193    -- Expand_N_Subtype_Indication --
3194    ---------------------------------
3195
3196    --  Add a check on the range of the subtype. The static case is
3197    --  partially duplicated by Process_Range_Expr_In_Decl in Sem_Ch3,
3198    --  but we still need to check here for the static case in order to
3199    --  avoid generating extraneous expanded code.
3200
3201    procedure Expand_N_Subtype_Indication (N : Node_Id) is
3202       Ran : constant Node_Id   := Range_Expression (Constraint (N));
3203       Typ : constant Entity_Id := Entity (Subtype_Mark (N));
3204
3205    begin
3206       if Nkind (Parent (N)) = N_Constrained_Array_Definition or else
3207          Nkind (Parent (N)) = N_Slice
3208       then
3209          Resolve (Ran, Typ);
3210          Apply_Range_Check (Ran, Typ);
3211       end if;
3212    end Expand_N_Subtype_Indication;
3213
3214    ---------------------------
3215    -- Expand_N_Variant_Part --
3216    ---------------------------
3217
3218    --  If the last variant does not contain the Others choice, replace
3219    --  it with an N_Others_Choice node since Gigi always wants an Others.
3220    --  Note that we do not bother to call Analyze on the modified variant
3221    --  part, since it's only effect would be to compute the contents of
3222    --  the Others_Discrete_Choices node laboriously, and of course we
3223    --  already know the list of choices that corresponds to the others
3224    --  choice (it's the list we are replacing!)
3225
3226    procedure Expand_N_Variant_Part (N : Node_Id) is
3227       Last_Var    : constant Node_Id := Last_Non_Pragma (Variants (N));
3228       Others_Node : Node_Id;
3229
3230    begin
3231       if Nkind (First (Discrete_Choices (Last_Var))) /= N_Others_Choice then
3232          Others_Node := Make_Others_Choice (Sloc (Last_Var));
3233          Set_Others_Discrete_Choices
3234            (Others_Node, Discrete_Choices (Last_Var));
3235          Set_Discrete_Choices (Last_Var, New_List (Others_Node));
3236       end if;
3237    end Expand_N_Variant_Part;
3238
3239    ---------------------------------
3240    -- Expand_Previous_Access_Type --
3241    ---------------------------------
3242
3243    procedure Expand_Previous_Access_Type (Def_Id : Entity_Id) is
3244       T : Entity_Id := First_Entity (Current_Scope);
3245
3246    begin
3247       --  Find all access types declared in the current scope, whose
3248       --  designated type is Def_Id.
3249
3250       while Present (T) loop
3251          if Is_Access_Type (T)
3252            and then Designated_Type (T) = Def_Id
3253          then
3254             Build_Master_Entity (Def_Id);
3255             Build_Master_Renaming (Parent (Def_Id), T);
3256          end if;
3257
3258          Next_Entity (T);
3259       end loop;
3260    end Expand_Previous_Access_Type;
3261
3262    ------------------------------
3263    -- Expand_Record_Controller --
3264    ------------------------------
3265
3266    procedure Expand_Record_Controller (T : Entity_Id) is
3267       Def             : Node_Id := Type_Definition (Parent (T));
3268       Comp_List       : Node_Id;
3269       Comp_Decl       : Node_Id;
3270       Loc             : Source_Ptr;
3271       First_Comp      : Node_Id;
3272       Controller_Type : Entity_Id;
3273       Ent             : Entity_Id;
3274
3275    begin
3276       if Nkind (Def) = N_Derived_Type_Definition then
3277          Def := Record_Extension_Part (Def);
3278       end if;
3279
3280       if Null_Present (Def) then
3281          Set_Component_List (Def,
3282            Make_Component_List (Sloc (Def),
3283              Component_Items => Empty_List,
3284              Variant_Part => Empty,
3285              Null_Present => True));
3286       end if;
3287
3288       Comp_List := Component_List (Def);
3289
3290       if Null_Present (Comp_List)
3291         or else Is_Empty_List (Component_Items (Comp_List))
3292       then
3293          Loc := Sloc (Comp_List);
3294       else
3295          Loc := Sloc (First (Component_Items (Comp_List)));
3296       end if;
3297
3298       if Is_Return_By_Reference_Type (T) then
3299          Controller_Type := RTE (RE_Limited_Record_Controller);
3300       else
3301          Controller_Type := RTE (RE_Record_Controller);
3302       end if;
3303
3304       Ent := Make_Defining_Identifier (Loc, Name_uController);
3305
3306       Comp_Decl :=
3307         Make_Component_Declaration (Loc,
3308           Defining_Identifier =>  Ent,
3309           Component_Definition =>
3310             Make_Component_Definition (Loc,
3311               Aliased_Present => False,
3312               Subtype_Indication => New_Reference_To (Controller_Type, Loc)));
3313
3314       if Null_Present (Comp_List)
3315         or else Is_Empty_List (Component_Items (Comp_List))
3316       then
3317          Set_Component_Items (Comp_List, New_List (Comp_Decl));
3318          Set_Null_Present (Comp_List, False);
3319
3320       else
3321          --  The controller cannot be placed before the _Parent field
3322          --  since gigi lays out field in order and _parent must be
3323          --  first to preserve the polymorphism of tagged types.
3324
3325          First_Comp := First (Component_Items (Comp_List));
3326
3327          if Chars (Defining_Identifier (First_Comp)) /= Name_uParent
3328            and then Chars (Defining_Identifier (First_Comp)) /= Name_uTag
3329          then
3330             Insert_Before (First_Comp, Comp_Decl);
3331          else
3332             Insert_After (First_Comp, Comp_Decl);
3333          end if;
3334       end if;
3335
3336       New_Scope (T);
3337       Analyze (Comp_Decl);
3338       Set_Ekind (Ent, E_Component);
3339       Init_Component_Location (Ent);
3340
3341       --  Move the _controller entity ahead in the list of internal
3342       --  entities of the enclosing record so that it is selected
3343       --  instead of a potentially inherited one.
3344
3345       declare
3346          E    : constant Entity_Id := Last_Entity (T);
3347          Comp : Entity_Id;
3348
3349       begin
3350          pragma Assert (Chars (E) = Name_uController);
3351
3352          Set_Next_Entity (E, First_Entity (T));
3353          Set_First_Entity (T, E);
3354
3355          Comp := Next_Entity (E);
3356          while Next_Entity (Comp) /= E loop
3357             Next_Entity (Comp);
3358          end loop;
3359
3360          Set_Next_Entity (Comp, Empty);
3361          Set_Last_Entity (T, Comp);
3362       end;
3363
3364       End_Scope;
3365
3366    exception
3367       when RE_Not_Available =>
3368          return;
3369    end Expand_Record_Controller;
3370
3371    ------------------------
3372    -- Expand_Tagged_Root --
3373    ------------------------
3374
3375    procedure Expand_Tagged_Root (T : Entity_Id) is
3376       Def       : constant Node_Id := Type_Definition (Parent (T));
3377       Comp_List : Node_Id;
3378       Comp_Decl : Node_Id;
3379       Sloc_N    : Source_Ptr;
3380
3381    begin
3382       if Null_Present (Def) then
3383          Set_Component_List (Def,
3384            Make_Component_List (Sloc (Def),
3385              Component_Items => Empty_List,
3386              Variant_Part => Empty,
3387              Null_Present => True));
3388       end if;
3389
3390       Comp_List := Component_List (Def);
3391
3392       if Null_Present (Comp_List)
3393         or else Is_Empty_List (Component_Items (Comp_List))
3394       then
3395          Sloc_N := Sloc (Comp_List);
3396       else
3397          Sloc_N := Sloc (First (Component_Items (Comp_List)));
3398       end if;
3399
3400       Comp_Decl :=
3401         Make_Component_Declaration (Sloc_N,
3402           Defining_Identifier => Tag_Component (T),
3403           Component_Definition =>
3404             Make_Component_Definition (Sloc_N,
3405               Aliased_Present => False,
3406               Subtype_Indication => New_Reference_To (RTE (RE_Tag), Sloc_N)));
3407
3408       if Null_Present (Comp_List)
3409         or else Is_Empty_List (Component_Items (Comp_List))
3410       then
3411          Set_Component_Items (Comp_List, New_List (Comp_Decl));
3412          Set_Null_Present (Comp_List, False);
3413
3414       else
3415          Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
3416       end if;
3417
3418       --  We don't Analyze the whole expansion because the tag component has
3419       --  already been analyzed previously. Here we just insure that the
3420       --  tree is coherent with the semantic decoration
3421
3422       Find_Type (Subtype_Indication (Component_Definition (Comp_Decl)));
3423
3424    exception
3425       when RE_Not_Available =>
3426          return;
3427    end Expand_Tagged_Root;
3428
3429    -----------------------
3430    -- Freeze_Array_Type --
3431    -----------------------
3432
3433    procedure Freeze_Array_Type (N : Node_Id) is
3434       Typ  : constant Entity_Id  := Entity (N);
3435       Base : constant Entity_Id  := Base_Type (Typ);
3436
3437    begin
3438       if not Is_Bit_Packed_Array (Typ) then
3439
3440          --  If the component contains tasks, so does the array type.
3441          --  This may not be indicated in the array type because the
3442          --  component may have been a private type at the point of
3443          --  definition. Same if component type is controlled.
3444
3445          Set_Has_Task (Base, Has_Task (Component_Type (Typ)));
3446          Set_Has_Controlled_Component (Base,
3447            Has_Controlled_Component (Component_Type (Typ))
3448              or else Is_Controlled (Component_Type (Typ)));
3449
3450          if No (Init_Proc (Base)) then
3451
3452             --  If this is an anonymous array created for a declaration
3453             --  with an initial value, its init_proc will never be called.
3454             --  The initial value itself may have been expanded into assign-
3455             --  ments, in which case the object declaration is carries the
3456             --  No_Initialization flag.
3457
3458             if Is_Itype (Base)
3459               and then Nkind (Associated_Node_For_Itype (Base)) =
3460                                                     N_Object_Declaration
3461               and then (Present (Expression (Associated_Node_For_Itype (Base)))
3462                           or else
3463                         No_Initialization (Associated_Node_For_Itype (Base)))
3464             then
3465                null;
3466
3467             --  We do not need an init proc for string or wide string, since
3468             --  the only time these need initialization in normalize or
3469             --  initialize scalars mode, and these types are treated specially
3470             --  and do not need initialization procedures.
3471
3472             elsif Root_Type (Base) = Standard_String
3473               or else Root_Type (Base) = Standard_Wide_String
3474             then
3475                null;
3476
3477             --  Otherwise we have to build an init proc for the subtype
3478
3479             else
3480                Build_Array_Init_Proc (Base, N);
3481             end if;
3482          end if;
3483
3484          if Typ = Base and then Has_Controlled_Component (Base) then
3485             Build_Controlling_Procs (Base);
3486          end if;
3487
3488       --  For packed case, there is a default initialization, except
3489       --  if the component type is itself a packed structure with an
3490       --  initialization procedure.
3491
3492       elsif Present (Init_Proc (Component_Type (Base)))
3493         and then No (Base_Init_Proc (Base))
3494       then
3495          Build_Array_Init_Proc (Base, N);
3496       end if;
3497    end Freeze_Array_Type;
3498
3499    -----------------------------
3500    -- Freeze_Enumeration_Type --
3501    -----------------------------
3502
3503    procedure Freeze_Enumeration_Type (N : Node_Id) is
3504       Typ           : constant Entity_Id  := Entity (N);
3505       Loc           : constant Source_Ptr := Sloc (Typ);
3506       Ent           : Entity_Id;
3507       Lst           : List_Id;
3508       Num           : Nat;
3509       Arr           : Entity_Id;
3510       Fent          : Entity_Id;
3511       Ityp          : Entity_Id;
3512       Is_Contiguous : Boolean;
3513       Pos_Expr      : Node_Id;
3514       Last_Repval   : Uint;
3515
3516       Func : Entity_Id;
3517       pragma Warnings (Off, Func);
3518
3519    begin
3520       --  Various optimization are possible if the given representation
3521       --  is contiguous.
3522
3523       Is_Contiguous := True;
3524       Ent := First_Literal (Typ);
3525       Last_Repval := Enumeration_Rep (Ent);
3526       Next_Literal (Ent);
3527
3528       while Present (Ent) loop
3529          if Enumeration_Rep (Ent) - Last_Repval /= 1 then
3530             Is_Contiguous := False;
3531             exit;
3532          else
3533             Last_Repval := Enumeration_Rep (Ent);
3534          end if;
3535
3536          Next_Literal (Ent);
3537       end loop;
3538
3539       if Is_Contiguous then
3540          Set_Has_Contiguous_Rep (Typ);
3541          Ent := First_Literal (Typ);
3542          Num := 1;
3543          Lst := New_List (New_Reference_To (Ent, Sloc (Ent)));
3544
3545       else
3546          --  Build list of literal references
3547
3548          Lst := New_List;
3549          Num := 0;
3550
3551          Ent := First_Literal (Typ);
3552          while Present (Ent) loop
3553             Append_To (Lst, New_Reference_To (Ent, Sloc (Ent)));
3554             Num := Num + 1;
3555             Next_Literal (Ent);
3556          end loop;
3557       end if;
3558
3559       --  Now build an array declaration.
3560
3561       --    typA : array (Natural range 0 .. num - 1) of ctype :=
3562       --             (v, v, v, v, v, ....)
3563
3564       --  where ctype is the corresponding integer type. If the
3565       --  representation is contiguous, we only keep the first literal,
3566       --  which provides the offset for Pos_To_Rep computations.
3567
3568       Arr :=
3569         Make_Defining_Identifier (Loc,
3570           Chars => New_External_Name (Chars (Typ), 'A'));
3571
3572       Append_Freeze_Action (Typ,
3573         Make_Object_Declaration (Loc,
3574           Defining_Identifier => Arr,
3575           Constant_Present    => True,
3576
3577           Object_Definition   =>
3578             Make_Constrained_Array_Definition (Loc,
3579               Discrete_Subtype_Definitions => New_List (
3580                 Make_Subtype_Indication (Loc,
3581                   Subtype_Mark => New_Reference_To (Standard_Natural, Loc),
3582                   Constraint =>
3583                     Make_Range_Constraint (Loc,
3584                       Range_Expression =>
3585                         Make_Range (Loc,
3586                           Low_Bound  =>
3587                             Make_Integer_Literal (Loc, 0),
3588                           High_Bound =>
3589                             Make_Integer_Literal (Loc, Num - 1))))),
3590
3591               Component_Definition =>
3592                 Make_Component_Definition (Loc,
3593                   Aliased_Present => False,
3594                   Subtype_Indication => New_Reference_To (Typ, Loc))),
3595
3596           Expression =>
3597             Make_Aggregate (Loc,
3598               Expressions => Lst)));
3599
3600       Set_Enum_Pos_To_Rep (Typ, Arr);
3601
3602       --  Now we build the function that converts representation values to
3603       --  position values. This function has the form:
3604
3605       --    function _Rep_To_Pos (A : etype; F : Boolean) return Integer is
3606       --    begin
3607       --       case ityp!(A) is
3608       --         when enum-lit'Enum_Rep => return posval;
3609       --         when enum-lit'Enum_Rep => return posval;
3610       --         ...
3611       --         when others   =>
3612       --           [raise Constraint_Error when F "invalid data"]
3613       --           return -1;
3614       --       end case;
3615       --    end;
3616
3617       --  Note: the F parameter determines whether the others case (no valid
3618       --  representation) raises Constraint_Error or returns a unique value
3619       --  of minus one. The latter case is used, e.g. in 'Valid code.
3620
3621       --  Note: the reason we use Enum_Rep values in the case here is to
3622       --  avoid the code generator making inappropriate assumptions about
3623       --  the range of the values in the case where the value is invalid.
3624       --  ityp is a signed or unsigned integer type of appropriate width.
3625
3626       --  Note: if exceptions are not supported, then we suppress the raise
3627       --  and return -1 unconditionally (this is an erroneous program in any
3628       --  case and there is no obligation to raise Constraint_Error here!)
3629       --  We also do this if pragma Restrictions (No_Exceptions) is active.
3630
3631       --  Representations are signed
3632
3633       if Enumeration_Rep (First_Literal (Typ)) < 0 then
3634
3635          --  The underlying type is signed. Reset the Is_Unsigned_Type
3636          --  explicitly, because it might have been inherited from a
3637          --  parent type.
3638
3639          Set_Is_Unsigned_Type (Typ, False);
3640
3641          if Esize (Typ) <= Standard_Integer_Size then
3642             Ityp := Standard_Integer;
3643          else
3644             Ityp := Universal_Integer;
3645          end if;
3646
3647       --  Representations are unsigned
3648
3649       else
3650          if Esize (Typ) <= Standard_Integer_Size then
3651             Ityp := RTE (RE_Unsigned);
3652          else
3653             Ityp := RTE (RE_Long_Long_Unsigned);
3654          end if;
3655       end if;
3656
3657       --  The body of the function is a case statement. First collect
3658       --  case alternatives, or optimize the contiguous case.
3659
3660       Lst := New_List;
3661
3662       --  If representation is contiguous, Pos is computed by subtracting
3663       --  the representation of the first literal.
3664
3665       if Is_Contiguous then
3666          Ent := First_Literal (Typ);
3667
3668          if Enumeration_Rep (Ent) = Last_Repval then
3669
3670             --  Another special case: for a single literal, Pos is zero.
3671
3672             Pos_Expr := Make_Integer_Literal (Loc, Uint_0);
3673
3674          else
3675             Pos_Expr :=
3676               Convert_To (Standard_Integer,
3677                 Make_Op_Subtract (Loc,
3678                   Left_Opnd =>
3679                      Unchecked_Convert_To (Ityp,
3680                        Make_Identifier (Loc, Name_uA)),
3681                    Right_Opnd =>
3682                      Make_Integer_Literal (Loc,
3683                         Intval =>
3684                           Enumeration_Rep (First_Literal (Typ)))));
3685          end if;
3686
3687          Append_To (Lst,
3688               Make_Case_Statement_Alternative (Loc,
3689                 Discrete_Choices => New_List (
3690                   Make_Range (Sloc (Enumeration_Rep_Expr (Ent)),
3691                     Low_Bound =>
3692                       Make_Integer_Literal (Loc,
3693                        Intval =>  Enumeration_Rep (Ent)),
3694                     High_Bound =>
3695                       Make_Integer_Literal (Loc, Intval => Last_Repval))),
3696
3697                 Statements => New_List (
3698                   Make_Return_Statement (Loc,
3699                     Expression => Pos_Expr))));
3700
3701       else
3702          Ent := First_Literal (Typ);
3703
3704          while Present (Ent) loop
3705             Append_To (Lst,
3706               Make_Case_Statement_Alternative (Loc,
3707                 Discrete_Choices => New_List (
3708                   Make_Integer_Literal (Sloc (Enumeration_Rep_Expr (Ent)),
3709                     Intval => Enumeration_Rep (Ent))),
3710
3711                 Statements => New_List (
3712                   Make_Return_Statement (Loc,
3713                     Expression =>
3714                       Make_Integer_Literal (Loc,
3715                         Intval => Enumeration_Pos (Ent))))));
3716
3717             Next_Literal (Ent);
3718          end loop;
3719       end if;
3720
3721       --  In normal mode, add the others clause with the test
3722
3723       if not Restrictions (No_Exception_Handlers) then
3724          Append_To (Lst,
3725            Make_Case_Statement_Alternative (Loc,
3726              Discrete_Choices => New_List (Make_Others_Choice (Loc)),
3727              Statements => New_List (
3728                Make_Raise_Constraint_Error (Loc,
3729                  Condition => Make_Identifier (Loc, Name_uF),
3730                  Reason    => CE_Invalid_Data),
3731                Make_Return_Statement (Loc,
3732                  Expression =>
3733                    Make_Integer_Literal (Loc, -1)))));
3734
3735       --  If Restriction (No_Exceptions_Handlers) is active then we always
3736       --  return -1 (since we cannot usefully raise Constraint_Error in
3737       --  this case). See description above for further details.
3738
3739       else
3740          Append_To (Lst,
3741            Make_Case_Statement_Alternative (Loc,
3742              Discrete_Choices => New_List (Make_Others_Choice (Loc)),
3743              Statements => New_List (
3744                Make_Return_Statement (Loc,
3745                  Expression =>
3746                    Make_Integer_Literal (Loc, -1)))));
3747       end if;
3748
3749       --  Now we can build the function body
3750
3751       Fent :=
3752         Make_Defining_Identifier (Loc, Make_TSS_Name (Typ, TSS_Rep_To_Pos));
3753
3754       Func :=
3755         Make_Subprogram_Body (Loc,
3756           Specification =>
3757             Make_Function_Specification (Loc,
3758               Defining_Unit_Name       => Fent,
3759               Parameter_Specifications => New_List (
3760                 Make_Parameter_Specification (Loc,
3761                   Defining_Identifier =>
3762                     Make_Defining_Identifier (Loc, Name_uA),
3763                   Parameter_Type => New_Reference_To (Typ, Loc)),
3764                 Make_Parameter_Specification (Loc,
3765                   Defining_Identifier =>
3766                     Make_Defining_Identifier (Loc, Name_uF),
3767                   Parameter_Type => New_Reference_To (Standard_Boolean, Loc))),
3768
3769               Subtype_Mark => New_Reference_To (Standard_Integer, Loc)),
3770
3771             Declarations => Empty_List,
3772
3773             Handled_Statement_Sequence =>
3774               Make_Handled_Sequence_Of_Statements (Loc,
3775                 Statements => New_List (
3776                   Make_Case_Statement (Loc,
3777                     Expression =>
3778                       Unchecked_Convert_To (Ityp,
3779                         Make_Identifier (Loc, Name_uA)),
3780                     Alternatives => Lst))));
3781
3782       Set_TSS (Typ, Fent);
3783       Set_Is_Pure (Fent);
3784
3785       if not Debug_Generated_Code then
3786          Set_Debug_Info_Off (Fent);
3787       end if;
3788
3789    exception
3790       when RE_Not_Available =>
3791          return;
3792    end Freeze_Enumeration_Type;
3793
3794    ------------------------
3795    -- Freeze_Record_Type --
3796    ------------------------
3797
3798    procedure Freeze_Record_Type (N : Node_Id) is
3799       Def_Id      : constant Node_Id := Entity (N);
3800       Comp        : Entity_Id;
3801       Type_Decl   : constant Node_Id := Parent (Def_Id);
3802       Predef_List : List_Id;
3803
3804       Renamed_Eq  : Node_Id := Empty;
3805       --  Could use some comments ???
3806
3807    begin
3808       --  Build discriminant checking functions if not a derived type (for
3809       --  derived types that are not tagged types, we always use the
3810       --  discriminant checking functions of the parent type). However, for
3811       --  untagged types the derivation may have taken place before the
3812       --  parent was frozen, so we copy explicitly the discriminant checking
3813       --  functions from the parent into the components of the derived type.
3814
3815       if not Is_Derived_Type (Def_Id)
3816         or else Has_New_Non_Standard_Rep (Def_Id)
3817         or else Is_Tagged_Type (Def_Id)
3818       then
3819          Build_Discr_Checking_Funcs (Type_Decl);
3820
3821       elsif Is_Derived_Type (Def_Id)
3822         and then not Is_Tagged_Type (Def_Id)
3823         and then Has_Discriminants (Def_Id)
3824       then
3825          declare
3826             Old_Comp : Entity_Id;
3827
3828          begin
3829             Old_Comp :=
3830               First_Component (Base_Type (Underlying_Type (Etype (Def_Id))));
3831             Comp := First_Component (Def_Id);
3832             while Present (Comp) loop
3833                if Ekind (Comp) = E_Component
3834                  and then Chars (Comp) = Chars (Old_Comp)
3835                then
3836                   Set_Discriminant_Checking_Func (Comp,
3837                      Discriminant_Checking_Func (Old_Comp));
3838                end if;
3839
3840                Next_Component (Old_Comp);
3841                Next_Component (Comp);
3842             end loop;
3843          end;
3844       end if;
3845
3846       if Is_Derived_Type (Def_Id)
3847         and then Is_Limited_Type (Def_Id)
3848         and then Is_Tagged_Type (Def_Id)
3849       then
3850          Check_Stream_Attributes (Def_Id);
3851       end if;
3852
3853       --  Update task and controlled component flags, because some of the
3854       --  component types may have been private at the point of the record
3855       --  declaration.
3856
3857       Comp := First_Component (Def_Id);
3858
3859       while Present (Comp) loop
3860          if Has_Task (Etype (Comp)) then
3861             Set_Has_Task (Def_Id);
3862
3863          elsif Has_Controlled_Component (Etype (Comp))
3864            or else (Chars (Comp) /= Name_uParent
3865                      and then Is_Controlled (Etype (Comp)))
3866          then
3867             Set_Has_Controlled_Component (Def_Id);
3868          end if;
3869
3870          Next_Component (Comp);
3871       end loop;
3872
3873       --  Creation of the Dispatch Table. Note that a Dispatch Table is
3874       --  created for regular tagged types as well as for Ada types
3875       --  deriving from a C++ Class, but not for tagged types directly
3876       --  corresponding to the C++ classes. In the later case we assume
3877       --  that the Vtable is created in the C++ side and we just use it.
3878
3879       if Is_Tagged_Type (Def_Id) then
3880          if Is_CPP_Class (Def_Id) then
3881             Set_All_DT_Position (Def_Id);
3882             Set_Default_Constructor (Def_Id);
3883
3884          else
3885             --  Usually inherited primitives are not delayed but the first
3886             --  Ada extension of a CPP_Class is an exception since the
3887             --  address of the inherited subprogram has to be inserted in
3888             --  the new Ada Dispatch Table and this is a freezing action
3889             --  (usually the inherited primitive address is inserted in the
3890             --  DT by Inherit_DT)
3891
3892             if Is_CPP_Class (Etype (Def_Id)) then
3893                declare
3894                   Elmt : Elmt_Id := First_Elmt (Primitive_Operations (Def_Id));
3895                   Subp : Entity_Id;
3896
3897                begin
3898                   while Present (Elmt) loop
3899                      Subp := Node (Elmt);
3900
3901                      if Present (Alias (Subp)) then
3902                         Set_Has_Delayed_Freeze (Subp);
3903                      end if;
3904
3905                      Next_Elmt (Elmt);
3906                   end loop;
3907                end;
3908             end if;
3909
3910             if Underlying_Type (Etype (Def_Id)) = Def_Id then
3911                Expand_Tagged_Root (Def_Id);
3912             end if;
3913
3914             --  Unfreeze momentarily the type to add the predefined
3915             --  primitives operations. The reason we unfreeze is so
3916             --  that these predefined operations will indeed end up
3917             --  as primitive operations (which must be before the
3918             --  freeze point).
3919
3920             Set_Is_Frozen (Def_Id, False);
3921             Make_Predefined_Primitive_Specs
3922               (Def_Id, Predef_List, Renamed_Eq);
3923             Insert_List_Before_And_Analyze (N, Predef_List);
3924             Set_Is_Frozen (Def_Id, True);
3925             Set_All_DT_Position (Def_Id);
3926
3927             --  Add the controlled component before the freezing actions
3928             --  it is referenced in those actions.
3929
3930             if Has_New_Controlled_Component (Def_Id) then
3931                Expand_Record_Controller (Def_Id);
3932             end if;
3933
3934             --  Suppress creation of a dispatch table when Java_VM because
3935             --  the dispatching mechanism is handled internally by the JVM.
3936
3937             if not Java_VM then
3938                Append_Freeze_Actions (Def_Id, Make_DT (Def_Id));
3939             end if;
3940
3941             --  Make sure that the primitives Initialize, Adjust and
3942             --  Finalize are Frozen before other TSS subprograms. We
3943             --  don't want them Frozen inside.
3944
3945             if Is_Controlled (Def_Id) then
3946                if not Is_Limited_Type (Def_Id) then
3947                   Append_Freeze_Actions (Def_Id,
3948                     Freeze_Entity
3949                       (Find_Prim_Op (Def_Id, Name_Adjust), Sloc (Def_Id)));
3950                end if;
3951
3952                Append_Freeze_Actions (Def_Id,
3953                  Freeze_Entity
3954                    (Find_Prim_Op (Def_Id, Name_Initialize), Sloc (Def_Id)));
3955
3956                Append_Freeze_Actions (Def_Id,
3957                  Freeze_Entity
3958                    (Find_Prim_Op (Def_Id, Name_Finalize), Sloc (Def_Id)));
3959             end if;
3960
3961             --  Freeze rest of primitive operations
3962
3963             Append_Freeze_Actions
3964               (Def_Id, Predefined_Primitive_Freeze (Def_Id));
3965          end if;
3966
3967       --  In the non-tagged case, an equality function is provided only
3968       --  for variant records (that are not unchecked unions).
3969
3970       elsif Has_Discriminants (Def_Id)
3971         and then not Is_Limited_Type (Def_Id)
3972       then
3973          declare
3974             Comps : constant Node_Id :=
3975                       Component_List (Type_Definition (Type_Decl));
3976
3977          begin
3978             if Present (Comps)
3979               and then Present (Variant_Part (Comps))
3980               and then not Is_Unchecked_Union (Def_Id)
3981             then
3982                Build_Variant_Record_Equality (Def_Id);
3983             end if;
3984          end;
3985       end if;
3986
3987       --  Before building the record initialization procedure, if we are
3988       --  dealing with a concurrent record value type, then we must go
3989       --  through the discriminants, exchanging discriminals between the
3990       --  concurrent type and the concurrent record value type. See the
3991       --  section "Handling of Discriminants" in the Einfo spec for details.
3992
3993       if Is_Concurrent_Record_Type (Def_Id)
3994         and then Has_Discriminants (Def_Id)
3995       then
3996          declare
3997             Ctyp : constant Entity_Id :=
3998                      Corresponding_Concurrent_Type (Def_Id);
3999             Conc_Discr : Entity_Id;
4000             Rec_Discr  : Entity_Id;
4001             Temp       : Entity_Id;
4002
4003          begin
4004             Conc_Discr := First_Discriminant (Ctyp);
4005             Rec_Discr  := First_Discriminant (Def_Id);
4006
4007             while Present (Conc_Discr) loop
4008                Temp := Discriminal (Conc_Discr);
4009                Set_Discriminal (Conc_Discr, Discriminal (Rec_Discr));
4010                Set_Discriminal (Rec_Discr, Temp);
4011
4012                Set_Discriminal_Link (Discriminal (Conc_Discr), Conc_Discr);
4013                Set_Discriminal_Link (Discriminal (Rec_Discr),  Rec_Discr);
4014
4015                Next_Discriminant (Conc_Discr);
4016                Next_Discriminant (Rec_Discr);
4017             end loop;
4018          end;
4019       end if;
4020
4021       if Has_Controlled_Component (Def_Id) then
4022          if No (Controller_Component (Def_Id)) then
4023             Expand_Record_Controller (Def_Id);
4024          end if;
4025
4026          Build_Controlling_Procs (Def_Id);
4027       end if;
4028
4029       Adjust_Discriminants (Def_Id);
4030       Build_Record_Init_Proc (Type_Decl, Def_Id);
4031
4032       --  For tagged type, build bodies of primitive operations. Note
4033       --  that we do this after building the record initialization
4034       --  experiment, since the primitive operations may need the
4035       --  initialization routine
4036
4037       if Is_Tagged_Type (Def_Id) then
4038          Predef_List := Predefined_Primitive_Bodies (Def_Id, Renamed_Eq);
4039          Append_Freeze_Actions (Def_Id, Predef_List);
4040       end if;
4041
4042    end Freeze_Record_Type;
4043
4044    ------------------------------
4045    -- Freeze_Stream_Operations --
4046    ------------------------------
4047
4048    procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id) is
4049       Names     : constant array (1 .. 4) of TSS_Name_Type :=
4050                     (TSS_Stream_Input,
4051                      TSS_Stream_Output,
4052                      TSS_Stream_Read,
4053                      TSS_Stream_Write);
4054       Stream_Op : Entity_Id;
4055
4056    begin
4057       --  Primitive operations of tagged types are frozen when the dispatch
4058       --  table is constructed.
4059
4060       if not Comes_From_Source (Typ)
4061         or else Is_Tagged_Type (Typ)
4062       then
4063          return;
4064       end if;
4065
4066       for J in Names'Range loop
4067          Stream_Op := TSS (Typ, Names (J));
4068
4069          if Present (Stream_Op)
4070            and then Is_Subprogram (Stream_Op)
4071            and then Nkind (Unit_Declaration_Node (Stream_Op)) =
4072                       N_Subprogram_Declaration
4073            and then not Is_Frozen (Stream_Op)
4074          then
4075             Append_Freeze_Actions
4076                (Typ, Freeze_Entity (Stream_Op, Sloc (N)));
4077          end if;
4078       end loop;
4079    end Freeze_Stream_Operations;
4080
4081    -----------------
4082    -- Freeze_Type --
4083    -----------------
4084
4085    --  Full type declarations are expanded at the point at which the type
4086    --  is frozen. The formal N is the Freeze_Node for the type. Any statements
4087    --  or declarations generated by the freezing (e.g. the procedure generated
4088    --  for initialization) are chained in the Acions field list of the freeze
4089    --  node using Append_Freeze_Actions.
4090
4091    procedure Freeze_Type (N : Node_Id) is
4092       Def_Id    : constant Entity_Id := Entity (N);
4093       RACW_Seen : Boolean := False;
4094
4095    begin
4096       --  Process associated access types needing special processing
4097
4098       if Present (Access_Types_To_Process (N)) then
4099          declare
4100             E : Elmt_Id := First_Elmt (Access_Types_To_Process (N));
4101          begin
4102             while Present (E) loop
4103
4104                if Is_Remote_Access_To_Class_Wide_Type (Node (E)) then
4105                   RACW_Seen := True;
4106                end if;
4107
4108                E := Next_Elmt (E);
4109             end loop;
4110          end;
4111
4112          if RACW_Seen then
4113
4114             --  If there are RACWs designating this type, make stubs now.
4115
4116             Remote_Types_Tagged_Full_View_Encountered (Def_Id);
4117          end if;
4118       end if;
4119
4120       --  Freeze processing for record types
4121
4122       if Is_Record_Type (Def_Id) then
4123          if Ekind (Def_Id) = E_Record_Type then
4124             Freeze_Record_Type (N);
4125
4126          --  The subtype may have been declared before the type was frozen.
4127          --  If the type has controlled components it is necessary to create
4128          --  the entity for the controller explicitly because it did not
4129          --  exist at the point of the subtype declaration. Only the entity is
4130          --  needed, the back-end will obtain the layout from the type.
4131          --  This is only necessary if this is constrained subtype whose
4132          --  component list is not shared with the base type.
4133
4134          elsif Ekind (Def_Id) = E_Record_Subtype
4135            and then Has_Discriminants (Def_Id)
4136            and then Last_Entity (Def_Id) /= Last_Entity (Base_Type (Def_Id))
4137            and then Present (Controller_Component (Def_Id))
4138          then
4139             declare
4140                Old_C : constant Entity_Id := Controller_Component (Def_Id);
4141                New_C : Entity_Id;
4142
4143             begin
4144                if Scope (Old_C) = Base_Type (Def_Id) then
4145
4146                   --  The entity is the one in the parent. Create new one.
4147
4148                   New_C := New_Copy (Old_C);
4149                   Set_Parent (New_C, Parent (Old_C));
4150                   New_Scope (Def_Id);
4151                   Enter_Name (New_C);
4152                   End_Scope;
4153                end if;
4154             end;
4155
4156          --  Similar process if the controller of the subtype is not
4157          --  present but the parent has it. This can happen with constrained
4158          --  record components where the subtype is an itype.
4159
4160          elsif Ekind (Def_Id) = E_Record_Subtype
4161            and then Is_Itype (Def_Id)
4162            and then No (Controller_Component (Def_Id))
4163            and then Present (Controller_Component (Etype (Def_Id)))
4164          then
4165             declare
4166                Old_C : constant Entity_Id :=
4167                          Controller_Component (Etype (Def_Id));
4168                New_C : constant Entity_Id := New_Copy (Old_C);
4169
4170             begin
4171                Set_Next_Entity  (New_C, First_Entity (Def_Id));
4172                Set_First_Entity (Def_Id, New_C);
4173
4174                --  The freeze node is only used to introduce the controller,
4175                --  the back-end has no use for it for a discriminated
4176                --   component.
4177
4178                Set_Freeze_Node (Def_Id, Empty);
4179                Set_Has_Delayed_Freeze (Def_Id, False);
4180                Remove (N);
4181             end;
4182          end if;
4183
4184       --  Freeze processing for array types
4185
4186       elsif Is_Array_Type (Def_Id) then
4187          Freeze_Array_Type (N);
4188
4189       --  Freeze processing for access types
4190
4191       --  For pool-specific access types, find out the pool object used for
4192       --  this type, needs actual expansion of it in some cases. Here are the
4193       --  different cases :
4194
4195       --  1. Rep Clause "for Def_Id'Storage_Size use 0;"
4196       --      ---> don't use any storage pool
4197
4198       --  2. Rep Clause : for Def_Id'Storage_Size use Expr.
4199       --     Expand:
4200       --      Def_Id__Pool : Stack_Bounded_Pool (Expr, DT'Size, DT'Alignment);
4201
4202       --  3. Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
4203       --      ---> Storage Pool is the specified one
4204
4205       --  See GNAT Pool packages in the Run-Time for more details
4206
4207       elsif Ekind (Def_Id) = E_Access_Type
4208         or else Ekind (Def_Id) = E_General_Access_Type
4209       then
4210          declare
4211             Loc         : constant Source_Ptr := Sloc (N);
4212             Desig_Type  : constant Entity_Id := Designated_Type (Def_Id);
4213             Pool_Object : Entity_Id;
4214             Siz_Exp     : Node_Id;
4215
4216             Freeze_Action_Typ : Entity_Id;
4217
4218          begin
4219             if Has_Storage_Size_Clause (Def_Id) then
4220                Siz_Exp := Expression (Parent (Storage_Size_Variable (Def_Id)));
4221             else
4222                Siz_Exp := Empty;
4223             end if;
4224
4225             --  Case 1
4226
4227             --    Rep Clause "for Def_Id'Storage_Size use 0;"
4228             --    ---> don't use any storage pool
4229
4230             if Has_Storage_Size_Clause (Def_Id)
4231               and then Compile_Time_Known_Value (Siz_Exp)
4232               and then Expr_Value (Siz_Exp) = 0
4233             then
4234                null;
4235
4236             --  Case 2
4237
4238             --    Rep Clause : for Def_Id'Storage_Size use Expr.
4239             --    ---> Expand:
4240             --           Def_Id__Pool : Stack_Bounded_Pool
4241             --                            (Expr, DT'Size, DT'Alignment);
4242
4243             elsif Has_Storage_Size_Clause (Def_Id) then
4244                declare
4245                   DT_Size  : Node_Id;
4246                   DT_Align : Node_Id;
4247
4248                begin
4249                   --  For unconstrained composite types we give a size of
4250                   --  zero so that the pool knows that it needs a special
4251                   --  algorithm for variable size object allocation.
4252
4253                   if Is_Composite_Type (Desig_Type)
4254                     and then not Is_Constrained (Desig_Type)
4255                   then
4256                      DT_Size :=
4257                        Make_Integer_Literal (Loc, 0);
4258
4259                      DT_Align :=
4260                        Make_Integer_Literal (Loc, Maximum_Alignment);
4261
4262                   else
4263                      DT_Size :=
4264                        Make_Attribute_Reference (Loc,
4265                          Prefix => New_Reference_To (Desig_Type, Loc),
4266                          Attribute_Name => Name_Max_Size_In_Storage_Elements);
4267
4268                      DT_Align :=
4269                        Make_Attribute_Reference (Loc,
4270                          Prefix => New_Reference_To (Desig_Type, Loc),
4271                          Attribute_Name => Name_Alignment);
4272                   end if;
4273
4274                   Pool_Object :=
4275                     Make_Defining_Identifier (Loc,
4276                       Chars => New_External_Name (Chars (Def_Id), 'P'));
4277
4278                   --  We put the code associated with the pools in the
4279                   --  entity that has the later freeze node, usually the
4280                   --  acces type but it can also be the designated_type;
4281                   --  because the pool code requires both those types to be
4282                   --  frozen
4283
4284                   if Is_Frozen (Desig_Type)
4285                     and then (not Present (Freeze_Node (Desig_Type))
4286                                or else Analyzed (Freeze_Node (Desig_Type)))
4287                   then
4288                      Freeze_Action_Typ := Def_Id;
4289
4290                   --  A Taft amendment type cannot get the freeze actions
4291                   --  since the full view is not there.
4292
4293                   elsif Is_Incomplete_Or_Private_Type (Desig_Type)
4294                     and then No (Full_View (Desig_Type))
4295                   then
4296                      Freeze_Action_Typ := Def_Id;
4297
4298                   else
4299                      Freeze_Action_Typ := Desig_Type;
4300                   end if;
4301
4302                   Append_Freeze_Action (Freeze_Action_Typ,
4303                     Make_Object_Declaration (Loc,
4304                       Defining_Identifier => Pool_Object,
4305                       Object_Definition =>
4306                         Make_Subtype_Indication (Loc,
4307                           Subtype_Mark =>
4308                             New_Reference_To
4309                               (RTE (RE_Stack_Bounded_Pool), Loc),
4310
4311                           Constraint =>
4312                             Make_Index_Or_Discriminant_Constraint (Loc,
4313                               Constraints => New_List (
4314
4315                               --  First discriminant is the Pool Size
4316
4317                                 New_Reference_To (
4318                                   Storage_Size_Variable (Def_Id), Loc),
4319
4320                               --  Second discriminant is the element size
4321
4322                                 DT_Size,
4323
4324                               --  Third discriminant is the alignment
4325
4326                                 DT_Align)))));
4327                end;
4328
4329                Set_Associated_Storage_Pool (Def_Id, Pool_Object);
4330
4331             --  Case 3
4332
4333             --    Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
4334             --    ---> Storage Pool is the specified one
4335
4336             elsif Present (Associated_Storage_Pool (Def_Id)) then
4337
4338                --  Nothing to do the associated storage pool has been attached
4339                --  when analyzing the rep. clause
4340
4341                null;
4342             end if;
4343
4344             --  For access-to-controlled types (including class-wide types
4345             --  and Taft-amendment types which potentially have controlled
4346             --  components), expand the list controller object that will
4347             --  store the dynamically allocated objects. Do not do this
4348             --  transformation for expander-generated access types, but do it
4349             --  for types that are the full view of types derived from other
4350             --  private types. Also suppress the list controller in the case
4351             --  of a designated type with convention Java, since this is used
4352             --  when binding to Java API specs, where there's no equivalent
4353             --  of a finalization list and we don't want to pull in the
4354             --  finalization support if not needed.
4355
4356             if not Comes_From_Source (Def_Id)
4357                and then not Has_Private_Declaration (Def_Id)
4358             then
4359                null;
4360
4361             elsif (Controlled_Type (Desig_Type)
4362                     and then Convention (Desig_Type) /= Convention_Java)
4363               or else
4364                 (Is_Incomplete_Or_Private_Type (Desig_Type)
4365                    and then No (Full_View (Desig_Type))
4366
4367                --  An exception is made for types defined in the run-time
4368                --  because Ada.Tags.Tag itself is such a type and cannot
4369                --  afford this unnecessary overhead that would generates a
4370                --  loop in the expansion scheme...
4371
4372                    and then not In_Runtime (Def_Id)
4373
4374                --  Another exception is if Restrictions (No_Finalization)
4375                --  is active, since then we know nothing is controlled.
4376
4377                    and then not Restrictions (No_Finalization))
4378
4379                --  If the designated type is not frozen yet, its controlled
4380                --  status must be retrieved explicitly.
4381
4382               or else (Is_Array_Type (Desig_Type)
4383                 and then not Is_Frozen (Desig_Type)
4384                 and then Controlled_Type (Component_Type (Desig_Type)))
4385             then
4386                Set_Associated_Final_Chain (Def_Id,
4387                  Make_Defining_Identifier (Loc,
4388                    New_External_Name (Chars (Def_Id), 'L')));
4389
4390                Append_Freeze_Action (Def_Id,
4391                  Make_Object_Declaration (Loc,
4392                    Defining_Identifier => Associated_Final_Chain (Def_Id),
4393                    Object_Definition   =>
4394                      New_Reference_To (RTE (RE_List_Controller), Loc)));
4395             end if;
4396          end;
4397
4398       --  Freeze processing for enumeration types
4399
4400       elsif Ekind (Def_Id) = E_Enumeration_Type then
4401
4402          --  We only have something to do if we have a non-standard
4403          --  representation (i.e. at least one literal whose pos value
4404          --  is not the same as its representation)
4405
4406          if Has_Non_Standard_Rep (Def_Id) then
4407             Freeze_Enumeration_Type (N);
4408          end if;
4409
4410       --  Private types that are completed by a derivation from a private
4411       --  type have an internally generated full view, that needs to be
4412       --  frozen. This must be done explicitly because the two views share
4413       --  the freeze node, and the underlying full view is not visible when
4414       --  the freeze node is analyzed.
4415
4416       elsif Is_Private_Type (Def_Id)
4417         and then Is_Derived_Type (Def_Id)
4418         and then Present (Full_View (Def_Id))
4419         and then Is_Itype (Full_View (Def_Id))
4420         and then Has_Private_Declaration (Full_View (Def_Id))
4421         and then Freeze_Node (Full_View (Def_Id)) = N
4422       then
4423          Set_Entity (N, Full_View (Def_Id));
4424          Freeze_Type (N);
4425          Set_Entity (N, Def_Id);
4426
4427       --  All other types require no expander action. There are such
4428       --  cases (e.g. task types and protected types). In such cases,
4429       --  the freeze nodes are there for use by Gigi.
4430
4431       end if;
4432
4433       Freeze_Stream_Operations (N, Def_Id);
4434
4435    exception
4436       when RE_Not_Available =>
4437          return;
4438    end Freeze_Type;
4439
4440    -------------------------
4441    -- Get_Simple_Init_Val --
4442    -------------------------
4443
4444    function Get_Simple_Init_Val
4445      (T    : Entity_Id;
4446       Loc  : Source_Ptr)
4447       return Node_Id
4448    is
4449       Val    : Node_Id;
4450       Typ    : Node_Id;
4451       Result : Node_Id;
4452       Val_RE : RE_Id;
4453
4454    begin
4455       --  For a private type, we should always have an underlying type
4456       --  (because this was already checked in Needs_Simple_Initialization).
4457       --  What we do is to get the value for the underlying type and then
4458       --  do an Unchecked_Convert to the private type.
4459
4460       if Is_Private_Type (T) then
4461          Val := Get_Simple_Init_Val (Underlying_Type (T), Loc);
4462
4463          --  A special case, if the underlying value is null, then qualify
4464          --  it with the underlying type, so that the null is properly typed
4465          --  Similarly, if it is an aggregate it must be qualified, because
4466          --  an unchecked conversion does not provide a context for it.
4467
4468          if Nkind (Val) = N_Null
4469            or else Nkind (Val) = N_Aggregate
4470          then
4471             Val :=
4472               Make_Qualified_Expression (Loc,
4473                 Subtype_Mark =>
4474                   New_Occurrence_Of (Underlying_Type (T), Loc),
4475                 Expression => Val);
4476          end if;
4477
4478          Result := Unchecked_Convert_To (T, Val);
4479
4480          --  Don't truncate result (important for Initialize/Normalize_Scalars)
4481
4482          if Nkind (Result) = N_Unchecked_Type_Conversion
4483            and then Is_Scalar_Type (Underlying_Type (T))
4484          then
4485             Set_No_Truncation (Result);
4486          end if;
4487
4488          return Result;
4489
4490       --  For scalars, we must have normalize/initialize scalars case
4491
4492       elsif Is_Scalar_Type (T) then
4493          pragma Assert (Init_Or_Norm_Scalars);
4494
4495          --  Processing for Normalize_Scalars case
4496
4497          if Normalize_Scalars then
4498
4499             --  First prepare a value (out of subtype range if possible)
4500
4501             if Is_Real_Type (T) or else Is_Integer_Type (T) then
4502                Val :=
4503                  Make_Attribute_Reference (Loc,
4504                    Prefix => New_Occurrence_Of (Base_Type (T), Loc),
4505                    Attribute_Name => Name_First);
4506
4507             elsif Is_Modular_Integer_Type (T) then
4508                Val :=
4509                  Make_Attribute_Reference (Loc,
4510                    Prefix => New_Occurrence_Of (Base_Type (T), Loc),
4511                    Attribute_Name => Name_Last);
4512
4513             else
4514                pragma Assert (Is_Enumeration_Type (T));
4515
4516                if Esize (T) <= 8 then
4517                   Typ := RTE (RE_Unsigned_8);
4518                elsif Esize (T) <= 16 then
4519                   Typ := RTE (RE_Unsigned_16);
4520                elsif Esize (T) <= 32 then
4521                   Typ := RTE (RE_Unsigned_32);
4522                else
4523                   Typ := RTE (RE_Unsigned_64);
4524                end if;
4525
4526                Val :=
4527                  Make_Attribute_Reference (Loc,
4528                    Prefix => New_Occurrence_Of (Typ, Loc),
4529                    Attribute_Name => Name_Last);
4530             end if;
4531
4532          --  Here for Initialize_Scalars case
4533
4534          else
4535             if Is_Floating_Point_Type (T) then
4536                if Root_Type (T) = Standard_Short_Float then
4537                   Val_RE := RE_IS_Isf;
4538                elsif Root_Type (T) = Standard_Float then
4539                   Val_RE := RE_IS_Ifl;
4540                elsif Root_Type (T) = Standard_Long_Float then
4541                   Val_RE := RE_IS_Ilf;
4542                else pragma Assert (Root_Type (T) = Standard_Long_Long_Float);
4543                   Val_RE := RE_IS_Ill;
4544                end if;
4545
4546             elsif Is_Unsigned_Type (Base_Type (T)) then
4547                if Esize (T) = 8 then
4548                   Val_RE := RE_IS_Iu1;
4549                elsif Esize (T) = 16 then
4550                   Val_RE := RE_IS_Iu2;
4551                elsif Esize (T) = 32 then
4552                   Val_RE := RE_IS_Iu4;
4553                else pragma Assert (Esize (T) = 64);
4554                   Val_RE := RE_IS_Iu8;
4555                end if;
4556
4557             else -- signed type
4558                if Esize (T) = 8 then
4559                   Val_RE := RE_IS_Is1;
4560                elsif Esize (T) = 16 then
4561                   Val_RE := RE_IS_Is2;
4562                elsif Esize (T) = 32 then
4563                   Val_RE := RE_IS_Is4;
4564                else pragma Assert (Esize (T) = 64);
4565                   Val_RE := RE_IS_Is8;
4566                end if;
4567             end if;
4568
4569             Val := New_Occurrence_Of (RTE (Val_RE), Loc);
4570          end if;
4571
4572          --  The final expression is obtained by doing an unchecked
4573          --  conversion of this result to the base type of the
4574          --  required subtype. We use the base type to avoid the
4575          --  unchecked conversion from chopping bits, and then we
4576          --  set Kill_Range_Check to preserve the "bad" value.
4577
4578          Result := Unchecked_Convert_To (Base_Type (T), Val);
4579
4580          --  Ensure result is not truncated, since we want the "bad" bits
4581          --  and also kill range check on result.
4582
4583          if Nkind (Result) = N_Unchecked_Type_Conversion then
4584             Set_No_Truncation (Result);
4585             Set_Kill_Range_Check (Result, True);
4586          end if;
4587
4588          return Result;
4589
4590       --  String or Wide_String (must have Initialize_Scalars set)
4591
4592       elsif Root_Type (T) = Standard_String
4593               or else
4594             Root_Type (T) = Standard_Wide_String
4595       then
4596          pragma Assert (Init_Or_Norm_Scalars);
4597
4598          return
4599            Make_Aggregate (Loc,
4600              Component_Associations => New_List (
4601                Make_Component_Association (Loc,
4602                  Choices => New_List (
4603                    Make_Others_Choice (Loc)),
4604                  Expression =>
4605                    Get_Simple_Init_Val (Component_Type (T), Loc))));
4606
4607       --  Access type is initialized to null
4608
4609       elsif Is_Access_Type (T) then
4610          return
4611            Make_Null (Loc);
4612
4613       --  We initialize modular packed bit arrays to zero, to make sure that
4614       --  unused bits are zero, as required (see spec of Exp_Pakd). Also note
4615       --  that this improves gigi code, since the value tracing knows that
4616       --  all bits of the variable start out at zero. The value of zero has
4617       --  to be unchecked converted to the proper array type.
4618
4619       elsif Is_Bit_Packed_Array (T) then
4620          declare
4621             PAT : constant Entity_Id := Packed_Array_Type (T);
4622             Nod : Node_Id;
4623
4624          begin
4625             pragma Assert (Is_Modular_Integer_Type (PAT));
4626
4627             Nod :=
4628               Make_Unchecked_Type_Conversion (Loc,
4629                 Subtype_Mark => New_Occurrence_Of (T, Loc),
4630                 Expression   => Make_Integer_Literal (Loc, 0));
4631
4632             Set_Etype (Expression (Nod), PAT);
4633             return Nod;
4634          end;
4635
4636       --  No other possibilities should arise, since we should only be
4637       --  calling Get_Simple_Init_Val if Needs_Simple_Initialization
4638       --  returned True, indicating one of the above cases held.
4639
4640       else
4641          raise Program_Error;
4642       end if;
4643
4644    exception
4645       when RE_Not_Available =>
4646          return Empty;
4647    end Get_Simple_Init_Val;
4648
4649    ------------------------------
4650    -- Has_New_Non_Standard_Rep --
4651    ------------------------------
4652
4653    function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean is
4654    begin
4655       if not Is_Derived_Type (T) then
4656          return Has_Non_Standard_Rep (T)
4657            or else Has_Non_Standard_Rep (Root_Type (T));
4658
4659       --  If Has_Non_Standard_Rep is not set on the derived type, the
4660       --  representation is fully inherited.
4661
4662       elsif not Has_Non_Standard_Rep (T) then
4663          return False;
4664
4665       else
4666          return First_Rep_Item (T) /= First_Rep_Item (Root_Type (T));
4667
4668          --  May need a more precise check here: the First_Rep_Item may
4669          --  be a stream attribute, which does not affect the representation
4670          --  of the type ???
4671       end if;
4672    end Has_New_Non_Standard_Rep;
4673
4674    ----------------
4675    -- In_Runtime --
4676    ----------------
4677
4678    function In_Runtime (E : Entity_Id) return Boolean is
4679       S1 : Entity_Id := Scope (E);
4680
4681    begin
4682       while Scope (S1) /= Standard_Standard loop
4683          S1 := Scope (S1);
4684       end loop;
4685
4686       return Chars (S1) = Name_System or else Chars (S1) = Name_Ada;
4687    end In_Runtime;
4688
4689    ------------------
4690    -- Init_Formals --
4691    ------------------
4692
4693    function Init_Formals (Typ : Entity_Id) return List_Id is
4694       Loc     : constant Source_Ptr := Sloc (Typ);
4695       Formals : List_Id;
4696
4697    begin
4698       --  First parameter is always _Init : in out typ. Note that we need
4699       --  this to be in/out because in the case of the task record value,
4700       --  there are default record fields (_Priority, _Size, -Task_Info)
4701       --  that may be referenced in the generated initialization routine.
4702
4703       Formals := New_List (
4704         Make_Parameter_Specification (Loc,
4705           Defining_Identifier =>
4706             Make_Defining_Identifier (Loc, Name_uInit),
4707           In_Present  => True,
4708           Out_Present => True,
4709           Parameter_Type => New_Reference_To (Typ, Loc)));
4710
4711       --  For task record value, or type that contains tasks, add two more
4712       --  formals, _Master : Master_Id and _Chain : in out Activation_Chain
4713       --  We also add these parameters for the task record type case.
4714
4715       if Has_Task (Typ)
4716         or else (Is_Record_Type (Typ) and then Is_Task_Record_Type (Typ))
4717       then
4718          Append_To (Formals,
4719            Make_Parameter_Specification (Loc,
4720              Defining_Identifier =>
4721                Make_Defining_Identifier (Loc, Name_uMaster),
4722              Parameter_Type => New_Reference_To (RTE (RE_Master_Id), Loc)));
4723
4724          Append_To (Formals,
4725            Make_Parameter_Specification (Loc,
4726              Defining_Identifier =>
4727                Make_Defining_Identifier (Loc, Name_uChain),
4728              In_Present => True,
4729              Out_Present => True,
4730              Parameter_Type =>
4731                New_Reference_To (RTE (RE_Activation_Chain), Loc)));
4732
4733          Append_To (Formals,
4734            Make_Parameter_Specification (Loc,
4735              Defining_Identifier =>
4736                Make_Defining_Identifier (Loc, Name_uTask_Name),
4737              In_Present => True,
4738              Parameter_Type =>
4739                New_Reference_To (Standard_String, Loc)));
4740       end if;
4741
4742       return Formals;
4743
4744    exception
4745       when RE_Not_Available =>
4746          return Empty_List;
4747    end Init_Formals;
4748
4749    ------------------
4750    -- Make_Eq_Case --
4751    ------------------
4752
4753    --  <Make_Eq_if shared components>
4754    --  case X.D1 is
4755    --     when V1 => <Make_Eq_Case> on subcomponents
4756    --     ...
4757    --     when Vn => <Make_Eq_Case> on subcomponents
4758    --  end case;
4759
4760    function Make_Eq_Case (Node : Node_Id; CL : Node_Id) return List_Id is
4761       Loc      : constant Source_Ptr := Sloc (Node);
4762       Result   : constant List_Id    := New_List;
4763       Variant  : Node_Id;
4764       Alt_List : List_Id;
4765
4766    begin
4767       Append_To (Result, Make_Eq_If (Node, Component_Items (CL)));
4768
4769       if No (Variant_Part (CL)) then
4770          return Result;
4771       end if;
4772
4773       Variant := First_Non_Pragma (Variants (Variant_Part (CL)));
4774
4775       if No (Variant) then
4776          return Result;
4777       end if;
4778
4779       Alt_List := New_List;
4780
4781       while Present (Variant) loop
4782          Append_To (Alt_List,
4783            Make_Case_Statement_Alternative (Loc,
4784              Discrete_Choices => New_Copy_List (Discrete_Choices (Variant)),
4785              Statements => Make_Eq_Case (Node, Component_List (Variant))));
4786
4787          Next_Non_Pragma (Variant);
4788       end loop;
4789
4790       Append_To (Result,
4791         Make_Case_Statement (Loc,
4792           Expression =>
4793             Make_Selected_Component (Loc,
4794               Prefix => Make_Identifier (Loc, Name_X),
4795               Selector_Name => New_Copy (Name (Variant_Part (CL)))),
4796           Alternatives => Alt_List));
4797
4798       return Result;
4799    end Make_Eq_Case;
4800
4801    ----------------
4802    -- Make_Eq_If --
4803    ----------------
4804
4805    --  Generates:
4806
4807    --    if
4808    --      X.C1 /= Y.C1
4809    --        or else
4810    --      X.C2 /= Y.C2
4811    --        ...
4812    --    then
4813    --       return False;
4814    --    end if;
4815
4816    --  or a null statement if the list L is empty
4817
4818    function Make_Eq_If (Node : Node_Id; L : List_Id) return Node_Id is
4819       Loc        : constant Source_Ptr := Sloc (Node);
4820       C          : Node_Id;
4821       Field_Name : Name_Id;
4822       Cond       : Node_Id;
4823
4824    begin
4825       if No (L) then
4826          return Make_Null_Statement (Loc);
4827
4828       else
4829          Cond := Empty;
4830
4831          C := First_Non_Pragma (L);
4832          while Present (C) loop
4833             Field_Name := Chars (Defining_Identifier (C));
4834
4835             --  The tags must not be compared they are not part of the value.
4836             --  Note also that in the following, we use Make_Identifier for
4837             --  the component names. Use of New_Reference_To to identify the
4838             --  components would be incorrect because the wrong entities for
4839             --  discriminants could be picked up in the private type case.
4840
4841             if Field_Name /= Name_uTag then
4842                Evolve_Or_Else (Cond,
4843                  Make_Op_Ne (Loc,
4844                    Left_Opnd =>
4845                      Make_Selected_Component (Loc,
4846                        Prefix        => Make_Identifier (Loc, Name_X),
4847                        Selector_Name =>
4848                          Make_Identifier (Loc, Field_Name)),
4849
4850                    Right_Opnd =>
4851                      Make_Selected_Component (Loc,
4852                        Prefix        => Make_Identifier (Loc, Name_Y),
4853                        Selector_Name =>
4854                          Make_Identifier (Loc, Field_Name))));
4855             end if;
4856
4857             Next_Non_Pragma (C);
4858          end loop;
4859
4860          if No (Cond) then
4861             return Make_Null_Statement (Loc);
4862
4863          else
4864             return
4865               Make_Implicit_If_Statement (Node,
4866                 Condition => Cond,
4867                 Then_Statements => New_List (
4868                   Make_Return_Statement (Loc,
4869                     Expression => New_Occurrence_Of (Standard_False, Loc))));
4870          end if;
4871       end if;
4872    end Make_Eq_If;
4873
4874    -------------------------------------
4875    -- Make_Predefined_Primitive_Specs --
4876    -------------------------------------
4877
4878    procedure Make_Predefined_Primitive_Specs
4879      (Tag_Typ     : Entity_Id;
4880       Predef_List : out List_Id;
4881       Renamed_Eq  : out Node_Id)
4882    is
4883       Loc       : constant Source_Ptr := Sloc (Tag_Typ);
4884       Res       : constant List_Id    := New_List;
4885       Prim      : Elmt_Id;
4886       Eq_Needed : Boolean;
4887       Eq_Spec   : Node_Id;
4888       Eq_Name   : Name_Id := Name_Op_Eq;
4889
4890       function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean;
4891       --  Returns true if Prim is a renaming of an unresolved predefined
4892       --  equality operation.
4893
4894       -------------------------------
4895       -- Is_Predefined_Eq_Renaming --
4896       -------------------------------
4897
4898       function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean is
4899       begin
4900          return Chars (Prim) /= Name_Op_Eq
4901            and then Present (Alias (Prim))
4902            and then Comes_From_Source (Prim)
4903            and then Is_Intrinsic_Subprogram (Alias (Prim))
4904            and then Chars (Alias (Prim)) = Name_Op_Eq;
4905       end Is_Predefined_Eq_Renaming;
4906
4907    --  Start of processing for Make_Predefined_Primitive_Specs
4908
4909    begin
4910       Renamed_Eq := Empty;
4911
4912       --  Spec of _Alignment
4913
4914       Append_To (Res, Predef_Spec_Or_Body (Loc,
4915         Tag_Typ => Tag_Typ,
4916         Name    => Name_uAlignment,
4917         Profile => New_List (
4918           Make_Parameter_Specification (Loc,
4919             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
4920             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
4921
4922         Ret_Type => Standard_Integer));
4923
4924       --  Spec of _Size
4925
4926       Append_To (Res, Predef_Spec_Or_Body (Loc,
4927         Tag_Typ => Tag_Typ,
4928         Name    => Name_uSize,
4929         Profile => New_List (
4930           Make_Parameter_Specification (Loc,
4931             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
4932             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
4933
4934         Ret_Type => Standard_Long_Long_Integer));
4935
4936       --  Specs for dispatching stream attributes. We skip these for limited
4937       --  types, since there is no question of dispatching in the limited case.
4938
4939       --  We also skip these operations if dispatching is not available
4940       --  or if streams are not available (since what's the point?)
4941
4942       if not Is_Limited_Type (Tag_Typ)
4943         and then RTE_Available (RE_Tag)
4944         and then RTE_Available (RE_Root_Stream_Type)
4945       then
4946          Append_To (Res,
4947            Predef_Stream_Attr_Spec (Loc, Tag_Typ, TSS_Stream_Read));
4948          Append_To (Res,
4949            Predef_Stream_Attr_Spec (Loc, Tag_Typ, TSS_Stream_Write));
4950          Append_To (Res,
4951            Predef_Stream_Attr_Spec (Loc, Tag_Typ, TSS_Stream_Input));
4952          Append_To (Res,
4953            Predef_Stream_Attr_Spec (Loc, Tag_Typ, TSS_Stream_Output));
4954       end if;
4955
4956       --  Spec of "=" if expanded if the type is not limited and if a
4957       --  user defined "=" was not already declared for the non-full
4958       --  view of a private extension
4959
4960       if not Is_Limited_Type (Tag_Typ) then
4961          Eq_Needed := True;
4962
4963          Prim := First_Elmt (Primitive_Operations (Tag_Typ));
4964          while Present (Prim) loop
4965
4966             --  If a primitive is encountered that renames the predefined
4967             --  equality operator before reaching any explicit equality
4968             --  primitive, then we still need to create a predefined
4969             --  equality function, because calls to it can occur via
4970             --  the renaming. A new name is created for the equality
4971             --  to avoid conflicting with any user-defined equality.
4972             --  (Note that this doesn't account for renamings of
4973             --  equality nested within subpackages???)
4974
4975             if Is_Predefined_Eq_Renaming (Node (Prim)) then
4976                Eq_Name := New_External_Name (Chars (Node (Prim)), 'E');
4977
4978             elsif Chars (Node (Prim)) = Name_Op_Eq
4979               and then (No (Alias (Node (Prim)))
4980                          or else Nkind (Unit_Declaration_Node (Node (Prim))) =
4981                                             N_Subprogram_Renaming_Declaration)
4982               and then Etype (First_Formal (Node (Prim))) =
4983                          Etype (Next_Formal (First_Formal (Node (Prim))))
4984
4985             then
4986                Eq_Needed := False;
4987                exit;
4988
4989             --  If the parent equality is abstract, the inherited equality is
4990             --  abstract as well, and no body can be created for for it.
4991
4992             elsif Chars (Node (Prim)) = Name_Op_Eq
4993               and then Present (Alias (Node (Prim)))
4994               and then Is_Abstract (Alias (Node (Prim)))
4995             then
4996                Eq_Needed := False;
4997                exit;
4998             end if;
4999
5000             Next_Elmt (Prim);
5001          end loop;
5002
5003          --  If a renaming of predefined equality was found
5004          --  but there was no user-defined equality (so Eq_Needed
5005          --  is still true), then set the name back to Name_Op_Eq.
5006          --  But in the case where a user-defined equality was
5007          --  located after such a renaming, then the predefined
5008          --  equality function is still needed, so Eq_Needed must
5009          --  be set back to True.
5010
5011          if Eq_Name /= Name_Op_Eq then
5012             if Eq_Needed then
5013                Eq_Name := Name_Op_Eq;
5014             else
5015                Eq_Needed := True;
5016             end if;
5017          end if;
5018
5019          if Eq_Needed then
5020             Eq_Spec := Predef_Spec_Or_Body (Loc,
5021               Tag_Typ => Tag_Typ,
5022               Name    => Eq_Name,
5023               Profile => New_List (
5024                 Make_Parameter_Specification (Loc,
5025                   Defining_Identifier =>
5026                     Make_Defining_Identifier (Loc, Name_X),
5027                     Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
5028                 Make_Parameter_Specification (Loc,
5029                   Defining_Identifier =>
5030                     Make_Defining_Identifier (Loc, Name_Y),
5031                     Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
5032                 Ret_Type => Standard_Boolean);
5033             Append_To (Res, Eq_Spec);
5034
5035             if Eq_Name /= Name_Op_Eq then
5036                Renamed_Eq := Defining_Unit_Name (Specification (Eq_Spec));
5037
5038                Prim := First_Elmt (Primitive_Operations (Tag_Typ));
5039                while Present (Prim) loop
5040
5041                   --  Any renamings of equality that appeared before an
5042                   --  overriding equality must be updated to refer to
5043                   --  the entity for the predefined equality, otherwise
5044                   --  calls via the renaming would get incorrectly
5045                   --  resolved to call the user-defined equality function.
5046
5047                   if Is_Predefined_Eq_Renaming (Node (Prim)) then
5048                      Set_Alias (Node (Prim), Renamed_Eq);
5049
5050                   --  Exit upon encountering a user-defined equality
5051
5052                   elsif Chars (Node (Prim)) = Name_Op_Eq
5053                     and then No (Alias (Node (Prim)))
5054                   then
5055                      exit;
5056                   end if;
5057
5058                   Next_Elmt (Prim);
5059                end loop;
5060             end if;
5061          end if;
5062
5063          --  Spec for dispatching assignment
5064
5065          Append_To (Res, Predef_Spec_Or_Body (Loc,
5066            Tag_Typ => Tag_Typ,
5067            Name    => Name_uAssign,
5068            Profile => New_List (
5069              Make_Parameter_Specification (Loc,
5070                Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
5071                Out_Present         => True,
5072                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
5073
5074              Make_Parameter_Specification (Loc,
5075                Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
5076                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)))));
5077       end if;
5078
5079       --  Specs for finalization actions that may be required in case a
5080       --  future extension contain a controlled element. We generate those
5081       --  only for root tagged types where they will get dummy bodies or
5082       --  when the type has controlled components and their body must be
5083       --  generated. It is also impossible to provide those for tagged
5084       --  types defined within s-finimp since it would involve circularity
5085       --  problems
5086
5087       if In_Finalization_Root (Tag_Typ) then
5088          null;
5089
5090       --  We also skip these if finalization is not available
5091
5092       elsif Restrictions (No_Finalization) then
5093          null;
5094
5095       elsif Etype (Tag_Typ) = Tag_Typ or else Controlled_Type (Tag_Typ) then
5096          if not Is_Limited_Type (Tag_Typ) then
5097             Append_To (Res,
5098               Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust));
5099          end if;
5100
5101          Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize));
5102       end if;
5103
5104       Predef_List := Res;
5105    end Make_Predefined_Primitive_Specs;
5106
5107    ---------------------------------
5108    -- Needs_Simple_Initialization --
5109    ---------------------------------
5110
5111    function Needs_Simple_Initialization (T : Entity_Id) return Boolean is
5112    begin
5113       --  Check for private type, in which case test applies to the
5114       --  underlying type of the private type.
5115
5116       if Is_Private_Type (T) then
5117          declare
5118             RT : constant Entity_Id := Underlying_Type (T);
5119
5120          begin
5121             if Present (RT) then
5122                return Needs_Simple_Initialization (RT);
5123             else
5124                return False;
5125             end if;
5126          end;
5127
5128       --  Cases needing simple initialization are access types, and, if pragma
5129       --  Normalize_Scalars or Initialize_Scalars is in effect, then all scalar
5130       --  types.
5131
5132       elsif Is_Access_Type (T)
5133         or else (Init_Or_Norm_Scalars and then (Is_Scalar_Type (T)))
5134
5135         or else (Is_Bit_Packed_Array (T)
5136                    and then Is_Modular_Integer_Type (Packed_Array_Type (T)))
5137       then
5138          return True;
5139
5140       --  If Initialize/Normalize_Scalars is in effect, string objects also
5141       --  need initialization, unless they are created in the course of
5142       --  expanding an aggregate (since in the latter case they will be
5143       --  filled with appropriate initializing values before they are used).
5144
5145       elsif Init_Or_Norm_Scalars
5146         and then
5147           (Root_Type (T) = Standard_String
5148             or else Root_Type (T) = Standard_Wide_String)
5149         and then
5150           (not Is_Itype (T)
5151             or else Nkind (Associated_Node_For_Itype (T)) /= N_Aggregate)
5152       then
5153          return True;
5154
5155       else
5156          return False;
5157       end if;
5158    end Needs_Simple_Initialization;
5159
5160    ----------------------
5161    -- Predef_Deep_Spec --
5162    ----------------------
5163
5164    function Predef_Deep_Spec
5165      (Loc      : Source_Ptr;
5166       Tag_Typ  : Entity_Id;
5167       Name     : TSS_Name_Type;
5168       For_Body : Boolean := False)
5169       return     Node_Id
5170    is
5171       Prof   : List_Id;
5172       Type_B : Entity_Id;
5173
5174    begin
5175       if Name = TSS_Deep_Finalize then
5176          Prof := New_List;
5177          Type_B := Standard_Boolean;
5178
5179       else
5180          Prof := New_List (
5181            Make_Parameter_Specification (Loc,
5182              Defining_Identifier => Make_Defining_Identifier (Loc, Name_L),
5183              In_Present          => True,
5184              Out_Present         => True,
5185              Parameter_Type      =>
5186                New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
5187          Type_B := Standard_Short_Short_Integer;
5188       end if;
5189
5190       Append_To (Prof,
5191            Make_Parameter_Specification (Loc,
5192              Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
5193              In_Present          => True,
5194              Out_Present         => True,
5195              Parameter_Type      => New_Reference_To (Tag_Typ, Loc)));
5196
5197       Append_To (Prof,
5198            Make_Parameter_Specification (Loc,
5199              Defining_Identifier => Make_Defining_Identifier (Loc, Name_B),
5200              Parameter_Type      => New_Reference_To (Type_B, Loc)));
5201
5202       return Predef_Spec_Or_Body (Loc,
5203         Name     => Make_TSS_Name (Tag_Typ, Name),
5204         Tag_Typ  => Tag_Typ,
5205         Profile  => Prof,
5206         For_Body => For_Body);
5207
5208    exception
5209       when RE_Not_Available =>
5210          return Empty;
5211    end Predef_Deep_Spec;
5212
5213    -------------------------
5214    -- Predef_Spec_Or_Body --
5215    -------------------------
5216
5217    function Predef_Spec_Or_Body
5218      (Loc      : Source_Ptr;
5219       Tag_Typ  : Entity_Id;
5220       Name     : Name_Id;
5221       Profile  : List_Id;
5222       Ret_Type : Entity_Id := Empty;
5223       For_Body : Boolean := False)
5224       return     Node_Id
5225    is
5226       Id   : constant Entity_Id := Make_Defining_Identifier (Loc, Name);
5227       Spec : Node_Id;
5228
5229    begin
5230       Set_Is_Public (Id, Is_Public (Tag_Typ));
5231
5232       --  The internal flag is set to mark these declarations because
5233       --  they have specific properties. First they are primitives even
5234       --  if they are not defined in the type scope (the freezing point
5235       --  is not necessarily in the same scope), furthermore the
5236       --  predefined equality can be overridden by a user-defined
5237       --  equality, no body will be generated in this case.
5238
5239       Set_Is_Internal (Id);
5240
5241       if not Debug_Generated_Code then
5242          Set_Debug_Info_Off (Id);
5243       end if;
5244
5245       if No (Ret_Type) then
5246          Spec :=
5247            Make_Procedure_Specification (Loc,
5248              Defining_Unit_Name       => Id,
5249              Parameter_Specifications => Profile);
5250       else
5251          Spec :=
5252            Make_Function_Specification (Loc,
5253              Defining_Unit_Name       => Id,
5254              Parameter_Specifications => Profile,
5255              Subtype_Mark             =>
5256                New_Reference_To (Ret_Type, Loc));
5257       end if;
5258
5259       --  If body case, return empty subprogram body. Note that this is
5260       --  ill-formed, because there is not even a null statement, and
5261       --  certainly not a return in the function case. The caller is
5262       --  expected to do surgery on the body to add the appropriate stuff.
5263
5264       if For_Body then
5265          return Make_Subprogram_Body (Loc, Spec, Empty_List, Empty);
5266
5267       --  For the case of Input/Output attributes applied to an abstract type,
5268       --  generate abstract specifications. These will never be called,
5269       --  but we need the slots allocated in the dispatching table so
5270       --  that typ'Class'Input and typ'Class'Output will work properly.
5271
5272       elsif (Is_TSS (Name, TSS_Stream_Input)
5273               or else
5274              Is_TSS (Name, TSS_Stream_Output))
5275         and then Is_Abstract (Tag_Typ)
5276       then
5277          return Make_Abstract_Subprogram_Declaration (Loc, Spec);
5278
5279       --  Normal spec case, where we return a subprogram declaration
5280
5281       else
5282          return Make_Subprogram_Declaration (Loc, Spec);
5283       end if;
5284    end Predef_Spec_Or_Body;
5285
5286    -----------------------------
5287    -- Predef_Stream_Attr_Spec --
5288    -----------------------------
5289
5290    function Predef_Stream_Attr_Spec
5291      (Loc      : Source_Ptr;
5292       Tag_Typ  : Entity_Id;
5293       Name     : TSS_Name_Type;
5294       For_Body : Boolean := False)
5295       return     Node_Id
5296    is
5297       Ret_Type : Entity_Id;
5298
5299    begin
5300       if Name = TSS_Stream_Input then
5301          Ret_Type := Tag_Typ;
5302       else
5303          Ret_Type := Empty;
5304       end if;
5305
5306       return Predef_Spec_Or_Body (Loc,
5307         Name     => Make_TSS_Name (Tag_Typ, Name),
5308         Tag_Typ  => Tag_Typ,
5309         Profile  => Build_Stream_Attr_Profile (Loc, Tag_Typ, Name),
5310         Ret_Type => Ret_Type,
5311         For_Body => For_Body);
5312    end Predef_Stream_Attr_Spec;
5313
5314    ---------------------------------
5315    -- Predefined_Primitive_Bodies --
5316    ---------------------------------
5317
5318    function Predefined_Primitive_Bodies
5319      (Tag_Typ    : Entity_Id;
5320       Renamed_Eq : Node_Id)
5321       return       List_Id
5322    is
5323       Loc       : constant Source_Ptr := Sloc (Tag_Typ);
5324       Res       : constant List_Id    := New_List;
5325       Decl      : Node_Id;
5326       Prim      : Elmt_Id;
5327       Eq_Needed : Boolean;
5328       Eq_Name   : Name_Id;
5329       Ent       : Entity_Id;
5330
5331    begin
5332       --  See if we have a predefined "=" operator
5333
5334       if Present (Renamed_Eq) then
5335          Eq_Needed := True;
5336          Eq_Name   := Chars (Renamed_Eq);
5337
5338       else
5339          Eq_Needed := False;
5340          Eq_Name   := No_Name;
5341
5342          Prim := First_Elmt (Primitive_Operations (Tag_Typ));
5343          while Present (Prim) loop
5344             if Chars (Node (Prim)) = Name_Op_Eq
5345               and then Is_Internal (Node (Prim))
5346             then
5347                Eq_Needed := True;
5348                Eq_Name := Name_Op_Eq;
5349             end if;
5350
5351             Next_Elmt (Prim);
5352          end loop;
5353       end if;
5354
5355       --  Body of _Alignment
5356
5357       Decl := Predef_Spec_Or_Body (Loc,
5358         Tag_Typ => Tag_Typ,
5359         Name    => Name_uAlignment,
5360         Profile => New_List (
5361           Make_Parameter_Specification (Loc,
5362             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
5363             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
5364
5365         Ret_Type => Standard_Integer,
5366         For_Body => True);
5367
5368       Set_Handled_Statement_Sequence (Decl,
5369         Make_Handled_Sequence_Of_Statements (Loc, New_List (
5370           Make_Return_Statement (Loc,
5371             Expression =>
5372               Make_Attribute_Reference (Loc,
5373                 Prefix => Make_Identifier (Loc, Name_X),
5374                 Attribute_Name  => Name_Alignment)))));
5375
5376       Append_To (Res, Decl);
5377
5378       --  Body of _Size
5379
5380       Decl := Predef_Spec_Or_Body (Loc,
5381         Tag_Typ => Tag_Typ,
5382         Name    => Name_uSize,
5383         Profile => New_List (
5384           Make_Parameter_Specification (Loc,
5385             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
5386             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
5387
5388         Ret_Type => Standard_Long_Long_Integer,
5389         For_Body => True);
5390
5391       Set_Handled_Statement_Sequence (Decl,
5392         Make_Handled_Sequence_Of_Statements (Loc, New_List (
5393           Make_Return_Statement (Loc,
5394             Expression =>
5395               Make_Attribute_Reference (Loc,
5396                 Prefix => Make_Identifier (Loc, Name_X),
5397                 Attribute_Name  => Name_Size)))));
5398
5399       Append_To (Res, Decl);
5400
5401       --  Bodies for Dispatching stream IO routines. We need these only for
5402       --  non-limited types (in the limited case there is no dispatching).
5403       --  We also skip them if dispatching is not available.
5404
5405       if not Is_Limited_Type (Tag_Typ)
5406         and then not Restrictions (No_Finalization)
5407       then
5408          if No (TSS (Tag_Typ, TSS_Stream_Read)) then
5409             Build_Record_Read_Procedure (Loc, Tag_Typ, Decl, Ent);
5410             Append_To (Res, Decl);
5411          end if;
5412
5413          if No (TSS (Tag_Typ, TSS_Stream_Write)) then
5414             Build_Record_Write_Procedure (Loc, Tag_Typ, Decl, Ent);
5415             Append_To (Res, Decl);
5416          end if;
5417
5418          --  Skip bodies of _Input and _Output for the abstract case, since
5419          --  the corresponding specs are abstract (see Predef_Spec_Or_Body)
5420
5421          if not Is_Abstract (Tag_Typ) then
5422             if No (TSS (Tag_Typ, TSS_Stream_Input)) then
5423                Build_Record_Or_Elementary_Input_Function
5424                  (Loc, Tag_Typ, Decl, Ent);
5425                Append_To (Res, Decl);
5426             end if;
5427
5428             if No (TSS (Tag_Typ, TSS_Stream_Output)) then
5429                Build_Record_Or_Elementary_Output_Procedure
5430                  (Loc, Tag_Typ, Decl, Ent);
5431                Append_To (Res, Decl);
5432             end if;
5433          end if;
5434       end if;
5435
5436       if not Is_Limited_Type (Tag_Typ) then
5437
5438          --  Body for equality
5439
5440          if Eq_Needed then
5441
5442             Decl := Predef_Spec_Or_Body (Loc,
5443               Tag_Typ => Tag_Typ,
5444               Name    => Eq_Name,
5445               Profile => New_List (
5446                 Make_Parameter_Specification (Loc,
5447                   Defining_Identifier =>
5448                     Make_Defining_Identifier (Loc, Name_X),
5449                   Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
5450
5451                 Make_Parameter_Specification (Loc,
5452                   Defining_Identifier =>
5453                     Make_Defining_Identifier (Loc, Name_Y),
5454                   Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
5455
5456               Ret_Type => Standard_Boolean,
5457               For_Body => True);
5458
5459             declare
5460                Def          : constant Node_Id := Parent (Tag_Typ);
5461                Stmts        : constant List_Id := New_List;
5462                Variant_Case : Boolean := Has_Discriminants (Tag_Typ);
5463                Comps        : Node_Id := Empty;
5464                Typ_Def      : Node_Id := Type_Definition (Def);
5465
5466             begin
5467                if Variant_Case then
5468                   if Nkind (Typ_Def) = N_Derived_Type_Definition then
5469                      Typ_Def := Record_Extension_Part (Typ_Def);
5470                   end if;
5471
5472                   if Present (Typ_Def) then
5473                      Comps := Component_List (Typ_Def);
5474                   end if;
5475
5476                   Variant_Case := Present (Comps)
5477                     and then Present (Variant_Part (Comps));
5478                end if;
5479
5480                if Variant_Case then
5481                   Append_To (Stmts,
5482                     Make_Eq_If (Tag_Typ, Discriminant_Specifications (Def)));
5483                   Append_List_To (Stmts, Make_Eq_Case (Tag_Typ, Comps));
5484                   Append_To (Stmts,
5485                     Make_Return_Statement (Loc,
5486                       Expression => New_Reference_To (Standard_True, Loc)));
5487
5488                else
5489                   Append_To (Stmts,
5490                     Make_Return_Statement (Loc,
5491                       Expression =>
5492                         Expand_Record_Equality (Tag_Typ,
5493                           Typ => Tag_Typ,
5494                           Lhs => Make_Identifier (Loc, Name_X),
5495                           Rhs => Make_Identifier (Loc, Name_Y),
5496                           Bodies => Declarations (Decl))));
5497                end if;
5498
5499                Set_Handled_Statement_Sequence (Decl,
5500                  Make_Handled_Sequence_Of_Statements (Loc, Stmts));
5501             end;
5502             Append_To (Res, Decl);
5503          end if;
5504
5505          --  Body for dispatching assignment
5506
5507          Decl := Predef_Spec_Or_Body (Loc,
5508            Tag_Typ => Tag_Typ,
5509            Name    => Name_uAssign,
5510            Profile => New_List (
5511              Make_Parameter_Specification (Loc,
5512                Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
5513                Out_Present         => True,
5514                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
5515
5516              Make_Parameter_Specification (Loc,
5517                Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
5518                Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
5519            For_Body => True);
5520
5521          Set_Handled_Statement_Sequence (Decl,
5522            Make_Handled_Sequence_Of_Statements (Loc, New_List (
5523              Make_Assignment_Statement (Loc,
5524                Name       => Make_Identifier (Loc, Name_X),
5525                Expression => Make_Identifier (Loc, Name_Y)))));
5526
5527          Append_To (Res, Decl);
5528       end if;
5529
5530       --  Generate dummy bodies for finalization actions of types that have
5531       --  no controlled components.
5532
5533       --  Skip this processing if we are in the finalization routine in the
5534       --  runtime itself, otherwise we get hopelessly circularly confused!
5535
5536       if In_Finalization_Root (Tag_Typ) then
5537          null;
5538
5539       --  Skip this if finalization is not available
5540
5541       elsif Restrictions (No_Finalization) then
5542          null;
5543
5544       elsif (Etype (Tag_Typ) = Tag_Typ or else Is_Controlled (Tag_Typ))
5545         and then not Has_Controlled_Component (Tag_Typ)
5546       then
5547          if not Is_Limited_Type (Tag_Typ) then
5548             Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust, True);
5549
5550             if Is_Controlled (Tag_Typ) then
5551                Set_Handled_Statement_Sequence (Decl,
5552                  Make_Handled_Sequence_Of_Statements (Loc,
5553                    Make_Adjust_Call (
5554                      Ref          => Make_Identifier (Loc, Name_V),
5555                      Typ          => Tag_Typ,
5556                      Flist_Ref    => Make_Identifier (Loc, Name_L),
5557                      With_Attach  => Make_Identifier (Loc, Name_B))));
5558
5559             else
5560                Set_Handled_Statement_Sequence (Decl,
5561                  Make_Handled_Sequence_Of_Statements (Loc, New_List (
5562                    Make_Null_Statement (Loc))));
5563             end if;
5564
5565             Append_To (Res, Decl);
5566          end if;
5567
5568          Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True);
5569
5570          if Is_Controlled (Tag_Typ) then
5571             Set_Handled_Statement_Sequence (Decl,
5572               Make_Handled_Sequence_Of_Statements (Loc,
5573                 Make_Final_Call (
5574                   Ref         => Make_Identifier (Loc, Name_V),
5575                   Typ         => Tag_Typ,
5576                   With_Detach => Make_Identifier (Loc, Name_B))));
5577
5578          else
5579             Set_Handled_Statement_Sequence (Decl,
5580               Make_Handled_Sequence_Of_Statements (Loc, New_List (
5581                 Make_Null_Statement (Loc))));
5582          end if;
5583
5584          Append_To (Res, Decl);
5585       end if;
5586
5587       return Res;
5588    end Predefined_Primitive_Bodies;
5589
5590    ---------------------------------
5591    -- Predefined_Primitive_Freeze --
5592    ---------------------------------
5593
5594    function Predefined_Primitive_Freeze
5595      (Tag_Typ : Entity_Id) return List_Id
5596    is
5597       Loc     : constant Source_Ptr := Sloc (Tag_Typ);
5598       Res     : constant List_Id    := New_List;
5599       Prim    : Elmt_Id;
5600       Frnodes : List_Id;
5601
5602    begin
5603       Prim := First_Elmt (Primitive_Operations (Tag_Typ));
5604       while Present (Prim) loop
5605          if Is_Internal (Node (Prim)) then
5606             Frnodes := Freeze_Entity (Node (Prim), Loc);
5607
5608             if Present (Frnodes) then
5609                Append_List_To (Res, Frnodes);
5610             end if;
5611          end if;
5612
5613          Next_Elmt (Prim);
5614       end loop;
5615
5616       return Res;
5617    end Predefined_Primitive_Freeze;
5618 end Exp_Ch3;