OSDN Git Service

New out of ssa Coalescer.
[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 --          Copyright (C) 1992-2006, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 with Atree;    use Atree;
28 with Checks;   use Checks;
29 with Debug;    use Debug;
30 with Einfo;    use Einfo;
31 with Errout;   use Errout;
32 with Exp_Aggr; use Exp_Aggr;
33 with Exp_Ch4;  use Exp_Ch4;
34 with Exp_Ch6;  use Exp_Ch6;
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 Rident;   use Rident;
51 with Rtsfind;  use Rtsfind;
52 with Sem;      use Sem;
53 with Sem_Attr; use Sem_Attr;
54 with Sem_Cat;  use Sem_Cat;
55 with Sem_Ch3;  use Sem_Ch3;
56 with Sem_Ch8;  use Sem_Ch8;
57 with Sem_Disp; use Sem_Disp;
58 with Sem_Eval; use Sem_Eval;
59 with Sem_Mech; use Sem_Mech;
60 with Sem_Res;  use Sem_Res;
61 with Sem_Util; use Sem_Util;
62 with Sinfo;    use Sinfo;
63 with Stand;    use Stand;
64 with Snames;   use Snames;
65 with Tbuild;   use Tbuild;
66 with Ttypes;   use Ttypes;
67 with Validsw;  use Validsw;
68
69 package body Exp_Ch3 is
70
71    -----------------------
72    -- Local Subprograms --
73    -----------------------
74
75    procedure Adjust_Discriminants (Rtype : Entity_Id);
76    --  This is used when freezing a record type. It attempts to construct
77    --  more restrictive subtypes for discriminants so that the max size of
78    --  the record can be calculated more accurately. See the body of this
79    --  procedure for details.
80
81    procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id);
82    --  Build initialization procedure for given array type. Nod is a node
83    --  used for attachment of any actions required in its construction.
84    --  It also supplies the source location used for the procedure.
85
86    function Build_Discriminant_Formals
87      (Rec_Id : Entity_Id;
88       Use_Dl : Boolean) return List_Id;
89    --  This function uses the discriminants of a type to build a list of
90    --  formal parameters, used in the following function. If the flag Use_Dl
91    --  is set, the list is built using the already defined discriminals
92    --  of the type. Otherwise new identifiers are created, with the source
93    --  names of the discriminants.
94
95    procedure Build_Record_Init_Proc (N : Node_Id; Pe : Entity_Id);
96    --  Build record initialization procedure. N is the type declaration
97    --  node, and Pe is the corresponding entity for the record type.
98
99    procedure Build_Slice_Assignment (Typ : Entity_Id);
100    --  Build assignment procedure for one-dimensional arrays of controlled
101    --  types. Other array and slice assignments are expanded in-line, but
102    --  the code expansion for controlled components (when control actions
103    --  are active) can lead to very large blocks that GCC3 handles poorly.
104
105    procedure Build_Variant_Record_Equality (Typ  : Entity_Id);
106    --  Create An Equality function for the non-tagged variant record 'Typ'
107    --  and attach it to the TSS list
108
109    procedure Check_Stream_Attributes (Typ : Entity_Id);
110    --  Check that if a limited extension has a parent with user-defined
111    --  stream attributes, and does not itself have user-definer
112    --  stream-attributes, then any limited component of the extension also
113    --  has the corresponding user-defined stream attributes.
114
115    procedure Clean_Task_Names
116      (Typ     : Entity_Id;
117       Proc_Id : Entity_Id);
118    --  If an initialization procedure includes calls to generate names
119    --  for task subcomponents, indicate that secondary stack cleanup is
120    --  needed after an initialization. Typ is the component type, and Proc_Id
121    --  the initialization procedure for the enclosing composite type.
122
123    procedure Expand_Tagged_Root (T : Entity_Id);
124    --  Add a field _Tag at the beginning of the record. This field carries
125    --  the value of the access to the Dispatch table. This procedure is only
126    --  called on root type, the _Tag field being inherited by the descendants.
127
128    procedure Expand_Record_Controller (T : Entity_Id);
129    --  T must be a record type that Has_Controlled_Component. Add a field
130    --  _controller of type Record_Controller or Limited_Record_Controller
131    --  in the record T.
132
133    procedure Freeze_Array_Type (N : Node_Id);
134    --  Freeze an array type. Deals with building the initialization procedure,
135    --  creating the packed array type for a packed array and also with the
136    --  creation of the controlling procedures for the controlled case. The
137    --  argument N is the N_Freeze_Entity node for the type.
138
139    procedure Freeze_Enumeration_Type (N : Node_Id);
140    --  Freeze enumeration type with non-standard representation. Builds the
141    --  array and function needed to convert between enumeration pos and
142    --  enumeration representation values. N is the N_Freeze_Entity node
143    --  for the type.
144
145    procedure Freeze_Record_Type (N : Node_Id);
146    --  Freeze record type. Builds all necessary discriminant checking
147    --  and other ancillary functions, and builds dispatch tables where
148    --  needed. The argument N is the N_Freeze_Entity node. This processing
149    --  applies only to E_Record_Type entities, not to class wide types,
150    --  record subtypes, or private types.
151
152    procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id);
153    --  Treat user-defined stream operations as renaming_as_body if the
154    --  subprogram they rename is not frozen when the type is frozen.
155
156    function Init_Formals (Typ : Entity_Id) return List_Id;
157    --  This function builds the list of formals for an initialization routine.
158    --  The first formal is always _Init with the given type. For task value
159    --  record types and types containing tasks, three additional formals are
160    --  added:
161    --
162    --    _Master    : Master_Id
163    --    _Chain     : in out Activation_Chain
164    --    _Task_Name : String
165    --
166    --  The caller must append additional entries for discriminants if required.
167
168    function In_Runtime (E : Entity_Id) return Boolean;
169    --  Check if E is defined in the RTL (in a child of Ada or System). Used
170    --  to avoid to bring in the overhead of _Input, _Output for tagged types.
171
172    function Make_Eq_Case
173      (E     : Entity_Id;
174       CL    : Node_Id;
175       Discr : Entity_Id := Empty) 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). E provides the Sloc to be
181    --  used for the generated code. Discr is used as the case statement switch
182    --  in the case of Unchecked_Union equality.
183
184    function Make_Eq_If
185      (E : Entity_Id;
186       L : List_Id) return Node_Id;
187    --  Building block for variant record equality. Defined to share the
188    --  code between the tagged and non-tagged case. Given the list of
189    --  components (or discriminants) L, it generates a return statement
190    --  that compares all components of local temporaries named X and Y
191    --  (that are declared as formals at some upper level). E provides the Sloc
192    --  to be used for the generated code.
193
194    procedure Make_Predefined_Primitive_Specs
195      (Tag_Typ     : Entity_Id;
196       Predef_List : out List_Id;
197       Renamed_Eq  : out Node_Id);
198    --  Create a list with the specs of the predefined primitive operations.
199    --  The following entries are present for all tagged types, and provide
200    --  the results of the corresponding attribute applied to the object.
201    --  Dispatching is required in general, since the result of the attribute
202    --  will vary with the actual object subtype.
203    --
204    --     _alignment     provides result of 'Alignment attribute
205    --     _size          provides result of 'Size attribute
206    --     typSR          provides result of 'Read attribute
207    --     typSW          provides result of 'Write attribute
208    --     typSI          provides result of 'Input attribute
209    --     typSO          provides result of 'Output attribute
210    --
211    --  The following entries are additionally present for non-limited
212    --  tagged types, and implement additional dispatching operations
213    --  for predefined operations:
214    --
215    --     _equality      implements "=" operator
216    --     _assign        implements assignment operation
217    --     typDF          implements deep finalization
218    --     typDA          implements deep adust
219    --
220    --  The latter two are empty procedures unless the type contains some
221    --  controlled components that require finalization actions (the deep
222    --  in the name refers to the fact that the action applies to components).
223    --
224    --  The list is returned in Predef_List. The Parameter Renamed_Eq
225    --  either returns the value Empty, or else the defining unit name
226    --  for the predefined equality function in the case where the type
227    --  has a primitive operation that is a renaming of predefined equality
228    --  (but only if there is also an overriding user-defined equality
229    --  function). The returned Renamed_Eq will be passed to the
230    --  corresponding parameter of Predefined_Primitive_Bodies.
231
232    function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean;
233    --  returns True if there are representation clauses for type T that
234    --  are not inherited. If the result is false, the init_proc and the
235    --  discriminant_checking functions of the parent can be reused by
236    --  a derived type.
237
238    procedure Make_Controlling_Function_Wrappers
239      (Tag_Typ   : Entity_Id;
240       Decl_List : out List_Id;
241       Body_List : out List_Id);
242    --  Ada 2005 (AI-391): Makes specs and bodies for the wrapper functions
243    --  associated with inherited functions with controlling results which
244    --  are not overridden. The body of each wrapper function consists solely
245    --  of a return statement whose expression is an extension aggregate
246    --  invoking the inherited subprogram's parent subprogram and extended
247    --  with a null association list.
248
249    procedure Make_Null_Procedure_Specs
250      (Tag_Typ   : Entity_Id;
251       Decl_List : out List_Id);
252    --  Ada 2005 (AI-251): Makes specs for null procedures associated with any
253    --  null procedures inherited from an interface type that have not been
254    --  overridden. Only one null procedure will be created for a given set of
255    --  inherited null procedures with homographic profiles.
256
257    function Predef_Spec_Or_Body
258      (Loc      : Source_Ptr;
259       Tag_Typ  : Entity_Id;
260       Name     : Name_Id;
261       Profile  : List_Id;
262       Ret_Type : Entity_Id := Empty;
263       For_Body : Boolean   := False) return Node_Id;
264    --  This function generates the appropriate expansion for a predefined
265    --  primitive operation specified by its name, parameter profile and
266    --  return type (Empty means this is a procedure). If For_Body is false,
267    --  then the returned node is a subprogram declaration. If For_Body is
268    --  true, then the returned node is a empty subprogram body containing
269    --  no declarations and no statements.
270
271    function Predef_Stream_Attr_Spec
272      (Loc      : Source_Ptr;
273       Tag_Typ  : Entity_Id;
274       Name     : TSS_Name_Type;
275       For_Body : Boolean := False) return Node_Id;
276    --  Specialized version of Predef_Spec_Or_Body that apply to read, write,
277    --  input and output attribute whose specs are constructed in Exp_Strm.
278
279    function Predef_Deep_Spec
280      (Loc      : Source_Ptr;
281       Tag_Typ  : Entity_Id;
282       Name     : TSS_Name_Type;
283       For_Body : Boolean := False) return Node_Id;
284    --  Specialized version of Predef_Spec_Or_Body that apply to _deep_adjust
285    --  and _deep_finalize
286
287    function Predefined_Primitive_Bodies
288      (Tag_Typ    : Entity_Id;
289       Renamed_Eq : Node_Id) return List_Id;
290    --  Create the bodies of the predefined primitives that are described in
291    --  Predefined_Primitive_Specs. When not empty, Renamed_Eq must denote
292    --  the defining unit name of the type's predefined equality as returned
293    --  by Make_Predefined_Primitive_Specs.
294
295    function Predefined_Primitive_Freeze (Tag_Typ : Entity_Id) return List_Id;
296    --  Freeze entities of all predefined primitive operations. This is needed
297    --  because the bodies of these operations do not normally do any freezeing.
298
299    function Stream_Operation_OK
300      (Typ       : Entity_Id;
301       Operation : TSS_Name_Type) return Boolean;
302    --  Check whether the named stream operation must be emitted for a given
303    --  type. The rules for inheritance of stream attributes by type extensions
304    --  are enforced by this function. Furthermore, various restrictions prevent
305    --  the generation of these operations, as a useful optimization or for
306    --  certification purposes.
307
308    --------------------------
309    -- Adjust_Discriminants --
310    --------------------------
311
312    --  This procedure attempts to define subtypes for discriminants that
313    --  are more restrictive than those declared. Such a replacement is
314    --  possible if we can demonstrate that values outside the restricted
315    --  range would cause constraint errors in any case. The advantage of
316    --  restricting the discriminant types in this way is tha the maximum
317    --  size of the variant record can be calculated more conservatively.
318
319    --  An example of a situation in which we can perform this type of
320    --  restriction is the following:
321
322    --    subtype B is range 1 .. 10;
323    --    type Q is array (B range <>) of Integer;
324
325    --    type V (N : Natural) is record
326    --       C : Q (1 .. N);
327    --    end record;
328
329    --  In this situation, we can restrict the upper bound of N to 10, since
330    --  any larger value would cause a constraint error in any case.
331
332    --  There are many situations in which such restriction is possible, but
333    --  for now, we just look for cases like the above, where the component
334    --  in question is a one dimensional array whose upper bound is one of
335    --  the record discriminants. Also the component must not be part of
336    --  any variant part, since then the component does not always exist.
337
338    procedure Adjust_Discriminants (Rtype : Entity_Id) is
339       Loc   : constant Source_Ptr := Sloc (Rtype);
340       Comp  : Entity_Id;
341       Ctyp  : Entity_Id;
342       Ityp  : Entity_Id;
343       Lo    : Node_Id;
344       Hi    : Node_Id;
345       P     : Node_Id;
346       Loval : Uint;
347       Discr : Entity_Id;
348       Dtyp  : Entity_Id;
349       Dhi   : Node_Id;
350       Dhiv  : Uint;
351       Ahi   : Node_Id;
352       Ahiv  : Uint;
353       Tnn   : Entity_Id;
354
355    begin
356       Comp := First_Component (Rtype);
357       while Present (Comp) loop
358
359          --  If our parent is a variant, quit, we do not look at components
360          --  that are in variant parts, because they may not always exist.
361
362          P := Parent (Comp);   -- component declaration
363          P := Parent (P);      -- component list
364
365          exit when Nkind (Parent (P)) = N_Variant;
366
367          --  We are looking for a one dimensional array type
368
369          Ctyp := Etype (Comp);
370
371          if not Is_Array_Type (Ctyp)
372            or else Number_Dimensions (Ctyp) > 1
373          then
374             goto Continue;
375          end if;
376
377          --  The lower bound must be constant, and the upper bound is a
378          --  discriminant (which is a discriminant of the current record).
379
380          Ityp := Etype (First_Index (Ctyp));
381          Lo := Type_Low_Bound (Ityp);
382          Hi := Type_High_Bound (Ityp);
383
384          if not Compile_Time_Known_Value (Lo)
385            or else Nkind (Hi) /= N_Identifier
386            or else No (Entity (Hi))
387            or else Ekind (Entity (Hi)) /= E_Discriminant
388          then
389             goto Continue;
390          end if;
391
392          --  We have an array with appropriate bounds
393
394          Loval := Expr_Value (Lo);
395          Discr := Entity (Hi);
396          Dtyp  := Etype (Discr);
397
398          --  See if the discriminant has a known upper bound
399
400          Dhi := Type_High_Bound (Dtyp);
401
402          if not Compile_Time_Known_Value (Dhi) then
403             goto Continue;
404          end if;
405
406          Dhiv := Expr_Value (Dhi);
407
408          --  See if base type of component array has known upper bound
409
410          Ahi := Type_High_Bound (Etype (First_Index (Base_Type (Ctyp))));
411
412          if not Compile_Time_Known_Value (Ahi) then
413             goto Continue;
414          end if;
415
416          Ahiv := Expr_Value (Ahi);
417
418          --  The condition for doing the restriction is that the high bound
419          --  of the discriminant is greater than the low bound of the array,
420          --  and is also greater than the high bound of the base type index.
421
422          if Dhiv > Loval and then Dhiv > Ahiv then
423
424             --  We can reset the upper bound of the discriminant type to
425             --  whichever is larger, the low bound of the component, or
426             --  the high bound of the base type array index.
427
428             --  We build a subtype that is declared as
429
430             --     subtype Tnn is discr_type range discr_type'First .. max;
431
432             --  And insert this declaration into the tree. The type of the
433             --  discriminant is then reset to this more restricted subtype.
434
435             Tnn := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
436
437             Insert_Action (Declaration_Node (Rtype),
438               Make_Subtype_Declaration (Loc,
439                 Defining_Identifier => Tnn,
440                 Subtype_Indication =>
441                   Make_Subtype_Indication (Loc,
442                     Subtype_Mark => New_Occurrence_Of (Dtyp, Loc),
443                     Constraint   =>
444                       Make_Range_Constraint (Loc,
445                         Range_Expression =>
446                           Make_Range (Loc,
447                             Low_Bound =>
448                               Make_Attribute_Reference (Loc,
449                                 Attribute_Name => Name_First,
450                                 Prefix => New_Occurrence_Of (Dtyp, Loc)),
451                             High_Bound =>
452                               Make_Integer_Literal (Loc,
453                                 Intval => UI_Max (Loval, Ahiv)))))));
454
455             Set_Etype (Discr, Tnn);
456          end if;
457
458       <<Continue>>
459          Next_Component (Comp);
460       end loop;
461    end Adjust_Discriminants;
462
463    ---------------------------
464    -- Build_Array_Init_Proc --
465    ---------------------------
466
467    procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id) is
468       Loc        : constant Source_Ptr := Sloc (Nod);
469       Comp_Type  : constant Entity_Id  := Component_Type (A_Type);
470       Index_List : List_Id;
471       Proc_Id    : Entity_Id;
472       Body_Stmts : List_Id;
473
474       function Init_Component return List_Id;
475       --  Create one statement to initialize one array component, designated
476       --  by a full set of indices.
477
478       function Init_One_Dimension (N : Int) return List_Id;
479       --  Create loop to initialize one dimension of the array. The single
480       --  statement in the loop body initializes the inner dimensions if any,
481       --  or else the single component. Note that this procedure is called
482       --  recursively, with N being the dimension to be initialized. A call
483       --  with N greater than the number of dimensions simply generates the
484       --  component initialization, terminating the recursion.
485
486       --------------------
487       -- Init_Component --
488       --------------------
489
490       function Init_Component return List_Id is
491          Comp : Node_Id;
492
493       begin
494          Comp :=
495            Make_Indexed_Component (Loc,
496              Prefix => Make_Identifier (Loc, Name_uInit),
497              Expressions => Index_List);
498
499          if Needs_Simple_Initialization (Comp_Type) then
500             Set_Assignment_OK (Comp);
501             return New_List (
502               Make_Assignment_Statement (Loc,
503                 Name => Comp,
504                 Expression =>
505                   Get_Simple_Init_Val
506                     (Comp_Type, Loc, Component_Size (A_Type))));
507
508          else
509             Clean_Task_Names (Comp_Type, Proc_Id);
510             return
511               Build_Initialization_Call (Loc, Comp, Comp_Type, True, A_Type);
512          end if;
513       end Init_Component;
514
515       ------------------------
516       -- Init_One_Dimension --
517       ------------------------
518
519       function Init_One_Dimension (N : Int) return List_Id is
520          Index      : Entity_Id;
521
522       begin
523          --  If the component does not need initializing, then there is nothing
524          --  to do here, so we return a null body. This occurs when generating
525          --  the dummy Init_Proc needed for Initialize_Scalars processing.
526
527          if not Has_Non_Null_Base_Init_Proc (Comp_Type)
528            and then not Needs_Simple_Initialization (Comp_Type)
529            and then not Has_Task (Comp_Type)
530          then
531             return New_List (Make_Null_Statement (Loc));
532
533          --  If all dimensions dealt with, we simply initialize the component
534
535          elsif N > Number_Dimensions (A_Type) then
536             return Init_Component;
537
538          --  Here we generate the required loop
539
540          else
541             Index :=
542               Make_Defining_Identifier (Loc, New_External_Name ('J', N));
543
544             Append (New_Reference_To (Index, Loc), Index_List);
545
546             return New_List (
547               Make_Implicit_Loop_Statement (Nod,
548                 Identifier => Empty,
549                 Iteration_Scheme =>
550                   Make_Iteration_Scheme (Loc,
551                     Loop_Parameter_Specification =>
552                       Make_Loop_Parameter_Specification (Loc,
553                         Defining_Identifier => Index,
554                         Discrete_Subtype_Definition =>
555                           Make_Attribute_Reference (Loc,
556                             Prefix => Make_Identifier (Loc, Name_uInit),
557                             Attribute_Name  => Name_Range,
558                             Expressions => New_List (
559                               Make_Integer_Literal (Loc, N))))),
560                 Statements =>  Init_One_Dimension (N + 1)));
561          end if;
562       end Init_One_Dimension;
563
564    --  Start of processing for Build_Array_Init_Proc
565
566    begin
567       if Suppress_Init_Proc (A_Type) then
568          return;
569       end if;
570
571       Index_List := New_List;
572
573       --  We need an initialization procedure if any of the following is true:
574
575       --    1. The component type has an initialization procedure
576       --    2. The component type needs simple initialization
577       --    3. Tasks are present
578       --    4. The type is marked as a publc entity
579
580       --  The reason for the public entity test is to deal properly with the
581       --  Initialize_Scalars pragma. This pragma can be set in the client and
582       --  not in the declaring package, this means the client will make a call
583       --  to the initialization procedure (because one of conditions 1-3 must
584       --  apply in this case), and we must generate a procedure (even if it is
585       --  null) to satisfy the call in this case.
586
587       --  Exception: do not build an array init_proc for a type whose root
588       --  type is Standard.String or Standard.Wide_[Wide_]String, since there
589       --  is no place to put the code, and in any case we handle initialization
590       --  of such types (in the Initialize_Scalars case, that's the only time
591       --  the issue arises) in a special manner anyway which does not need an
592       --  init_proc.
593
594       if Has_Non_Null_Base_Init_Proc (Comp_Type)
595         or else Needs_Simple_Initialization (Comp_Type)
596         or else Has_Task (Comp_Type)
597         or else (not Restriction_Active (No_Initialize_Scalars)
598                    and then Is_Public (A_Type)
599                    and then Root_Type (A_Type) /= Standard_String
600                    and then Root_Type (A_Type) /= Standard_Wide_String
601                    and then Root_Type (A_Type) /= Standard_Wide_Wide_String)
602       then
603          Proc_Id :=
604            Make_Defining_Identifier (Loc, Make_Init_Proc_Name (A_Type));
605
606          Body_Stmts := Init_One_Dimension (1);
607
608          Discard_Node (
609            Make_Subprogram_Body (Loc,
610              Specification =>
611                Make_Procedure_Specification (Loc,
612                  Defining_Unit_Name => Proc_Id,
613                  Parameter_Specifications => Init_Formals (A_Type)),
614              Declarations => New_List,
615              Handled_Statement_Sequence =>
616                Make_Handled_Sequence_Of_Statements (Loc,
617                  Statements => Body_Stmts)));
618
619          Set_Ekind          (Proc_Id, E_Procedure);
620          Set_Is_Public      (Proc_Id, Is_Public (A_Type));
621          Set_Is_Internal    (Proc_Id);
622          Set_Has_Completion (Proc_Id);
623
624          if not Debug_Generated_Code then
625             Set_Debug_Info_Off (Proc_Id);
626          end if;
627
628          --  Set inlined unless controlled stuff or tasks around, in which
629          --  case we do not want to inline, because nested stuff may cause
630          --  difficulties in interunit inlining, and furthermore there is
631          --  in any case no point in inlining such complex init procs.
632
633          if not Has_Task (Proc_Id)
634            and then not Controlled_Type (Proc_Id)
635          then
636             Set_Is_Inlined (Proc_Id);
637          end if;
638
639          --  Associate Init_Proc with type, and determine if the procedure
640          --  is null (happens because of the Initialize_Scalars pragma case,
641          --  where we have to generate a null procedure in case it is called
642          --  by a client with Initialize_Scalars set). Such procedures have
643          --  to be generated, but do not have to be called, so we mark them
644          --  as null to suppress the call.
645
646          Set_Init_Proc (A_Type, Proc_Id);
647
648          if List_Length (Body_Stmts) = 1
649            and then Nkind (First (Body_Stmts)) = N_Null_Statement
650          then
651             Set_Is_Null_Init_Proc (Proc_Id);
652          end if;
653       end if;
654    end Build_Array_Init_Proc;
655
656    -----------------------------
657    -- Build_Class_Wide_Master --
658    -----------------------------
659
660    procedure Build_Class_Wide_Master (T : Entity_Id) is
661       Loc  : constant Source_Ptr := Sloc (T);
662       M_Id : Entity_Id;
663       Decl : Node_Id;
664       P    : Node_Id;
665       Par  : Node_Id;
666
667    begin
668       --  Nothing to do if there is no task hierarchy
669
670       if Restriction_Active (No_Task_Hierarchy) then
671          return;
672       end if;
673
674       --  Find declaration that created the access type: either a
675       --  type declaration, or an object declaration with an
676       --  access definition, in which case the type is anonymous.
677
678       if Is_Itype (T) then
679          P := Associated_Node_For_Itype (T);
680       else
681          P := Parent (T);
682       end if;
683
684       --  Nothing to do if we already built a master entity for this scope
685
686       if not Has_Master_Entity (Scope (T)) then
687
688          --  first build the master entity
689          --    _Master : constant Master_Id := Current_Master.all;
690          --  and insert it just before the current declaration
691
692          Decl :=
693            Make_Object_Declaration (Loc,
694              Defining_Identifier =>
695                Make_Defining_Identifier (Loc, Name_uMaster),
696              Constant_Present => True,
697              Object_Definition => New_Reference_To (Standard_Integer, Loc),
698              Expression =>
699                Make_Explicit_Dereference (Loc,
700                  New_Reference_To (RTE (RE_Current_Master), Loc)));
701
702          Insert_Before (P, Decl);
703          Analyze (Decl);
704          Set_Has_Master_Entity (Scope (T));
705
706          --  Now mark the containing scope as a task master
707
708          Par := P;
709          while Nkind (Par) /= N_Compilation_Unit loop
710             Par := Parent (Par);
711
712             --  If we fall off the top, we are at the outer level, and the
713             --  environment task is our effective master, so nothing to mark.
714
715             if Nkind (Par) = N_Task_Body
716               or else Nkind (Par) = N_Block_Statement
717               or else Nkind (Par) = N_Subprogram_Body
718             then
719                Set_Is_Task_Master (Par, True);
720                exit;
721             end if;
722          end loop;
723       end if;
724
725       --  Now define the renaming of the master_id
726
727       M_Id :=
728         Make_Defining_Identifier (Loc,
729           New_External_Name (Chars (T), 'M'));
730
731       Decl :=
732         Make_Object_Renaming_Declaration (Loc,
733           Defining_Identifier => M_Id,
734           Subtype_Mark => New_Reference_To (Standard_Integer, Loc),
735           Name => Make_Identifier (Loc, Name_uMaster));
736       Insert_Before (P, Decl);
737       Analyze (Decl);
738
739       Set_Master_Id (T, M_Id);
740
741    exception
742       when RE_Not_Available =>
743          return;
744    end Build_Class_Wide_Master;
745
746    --------------------------------
747    -- Build_Discr_Checking_Funcs --
748    --------------------------------
749
750    procedure Build_Discr_Checking_Funcs (N : Node_Id) is
751       Rec_Id            : Entity_Id;
752       Loc               : Source_Ptr;
753       Enclosing_Func_Id : Entity_Id;
754       Sequence          : Nat     := 1;
755       Type_Def          : Node_Id;
756       V                 : Node_Id;
757
758       function Build_Case_Statement
759         (Case_Id : Entity_Id;
760          Variant : Node_Id) return Node_Id;
761       --  Build a case statement containing only two alternatives. The
762       --  first alternative corresponds exactly to the discrete choices
763       --  given on the variant with contains the components that we are
764       --  generating the checks for. If the discriminant is one of these
765       --  return False. The second alternative is an OTHERS choice that
766       --  will return True indicating the discriminant did not match.
767
768       function Build_Dcheck_Function
769         (Case_Id : Entity_Id;
770          Variant : Node_Id) return Entity_Id;
771       --  Build the discriminant checking function for a given variant
772
773       procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id);
774       --  Builds the discriminant checking function for each variant of the
775       --  given variant part of the record type.
776
777       --------------------------
778       -- Build_Case_Statement --
779       --------------------------
780
781       function Build_Case_Statement
782         (Case_Id : Entity_Id;
783          Variant : Node_Id) return Node_Id
784       is
785          Alt_List       : constant List_Id := New_List;
786          Actuals_List   : List_Id;
787          Case_Node      : Node_Id;
788          Case_Alt_Node  : Node_Id;
789          Choice         : Node_Id;
790          Choice_List    : List_Id;
791          D              : Entity_Id;
792          Return_Node    : Node_Id;
793
794       begin
795          Case_Node := New_Node (N_Case_Statement, Loc);
796
797          --  Replace the discriminant which controls the variant, with the
798          --  name of the formal of the checking function.
799
800          Set_Expression (Case_Node,
801            Make_Identifier (Loc, Chars (Case_Id)));
802
803          Choice := First (Discrete_Choices (Variant));
804
805          if Nkind (Choice) = N_Others_Choice then
806             Choice_List := New_Copy_List (Others_Discrete_Choices (Choice));
807          else
808             Choice_List := New_Copy_List (Discrete_Choices (Variant));
809          end if;
810
811          if not Is_Empty_List (Choice_List) then
812             Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
813             Set_Discrete_Choices (Case_Alt_Node, Choice_List);
814
815             --  In case this is a nested variant, we need to return the result
816             --  of the discriminant checking function for the immediately
817             --  enclosing variant.
818
819             if Present (Enclosing_Func_Id) then
820                Actuals_List := New_List;
821
822                D := First_Discriminant (Rec_Id);
823                while Present (D) loop
824                   Append (Make_Identifier (Loc, Chars (D)), Actuals_List);
825                   Next_Discriminant (D);
826                end loop;
827
828                Return_Node :=
829                  Make_Return_Statement (Loc,
830                    Expression =>
831                      Make_Function_Call (Loc,
832                        Name =>
833                          New_Reference_To (Enclosing_Func_Id,  Loc),
834                        Parameter_Associations =>
835                          Actuals_List));
836
837             else
838                Return_Node :=
839                  Make_Return_Statement (Loc,
840                    Expression =>
841                      New_Reference_To (Standard_False, Loc));
842             end if;
843
844             Set_Statements (Case_Alt_Node, New_List (Return_Node));
845             Append (Case_Alt_Node, Alt_List);
846          end if;
847
848          Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
849          Choice_List := New_List (New_Node (N_Others_Choice, Loc));
850          Set_Discrete_Choices (Case_Alt_Node, Choice_List);
851
852          Return_Node :=
853            Make_Return_Statement (Loc,
854              Expression =>
855                New_Reference_To (Standard_True, Loc));
856
857          Set_Statements (Case_Alt_Node, New_List (Return_Node));
858          Append (Case_Alt_Node, Alt_List);
859
860          Set_Alternatives (Case_Node, Alt_List);
861          return Case_Node;
862       end Build_Case_Statement;
863
864       ---------------------------
865       -- Build_Dcheck_Function --
866       ---------------------------
867
868       function Build_Dcheck_Function
869         (Case_Id : Entity_Id;
870          Variant : Node_Id) return Entity_Id
871       is
872          Body_Node           : Node_Id;
873          Func_Id             : Entity_Id;
874          Parameter_List      : List_Id;
875          Spec_Node           : Node_Id;
876
877       begin
878          Body_Node := New_Node (N_Subprogram_Body, Loc);
879          Sequence := Sequence + 1;
880
881          Func_Id :=
882            Make_Defining_Identifier (Loc,
883              Chars => New_External_Name (Chars (Rec_Id), 'D', Sequence));
884
885          Spec_Node := New_Node (N_Function_Specification, Loc);
886          Set_Defining_Unit_Name (Spec_Node, Func_Id);
887
888          Parameter_List := Build_Discriminant_Formals (Rec_Id, False);
889
890          Set_Parameter_Specifications (Spec_Node, Parameter_List);
891          Set_Result_Definition (Spec_Node,
892                                 New_Reference_To (Standard_Boolean,  Loc));
893          Set_Specification (Body_Node, Spec_Node);
894          Set_Declarations (Body_Node, New_List);
895
896          Set_Handled_Statement_Sequence (Body_Node,
897            Make_Handled_Sequence_Of_Statements (Loc,
898              Statements => New_List (
899                Build_Case_Statement (Case_Id, Variant))));
900
901          Set_Ekind       (Func_Id, E_Function);
902          Set_Mechanism   (Func_Id, Default_Mechanism);
903          Set_Is_Inlined  (Func_Id, True);
904          Set_Is_Pure     (Func_Id, True);
905          Set_Is_Public   (Func_Id, Is_Public (Rec_Id));
906          Set_Is_Internal (Func_Id, True);
907
908          if not Debug_Generated_Code then
909             Set_Debug_Info_Off (Func_Id);
910          end if;
911
912          Analyze (Body_Node);
913
914          Append_Freeze_Action (Rec_Id, Body_Node);
915          Set_Dcheck_Function (Variant, Func_Id);
916          return Func_Id;
917       end Build_Dcheck_Function;
918
919       ----------------------------
920       -- Build_Dcheck_Functions --
921       ----------------------------
922
923       procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id) is
924          Component_List_Node : Node_Id;
925          Decl                : Entity_Id;
926          Discr_Name          : Entity_Id;
927          Func_Id             : Entity_Id;
928          Variant             : Node_Id;
929          Saved_Enclosing_Func_Id : Entity_Id;
930
931       begin
932          --  Build the discriminant checking function for each variant, label
933          --  all components of that variant with the function's name.
934
935          Discr_Name := Entity (Name (Variant_Part_Node));
936          Variant := First_Non_Pragma (Variants (Variant_Part_Node));
937
938          while Present (Variant) loop
939             Func_Id := Build_Dcheck_Function (Discr_Name, Variant);
940             Component_List_Node := Component_List (Variant);
941
942             if not Null_Present (Component_List_Node) then
943                Decl :=
944                  First_Non_Pragma (Component_Items (Component_List_Node));
945
946                while Present (Decl) loop
947                   Set_Discriminant_Checking_Func
948                     (Defining_Identifier (Decl), Func_Id);
949
950                   Next_Non_Pragma (Decl);
951                end loop;
952
953                if Present (Variant_Part (Component_List_Node)) then
954                   Saved_Enclosing_Func_Id := Enclosing_Func_Id;
955                   Enclosing_Func_Id := Func_Id;
956                   Build_Dcheck_Functions (Variant_Part (Component_List_Node));
957                   Enclosing_Func_Id := Saved_Enclosing_Func_Id;
958                end if;
959             end if;
960
961             Next_Non_Pragma (Variant);
962          end loop;
963       end Build_Dcheck_Functions;
964
965    --  Start of processing for Build_Discr_Checking_Funcs
966
967    begin
968       --  Only build if not done already
969
970       if not Discr_Check_Funcs_Built (N) then
971          Type_Def := Type_Definition (N);
972
973          if Nkind (Type_Def) = N_Record_Definition then
974             if No (Component_List (Type_Def)) then   -- null record.
975                return;
976             else
977                V := Variant_Part (Component_List (Type_Def));
978             end if;
979
980          else pragma Assert (Nkind (Type_Def) = N_Derived_Type_Definition);
981             if No (Component_List (Record_Extension_Part (Type_Def))) then
982                return;
983             else
984                V := Variant_Part
985                       (Component_List (Record_Extension_Part (Type_Def)));
986             end if;
987          end if;
988
989          Rec_Id := Defining_Identifier (N);
990
991          if Present (V) and then not Is_Unchecked_Union (Rec_Id) then
992             Loc := Sloc (N);
993             Enclosing_Func_Id := Empty;
994             Build_Dcheck_Functions (V);
995          end if;
996
997          Set_Discr_Check_Funcs_Built (N);
998       end if;
999    end Build_Discr_Checking_Funcs;
1000
1001    --------------------------------
1002    -- Build_Discriminant_Formals --
1003    --------------------------------
1004
1005    function Build_Discriminant_Formals
1006      (Rec_Id : Entity_Id;
1007       Use_Dl : Boolean) return List_Id
1008    is
1009       Loc             : Source_Ptr       := Sloc (Rec_Id);
1010       Parameter_List  : constant List_Id := New_List;
1011       D               : Entity_Id;
1012       Formal          : Entity_Id;
1013       Param_Spec_Node : Node_Id;
1014
1015    begin
1016       if Has_Discriminants (Rec_Id) then
1017          D := First_Discriminant (Rec_Id);
1018          while Present (D) loop
1019             Loc := Sloc (D);
1020
1021             if Use_Dl then
1022                Formal := Discriminal (D);
1023             else
1024                Formal := Make_Defining_Identifier (Loc, Chars (D));
1025             end if;
1026
1027             Param_Spec_Node :=
1028               Make_Parameter_Specification (Loc,
1029                   Defining_Identifier => Formal,
1030                 Parameter_Type =>
1031                   New_Reference_To (Etype (D), Loc));
1032             Append (Param_Spec_Node, Parameter_List);
1033             Next_Discriminant (D);
1034          end loop;
1035       end if;
1036
1037       return Parameter_List;
1038    end Build_Discriminant_Formals;
1039
1040    -------------------------------
1041    -- Build_Initialization_Call --
1042    -------------------------------
1043
1044    --  References to a discriminant inside the record type declaration
1045    --  can appear either in the subtype_indication to constrain a
1046    --  record or an array, or as part of a larger expression given for
1047    --  the initial value of a component. In both of these cases N appears
1048    --  in the record initialization procedure and needs to be replaced by
1049    --  the formal parameter of the initialization procedure which
1050    --  corresponds to that discriminant.
1051
1052    --  In the example below, references to discriminants D1 and D2 in proc_1
1053    --  are replaced by references to formals with the same name
1054    --  (discriminals)
1055
1056    --  A similar replacement is done for calls to any record
1057    --  initialization procedure for any components that are themselves
1058    --  of a record type.
1059
1060    --  type R (D1, D2 : Integer) is record
1061    --     X : Integer := F * D1;
1062    --     Y : Integer := F * D2;
1063    --  end record;
1064
1065    --  procedure proc_1 (Out_2 : out R; D1 : Integer; D2 : Integer) is
1066    --  begin
1067    --     Out_2.D1 := D1;
1068    --     Out_2.D2 := D2;
1069    --     Out_2.X := F * D1;
1070    --     Out_2.Y := F * D2;
1071    --  end;
1072
1073    function Build_Initialization_Call
1074      (Loc               : Source_Ptr;
1075       Id_Ref            : Node_Id;
1076       Typ               : Entity_Id;
1077       In_Init_Proc      : Boolean := False;
1078       Enclos_Type       : Entity_Id := Empty;
1079       Discr_Map         : Elist_Id := New_Elmt_List;
1080       With_Default_Init : Boolean := False) return List_Id
1081    is
1082       First_Arg      : Node_Id;
1083       Args           : List_Id;
1084       Decls          : List_Id;
1085       Decl           : Node_Id;
1086       Discr          : Entity_Id;
1087       Arg            : Node_Id;
1088       Proc           : constant Entity_Id := Base_Init_Proc (Typ);
1089       Init_Type      : constant Entity_Id := Etype (First_Formal (Proc));
1090       Full_Init_Type : constant Entity_Id := Underlying_Type (Init_Type);
1091       Res            : constant List_Id   := New_List;
1092       Full_Type      : Entity_Id := Typ;
1093       Controller_Typ : Entity_Id;
1094
1095    begin
1096       --  Nothing to do if the Init_Proc is null, unless Initialize_Scalars
1097       --  is active (in which case we make the call anyway, since in the
1098       --  actual compiled client it may be non null).
1099
1100       if Is_Null_Init_Proc (Proc) and then not Init_Or_Norm_Scalars then
1101          return Empty_List;
1102       end if;
1103
1104       --  Go to full view if private type. In the case of successive
1105       --  private derivations, this can require more than one step.
1106
1107       while Is_Private_Type (Full_Type)
1108         and then Present (Full_View (Full_Type))
1109       loop
1110          Full_Type := Full_View (Full_Type);
1111       end loop;
1112
1113       --  If Typ is derived, the procedure is the initialization procedure for
1114       --  the root type. Wrap the argument in an conversion to make it type
1115       --  honest. Actually it isn't quite type honest, because there can be
1116       --  conflicts of views in the private type case. That is why we set
1117       --  Conversion_OK in the conversion node.
1118
1119       if (Is_Record_Type (Typ)
1120            or else Is_Array_Type (Typ)
1121            or else Is_Private_Type (Typ))
1122         and then Init_Type /= Base_Type (Typ)
1123       then
1124          First_Arg := OK_Convert_To (Etype (Init_Type), Id_Ref);
1125          Set_Etype (First_Arg, Init_Type);
1126
1127       else
1128          First_Arg := Id_Ref;
1129       end if;
1130
1131       Args := New_List (Convert_Concurrent (First_Arg, Typ));
1132
1133       --  In the tasks case, add _Master as the value of the _Master parameter
1134       --  and _Chain as the value of the _Chain parameter. At the outer level,
1135       --  these will be variables holding the corresponding values obtained
1136       --  from GNARL. At inner levels, they will be the parameters passed down
1137       --  through the outer routines.
1138
1139       if Has_Task (Full_Type) then
1140          if Restriction_Active (No_Task_Hierarchy) then
1141
1142             --  See comments in System.Tasking.Initialization.Init_RTS
1143             --  for the value 3 (should be rtsfindable constant ???)
1144
1145             Append_To (Args, Make_Integer_Literal (Loc, 3));
1146          else
1147             Append_To (Args, Make_Identifier (Loc, Name_uMaster));
1148          end if;
1149
1150          Append_To (Args, Make_Identifier (Loc, Name_uChain));
1151
1152          --  Ada 2005 (AI-287): In case of default initialized components
1153          --  with tasks, we generate a null string actual parameter.
1154          --  This is just a workaround that must be improved later???
1155
1156          if With_Default_Init then
1157             Append_To (Args,
1158               Make_String_Literal (Loc,
1159                 Strval => ""));
1160
1161          else
1162             Decls :=
1163               Build_Task_Image_Decls (Loc, Id_Ref, Enclos_Type, In_Init_Proc);
1164             Decl  := Last (Decls);
1165
1166             Append_To (Args,
1167               New_Occurrence_Of (Defining_Identifier (Decl), Loc));
1168             Append_List (Decls, Res);
1169          end if;
1170
1171       else
1172          Decls := No_List;
1173          Decl  := Empty;
1174       end if;
1175
1176       --  Add discriminant values if discriminants are present
1177
1178       if Has_Discriminants (Full_Init_Type) then
1179          Discr := First_Discriminant (Full_Init_Type);
1180
1181          while Present (Discr) loop
1182
1183             --  If this is a discriminated concurrent type, the init_proc
1184             --  for the corresponding record is being called. Use that
1185             --  type directly to find the discriminant value, to handle
1186             --  properly intervening renamed discriminants.
1187
1188             declare
1189                T : Entity_Id := Full_Type;
1190
1191             begin
1192                if Is_Protected_Type (T) then
1193                   T := Corresponding_Record_Type (T);
1194
1195                elsif Is_Private_Type (T)
1196                  and then Present (Underlying_Full_View (T))
1197                  and then Is_Protected_Type (Underlying_Full_View (T))
1198                then
1199                   T := Corresponding_Record_Type (Underlying_Full_View (T));
1200                end if;
1201
1202                Arg :=
1203                  Get_Discriminant_Value (
1204                    Discr,
1205                    T,
1206                    Discriminant_Constraint (Full_Type));
1207             end;
1208
1209             if In_Init_Proc then
1210
1211                --  Replace any possible references to the discriminant in the
1212                --  call to the record initialization procedure with references
1213                --  to the appropriate formal parameter.
1214
1215                if Nkind (Arg) = N_Identifier
1216                   and then Ekind (Entity (Arg)) = E_Discriminant
1217                then
1218                   Arg := New_Reference_To (Discriminal (Entity (Arg)), Loc);
1219
1220                --  Case of access discriminants. We replace the reference
1221                --  to the type by a reference to the actual object
1222
1223                elsif Nkind (Arg) = N_Attribute_Reference
1224                  and then Is_Access_Type (Etype (Arg))
1225                  and then Is_Entity_Name (Prefix (Arg))
1226                  and then Is_Type (Entity (Prefix (Arg)))
1227                then
1228                   Arg :=
1229                     Make_Attribute_Reference (Loc,
1230                       Prefix         => New_Copy (Prefix (Id_Ref)),
1231                       Attribute_Name => Name_Unrestricted_Access);
1232
1233                --  Otherwise make a copy of the default expression. Note
1234                --  that we use the current Sloc for this, because we do not
1235                --  want the call to appear to be at the declaration point.
1236                --  Within the expression, replace discriminants with their
1237                --  discriminals.
1238
1239                else
1240                   Arg :=
1241                     New_Copy_Tree (Arg, Map => Discr_Map, New_Sloc => Loc);
1242                end if;
1243
1244             else
1245                if Is_Constrained (Full_Type) then
1246                   Arg := Duplicate_Subexpr_No_Checks (Arg);
1247                else
1248                   --  The constraints come from the discriminant default
1249                   --  exps, they must be reevaluated, so we use New_Copy_Tree
1250                   --  but we ensure the proper Sloc (for any embedded calls).
1251
1252                   Arg := New_Copy_Tree (Arg, New_Sloc => Loc);
1253                end if;
1254             end if;
1255
1256             --  Ada 2005 (AI-287) In case of default initialized components,
1257             --  we need to generate the corresponding selected component node
1258             --  to access the discriminant value. In other cases this is not
1259             --  required because we are inside the init proc and we use the
1260             --  corresponding formal.
1261
1262             if With_Default_Init
1263               and then Nkind (Id_Ref) = N_Selected_Component
1264               and then Nkind (Arg) = N_Identifier
1265             then
1266                Append_To (Args,
1267                  Make_Selected_Component (Loc,
1268                    Prefix => New_Copy_Tree (Prefix (Id_Ref)),
1269                    Selector_Name => Arg));
1270             else
1271                Append_To (Args, Arg);
1272             end if;
1273
1274             Next_Discriminant (Discr);
1275          end loop;
1276       end if;
1277
1278       --  If this is a call to initialize the parent component of a derived
1279       --  tagged type, indicate that the tag should not be set in the parent.
1280
1281       if Is_Tagged_Type (Full_Init_Type)
1282         and then not Is_CPP_Class (Full_Init_Type)
1283         and then Nkind (Id_Ref) = N_Selected_Component
1284         and then Chars (Selector_Name (Id_Ref)) = Name_uParent
1285       then
1286          Append_To (Args, New_Occurrence_Of (Standard_False, Loc));
1287       end if;
1288
1289       Append_To (Res,
1290         Make_Procedure_Call_Statement (Loc,
1291           Name => New_Occurrence_Of (Proc, Loc),
1292           Parameter_Associations => Args));
1293
1294       if Controlled_Type (Typ)
1295         and then Nkind (Id_Ref) = N_Selected_Component
1296       then
1297          if Chars (Selector_Name (Id_Ref)) /= Name_uParent then
1298             Append_List_To (Res,
1299               Make_Init_Call (
1300                 Ref         => New_Copy_Tree (First_Arg),
1301                 Typ         => Typ,
1302                 Flist_Ref   =>
1303                   Find_Final_List (Typ, New_Copy_Tree (First_Arg)),
1304                 With_Attach => Make_Integer_Literal (Loc, 1)));
1305
1306          --  If the enclosing type is an extension with new controlled
1307          --  components, it has his own record controller. If the parent
1308          --  also had a record controller, attach it to the new one.
1309          --  Build_Init_Statements relies on the fact that in this specific
1310          --  case the last statement of the result is the attach call to
1311          --  the controller. If this is changed, it must be synchronized.
1312
1313          elsif Present (Enclos_Type)
1314            and then Has_New_Controlled_Component (Enclos_Type)
1315            and then Has_Controlled_Component (Typ)
1316          then
1317             if Is_Inherently_Limited_Type (Typ) then
1318                Controller_Typ := RTE (RE_Limited_Record_Controller);
1319             else
1320                Controller_Typ := RTE (RE_Record_Controller);
1321             end if;
1322
1323             Append_List_To (Res,
1324               Make_Init_Call (
1325                 Ref       =>
1326                   Make_Selected_Component (Loc,
1327                     Prefix        => New_Copy_Tree (First_Arg),
1328                     Selector_Name => Make_Identifier (Loc, Name_uController)),
1329                 Typ       => Controller_Typ,
1330                 Flist_Ref => Find_Final_List (Typ, New_Copy_Tree (First_Arg)),
1331                 With_Attach => Make_Integer_Literal (Loc, 1)));
1332          end if;
1333       end if;
1334
1335       return Res;
1336
1337    exception
1338       when RE_Not_Available =>
1339          return Empty_List;
1340    end Build_Initialization_Call;
1341
1342    ---------------------------
1343    -- Build_Master_Renaming --
1344    ---------------------------
1345
1346    procedure Build_Master_Renaming (N : Node_Id; T : Entity_Id) is
1347       Loc  : constant Source_Ptr := Sloc (N);
1348       M_Id : Entity_Id;
1349       Decl : Node_Id;
1350
1351    begin
1352       --  Nothing to do if there is no task hierarchy
1353
1354       if Restriction_Active (No_Task_Hierarchy) then
1355          return;
1356       end if;
1357
1358       M_Id :=
1359         Make_Defining_Identifier (Loc,
1360           New_External_Name (Chars (T), 'M'));
1361
1362       Decl :=
1363         Make_Object_Renaming_Declaration (Loc,
1364           Defining_Identifier => M_Id,
1365           Subtype_Mark => New_Reference_To (RTE (RE_Master_Id), Loc),
1366           Name => Make_Identifier (Loc, Name_uMaster));
1367       Insert_Before (N, Decl);
1368       Analyze (Decl);
1369
1370       Set_Master_Id (T, M_Id);
1371
1372    exception
1373       when RE_Not_Available =>
1374          return;
1375    end Build_Master_Renaming;
1376
1377    ----------------------------
1378    -- Build_Record_Init_Proc --
1379    ----------------------------
1380
1381    procedure Build_Record_Init_Proc (N : Node_Id; Pe : Entity_Id) is
1382       Loc         : Source_Ptr := Sloc (N);
1383       Discr_Map   : constant Elist_Id := New_Elmt_List;
1384       Proc_Id     : Entity_Id;
1385       Rec_Type    : Entity_Id;
1386       Set_Tag     : Entity_Id := Empty;
1387
1388       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id;
1389       --  Build a assignment statement node which assigns to record
1390       --  component its default expression if defined. The left hand side
1391       --  of the assignment is marked Assignment_OK so that initialization
1392       --  of limited private records works correctly, Return also the
1393       --  adjustment call for controlled objects
1394
1395       procedure Build_Discriminant_Assignments (Statement_List : List_Id);
1396       --  If the record has discriminants, adds assignment statements to
1397       --  statement list to initialize the discriminant values from the
1398       --  arguments of the initialization procedure.
1399
1400       function Build_Init_Statements (Comp_List : Node_Id) return List_Id;
1401       --  Build a list representing a sequence of statements which initialize
1402       --  components of the given component list. This may involve building
1403       --  case statements for the variant parts.
1404
1405       function Build_Init_Call_Thru (Parameters : List_Id) return List_Id;
1406       --  Given a non-tagged type-derivation that declares discriminants,
1407       --  such as
1408       --
1409       --  type R (R1, R2 : Integer) is record ... end record;
1410       --
1411       --  type D (D1 : Integer) is new R (1, D1);
1412       --
1413       --  we make the _init_proc of D be
1414       --
1415       --       procedure _init_proc(X : D; D1 : Integer) is
1416       --       begin
1417       --          _init_proc( R(X), 1, D1);
1418       --       end _init_proc;
1419       --
1420       --  This function builds the call statement in this _init_proc.
1421
1422       procedure Build_Init_Procedure;
1423       --  Build the tree corresponding to the procedure specification and body
1424       --  of the initialization procedure (by calling all the preceding
1425       --  auxiliary routines), and install it as the _init TSS.
1426
1427       procedure Build_Offset_To_Top_Functions;
1428       --  Ada 2005 (AI-251): Build the tree corresponding to the procedure spec
1429       --  and body of the Offset_To_Top function that is generated when the
1430       --  parent of a type with discriminants has secondary dispatch tables.
1431
1432       procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id);
1433       --  Add range checks to components of disciminated records. S is a
1434       --  subtype indication of a record component. Check_List is a list
1435       --  to which the check actions are appended.
1436
1437       function Component_Needs_Simple_Initialization
1438         (T : Entity_Id) return Boolean;
1439       --  Determines if a component needs simple initialization, given its type
1440       --  T. This is the same as Needs_Simple_Initialization except for the
1441       --  following difference: the types Tag, Interface_Tag, and Vtable_Ptr
1442       --  which are access types which would normally require simple
1443       --  initialization to null, do not require initialization as components,
1444       --  since they are explicitly initialized by other means.
1445
1446       procedure Constrain_Array
1447         (SI         : Node_Id;
1448          Check_List : List_Id);
1449       --  Called from Build_Record_Checks.
1450       --  Apply a list of index constraints to an unconstrained array type.
1451       --  The first parameter is the entity for the resulting subtype.
1452       --  Check_List is a list to which the check actions are appended.
1453
1454       procedure Constrain_Index
1455         (Index      : Node_Id;
1456          S          : Node_Id;
1457          Check_List : List_Id);
1458       --  Called from Build_Record_Checks.
1459       --  Process an index constraint in a constrained array declaration.
1460       --  The constraint can be a subtype name, or a range with or without
1461       --  an explicit subtype mark. The index is the corresponding index of the
1462       --  unconstrained array. S is the range expression. Check_List is a list
1463       --  to which the check actions are appended.
1464
1465       function Parent_Subtype_Renaming_Discrims return Boolean;
1466       --  Returns True for base types N that rename discriminants, else False
1467
1468       function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean;
1469       --  Determines whether a record initialization procedure needs to be
1470       --  generated for the given record type.
1471
1472       ----------------------
1473       -- Build_Assignment --
1474       ----------------------
1475
1476       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id is
1477          Exp  : Node_Id := N;
1478          Lhs  : Node_Id;
1479          Typ  : constant Entity_Id := Underlying_Type (Etype (Id));
1480          Kind : Node_Kind := Nkind (N);
1481          Res  : List_Id;
1482
1483       begin
1484          Loc := Sloc (N);
1485          Lhs :=
1486            Make_Selected_Component (Loc,
1487              Prefix => Make_Identifier (Loc, Name_uInit),
1488              Selector_Name => New_Occurrence_Of (Id, Loc));
1489          Set_Assignment_OK (Lhs);
1490
1491          --  Case of an access attribute applied to the current instance.
1492          --  Replace the reference to the type by a reference to the actual
1493          --  object. (Note that this handles the case of the top level of
1494          --  the expression being given by such an attribute, but does not
1495          --  cover uses nested within an initial value expression. Nested
1496          --  uses are unlikely to occur in practice, but are theoretically
1497          --  possible. It is not clear how to handle them without fully
1498          --  traversing the expression. ???
1499
1500          if Kind = N_Attribute_Reference
1501            and then (Attribute_Name (N) = Name_Unchecked_Access
1502                        or else
1503                      Attribute_Name (N) = Name_Unrestricted_Access)
1504            and then Is_Entity_Name (Prefix (N))
1505            and then Is_Type (Entity (Prefix (N)))
1506            and then Entity (Prefix (N)) = Rec_Type
1507          then
1508             Exp :=
1509               Make_Attribute_Reference (Loc,
1510                 Prefix         => Make_Identifier (Loc, Name_uInit),
1511                 Attribute_Name => Name_Unrestricted_Access);
1512          end if;
1513
1514          --  Ada 2005 (AI-231): Add the run-time check if required
1515
1516          if Ada_Version >= Ada_05
1517            and then Can_Never_Be_Null (Etype (Id))            -- Lhs
1518          then
1519             if Nkind (Exp) = N_Null then
1520                return New_List (
1521                  Make_Raise_Constraint_Error (Sloc (Exp),
1522                    Reason => CE_Null_Not_Allowed));
1523
1524             elsif Present (Etype (Exp))
1525               and then not Can_Never_Be_Null (Etype (Exp))
1526             then
1527                Install_Null_Excluding_Check (Exp);
1528             end if;
1529          end if;
1530
1531          --  Take a copy of Exp to ensure that later copies of this
1532          --  component_declaration in derived types see the original tree,
1533          --  not a node rewritten during expansion of the init_proc.
1534
1535          Exp := New_Copy_Tree (Exp);
1536
1537          Res := New_List (
1538            Make_Assignment_Statement (Loc,
1539              Name       => Lhs,
1540              Expression => Exp));
1541
1542          Set_No_Ctrl_Actions (First (Res));
1543
1544          --  Adjust the tag if tagged (because of possible view conversions).
1545          --  Suppress the tag adjustment when Java_VM because JVM tags are
1546          --  represented implicitly in objects.
1547
1548          if Is_Tagged_Type (Typ) and then not Java_VM then
1549             Append_To (Res,
1550               Make_Assignment_Statement (Loc,
1551                 Name =>
1552                   Make_Selected_Component (Loc,
1553                     Prefix =>  New_Copy_Tree (Lhs),
1554                     Selector_Name =>
1555                       New_Reference_To (First_Tag_Component (Typ), Loc)),
1556
1557                 Expression =>
1558                   Unchecked_Convert_To (RTE (RE_Tag),
1559                     New_Reference_To
1560                       (Node (First_Elmt (Access_Disp_Table (Typ))), Loc))));
1561          end if;
1562
1563          --  Adjust the component if controlled except if it is an
1564          --  aggregate that will be expanded inline
1565
1566          if Kind = N_Qualified_Expression then
1567             Kind := Nkind (Expression (N));
1568          end if;
1569
1570          if Controlled_Type (Typ)
1571          and then not (Kind = N_Aggregate or else Kind = N_Extension_Aggregate)
1572          then
1573             Append_List_To (Res,
1574               Make_Adjust_Call (
1575                Ref          => New_Copy_Tree (Lhs),
1576                Typ          => Etype (Id),
1577                Flist_Ref    =>
1578                  Find_Final_List (Etype (Id), New_Copy_Tree (Lhs)),
1579                With_Attach  => Make_Integer_Literal (Loc, 1)));
1580          end if;
1581
1582          return Res;
1583
1584       exception
1585          when RE_Not_Available =>
1586             return Empty_List;
1587       end Build_Assignment;
1588
1589       ------------------------------------
1590       -- Build_Discriminant_Assignments --
1591       ------------------------------------
1592
1593       procedure Build_Discriminant_Assignments (Statement_List : List_Id) is
1594          D         : Entity_Id;
1595          Is_Tagged : constant Boolean := Is_Tagged_Type (Rec_Type);
1596
1597       begin
1598          if Has_Discriminants (Rec_Type)
1599            and then not Is_Unchecked_Union (Rec_Type)
1600          then
1601             D := First_Discriminant (Rec_Type);
1602
1603             while Present (D) loop
1604                --  Don't generate the assignment for discriminants in derived
1605                --  tagged types if the discriminant is a renaming of some
1606                --  ancestor discriminant. This initialization will be done
1607                --  when initializing the _parent field of the derived record.
1608
1609                if Is_Tagged and then
1610                  Present (Corresponding_Discriminant (D))
1611                then
1612                   null;
1613
1614                else
1615                   Loc := Sloc (D);
1616                   Append_List_To (Statement_List,
1617                     Build_Assignment (D,
1618                       New_Reference_To (Discriminal (D), Loc)));
1619                end if;
1620
1621                Next_Discriminant (D);
1622             end loop;
1623          end if;
1624       end Build_Discriminant_Assignments;
1625
1626       --------------------------
1627       -- Build_Init_Call_Thru --
1628       --------------------------
1629
1630       function Build_Init_Call_Thru (Parameters : List_Id) return List_Id is
1631          Parent_Proc : constant Entity_Id :=
1632                          Base_Init_Proc (Etype (Rec_Type));
1633
1634          Parent_Type : constant Entity_Id :=
1635                          Etype (First_Formal (Parent_Proc));
1636
1637          Uparent_Type : constant Entity_Id :=
1638                           Underlying_Type (Parent_Type);
1639
1640          First_Discr_Param : Node_Id;
1641
1642          Parent_Discr : Entity_Id;
1643          First_Arg    : Node_Id;
1644          Args         : List_Id;
1645          Arg          : Node_Id;
1646          Res          : List_Id;
1647
1648       begin
1649          --  First argument (_Init) is the object to be initialized.
1650          --  ??? not sure where to get a reasonable Loc for First_Arg
1651
1652          First_Arg :=
1653            OK_Convert_To (Parent_Type,
1654              New_Reference_To (Defining_Identifier (First (Parameters)), Loc));
1655
1656          Set_Etype (First_Arg, Parent_Type);
1657
1658          Args := New_List (Convert_Concurrent (First_Arg, Rec_Type));
1659
1660          --  In the tasks case,
1661          --    add _Master as the value of the _Master parameter
1662          --    add _Chain as the value of the _Chain parameter.
1663          --    add _Task_Name as the value of the _Task_Name parameter.
1664          --  At the outer level, these will be variables holding the
1665          --  corresponding values obtained from GNARL or the expander.
1666          --
1667          --  At inner levels, they will be the parameters passed down through
1668          --  the outer routines.
1669
1670          First_Discr_Param := Next (First (Parameters));
1671
1672          if Has_Task (Rec_Type) then
1673             if Restriction_Active (No_Task_Hierarchy) then
1674
1675                --  See comments in System.Tasking.Initialization.Init_RTS
1676                --  for the value 3.
1677
1678                Append_To (Args, Make_Integer_Literal (Loc, 3));
1679             else
1680                Append_To (Args, Make_Identifier (Loc, Name_uMaster));
1681             end if;
1682
1683             Append_To (Args, Make_Identifier (Loc, Name_uChain));
1684             Append_To (Args, Make_Identifier (Loc, Name_uTask_Name));
1685             First_Discr_Param := Next (Next (Next (First_Discr_Param)));
1686          end if;
1687
1688          --  Append discriminant values
1689
1690          if Has_Discriminants (Uparent_Type) then
1691             pragma Assert (not Is_Tagged_Type (Uparent_Type));
1692
1693             Parent_Discr := First_Discriminant (Uparent_Type);
1694             while Present (Parent_Discr) loop
1695
1696                --  Get the initial value for this discriminant
1697                --  ??? needs to be cleaned up to use parent_Discr_Constr
1698                --  directly.
1699
1700                declare
1701                   Discr_Value : Elmt_Id :=
1702                                   First_Elmt
1703                                     (Stored_Constraint (Rec_Type));
1704
1705                   Discr       : Entity_Id :=
1706                                   First_Stored_Discriminant (Uparent_Type);
1707                begin
1708                   while Original_Record_Component (Parent_Discr) /= Discr loop
1709                      Next_Stored_Discriminant (Discr);
1710                      Next_Elmt (Discr_Value);
1711                   end loop;
1712
1713                   Arg := Node (Discr_Value);
1714                end;
1715
1716                --  Append it to the list
1717
1718                if Nkind (Arg) = N_Identifier
1719                   and then Ekind (Entity (Arg)) = E_Discriminant
1720                then
1721                   Append_To (Args,
1722                     New_Reference_To (Discriminal (Entity (Arg)), Loc));
1723
1724                --  Case of access discriminants. We replace the reference
1725                --  to the type by a reference to the actual object.
1726
1727                --  Is above comment right??? Use of New_Copy below seems mighty
1728                --  suspicious ???
1729
1730                else
1731                   Append_To (Args, New_Copy (Arg));
1732                end if;
1733
1734                Next_Discriminant (Parent_Discr);
1735             end loop;
1736          end if;
1737
1738          Res :=
1739             New_List (
1740               Make_Procedure_Call_Statement (Loc,
1741                 Name => New_Occurrence_Of (Parent_Proc, Loc),
1742                 Parameter_Associations => Args));
1743
1744          return Res;
1745       end Build_Init_Call_Thru;
1746
1747       -----------------------------------
1748       -- Build_Offset_To_Top_Functions --
1749       -----------------------------------
1750
1751       procedure Build_Offset_To_Top_Functions is
1752          ADT       : Elmt_Id;
1753          Body_Node : Node_Id;
1754          Func_Id   : Entity_Id;
1755          Spec_Node : Node_Id;
1756          E         : Entity_Id;
1757
1758          procedure Build_Offset_To_Top_Internal (Typ : Entity_Id);
1759          --  Internal subprogram used to recursively traverse all the ancestors
1760
1761          ----------------------------------
1762          -- Build_Offset_To_Top_Internal --
1763          ----------------------------------
1764
1765          procedure Build_Offset_To_Top_Internal (Typ : Entity_Id) is
1766          begin
1767             --  Climb to the ancestor (if any) handling private types
1768
1769             if Present (Full_View (Etype (Typ))) then
1770                if Full_View (Etype (Typ)) /= Typ then
1771                   Build_Offset_To_Top_Internal (Full_View (Etype (Typ)));
1772                end if;
1773
1774             elsif Etype (Typ) /= Typ then
1775                Build_Offset_To_Top_Internal (Etype (Typ));
1776             end if;
1777
1778             if Present (Abstract_Interfaces (Typ))
1779               and then not Is_Empty_Elmt_List (Abstract_Interfaces (Typ))
1780             then
1781                E := First_Entity (Typ);
1782                while Present (E) loop
1783                   if Is_Tag (E)
1784                     and then Chars (E) /= Name_uTag
1785                   then
1786                      if Typ = Rec_Type then
1787                         Body_Node := New_Node (N_Subprogram_Body, Loc);
1788
1789                         Func_Id := Make_Defining_Identifier (Loc,
1790                                      New_Internal_Name ('F'));
1791
1792                         Set_DT_Offset_To_Top_Func (E, Func_Id);
1793
1794                         Spec_Node := New_Node (N_Function_Specification, Loc);
1795                         Set_Defining_Unit_Name (Spec_Node, Func_Id);
1796                         Set_Parameter_Specifications (Spec_Node, New_List (
1797                            Make_Parameter_Specification (Loc,
1798                              Defining_Identifier =>
1799                                Make_Defining_Identifier (Loc, Name_uO),
1800                              In_Present => True,
1801                              Parameter_Type => New_Reference_To (Typ, Loc))));
1802                         Set_Result_Definition (Spec_Node,
1803                           New_Reference_To (RTE (RE_Storage_Offset), Loc));
1804
1805                         Set_Specification (Body_Node, Spec_Node);
1806                         Set_Declarations (Body_Node, New_List);
1807                         Set_Handled_Statement_Sequence (Body_Node,
1808                           Make_Handled_Sequence_Of_Statements (Loc,
1809                             Statements => New_List (
1810                               Make_Return_Statement (Loc,
1811                                 Expression =>
1812                                   Make_Attribute_Reference (Loc,
1813                                     Prefix =>
1814                                       Make_Selected_Component (Loc,
1815                                         Prefix => Make_Identifier (Loc,
1816                                                     Name_uO),
1817                                         Selector_Name => New_Reference_To
1818                                                            (E, Loc)),
1819                                     Attribute_Name => Name_Position)))));
1820
1821                         Set_Ekind       (Func_Id, E_Function);
1822                         Set_Mechanism   (Func_Id, Default_Mechanism);
1823                         Set_Is_Internal (Func_Id, True);
1824
1825                         if not Debug_Generated_Code then
1826                            Set_Debug_Info_Off (Func_Id);
1827                         end if;
1828
1829                         Analyze (Body_Node);
1830
1831                         Append_Freeze_Action (Rec_Type, Body_Node);
1832                      end if;
1833
1834                      Next_Elmt (ADT);
1835                   end if;
1836
1837                   Next_Entity (E);
1838                end loop;
1839             end if;
1840          end Build_Offset_To_Top_Internal;
1841
1842       --  Start of processing for Build_Offset_To_Top_Functions
1843
1844       begin
1845          if Etype (Rec_Type) = Rec_Type
1846            or else not Has_Discriminants (Etype (Rec_Type))
1847            or else No (Abstract_Interfaces (Rec_Type))
1848            or else Is_Empty_Elmt_List (Abstract_Interfaces (Rec_Type))
1849          then
1850             return;
1851          end if;
1852
1853          --  Skip the first _Tag, which is the main tag of the
1854          --  tagged type. Following tags correspond with abstract
1855          --  interfaces.
1856
1857          ADT := Next_Elmt (First_Elmt (Access_Disp_Table (Rec_Type)));
1858
1859          --  Handle private types
1860
1861          if Present (Full_View (Rec_Type)) then
1862             Build_Offset_To_Top_Internal (Full_View (Rec_Type));
1863          else
1864             Build_Offset_To_Top_Internal (Rec_Type);
1865          end if;
1866       end Build_Offset_To_Top_Functions;
1867
1868       --------------------------
1869       -- Build_Init_Procedure --
1870       --------------------------
1871
1872       procedure Build_Init_Procedure is
1873          Body_Node             : Node_Id;
1874          Handled_Stmt_Node     : Node_Id;
1875          Parameters            : List_Id;
1876          Proc_Spec_Node        : Node_Id;
1877          Body_Stmts            : List_Id;
1878          Record_Extension_Node : Node_Id;
1879          Init_Tag              : Node_Id;
1880
1881       begin
1882          Body_Stmts := New_List;
1883          Body_Node := New_Node (N_Subprogram_Body, Loc);
1884
1885          Proc_Id :=
1886            Make_Defining_Identifier (Loc,
1887              Chars => Make_Init_Proc_Name (Rec_Type));
1888          Set_Ekind (Proc_Id, E_Procedure);
1889
1890          Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
1891          Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);
1892
1893          Parameters := Init_Formals (Rec_Type);
1894          Append_List_To (Parameters,
1895            Build_Discriminant_Formals (Rec_Type, True));
1896
1897          --  For tagged types, we add a flag to indicate whether the routine
1898          --  is called to initialize a parent component in the init_proc of
1899          --  a type extension. If the flag is false, we do not set the tag
1900          --  because it has been set already in the extension.
1901
1902          if Is_Tagged_Type (Rec_Type)
1903            and then not Is_CPP_Class (Rec_Type)
1904          then
1905             Set_Tag :=
1906                   Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1907
1908             Append_To (Parameters,
1909               Make_Parameter_Specification (Loc,
1910                 Defining_Identifier => Set_Tag,
1911                 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
1912                 Expression => New_Occurrence_Of (Standard_True, Loc)));
1913          end if;
1914
1915          Set_Parameter_Specifications (Proc_Spec_Node, Parameters);
1916          Set_Specification (Body_Node, Proc_Spec_Node);
1917          Set_Declarations (Body_Node, New_List);
1918
1919          if Parent_Subtype_Renaming_Discrims then
1920
1921             --  N is a Derived_Type_Definition that renames the parameters
1922             --  of the ancestor type. We initialize it by expanding our
1923             --  discriminants and call the ancestor _init_proc with a
1924             --  type-converted object
1925
1926             Append_List_To (Body_Stmts,
1927               Build_Init_Call_Thru (Parameters));
1928
1929          elsif Nkind (Type_Definition (N)) = N_Record_Definition then
1930             Build_Discriminant_Assignments (Body_Stmts);
1931
1932             if not Null_Present (Type_Definition (N)) then
1933                Append_List_To (Body_Stmts,
1934                  Build_Init_Statements (
1935                    Component_List (Type_Definition (N))));
1936             end if;
1937
1938          else
1939             --  N is a Derived_Type_Definition with a possible non-empty
1940             --  extension. The initialization of a type extension consists
1941             --  in the initialization of the components in the extension.
1942
1943             Build_Discriminant_Assignments (Body_Stmts);
1944
1945             Record_Extension_Node :=
1946               Record_Extension_Part (Type_Definition (N));
1947
1948             if not Null_Present (Record_Extension_Node) then
1949                declare
1950                   Stmts : constant List_Id :=
1951                             Build_Init_Statements (
1952                               Component_List (Record_Extension_Node));
1953
1954                begin
1955                   --  The parent field must be initialized first because
1956                   --  the offset of the new discriminants may depend on it
1957
1958                   Prepend_To (Body_Stmts, Remove_Head (Stmts));
1959                   Append_List_To (Body_Stmts, Stmts);
1960                end;
1961             end if;
1962          end if;
1963
1964          --  Add here the assignment to instantiate the Tag
1965
1966          --  The assignement corresponds to the code:
1967
1968          --     _Init._Tag := Typ'Tag;
1969
1970          --  Suppress the tag assignment when Java_VM because JVM tags are
1971          --  represented implicitly in objects. It is also suppressed in
1972          --  case of CPP_Class types because in this case the tag is
1973          --  initialized in the C++ side.
1974
1975          if Is_Tagged_Type (Rec_Type)
1976            and then not Is_CPP_Class (Rec_Type)
1977            and then not Java_VM
1978          then
1979             Init_Tag :=
1980               Make_Assignment_Statement (Loc,
1981                 Name =>
1982                   Make_Selected_Component (Loc,
1983                     Prefix => Make_Identifier (Loc, Name_uInit),
1984                     Selector_Name =>
1985                       New_Reference_To (First_Tag_Component (Rec_Type), Loc)),
1986
1987                 Expression =>
1988                   New_Reference_To
1989                     (Node (First_Elmt (Access_Disp_Table (Rec_Type))), Loc));
1990
1991             --  The tag must be inserted before the assignments to other
1992             --  components,  because the initial value of the component may
1993             --  depend ot the tag (eg. through a dispatching operation on
1994             --  an access to the current type). The tag assignment is not done
1995             --  when initializing the parent component of a type extension,
1996             --  because in that case the tag is set in the extension.
1997             --  Extensions of imported C++ classes add a final complication,
1998             --  because we cannot inhibit tag setting in the constructor for
1999             --  the parent. In that case we insert the tag initialization
2000             --  after the calls to initialize the parent.
2001
2002             if not Is_CPP_Class (Etype (Rec_Type)) then
2003                Init_Tag :=
2004                  Make_If_Statement (Loc,
2005                    Condition => New_Occurrence_Of (Set_Tag, Loc),
2006                    Then_Statements => New_List (Init_Tag));
2007
2008                Prepend_To (Body_Stmts, Init_Tag);
2009
2010             else
2011                declare
2012                   Nod   : Node_Id := First (Body_Stmts);
2013                   New_N : Node_Id;
2014                   Args  : List_Id;
2015
2016                begin
2017                   --  We assume the first init_proc call is for the parent
2018
2019                   while Present (Next (Nod))
2020                     and then (Nkind (Nod) /= N_Procedure_Call_Statement
2021                                or else not Is_Init_Proc (Name (Nod)))
2022                   loop
2023                      Nod := Next (Nod);
2024                   end loop;
2025
2026                   --  Generate:
2027                   --     ancestor_constructor (_init.parent);
2028                   --     if Arg2 then
2029                   --        _init._tag := new_dt;
2030                   --     end if;
2031
2032                   if Debug_Flag_QQ then
2033                      Init_Tag :=
2034                        Make_If_Statement (Loc,
2035                          Condition => New_Occurrence_Of (Set_Tag, Loc),
2036                          Then_Statements => New_List (Init_Tag));
2037                      Insert_After (Nod, Init_Tag);
2038
2039                   --  Generate:
2040                   --     ancestor_constructor (_init.parent);
2041                   --     if Arg2 then
2042                   --        inherit_dt (_init._tag, new_dt, num_prims);
2043                   --        _init._tag := new_dt;
2044                   --     end if;
2045                   else
2046                      Args := New_List (
2047                         Node1 =>
2048                           Make_Selected_Component (Loc,
2049                             Prefix => Make_Identifier (Loc, Name_uInit),
2050                             Selector_Name =>
2051                               New_Reference_To
2052                                 (First_Tag_Component (Rec_Type), Loc)),
2053
2054                         Node2 =>
2055                           New_Reference_To
2056                             (Node (First_Elmt (Access_Disp_Table (Rec_Type))),
2057                              Loc),
2058
2059                         Node3 =>
2060                           Make_Integer_Literal (Loc,
2061                             DT_Entry_Count (First_Tag_Component (Rec_Type))));
2062
2063                      New_N :=
2064                        Make_Procedure_Call_Statement (Loc,
2065                          Name => New_Reference_To (RTE (RE_Inherit_CPP_DT),
2066                                                    Loc),
2067                          Parameter_Associations => Args);
2068
2069                      Init_Tag :=
2070                        Make_If_Statement (Loc,
2071                          Condition => New_Occurrence_Of (Set_Tag, Loc),
2072                          Then_Statements => New_List (New_N, Init_Tag));
2073
2074                      Insert_After (Nod, Init_Tag);
2075
2076                      --  We have inherited the whole contents of the DT table
2077                      --  from the CPP side. Therefore all our previous initia-
2078                      --  lization has been lost and we must refill entries
2079                      --  associated with Ada primitives. This needs more work
2080                      --  to avoid its execution each time an object is
2081                      --  initialized???
2082
2083                      declare
2084                         E    : Elmt_Id;
2085                         Prim : Node_Id;
2086
2087                      begin
2088                         E := First_Elmt (Primitive_Operations (Rec_Type));
2089                         while Present (E) loop
2090                            Prim := Node (E);
2091
2092                            if not Is_Imported (Prim)
2093                              and then Convention (Prim) = Convention_CPP
2094                              and then not Present (Abstract_Interface_Alias
2095                                                     (Prim))
2096                            then
2097                               Insert_After (Init_Tag,
2098                                  Fill_DT_Entry (Loc, Prim));
2099                            end if;
2100
2101                            Next_Elmt (E);
2102                         end loop;
2103                      end;
2104                   end if;
2105                end;
2106             end if;
2107
2108             --  Ada 2005 (AI-251): Initialization of all the tags
2109             --  corresponding with abstract interfaces
2110
2111             if Ada_Version >= Ada_05
2112               and then not Is_Interface (Rec_Type)
2113             then
2114                Init_Secondary_Tags
2115                  (Typ        => Rec_Type,
2116                   Target     => Make_Identifier (Loc, Name_uInit),
2117                   Stmts_List => Body_Stmts);
2118             end if;
2119          end if;
2120
2121          Handled_Stmt_Node := New_Node (N_Handled_Sequence_Of_Statements, Loc);
2122          Set_Statements (Handled_Stmt_Node, Body_Stmts);
2123          Set_Exception_Handlers (Handled_Stmt_Node, No_List);
2124          Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);
2125
2126          if not Debug_Generated_Code then
2127             Set_Debug_Info_Off (Proc_Id);
2128          end if;
2129
2130          --  Associate Init_Proc with type, and determine if the procedure
2131          --  is null (happens because of the Initialize_Scalars pragma case,
2132          --  where we have to generate a null procedure in case it is called
2133          --  by a client with Initialize_Scalars set). Such procedures have
2134          --  to be generated, but do not have to be called, so we mark them
2135          --  as null to suppress the call.
2136
2137          Set_Init_Proc (Rec_Type, Proc_Id);
2138
2139          if List_Length (Body_Stmts) = 1
2140            and then Nkind (First (Body_Stmts)) = N_Null_Statement
2141          then
2142             Set_Is_Null_Init_Proc (Proc_Id);
2143          end if;
2144       end Build_Init_Procedure;
2145
2146       ---------------------------
2147       -- Build_Init_Statements --
2148       ---------------------------
2149
2150       function Build_Init_Statements (Comp_List : Node_Id) return List_Id is
2151          Check_List     : constant List_Id := New_List;
2152          Alt_List       : List_Id;
2153          Statement_List : List_Id;
2154          Stmts          : List_Id;
2155
2156          Per_Object_Constraint_Components : Boolean;
2157
2158          Decl     : Node_Id;
2159          Variant  : Node_Id;
2160
2161          Id  : Entity_Id;
2162          Typ : Entity_Id;
2163
2164          function Has_Access_Constraint (E : Entity_Id) return Boolean;
2165          --  Components with access discriminants that depend on the current
2166          --  instance must be initialized after all other components.
2167
2168          ---------------------------
2169          -- Has_Access_Constraint --
2170          ---------------------------
2171
2172          function Has_Access_Constraint (E : Entity_Id) return Boolean is
2173             Disc : Entity_Id;
2174             T    : constant Entity_Id := Etype (E);
2175
2176          begin
2177             if Has_Per_Object_Constraint (E)
2178               and then Has_Discriminants (T)
2179             then
2180                Disc := First_Discriminant (T);
2181                while Present (Disc) loop
2182                   if Is_Access_Type (Etype (Disc)) then
2183                      return True;
2184                   end if;
2185
2186                   Next_Discriminant (Disc);
2187                end loop;
2188
2189                return False;
2190             else
2191                return False;
2192             end if;
2193          end Has_Access_Constraint;
2194
2195       --  Start of processing for Build_Init_Statements
2196
2197       begin
2198          if Null_Present (Comp_List) then
2199             return New_List (Make_Null_Statement (Loc));
2200          end if;
2201
2202          Statement_List := New_List;
2203
2204          --  Loop through components, skipping pragmas, in 2 steps. The first
2205          --  step deals with regular components. The second step deals with
2206          --  components have per object constraints, and no explicit initia-
2207          --  lization.
2208
2209          Per_Object_Constraint_Components := False;
2210
2211          --  First step : regular components
2212
2213          Decl := First_Non_Pragma (Component_Items (Comp_List));
2214          while Present (Decl) loop
2215             Loc := Sloc (Decl);
2216             Build_Record_Checks
2217               (Subtype_Indication (Component_Definition (Decl)), Check_List);
2218
2219             Id := Defining_Identifier (Decl);
2220             Typ := Etype (Id);
2221
2222             if Has_Access_Constraint (Id)
2223               and then No (Expression (Decl))
2224             then
2225                --  Skip processing for now and ask for a second pass
2226
2227                Per_Object_Constraint_Components := True;
2228
2229             else
2230                --  Case of explicit initialization
2231
2232                if Present (Expression (Decl)) then
2233                   Stmts := Build_Assignment (Id, Expression (Decl));
2234
2235                --  Case of composite component with its own Init_Proc
2236
2237                elsif not Is_Interface (Typ)
2238                  and then Has_Non_Null_Base_Init_Proc (Typ)
2239                then
2240                   Stmts :=
2241                     Build_Initialization_Call
2242                       (Loc,
2243                        Make_Selected_Component (Loc,
2244                          Prefix => Make_Identifier (Loc, Name_uInit),
2245                          Selector_Name => New_Occurrence_Of (Id, Loc)),
2246                        Typ,
2247                        True,
2248                        Rec_Type,
2249                        Discr_Map => Discr_Map);
2250
2251                   Clean_Task_Names (Typ, Proc_Id);
2252
2253                --  Case of component needing simple initialization
2254
2255                elsif Component_Needs_Simple_Initialization (Typ) then
2256                   Stmts :=
2257                     Build_Assignment
2258                       (Id, Get_Simple_Init_Val (Typ, Loc, Esize (Id)));
2259
2260                --  Nothing needed for this case
2261
2262                else
2263                   Stmts := No_List;
2264                end if;
2265
2266                if Present (Check_List) then
2267                   Append_List_To (Statement_List, Check_List);
2268                end if;
2269
2270                if Present (Stmts) then
2271
2272                   --  Add the initialization of the record controller before
2273                   --  the _Parent field is attached to it when the attachment
2274                   --  can occur. It does not work to simply initialize the
2275                   --  controller first: it must be initialized after the parent
2276                   --  if the parent holds discriminants that can be used
2277                   --  to compute the offset of the controller. We assume here
2278                   --  that the last statement of the initialization call is the
2279                   --  attachement of the parent (see Build_Initialization_Call)
2280
2281                   if Chars (Id) = Name_uController
2282                     and then Rec_Type /= Etype (Rec_Type)
2283                     and then Has_Controlled_Component (Etype (Rec_Type))
2284                     and then Has_New_Controlled_Component (Rec_Type)
2285                   then
2286                      Insert_List_Before (Last (Statement_List), Stmts);
2287                   else
2288                      Append_List_To (Statement_List, Stmts);
2289                   end if;
2290                end if;
2291             end if;
2292
2293             Next_Non_Pragma (Decl);
2294          end loop;
2295
2296          if Per_Object_Constraint_Components then
2297
2298             --  Second pass: components with per-object constraints
2299
2300             Decl := First_Non_Pragma (Component_Items (Comp_List));
2301
2302             while Present (Decl) loop
2303                Loc := Sloc (Decl);
2304                Id := Defining_Identifier (Decl);
2305                Typ := Etype (Id);
2306
2307                if Has_Access_Constraint (Id)
2308                  and then No (Expression (Decl))
2309                then
2310                   if Has_Non_Null_Base_Init_Proc (Typ) then
2311                      Append_List_To (Statement_List,
2312                        Build_Initialization_Call (Loc,
2313                          Make_Selected_Component (Loc,
2314                            Prefix => Make_Identifier (Loc, Name_uInit),
2315                            Selector_Name => New_Occurrence_Of (Id, Loc)),
2316                          Typ, True, Rec_Type, Discr_Map => Discr_Map));
2317
2318                      Clean_Task_Names (Typ, Proc_Id);
2319
2320                   elsif Component_Needs_Simple_Initialization (Typ) then
2321                      Append_List_To (Statement_List,
2322                        Build_Assignment
2323                          (Id, Get_Simple_Init_Val (Typ, Loc, Esize (Id))));
2324                   end if;
2325                end if;
2326
2327                Next_Non_Pragma (Decl);
2328             end loop;
2329          end if;
2330
2331          --  Process the variant part
2332
2333          if Present (Variant_Part (Comp_List)) then
2334             Alt_List := New_List;
2335             Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
2336
2337             while Present (Variant) loop
2338                Loc := Sloc (Variant);
2339                Append_To (Alt_List,
2340                  Make_Case_Statement_Alternative (Loc,
2341                    Discrete_Choices =>
2342                      New_Copy_List (Discrete_Choices (Variant)),
2343                    Statements =>
2344                      Build_Init_Statements (Component_List (Variant))));
2345
2346                Next_Non_Pragma (Variant);
2347             end loop;
2348
2349             --  The expression of the case statement which is a reference
2350             --  to one of the discriminants is replaced by the appropriate
2351             --  formal parameter of the initialization procedure.
2352
2353             Append_To (Statement_List,
2354               Make_Case_Statement (Loc,
2355                 Expression =>
2356                   New_Reference_To (Discriminal (
2357                     Entity (Name (Variant_Part (Comp_List)))), Loc),
2358                 Alternatives => Alt_List));
2359          end if;
2360
2361          --  For a task record type, add the task create call and calls
2362          --  to bind any interrupt (signal) entries.
2363
2364          if Is_Task_Record_Type (Rec_Type) then
2365
2366             --  In the case of the restricted run time the ATCB has already
2367             --  been preallocated.
2368
2369             if Restricted_Profile then
2370                Append_To (Statement_List,
2371                  Make_Assignment_Statement (Loc,
2372                    Name => Make_Selected_Component (Loc,
2373                      Prefix => Make_Identifier (Loc, Name_uInit),
2374                      Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
2375                    Expression => Make_Attribute_Reference (Loc,
2376                      Prefix =>
2377                        Make_Selected_Component (Loc,
2378                          Prefix => Make_Identifier (Loc, Name_uInit),
2379                          Selector_Name =>
2380                            Make_Identifier (Loc, Name_uATCB)),
2381                      Attribute_Name => Name_Unchecked_Access)));
2382             end if;
2383
2384             Append_To (Statement_List, Make_Task_Create_Call (Rec_Type));
2385
2386             declare
2387                Task_Type : constant Entity_Id :=
2388                              Corresponding_Concurrent_Type (Rec_Type);
2389                Task_Decl : constant Node_Id := Parent (Task_Type);
2390                Task_Def  : constant Node_Id := Task_Definition (Task_Decl);
2391                Vis_Decl  : Node_Id;
2392                Ent       : Entity_Id;
2393
2394             begin
2395                if Present (Task_Def) then
2396                   Vis_Decl := First (Visible_Declarations (Task_Def));
2397                   while Present (Vis_Decl) loop
2398                      Loc := Sloc (Vis_Decl);
2399
2400                      if Nkind (Vis_Decl) = N_Attribute_Definition_Clause then
2401                         if Get_Attribute_Id (Chars (Vis_Decl)) =
2402                                                        Attribute_Address
2403                         then
2404                            Ent := Entity (Name (Vis_Decl));
2405
2406                            if Ekind (Ent) = E_Entry then
2407                               Append_To (Statement_List,
2408                                 Make_Procedure_Call_Statement (Loc,
2409                                   Name => New_Reference_To (
2410                                     RTE (RE_Bind_Interrupt_To_Entry), Loc),
2411                                   Parameter_Associations => New_List (
2412                                     Make_Selected_Component (Loc,
2413                                       Prefix =>
2414                                         Make_Identifier (Loc, Name_uInit),
2415                                       Selector_Name =>
2416                                         Make_Identifier (Loc, Name_uTask_Id)),
2417                                     Entry_Index_Expression (
2418                                       Loc, Ent, Empty, Task_Type),
2419                                     Expression (Vis_Decl))));
2420                            end if;
2421                         end if;
2422                      end if;
2423
2424                      Next (Vis_Decl);
2425                   end loop;
2426                end if;
2427             end;
2428          end if;
2429
2430          --  For a protected type, add statements generated by
2431          --  Make_Initialize_Protection.
2432
2433          if Is_Protected_Record_Type (Rec_Type) then
2434             Append_List_To (Statement_List,
2435               Make_Initialize_Protection (Rec_Type));
2436          end if;
2437
2438          --  If no initializations when generated for component declarations
2439          --  corresponding to this Statement_List, append a null statement
2440          --  to the Statement_List to make it a valid Ada tree.
2441
2442          if Is_Empty_List (Statement_List) then
2443             Append (New_Node (N_Null_Statement, Loc), Statement_List);
2444          end if;
2445
2446          return Statement_List;
2447
2448       exception
2449          when RE_Not_Available =>
2450          return Empty_List;
2451       end Build_Init_Statements;
2452
2453       -------------------------
2454       -- Build_Record_Checks --
2455       -------------------------
2456
2457       procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id) is
2458          Subtype_Mark_Id : Entity_Id;
2459
2460       begin
2461          if Nkind (S) = N_Subtype_Indication then
2462             Find_Type (Subtype_Mark (S));
2463             Subtype_Mark_Id := Entity (Subtype_Mark (S));
2464
2465             --  Remaining processing depends on type
2466
2467             case Ekind (Subtype_Mark_Id) is
2468
2469                when Array_Kind =>
2470                   Constrain_Array (S, Check_List);
2471
2472                when others =>
2473                   null;
2474             end case;
2475          end if;
2476       end Build_Record_Checks;
2477
2478       -------------------------------------------
2479       -- Component_Needs_Simple_Initialization --
2480       -------------------------------------------
2481
2482       function Component_Needs_Simple_Initialization
2483         (T : Entity_Id) return Boolean
2484       is
2485       begin
2486          return
2487            Needs_Simple_Initialization (T)
2488              and then not Is_RTE (T, RE_Tag)
2489              and then not Is_RTE (T, RE_Vtable_Ptr)
2490
2491                --  Ada 2005 (AI-251): Check also the tag of abstract interfaces
2492
2493              and then not Is_RTE (T, RE_Interface_Tag);
2494       end Component_Needs_Simple_Initialization;
2495
2496       ---------------------
2497       -- Constrain_Array --
2498       ---------------------
2499
2500       procedure Constrain_Array
2501         (SI          : Node_Id;
2502          Check_List  : List_Id)
2503       is
2504          C                     : constant Node_Id := Constraint (SI);
2505          Number_Of_Constraints : Nat := 0;
2506          Index                 : Node_Id;
2507          S, T                  : Entity_Id;
2508
2509       begin
2510          T := Entity (Subtype_Mark (SI));
2511
2512          if Ekind (T) in Access_Kind then
2513             T := Designated_Type (T);
2514          end if;
2515
2516          S := First (Constraints (C));
2517
2518          while Present (S) loop
2519             Number_Of_Constraints := Number_Of_Constraints + 1;
2520             Next (S);
2521          end loop;
2522
2523          --  In either case, the index constraint must provide a discrete
2524          --  range for each index of the array type and the type of each
2525          --  discrete range must be the same as that of the corresponding
2526          --  index. (RM 3.6.1)
2527
2528          S := First (Constraints (C));
2529          Index := First_Index (T);
2530          Analyze (Index);
2531
2532          --  Apply constraints to each index type
2533
2534          for J in 1 .. Number_Of_Constraints loop
2535             Constrain_Index (Index, S, Check_List);
2536             Next (Index);
2537             Next (S);
2538          end loop;
2539
2540       end Constrain_Array;
2541
2542       ---------------------
2543       -- Constrain_Index --
2544       ---------------------
2545
2546       procedure Constrain_Index
2547         (Index        : Node_Id;
2548          S            : Node_Id;
2549          Check_List   : List_Id)
2550       is
2551          T : constant Entity_Id := Etype (Index);
2552
2553       begin
2554          if Nkind (S) = N_Range then
2555             Process_Range_Expr_In_Decl (S, T, Check_List);
2556          end if;
2557       end Constrain_Index;
2558
2559       --------------------------------------
2560       -- Parent_Subtype_Renaming_Discrims --
2561       --------------------------------------
2562
2563       function Parent_Subtype_Renaming_Discrims return Boolean is
2564          De : Entity_Id;
2565          Dp : Entity_Id;
2566
2567       begin
2568          if Base_Type (Pe) /= Pe then
2569             return False;
2570          end if;
2571
2572          if Etype (Pe) = Pe
2573            or else not Has_Discriminants (Pe)
2574            or else Is_Constrained (Pe)
2575            or else Is_Tagged_Type (Pe)
2576          then
2577             return False;
2578          end if;
2579
2580          --  If there are no explicit stored discriminants we have inherited
2581          --  the root type discriminants so far, so no renamings occurred.
2582
2583          if First_Discriminant (Pe) = First_Stored_Discriminant (Pe) then
2584             return False;
2585          end if;
2586
2587          --  Check if we have done some trivial renaming of the parent
2588          --  discriminants, i.e. someting like
2589          --
2590          --    type DT (X1,X2: int) is new PT (X1,X2);
2591
2592          De := First_Discriminant (Pe);
2593          Dp := First_Discriminant (Etype (Pe));
2594
2595          while Present (De) loop
2596             pragma Assert (Present (Dp));
2597
2598             if Corresponding_Discriminant (De) /= Dp then
2599                return True;
2600             end if;
2601
2602             Next_Discriminant (De);
2603             Next_Discriminant (Dp);
2604          end loop;
2605
2606          return Present (Dp);
2607       end Parent_Subtype_Renaming_Discrims;
2608
2609       ------------------------
2610       -- Requires_Init_Proc --
2611       ------------------------
2612
2613       function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean is
2614          Comp_Decl : Node_Id;
2615          Id        : Entity_Id;
2616          Typ       : Entity_Id;
2617
2618       begin
2619          --  Definitely do not need one if specifically suppressed
2620
2621          if Suppress_Init_Proc (Rec_Id) then
2622             return False;
2623          end if;
2624
2625          --  If it is a type derived from a type with unknown discriminants,
2626          --  we cannot build an initialization procedure for it.
2627
2628          if Has_Unknown_Discriminants (Rec_Id) then
2629             return False;
2630          end if;
2631
2632          --  Otherwise we need to generate an initialization procedure if
2633          --  Is_CPP_Class is False and at least one of the following applies:
2634
2635          --  1. Discriminants are present, since they need to be initialized
2636          --     with the appropriate discriminant constraint expressions.
2637          --     However, the discriminant of an unchecked union does not
2638          --     count, since the discriminant is not present.
2639
2640          --  2. The type is a tagged type, since the implicit Tag component
2641          --     needs to be initialized with a pointer to the dispatch table.
2642
2643          --  3. The type contains tasks
2644
2645          --  4. One or more components has an initial value
2646
2647          --  5. One or more components is for a type which itself requires
2648          --     an initialization procedure.
2649
2650          --  6. One or more components is a type that requires simple
2651          --     initialization (see Needs_Simple_Initialization), except
2652          --     that types Tag and Interface_Tag are excluded, since fields
2653          --     of these types are initialized by other means.
2654
2655          --  7. The type is the record type built for a task type (since at
2656          --     the very least, Create_Task must be called)
2657
2658          --  8. The type is the record type built for a protected type (since
2659          --     at least Initialize_Protection must be called)
2660
2661          --  9. The type is marked as a public entity. The reason we add this
2662          --     case (even if none of the above apply) is to properly handle
2663          --     Initialize_Scalars. If a package is compiled without an IS
2664          --     pragma, and the client is compiled with an IS pragma, then
2665          --     the client will think an initialization procedure is present
2666          --     and call it, when in fact no such procedure is required, but
2667          --     since the call is generated, there had better be a routine
2668          --     at the other end of the call, even if it does nothing!)
2669
2670          --  Note: the reason we exclude the CPP_Class case is because in this
2671          --  case the initialization is performed in the C++ side.
2672
2673          if Is_CPP_Class (Rec_Id) then
2674             return False;
2675
2676          elsif not Restriction_Active (No_Initialize_Scalars)
2677            and then Is_Public (Rec_Id)
2678          then
2679             return True;
2680
2681          elsif (Has_Discriminants (Rec_Id)
2682                   and then not Is_Unchecked_Union (Rec_Id))
2683            or else Is_Tagged_Type (Rec_Id)
2684            or else Is_Concurrent_Record_Type (Rec_Id)
2685            or else Has_Task (Rec_Id)
2686          then
2687             return True;
2688          end if;
2689
2690          Id := First_Component (Rec_Id);
2691
2692          while Present (Id) loop
2693             Comp_Decl := Parent (Id);
2694             Typ := Etype (Id);
2695
2696             if Present (Expression (Comp_Decl))
2697               or else Has_Non_Null_Base_Init_Proc (Typ)
2698               or else Component_Needs_Simple_Initialization (Typ)
2699             then
2700                return True;
2701             end if;
2702
2703             Next_Component (Id);
2704          end loop;
2705
2706          return False;
2707       end Requires_Init_Proc;
2708
2709    --  Start of processing for Build_Record_Init_Proc
2710
2711    begin
2712       Rec_Type := Defining_Identifier (N);
2713
2714       --  This may be full declaration of a private type, in which case
2715       --  the visible entity is a record, and the private entity has been
2716       --  exchanged with it in the private part of the current package.
2717       --  The initialization procedure is built for the record type, which
2718       --  is retrievable from the private entity.
2719
2720       if Is_Incomplete_Or_Private_Type (Rec_Type) then
2721          Rec_Type := Underlying_Type (Rec_Type);
2722       end if;
2723
2724       --  If there are discriminants, build the discriminant map to replace
2725       --  discriminants by their discriminals in complex bound expressions.
2726       --  These only arise for the corresponding records of protected types.
2727
2728       if Is_Concurrent_Record_Type (Rec_Type)
2729         and then Has_Discriminants (Rec_Type)
2730       then
2731          declare
2732             Disc : Entity_Id;
2733          begin
2734             Disc := First_Discriminant (Rec_Type);
2735             while Present (Disc) loop
2736                Append_Elmt (Disc, Discr_Map);
2737                Append_Elmt (Discriminal (Disc), Discr_Map);
2738                Next_Discriminant (Disc);
2739             end loop;
2740          end;
2741       end if;
2742
2743       --  Derived types that have no type extension can use the initialization
2744       --  procedure of their parent and do not need a procedure of their own.
2745       --  This is only correct if there are no representation clauses for the
2746       --  type or its parent, and if the parent has in fact been frozen so
2747       --  that its initialization procedure exists.
2748
2749       if Is_Derived_Type (Rec_Type)
2750         and then not Is_Tagged_Type (Rec_Type)
2751         and then not Is_Unchecked_Union (Rec_Type)
2752         and then not Has_New_Non_Standard_Rep (Rec_Type)
2753         and then not Parent_Subtype_Renaming_Discrims
2754         and then Has_Non_Null_Base_Init_Proc (Etype (Rec_Type))
2755       then
2756          Copy_TSS (Base_Init_Proc (Etype (Rec_Type)), Rec_Type);
2757
2758       --  Otherwise if we need an initialization procedure, then build one,
2759       --  mark it as public and inlinable and as having a completion.
2760
2761       elsif Requires_Init_Proc (Rec_Type)
2762         or else Is_Unchecked_Union (Rec_Type)
2763       then
2764          Build_Offset_To_Top_Functions;
2765          Build_Init_Procedure;
2766          Set_Is_Public (Proc_Id, Is_Public (Pe));
2767
2768          --  The initialization of protected records is not worth inlining.
2769          --  In addition, when compiled for another unit for inlining purposes,
2770          --  it may make reference to entities that have not been elaborated
2771          --  yet. The initialization of controlled records contains a nested
2772          --  clean-up procedure that makes it impractical to inline as well,
2773          --  and leads to undefined symbols if inlined in a different unit.
2774          --  Similar considerations apply to task types.
2775
2776          if not Is_Concurrent_Type (Rec_Type)
2777            and then not Has_Task (Rec_Type)
2778            and then not Controlled_Type (Rec_Type)
2779          then
2780             Set_Is_Inlined  (Proc_Id);
2781          end if;
2782
2783          Set_Is_Internal    (Proc_Id);
2784          Set_Has_Completion (Proc_Id);
2785
2786          if not Debug_Generated_Code then
2787             Set_Debug_Info_Off (Proc_Id);
2788          end if;
2789       end if;
2790    end Build_Record_Init_Proc;
2791
2792    ----------------------------
2793    -- Build_Slice_Assignment --
2794    ----------------------------
2795
2796    --  Generates the following subprogram:
2797
2798    --    procedure Assign
2799    --     (Source,   Target   : Array_Type,
2800    --      Left_Lo,  Left_Hi, Right_Lo, Right_Hi : Index;
2801    --      Rev :     Boolean)
2802    --    is
2803    --       Li1 : Index;
2804    --       Ri1 : Index;
2805
2806    --    begin
2807    --       if Rev  then
2808    --          Li1 := Left_Hi;
2809    --          Ri1 := Right_Hi;
2810    --       else
2811    --          Li1 := Left_Lo;
2812    --          Ri1 := Right_Lo;
2813    --       end if;
2814
2815    --       loop
2816    --             if Rev then
2817    --                exit when Li1 < Left_Lo;
2818    --             else
2819    --                exit when Li1 > Left_Hi;
2820    --             end if;
2821
2822    --             Target (Li1) := Source (Ri1);
2823
2824    --             if Rev then
2825    --                Li1 := Index'pred (Li1);
2826    --                Ri1 := Index'pred (Ri1);
2827    --             else
2828    --                Li1 := Index'succ (Li1);
2829    --                Ri1 := Index'succ (Ri1);
2830    --             end if;
2831    --       end loop;
2832    --    end Assign;
2833
2834    procedure Build_Slice_Assignment (Typ : Entity_Id) is
2835       Loc   : constant Source_Ptr := Sloc (Typ);
2836       Index : constant Entity_Id  := Base_Type (Etype (First_Index (Typ)));
2837
2838       --  Build formal parameters of procedure
2839
2840       Larray   : constant Entity_Id :=
2841                    Make_Defining_Identifier
2842                      (Loc, Chars => New_Internal_Name ('A'));
2843       Rarray   : constant Entity_Id :=
2844                    Make_Defining_Identifier
2845                      (Loc, Chars => New_Internal_Name ('R'));
2846       Left_Lo  : constant Entity_Id :=
2847                    Make_Defining_Identifier
2848                      (Loc, Chars => New_Internal_Name ('L'));
2849       Left_Hi  : constant Entity_Id :=
2850                    Make_Defining_Identifier
2851                      (Loc, Chars => New_Internal_Name ('L'));
2852       Right_Lo : constant Entity_Id :=
2853                    Make_Defining_Identifier
2854                      (Loc, Chars => New_Internal_Name ('R'));
2855       Right_Hi : constant Entity_Id :=
2856                    Make_Defining_Identifier
2857                      (Loc, Chars => New_Internal_Name ('R'));
2858       Rev      : constant Entity_Id :=
2859                    Make_Defining_Identifier
2860                      (Loc, Chars => New_Internal_Name ('D'));
2861       Proc_Name : constant Entity_Id :=
2862                     Make_Defining_Identifier (Loc,
2863                       Chars => Make_TSS_Name (Typ, TSS_Slice_Assign));
2864
2865       Lnn : constant Entity_Id :=
2866               Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
2867       Rnn : constant Entity_Id :=
2868               Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2869       --  Subscripts for left and right sides
2870
2871       Decls : List_Id;
2872       Loops : Node_Id;
2873       Stats : List_Id;
2874
2875    begin
2876       --  Build declarations for indices
2877
2878       Decls := New_List;
2879
2880       Append_To (Decls,
2881          Make_Object_Declaration (Loc,
2882            Defining_Identifier => Lnn,
2883            Object_Definition  =>
2884              New_Occurrence_Of (Index, Loc)));
2885
2886       Append_To (Decls,
2887         Make_Object_Declaration (Loc,
2888           Defining_Identifier => Rnn,
2889           Object_Definition  =>
2890             New_Occurrence_Of (Index, Loc)));
2891
2892       Stats := New_List;
2893
2894       --  Build initializations for indices
2895
2896       declare
2897          F_Init : constant List_Id := New_List;
2898          B_Init : constant List_Id := New_List;
2899
2900       begin
2901          Append_To (F_Init,
2902            Make_Assignment_Statement (Loc,
2903              Name => New_Occurrence_Of (Lnn, Loc),
2904              Expression => New_Occurrence_Of (Left_Lo, Loc)));
2905
2906          Append_To (F_Init,
2907            Make_Assignment_Statement (Loc,
2908              Name => New_Occurrence_Of (Rnn, Loc),
2909              Expression => New_Occurrence_Of (Right_Lo, Loc)));
2910
2911          Append_To (B_Init,
2912            Make_Assignment_Statement (Loc,
2913              Name => New_Occurrence_Of (Lnn, Loc),
2914              Expression => New_Occurrence_Of (Left_Hi, Loc)));
2915
2916          Append_To (B_Init,
2917            Make_Assignment_Statement (Loc,
2918              Name => New_Occurrence_Of (Rnn, Loc),
2919              Expression => New_Occurrence_Of (Right_Hi, Loc)));
2920
2921          Append_To (Stats,
2922            Make_If_Statement (Loc,
2923              Condition => New_Occurrence_Of (Rev, Loc),
2924              Then_Statements => B_Init,
2925              Else_Statements => F_Init));
2926       end;
2927
2928       --  Now construct the assignment statement
2929
2930       Loops :=
2931         Make_Loop_Statement (Loc,
2932           Statements => New_List (
2933             Make_Assignment_Statement (Loc,
2934               Name =>
2935                 Make_Indexed_Component (Loc,
2936                   Prefix => New_Occurrence_Of (Larray, Loc),
2937                   Expressions => New_List (New_Occurrence_Of (Lnn, Loc))),
2938               Expression =>
2939                 Make_Indexed_Component (Loc,
2940                   Prefix => New_Occurrence_Of (Rarray, Loc),
2941                   Expressions => New_List (New_Occurrence_Of (Rnn, Loc))))),
2942           End_Label  => Empty);
2943
2944       --  Build exit condition
2945
2946       declare
2947          F_Ass : constant List_Id := New_List;
2948          B_Ass : constant List_Id := New_List;
2949
2950       begin
2951          Append_To (F_Ass,
2952            Make_Exit_Statement (Loc,
2953              Condition =>
2954                Make_Op_Gt (Loc,
2955                  Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
2956                  Right_Opnd => New_Occurrence_Of (Left_Hi, Loc))));
2957
2958          Append_To (B_Ass,
2959            Make_Exit_Statement (Loc,
2960              Condition =>
2961                Make_Op_Lt (Loc,
2962                  Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
2963                  Right_Opnd => New_Occurrence_Of (Left_Lo, Loc))));
2964
2965          Prepend_To (Statements (Loops),
2966            Make_If_Statement (Loc,
2967              Condition       => New_Occurrence_Of (Rev, Loc),
2968              Then_Statements => B_Ass,
2969              Else_Statements => F_Ass));
2970       end;
2971
2972       --  Build the increment/decrement statements
2973
2974       declare
2975          F_Ass : constant List_Id := New_List;
2976          B_Ass : constant List_Id := New_List;
2977
2978       begin
2979          Append_To (F_Ass,
2980            Make_Assignment_Statement (Loc,
2981              Name => New_Occurrence_Of (Lnn, Loc),
2982              Expression =>
2983                Make_Attribute_Reference (Loc,
2984                  Prefix =>
2985                    New_Occurrence_Of (Index, Loc),
2986                  Attribute_Name => Name_Succ,
2987                  Expressions => New_List (
2988                    New_Occurrence_Of (Lnn, Loc)))));
2989
2990          Append_To (F_Ass,
2991            Make_Assignment_Statement (Loc,
2992              Name => New_Occurrence_Of (Rnn, Loc),
2993              Expression =>
2994                Make_Attribute_Reference (Loc,
2995                  Prefix =>
2996                    New_Occurrence_Of (Index, Loc),
2997                  Attribute_Name => Name_Succ,
2998                  Expressions => New_List (
2999                    New_Occurrence_Of (Rnn, Loc)))));
3000
3001          Append_To (B_Ass,
3002            Make_Assignment_Statement (Loc,
3003              Name => New_Occurrence_Of (Lnn, Loc),
3004              Expression =>
3005                Make_Attribute_Reference (Loc,
3006                  Prefix =>
3007                    New_Occurrence_Of (Index, Loc),
3008                  Attribute_Name => Name_Pred,
3009                    Expressions => New_List (
3010                      New_Occurrence_Of (Lnn, Loc)))));
3011
3012          Append_To (B_Ass,
3013            Make_Assignment_Statement (Loc,
3014              Name => New_Occurrence_Of (Rnn, Loc),
3015              Expression =>
3016                Make_Attribute_Reference (Loc,
3017                  Prefix =>
3018                    New_Occurrence_Of (Index, Loc),
3019                  Attribute_Name => Name_Pred,
3020                  Expressions => New_List (
3021                    New_Occurrence_Of (Rnn, Loc)))));
3022
3023          Append_To (Statements (Loops),
3024            Make_If_Statement (Loc,
3025              Condition => New_Occurrence_Of (Rev, Loc),
3026              Then_Statements => B_Ass,
3027              Else_Statements => F_Ass));
3028       end;
3029
3030       Append_To (Stats, Loops);
3031
3032       declare
3033          Spec    : Node_Id;
3034          Formals : List_Id := New_List;
3035
3036       begin
3037          Formals := New_List (
3038            Make_Parameter_Specification (Loc,
3039              Defining_Identifier => Larray,
3040              Out_Present => True,
3041              Parameter_Type =>
3042                New_Reference_To (Base_Type (Typ), Loc)),
3043
3044            Make_Parameter_Specification (Loc,
3045              Defining_Identifier => Rarray,
3046              Parameter_Type =>
3047                New_Reference_To (Base_Type (Typ), Loc)),
3048
3049            Make_Parameter_Specification (Loc,
3050              Defining_Identifier => Left_Lo,
3051              Parameter_Type =>
3052                New_Reference_To (Index, Loc)),
3053
3054            Make_Parameter_Specification (Loc,
3055              Defining_Identifier => Left_Hi,
3056              Parameter_Type =>
3057                New_Reference_To (Index, Loc)),
3058
3059            Make_Parameter_Specification (Loc,
3060              Defining_Identifier => Right_Lo,
3061              Parameter_Type =>
3062                New_Reference_To (Index, Loc)),
3063
3064            Make_Parameter_Specification (Loc,
3065              Defining_Identifier => Right_Hi,
3066              Parameter_Type =>
3067                New_Reference_To (Index, Loc)));
3068
3069          Append_To (Formals,
3070            Make_Parameter_Specification (Loc,
3071              Defining_Identifier => Rev,
3072              Parameter_Type =>
3073                New_Reference_To (Standard_Boolean, Loc)));
3074
3075          Spec :=
3076            Make_Procedure_Specification (Loc,
3077              Defining_Unit_Name       => Proc_Name,
3078              Parameter_Specifications => Formals);
3079
3080          Discard_Node (
3081            Make_Subprogram_Body (Loc,
3082              Specification              => Spec,
3083              Declarations               => Decls,
3084              Handled_Statement_Sequence =>
3085                Make_Handled_Sequence_Of_Statements (Loc,
3086                  Statements => Stats)));
3087       end;
3088
3089       Set_TSS (Typ, Proc_Name);
3090       Set_Is_Pure (Proc_Name);
3091    end Build_Slice_Assignment;
3092
3093    ------------------------------------
3094    -- Build_Variant_Record_Equality --
3095    ------------------------------------
3096
3097    --  Generates:
3098
3099    --    function _Equality (X, Y : T) return Boolean is
3100    --    begin
3101    --       --  Compare discriminants
3102
3103    --       if False or else X.D1 /= Y.D1 or else X.D2 /= Y.D2 then
3104    --          return False;
3105    --       end if;
3106
3107    --       --  Compare components
3108
3109    --       if False or else X.C1 /= Y.C1 or else X.C2 /= Y.C2 then
3110    --          return False;
3111    --       end if;
3112
3113    --       --  Compare variant part
3114
3115    --       case X.D1 is
3116    --          when V1 =>
3117    --             if False or else X.C2 /= Y.C2 or else X.C3 /= Y.C3 then
3118    --                return False;
3119    --             end if;
3120    --          ...
3121    --          when Vn =>
3122    --             if False or else X.Cn /= Y.Cn then
3123    --                return False;
3124    --             end if;
3125    --       end case;
3126    --       return True;
3127    --    end _Equality;
3128
3129    procedure Build_Variant_Record_Equality (Typ : Entity_Id) is
3130       Loc   : constant Source_Ptr := Sloc (Typ);
3131
3132       F : constant Entity_Id :=
3133             Make_Defining_Identifier (Loc,
3134               Chars => Make_TSS_Name (Typ, TSS_Composite_Equality));
3135
3136       X : constant Entity_Id :=
3137            Make_Defining_Identifier (Loc,
3138              Chars => Name_X);
3139
3140       Y : constant Entity_Id :=
3141             Make_Defining_Identifier (Loc,
3142               Chars => Name_Y);
3143
3144       Def   : constant Node_Id := Parent (Typ);
3145       Comps : constant Node_Id := Component_List (Type_Definition (Def));
3146       Stmts : constant List_Id := New_List;
3147       Pspecs : constant List_Id := New_List;
3148
3149    begin
3150       --  Derived Unchecked_Union types no longer inherit the equality function
3151       --  of their parent.
3152
3153       if Is_Derived_Type (Typ)
3154         and then not Is_Unchecked_Union (Typ)
3155         and then not Has_New_Non_Standard_Rep (Typ)
3156       then
3157          declare
3158             Parent_Eq : constant Entity_Id :=
3159                           TSS (Root_Type (Typ), TSS_Composite_Equality);
3160
3161          begin
3162             if Present (Parent_Eq) then
3163                Copy_TSS (Parent_Eq, Typ);
3164                return;
3165             end if;
3166          end;
3167       end if;
3168
3169       Discard_Node (
3170         Make_Subprogram_Body (Loc,
3171           Specification =>
3172             Make_Function_Specification (Loc,
3173               Defining_Unit_Name       => F,
3174               Parameter_Specifications => Pspecs,
3175               Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
3176           Declarations               => New_List,
3177           Handled_Statement_Sequence =>
3178             Make_Handled_Sequence_Of_Statements (Loc,
3179               Statements => Stmts)));
3180
3181       Append_To (Pspecs,
3182         Make_Parameter_Specification (Loc,
3183           Defining_Identifier => X,
3184           Parameter_Type      => New_Reference_To (Typ, Loc)));
3185
3186       Append_To (Pspecs,
3187         Make_Parameter_Specification (Loc,
3188           Defining_Identifier => Y,
3189           Parameter_Type      => New_Reference_To (Typ, Loc)));
3190
3191       --  Unchecked_Unions require additional machinery to support equality.
3192       --  Two extra parameters (A and B) are added to the equality function
3193       --  parameter list in order to capture the inferred values of the
3194       --  discriminants in later calls.
3195
3196       if Is_Unchecked_Union (Typ) then
3197          declare
3198             Discr_Type : constant Node_Id := Etype (First_Discriminant (Typ));
3199
3200             A : constant Node_Id :=
3201                   Make_Defining_Identifier (Loc,
3202                     Chars => Name_A);
3203
3204             B : constant Node_Id :=
3205                   Make_Defining_Identifier (Loc,
3206                     Chars => Name_B);
3207
3208          begin
3209             --  Add A and B to the parameter list
3210
3211             Append_To (Pspecs,
3212               Make_Parameter_Specification (Loc,
3213                 Defining_Identifier => A,
3214                 Parameter_Type => New_Reference_To (Discr_Type, Loc)));
3215
3216             Append_To (Pspecs,
3217               Make_Parameter_Specification (Loc,
3218                 Defining_Identifier => B,
3219                 Parameter_Type => New_Reference_To (Discr_Type, Loc)));
3220
3221             --  Generate the following header code to compare the inferred
3222             --  discriminants:
3223
3224             --  if a /= b then
3225             --     return False;
3226             --  end if;
3227
3228             Append_To (Stmts,
3229               Make_If_Statement (Loc,
3230                 Condition =>
3231                   Make_Op_Ne (Loc,
3232                     Left_Opnd => New_Reference_To (A, Loc),
3233                     Right_Opnd => New_Reference_To (B, Loc)),
3234                 Then_Statements => New_List (
3235                   Make_Return_Statement (Loc,
3236                     Expression => New_Occurrence_Of (Standard_False, Loc)))));
3237
3238             --  Generate component-by-component comparison. Note that we must
3239             --  propagate one of the inferred discriminant formals to act as
3240             --  the case statement switch.
3241
3242             Append_List_To (Stmts,
3243               Make_Eq_Case (Typ, Comps, A));
3244
3245          end;
3246
3247       --  Normal case (not unchecked union)
3248
3249       else
3250          Append_To (Stmts,
3251            Make_Eq_If (Typ,
3252              Discriminant_Specifications (Def)));
3253
3254          Append_List_To (Stmts,
3255            Make_Eq_Case (Typ, Comps));
3256       end if;
3257
3258       Append_To (Stmts,
3259         Make_Return_Statement (Loc,
3260           Expression => New_Reference_To (Standard_True, Loc)));
3261
3262       Set_TSS (Typ, F);
3263       Set_Is_Pure (F);
3264
3265       if not Debug_Generated_Code then
3266          Set_Debug_Info_Off (F);
3267       end if;
3268    end Build_Variant_Record_Equality;
3269
3270    -----------------------------
3271    -- Check_Stream_Attributes --
3272    -----------------------------
3273
3274    procedure Check_Stream_Attributes (Typ : Entity_Id) is
3275       Comp      : Entity_Id;
3276       Par_Read  : constant Boolean :=
3277                     Stream_Attribute_Available (Typ, TSS_Stream_Read)
3278                       and then not Has_Specified_Stream_Read (Typ);
3279       Par_Write : constant Boolean :=
3280                     Stream_Attribute_Available (Typ, TSS_Stream_Write)
3281                       and then not Has_Specified_Stream_Write (Typ);
3282
3283       procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type);
3284       --  Check that Comp has a user-specified Nam stream attribute
3285
3286       ----------------
3287       -- Check_Attr --
3288       ----------------
3289
3290       procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type) is
3291       begin
3292          if not Stream_Attribute_Available (Etype (Comp), TSS_Nam) then
3293             Error_Msg_Name_1 := Nam;
3294             Error_Msg_N
3295               ("|component& in limited extension must have% attribute", Comp);
3296          end if;
3297       end Check_Attr;
3298
3299    --  Start of processing for Check_Stream_Attributes
3300
3301    begin
3302       if Par_Read or else Par_Write then
3303          Comp := First_Component (Typ);
3304          while Present (Comp) loop
3305             if Comes_From_Source (Comp)
3306               and then Original_Record_Component (Comp) = Comp
3307               and then Is_Limited_Type (Etype (Comp))
3308             then
3309                if Par_Read then
3310                   Check_Attr (Name_Read, TSS_Stream_Read);
3311                end if;
3312
3313                if Par_Write then
3314                   Check_Attr (Name_Write, TSS_Stream_Write);
3315                end if;
3316             end if;
3317
3318             Next_Component (Comp);
3319          end loop;
3320       end if;
3321    end Check_Stream_Attributes;
3322
3323    -----------------------------
3324    -- Expand_Record_Extension --
3325    -----------------------------
3326
3327    --  Add a field _parent at the beginning of the record extension. This is
3328    --  used to implement inheritance. Here are some examples of expansion:
3329
3330    --  1. no discriminants
3331    --      type T2 is new T1 with null record;
3332    --   gives
3333    --      type T2 is new T1 with record
3334    --        _Parent : T1;
3335    --      end record;
3336
3337    --  2. renamed discriminants
3338    --    type T2 (B, C : Int) is new T1 (A => B) with record
3339    --       _Parent : T1 (A => B);
3340    --       D : Int;
3341    --    end;
3342
3343    --  3. inherited discriminants
3344    --    type T2 is new T1 with record -- discriminant A inherited
3345    --       _Parent : T1 (A);
3346    --       D : Int;
3347    --    end;
3348
3349    procedure Expand_Record_Extension (T : Entity_Id; Def : Node_Id) is
3350       Indic        : constant Node_Id    := Subtype_Indication (Def);
3351       Loc          : constant Source_Ptr := Sloc (Def);
3352       Rec_Ext_Part : Node_Id             := Record_Extension_Part (Def);
3353       Par_Subtype  : Entity_Id;
3354       Comp_List    : Node_Id;
3355       Comp_Decl    : Node_Id;
3356       Parent_N     : Node_Id;
3357       D            : Entity_Id;
3358       List_Constr  : constant List_Id    := New_List;
3359
3360    begin
3361       --  Expand_Record_Extension is called directly from the semantics, so
3362       --  we must check to see whether expansion is active before proceeding
3363
3364       if not Expander_Active then
3365          return;
3366       end if;
3367
3368       --  This may be a derivation of an untagged private type whose full
3369       --  view is tagged, in which case the Derived_Type_Definition has no
3370       --  extension part. Build an empty one now.
3371
3372       if No (Rec_Ext_Part) then
3373          Rec_Ext_Part :=
3374            Make_Record_Definition (Loc,
3375              End_Label      => Empty,
3376              Component_List => Empty,
3377              Null_Present   => True);
3378
3379          Set_Record_Extension_Part (Def, Rec_Ext_Part);
3380          Mark_Rewrite_Insertion (Rec_Ext_Part);
3381       end if;
3382
3383       Comp_List := Component_List (Rec_Ext_Part);
3384
3385       Parent_N := Make_Defining_Identifier (Loc, Name_uParent);
3386
3387       --  If the derived type inherits its discriminants the type of the
3388       --  _parent field must be constrained by the inherited discriminants
3389
3390       if Has_Discriminants (T)
3391         and then Nkind (Indic) /= N_Subtype_Indication
3392         and then not Is_Constrained (Entity (Indic))
3393       then
3394          D := First_Discriminant (T);
3395          while Present (D) loop
3396             Append_To (List_Constr, New_Occurrence_Of (D, Loc));
3397             Next_Discriminant (D);
3398          end loop;
3399
3400          Par_Subtype :=
3401            Process_Subtype (
3402              Make_Subtype_Indication (Loc,
3403                Subtype_Mark => New_Reference_To (Entity (Indic), Loc),
3404                Constraint   =>
3405                  Make_Index_Or_Discriminant_Constraint (Loc,
3406                    Constraints => List_Constr)),
3407              Def);
3408
3409       --  Otherwise the original subtype_indication is just what is needed
3410
3411       else
3412          Par_Subtype := Process_Subtype (New_Copy_Tree (Indic), Def);
3413       end if;
3414
3415       Set_Parent_Subtype (T, Par_Subtype);
3416
3417       Comp_Decl :=
3418         Make_Component_Declaration (Loc,
3419           Defining_Identifier => Parent_N,
3420           Component_Definition =>
3421             Make_Component_Definition (Loc,
3422               Aliased_Present => False,
3423               Subtype_Indication => New_Reference_To (Par_Subtype, Loc)));
3424
3425       if Null_Present (Rec_Ext_Part) then
3426          Set_Component_List (Rec_Ext_Part,
3427            Make_Component_List (Loc,
3428              Component_Items => New_List (Comp_Decl),
3429              Variant_Part => Empty,
3430              Null_Present => False));
3431          Set_Null_Present (Rec_Ext_Part, False);
3432
3433       elsif Null_Present (Comp_List)
3434         or else Is_Empty_List (Component_Items (Comp_List))
3435       then
3436          Set_Component_Items (Comp_List, New_List (Comp_Decl));
3437          Set_Null_Present (Comp_List, False);
3438
3439       else
3440          Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
3441       end if;
3442
3443       Analyze (Comp_Decl);
3444    end Expand_Record_Extension;
3445
3446    ------------------------------------
3447    -- Expand_N_Full_Type_Declaration --
3448    ------------------------------------
3449
3450    procedure Expand_N_Full_Type_Declaration (N : Node_Id) is
3451       Def_Id : constant Entity_Id := Defining_Identifier (N);
3452       B_Id   : constant Entity_Id := Base_Type (Def_Id);
3453       Par_Id : Entity_Id;
3454       FN     : Node_Id;
3455
3456    begin
3457       if Is_Access_Type (Def_Id) then
3458
3459          --  Anonymous access types are created for the components of the
3460          --  record parameter for an entry declaration. No master is created
3461          --  for such a type.
3462
3463          if Has_Task (Designated_Type (Def_Id))
3464            and then Comes_From_Source (N)
3465          then
3466             Build_Master_Entity (Def_Id);
3467             Build_Master_Renaming (Parent (Def_Id), Def_Id);
3468
3469          --  Create a class-wide master because a Master_Id must be generated
3470          --  for access-to-limited-class-wide types whose root may be extended
3471          --  with task components, and for access-to-limited-interfaces because
3472          --  they can be used to reference tasks implementing such interface.
3473
3474          elsif Is_Class_Wide_Type (Designated_Type (Def_Id))
3475            and then (Is_Limited_Type (Designated_Type (Def_Id))
3476                        or else
3477                         (Is_Interface (Designated_Type (Def_Id))
3478                            and then
3479                              Is_Limited_Interface (Designated_Type (Def_Id))))
3480            and then Tasking_Allowed
3481
3482             --  Do not create a class-wide master for types whose convention is
3483             --  Java since these types cannot embed Ada tasks anyway. Note that
3484             --  the following test cannot catch the following case:
3485
3486             --      package java.lang.Object is
3487             --         type Typ is tagged limited private;
3488             --         type Ref is access all Typ'Class;
3489             --      private
3490             --         type Typ is tagged limited ...;
3491             --         pragma Convention (Typ, Java)
3492             --      end;
3493
3494             --  Because the convention appears after we have done the
3495             --  processing for type Ref.
3496
3497            and then Convention (Designated_Type (Def_Id)) /= Convention_Java
3498          then
3499             Build_Class_Wide_Master (Def_Id);
3500
3501          elsif Ekind (Def_Id) = E_Access_Protected_Subprogram_Type then
3502             Expand_Access_Protected_Subprogram_Type (N);
3503          end if;
3504
3505       elsif Has_Task (Def_Id) then
3506          Expand_Previous_Access_Type (Def_Id);
3507       end if;
3508
3509       Par_Id := Etype (B_Id);
3510
3511       --  The parent type is private then we need to inherit
3512       --  any TSS operations from the full view.
3513
3514       if Ekind (Par_Id) in Private_Kind
3515         and then Present (Full_View (Par_Id))
3516       then
3517          Par_Id := Base_Type (Full_View (Par_Id));
3518       end if;
3519
3520       if Nkind (Type_Definition (Original_Node (N)))
3521          = N_Derived_Type_Definition
3522         and then not Is_Tagged_Type (Def_Id)
3523         and then Present (Freeze_Node (Par_Id))
3524         and then Present (TSS_Elist (Freeze_Node (Par_Id)))
3525       then
3526          Ensure_Freeze_Node (B_Id);
3527          FN :=  Freeze_Node (B_Id);
3528
3529          if No (TSS_Elist (FN)) then
3530             Set_TSS_Elist (FN, New_Elmt_List);
3531          end if;
3532
3533          declare
3534             T_E   : constant Elist_Id := TSS_Elist (FN);
3535             Elmt  : Elmt_Id;
3536
3537          begin
3538             Elmt  := First_Elmt (TSS_Elist (Freeze_Node (Par_Id)));
3539
3540             while Present (Elmt) loop
3541                if Chars (Node (Elmt)) /= Name_uInit then
3542                   Append_Elmt (Node (Elmt), T_E);
3543                end if;
3544
3545                Next_Elmt (Elmt);
3546             end loop;
3547
3548             --  If the derived type itself is private with a full view, then
3549             --  associate the full view with the inherited TSS_Elist as well.
3550
3551             if Ekind (B_Id) in Private_Kind
3552               and then Present (Full_View (B_Id))
3553             then
3554                Ensure_Freeze_Node (Base_Type (Full_View (B_Id)));
3555                Set_TSS_Elist
3556                  (Freeze_Node (Base_Type (Full_View (B_Id))), TSS_Elist (FN));
3557             end if;
3558          end;
3559       end if;
3560    end Expand_N_Full_Type_Declaration;
3561
3562    ---------------------------------
3563    -- Expand_N_Object_Declaration --
3564    ---------------------------------
3565
3566    --  First we do special processing for objects of a tagged type where this
3567    --  is the point at which the type is frozen. The creation of the dispatch
3568    --  table and the initialization procedure have to be deferred to this
3569    --  point, since we reference previously declared primitive subprograms.
3570
3571    --  For all types, we call an initialization procedure if there is one
3572
3573    procedure Expand_N_Object_Declaration (N : Node_Id) is
3574       Def_Id  : constant Entity_Id  := Defining_Identifier (N);
3575       Typ     : constant Entity_Id  := Etype (Def_Id);
3576       Loc     : constant Source_Ptr := Sloc (N);
3577       Expr    : constant Node_Id    := Expression (N);
3578
3579       New_Ref : Node_Id;
3580       Id_Ref  : Node_Id;
3581       Expr_Q  : Node_Id;
3582
3583    begin
3584       --  Don't do anything for deferred constants. All proper actions will
3585       --  be expanded during the full declaration.
3586
3587       if No (Expr) and Constant_Present (N) then
3588          return;
3589       end if;
3590
3591       --  Make shared memory routines for shared passive variable
3592
3593       if Is_Shared_Passive (Def_Id) then
3594          Make_Shared_Var_Procs (N);
3595       end if;
3596
3597       --  If tasks being declared, make sure we have an activation chain
3598       --  defined for the tasks (has no effect if we already have one), and
3599       --  also that a Master variable is established and that the appropriate
3600       --  enclosing construct is established as a task master.
3601
3602       if Has_Task (Typ) then
3603          Build_Activation_Chain_Entity (N);
3604          Build_Master_Entity (Def_Id);
3605       end if;
3606
3607       --  Default initialization required, and no expression present
3608
3609       if No (Expr) then
3610
3611          --  Expand Initialize call for controlled objects. One may wonder why
3612          --  the Initialize Call is not done in the regular Init procedure
3613          --  attached to the record type. That's because the init procedure is
3614          --  recursively called on each component, including _Parent, thus the
3615          --  Init call for a controlled object would generate not only one
3616          --  Initialize call as it is required but one for each ancestor of
3617          --  its type. This processing is suppressed if No_Initialization set.
3618
3619          if not Controlled_Type (Typ)
3620            or else No_Initialization (N)
3621          then
3622             null;
3623
3624          elsif not Abort_Allowed
3625            or else not Comes_From_Source (N)
3626          then
3627             Insert_Actions_After (N,
3628               Make_Init_Call (
3629                 Ref         => New_Occurrence_Of (Def_Id, Loc),
3630                 Typ         => Base_Type (Typ),
3631                 Flist_Ref   => Find_Final_List (Def_Id),
3632                 With_Attach => Make_Integer_Literal (Loc, 1)));
3633
3634          --  Abort allowed
3635
3636          else
3637             --  We need to protect the initialize call
3638
3639             --  begin
3640             --     Defer_Abort.all;
3641             --     Initialize (...);
3642             --  at end
3643             --     Undefer_Abort.all;
3644             --  end;
3645
3646             --  ??? this won't protect the initialize call for controlled
3647             --  components which are part of the init proc, so this block
3648             --  should probably also contain the call to _init_proc but this
3649             --  requires some code reorganization...
3650
3651             declare
3652                L   : constant List_Id :=
3653                       Make_Init_Call (
3654                         Ref         => New_Occurrence_Of (Def_Id, Loc),
3655                         Typ         => Base_Type (Typ),
3656                         Flist_Ref   => Find_Final_List (Def_Id),
3657                         With_Attach => Make_Integer_Literal (Loc, 1));
3658
3659                Blk : constant Node_Id :=
3660                  Make_Block_Statement (Loc,
3661                    Handled_Statement_Sequence =>
3662                      Make_Handled_Sequence_Of_Statements (Loc, L));
3663
3664             begin
3665                Prepend_To (L, Build_Runtime_Call (Loc, RE_Abort_Defer));
3666                Set_At_End_Proc (Handled_Statement_Sequence (Blk),
3667                  New_Occurrence_Of (RTE (RE_Abort_Undefer_Direct), Loc));
3668                Insert_Actions_After (N, New_List (Blk));
3669                Expand_At_End_Handler
3670                  (Handled_Statement_Sequence (Blk), Entity (Identifier (Blk)));
3671             end;
3672          end if;
3673
3674          --  Call type initialization procedure if there is one. We build the
3675          --  call and put it immediately after the object declaration, so that
3676          --  it will be expanded in the usual manner. Note that this will
3677          --  result in proper handling of defaulted discriminants. The call
3678          --  to the Init_Proc is suppressed if No_Initialization is set.
3679
3680          if Has_Non_Null_Base_Init_Proc (Typ)
3681            and then not No_Initialization (N)
3682          then
3683             --  The call to the initialization procedure does NOT freeze
3684             --  the object being initialized. This is because the call is
3685             --  not a source level call. This works fine, because the only
3686             --  possible statements depending on freeze status that can
3687             --  appear after the _Init call are rep clauses which can
3688             --  safely appear after actual references to the object.
3689
3690             Id_Ref := New_Reference_To (Def_Id, Loc);
3691             Set_Must_Not_Freeze (Id_Ref);
3692             Set_Assignment_OK (Id_Ref);
3693
3694             Insert_Actions_After (N,
3695               Build_Initialization_Call (Loc, Id_Ref, Typ));
3696
3697          --  If simple initialization is required, then set an appropriate
3698          --  simple initialization expression in place. This special
3699          --  initialization is required even though No_Init_Flag is present.
3700
3701          --  An internally generated temporary needs no initialization because
3702          --  it will be assigned subsequently. In particular, there is no
3703          --  point in applying Initialize_Scalars to such a temporary.
3704
3705          elsif Needs_Simple_Initialization (Typ)
3706             and then not Is_Internal (Def_Id)
3707          then
3708             Set_No_Initialization (N, False);
3709             Set_Expression (N, Get_Simple_Init_Val (Typ, Loc, Esize (Def_Id)));
3710             Analyze_And_Resolve (Expression (N), Typ);
3711          end if;
3712
3713          --  Generate attribute for Persistent_BSS if needed
3714
3715          if Persistent_BSS_Mode
3716            and then Comes_From_Source (N)
3717            and then Is_Potentially_Persistent_Type (Typ)
3718            and then Is_Library_Level_Entity (Def_Id)
3719          then
3720             declare
3721                Prag : Node_Id;
3722             begin
3723                Prag :=
3724                  Make_Linker_Section_Pragma
3725                    (Def_Id, Sloc (N), ".persistent.bss");
3726                Insert_After (N, Prag);
3727                Analyze (Prag);
3728             end;
3729          end if;
3730
3731          --  If access type, then we know it is null if not initialized
3732
3733          if Is_Access_Type (Typ) then
3734             Set_Is_Known_Null (Def_Id);
3735          end if;
3736
3737       --  Explicit initialization present
3738
3739       else
3740          --  Obtain actual expression from qualified expression
3741
3742          if Nkind (Expr) = N_Qualified_Expression then
3743             Expr_Q := Expression (Expr);
3744          else
3745             Expr_Q := Expr;
3746          end if;
3747
3748          --  When we have the appropriate type of aggregate in the expression
3749          --  (it has been determined during analysis of the aggregate by
3750          --  setting the delay flag), let's perform in place assignment and
3751          --  thus avoid creating a temporary.
3752
3753          if Is_Delayed_Aggregate (Expr_Q) then
3754             Convert_Aggr_In_Object_Decl (N);
3755
3756          else
3757             --  Ada 2005 (AI-318-02): If the initialization expression is a
3758             --  call to a build-in-place function, then access to the declared
3759             --  object must be passed to the function. Currently we limit such
3760             --  functions to those with constrained limited result subtypes,
3761             --  but eventually we plan to expand the allowed forms of funtions
3762             --  that are treated as build-in-place.
3763
3764             if Ada_Version >= Ada_05
3765               and then Is_Build_In_Place_Function_Call (Expr_Q)
3766             then
3767                Make_Build_In_Place_Call_In_Object_Declaration (N, Expr_Q);
3768             end if;
3769
3770             --  In most cases, we must check that the initial value meets any
3771             --  constraint imposed by the declared type. However, there is one
3772             --  very important exception to this rule. If the entity has an
3773             --  unconstrained nominal subtype, then it acquired its constraints
3774             --  from the expression in the first place, and not only does this
3775             --  mean that the constraint check is not needed, but an attempt to
3776             --  perform the constraint check can cause order order of
3777             --  elaboration problems.
3778
3779             if not Is_Constr_Subt_For_U_Nominal (Typ) then
3780
3781                --  If this is an allocator for an aggregate that has been
3782                --  allocated in place, delay checks until assignments are
3783                --  made, because the discriminants are not initialized.
3784
3785                if Nkind (Expr) = N_Allocator
3786                  and then No_Initialization (Expr)
3787                then
3788                   null;
3789                else
3790                   Apply_Constraint_Check (Expr, Typ);
3791                end if;
3792             end if;
3793
3794             --  If the type is controlled we attach the object to the final
3795             --  list and adjust the target after the copy. This
3796             --  ??? incomplete sentence
3797
3798             --  Ada 2005 (AI-251): Do not register in the final list objects
3799             --  containing class-wide interfaces; otherwise we erroneously
3800             --  register the tag of the interface in the final list. Example:
3801
3802             --    Obj1 : T; --  Controlled object that implements Iface
3803             --    Obj2 : Iface'Class := Iface'Class (Obj1);
3804
3805             --  Obj1 is registered in the final list; Obj2 is not registered.
3806
3807             if Controlled_Type (Typ)
3808               and then not (Is_Interface (Typ)
3809                              and then Is_Class_Wide_Type (Typ))
3810             then
3811                declare
3812                   Flist : Node_Id;
3813                   F     : Entity_Id;
3814
3815                begin
3816                   --  Attach the result to a dummy final list which will never
3817                   --  be finalized if Delay_Finalize_Attachis set. It is
3818                   --  important to attach to a dummy final list rather than not
3819                   --  attaching at all in order to reset the pointers coming
3820                   --  from the initial value. Equivalent code exists in the
3821                   --  sec-stack case in Exp_Ch4.Expand_N_Allocator.
3822
3823                   if Delay_Finalize_Attach (N) then
3824                      F :=
3825                        Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
3826                      Insert_Action (N,
3827                        Make_Object_Declaration (Loc,
3828                          Defining_Identifier => F,
3829                          Object_Definition   =>
3830                            New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
3831
3832                      Flist := New_Reference_To (F, Loc);
3833
3834                   else
3835                      Flist := Find_Final_List (Def_Id);
3836                   end if;
3837
3838                   --  Adjustment is only needed when the controlled type is not
3839                   --  limited.
3840
3841                   if not Is_Limited_Type (Typ) then
3842                      Insert_Actions_After (N,
3843                        Make_Adjust_Call (
3844                          Ref          => New_Reference_To (Def_Id, Loc),
3845                          Typ          => Base_Type (Typ),
3846                          Flist_Ref    => Flist,
3847                          With_Attach  => Make_Integer_Literal (Loc, 1)));
3848                   end if;
3849                end;
3850             end if;
3851
3852             --  For tagged types, when an init value is given, the tag has to
3853             --  be re-initialized separately in order to avoid the propagation
3854             --  of a wrong tag coming from a view conversion unless the type
3855             --  is class wide (in this case the tag comes from the init value).
3856             --  Suppress the tag assignment when Java_VM because JVM tags are
3857             --  represented implicitly in objects. Ditto for types that are
3858             --  CPP_CLASS, and for initializations that are aggregates, because
3859             --  they have to have the right tag.
3860
3861             if Is_Tagged_Type (Typ)
3862               and then not Is_Class_Wide_Type (Typ)
3863               and then not Is_CPP_Class (Typ)
3864               and then not Java_VM
3865               and then Nkind (Expr) /= N_Aggregate
3866             then
3867                --  The re-assignment of the tag has to be done even if the
3868                --  object is a constant.
3869
3870                New_Ref :=
3871                  Make_Selected_Component (Loc,
3872                     Prefix => New_Reference_To (Def_Id, Loc),
3873                     Selector_Name =>
3874                       New_Reference_To (First_Tag_Component (Typ), Loc));
3875
3876                Set_Assignment_OK (New_Ref);
3877
3878                Insert_After (N,
3879                  Make_Assignment_Statement (Loc,
3880                    Name => New_Ref,
3881                    Expression =>
3882                      Unchecked_Convert_To (RTE (RE_Tag),
3883                        New_Reference_To
3884                          (Node
3885                            (First_Elmt
3886                              (Access_Disp_Table (Base_Type (Typ)))),
3887                           Loc))));
3888
3889             --  For discrete types, set the Is_Known_Valid flag if the
3890             --  initializing value is known to be valid.
3891
3892             elsif Is_Discrete_Type (Typ) and then Expr_Known_Valid (Expr) then
3893                Set_Is_Known_Valid (Def_Id);
3894
3895             elsif Is_Access_Type (Typ) then
3896
3897                --  For access types set the Is_Known_Non_Null flag if the
3898                --  initializing value is known to be non-null. We can also set
3899                --  Can_Never_Be_Null if this is a constant.
3900
3901                if Known_Non_Null (Expr) then
3902                   Set_Is_Known_Non_Null (Def_Id, True);
3903
3904                   if Constant_Present (N) then
3905                      Set_Can_Never_Be_Null (Def_Id);
3906                   end if;
3907                end if;
3908             end if;
3909
3910             --  If validity checking on copies, validate initial expression
3911
3912             if Validity_Checks_On
3913                and then Validity_Check_Copies
3914             then
3915                Ensure_Valid (Expr);
3916                Set_Is_Known_Valid (Def_Id);
3917             end if;
3918          end if;
3919
3920          --  Cases where the back end cannot handle the initialization directly
3921          --  In such cases, we expand an assignment that will be appropriately
3922          --  handled by Expand_N_Assignment_Statement.
3923
3924          --  The exclusion of the unconstrained case is wrong, but for now it
3925          --  is too much trouble ???
3926
3927          if (Is_Possibly_Unaligned_Slice (Expr)
3928                or else (Is_Possibly_Unaligned_Object (Expr)
3929                           and then not Represented_As_Scalar (Etype (Expr))))
3930
3931             --  The exclusion of the unconstrained case is wrong, but for now
3932             --  it is too much trouble ???
3933
3934            and then not (Is_Array_Type (Etype (Expr))
3935                            and then not Is_Constrained (Etype (Expr)))
3936          then
3937             declare
3938                Stat : constant Node_Id :=
3939                        Make_Assignment_Statement (Loc,
3940                          Name       => New_Reference_To (Def_Id, Loc),
3941                          Expression => Relocate_Node (Expr));
3942             begin
3943                Set_Expression (N, Empty);
3944                Set_No_Initialization (N);
3945                Set_Assignment_OK (Name (Stat));
3946                Set_No_Ctrl_Actions (Stat);
3947                Insert_After (N, Stat);
3948                Analyze (Stat);
3949             end;
3950          end if;
3951       end if;
3952
3953       --  For array type, check for size too large
3954       --  We really need this for record types too???
3955
3956       if Is_Array_Type (Typ) then
3957          Apply_Array_Size_Check (N, Typ);
3958       end if;
3959
3960    exception
3961       when RE_Not_Available =>
3962          return;
3963    end Expand_N_Object_Declaration;
3964
3965    ---------------------------------
3966    -- Expand_N_Subtype_Indication --
3967    ---------------------------------
3968
3969    --  Add a check on the range of the subtype. The static case is partially
3970    --  duplicated by Process_Range_Expr_In_Decl in Sem_Ch3, but we still need
3971    --  to check here for the static case in order to avoid generating
3972    --  extraneous expanded code. Also deal with validity checking.
3973
3974    procedure Expand_N_Subtype_Indication (N : Node_Id) is
3975       Ran : constant Node_Id   := Range_Expression (Constraint (N));
3976       Typ : constant Entity_Id := Entity (Subtype_Mark (N));
3977
3978    begin
3979       if Nkind (Constraint (N)) = N_Range_Constraint then
3980          Validity_Check_Range (Range_Expression (Constraint (N)));
3981       end if;
3982
3983       if Nkind (Parent (N)) = N_Constrained_Array_Definition
3984            or else
3985          Nkind (Parent (N)) = N_Slice
3986       then
3987          Resolve (Ran, Typ);
3988          Apply_Range_Check (Ran, Typ);
3989       end if;
3990    end Expand_N_Subtype_Indication;
3991
3992    ---------------------------
3993    -- Expand_N_Variant_Part --
3994    ---------------------------
3995
3996    --  If the last variant does not contain the Others choice, replace it with
3997    --  an N_Others_Choice node since Gigi always wants an Others. Note that we
3998    --  do not bother to call Analyze on the modified variant part, since it's
3999    --  only effect would be to compute the contents of the
4000    --  Others_Discrete_Choices node laboriously, and of course we already know
4001    --  the list of choices that corresponds to the others choice (it's the
4002    --  list we are replacing!)
4003
4004    procedure Expand_N_Variant_Part (N : Node_Id) is
4005       Last_Var    : constant Node_Id := Last_Non_Pragma (Variants (N));
4006       Others_Node : Node_Id;
4007    begin
4008       if Nkind (First (Discrete_Choices (Last_Var))) /= N_Others_Choice then
4009          Others_Node := Make_Others_Choice (Sloc (Last_Var));
4010          Set_Others_Discrete_Choices
4011            (Others_Node, Discrete_Choices (Last_Var));
4012          Set_Discrete_Choices (Last_Var, New_List (Others_Node));
4013       end if;
4014    end Expand_N_Variant_Part;
4015
4016    ---------------------------------
4017    -- Expand_Previous_Access_Type --
4018    ---------------------------------
4019
4020    procedure Expand_Previous_Access_Type (Def_Id : Entity_Id) is
4021       T : Entity_Id := First_Entity (Current_Scope);
4022
4023    begin
4024       --  Find all access types declared in the current scope, whose
4025       --  designated type is Def_Id.
4026
4027       while Present (T) loop
4028          if Is_Access_Type (T)
4029            and then Designated_Type (T) = Def_Id
4030          then
4031             Build_Master_Entity (Def_Id);
4032             Build_Master_Renaming (Parent (Def_Id), T);
4033          end if;
4034
4035          Next_Entity (T);
4036       end loop;
4037    end Expand_Previous_Access_Type;
4038
4039    ------------------------------
4040    -- Expand_Record_Controller --
4041    ------------------------------
4042
4043    procedure Expand_Record_Controller (T : Entity_Id) is
4044       Def             : Node_Id := Type_Definition (Parent (T));
4045       Comp_List       : Node_Id;
4046       Comp_Decl       : Node_Id;
4047       Loc             : Source_Ptr;
4048       First_Comp      : Node_Id;
4049       Controller_Type : Entity_Id;
4050       Ent             : Entity_Id;
4051
4052    begin
4053       if Nkind (Def) = N_Derived_Type_Definition then
4054          Def := Record_Extension_Part (Def);
4055       end if;
4056
4057       if Null_Present (Def) then
4058          Set_Component_List (Def,
4059            Make_Component_List (Sloc (Def),
4060              Component_Items => Empty_List,
4061              Variant_Part => Empty,
4062              Null_Present => True));
4063       end if;
4064
4065       Comp_List := Component_List (Def);
4066
4067       if Null_Present (Comp_List)
4068         or else Is_Empty_List (Component_Items (Comp_List))
4069       then
4070          Loc := Sloc (Comp_List);
4071       else
4072          Loc := Sloc (First (Component_Items (Comp_List)));
4073       end if;
4074
4075       if Is_Inherently_Limited_Type (T) then
4076          Controller_Type := RTE (RE_Limited_Record_Controller);
4077       else
4078          Controller_Type := RTE (RE_Record_Controller);
4079       end if;
4080
4081       Ent := Make_Defining_Identifier (Loc, Name_uController);
4082
4083       Comp_Decl :=
4084         Make_Component_Declaration (Loc,
4085           Defining_Identifier =>  Ent,
4086           Component_Definition =>
4087             Make_Component_Definition (Loc,
4088               Aliased_Present => False,
4089               Subtype_Indication => New_Reference_To (Controller_Type, Loc)));
4090
4091       if Null_Present (Comp_List)
4092         or else Is_Empty_List (Component_Items (Comp_List))
4093       then
4094          Set_Component_Items (Comp_List, New_List (Comp_Decl));
4095          Set_Null_Present (Comp_List, False);
4096
4097       else
4098          --  The controller cannot be placed before the _Parent field since
4099          --  gigi lays out field in order and _parent must be first to
4100          --  preserve the polymorphism of tagged types.
4101
4102          First_Comp := First (Component_Items (Comp_List));
4103
4104          if not Is_Tagged_Type (T) then
4105             Insert_Before (First_Comp, Comp_Decl);
4106
4107          --  if T is a tagged type, place controller declaration after
4108          --  parent field and after eventual tags of implemented
4109          --  interfaces, if present.
4110
4111          else
4112             while Present (First_Comp)
4113               and then
4114                 (Chars (Defining_Identifier (First_Comp)) = Name_uParent
4115                    or else Is_Tag (Defining_Identifier (First_Comp)))
4116             loop
4117                Next (First_Comp);
4118             end loop;
4119
4120             --  An empty tagged extension might consist only of the parent
4121             --  component. Otherwise insert the controller before the first
4122             --  component that is neither parent nor tag.
4123
4124             if Present (First_Comp) then
4125                Insert_Before (First_Comp, Comp_Decl);
4126             else
4127                Append (Comp_Decl, Component_Items (Comp_List));
4128             end if;
4129          end if;
4130       end if;
4131
4132       New_Scope (T);
4133       Analyze (Comp_Decl);
4134       Set_Ekind (Ent, E_Component);
4135       Init_Component_Location (Ent);
4136
4137       --  Move the _controller entity ahead in the list of internal entities
4138       --  of the enclosing record so that it is selected instead of a
4139       --  potentially inherited one.
4140
4141       declare
4142          E    : constant Entity_Id := Last_Entity (T);
4143          Comp : Entity_Id;
4144
4145       begin
4146          pragma Assert (Chars (E) = Name_uController);
4147
4148          Set_Next_Entity (E, First_Entity (T));
4149          Set_First_Entity (T, E);
4150
4151          Comp := Next_Entity (E);
4152          while Next_Entity (Comp) /= E loop
4153             Next_Entity (Comp);
4154          end loop;
4155
4156          Set_Next_Entity (Comp, Empty);
4157          Set_Last_Entity (T, Comp);
4158       end;
4159
4160       End_Scope;
4161
4162    exception
4163       when RE_Not_Available =>
4164          return;
4165    end Expand_Record_Controller;
4166
4167    ------------------------
4168    -- Expand_Tagged_Root --
4169    ------------------------
4170
4171    procedure Expand_Tagged_Root (T : Entity_Id) is
4172       Def       : constant Node_Id := Type_Definition (Parent (T));
4173       Comp_List : Node_Id;
4174       Comp_Decl : Node_Id;
4175       Sloc_N    : Source_Ptr;
4176
4177    begin
4178       if Null_Present (Def) then
4179          Set_Component_List (Def,
4180            Make_Component_List (Sloc (Def),
4181              Component_Items => Empty_List,
4182              Variant_Part => Empty,
4183              Null_Present => True));
4184       end if;
4185
4186       Comp_List := Component_List (Def);
4187
4188       if Null_Present (Comp_List)
4189         or else Is_Empty_List (Component_Items (Comp_List))
4190       then
4191          Sloc_N := Sloc (Comp_List);
4192       else
4193          Sloc_N := Sloc (First (Component_Items (Comp_List)));
4194       end if;
4195
4196       Comp_Decl :=
4197         Make_Component_Declaration (Sloc_N,
4198           Defining_Identifier => First_Tag_Component (T),
4199           Component_Definition =>
4200             Make_Component_Definition (Sloc_N,
4201               Aliased_Present => False,
4202               Subtype_Indication => New_Reference_To (RTE (RE_Tag), Sloc_N)));
4203
4204       if Null_Present (Comp_List)
4205         or else Is_Empty_List (Component_Items (Comp_List))
4206       then
4207          Set_Component_Items (Comp_List, New_List (Comp_Decl));
4208          Set_Null_Present (Comp_List, False);
4209
4210       else
4211          Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
4212       end if;
4213
4214       --  We don't Analyze the whole expansion because the tag component has
4215       --  already been analyzed previously. Here we just insure that the tree
4216       --  is coherent with the semantic decoration
4217
4218       Find_Type (Subtype_Indication (Component_Definition (Comp_Decl)));
4219
4220    exception
4221       when RE_Not_Available =>
4222          return;
4223    end Expand_Tagged_Root;
4224
4225    ----------------------
4226    -- Clean_Task_Names --
4227    ----------------------
4228
4229    procedure Clean_Task_Names
4230      (Typ     : Entity_Id;
4231       Proc_Id : Entity_Id)
4232    is
4233    begin
4234       if Has_Task (Typ)
4235         and then not Restriction_Active (No_Implicit_Heap_Allocations)
4236         and then not Global_Discard_Names
4237       then
4238          Set_Uses_Sec_Stack (Proc_Id);
4239       end if;
4240    end Clean_Task_Names;
4241
4242    -----------------------
4243    -- Freeze_Array_Type --
4244    -----------------------
4245
4246    procedure Freeze_Array_Type (N : Node_Id) is
4247       Typ  : constant Entity_Id  := Entity (N);
4248       Base : constant Entity_Id  := Base_Type (Typ);
4249
4250    begin
4251       if not Is_Bit_Packed_Array (Typ) then
4252
4253          --  If the component contains tasks, so does the array type. This may
4254          --  not be indicated in the array type because the component may have
4255          --  been a private type at the point of definition. Same if component
4256          --  type is controlled.
4257
4258          Set_Has_Task (Base, Has_Task (Component_Type (Typ)));
4259          Set_Has_Controlled_Component (Base,
4260            Has_Controlled_Component (Component_Type (Typ))
4261              or else Is_Controlled (Component_Type (Typ)));
4262
4263          if No (Init_Proc (Base)) then
4264
4265             --  If this is an anonymous array created for a declaration with
4266             --  an initial value, its init_proc will never be called. The
4267             --  initial value itself may have been expanded into assign-
4268             --  ments, in which case the object declaration is carries the
4269             --  No_Initialization flag.
4270
4271             if Is_Itype (Base)
4272               and then Nkind (Associated_Node_For_Itype (Base)) =
4273                                                     N_Object_Declaration
4274               and then (Present (Expression (Associated_Node_For_Itype (Base)))
4275                           or else
4276                         No_Initialization (Associated_Node_For_Itype (Base)))
4277             then
4278                null;
4279
4280             --  We do not need an init proc for string or wide [wide] string,
4281             --  since the only time these need initialization in normalize or
4282             --  initialize scalars mode, and these types are treated specially
4283             --  and do not need initialization procedures.
4284
4285             elsif Root_Type (Base) = Standard_String
4286               or else Root_Type (Base) = Standard_Wide_String
4287               or else Root_Type (Base) = Standard_Wide_Wide_String
4288             then
4289                null;
4290
4291             --  Otherwise we have to build an init proc for the subtype
4292
4293             else
4294                Build_Array_Init_Proc (Base, N);
4295             end if;
4296          end if;
4297
4298          if Typ = Base and then Has_Controlled_Component (Base) then
4299             Build_Controlling_Procs (Base);
4300
4301             if not Is_Limited_Type (Component_Type (Typ))
4302               and then Number_Dimensions (Typ) = 1
4303             then
4304                Build_Slice_Assignment (Typ);
4305             end if;
4306          end if;
4307
4308       --  For packed case, there is a default initialization, except if the
4309       --  component type is itself a packed structure with an initialization
4310       --  procedure.
4311
4312       elsif Present (Init_Proc (Component_Type (Base)))
4313         and then No (Base_Init_Proc (Base))
4314       then
4315          Build_Array_Init_Proc (Base, N);
4316       end if;
4317    end Freeze_Array_Type;
4318
4319    -----------------------------
4320    -- Freeze_Enumeration_Type --
4321    -----------------------------
4322
4323    procedure Freeze_Enumeration_Type (N : Node_Id) is
4324       Typ           : constant Entity_Id  := Entity (N);
4325       Loc           : constant Source_Ptr := Sloc (Typ);
4326       Ent           : Entity_Id;
4327       Lst           : List_Id;
4328       Num           : Nat;
4329       Arr           : Entity_Id;
4330       Fent          : Entity_Id;
4331       Ityp          : Entity_Id;
4332       Is_Contiguous : Boolean;
4333       Pos_Expr      : Node_Id;
4334       Last_Repval   : Uint;
4335
4336       Func : Entity_Id;
4337       pragma Warnings (Off, Func);
4338
4339    begin
4340       --  Various optimization are possible if the given representation is
4341       --  contiguous.
4342
4343       Is_Contiguous := True;
4344       Ent := First_Literal (Typ);
4345       Last_Repval := Enumeration_Rep (Ent);
4346       Next_Literal (Ent);
4347
4348       while Present (Ent) loop
4349          if Enumeration_Rep (Ent) - Last_Repval /= 1 then
4350             Is_Contiguous := False;
4351             exit;
4352          else
4353             Last_Repval := Enumeration_Rep (Ent);
4354          end if;
4355
4356          Next_Literal (Ent);
4357       end loop;
4358
4359       if Is_Contiguous then
4360          Set_Has_Contiguous_Rep (Typ);
4361          Ent := First_Literal (Typ);
4362          Num := 1;
4363          Lst := New_List (New_Reference_To (Ent, Sloc (Ent)));
4364
4365       else
4366          --  Build list of literal references
4367
4368          Lst := New_List;
4369          Num := 0;
4370
4371          Ent := First_Literal (Typ);
4372          while Present (Ent) loop
4373             Append_To (Lst, New_Reference_To (Ent, Sloc (Ent)));
4374             Num := Num + 1;
4375             Next_Literal (Ent);
4376          end loop;
4377       end if;
4378
4379       --  Now build an array declaration
4380
4381       --    typA : array (Natural range 0 .. num - 1) of ctype :=
4382       --             (v, v, v, v, v, ....)
4383
4384       --  where ctype is the corresponding integer type. If the representation
4385       --  is contiguous, we only keep the first literal, which provides the
4386       --  offset for Pos_To_Rep computations.
4387
4388       Arr :=
4389         Make_Defining_Identifier (Loc,
4390           Chars => New_External_Name (Chars (Typ), 'A'));
4391
4392       Append_Freeze_Action (Typ,
4393         Make_Object_Declaration (Loc,
4394           Defining_Identifier => Arr,
4395           Constant_Present    => True,
4396
4397           Object_Definition   =>
4398             Make_Constrained_Array_Definition (Loc,
4399               Discrete_Subtype_Definitions => New_List (
4400                 Make_Subtype_Indication (Loc,
4401                   Subtype_Mark => New_Reference_To (Standard_Natural, Loc),
4402                   Constraint =>
4403                     Make_Range_Constraint (Loc,
4404                       Range_Expression =>
4405                         Make_Range (Loc,
4406                           Low_Bound  =>
4407                             Make_Integer_Literal (Loc, 0),
4408                           High_Bound =>
4409                             Make_Integer_Literal (Loc, Num - 1))))),
4410
4411               Component_Definition =>
4412                 Make_Component_Definition (Loc,
4413                   Aliased_Present => False,
4414                   Subtype_Indication => New_Reference_To (Typ, Loc))),
4415
4416           Expression =>
4417             Make_Aggregate (Loc,
4418               Expressions => Lst)));
4419
4420       Set_Enum_Pos_To_Rep (Typ, Arr);
4421
4422       --  Now we build the function that converts representation values to
4423       --  position values. This function has the form:
4424
4425       --    function _Rep_To_Pos (A : etype; F : Boolean) return Integer is
4426       --    begin
4427       --       case ityp!(A) is
4428       --         when enum-lit'Enum_Rep => return posval;
4429       --         when enum-lit'Enum_Rep => return posval;
4430       --         ...
4431       --         when others   =>
4432       --           [raise Constraint_Error when F "invalid data"]
4433       --           return -1;
4434       --       end case;
4435       --    end;
4436
4437       --  Note: the F parameter determines whether the others case (no valid
4438       --  representation) raises Constraint_Error or returns a unique value
4439       --  of minus one. The latter case is used, e.g. in 'Valid code.
4440
4441       --  Note: the reason we use Enum_Rep values in the case here is to avoid
4442       --  the code generator making inappropriate assumptions about the range
4443       --  of the values in the case where the value is invalid. ityp is a
4444       --  signed or unsigned integer type of appropriate width.
4445
4446       --  Note: if exceptions are not supported, then we suppress the raise
4447       --  and return -1 unconditionally (this is an erroneous program in any
4448       --  case and there is no obligation to raise Constraint_Error here!) We
4449       --  also do this if pragma Restrictions (No_Exceptions) is active.
4450
4451       --  Representations are signed
4452
4453       if Enumeration_Rep (First_Literal (Typ)) < 0 then
4454
4455          --  The underlying type is signed. Reset the Is_Unsigned_Type
4456          --  explicitly, because it might have been inherited from
4457          --  parent type.
4458
4459          Set_Is_Unsigned_Type (Typ, False);
4460
4461          if Esize (Typ) <= Standard_Integer_Size then
4462             Ityp := Standard_Integer;
4463          else
4464             Ityp := Universal_Integer;
4465          end if;
4466
4467       --  Representations are unsigned
4468
4469       else
4470          if Esize (Typ) <= Standard_Integer_Size then
4471             Ityp := RTE (RE_Unsigned);
4472          else
4473             Ityp := RTE (RE_Long_Long_Unsigned);
4474          end if;
4475       end if;
4476
4477       --  The body of the function is a case statement. First collect case
4478       --  alternatives, or optimize the contiguous case.
4479
4480       Lst := New_List;
4481
4482       --  If representation is contiguous, Pos is computed by subtracting
4483       --  the representation of the first literal.
4484
4485       if Is_Contiguous then
4486          Ent := First_Literal (Typ);
4487
4488          if Enumeration_Rep (Ent) = Last_Repval then
4489
4490             --  Another special case: for a single literal, Pos is zero
4491
4492             Pos_Expr := Make_Integer_Literal (Loc, Uint_0);
4493
4494          else
4495             Pos_Expr :=
4496               Convert_To (Standard_Integer,
4497                 Make_Op_Subtract (Loc,
4498                   Left_Opnd =>
4499                      Unchecked_Convert_To (Ityp,
4500                        Make_Identifier (Loc, Name_uA)),
4501                    Right_Opnd =>
4502                      Make_Integer_Literal (Loc,
4503                         Intval =>
4504                           Enumeration_Rep (First_Literal (Typ)))));
4505          end if;
4506
4507          Append_To (Lst,
4508               Make_Case_Statement_Alternative (Loc,
4509                 Discrete_Choices => New_List (
4510                   Make_Range (Sloc (Enumeration_Rep_Expr (Ent)),
4511                     Low_Bound =>
4512                       Make_Integer_Literal (Loc,
4513                        Intval =>  Enumeration_Rep (Ent)),
4514                     High_Bound =>
4515                       Make_Integer_Literal (Loc, Intval => Last_Repval))),
4516
4517                 Statements => New_List (
4518                   Make_Return_Statement (Loc,
4519                     Expression => Pos_Expr))));
4520
4521       else
4522          Ent := First_Literal (Typ);
4523
4524          while Present (Ent) loop
4525             Append_To (Lst,
4526               Make_Case_Statement_Alternative (Loc,
4527                 Discrete_Choices => New_List (
4528                   Make_Integer_Literal (Sloc (Enumeration_Rep_Expr (Ent)),
4529                     Intval => Enumeration_Rep (Ent))),
4530
4531                 Statements => New_List (
4532                   Make_Return_Statement (Loc,
4533                     Expression =>
4534                       Make_Integer_Literal (Loc,
4535                         Intval => Enumeration_Pos (Ent))))));
4536
4537             Next_Literal (Ent);
4538          end loop;
4539       end if;
4540
4541       --  In normal mode, add the others clause with the test
4542
4543       if not Restriction_Active (No_Exception_Handlers) then
4544          Append_To (Lst,
4545            Make_Case_Statement_Alternative (Loc,
4546              Discrete_Choices => New_List (Make_Others_Choice (Loc)),
4547              Statements => New_List (
4548                Make_Raise_Constraint_Error (Loc,
4549                  Condition => Make_Identifier (Loc, Name_uF),
4550                  Reason    => CE_Invalid_Data),
4551                Make_Return_Statement (Loc,
4552                  Expression =>
4553                    Make_Integer_Literal (Loc, -1)))));
4554
4555       --  If Restriction (No_Exceptions_Handlers) is active then we always
4556       --  return -1 (since we cannot usefully raise Constraint_Error in
4557       --  this case). See description above for further details.
4558
4559       else
4560          Append_To (Lst,
4561            Make_Case_Statement_Alternative (Loc,
4562              Discrete_Choices => New_List (Make_Others_Choice (Loc)),
4563              Statements => New_List (
4564                Make_Return_Statement (Loc,
4565                  Expression =>
4566                    Make_Integer_Literal (Loc, -1)))));
4567       end if;
4568
4569       --  Now we can build the function body
4570
4571       Fent :=
4572         Make_Defining_Identifier (Loc, Make_TSS_Name (Typ, TSS_Rep_To_Pos));
4573
4574       Func :=
4575         Make_Subprogram_Body (Loc,
4576           Specification =>
4577             Make_Function_Specification (Loc,
4578               Defining_Unit_Name       => Fent,
4579               Parameter_Specifications => New_List (
4580                 Make_Parameter_Specification (Loc,
4581                   Defining_Identifier =>
4582                     Make_Defining_Identifier (Loc, Name_uA),
4583                   Parameter_Type => New_Reference_To (Typ, Loc)),
4584                 Make_Parameter_Specification (Loc,
4585                   Defining_Identifier =>
4586                     Make_Defining_Identifier (Loc, Name_uF),
4587                   Parameter_Type => New_Reference_To (Standard_Boolean, Loc))),
4588
4589               Result_Definition => New_Reference_To (Standard_Integer, Loc)),
4590
4591             Declarations => Empty_List,
4592
4593             Handled_Statement_Sequence =>
4594               Make_Handled_Sequence_Of_Statements (Loc,
4595                 Statements => New_List (
4596                   Make_Case_Statement (Loc,
4597                     Expression =>
4598                       Unchecked_Convert_To (Ityp,
4599                         Make_Identifier (Loc, Name_uA)),
4600                     Alternatives => Lst))));
4601
4602       Set_TSS (Typ, Fent);
4603       Set_Is_Pure (Fent);
4604
4605       if not Debug_Generated_Code then
4606          Set_Debug_Info_Off (Fent);
4607       end if;
4608
4609    exception
4610       when RE_Not_Available =>
4611          return;
4612    end Freeze_Enumeration_Type;
4613
4614    ------------------------
4615    -- Freeze_Record_Type --
4616    ------------------------
4617
4618    procedure Freeze_Record_Type (N : Node_Id) is
4619       Comp        : Entity_Id;
4620       Def_Id      : constant Node_Id := Entity (N);
4621       Predef_List : List_Id;
4622       Type_Decl   : constant Node_Id := Parent (Def_Id);
4623
4624       Renamed_Eq  : Node_Id := Empty;
4625       --  Could use some comments ???
4626
4627       Wrapper_Decl_List   : List_Id := No_List;
4628       Wrapper_Body_List   : List_Id := No_List;
4629       Null_Proc_Decl_List : List_Id := No_List;
4630
4631    begin
4632       --  Build discriminant checking functions if not a derived type (for
4633       --  derived types that are not tagged types, we always use the
4634       --  discriminant checking functions of the parent type). However, for
4635       --  untagged types the derivation may have taken place before the
4636       --  parent was frozen, so we copy explicitly the discriminant checking
4637       --  functions from the parent into the components of the derived type.
4638
4639       if not Is_Derived_Type (Def_Id)
4640         or else Has_New_Non_Standard_Rep (Def_Id)
4641         or else Is_Tagged_Type (Def_Id)
4642       then
4643          Build_Discr_Checking_Funcs (Type_Decl);
4644
4645       elsif Is_Derived_Type (Def_Id)
4646         and then not Is_Tagged_Type (Def_Id)
4647
4648          --  If we have a derived Unchecked_Union, we do not inherit the
4649          --  discriminant checking functions from the parent type since the
4650          --  discriminants are non existent.
4651
4652         and then not Is_Unchecked_Union (Def_Id)
4653         and then Has_Discriminants (Def_Id)
4654       then
4655          declare
4656             Old_Comp : Entity_Id;
4657
4658          begin
4659             Old_Comp :=
4660               First_Component (Base_Type (Underlying_Type (Etype (Def_Id))));
4661             Comp := First_Component (Def_Id);
4662             while Present (Comp) loop
4663                if Ekind (Comp) = E_Component
4664                  and then Chars (Comp) = Chars (Old_Comp)
4665                then
4666                   Set_Discriminant_Checking_Func (Comp,
4667                      Discriminant_Checking_Func (Old_Comp));
4668                end if;
4669
4670                Next_Component (Old_Comp);
4671                Next_Component (Comp);
4672             end loop;
4673          end;
4674       end if;
4675
4676       if Is_Derived_Type (Def_Id)
4677         and then Is_Limited_Type (Def_Id)
4678         and then Is_Tagged_Type (Def_Id)
4679       then
4680          Check_Stream_Attributes (Def_Id);
4681       end if;
4682
4683       --  Update task and controlled component flags, because some of the
4684       --  component types may have been private at the point of the record
4685       --  declaration.
4686
4687       Comp := First_Component (Def_Id);
4688
4689       while Present (Comp) loop
4690          if Has_Task (Etype (Comp)) then
4691             Set_Has_Task (Def_Id);
4692
4693          elsif Has_Controlled_Component (Etype (Comp))
4694            or else (Chars (Comp) /= Name_uParent
4695                      and then Is_Controlled (Etype (Comp)))
4696          then
4697             Set_Has_Controlled_Component (Def_Id);
4698          end if;
4699
4700          Next_Component (Comp);
4701       end loop;
4702
4703       --  Creation of the Dispatch Table. Note that a Dispatch Table is
4704       --  created for regular tagged types as well as for Ada types deriving
4705       --  from a C++ Class, but not for tagged types directly corresponding to
4706       --  the C++ classes. In the later case we assume that the Vtable is
4707       --  created in the C++ side and we just use it.
4708
4709       if Is_Tagged_Type (Def_Id) then
4710
4711          if Is_CPP_Class (Def_Id) then
4712
4713             --  Because of the new C++ ABI compatibility we now allow the
4714             --  programer to use the Ada tag (and in this case we must do
4715             --  the normal expansion of the tag)
4716
4717             if Etype (First_Component (Def_Id)) = RTE (RE_Tag)
4718               and then Underlying_Type (Etype (Def_Id)) = Def_Id
4719             then
4720                Expand_Tagged_Root (Def_Id);
4721             end if;
4722
4723             Set_All_DT_Position (Def_Id);
4724             Set_Default_Constructor (Def_Id);
4725
4726          else
4727             --  Usually inherited primitives are not delayed but the first Ada
4728             --  extension of a CPP_Class is an exception since the address of
4729             --  the inherited subprogram has to be inserted in the new Ada
4730             --  Dispatch Table and this is a freezing action (usually the
4731             --  inherited primitive address is inserted in the DT by
4732             --  Inherit_DT)
4733
4734             --  Similarly, if this is an inherited operation whose parent is
4735             --  not frozen yet, it is not in the DT of the parent, and we
4736             --  generate an explicit freeze node for the inherited operation,
4737             --  so that it is properly inserted in the DT of the current type.
4738
4739             declare
4740                Elmt : Elmt_Id := First_Elmt (Primitive_Operations (Def_Id));
4741                Subp : Entity_Id;
4742
4743             begin
4744                while Present (Elmt) loop
4745                   Subp := Node (Elmt);
4746
4747                   if Present (Alias (Subp)) then
4748                      if Is_CPP_Class (Etype (Def_Id)) then
4749                         Set_Has_Delayed_Freeze (Subp);
4750
4751                      elsif Has_Delayed_Freeze (Alias (Subp))
4752                        and then not Is_Frozen (Alias (Subp))
4753                      then
4754                         Set_Is_Frozen (Subp, False);
4755                         Set_Has_Delayed_Freeze (Subp);
4756                      end if;
4757                   end if;
4758
4759                   Next_Elmt (Elmt);
4760                end loop;
4761             end;
4762
4763             if Underlying_Type (Etype (Def_Id)) = Def_Id then
4764                Expand_Tagged_Root (Def_Id);
4765             end if;
4766
4767             --  Unfreeze momentarily the type to add the predefined primitives
4768             --  operations. The reason we unfreeze is so that these predefined
4769             --  operations will indeed end up as primitive operations (which
4770             --  must be before the freeze point).
4771
4772             Set_Is_Frozen (Def_Id, False);
4773             Make_Predefined_Primitive_Specs
4774               (Def_Id, Predef_List, Renamed_Eq);
4775             Insert_List_Before_And_Analyze (N, Predef_List);
4776
4777             --  Ada 2005 (AI-391): For a nonabstract null extension, create
4778             --  wrapper functions for each nonoverridden inherited function
4779             --  with a controlling result of the type. The wrapper for such
4780             --  a function returns an extension aggregate that invokes the
4781             --  the parent function.
4782
4783             if Ada_Version >= Ada_05
4784               and then not Is_Abstract (Def_Id)
4785               and then Is_Null_Extension (Def_Id)
4786             then
4787                Make_Controlling_Function_Wrappers
4788                  (Def_Id, Wrapper_Decl_List, Wrapper_Body_List);
4789                Insert_List_Before_And_Analyze (N, Wrapper_Decl_List);
4790             end if;
4791
4792             --  Ada 2005 (AI-251): For a nonabstract type extension, build
4793             --  null procedure declarations for each set of homographic null
4794             --  procedures that are inherited from interface types but not
4795             --  overridden. This is done to ensure that the dispatch table
4796             --  entry associated with such null primitives are properly filled.
4797
4798             if Ada_Version >= Ada_05
4799               and then Etype (Def_Id) /= Def_Id
4800               and then not Is_Abstract (Def_Id)
4801             then
4802                Make_Null_Procedure_Specs (Def_Id, Null_Proc_Decl_List);
4803                Insert_Actions (N, Null_Proc_Decl_List);
4804             end if;
4805
4806             Set_Is_Frozen (Def_Id, True);
4807             Set_All_DT_Position (Def_Id);
4808
4809             --  Add the controlled component before the freezing actions
4810             --  referenced in those actions.
4811
4812             if Has_New_Controlled_Component (Def_Id) then
4813                Expand_Record_Controller (Def_Id);
4814             end if;
4815
4816             --  Suppress creation of a dispatch table when Java_VM because the
4817             --  dispatching mechanism is handled internally by the JVM.
4818
4819             if not Java_VM then
4820
4821                --  Ada 2005 (AI-251): Build the secondary dispatch tables
4822
4823                declare
4824                   ADT : Elist_Id := Access_Disp_Table (Def_Id);
4825
4826                   procedure Add_Secondary_Tables (Typ : Entity_Id);
4827                   --  Internal subprogram, recursively climb to the ancestors
4828
4829                   --------------------------
4830                   -- Add_Secondary_Tables --
4831                   --------------------------
4832
4833                   procedure Add_Secondary_Tables (Typ : Entity_Id) is
4834                      E            : Entity_Id;
4835                      Iface        : Elmt_Id;
4836                      Result       : List_Id;
4837                      Suffix_Index : Int;
4838
4839                   begin
4840                      --  Climb to the ancestor (if any) handling private types
4841
4842                      if Present (Full_View (Etype (Typ))) then
4843                         if Full_View (Etype (Typ)) /= Typ then
4844                            Add_Secondary_Tables (Full_View (Etype (Typ)));
4845                         end if;
4846
4847                      elsif Etype (Typ) /= Typ then
4848                         Add_Secondary_Tables (Etype (Typ));
4849                      end if;
4850
4851                      if Present (Abstract_Interfaces (Typ))
4852                        and then
4853                          not Is_Empty_Elmt_List (Abstract_Interfaces (Typ))
4854                      then
4855                         Iface := First_Elmt (Abstract_Interfaces (Typ));
4856                         Suffix_Index := 0;
4857
4858                         E := First_Entity (Typ);
4859                         while Present (E) loop
4860                            if Is_Tag (E) and then Chars (E) /= Name_uTag then
4861                               Make_Secondary_DT
4862                                 (Typ             => Def_Id,
4863                                  Ancestor_Typ    => Typ,
4864                                  Suffix_Index    => Suffix_Index,
4865                                  Iface           => Node (Iface),
4866                                  AI_Tag          => E,
4867                                  Acc_Disp_Tables => ADT,
4868                                  Result          => Result);
4869
4870                               Append_Freeze_Actions (Def_Id, Result);
4871                               Suffix_Index := Suffix_Index + 1;
4872                               Next_Elmt (Iface);
4873                            end if;
4874
4875                            Next_Entity (E);
4876                         end loop;
4877                      end if;
4878                   end Add_Secondary_Tables;
4879
4880                --  Start of processing to build secondary dispatch tables
4881
4882                begin
4883                   --  Handle private types
4884
4885                   if Present (Full_View (Def_Id)) then
4886                      Add_Secondary_Tables (Full_View (Def_Id));
4887                   else
4888                      Add_Secondary_Tables (Def_Id);
4889                   end if;
4890
4891                   Set_Access_Disp_Table (Def_Id, ADT);
4892                   Append_Freeze_Actions (Def_Id, Make_DT (Def_Id));
4893                end;
4894             end if;
4895
4896             --  Make sure that the primitives Initialize, Adjust and Finalize
4897             --  are Frozen before other TSS subprograms. We don't want them
4898             --  Frozen inside.
4899
4900             if Is_Controlled (Def_Id) then
4901                if not Is_Limited_Type (Def_Id) then
4902                   Append_Freeze_Actions (Def_Id,
4903                     Freeze_Entity
4904                       (Find_Prim_Op (Def_Id, Name_Adjust), Sloc (Def_Id)));
4905                end if;
4906
4907                Append_Freeze_Actions (Def_Id,
4908                  Freeze_Entity
4909                    (Find_Prim_Op (Def_Id, Name_Initialize), Sloc (Def_Id)));
4910
4911                Append_Freeze_Actions (Def_Id,
4912                  Freeze_Entity
4913                    (Find_Prim_Op (Def_Id, Name_Finalize), Sloc (Def_Id)));
4914             end if;
4915
4916             --  Freeze rest of primitive operations
4917
4918             Append_Freeze_Actions
4919               (Def_Id, Predefined_Primitive_Freeze (Def_Id));
4920             Append_Freeze_Actions
4921               (Def_Id, Init_Predefined_Interface_Primitives (Def_Id));
4922          end if;
4923
4924       --  In the non-tagged case, an equality function is provided only for
4925       --  variant records (that are not unchecked unions).
4926
4927       elsif Has_Discriminants (Def_Id)
4928         and then not Is_Limited_Type (Def_Id)
4929       then
4930          declare
4931             Comps : constant Node_Id :=
4932                       Component_List (Type_Definition (Type_Decl));
4933
4934          begin
4935             if Present (Comps)
4936               and then Present (Variant_Part (Comps))
4937             then
4938                Build_Variant_Record_Equality (Def_Id);
4939             end if;
4940          end;
4941       end if;
4942
4943       --  Before building the record initialization procedure, if we are
4944       --  dealing with a concurrent record value type, then we must go through
4945       --  the discriminants, exchanging discriminals between the concurrent
4946       --  type and the concurrent record value type. See the section "Handling
4947       --  of Discriminants" in the Einfo spec for details.
4948
4949       if Is_Concurrent_Record_Type (Def_Id)
4950         and then Has_Discriminants (Def_Id)
4951       then
4952          declare
4953             Ctyp : constant Entity_Id :=
4954                      Corresponding_Concurrent_Type (Def_Id);
4955             Conc_Discr : Entity_Id;
4956             Rec_Discr  : Entity_Id;
4957             Temp       : Entity_Id;
4958
4959          begin
4960             Conc_Discr := First_Discriminant (Ctyp);
4961             Rec_Discr  := First_Discriminant (Def_Id);
4962
4963             while Present (Conc_Discr) loop
4964                Temp := Discriminal (Conc_Discr);
4965                Set_Discriminal (Conc_Discr, Discriminal (Rec_Discr));
4966                Set_Discriminal (Rec_Discr, Temp);
4967
4968                Set_Discriminal_Link (Discriminal (Conc_Discr), Conc_Discr);
4969                Set_Discriminal_Link (Discriminal (Rec_Discr),  Rec_Discr);
4970
4971                Next_Discriminant (Conc_Discr);
4972                Next_Discriminant (Rec_Discr);
4973             end loop;
4974          end;
4975       end if;
4976
4977       if Has_Controlled_Component (Def_Id) then
4978          if No (Controller_Component (Def_Id)) then
4979             Expand_Record_Controller (Def_Id);
4980          end if;
4981
4982          Build_Controlling_Procs (Def_Id);
4983       end if;
4984
4985       Adjust_Discriminants (Def_Id);
4986       Build_Record_Init_Proc (Type_Decl, Def_Id);
4987
4988       --  For tagged type, build bodies of primitive operations. Note that we
4989       --  do this after building the record initialization experiment, since
4990       --  the primitive operations may need the initialization routine
4991
4992       if Is_Tagged_Type (Def_Id) then
4993          Predef_List := Predefined_Primitive_Bodies (Def_Id, Renamed_Eq);
4994          Append_Freeze_Actions (Def_Id, Predef_List);
4995
4996          --  Ada 2005 (AI-391): If any wrappers were created for nonoverridden
4997          --  inherited functions, then add their bodies to the freeze actions.
4998
4999          if Present (Wrapper_Body_List) then
5000             Append_Freeze_Actions (Def_Id, Wrapper_Body_List);
5001          end if;
5002
5003          --  Populate the two auxiliary tables used for dispatching
5004          --  asynchronous, conditional and timed selects for synchronized
5005          --  types that implement a limited interface.
5006
5007          if Ada_Version >= Ada_05
5008            and then not Restriction_Active (No_Dispatching_Calls)
5009            and then Is_Concurrent_Record_Type (Def_Id)
5010            and then Implements_Interface (
5011                       Typ          => Def_Id,
5012                       Kind         => Any_Limited_Interface,
5013                       Check_Parent => True)
5014          then
5015             Append_Freeze_Actions (Def_Id,
5016               Make_Select_Specific_Data_Table (Def_Id));
5017          end if;
5018       end if;
5019    end Freeze_Record_Type;
5020
5021    ------------------------------
5022    -- Freeze_Stream_Operations --
5023    ------------------------------
5024
5025    procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id) is
5026       Names     : constant array (1 .. 4) of TSS_Name_Type :=
5027                     (TSS_Stream_Input,
5028                      TSS_Stream_Output,
5029                      TSS_Stream_Read,
5030                      TSS_Stream_Write);
5031       Stream_Op : Entity_Id;
5032
5033    begin
5034       --  Primitive operations of tagged types are frozen when the dispatch
5035       --  table is constructed.
5036
5037       if not Comes_From_Source (Typ)
5038         or else Is_Tagged_Type (Typ)
5039       then
5040          return;
5041       end if;
5042
5043       for J in Names'Range loop
5044          Stream_Op := TSS (Typ, Names (J));
5045
5046          if Present (Stream_Op)
5047            and then Is_Subprogram (Stream_Op)
5048            and then Nkind (Unit_Declaration_Node (Stream_Op)) =
5049                       N_Subprogram_Declaration
5050            and then not Is_Frozen (Stream_Op)
5051          then
5052             Append_Freeze_Actions
5053                (Typ, Freeze_Entity (Stream_Op, Sloc (N)));
5054          end if;
5055       end loop;
5056    end Freeze_Stream_Operations;
5057
5058    -----------------
5059    -- Freeze_Type --
5060    -----------------
5061
5062    --  Full type declarations are expanded at the point at which the type is
5063    --  frozen. The formal N is the Freeze_Node for the type. Any statements or
5064    --  declarations generated by the freezing (e.g. the procedure generated
5065    --  for initialization) are chained in the Actions field list of the freeze
5066    --  node using Append_Freeze_Actions.
5067
5068    function Freeze_Type (N : Node_Id) return Boolean is
5069       Def_Id    : constant Entity_Id := Entity (N);
5070       RACW_Seen : Boolean := False;
5071       Result    : Boolean := False;
5072
5073    begin
5074       --  Process associated access types needing special processing
5075
5076       if Present (Access_Types_To_Process (N)) then
5077          declare
5078             E : Elmt_Id := First_Elmt (Access_Types_To_Process (N));
5079          begin
5080             while Present (E) loop
5081
5082                if Is_Remote_Access_To_Class_Wide_Type (Node (E)) then
5083                   Validate_RACW_Primitives (Node (E));
5084                   RACW_Seen := True;
5085                end if;
5086
5087                E := Next_Elmt (E);
5088             end loop;
5089          end;
5090
5091          if RACW_Seen then
5092
5093             --  If there are RACWs designating this type, make stubs now
5094
5095             Remote_Types_Tagged_Full_View_Encountered (Def_Id);
5096          end if;
5097       end if;
5098
5099       --  Freeze processing for record types
5100
5101       if Is_Record_Type (Def_Id) then
5102          if Ekind (Def_Id) = E_Record_Type then
5103             Freeze_Record_Type (N);
5104
5105          --  The subtype may have been declared before the type was frozen. If
5106          --  the type has controlled components it is necessary to create the
5107          --  entity for the controller explicitly because it did not exist at
5108          --  the point of the subtype declaration. Only the entity is needed,
5109          --  the back-end will obtain the layout from the type. This is only
5110          --  necessary if this is constrained subtype whose component list is
5111          --  not shared with the base type.
5112
5113          elsif Ekind (Def_Id) = E_Record_Subtype
5114            and then Has_Discriminants (Def_Id)
5115            and then Last_Entity (Def_Id) /= Last_Entity (Base_Type (Def_Id))
5116            and then Present (Controller_Component (Def_Id))
5117          then
5118             declare
5119                Old_C : constant Entity_Id := Controller_Component (Def_Id);
5120                New_C : Entity_Id;
5121
5122             begin
5123                if Scope (Old_C) = Base_Type (Def_Id) then
5124
5125                   --  The entity is the one in the parent. Create new one
5126
5127                   New_C := New_Copy (Old_C);
5128                   Set_Parent (New_C, Parent (Old_C));
5129                   New_Scope (Def_Id);
5130                   Enter_Name (New_C);
5131                   End_Scope;
5132                end if;
5133             end;
5134
5135             if Is_Itype (Def_Id)
5136               and then Is_Record_Type (Underlying_Type (Scope (Def_Id)))
5137             then
5138                --  The freeze node is only used to introduce the controller,
5139                --  the back-end has no use for it for a discriminated
5140                --  component.
5141
5142                Set_Freeze_Node (Def_Id, Empty);
5143                Set_Has_Delayed_Freeze (Def_Id, False);
5144                Result := True;
5145             end if;
5146
5147          --  Similar process if the controller of the subtype is not present
5148          --  but the parent has it. This can happen with constrained
5149          --  record components where the subtype is an itype.
5150
5151          elsif Ekind (Def_Id) = E_Record_Subtype
5152            and then Is_Itype (Def_Id)
5153            and then No (Controller_Component (Def_Id))
5154            and then Present (Controller_Component (Etype (Def_Id)))
5155          then
5156             declare
5157                Old_C : constant Entity_Id :=
5158                          Controller_Component (Etype (Def_Id));
5159                New_C : constant Entity_Id := New_Copy (Old_C);
5160
5161             begin
5162                Set_Next_Entity  (New_C, First_Entity (Def_Id));
5163                Set_First_Entity (Def_Id, New_C);
5164
5165                --  The freeze node is only used to introduce the controller,
5166                --  the back-end has no use for it for a discriminated
5167                --   component.
5168
5169                Set_Freeze_Node (Def_Id, Empty);
5170                Set_Has_Delayed_Freeze (Def_Id, False);
5171                Result := True;
5172             end;
5173          end if;
5174
5175       --  Freeze processing for array types
5176
5177       elsif Is_Array_Type (Def_Id) then
5178          Freeze_Array_Type (N);
5179
5180       --  Freeze processing for access types
5181
5182       --  For pool-specific access types, find out the pool object used for
5183       --  this type, needs actual expansion of it in some cases. Here are the
5184       --  different cases :
5185
5186       --  1. Rep Clause "for Def_Id'Storage_Size use 0;"
5187       --      ---> don't use any storage pool
5188
5189       --  2. Rep Clause : for Def_Id'Storage_Size use Expr.
5190       --     Expand:
5191       --      Def_Id__Pool : Stack_Bounded_Pool (Expr, DT'Size, DT'Alignment);
5192
5193       --  3. Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
5194       --      ---> Storage Pool is the specified one
5195
5196       --  See GNAT Pool packages in the Run-Time for more details
5197
5198       elsif Ekind (Def_Id) = E_Access_Type
5199         or else Ekind (Def_Id) = E_General_Access_Type
5200       then
5201          declare
5202             Loc         : constant Source_Ptr := Sloc (N);
5203             Desig_Type  : constant Entity_Id := Designated_Type (Def_Id);
5204             Pool_Object : Entity_Id;
5205             Siz_Exp     : Node_Id;
5206
5207             Freeze_Action_Typ : Entity_Id;
5208
5209          begin
5210             if Has_Storage_Size_Clause (Def_Id) then
5211                Siz_Exp := Expression (Parent (Storage_Size_Variable (Def_Id)));
5212             else
5213                Siz_Exp := Empty;
5214             end if;
5215
5216             --  Case 1
5217
5218             --    Rep Clause "for Def_Id'Storage_Size use 0;"
5219             --    ---> don't use any storage pool
5220
5221             if Has_Storage_Size_Clause (Def_Id)
5222               and then Compile_Time_Known_Value (Siz_Exp)
5223               and then Expr_Value (Siz_Exp) = 0
5224             then
5225                null;
5226
5227             --  Case 2
5228
5229             --    Rep Clause : for Def_Id'Storage_Size use Expr.
5230             --    ---> Expand:
5231             --           Def_Id__Pool : Stack_Bounded_Pool
5232             --                            (Expr, DT'Size, DT'Alignment);
5233
5234             elsif Has_Storage_Size_Clause (Def_Id) then
5235                declare
5236                   DT_Size  : Node_Id;
5237                   DT_Align : Node_Id;
5238
5239                begin
5240                   --  For unconstrained composite types we give a size of zero
5241                   --  so that the pool knows that it needs a special algorithm
5242                   --  for variable size object allocation.
5243
5244                   if Is_Composite_Type (Desig_Type)
5245                     and then not Is_Constrained (Desig_Type)
5246                   then
5247                      DT_Size :=
5248                        Make_Integer_Literal (Loc, 0);
5249
5250                      DT_Align :=
5251                        Make_Integer_Literal (Loc, Maximum_Alignment);
5252
5253                   else
5254                      DT_Size :=
5255                        Make_Attribute_Reference (Loc,
5256                          Prefix => New_Reference_To (Desig_Type, Loc),
5257                          Attribute_Name => Name_Max_Size_In_Storage_Elements);
5258
5259                      DT_Align :=
5260                        Make_Attribute_Reference (Loc,
5261                          Prefix => New_Reference_To (Desig_Type, Loc),
5262                          Attribute_Name => Name_Alignment);
5263                   end if;
5264
5265                   Pool_Object :=
5266                     Make_Defining_Identifier (Loc,
5267                       Chars => New_External_Name (Chars (Def_Id), 'P'));
5268
5269                   --  We put the code associated with the pools in the entity
5270                   --  that has the later freeze node, usually the acces type
5271                   --  but it can also be the designated_type; because the pool
5272                   --  code requires both those types to be frozen
5273
5274                   if Is_Frozen (Desig_Type)
5275                     and then (No (Freeze_Node (Desig_Type))
5276                                or else Analyzed (Freeze_Node (Desig_Type)))
5277                   then
5278                      Freeze_Action_Typ := Def_Id;
5279
5280                   --  A Taft amendment type cannot get the freeze actions
5281                   --  since the full view is not there.
5282
5283                   elsif Is_Incomplete_Or_Private_Type (Desig_Type)
5284                     and then No (Full_View (Desig_Type))
5285                   then
5286                      Freeze_Action_Typ := Def_Id;
5287
5288                   else
5289                      Freeze_Action_Typ := Desig_Type;
5290                   end if;
5291
5292                   Append_Freeze_Action (Freeze_Action_Typ,
5293                     Make_Object_Declaration (Loc,
5294                       Defining_Identifier => Pool_Object,
5295                       Object_Definition =>
5296                         Make_Subtype_Indication (Loc,
5297                           Subtype_Mark =>
5298                             New_Reference_To
5299                               (RTE (RE_Stack_Bounded_Pool), Loc),
5300
5301                           Constraint =>
5302                             Make_Index_Or_Discriminant_Constraint (Loc,
5303                               Constraints => New_List (
5304
5305                               --  First discriminant is the Pool Size
5306
5307                                 New_Reference_To (
5308                                   Storage_Size_Variable (Def_Id), Loc),
5309
5310                               --  Second discriminant is the element size
5311
5312                                 DT_Size,
5313
5314                               --  Third discriminant is the alignment
5315
5316                                 DT_Align)))));
5317                end;
5318
5319                Set_Associated_Storage_Pool (Def_Id, Pool_Object);
5320
5321             --  Case 3
5322
5323             --    Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
5324             --    ---> Storage Pool is the specified one
5325
5326             elsif Present (Associated_Storage_Pool (Def_Id)) then
5327
5328                --  Nothing to do the associated storage pool has been attached
5329                --  when analyzing the rep. clause
5330
5331                null;
5332             end if;
5333
5334             --  For access-to-controlled types (including class-wide types and
5335             --  Taft-amendment types which potentially have controlled
5336             --  components), expand the list controller object that will store
5337             --  the dynamically allocated objects. Do not do this
5338             --  transformation for expander-generated access types, but do it
5339             --  for types that are the full view of types derived from other
5340             --  private types. Also suppress the list controller in the case
5341             --  of a designated type with convention Java, since this is used
5342             --  when binding to Java API specs, where there's no equivalent of
5343             --  a finalization list and we don't want to pull in the
5344             --  finalization support if not needed.
5345
5346             if not Comes_From_Source (Def_Id)
5347                and then not Has_Private_Declaration (Def_Id)
5348             then
5349                null;
5350
5351             elsif (Controlled_Type (Desig_Type)
5352                     and then Convention (Desig_Type) /= Convention_Java)
5353               or else
5354                 (Is_Incomplete_Or_Private_Type (Desig_Type)
5355                    and then No (Full_View (Desig_Type))
5356
5357                   --  An exception is made for types defined in the run-time
5358                   --  because Ada.Tags.Tag itself is such a type and cannot
5359                   --  afford this unnecessary overhead that would generates a
5360                   --  loop in the expansion scheme...
5361
5362                   and then not In_Runtime (Def_Id)
5363
5364                   --  Another exception is if Restrictions (No_Finalization)
5365                   --  is active, since then we know nothing is controlled.
5366
5367                   and then not Restriction_Active (No_Finalization))
5368
5369                --  If the designated type is not frozen yet, its controlled
5370                --  status must be retrieved explicitly.
5371
5372               or else (Is_Array_Type (Desig_Type)
5373                 and then not Is_Frozen (Desig_Type)
5374                 and then Controlled_Type (Component_Type (Desig_Type)))
5375             then
5376                Set_Associated_Final_Chain (Def_Id,
5377                  Make_Defining_Identifier (Loc,
5378                    New_External_Name (Chars (Def_Id), 'L')));
5379
5380                Append_Freeze_Action (Def_Id,
5381                  Make_Object_Declaration (Loc,
5382                    Defining_Identifier => Associated_Final_Chain (Def_Id),
5383                    Object_Definition   =>
5384                      New_Reference_To (RTE (RE_List_Controller), Loc)));
5385             end if;
5386          end;
5387
5388       --  Freeze processing for enumeration types
5389
5390       elsif Ekind (Def_Id) = E_Enumeration_Type then
5391
5392          --  We only have something to do if we have a non-standard
5393          --  representation (i.e. at least one literal whose pos value
5394          --  is not the same as its representation)
5395
5396          if Has_Non_Standard_Rep (Def_Id) then
5397             Freeze_Enumeration_Type (N);
5398          end if;
5399
5400       --  Private types that are completed by a derivation from a private
5401       --  type have an internally generated full view, that needs to be
5402       --  frozen. This must be done explicitly because the two views share
5403       --  the freeze node, and the underlying full view is not visible when
5404       --  the freeze node is analyzed.
5405
5406       elsif Is_Private_Type (Def_Id)
5407         and then Is_Derived_Type (Def_Id)
5408         and then Present (Full_View (Def_Id))
5409         and then Is_Itype (Full_View (Def_Id))
5410         and then Has_Private_Declaration (Full_View (Def_Id))
5411         and then Freeze_Node (Full_View (Def_Id)) = N
5412       then
5413          Set_Entity (N, Full_View (Def_Id));
5414          Result := Freeze_Type (N);
5415          Set_Entity (N, Def_Id);
5416
5417       --  All other types require no expander action. There are such cases
5418       --  (e.g. task types and protected types). In such cases, the freeze
5419       --  nodes are there for use by Gigi.
5420
5421       end if;
5422
5423       Freeze_Stream_Operations (N, Def_Id);
5424       return Result;
5425
5426    exception
5427       when RE_Not_Available =>
5428          return False;
5429    end Freeze_Type;
5430
5431    -------------------------
5432    -- Get_Simple_Init_Val --
5433    -------------------------
5434
5435    function Get_Simple_Init_Val
5436      (T    : Entity_Id;
5437       Loc  : Source_Ptr;
5438       Size : Uint := No_Uint) return Node_Id
5439    is
5440       Val    : Node_Id;
5441       Result : Node_Id;
5442       Val_RE : RE_Id;
5443
5444       Size_To_Use : Uint;
5445       --  This is the size to be used for computation of the appropriate
5446       --  initial value for the Normalize_Scalars and Initialize_Scalars case.
5447
5448       Lo_Bound : Uint;
5449       Hi_Bound : Uint;
5450       --  These are the values computed by the procedure Check_Subtype_Bounds
5451
5452       procedure Check_Subtype_Bounds;
5453       --  This procedure examines the subtype T, and its ancestor subtypes and
5454       --  derived types to determine the best known information about the
5455       --  bounds of the subtype. After the call Lo_Bound is set either to
5456       --  No_Uint if no information can be determined, or to a value which
5457       --  represents a known low bound, i.e. a valid value of the subtype can
5458       --  not be less than this value. Hi_Bound is similarly set to a known
5459       --  high bound (valid value cannot be greater than this).
5460
5461       --------------------------
5462       -- Check_Subtype_Bounds --
5463       --------------------------
5464
5465       procedure Check_Subtype_Bounds is
5466          ST1  : Entity_Id;
5467          ST2  : Entity_Id;
5468          Lo   : Node_Id;
5469          Hi   : Node_Id;
5470          Loval : Uint;
5471          Hival : Uint;
5472
5473       begin
5474          Lo_Bound := No_Uint;
5475          Hi_Bound := No_Uint;
5476
5477          --  Loop to climb ancestor subtypes and derived types
5478
5479          ST1 := T;
5480          loop
5481             if not Is_Discrete_Type (ST1) then
5482                return;
5483             end if;
5484
5485             Lo := Type_Low_Bound (ST1);
5486             Hi := Type_High_Bound (ST1);
5487
5488             if Compile_Time_Known_Value (Lo) then
5489                Loval := Expr_Value (Lo);
5490
5491                if Lo_Bound = No_Uint or else Lo_Bound < Loval then
5492                   Lo_Bound := Loval;
5493                end if;
5494             end if;
5495
5496             if Compile_Time_Known_Value (Hi) then
5497                Hival := Expr_Value (Hi);
5498
5499                if Hi_Bound = No_Uint or else Hi_Bound > Hival then
5500                   Hi_Bound := Hival;
5501                end if;
5502             end if;
5503
5504             ST2 := Ancestor_Subtype (ST1);
5505
5506             if No (ST2) then
5507                ST2 := Etype (ST1);
5508             end if;
5509
5510             exit when ST1 = ST2;
5511             ST1 := ST2;
5512          end loop;
5513       end Check_Subtype_Bounds;
5514
5515    --  Start of processing for Get_Simple_Init_Val
5516
5517    begin
5518       --  For a private type, we should always have an underlying type
5519       --  (because this was already checked in Needs_Simple_Initialization).
5520       --  What we do is to get the value for the underlying type and then do
5521       --  an Unchecked_Convert to the private type.
5522
5523       if Is_Private_Type (T) then
5524          Val := Get_Simple_Init_Val (Underlying_Type (T), Loc, Size);
5525
5526          --  A special case, if the underlying value is null, then qualify it
5527          --  with the underlying type, so that the null is properly typed
5528          --  Similarly, if it is an aggregate it must be qualified, because an
5529          --  unchecked conversion does not provide a context for it.
5530
5531          if Nkind (Val) = N_Null
5532            or else Nkind (Val) = N_Aggregate
5533          then
5534             Val :=
5535               Make_Qualified_Expression (Loc,
5536                 Subtype_Mark =>
5537                   New_Occurrence_Of (Underlying_Type (T), Loc),
5538                 Expression => Val);
5539          end if;
5540
5541          Result := Unchecked_Convert_To (T, Val);
5542
5543          --  Don't truncate result (important for Initialize/Normalize_Scalars)
5544
5545          if Nkind (Result) = N_Unchecked_Type_Conversion
5546            and then Is_Scalar_Type (Underlying_Type (T))
5547          then
5548             Set_No_Truncation (Result);
5549          end if;
5550
5551          return Result;
5552
5553       --  For scalars, we must have normalize/initialize scalars case
5554
5555       elsif Is_Scalar_Type (T) then
5556          pragma Assert (Init_Or_Norm_Scalars);
5557
5558          --  Compute size of object. If it is given by the caller, we can use
5559          --  it directly, otherwise we use Esize (T) as an estimate. As far as
5560          --  we know this covers all cases correctly.
5561
5562          if Size = No_Uint or else Size <= Uint_0 then
5563             Size_To_Use := UI_Max (Uint_1, Esize (T));
5564          else
5565             Size_To_Use := Size;
5566          end if;
5567
5568          --  Maximum size to use is 64 bits, since we will create values
5569          --  of type Unsigned_64 and the range must fit this type.
5570
5571          if Size_To_Use /= No_Uint and then Size_To_Use > Uint_64 then
5572             Size_To_Use := Uint_64;
5573          end if;
5574
5575          --  Check known bounds of subtype
5576
5577          Check_Subtype_Bounds;
5578
5579          --  Processing for Normalize_Scalars case
5580
5581          if Normalize_Scalars then
5582
5583             --  If zero is invalid, it is a convenient value to use that is
5584             --  for sure an appropriate invalid value in all situations.
5585
5586             if Lo_Bound /= No_Uint and then Lo_Bound > Uint_0 then
5587                Val := Make_Integer_Literal (Loc, 0);
5588
5589             --  Cases where all one bits is the appropriate invalid value
5590
5591             --  For modular types, all 1 bits is either invalid or valid. If
5592             --  it is valid, then there is nothing that can be done since there
5593             --  are no invalid values (we ruled out zero already).
5594
5595             --  For signed integer types that have no negative values, either
5596             --  there is room for negative values, or there is not. If there
5597             --  is, then all 1 bits may be interpretecd as minus one, which is
5598             --  certainly invalid. Alternatively it is treated as the largest
5599             --  positive value, in which case the observation for modular types
5600             --  still applies.
5601
5602             --  For float types, all 1-bits is a NaN (not a number), which is
5603             --  certainly an appropriately invalid value.
5604
5605             elsif Is_Unsigned_Type (T)
5606               or else Is_Floating_Point_Type (T)
5607               or else Is_Enumeration_Type (T)
5608             then
5609                Val := Make_Integer_Literal (Loc, 2 ** Size_To_Use - 1);
5610
5611                --  Resolve as Unsigned_64, because the largest number we
5612                --  can generate is out of range of universal integer.
5613
5614                Analyze_And_Resolve (Val, RTE (RE_Unsigned_64));
5615
5616             --  Case of signed types
5617
5618             else
5619                declare
5620                   Signed_Size : constant Uint :=
5621                                   UI_Min (Uint_63, Size_To_Use - 1);
5622
5623                begin
5624                   --  Normally we like to use the most negative number. The
5625                   --  one exception is when this number is in the known
5626                   --  subtype range and the largest positive number is not in
5627                   --  the known subtype range.
5628
5629                   --  For this exceptional case, use largest positive value
5630
5631                   if Lo_Bound /= No_Uint and then Hi_Bound /= No_Uint
5632                     and then Lo_Bound <= (-(2 ** Signed_Size))
5633                     and then Hi_Bound < 2 ** Signed_Size
5634                   then
5635                      Val := Make_Integer_Literal (Loc, 2 ** Signed_Size - 1);
5636
5637                      --  Normal case of largest negative value
5638
5639                   else
5640                      Val := Make_Integer_Literal (Loc, -(2 ** Signed_Size));
5641                   end if;
5642                end;
5643             end if;
5644
5645          --  Here for Initialize_Scalars case
5646
5647          else
5648             --  For float types, use float values from System.Scalar_Values
5649
5650             if Is_Floating_Point_Type (T) then
5651                if Root_Type (T) = Standard_Short_Float then
5652                   Val_RE := RE_IS_Isf;
5653                elsif Root_Type (T) = Standard_Float then
5654                   Val_RE := RE_IS_Ifl;
5655                elsif Root_Type (T) = Standard_Long_Float then
5656                   Val_RE := RE_IS_Ilf;
5657                else pragma Assert (Root_Type (T) = Standard_Long_Long_Float);
5658                   Val_RE := RE_IS_Ill;
5659                end if;
5660
5661             --  If zero is invalid, use zero values from System.Scalar_Values
5662
5663             elsif Lo_Bound /= No_Uint and then Lo_Bound > Uint_0 then
5664                if Size_To_Use <= 8 then
5665                   Val_RE := RE_IS_Iz1;
5666                elsif Size_To_Use <= 16 then
5667                   Val_RE := RE_IS_Iz2;
5668                elsif Size_To_Use <= 32 then
5669                   Val_RE := RE_IS_Iz4;
5670                else
5671                   Val_RE := RE_IS_Iz8;
5672                end if;
5673
5674             --  For unsigned, use unsigned values from System.Scalar_Values
5675
5676             elsif Is_Unsigned_Type (T) then
5677                if Size_To_Use <= 8 then
5678                   Val_RE := RE_IS_Iu1;
5679                elsif Size_To_Use <= 16 then
5680                   Val_RE := RE_IS_Iu2;
5681                elsif Size_To_Use <= 32 then
5682                   Val_RE := RE_IS_Iu4;
5683                else
5684                   Val_RE := RE_IS_Iu8;
5685                end if;
5686
5687             --  For signed, use signed values from System.Scalar_Values
5688
5689             else
5690                if Size_To_Use <= 8 then
5691                   Val_RE := RE_IS_Is1;
5692                elsif Size_To_Use <= 16 then
5693                   Val_RE := RE_IS_Is2;
5694                elsif Size_To_Use <= 32 then
5695                   Val_RE := RE_IS_Is4;
5696                else
5697                   Val_RE := RE_IS_Is8;
5698                end if;
5699             end if;
5700
5701             Val := New_Occurrence_Of (RTE (Val_RE), Loc);
5702          end if;
5703
5704          --  The final expression is obtained by doing an unchecked conversion
5705          --  of this result to the base type of the required subtype. We use
5706          --  the base type to avoid the unchecked conversion from chopping
5707          --  bits, and then we set Kill_Range_Check to preserve the "bad"
5708          --  value.
5709
5710          Result := Unchecked_Convert_To (Base_Type (T), Val);
5711
5712          --  Ensure result is not truncated, since we want the "bad" bits
5713          --  and also kill range check on result.
5714
5715          if Nkind (Result) = N_Unchecked_Type_Conversion then
5716             Set_No_Truncation (Result);
5717             Set_Kill_Range_Check (Result, True);
5718          end if;
5719
5720          return Result;
5721
5722       --  String or Wide_[Wide]_String (must have Initialize_Scalars set)
5723
5724       elsif Root_Type (T) = Standard_String
5725               or else
5726             Root_Type (T) = Standard_Wide_String
5727               or else
5728             Root_Type (T) = Standard_Wide_Wide_String
5729       then
5730          pragma Assert (Init_Or_Norm_Scalars);
5731
5732          return
5733            Make_Aggregate (Loc,
5734              Component_Associations => New_List (
5735                Make_Component_Association (Loc,
5736                  Choices => New_List (
5737                    Make_Others_Choice (Loc)),
5738                  Expression =>
5739                    Get_Simple_Init_Val
5740                      (Component_Type (T), Loc, Esize (Root_Type (T))))));
5741
5742       --  Access type is initialized to null
5743
5744       elsif Is_Access_Type (T) then
5745          return
5746            Make_Null (Loc);
5747
5748       --  No other possibilities should arise, since we should only be
5749       --  calling Get_Simple_Init_Val if Needs_Simple_Initialization
5750       --  returned True, indicating one of the above cases held.
5751
5752       else
5753          raise Program_Error;
5754       end if;
5755
5756    exception
5757       when RE_Not_Available =>
5758          return Empty;
5759    end Get_Simple_Init_Val;
5760
5761    ------------------------------
5762    -- Has_New_Non_Standard_Rep --
5763    ------------------------------
5764
5765    function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean is
5766    begin
5767       if not Is_Derived_Type (T) then
5768          return Has_Non_Standard_Rep (T)
5769            or else Has_Non_Standard_Rep (Root_Type (T));
5770
5771       --  If Has_Non_Standard_Rep is not set on the derived type, the
5772       --  representation is fully inherited.
5773
5774       elsif not Has_Non_Standard_Rep (T) then
5775          return False;
5776
5777       else
5778          return First_Rep_Item (T) /= First_Rep_Item (Root_Type (T));
5779
5780          --  May need a more precise check here: the First_Rep_Item may
5781          --  be a stream attribute, which does not affect the representation
5782          --  of the type ???
5783       end if;
5784    end Has_New_Non_Standard_Rep;
5785
5786    ----------------
5787    -- In_Runtime --
5788    ----------------
5789
5790    function In_Runtime (E : Entity_Id) return Boolean is
5791       S1 : Entity_Id := Scope (E);
5792
5793    begin
5794       while Scope (S1) /= Standard_Standard loop
5795          S1 := Scope (S1);
5796       end loop;
5797
5798       return Chars (S1) = Name_System or else Chars (S1) = Name_Ada;
5799    end In_Runtime;
5800
5801    ------------------
5802    -- Init_Formals --
5803    ------------------
5804
5805    function Init_Formals (Typ : Entity_Id) return List_Id is
5806       Loc     : constant Source_Ptr := Sloc (Typ);
5807       Formals : List_Id;
5808
5809    begin
5810       --  First parameter is always _Init : in out typ. Note that we need
5811       --  this to be in/out because in the case of the task record value,
5812       --  there are default record fields (_Priority, _Size, -Task_Info)
5813       --  that may be referenced in the generated initialization routine.
5814
5815       Formals := New_List (
5816         Make_Parameter_Specification (Loc,
5817           Defining_Identifier =>
5818             Make_Defining_Identifier (Loc, Name_uInit),
5819           In_Present  => True,
5820           Out_Present => True,
5821           Parameter_Type => New_Reference_To (Typ, Loc)));
5822
5823       --  For task record value, or type that contains tasks, add two more
5824       --  formals, _Master : Master_Id and _Chain : in out Activation_Chain
5825       --  We also add these parameters for the task record type case.
5826
5827       if Has_Task (Typ)
5828         or else (Is_Record_Type (Typ) and then Is_Task_Record_Type (Typ))
5829       then
5830          Append_To (Formals,
5831            Make_Parameter_Specification (Loc,
5832              Defining_Identifier =>
5833                Make_Defining_Identifier (Loc, Name_uMaster),
5834              Parameter_Type => New_Reference_To (RTE (RE_Master_Id), Loc)));
5835
5836          Append_To (Formals,
5837            Make_Parameter_Specification (Loc,
5838              Defining_Identifier =>
5839                Make_Defining_Identifier (Loc, Name_uChain),
5840              In_Present => True,
5841              Out_Present => True,
5842              Parameter_Type =>
5843                New_Reference_To (RTE (RE_Activation_Chain), Loc)));
5844
5845          Append_To (Formals,
5846            Make_Parameter_Specification (Loc,
5847              Defining_Identifier =>
5848                Make_Defining_Identifier (Loc, Name_uTask_Name),
5849              In_Present => True,
5850              Parameter_Type =>
5851                New_Reference_To (Standard_String, Loc)));
5852       end if;
5853
5854       return Formals;
5855
5856    exception
5857       when RE_Not_Available =>
5858          return Empty_List;
5859    end Init_Formals;
5860
5861    -------------------------
5862    -- Init_Secondary_Tags --
5863    -------------------------
5864
5865    procedure Init_Secondary_Tags
5866      (Typ        : Entity_Id;
5867       Target     : Node_Id;
5868       Stmts_List : List_Id)
5869    is
5870       Loc      : constant Source_Ptr := Sloc (Target);
5871       ADT      : Elmt_Id;
5872       Full_Typ : Entity_Id;
5873
5874       procedure Init_Secondary_Tags_Internal (Typ : Entity_Id);
5875       --  Internal subprogram used to recursively climb to the root type.
5876       --  We assume that all the primitives of the imported C++ class are
5877       --  defined in the C side.
5878
5879       ----------------------------------
5880       -- Init_Secondary_Tags_Internal --
5881       ----------------------------------
5882
5883       procedure Init_Secondary_Tags_Internal (Typ : Entity_Id) is
5884          Args   : List_Id;
5885          Aux_N  : Node_Id;
5886          E      : Entity_Id;
5887          Iface  : Entity_Id;
5888          New_N  : Node_Id;
5889          Prev_E : Entity_Id;
5890
5891       begin
5892          --  Climb to the ancestor (if any) handling private types
5893
5894          if Present (Full_View (Etype (Typ))) then
5895             if Full_View (Etype (Typ)) /= Typ then
5896                Init_Secondary_Tags_Internal (Full_View (Etype (Typ)));
5897             end if;
5898
5899          elsif Etype (Typ) /= Typ then
5900             Init_Secondary_Tags_Internal (Etype (Typ));
5901          end if;
5902
5903          if Is_Interface (Typ) then
5904             --  Generate:
5905             --    Set_Offset_To_Top
5906             --      (This         => Init,
5907             --       Interface_T  => Iface'Tag,
5908             --       Is_Constant  => True,
5909             --       Offset_Value => 0,
5910             --       Offset_Func  => null)
5911
5912             Append_To (Stmts_List,
5913               Make_Procedure_Call_Statement (Loc,
5914                 Name => New_Reference_To (RTE (RE_Set_Offset_To_Top), Loc),
5915                 Parameter_Associations => New_List (
5916                   Make_Attribute_Reference (Loc,
5917                     Prefix => New_Copy_Tree (Target),
5918                     Attribute_Name => Name_Address),
5919
5920                   Unchecked_Convert_To (RTE (RE_Tag),
5921                     New_Reference_To
5922                       (Node (First_Elmt (Access_Disp_Table (Typ))),
5923                        Loc)),
5924
5925                   New_Occurrence_Of (Standard_True, Loc),
5926
5927                   Make_Integer_Literal (Loc, Uint_0),
5928
5929                   New_Reference_To (RTE (RE_Null_Address), Loc))));
5930          end if;
5931
5932          if Present (Abstract_Interfaces (Typ))
5933            and then not Is_Empty_Elmt_List (Abstract_Interfaces (Typ))
5934          then
5935             E := First_Entity (Typ);
5936             while Present (E) loop
5937                if Is_Tag (E)
5938                  and then Chars (E) /= Name_uTag
5939                then
5940                   Aux_N := Node (ADT);
5941                   pragma Assert (Present (Aux_N));
5942
5943                   Iface := Find_Interface (Typ, E);
5944
5945                   --  If we are compiling under the CPP full ABI compatibility
5946                   --  mode and the ancestor is a CPP_Pragma tagged type then
5947                   --  we generate code to inherit the contents of the dispatch
5948                   --  table directly from the ancestor.
5949
5950                   if Is_CPP_Class (Etype (Typ))
5951                     and then not Debug_Flag_QQ
5952                   then
5953                      Args := New_List (
5954                        Node1 =>
5955                          Unchecked_Convert_To (RTE (RE_Tag),
5956                            Make_Selected_Component (Loc,
5957                              Prefix        => New_Copy_Tree (Target),
5958                              Selector_Name => New_Reference_To (E, Loc))),
5959                        Node2 =>
5960                          Unchecked_Convert_To (RTE (RE_Tag),
5961                            New_Reference_To (Aux_N, Loc)),
5962
5963                        Node3 =>
5964                          Make_Integer_Literal (Loc,
5965                            DT_Entry_Count (First_Tag_Component (Iface))));
5966
5967                      --  Issue error if Inherit_CPP_DT is not available
5968                      --  in a configurable run-time environment.
5969
5970                      if not RTE_Available (RE_Inherit_CPP_DT) then
5971                         Error_Msg_CRT ("cpp interfacing", Typ);
5972                         return;
5973                      end if;
5974
5975                      New_N :=
5976                        Make_Procedure_Call_Statement (Loc,
5977                          Name => New_Reference_To (RTE (RE_Inherit_CPP_DT),
5978                                                    Loc),
5979                          Parameter_Associations => Args);
5980
5981                      Append_To (Stmts_List, New_N);
5982                   end if;
5983
5984                   --  Initialize the pointer to the secondary DT associated
5985                   --  with the interface
5986
5987                   Append_To (Stmts_List,
5988                     Make_Assignment_Statement (Loc,
5989                       Name =>
5990                         Make_Selected_Component (Loc,
5991                           Prefix => New_Copy_Tree (Target),
5992                           Selector_Name => New_Reference_To (E, Loc)),
5993                       Expression =>
5994                         New_Reference_To (Aux_N, Loc)));
5995
5996                   --  If the ancestor is CPP_Class, nothing else to do here
5997
5998                   if Is_CPP_Class (Etype (Typ)) and then not Debug_Flag_QQ then
5999                      null;
6000
6001                   --  Otherwise, comment required ???
6002
6003                   else
6004                      --  Issue error if Set_Offset_To_Top is not available in a
6005                      --  configurable run-time environment.
6006
6007                      if not RTE_Available (RE_Set_Offset_To_Top) then
6008                         Error_Msg_CRT ("abstract interface types", Typ);
6009                         return;
6010                      end if;
6011
6012                      --  We generate a different call when the parent of the
6013                      --  type has discriminants.
6014
6015                      if Typ /= Etype (Typ)
6016                        and then Has_Discriminants (Etype (Typ))
6017                      then
6018                         pragma Assert
6019                           (Present (DT_Offset_To_Top_Func (E)));
6020
6021                         --  Generate:
6022                         --    Set_Offset_To_Top
6023                         --      (This         => Init,
6024                         --       Interface_T  => Iface'Tag,
6025                         --       Is_Constant  => False,
6026                         --       Offset_Value => n,
6027                         --       Offset_Func  => Fn'Address)
6028
6029                         Append_To (Stmts_List,
6030                           Make_Procedure_Call_Statement (Loc,
6031                             Name => New_Reference_To
6032                                       (RTE (RE_Set_Offset_To_Top), Loc),
6033                             Parameter_Associations => New_List (
6034                               Make_Attribute_Reference (Loc,
6035                                 Prefix => New_Copy_Tree (Target),
6036                                 Attribute_Name => Name_Address),
6037
6038                               Unchecked_Convert_To (RTE (RE_Tag),
6039                                 New_Reference_To
6040                                   (Node (First_Elmt
6041                                          (Access_Disp_Table (Iface))),
6042                                    Loc)),
6043
6044                               New_Occurrence_Of (Standard_False, Loc),
6045
6046                               Unchecked_Convert_To
6047                                 (RTE (RE_Storage_Offset),
6048                                  Make_Attribute_Reference (Loc,
6049                                    Prefix         =>
6050                                      Make_Selected_Component (Loc,
6051                                        Prefix => New_Copy_Tree (Target),
6052                                        Selector_Name =>
6053                                          New_Reference_To (E, Loc)),
6054                                    Attribute_Name => Name_Position)),
6055
6056                               Unchecked_Convert_To (RTE (RE_Address),
6057                                 Make_Attribute_Reference (Loc,
6058                                   Prefix => New_Reference_To
6059                                               (DT_Offset_To_Top_Func (E),
6060                                                Loc),
6061                                   Attribute_Name =>
6062                                     Name_Address)))));
6063
6064                         --  In this case the next component stores the
6065                         --  value of the offset to the top.
6066
6067                         Prev_E := E;
6068                         Next_Entity (E);
6069                         pragma Assert (Present (E));
6070
6071                         Append_To (Stmts_List,
6072                           Make_Assignment_Statement (Loc,
6073                             Name =>
6074                               Make_Selected_Component (Loc,
6075                                 Prefix => New_Copy_Tree (Target),
6076                                 Selector_Name => New_Reference_To (E, Loc)),
6077                             Expression =>
6078                               Make_Attribute_Reference (Loc,
6079                                 Prefix         =>
6080                                   Make_Selected_Component (Loc,
6081                                     Prefix => New_Copy_Tree (Target),
6082                                     Selector_Name =>
6083                                       New_Reference_To (Prev_E, Loc)),
6084                               Attribute_Name => Name_Position)));
6085
6086                      --  Normal case: No discriminants in the parent type
6087
6088                      else
6089                         --  Generate:
6090                         --    Set_Offset_To_Top
6091                         --      (This         => Init,
6092                         --       Interface_T  => Iface'Tag,
6093                         --       Is_Constant  => True,
6094                         --       Offset_Value => n,
6095                         --       Offset_Func  => null);
6096
6097                         Append_To (Stmts_List,
6098                           Make_Procedure_Call_Statement (Loc,
6099                             Name => New_Reference_To
6100                                       (RTE (RE_Set_Offset_To_Top), Loc),
6101                             Parameter_Associations => New_List (
6102                               Make_Attribute_Reference (Loc,
6103                                 Prefix => New_Copy_Tree (Target),
6104                                 Attribute_Name => Name_Address),
6105
6106                               Unchecked_Convert_To (RTE (RE_Tag),
6107                                 New_Reference_To
6108                                   (Node (First_Elmt
6109                                          (Access_Disp_Table (Iface))),
6110                                    Loc)),
6111
6112                               New_Occurrence_Of (Standard_True, Loc),
6113
6114                               Unchecked_Convert_To
6115                                 (RTE (RE_Storage_Offset),
6116                                  Make_Attribute_Reference (Loc,
6117                                    Prefix =>
6118                                     Make_Selected_Component (Loc,
6119                                       Prefix => New_Copy_Tree (Target),
6120                                       Selector_Name  =>
6121                                         New_Reference_To (E, Loc)),
6122                                   Attribute_Name => Name_Position)),
6123
6124                               New_Reference_To
6125                                 (RTE (RE_Null_Address), Loc))));
6126                      end if;
6127                   end if;
6128
6129                   Next_Elmt (ADT);
6130                end if;
6131
6132                Next_Entity (E);
6133             end loop;
6134          end if;
6135       end Init_Secondary_Tags_Internal;
6136
6137    --  Start of processing for Init_Secondary_Tags
6138
6139    begin
6140       --  Skip the first _Tag, which is the main tag of the tagged type.
6141       --  Following tags correspond with abstract interfaces.
6142
6143       ADT := Next_Elmt (First_Elmt (Access_Disp_Table (Typ)));
6144
6145       --  Handle private types
6146
6147       if Present (Full_View (Typ)) then
6148          Full_Typ := Full_View (Typ);
6149       else
6150          Full_Typ := Typ;
6151       end if;
6152
6153       Init_Secondary_Tags_Internal (Full_Typ);
6154    end Init_Secondary_Tags;
6155
6156    ----------------------------------------
6157    -- Make_Controlling_Function_Wrappers --
6158    ----------------------------------------
6159
6160    procedure Make_Controlling_Function_Wrappers
6161      (Tag_Typ   : Entity_Id;
6162       Decl_List : out List_Id;
6163       Body_List : out List_Id)
6164    is
6165       Loc         : constant Source_Ptr := Sloc (Tag_Typ);
6166       Prim_Elmt   : Elmt_Id;
6167       Subp        : Entity_Id;
6168       Actual_List : List_Id;
6169       Formal_List : List_Id;
6170       Formal      : Entity_Id;
6171       Par_Formal  : Entity_Id;
6172       Formal_Node : Node_Id;
6173       Func_Spec   : Node_Id;
6174       Func_Decl   : Node_Id;
6175       Func_Body   : Node_Id;
6176       Return_Stmt : Node_Id;
6177
6178    begin
6179       Decl_List := New_List;
6180       Body_List := New_List;
6181
6182       Prim_Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
6183
6184       while Present (Prim_Elmt) loop
6185          Subp := Node (Prim_Elmt);
6186
6187          --  If a primitive function with a controlling result of the type has
6188          --  not been overridden by the user, then we must create a wrapper
6189          --  function here that effectively overrides it and invokes the
6190          --  (non-abstract) parent function. This can only occur for a null
6191          --  extension. Note that functions with anonymous controlling access
6192          --  results don't qualify and must be overridden. We also exclude
6193          --  Input attributes, since each type will have its own version of
6194          --  Input constructed by the expander. The test for Comes_From_Source
6195          --  is needed to distinguish inherited operations from renamings
6196          --  (which also have Alias set).
6197
6198          if Is_Abstract (Subp)
6199            and then Present (Alias (Subp))
6200            and then not Is_Abstract (Alias (Subp))
6201            and then not Comes_From_Source (Subp)
6202            and then Ekind (Subp) = E_Function
6203            and then Has_Controlling_Result (Subp)
6204            and then not Is_Access_Type (Etype (Subp))
6205            and then not Is_TSS (Subp, TSS_Stream_Input)
6206          then
6207             Formal_List := No_List;
6208             Formal := First_Formal (Subp);
6209
6210             if Present (Formal) then
6211                Formal_List := New_List;
6212
6213                while Present (Formal) loop
6214                   Append
6215                     (Make_Parameter_Specification
6216                        (Loc,
6217                         Defining_Identifier =>
6218                           Make_Defining_Identifier (Sloc (Formal),
6219                             Chars => Chars (Formal)),
6220                         In_Present  => In_Present (Parent (Formal)),
6221                         Out_Present => Out_Present (Parent (Formal)),
6222                         Parameter_Type =>
6223                           New_Reference_To (Etype (Formal), Loc),
6224                         Expression =>
6225                           New_Copy_Tree (Expression (Parent (Formal)))),
6226                      Formal_List);
6227
6228                   Next_Formal (Formal);
6229                end loop;
6230             end if;
6231
6232             Func_Spec :=
6233               Make_Function_Specification (Loc,
6234                 Defining_Unit_Name =>
6235                   Make_Defining_Identifier (Loc, Chars (Subp)),
6236                 Parameter_Specifications =>
6237                   Formal_List,
6238                 Result_Definition =>
6239                   New_Reference_To (Etype (Subp), Loc));
6240
6241             Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
6242             Append_To (Decl_List, Func_Decl);
6243
6244             --  Build a wrapper body that calls the parent function. The body
6245             --  contains a single return statement that returns an extension
6246             --  aggregate whose ancestor part is a call to the parent function,
6247             --  passing the formals as actuals (with any controlling arguments
6248             --  converted to the types of the corresponding formals of the
6249             --  parent function, which might be anonymous access types), and
6250             --  having a null extension.
6251
6252             Formal      := First_Formal (Subp);
6253             Par_Formal  := First_Formal (Alias (Subp));
6254             Formal_Node := First (Formal_List);
6255
6256             if Present (Formal) then
6257                Actual_List := New_List;
6258             else
6259                Actual_List := No_List;
6260             end if;
6261
6262             while Present (Formal) loop
6263                if Is_Controlling_Formal (Formal) then
6264                   Append_To (Actual_List,
6265                     Make_Type_Conversion (Loc,
6266                       Subtype_Mark =>
6267                         New_Occurrence_Of (Etype (Par_Formal), Loc),
6268                       Expression   =>
6269                         New_Reference_To
6270                           (Defining_Identifier (Formal_Node), Loc)));
6271                else
6272                   Append_To
6273                     (Actual_List,
6274                      New_Reference_To
6275                        (Defining_Identifier (Formal_Node), Loc));
6276                end if;
6277
6278                Next_Formal (Formal);
6279                Next_Formal (Par_Formal);
6280                Next (Formal_Node);
6281             end loop;
6282
6283             Return_Stmt :=
6284               Make_Return_Statement (Loc,
6285                 Expression =>
6286                   Make_Extension_Aggregate (Loc,
6287                     Ancestor_Part =>
6288                       Make_Function_Call (Loc,
6289                         Name => New_Reference_To (Alias (Subp), Loc),
6290                         Parameter_Associations => Actual_List),
6291                     Null_Record_Present => True));
6292
6293             Func_Body :=
6294               Make_Subprogram_Body (Loc,
6295                 Specification => New_Copy_Tree (Func_Spec),
6296                 Declarations => Empty_List,
6297                 Handled_Statement_Sequence =>
6298                   Make_Handled_Sequence_Of_Statements (Loc,
6299                     Statements => New_List (Return_Stmt)));
6300
6301             Set_Defining_Unit_Name
6302               (Specification (Func_Body),
6303                 Make_Defining_Identifier (Loc, Chars (Subp)));
6304
6305             Append_To (Body_List, Func_Body);
6306
6307             --  Replace the inherited function with the wrapper function
6308             --  in the primitive operations list.
6309
6310             Override_Dispatching_Operation
6311               (Tag_Typ, Subp, New_Op => Defining_Unit_Name (Func_Spec));
6312          end if;
6313
6314          Next_Elmt (Prim_Elmt);
6315       end loop;
6316    end Make_Controlling_Function_Wrappers;
6317
6318    ------------------
6319    -- Make_Eq_Case --
6320    ------------------
6321
6322    --  <Make_Eq_if shared components>
6323    --  case X.D1 is
6324    --     when V1 => <Make_Eq_Case> on subcomponents
6325    --     ...
6326    --     when Vn => <Make_Eq_Case> on subcomponents
6327    --  end case;
6328
6329    function Make_Eq_Case
6330      (E     : Entity_Id;
6331       CL    : Node_Id;
6332       Discr : Entity_Id := Empty) return List_Id
6333    is
6334       Loc      : constant Source_Ptr := Sloc (E);
6335       Result   : constant List_Id    := New_List;
6336       Variant  : Node_Id;
6337       Alt_List : List_Id;
6338
6339    begin
6340       Append_To (Result, Make_Eq_If (E, Component_Items (CL)));
6341
6342       if No (Variant_Part (CL)) then
6343          return Result;
6344       end if;
6345
6346       Variant := First_Non_Pragma (Variants (Variant_Part (CL)));
6347
6348       if No (Variant) then
6349          return Result;
6350       end if;
6351
6352       Alt_List := New_List;
6353
6354       while Present (Variant) loop
6355          Append_To (Alt_List,
6356            Make_Case_Statement_Alternative (Loc,
6357              Discrete_Choices => New_Copy_List (Discrete_Choices (Variant)),
6358              Statements => Make_Eq_Case (E, Component_List (Variant))));
6359
6360          Next_Non_Pragma (Variant);
6361       end loop;
6362
6363       --  If we have an Unchecked_Union, use one of the parameters that
6364       --  captures the discriminants.
6365
6366       if Is_Unchecked_Union (E) then
6367          Append_To (Result,
6368            Make_Case_Statement (Loc,
6369              Expression => New_Reference_To (Discr, Loc),
6370              Alternatives => Alt_List));
6371
6372       else
6373          Append_To (Result,
6374            Make_Case_Statement (Loc,
6375              Expression =>
6376                Make_Selected_Component (Loc,
6377                  Prefix => Make_Identifier (Loc, Name_X),
6378                  Selector_Name => New_Copy (Name (Variant_Part (CL)))),
6379              Alternatives => Alt_List));
6380       end if;
6381
6382       return Result;
6383    end Make_Eq_Case;
6384
6385    ----------------
6386    -- Make_Eq_If --
6387    ----------------
6388
6389    --  Generates:
6390
6391    --    if
6392    --      X.C1 /= Y.C1
6393    --        or else
6394    --      X.C2 /= Y.C2
6395    --        ...
6396    --    then
6397    --       return False;
6398    --    end if;
6399
6400    --  or a null statement if the list L is empty
6401
6402    function Make_Eq_If
6403      (E : Entity_Id;
6404       L : List_Id) return Node_Id
6405    is
6406       Loc        : constant Source_Ptr := Sloc (E);
6407       C          : Node_Id;
6408       Field_Name : Name_Id;
6409       Cond       : Node_Id;
6410
6411    begin
6412       if No (L) then
6413          return Make_Null_Statement (Loc);
6414
6415       else
6416          Cond := Empty;
6417
6418          C := First_Non_Pragma (L);
6419          while Present (C) loop
6420             Field_Name := Chars (Defining_Identifier (C));
6421
6422             --  The tags must not be compared they are not part of the value.
6423             --  Note also that in the following, we use Make_Identifier for
6424             --  the component names. Use of New_Reference_To to identify the
6425             --  components would be incorrect because the wrong entities for
6426             --  discriminants could be picked up in the private type case.
6427
6428             if Field_Name /= Name_uTag then
6429                Evolve_Or_Else (Cond,
6430                  Make_Op_Ne (Loc,
6431                    Left_Opnd =>
6432                      Make_Selected_Component (Loc,
6433                        Prefix        => Make_Identifier (Loc, Name_X),
6434                        Selector_Name =>
6435                          Make_Identifier (Loc, Field_Name)),
6436
6437                    Right_Opnd =>
6438                      Make_Selected_Component (Loc,
6439                        Prefix        => Make_Identifier (Loc, Name_Y),
6440                        Selector_Name =>
6441                          Make_Identifier (Loc, Field_Name))));
6442             end if;
6443
6444             Next_Non_Pragma (C);
6445          end loop;
6446
6447          if No (Cond) then
6448             return Make_Null_Statement (Loc);
6449
6450          else
6451             return
6452               Make_Implicit_If_Statement (E,
6453                 Condition => Cond,
6454                 Then_Statements => New_List (
6455                   Make_Return_Statement (Loc,
6456                     Expression => New_Occurrence_Of (Standard_False, Loc))));
6457          end if;
6458       end if;
6459    end Make_Eq_If;
6460
6461    -------------------------------
6462    -- Make_Null_Procedure_Specs --
6463    -------------------------------
6464
6465    procedure Make_Null_Procedure_Specs
6466      (Tag_Typ   : Entity_Id;
6467       Decl_List : out List_Id)
6468    is
6469       Loc         : constant Source_Ptr := Sloc (Tag_Typ);
6470       Formal      : Entity_Id;
6471       Formal_List : List_Id;
6472       Parent_Subp : Entity_Id;
6473       Prim_Elmt   : Elmt_Id;
6474       Proc_Spec   : Node_Id;
6475       Proc_Decl   : Node_Id;
6476       Subp        : Entity_Id;
6477
6478       function Is_Null_Interface_Primitive (E : Entity_Id) return Boolean;
6479       --  Returns True if E is a null procedure that is an interface primitive
6480
6481       ---------------------------------
6482       -- Is_Null_Interface_Primitive --
6483       ---------------------------------
6484
6485       function Is_Null_Interface_Primitive (E : Entity_Id) return Boolean is
6486       begin
6487          return Comes_From_Source (E)
6488            and then Is_Dispatching_Operation (E)
6489            and then Ekind (E) = E_Procedure
6490            and then Null_Present (Parent (E))
6491            and then Is_Interface (Find_Dispatching_Type (E));
6492       end Is_Null_Interface_Primitive;
6493
6494    --  Start of processing for Make_Null_Procedure_Specs
6495
6496    begin
6497       Decl_List := New_List;
6498       Prim_Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
6499       while Present (Prim_Elmt) loop
6500          Subp := Node (Prim_Elmt);
6501
6502          --  If a null procedure inherited from an interface has not been
6503          --  overridden, then we build a null procedure declaration to
6504          --  override the inherited procedure.
6505
6506          Parent_Subp := Alias (Subp);
6507
6508          if Present (Parent_Subp)
6509            and then Is_Null_Interface_Primitive (Parent_Subp)
6510          then
6511             Formal_List := No_List;
6512             Formal := First_Formal (Subp);
6513
6514             if Present (Formal) then
6515                Formal_List := New_List;
6516
6517                while Present (Formal) loop
6518                   Append
6519                     (Make_Parameter_Specification (Loc,
6520                        Defining_Identifier =>
6521                          Make_Defining_Identifier (Sloc (Formal),
6522                            Chars => Chars (Formal)),
6523                        In_Present  => In_Present (Parent (Formal)),
6524                        Out_Present => Out_Present (Parent (Formal)),
6525                        Parameter_Type =>
6526                          New_Reference_To (Etype (Formal), Loc),
6527                        Expression =>
6528                          New_Copy_Tree (Expression (Parent (Formal)))),
6529                      Formal_List);
6530
6531                   Next_Formal (Formal);
6532                end loop;
6533             end if;
6534
6535             Proc_Spec :=
6536               Make_Procedure_Specification (Loc,
6537                 Defining_Unit_Name =>
6538                   Make_Defining_Identifier (Loc, Chars (Subp)),
6539                 Parameter_Specifications => Formal_List);
6540             Set_Null_Present (Proc_Spec);
6541
6542             Proc_Decl := Make_Subprogram_Declaration (Loc, Proc_Spec);
6543             Append_To (Decl_List, Proc_Decl);
6544             Analyze (Proc_Decl);
6545          end if;
6546
6547          Next_Elmt (Prim_Elmt);
6548       end loop;
6549    end Make_Null_Procedure_Specs;
6550
6551    -------------------------------------
6552    -- Make_Predefined_Primitive_Specs --
6553    -------------------------------------
6554
6555    procedure Make_Predefined_Primitive_Specs
6556      (Tag_Typ     : Entity_Id;
6557       Predef_List : out List_Id;
6558       Renamed_Eq  : out Node_Id)
6559    is
6560       Loc       : constant Source_Ptr := Sloc (Tag_Typ);
6561       Res       : constant List_Id    := New_List;
6562       Prim      : Elmt_Id;
6563       Eq_Needed : Boolean;
6564       Eq_Spec   : Node_Id;
6565       Eq_Name   : Name_Id := Name_Op_Eq;
6566
6567       function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean;
6568       --  Returns true if Prim is a renaming of an unresolved predefined
6569       --  equality operation.
6570
6571       -------------------------------
6572       -- Is_Predefined_Eq_Renaming --
6573       -------------------------------
6574
6575       function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean is
6576       begin
6577          return Chars (Prim) /= Name_Op_Eq
6578            and then Present (Alias (Prim))
6579            and then Comes_From_Source (Prim)
6580            and then Is_Intrinsic_Subprogram (Alias (Prim))
6581            and then Chars (Alias (Prim)) = Name_Op_Eq;
6582       end Is_Predefined_Eq_Renaming;
6583
6584    --  Start of processing for Make_Predefined_Primitive_Specs
6585
6586    begin
6587       Renamed_Eq := Empty;
6588
6589       --  Spec of _Size
6590
6591       Append_To (Res, Predef_Spec_Or_Body (Loc,
6592         Tag_Typ => Tag_Typ,
6593         Name    => Name_uSize,
6594         Profile => New_List (
6595           Make_Parameter_Specification (Loc,
6596             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
6597             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
6598
6599         Ret_Type => Standard_Long_Long_Integer));
6600
6601       --  Spec of _Alignment
6602
6603       Append_To (Res, Predef_Spec_Or_Body (Loc,
6604         Tag_Typ => Tag_Typ,
6605         Name    => Name_uAlignment,
6606         Profile => New_List (
6607           Make_Parameter_Specification (Loc,
6608             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
6609             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
6610
6611         Ret_Type => Standard_Integer));
6612
6613       --  Specs for dispatching stream attributes
6614
6615       declare
6616          Stream_Op_TSS_Names :
6617            constant array (Integer range <>) of TSS_Name_Type :=
6618              (TSS_Stream_Read,
6619               TSS_Stream_Write,
6620               TSS_Stream_Input,
6621               TSS_Stream_Output);
6622       begin
6623          for Op in Stream_Op_TSS_Names'Range loop
6624             if Stream_Operation_OK (Tag_Typ, Stream_Op_TSS_Names (Op)) then
6625                Append_To (Res,
6626                   Predef_Stream_Attr_Spec (Loc, Tag_Typ,
6627                     Stream_Op_TSS_Names (Op)));
6628             end if;
6629          end loop;
6630       end;
6631
6632       --  Spec of "=" if expanded if the type is not limited and if a
6633       --  user defined "=" was not already declared for the non-full
6634       --  view of a private extension
6635
6636       if not Is_Limited_Type (Tag_Typ) then
6637          Eq_Needed := True;
6638
6639          Prim := First_Elmt (Primitive_Operations (Tag_Typ));
6640          while Present (Prim) loop
6641
6642             --  If a primitive is encountered that renames the predefined
6643             --  equality operator before reaching any explicit equality
6644             --  primitive, then we still need to create a predefined
6645             --  equality function, because calls to it can occur via
6646             --  the renaming. A new name is created for the equality
6647             --  to avoid conflicting with any user-defined equality.
6648             --  (Note that this doesn't account for renamings of
6649             --  equality nested within subpackages???)
6650
6651             if Is_Predefined_Eq_Renaming (Node (Prim)) then
6652                Eq_Name := New_External_Name (Chars (Node (Prim)), 'E');
6653
6654             elsif Chars (Node (Prim)) = Name_Op_Eq
6655               and then (No (Alias (Node (Prim)))
6656                          or else Nkind (Unit_Declaration_Node (Node (Prim))) =
6657                                             N_Subprogram_Renaming_Declaration)
6658               and then Etype (First_Formal (Node (Prim))) =
6659                          Etype (Next_Formal (First_Formal (Node (Prim))))
6660               and then Base_Type (Etype (Node (Prim))) = Standard_Boolean
6661
6662             then
6663                Eq_Needed := False;
6664                exit;
6665
6666             --  If the parent equality is abstract, the inherited equality is
6667             --  abstract as well, and no body can be created for for it.
6668
6669             elsif Chars (Node (Prim)) = Name_Op_Eq
6670               and then Present (Alias (Node (Prim)))
6671               and then Is_Abstract (Alias (Node (Prim)))
6672             then
6673                Eq_Needed := False;
6674                exit;
6675             end if;
6676
6677             Next_Elmt (Prim);
6678          end loop;
6679
6680          --  If a renaming of predefined equality was found
6681          --  but there was no user-defined equality (so Eq_Needed
6682          --  is still true), then set the name back to Name_Op_Eq.
6683          --  But in the case where a user-defined equality was
6684          --  located after such a renaming, then the predefined
6685          --  equality function is still needed, so Eq_Needed must
6686          --  be set back to True.
6687
6688          if Eq_Name /= Name_Op_Eq then
6689             if Eq_Needed then
6690                Eq_Name := Name_Op_Eq;
6691             else
6692                Eq_Needed := True;
6693             end if;
6694          end if;
6695
6696          if Eq_Needed then
6697             Eq_Spec := Predef_Spec_Or_Body (Loc,
6698               Tag_Typ => Tag_Typ,
6699               Name    => Eq_Name,
6700               Profile => New_List (
6701                 Make_Parameter_Specification (Loc,
6702                   Defining_Identifier =>
6703                     Make_Defining_Identifier (Loc, Name_X),
6704                     Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
6705                 Make_Parameter_Specification (Loc,
6706                   Defining_Identifier =>
6707                     Make_Defining_Identifier (Loc, Name_Y),
6708                     Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
6709                 Ret_Type => Standard_Boolean);
6710             Append_To (Res, Eq_Spec);
6711
6712             if Eq_Name /= Name_Op_Eq then
6713                Renamed_Eq := Defining_Unit_Name (Specification (Eq_Spec));
6714
6715                Prim := First_Elmt (Primitive_Operations (Tag_Typ));
6716                while Present (Prim) loop
6717
6718                   --  Any renamings of equality that appeared before an
6719                   --  overriding equality must be updated to refer to
6720                   --  the entity for the predefined equality, otherwise
6721                   --  calls via the renaming would get incorrectly
6722                   --  resolved to call the user-defined equality function.
6723
6724                   if Is_Predefined_Eq_Renaming (Node (Prim)) then
6725                      Set_Alias (Node (Prim), Renamed_Eq);
6726
6727                   --  Exit upon encountering a user-defined equality
6728
6729                   elsif Chars (Node (Prim)) = Name_Op_Eq
6730                     and then No (Alias (Node (Prim)))
6731                   then
6732                      exit;
6733                   end if;
6734
6735                   Next_Elmt (Prim);
6736                end loop;
6737             end if;
6738          end if;
6739
6740          --  Spec for dispatching assignment
6741
6742          Append_To (Res, Predef_Spec_Or_Body (Loc,
6743            Tag_Typ => Tag_Typ,
6744            Name    => Name_uAssign,
6745            Profile => New_List (
6746              Make_Parameter_Specification (Loc,
6747                Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
6748                Out_Present         => True,
6749                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
6750
6751              Make_Parameter_Specification (Loc,
6752                Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
6753                Parameter_Type      => New_Reference_To (Tag_Typ, Loc)))));
6754       end if;
6755
6756       --  Generate the declarations for the following primitive operations:
6757
6758       --    disp_asynchronous_select
6759       --    disp_conditional_select
6760       --    disp_get_prim_op_kind
6761       --    disp_get_task_id
6762       --    disp_timed_select
6763
6764       --  for limited interfaces and synchronized types that implement a
6765       --  limited interface.
6766
6767       if Ada_Version >= Ada_05
6768         and then
6769           ((Is_Interface (Tag_Typ) and then Is_Limited_Record (Tag_Typ))
6770               or else
6771                 (Is_Concurrent_Record_Type (Tag_Typ)
6772                    and then Implements_Interface (
6773                               Typ          => Tag_Typ,
6774                               Kind         => Any_Limited_Interface,
6775                               Check_Parent => True)))
6776       then
6777          Append_To (Res,
6778            Make_Subprogram_Declaration (Loc,
6779              Specification =>
6780                Make_Disp_Asynchronous_Select_Spec (Tag_Typ)));
6781
6782          Append_To (Res,
6783            Make_Subprogram_Declaration (Loc,
6784              Specification =>
6785                Make_Disp_Conditional_Select_Spec (Tag_Typ)));
6786
6787          Append_To (Res,
6788            Make_Subprogram_Declaration (Loc,
6789              Specification =>
6790                Make_Disp_Get_Prim_Op_Kind_Spec (Tag_Typ)));
6791
6792          Append_To (Res,
6793            Make_Subprogram_Declaration (Loc,
6794              Specification =>
6795                Make_Disp_Get_Task_Id_Spec (Tag_Typ)));
6796
6797          Append_To (Res,
6798            Make_Subprogram_Declaration (Loc,
6799              Specification =>
6800                Make_Disp_Timed_Select_Spec (Tag_Typ)));
6801       end if;
6802
6803       --  Specs for finalization actions that may be required in case a
6804       --  future extension contain a controlled element. We generate those
6805       --  only for root tagged types where they will get dummy bodies or
6806       --  when the type has controlled components and their body must be
6807       --  generated. It is also impossible to provide those for tagged
6808       --  types defined within s-finimp since it would involve circularity
6809       --  problems
6810
6811       if In_Finalization_Root (Tag_Typ) then
6812          null;
6813
6814       --  We also skip these if finalization is not available
6815
6816       elsif Restriction_Active (No_Finalization) then
6817          null;
6818
6819       elsif Etype (Tag_Typ) = Tag_Typ
6820         or else Controlled_Type (Tag_Typ)
6821
6822          --  Ada 2005 (AI-251): We must also generate these subprograms if
6823          --  the immediate ancestor is an interface to ensure the correct
6824          --  initialization of its dispatch table.
6825
6826         or else (not Is_Interface (Tag_Typ)
6827                    and then
6828                  Is_Interface (Etype (Tag_Typ)))
6829       then
6830          if not Is_Limited_Type (Tag_Typ) then
6831             Append_To (Res,
6832               Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust));
6833          end if;
6834
6835          Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize));
6836       end if;
6837
6838       Predef_List := Res;
6839    end Make_Predefined_Primitive_Specs;
6840
6841    ---------------------------------
6842    -- Needs_Simple_Initialization --
6843    ---------------------------------
6844
6845    function Needs_Simple_Initialization (T : Entity_Id) return Boolean is
6846    begin
6847       --  Check for private type, in which case test applies to the
6848       --  underlying type of the private type.
6849
6850       if Is_Private_Type (T) then
6851          declare
6852             RT : constant Entity_Id := Underlying_Type (T);
6853
6854          begin
6855             if Present (RT) then
6856                return Needs_Simple_Initialization (RT);
6857             else
6858                return False;
6859             end if;
6860          end;
6861
6862       --  Cases needing simple initialization are access types, and, if pragma
6863       --  Normalize_Scalars or Initialize_Scalars is in effect, then all scalar
6864       --  types.
6865
6866       elsif Is_Access_Type (T)
6867         or else (Init_Or_Norm_Scalars and then (Is_Scalar_Type (T)))
6868       then
6869          return True;
6870
6871       --  If Initialize/Normalize_Scalars is in effect, string objects also
6872       --  need initialization, unless they are created in the course of
6873       --  expanding an aggregate (since in the latter case they will be
6874       --  filled with appropriate initializing values before they are used).
6875
6876       elsif Init_Or_Norm_Scalars
6877         and then
6878           (Root_Type (T) = Standard_String
6879              or else Root_Type (T) = Standard_Wide_String
6880              or else Root_Type (T) = Standard_Wide_Wide_String)
6881         and then
6882           (not Is_Itype (T)
6883             or else Nkind (Associated_Node_For_Itype (T)) /= N_Aggregate)
6884       then
6885          return True;
6886
6887       else
6888          return False;
6889       end if;
6890    end Needs_Simple_Initialization;
6891
6892    ----------------------
6893    -- Predef_Deep_Spec --
6894    ----------------------
6895
6896    function Predef_Deep_Spec
6897      (Loc      : Source_Ptr;
6898       Tag_Typ  : Entity_Id;
6899       Name     : TSS_Name_Type;
6900       For_Body : Boolean := False) return Node_Id
6901    is
6902       Prof   : List_Id;
6903       Type_B : Entity_Id;
6904
6905    begin
6906       if Name = TSS_Deep_Finalize then
6907          Prof := New_List;
6908          Type_B := Standard_Boolean;
6909
6910       else
6911          Prof := New_List (
6912            Make_Parameter_Specification (Loc,
6913              Defining_Identifier => Make_Defining_Identifier (Loc, Name_L),
6914              In_Present          => True,
6915              Out_Present         => True,
6916              Parameter_Type      =>
6917                New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
6918          Type_B := Standard_Short_Short_Integer;
6919       end if;
6920
6921       Append_To (Prof,
6922            Make_Parameter_Specification (Loc,
6923              Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
6924              In_Present          => True,
6925              Out_Present         => True,
6926              Parameter_Type      => New_Reference_To (Tag_Typ, Loc)));
6927
6928       Append_To (Prof,
6929            Make_Parameter_Specification (Loc,
6930              Defining_Identifier => Make_Defining_Identifier (Loc, Name_B),
6931              Parameter_Type      => New_Reference_To (Type_B, Loc)));
6932
6933       return Predef_Spec_Or_Body (Loc,
6934         Name     => Make_TSS_Name (Tag_Typ, Name),
6935         Tag_Typ  => Tag_Typ,
6936         Profile  => Prof,
6937         For_Body => For_Body);
6938
6939    exception
6940       when RE_Not_Available =>
6941          return Empty;
6942    end Predef_Deep_Spec;
6943
6944    -------------------------
6945    -- Predef_Spec_Or_Body --
6946    -------------------------
6947
6948    function Predef_Spec_Or_Body
6949      (Loc      : Source_Ptr;
6950       Tag_Typ  : Entity_Id;
6951       Name     : Name_Id;
6952       Profile  : List_Id;
6953       Ret_Type : Entity_Id := Empty;
6954       For_Body : Boolean := False) return Node_Id
6955    is
6956       Id   : constant Entity_Id := Make_Defining_Identifier (Loc, Name);
6957       Spec : Node_Id;
6958
6959    begin
6960       Set_Is_Public (Id, Is_Public (Tag_Typ));
6961
6962       --  The internal flag is set to mark these declarations because
6963       --  they have specific properties. First they are primitives even
6964       --  if they are not defined in the type scope (the freezing point
6965       --  is not necessarily in the same scope), furthermore the
6966       --  predefined equality can be overridden by a user-defined
6967       --  equality, no body will be generated in this case.
6968
6969       Set_Is_Internal (Id);
6970
6971       if not Debug_Generated_Code then
6972          Set_Debug_Info_Off (Id);
6973       end if;
6974
6975       if No (Ret_Type) then
6976          Spec :=
6977            Make_Procedure_Specification (Loc,
6978              Defining_Unit_Name       => Id,
6979              Parameter_Specifications => Profile);
6980       else
6981          Spec :=
6982            Make_Function_Specification (Loc,
6983              Defining_Unit_Name       => Id,
6984              Parameter_Specifications => Profile,
6985              Result_Definition        =>
6986                New_Reference_To (Ret_Type, Loc));
6987       end if;
6988
6989       --  If body case, return empty subprogram body. Note that this is
6990       --  ill-formed, because there is not even a null statement, and
6991       --  certainly not a return in the function case. The caller is
6992       --  expected to do surgery on the body to add the appropriate stuff.
6993
6994       if For_Body then
6995          return Make_Subprogram_Body (Loc, Spec, Empty_List, Empty);
6996
6997       --  For the case of Input/Output attributes applied to an abstract type,
6998       --  generate abstract specifications. These will never be called,
6999       --  but we need the slots allocated in the dispatching table so
7000       --  that typ'Class'Input and typ'Class'Output will work properly.
7001
7002       elsif (Is_TSS (Name, TSS_Stream_Input)
7003               or else
7004              Is_TSS (Name, TSS_Stream_Output))
7005         and then Is_Abstract (Tag_Typ)
7006       then
7007          return Make_Abstract_Subprogram_Declaration (Loc, Spec);
7008
7009       --  Normal spec case, where we return a subprogram declaration
7010
7011       else
7012          return Make_Subprogram_Declaration (Loc, Spec);
7013       end if;
7014    end Predef_Spec_Or_Body;
7015
7016    -----------------------------
7017    -- Predef_Stream_Attr_Spec --
7018    -----------------------------
7019
7020    function Predef_Stream_Attr_Spec
7021      (Loc      : Source_Ptr;
7022       Tag_Typ  : Entity_Id;
7023       Name     : TSS_Name_Type;
7024       For_Body : Boolean := False) return Node_Id
7025    is
7026       Ret_Type : Entity_Id;
7027
7028    begin
7029       if Name = TSS_Stream_Input then
7030          Ret_Type := Tag_Typ;
7031       else
7032          Ret_Type := Empty;
7033       end if;
7034
7035       return Predef_Spec_Or_Body (Loc,
7036         Name     => Make_TSS_Name (Tag_Typ, Name),
7037         Tag_Typ  => Tag_Typ,
7038         Profile  => Build_Stream_Attr_Profile (Loc, Tag_Typ, Name),
7039         Ret_Type => Ret_Type,
7040         For_Body => For_Body);
7041    end Predef_Stream_Attr_Spec;
7042
7043    ---------------------------------
7044    -- Predefined_Primitive_Bodies --
7045    ---------------------------------
7046
7047    function Predefined_Primitive_Bodies
7048      (Tag_Typ    : Entity_Id;
7049       Renamed_Eq : Node_Id) return List_Id
7050    is
7051       Loc       : constant Source_Ptr := Sloc (Tag_Typ);
7052       Res       : constant List_Id    := New_List;
7053       Decl      : Node_Id;
7054       Prim      : Elmt_Id;
7055       Eq_Needed : Boolean;
7056       Eq_Name   : Name_Id;
7057       Ent       : Entity_Id;
7058
7059    begin
7060       --  See if we have a predefined "=" operator
7061
7062       if Present (Renamed_Eq) then
7063          Eq_Needed := True;
7064          Eq_Name   := Chars (Renamed_Eq);
7065
7066       else
7067          Eq_Needed := False;
7068          Eq_Name   := No_Name;
7069
7070          Prim := First_Elmt (Primitive_Operations (Tag_Typ));
7071          while Present (Prim) loop
7072             if Chars (Node (Prim)) = Name_Op_Eq
7073               and then Is_Internal (Node (Prim))
7074             then
7075                Eq_Needed := True;
7076                Eq_Name := Name_Op_Eq;
7077             end if;
7078
7079             Next_Elmt (Prim);
7080          end loop;
7081       end if;
7082
7083       --  Body of _Alignment
7084
7085       Decl := Predef_Spec_Or_Body (Loc,
7086         Tag_Typ => Tag_Typ,
7087         Name    => Name_uAlignment,
7088         Profile => New_List (
7089           Make_Parameter_Specification (Loc,
7090             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
7091             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
7092
7093         Ret_Type => Standard_Integer,
7094         For_Body => True);
7095
7096       Set_Handled_Statement_Sequence (Decl,
7097         Make_Handled_Sequence_Of_Statements (Loc, New_List (
7098           Make_Return_Statement (Loc,
7099             Expression =>
7100               Make_Attribute_Reference (Loc,
7101                 Prefix => Make_Identifier (Loc, Name_X),
7102                 Attribute_Name  => Name_Alignment)))));
7103
7104       Append_To (Res, Decl);
7105
7106       --  Body of _Size
7107
7108       Decl := Predef_Spec_Or_Body (Loc,
7109         Tag_Typ => Tag_Typ,
7110         Name    => Name_uSize,
7111         Profile => New_List (
7112           Make_Parameter_Specification (Loc,
7113             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
7114             Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
7115
7116         Ret_Type => Standard_Long_Long_Integer,
7117         For_Body => True);
7118
7119       Set_Handled_Statement_Sequence (Decl,
7120         Make_Handled_Sequence_Of_Statements (Loc, New_List (
7121           Make_Return_Statement (Loc,
7122             Expression =>
7123               Make_Attribute_Reference (Loc,
7124                 Prefix => Make_Identifier (Loc, Name_X),
7125                 Attribute_Name  => Name_Size)))));
7126
7127       Append_To (Res, Decl);
7128
7129       --  Bodies for Dispatching stream IO routines. We need these only for
7130       --  non-limited types (in the limited case there is no dispatching).
7131       --  We also skip them if dispatching or finalization are not available.
7132
7133       if Stream_Operation_OK (Tag_Typ, TSS_Stream_Read)
7134         and then No (TSS (Tag_Typ, TSS_Stream_Read))
7135       then
7136          Build_Record_Read_Procedure (Loc, Tag_Typ, Decl, Ent);
7137          Append_To (Res, Decl);
7138       end if;
7139
7140       if Stream_Operation_OK (Tag_Typ, TSS_Stream_Write)
7141         and then No (TSS (Tag_Typ, TSS_Stream_Write))
7142       then
7143          Build_Record_Write_Procedure (Loc, Tag_Typ, Decl, Ent);
7144          Append_To (Res, Decl);
7145       end if;
7146
7147       --  Skip bodies of _Input and _Output for the abstract case, since
7148       --  the corresponding specs are abstract (see Predef_Spec_Or_Body)
7149
7150       if not Is_Abstract (Tag_Typ) then
7151          if Stream_Operation_OK (Tag_Typ, TSS_Stream_Input)
7152            and then No (TSS (Tag_Typ, TSS_Stream_Input))
7153          then
7154             Build_Record_Or_Elementary_Input_Function
7155               (Loc, Tag_Typ, Decl, Ent);
7156             Append_To (Res, Decl);
7157          end if;
7158
7159          if Stream_Operation_OK (Tag_Typ, TSS_Stream_Output)
7160            and then No (TSS (Tag_Typ, TSS_Stream_Output))
7161          then
7162             Build_Record_Or_Elementary_Output_Procedure
7163               (Loc, Tag_Typ, Decl, Ent);
7164             Append_To (Res, Decl);
7165          end if;
7166       end if;
7167
7168       --  Generate the bodies for the following primitive operations:
7169
7170       --    disp_asynchronous_select
7171       --    disp_conditional_select
7172       --    disp_get_prim_op_kind
7173       --    disp_get_task_id
7174       --    disp_timed_select
7175
7176       --  for limited interfaces and synchronized types that implement a
7177       --  limited interface. The interface versions will have null bodies.
7178
7179       if Ada_Version >= Ada_05
7180         and then
7181           not Restriction_Active (No_Dispatching_Calls)
7182         and then
7183           ((Is_Interface (Tag_Typ) and then Is_Limited_Record (Tag_Typ))
7184               or else
7185                 (Is_Concurrent_Record_Type (Tag_Typ)
7186                    and then Implements_Interface (
7187                               Typ          => Tag_Typ,
7188                               Kind         => Any_Limited_Interface,
7189                               Check_Parent => True)))
7190       then
7191          Append_To (Res, Make_Disp_Asynchronous_Select_Body (Tag_Typ));
7192          Append_To (Res, Make_Disp_Conditional_Select_Body  (Tag_Typ));
7193          Append_To (Res, Make_Disp_Get_Prim_Op_Kind_Body    (Tag_Typ));
7194          Append_To (Res, Make_Disp_Get_Task_Id_Body         (Tag_Typ));
7195          Append_To (Res, Make_Disp_Timed_Select_Body        (Tag_Typ));
7196       end if;
7197
7198       if not Is_Limited_Type (Tag_Typ) then
7199
7200          --  Body for equality
7201
7202          if Eq_Needed then
7203             Decl :=
7204               Predef_Spec_Or_Body (Loc,
7205                 Tag_Typ => Tag_Typ,
7206                 Name    => Eq_Name,
7207                 Profile => New_List (
7208                   Make_Parameter_Specification (Loc,
7209                     Defining_Identifier =>
7210                       Make_Defining_Identifier (Loc, Name_X),
7211                     Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
7212
7213                   Make_Parameter_Specification (Loc,
7214                     Defining_Identifier =>
7215                       Make_Defining_Identifier (Loc, Name_Y),
7216                     Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
7217
7218                 Ret_Type => Standard_Boolean,
7219                 For_Body => True);
7220
7221             declare
7222                Def          : constant Node_Id := Parent (Tag_Typ);
7223                Stmts        : constant List_Id := New_List;
7224                Variant_Case : Boolean := Has_Discriminants (Tag_Typ);
7225                Comps        : Node_Id := Empty;
7226                Typ_Def      : Node_Id := Type_Definition (Def);
7227
7228             begin
7229                if Variant_Case then
7230                   if Nkind (Typ_Def) = N_Derived_Type_Definition then
7231                      Typ_Def := Record_Extension_Part (Typ_Def);
7232                   end if;
7233
7234                   if Present (Typ_Def) then
7235                      Comps := Component_List (Typ_Def);
7236                   end if;
7237
7238                   Variant_Case := Present (Comps)
7239                     and then Present (Variant_Part (Comps));
7240                end if;
7241
7242                if Variant_Case then
7243                   Append_To (Stmts,
7244                     Make_Eq_If (Tag_Typ, Discriminant_Specifications (Def)));
7245                   Append_List_To (Stmts, Make_Eq_Case (Tag_Typ, Comps));
7246                   Append_To (Stmts,
7247                     Make_Return_Statement (Loc,
7248                       Expression => New_Reference_To (Standard_True, Loc)));
7249
7250                else
7251                   Append_To (Stmts,
7252                     Make_Return_Statement (Loc,
7253                       Expression =>
7254                         Expand_Record_Equality (Tag_Typ,
7255                           Typ => Tag_Typ,
7256                           Lhs => Make_Identifier (Loc, Name_X),
7257                           Rhs => Make_Identifier (Loc, Name_Y),
7258                           Bodies => Declarations (Decl))));
7259                end if;
7260
7261                Set_Handled_Statement_Sequence (Decl,
7262                  Make_Handled_Sequence_Of_Statements (Loc, Stmts));
7263             end;
7264             Append_To (Res, Decl);
7265          end if;
7266
7267          --  Body for dispatching assignment
7268
7269          Decl :=
7270            Predef_Spec_Or_Body (Loc,
7271              Tag_Typ => Tag_Typ,
7272              Name    => Name_uAssign,
7273              Profile => New_List (
7274                Make_Parameter_Specification (Loc,
7275                  Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
7276                  Out_Present         => True,
7277                  Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
7278
7279                Make_Parameter_Specification (Loc,
7280                  Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
7281                  Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
7282              For_Body => True);
7283
7284          Set_Handled_Statement_Sequence (Decl,
7285            Make_Handled_Sequence_Of_Statements (Loc, New_List (
7286              Make_Assignment_Statement (Loc,
7287                Name       => Make_Identifier (Loc, Name_X),
7288                Expression => Make_Identifier (Loc, Name_Y)))));
7289
7290          Append_To (Res, Decl);
7291       end if;
7292
7293       --  Generate dummy bodies for finalization actions of types that have
7294       --  no controlled components.
7295
7296       --  Skip this processing if we are in the finalization routine in the
7297       --  runtime itself, otherwise we get hopelessly circularly confused!
7298
7299       if In_Finalization_Root (Tag_Typ) then
7300          null;
7301
7302       --  Skip this if finalization is not available
7303
7304       elsif Restriction_Active (No_Finalization) then
7305          null;
7306
7307       elsif (Etype (Tag_Typ) = Tag_Typ
7308              or else Is_Controlled (Tag_Typ)
7309
7310                --  Ada 2005 (AI-251): We must also generate these subprograms
7311                --  if the immediate ancestor of Tag_Typ is an interface to
7312                --  ensure the correct initialization of its dispatch table.
7313
7314              or else (not Is_Interface (Tag_Typ)
7315                         and then
7316                       Is_Interface (Etype (Tag_Typ))))
7317         and then not Has_Controlled_Component (Tag_Typ)
7318       then
7319          if not Is_Limited_Type (Tag_Typ) then
7320             Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust, True);
7321
7322             if Is_Controlled (Tag_Typ) then
7323                Set_Handled_Statement_Sequence (Decl,
7324                  Make_Handled_Sequence_Of_Statements (Loc,
7325                    Make_Adjust_Call (
7326                      Ref          => Make_Identifier (Loc, Name_V),
7327                      Typ          => Tag_Typ,
7328                      Flist_Ref    => Make_Identifier (Loc, Name_L),
7329                      With_Attach  => Make_Identifier (Loc, Name_B))));
7330
7331             else
7332                Set_Handled_Statement_Sequence (Decl,
7333                  Make_Handled_Sequence_Of_Statements (Loc, New_List (
7334                    Make_Null_Statement (Loc))));
7335             end if;
7336
7337             Append_To (Res, Decl);
7338          end if;
7339
7340          Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True);
7341
7342          if Is_Controlled (Tag_Typ) then
7343             Set_Handled_Statement_Sequence (Decl,
7344               Make_Handled_Sequence_Of_Statements (Loc,
7345                 Make_Final_Call (
7346                   Ref         => Make_Identifier (Loc, Name_V),
7347                   Typ         => Tag_Typ,
7348                   With_Detach => Make_Identifier (Loc, Name_B))));
7349
7350          else
7351             Set_Handled_Statement_Sequence (Decl,
7352               Make_Handled_Sequence_Of_Statements (Loc, New_List (
7353                 Make_Null_Statement (Loc))));
7354          end if;
7355
7356          Append_To (Res, Decl);
7357       end if;
7358
7359       return Res;
7360    end Predefined_Primitive_Bodies;
7361
7362    ---------------------------------
7363    -- Predefined_Primitive_Freeze --
7364    ---------------------------------
7365
7366    function Predefined_Primitive_Freeze
7367      (Tag_Typ : Entity_Id) return List_Id
7368    is
7369       Loc     : constant Source_Ptr := Sloc (Tag_Typ);
7370       Res     : constant List_Id    := New_List;
7371       Prim    : Elmt_Id;
7372       Frnodes : List_Id;
7373
7374    begin
7375       Prim := First_Elmt (Primitive_Operations (Tag_Typ));
7376       while Present (Prim) loop
7377          if Is_Internal (Node (Prim)) then
7378             Frnodes := Freeze_Entity (Node (Prim), Loc);
7379
7380             if Present (Frnodes) then
7381                Append_List_To (Res, Frnodes);
7382             end if;
7383          end if;
7384
7385          Next_Elmt (Prim);
7386       end loop;
7387
7388       return Res;
7389    end Predefined_Primitive_Freeze;
7390
7391    -------------------------
7392    -- Stream_Operation_OK --
7393    -------------------------
7394
7395    function Stream_Operation_OK
7396      (Typ       : Entity_Id;
7397       Operation : TSS_Name_Type) return Boolean
7398    is
7399       Has_Inheritable_Stream_Attribute : Boolean := False;
7400
7401    begin
7402       if Is_Limited_Type (Typ)
7403         and then Is_Tagged_Type (Typ)
7404         and then Is_Derived_Type (Typ)
7405       then
7406          --  Special case of a limited type extension: a default implementation
7407          --  of the stream attributes Read and Write exists if the attribute
7408          --  has been specified for an ancestor type.
7409
7410          Has_Inheritable_Stream_Attribute :=
7411            Present (Find_Inherited_TSS (Base_Type (Etype (Typ)), Operation));
7412       end if;
7413
7414       return
7415         not (Is_Limited_Type (Typ)
7416                and then not Has_Inheritable_Stream_Attribute)
7417           and then not Has_Unknown_Discriminants (Typ)
7418           and then RTE_Available (RE_Tag)
7419           and then RTE_Available (RE_Root_Stream_Type)
7420           and then not Restriction_Active (No_Dispatch)
7421           and then not Restriction_Active (No_Streams);
7422    end Stream_Operation_OK;
7423 end Exp_Ch3;