OSDN Git Service

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