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-2018, 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 3,  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 COPYING3.  If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license.          --
20--                                                                          --
21-- GNAT was originally developed  by the GNAT team at  New York University. --
22-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23--                                                                          --
24------------------------------------------------------------------------------
25
26with Aspects;  use Aspects;
27with Atree;    use Atree;
28with Checks;   use Checks;
29with Einfo;    use Einfo;
30with Errout;   use Errout;
31with Exp_Aggr; use Exp_Aggr;
32with Exp_Atag; use Exp_Atag;
33with Exp_Ch4;  use Exp_Ch4;
34with Exp_Ch6;  use Exp_Ch6;
35with Exp_Ch7;  use Exp_Ch7;
36with Exp_Ch9;  use Exp_Ch9;
37with Exp_Dbug; use Exp_Dbug;
38with Exp_Disp; use Exp_Disp;
39with Exp_Dist; use Exp_Dist;
40with Exp_Smem; use Exp_Smem;
41with Exp_Strm; use Exp_Strm;
42with Exp_Tss;  use Exp_Tss;
43with Exp_Util; use Exp_Util;
44with Freeze;   use Freeze;
45with Ghost;    use Ghost;
46with Lib;      use Lib;
47with Namet;    use Namet;
48with Nlists;   use Nlists;
49with Nmake;    use Nmake;
50with Opt;      use Opt;
51with Restrict; use Restrict;
52with Rident;   use Rident;
53with Rtsfind;  use Rtsfind;
54with Sem;      use Sem;
55with Sem_Aux;  use Sem_Aux;
56with Sem_Attr; use Sem_Attr;
57with Sem_Cat;  use Sem_Cat;
58with Sem_Ch3;  use Sem_Ch3;
59with Sem_Ch6;  use Sem_Ch6;
60with Sem_Ch8;  use Sem_Ch8;
61with Sem_Disp; use Sem_Disp;
62with Sem_Eval; use Sem_Eval;
63with Sem_Mech; use Sem_Mech;
64with Sem_Res;  use Sem_Res;
65with Sem_SCIL; use Sem_SCIL;
66with Sem_Type; use Sem_Type;
67with Sem_Util; use Sem_Util;
68with Sinfo;    use Sinfo;
69with Stand;    use Stand;
70with Snames;   use Snames;
71with Tbuild;   use Tbuild;
72with Ttypes;   use Ttypes;
73with Validsw;  use Validsw;
74
75package body Exp_Ch3 is
76
77   -----------------------
78   -- Local Subprograms --
79   -----------------------
80
81   procedure Adjust_Discriminants (Rtype : Entity_Id);
82   --  This is used when freezing a record type. It attempts to construct
83   --  more restrictive subtypes for discriminants so that the max size of
84   --  the record can be calculated more accurately. See the body of this
85   --  procedure for details.
86
87   procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id);
88   --  Build initialization procedure for given array type. Nod is a node
89   --  used for attachment of any actions required in its construction.
90   --  It also supplies the source location used for the procedure.
91
92   function Build_Discriminant_Formals
93     (Rec_Id : Entity_Id;
94      Use_Dl : Boolean) return List_Id;
95   --  This function uses the discriminants of a type to build a list of
96   --  formal parameters, used in Build_Init_Procedure among other places.
97   --  If the flag Use_Dl is set, the list is built using the already
98   --  defined discriminals of the type, as is the case for concurrent
99   --  types with discriminants. Otherwise new identifiers are created,
100   --  with the source names of the discriminants.
101
102   function Build_Equivalent_Array_Aggregate (T : Entity_Id) return Node_Id;
103   --  This function builds a static aggregate that can serve as the initial
104   --  value for an array type whose bounds are static, and whose component
105   --  type is a composite type that has a static equivalent aggregate.
106   --  The equivalent array aggregate is used both for object initialization
107   --  and for component initialization, when used in the following function.
108
109   function Build_Equivalent_Record_Aggregate (T : Entity_Id) return Node_Id;
110   --  This function builds a static aggregate that can serve as the initial
111   --  value for a record type whose components are scalar and initialized
112   --  with compile-time values, or arrays with similar initialization or
113   --  defaults. When possible, initialization of an object of the type can
114   --  be achieved by using a copy of the aggregate as an initial value, thus
115   --  removing the implicit call that would otherwise constitute elaboration
116   --  code.
117
118   procedure Build_Record_Init_Proc (N : Node_Id; Rec_Ent : Entity_Id);
119   --  Build record initialization procedure. N is the type declaration
120   --  node, and Rec_Ent is the corresponding entity for the record type.
121
122   procedure Build_Slice_Assignment (Typ : Entity_Id);
123   --  Build assignment procedure for one-dimensional arrays of controlled
124   --  types. Other array and slice assignments are expanded in-line, but
125   --  the code expansion for controlled components (when control actions
126   --  are active) can lead to very large blocks that GCC3 handles poorly.
127
128   procedure Build_Untagged_Equality (Typ : Entity_Id);
129   --  AI05-0123: Equality on untagged records composes. This procedure
130   --  builds the equality routine for an untagged record that has components
131   --  of a record type that has user-defined primitive equality operations.
132   --  The resulting operation is a TSS subprogram.
133
134   procedure Build_Variant_Record_Equality (Typ  : Entity_Id);
135   --  Create An Equality function for the untagged variant record Typ and
136   --  attach it to the TSS list
137
138   procedure Check_Stream_Attributes (Typ : Entity_Id);
139   --  Check that if a limited extension has a parent with user-defined stream
140   --  attributes, and does not itself have user-defined stream-attributes,
141   --  then any limited component of the extension also has the corresponding
142   --  user-defined stream attributes.
143
144   procedure Clean_Task_Names
145     (Typ     : Entity_Id;
146      Proc_Id : Entity_Id);
147   --  If an initialization procedure includes calls to generate names
148   --  for task subcomponents, indicate that secondary stack cleanup is
149   --  needed after an initialization. Typ is the component type, and Proc_Id
150   --  the initialization procedure for the enclosing composite type.
151
152   procedure Expand_Freeze_Array_Type (N : Node_Id);
153   --  Freeze an array type. Deals with building the initialization procedure,
154   --  creating the packed array type for a packed array and also with the
155   --  creation of the controlling procedures for the controlled case. The
156   --  argument N is the N_Freeze_Entity node for the type.
157
158   procedure Expand_Freeze_Class_Wide_Type (N : Node_Id);
159   --  Freeze a class-wide type. Build routine Finalize_Address for the purpose
160   --  of finalizing controlled derivations from the class-wide's root type.
161
162   procedure Expand_Freeze_Enumeration_Type (N : Node_Id);
163   --  Freeze enumeration type with non-standard representation. Builds the
164   --  array and function needed to convert between enumeration pos and
165   --  enumeration representation values. N is the N_Freeze_Entity node
166   --  for the type.
167
168   procedure Expand_Freeze_Record_Type (N : Node_Id);
169   --  Freeze record type. Builds all necessary discriminant checking
170   --  and other ancillary functions, and builds dispatch tables where
171   --  needed. The argument N is the N_Freeze_Entity node. This processing
172   --  applies only to E_Record_Type entities, not to class wide types,
173   --  record subtypes, or private types.
174
175   procedure Expand_Tagged_Root (T : Entity_Id);
176   --  Add a field _Tag at the beginning of the record. This field carries
177   --  the value of the access to the Dispatch table. This procedure is only
178   --  called on root type, the _Tag field being inherited by the descendants.
179
180   procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id);
181   --  Treat user-defined stream operations as renaming_as_body if the
182   --  subprogram they rename is not frozen when the type is frozen.
183
184   procedure Initialization_Warning (E : Entity_Id);
185   --  If static elaboration of the package is requested, indicate
186   --  when a type does meet the conditions for static initialization. If
187   --  E is a type, it has components that have no static initialization.
188   --  if E is an entity, its initial expression is not compile-time known.
189
190   function Init_Formals (Typ : Entity_Id) return List_Id;
191   --  This function builds the list of formals for an initialization routine.
192   --  The first formal is always _Init with the given type. For task value
193   --  record types and types containing tasks, three additional formals are
194   --  added:
195   --
196   --    _Master    : Master_Id
197   --    _Chain     : in out Activation_Chain
198   --    _Task_Name : String
199   --
200   --  The caller must append additional entries for discriminants if required.
201
202   function Inline_Init_Proc (Typ : Entity_Id) return Boolean;
203   --  Returns true if the initialization procedure of Typ should be inlined
204
205   function In_Runtime (E : Entity_Id) return Boolean;
206   --  Check if E is defined in the RTL (in a child of Ada or System). Used
207   --  to avoid to bring in the overhead of _Input, _Output for tagged types.
208
209   function Is_User_Defined_Equality (Prim : Node_Id) return Boolean;
210   --  Returns true if Prim is a user defined equality function
211
212   function Make_Eq_Body
213     (Typ     : Entity_Id;
214      Eq_Name : Name_Id) return Node_Id;
215   --  Build the body of a primitive equality operation for a tagged record
216   --  type, or in Ada 2012 for any record type that has components with a
217   --  user-defined equality. Factored out of Predefined_Primitive_Bodies.
218
219   function Make_Eq_Case
220     (E      : Entity_Id;
221      CL     : Node_Id;
222      Discrs : Elist_Id := New_Elmt_List) return List_Id;
223   --  Building block for variant record equality. Defined to share the code
224   --  between the tagged and untagged case. Given a Component_List node CL,
225   --  it generates an 'if' followed by a 'case' statement that compares all
226   --  components of local temporaries named X and Y (that are declared as
227   --  formals at some upper level). E provides the Sloc to be used for the
228   --  generated code.
229   --
230   --  IF E is an unchecked_union,  Discrs is the list of formals created for
231   --  the inferred discriminants of one operand. These formals are used in
232   --  the generated case statements for each variant of the unchecked union.
233
234   function Make_Eq_If
235     (E : Entity_Id;
236      L : List_Id) return Node_Id;
237   --  Building block for variant record equality. Defined to share the code
238   --  between the tagged and untagged case. Given the list of components
239   --  (or discriminants) L, it generates a return statement that compares all
240   --  components of local temporaries named X and Y (that are declared as
241   --  formals at some upper level). E provides the Sloc to be used for the
242   --  generated code.
243
244   function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id;
245   --  Search for a renaming of the inequality dispatching primitive of
246   --  this tagged type. If found then build and return the corresponding
247   --  rename-as-body inequality subprogram; otherwise return Empty.
248
249   procedure Make_Predefined_Primitive_Specs
250     (Tag_Typ     : Entity_Id;
251      Predef_List : out List_Id;
252      Renamed_Eq  : out Entity_Id);
253   --  Create a list with the specs of the predefined primitive operations.
254   --  For tagged types that are interfaces all these primitives are defined
255   --  abstract.
256   --
257   --  The following entries are present for all tagged types, and provide
258   --  the results of the corresponding attribute applied to the object.
259   --  Dispatching is required in general, since the result of the attribute
260   --  will vary with the actual object subtype.
261   --
262   --     _size          provides result of 'Size attribute
263   --     typSR          provides result of 'Read attribute
264   --     typSW          provides result of 'Write attribute
265   --     typSI          provides result of 'Input attribute
266   --     typSO          provides result of 'Output attribute
267   --
268   --  The following entries are additionally present for non-limited tagged
269   --  types, and implement additional dispatching operations for predefined
270   --  operations:
271   --
272   --     _equality      implements "=" operator
273   --     _assign        implements assignment operation
274   --     typDF          implements deep finalization
275   --     typDA          implements deep adjust
276   --
277   --  The latter two are empty procedures unless the type contains some
278   --  controlled components that require finalization actions (the deep
279   --  in the name refers to the fact that the action applies to components).
280   --
281   --  The list is returned in Predef_List. The Parameter Renamed_Eq either
282   --  returns the value Empty, or else the defining unit name for the
283   --  predefined equality function in the case where the type has a primitive
284   --  operation that is a renaming of predefined equality (but only if there
285   --  is also an overriding user-defined equality function). The returned
286   --  Renamed_Eq will be passed to the corresponding parameter of
287   --  Predefined_Primitive_Bodies.
288
289   function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean;
290   --  Returns True if there are representation clauses for type T that are not
291   --  inherited. If the result is false, the init_proc and the discriminant
292   --  checking functions of the parent can be reused by a derived type.
293
294   procedure Make_Controlling_Function_Wrappers
295     (Tag_Typ   : Entity_Id;
296      Decl_List : out List_Id;
297      Body_List : out List_Id);
298   --  Ada 2005 (AI-391): Makes specs and bodies for the wrapper functions
299   --  associated with inherited functions with controlling results which
300   --  are not overridden. The body of each wrapper function consists solely
301   --  of a return statement whose expression is an extension aggregate
302   --  invoking the inherited subprogram's parent subprogram and extended
303   --  with a null association list.
304
305   function Make_Null_Procedure_Specs (Tag_Typ : Entity_Id) return List_Id;
306   --  Ada 2005 (AI-251): Makes specs for null procedures associated with any
307   --  null procedures inherited from an interface type that have not been
308   --  overridden. Only one null procedure will be created for a given set of
309   --  inherited null procedures with homographic profiles.
310
311   function Predef_Spec_Or_Body
312     (Loc      : Source_Ptr;
313      Tag_Typ  : Entity_Id;
314      Name     : Name_Id;
315      Profile  : List_Id;
316      Ret_Type : Entity_Id := Empty;
317      For_Body : Boolean   := False) return Node_Id;
318   --  This function generates the appropriate expansion for a predefined
319   --  primitive operation specified by its name, parameter profile and
320   --  return type (Empty means this is a procedure). If For_Body is false,
321   --  then the returned node is a subprogram declaration. If For_Body is
322   --  true, then the returned node is a empty subprogram body containing
323   --  no declarations and no statements.
324
325   function Predef_Stream_Attr_Spec
326     (Loc      : Source_Ptr;
327      Tag_Typ  : Entity_Id;
328      Name     : TSS_Name_Type;
329      For_Body : Boolean := False) return Node_Id;
330   --  Specialized version of Predef_Spec_Or_Body that apply to read, write,
331   --  input and output attribute whose specs are constructed in Exp_Strm.
332
333   function Predef_Deep_Spec
334     (Loc      : Source_Ptr;
335      Tag_Typ  : Entity_Id;
336      Name     : TSS_Name_Type;
337      For_Body : Boolean := False) return Node_Id;
338   --  Specialized version of Predef_Spec_Or_Body that apply to _deep_adjust
339   --  and _deep_finalize
340
341   function Predefined_Primitive_Bodies
342     (Tag_Typ    : Entity_Id;
343      Renamed_Eq : Entity_Id) return List_Id;
344   --  Create the bodies of the predefined primitives that are described in
345   --  Predefined_Primitive_Specs. When not empty, Renamed_Eq must denote
346   --  the defining unit name of the type's predefined equality as returned
347   --  by Make_Predefined_Primitive_Specs.
348
349   function Predefined_Primitive_Freeze (Tag_Typ : Entity_Id) return List_Id;
350   --  Freeze entities of all predefined primitive operations. This is needed
351   --  because the bodies of these operations do not normally do any freezing.
352
353   function Stream_Operation_OK
354     (Typ       : Entity_Id;
355      Operation : TSS_Name_Type) return Boolean;
356   --  Check whether the named stream operation must be emitted for a given
357   --  type. The rules for inheritance of stream attributes by type extensions
358   --  are enforced by this function. Furthermore, various restrictions prevent
359   --  the generation of these operations, as a useful optimization or for
360   --  certification purposes and to save unnecessary generated code.
361
362   --------------------------
363   -- Adjust_Discriminants --
364   --------------------------
365
366   --  This procedure attempts to define subtypes for discriminants that are
367   --  more restrictive than those declared. Such a replacement is possible if
368   --  we can demonstrate that values outside the restricted range would cause
369   --  constraint errors in any case. The advantage of restricting the
370   --  discriminant types in this way is that the maximum size of the variant
371   --  record can be calculated more conservatively.
372
373   --  An example of a situation in which we can perform this type of
374   --  restriction is the following:
375
376   --    subtype B is range 1 .. 10;
377   --    type Q is array (B range <>) of Integer;
378
379   --    type V (N : Natural) is record
380   --       C : Q (1 .. N);
381   --    end record;
382
383   --  In this situation, we can restrict the upper bound of N to 10, since
384   --  any larger value would cause a constraint error in any case.
385
386   --  There are many situations in which such restriction is possible, but
387   --  for now, we just look for cases like the above, where the component
388   --  in question is a one dimensional array whose upper bound is one of
389   --  the record discriminants. Also the component must not be part of
390   --  any variant part, since then the component does not always exist.
391
392   procedure Adjust_Discriminants (Rtype : Entity_Id) is
393      Loc   : constant Source_Ptr := Sloc (Rtype);
394      Comp  : Entity_Id;
395      Ctyp  : Entity_Id;
396      Ityp  : Entity_Id;
397      Lo    : Node_Id;
398      Hi    : Node_Id;
399      P     : Node_Id;
400      Loval : Uint;
401      Discr : Entity_Id;
402      Dtyp  : Entity_Id;
403      Dhi   : Node_Id;
404      Dhiv  : Uint;
405      Ahi   : Node_Id;
406      Ahiv  : Uint;
407      Tnn   : Entity_Id;
408
409   begin
410      Comp := First_Component (Rtype);
411      while Present (Comp) loop
412
413         --  If our parent is a variant, quit, we do not look at components
414         --  that are in variant parts, because they may not always exist.
415
416         P := Parent (Comp);   -- component declaration
417         P := Parent (P);      -- component list
418
419         exit when Nkind (Parent (P)) = N_Variant;
420
421         --  We are looking for a one dimensional array type
422
423         Ctyp := Etype (Comp);
424
425         if not Is_Array_Type (Ctyp) or else Number_Dimensions (Ctyp) > 1 then
426            goto Continue;
427         end if;
428
429         --  The lower bound must be constant, and the upper bound is a
430         --  discriminant (which is a discriminant of the current record).
431
432         Ityp := Etype (First_Index (Ctyp));
433         Lo := Type_Low_Bound (Ityp);
434         Hi := Type_High_Bound (Ityp);
435
436         if not Compile_Time_Known_Value (Lo)
437           or else Nkind (Hi) /= N_Identifier
438           or else No (Entity (Hi))
439           or else Ekind (Entity (Hi)) /= E_Discriminant
440         then
441            goto Continue;
442         end if;
443
444         --  We have an array with appropriate bounds
445
446         Loval := Expr_Value (Lo);
447         Discr := Entity (Hi);
448         Dtyp  := Etype (Discr);
449
450         --  See if the discriminant has a known upper bound
451
452         Dhi := Type_High_Bound (Dtyp);
453
454         if not Compile_Time_Known_Value (Dhi) then
455            goto Continue;
456         end if;
457
458         Dhiv := Expr_Value (Dhi);
459
460         --  See if base type of component array has known upper bound
461
462         Ahi := Type_High_Bound (Etype (First_Index (Base_Type (Ctyp))));
463
464         if not Compile_Time_Known_Value (Ahi) then
465            goto Continue;
466         end if;
467
468         Ahiv := Expr_Value (Ahi);
469
470         --  The condition for doing the restriction is that the high bound
471         --  of the discriminant is greater than the low bound of the array,
472         --  and is also greater than the high bound of the base type index.
473
474         if Dhiv > Loval and then Dhiv > Ahiv then
475
476            --  We can reset the upper bound of the discriminant type to
477            --  whichever is larger, the low bound of the component, or
478            --  the high bound of the base type array index.
479
480            --  We build a subtype that is declared as
481
482            --     subtype Tnn is discr_type range discr_type'First .. max;
483
484            --  And insert this declaration into the tree. The type of the
485            --  discriminant is then reset to this more restricted subtype.
486
487            Tnn := Make_Temporary (Loc, 'T');
488
489            Insert_Action (Declaration_Node (Rtype),
490              Make_Subtype_Declaration (Loc,
491                Defining_Identifier => Tnn,
492                Subtype_Indication =>
493                  Make_Subtype_Indication (Loc,
494                    Subtype_Mark => New_Occurrence_Of (Dtyp, Loc),
495                    Constraint   =>
496                      Make_Range_Constraint (Loc,
497                        Range_Expression =>
498                          Make_Range (Loc,
499                            Low_Bound =>
500                              Make_Attribute_Reference (Loc,
501                                Attribute_Name => Name_First,
502                                Prefix => New_Occurrence_Of (Dtyp, Loc)),
503                            High_Bound =>
504                              Make_Integer_Literal (Loc,
505                                Intval => UI_Max (Loval, Ahiv)))))));
506
507            Set_Etype (Discr, Tnn);
508         end if;
509
510      <<Continue>>
511         Next_Component (Comp);
512      end loop;
513   end Adjust_Discriminants;
514
515   ---------------------------
516   -- Build_Array_Init_Proc --
517   ---------------------------
518
519   procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id) is
520      Comp_Type        : constant Entity_Id := Component_Type (A_Type);
521      Comp_Simple_Init : constant Boolean   :=
522        Needs_Simple_Initialization
523          (T           => Comp_Type,
524           Consider_IS =>
525             not (Validity_Check_Copies and Is_Bit_Packed_Array (A_Type)));
526      --  True if the component needs simple initialization, based on its type,
527      --  plus the fact that we do not do simple initialization for components
528      --  of bit-packed arrays when validity checks are enabled, because the
529      --  initialization with deliberately out-of-range values would raise
530      --  Constraint_Error.
531
532      Body_Stmts       : List_Id;
533      Has_Default_Init : Boolean;
534      Index_List       : List_Id;
535      Loc              : Source_Ptr;
536      Proc_Id          : Entity_Id;
537
538      function Init_Component return List_Id;
539      --  Create one statement to initialize one array component, designated
540      --  by a full set of indexes.
541
542      function Init_One_Dimension (N : Int) return List_Id;
543      --  Create loop to initialize one dimension of the array. The single
544      --  statement in the loop body initializes the inner dimensions if any,
545      --  or else the single component. Note that this procedure is called
546      --  recursively, with N being the dimension to be initialized. A call
547      --  with N greater than the number of dimensions simply generates the
548      --  component initialization, terminating the recursion.
549
550      --------------------
551      -- Init_Component --
552      --------------------
553
554      function Init_Component return List_Id is
555         Comp : Node_Id;
556
557      begin
558         Comp :=
559           Make_Indexed_Component (Loc,
560             Prefix      => Make_Identifier (Loc, Name_uInit),
561             Expressions => Index_List);
562
563         if Has_Default_Aspect (A_Type) then
564            Set_Assignment_OK (Comp);
565            return New_List (
566              Make_Assignment_Statement (Loc,
567                Name       => Comp,
568                Expression =>
569                  Convert_To (Comp_Type,
570                    Default_Aspect_Component_Value (First_Subtype (A_Type)))));
571
572         elsif Comp_Simple_Init then
573            Set_Assignment_OK (Comp);
574            return New_List (
575              Make_Assignment_Statement (Loc,
576                Name       => Comp,
577                Expression =>
578                  Get_Simple_Init_Val
579                    (Comp_Type, Nod, Component_Size (A_Type))));
580
581         else
582            Clean_Task_Names (Comp_Type, Proc_Id);
583            return
584              Build_Initialization_Call
585                (Loc, Comp, Comp_Type,
586                 In_Init_Proc => True,
587                 Enclos_Type  => A_Type);
588         end if;
589      end Init_Component;
590
591      ------------------------
592      -- Init_One_Dimension --
593      ------------------------
594
595      function Init_One_Dimension (N : Int) return List_Id is
596         Index : Entity_Id;
597
598      begin
599         --  If the component does not need initializing, then there is nothing
600         --  to do here, so we return a null body. This occurs when generating
601         --  the dummy Init_Proc needed for Initialize_Scalars processing.
602
603         if not Has_Non_Null_Base_Init_Proc (Comp_Type)
604           and then not Comp_Simple_Init
605           and then not Has_Task (Comp_Type)
606           and then not Has_Default_Aspect (A_Type)
607         then
608            return New_List (Make_Null_Statement (Loc));
609
610         --  If all dimensions dealt with, we simply initialize the component
611
612         elsif N > Number_Dimensions (A_Type) then
613            return Init_Component;
614
615         --  Here we generate the required loop
616
617         else
618            Index :=
619              Make_Defining_Identifier (Loc, New_External_Name ('J', N));
620
621            Append (New_Occurrence_Of (Index, Loc), Index_List);
622
623            return New_List (
624              Make_Implicit_Loop_Statement (Nod,
625                Identifier       => Empty,
626                Iteration_Scheme =>
627                  Make_Iteration_Scheme (Loc,
628                    Loop_Parameter_Specification =>
629                      Make_Loop_Parameter_Specification (Loc,
630                        Defining_Identifier         => Index,
631                        Discrete_Subtype_Definition =>
632                          Make_Attribute_Reference (Loc,
633                            Prefix          =>
634                              Make_Identifier (Loc, Name_uInit),
635                            Attribute_Name  => Name_Range,
636                            Expressions     => New_List (
637                              Make_Integer_Literal (Loc, N))))),
638                Statements       => Init_One_Dimension (N + 1)));
639         end if;
640      end Init_One_Dimension;
641
642   --  Start of processing for Build_Array_Init_Proc
643
644   begin
645      --  The init proc is created when analyzing the freeze node for the type,
646      --  but it properly belongs with the array type declaration. However, if
647      --  the freeze node is for a subtype of a type declared in another unit
648      --  it seems preferable to use the freeze node as the source location of
649      --  the init proc. In any case this is preferable for gcov usage, and
650      --  the Sloc is not otherwise used by the compiler.
651
652      if In_Open_Scopes (Scope (A_Type)) then
653         Loc := Sloc (A_Type);
654      else
655         Loc := Sloc (Nod);
656      end if;
657
658      --  Nothing to generate in the following cases:
659
660      --    1. Initialization is suppressed for the type
661      --    2. An initialization already exists for the base type
662
663      if Initialization_Suppressed (A_Type)
664        or else Present (Base_Init_Proc (A_Type))
665      then
666         return;
667      end if;
668
669      Index_List := New_List;
670
671      --  We need an initialization procedure if any of the following is true:
672
673      --    1. The component type has an initialization procedure
674      --    2. The component type needs simple initialization
675      --    3. Tasks are present
676      --    4. The type is marked as a public entity
677      --    5. The array type has a Default_Component_Value aspect
678
679      --  The reason for the public entity test is to deal properly with the
680      --  Initialize_Scalars pragma. This pragma can be set in the client and
681      --  not in the declaring package, this means the client will make a call
682      --  to the initialization procedure (because one of conditions 1-3 must
683      --  apply in this case), and we must generate a procedure (even if it is
684      --  null) to satisfy the call in this case.
685
686      --  Exception: do not build an array init_proc for a type whose root
687      --  type is Standard.String or Standard.Wide_[Wide_]String, since there
688      --  is no place to put the code, and in any case we handle initialization
689      --  of such types (in the Initialize_Scalars case, that's the only time
690      --  the issue arises) in a special manner anyway which does not need an
691      --  init_proc.
692
693      Has_Default_Init := Has_Non_Null_Base_Init_Proc (Comp_Type)
694                            or else Comp_Simple_Init
695                            or else Has_Task (Comp_Type)
696                            or else Has_Default_Aspect (A_Type);
697
698      if Has_Default_Init
699        or else (not Restriction_Active (No_Initialize_Scalars)
700                  and then Is_Public (A_Type)
701                  and then not Is_Standard_String_Type (A_Type))
702      then
703         Proc_Id :=
704           Make_Defining_Identifier (Loc,
705             Chars => Make_Init_Proc_Name (A_Type));
706
707         --  If No_Default_Initialization restriction is active, then we don't
708         --  want to build an init_proc, but we need to mark that an init_proc
709         --  would be needed if this restriction was not active (so that we can
710         --  detect attempts to call it), so set a dummy init_proc in place.
711         --  This is only done though when actual default initialization is
712         --  needed (and not done when only Is_Public is True), since otherwise
713         --  objects such as arrays of scalars could be wrongly flagged as
714         --  violating the restriction.
715
716         if Restriction_Active (No_Default_Initialization) then
717            if Has_Default_Init then
718               Set_Init_Proc (A_Type, Proc_Id);
719            end if;
720
721            return;
722         end if;
723
724         Body_Stmts := Init_One_Dimension (1);
725
726         Discard_Node (
727           Make_Subprogram_Body (Loc,
728             Specification =>
729               Make_Procedure_Specification (Loc,
730                 Defining_Unit_Name => Proc_Id,
731                 Parameter_Specifications => Init_Formals (A_Type)),
732             Declarations => New_List,
733             Handled_Statement_Sequence =>
734               Make_Handled_Sequence_Of_Statements (Loc,
735                 Statements => Body_Stmts)));
736
737         Set_Ekind          (Proc_Id, E_Procedure);
738         Set_Is_Public      (Proc_Id, Is_Public (A_Type));
739         Set_Is_Internal    (Proc_Id);
740         Set_Has_Completion (Proc_Id);
741
742         if not Debug_Generated_Code then
743            Set_Debug_Info_Off (Proc_Id);
744         end if;
745
746         --  Set Inlined on Init_Proc if it is set on the Init_Proc of the
747         --  component type itself (see also Build_Record_Init_Proc).
748
749         Set_Is_Inlined (Proc_Id, Inline_Init_Proc (Comp_Type));
750
751         --  Associate Init_Proc with type, and determine if the procedure
752         --  is null (happens because of the Initialize_Scalars pragma case,
753         --  where we have to generate a null procedure in case it is called
754         --  by a client with Initialize_Scalars set). Such procedures have
755         --  to be generated, but do not have to be called, so we mark them
756         --  as null to suppress the call.
757
758         Set_Init_Proc (A_Type, Proc_Id);
759
760         if List_Length (Body_Stmts) = 1
761
762           --  We must skip SCIL nodes because they may have been added to this
763           --  list by Insert_Actions.
764
765           and then Nkind (First_Non_SCIL_Node (Body_Stmts)) = N_Null_Statement
766         then
767            Set_Is_Null_Init_Proc (Proc_Id);
768
769         else
770            --  Try to build a static aggregate to statically initialize
771            --  objects of the type. This can only be done for constrained
772            --  one-dimensional arrays with static bounds.
773
774            Set_Static_Initialization
775              (Proc_Id,
776               Build_Equivalent_Array_Aggregate (First_Subtype (A_Type)));
777         end if;
778      end if;
779   end Build_Array_Init_Proc;
780
781   --------------------------------
782   -- Build_Discr_Checking_Funcs --
783   --------------------------------
784
785   procedure Build_Discr_Checking_Funcs (N : Node_Id) is
786      Rec_Id            : Entity_Id;
787      Loc               : Source_Ptr;
788      Enclosing_Func_Id : Entity_Id;
789      Sequence          : Nat := 1;
790      Type_Def          : Node_Id;
791      V                 : Node_Id;
792
793      function Build_Case_Statement
794        (Case_Id : Entity_Id;
795         Variant : Node_Id) return Node_Id;
796      --  Build a case statement containing only two alternatives. The first
797      --  alternative corresponds exactly to the discrete choices given on the
798      --  variant with contains the components that we are generating the
799      --  checks for. If the discriminant is one of these return False. The
800      --  second alternative is an OTHERS choice that will return True
801      --  indicating the discriminant did not match.
802
803      function Build_Dcheck_Function
804        (Case_Id : Entity_Id;
805         Variant : Node_Id) return Entity_Id;
806      --  Build the discriminant checking function for a given variant
807
808      procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id);
809      --  Builds the discriminant checking function for each variant of the
810      --  given variant part of the record type.
811
812      --------------------------
813      -- Build_Case_Statement --
814      --------------------------
815
816      function Build_Case_Statement
817        (Case_Id : Entity_Id;
818         Variant : Node_Id) return Node_Id
819      is
820         Alt_List       : constant List_Id := New_List;
821         Actuals_List   : List_Id;
822         Case_Node      : Node_Id;
823         Case_Alt_Node  : Node_Id;
824         Choice         : Node_Id;
825         Choice_List    : List_Id;
826         D              : Entity_Id;
827         Return_Node    : Node_Id;
828
829      begin
830         Case_Node := New_Node (N_Case_Statement, Loc);
831
832         --  Replace the discriminant which controls the variant with the name
833         --  of the formal of the checking function.
834
835         Set_Expression (Case_Node, Make_Identifier (Loc, Chars (Case_Id)));
836
837         Choice := First (Discrete_Choices (Variant));
838
839         if Nkind (Choice) = N_Others_Choice then
840            Choice_List := New_Copy_List (Others_Discrete_Choices (Choice));
841         else
842            Choice_List := New_Copy_List (Discrete_Choices (Variant));
843         end if;
844
845         if not Is_Empty_List (Choice_List) then
846            Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
847            Set_Discrete_Choices (Case_Alt_Node, Choice_List);
848
849            --  In case this is a nested variant, we need to return the result
850            --  of the discriminant checking function for the immediately
851            --  enclosing variant.
852
853            if Present (Enclosing_Func_Id) then
854               Actuals_List := New_List;
855
856               D := First_Discriminant (Rec_Id);
857               while Present (D) loop
858                  Append (Make_Identifier (Loc, Chars (D)), Actuals_List);
859                  Next_Discriminant (D);
860               end loop;
861
862               Return_Node :=
863                 Make_Simple_Return_Statement (Loc,
864                   Expression =>
865                     Make_Function_Call (Loc,
866                       Name =>
867                         New_Occurrence_Of (Enclosing_Func_Id,  Loc),
868                       Parameter_Associations =>
869                         Actuals_List));
870
871            else
872               Return_Node :=
873                 Make_Simple_Return_Statement (Loc,
874                   Expression =>
875                     New_Occurrence_Of (Standard_False, Loc));
876            end if;
877
878            Set_Statements (Case_Alt_Node, New_List (Return_Node));
879            Append (Case_Alt_Node, Alt_List);
880         end if;
881
882         Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
883         Choice_List := New_List (New_Node (N_Others_Choice, Loc));
884         Set_Discrete_Choices (Case_Alt_Node, Choice_List);
885
886         Return_Node :=
887           Make_Simple_Return_Statement (Loc,
888             Expression =>
889               New_Occurrence_Of (Standard_True, Loc));
890
891         Set_Statements (Case_Alt_Node, New_List (Return_Node));
892         Append (Case_Alt_Node, Alt_List);
893
894         Set_Alternatives (Case_Node, Alt_List);
895         return Case_Node;
896      end Build_Case_Statement;
897
898      ---------------------------
899      -- Build_Dcheck_Function --
900      ---------------------------
901
902      function Build_Dcheck_Function
903        (Case_Id : Entity_Id;
904         Variant : Node_Id) return Entity_Id
905      is
906         Body_Node           : Node_Id;
907         Func_Id             : Entity_Id;
908         Parameter_List      : List_Id;
909         Spec_Node           : Node_Id;
910
911      begin
912         Body_Node := New_Node (N_Subprogram_Body, Loc);
913         Sequence := Sequence + 1;
914
915         Func_Id :=
916           Make_Defining_Identifier (Loc,
917             Chars => New_External_Name (Chars (Rec_Id), 'D', Sequence));
918         Set_Is_Discriminant_Check_Function (Func_Id);
919
920         Spec_Node := New_Node (N_Function_Specification, Loc);
921         Set_Defining_Unit_Name (Spec_Node, Func_Id);
922
923         Parameter_List := Build_Discriminant_Formals (Rec_Id, False);
924
925         Set_Parameter_Specifications (Spec_Node, Parameter_List);
926         Set_Result_Definition (Spec_Node,
927                                New_Occurrence_Of (Standard_Boolean,  Loc));
928         Set_Specification (Body_Node, Spec_Node);
929         Set_Declarations (Body_Node, New_List);
930
931         Set_Handled_Statement_Sequence (Body_Node,
932           Make_Handled_Sequence_Of_Statements (Loc,
933             Statements => New_List (
934               Build_Case_Statement (Case_Id, Variant))));
935
936         Set_Ekind       (Func_Id, E_Function);
937         Set_Mechanism   (Func_Id, Default_Mechanism);
938         Set_Is_Inlined  (Func_Id, True);
939         Set_Is_Pure     (Func_Id, True);
940         Set_Is_Public   (Func_Id, Is_Public (Rec_Id));
941         Set_Is_Internal (Func_Id, True);
942
943         if not Debug_Generated_Code then
944            Set_Debug_Info_Off (Func_Id);
945         end if;
946
947         Analyze (Body_Node);
948
949         Append_Freeze_Action (Rec_Id, Body_Node);
950         Set_Dcheck_Function (Variant, Func_Id);
951         return Func_Id;
952      end Build_Dcheck_Function;
953
954      ----------------------------
955      -- Build_Dcheck_Functions --
956      ----------------------------
957
958      procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id) is
959         Component_List_Node : Node_Id;
960         Decl                : Entity_Id;
961         Discr_Name          : Entity_Id;
962         Func_Id             : Entity_Id;
963         Variant             : Node_Id;
964         Saved_Enclosing_Func_Id : Entity_Id;
965
966      begin
967         --  Build the discriminant-checking function for each variant, and
968         --  label all components of that variant with the function's name.
969         --  We only Generate a discriminant-checking function when the
970         --  variant is not empty, to prevent the creation of dead code.
971
972         Discr_Name := Entity (Name (Variant_Part_Node));
973         Variant := First_Non_Pragma (Variants (Variant_Part_Node));
974
975         while Present (Variant) loop
976            Component_List_Node := Component_List (Variant);
977
978            if not Null_Present (Component_List_Node) then
979               Func_Id := Build_Dcheck_Function (Discr_Name, Variant);
980
981               Decl :=
982                 First_Non_Pragma (Component_Items (Component_List_Node));
983               while Present (Decl) loop
984                  Set_Discriminant_Checking_Func
985                    (Defining_Identifier (Decl), Func_Id);
986                  Next_Non_Pragma (Decl);
987               end loop;
988
989               if Present (Variant_Part (Component_List_Node)) then
990                  Saved_Enclosing_Func_Id := Enclosing_Func_Id;
991                  Enclosing_Func_Id := Func_Id;
992                  Build_Dcheck_Functions (Variant_Part (Component_List_Node));
993                  Enclosing_Func_Id := Saved_Enclosing_Func_Id;
994               end if;
995            end if;
996
997            Next_Non_Pragma (Variant);
998         end loop;
999      end Build_Dcheck_Functions;
1000
1001   --  Start of processing for Build_Discr_Checking_Funcs
1002
1003   begin
1004      --  Only build if not done already
1005
1006      if not Discr_Check_Funcs_Built (N) then
1007         Type_Def := Type_Definition (N);
1008
1009         if Nkind (Type_Def) = N_Record_Definition then
1010            if No (Component_List (Type_Def)) then   -- null record.
1011               return;
1012            else
1013               V := Variant_Part (Component_List (Type_Def));
1014            end if;
1015
1016         else pragma Assert (Nkind (Type_Def) = N_Derived_Type_Definition);
1017            if No (Component_List (Record_Extension_Part (Type_Def))) then
1018               return;
1019            else
1020               V := Variant_Part
1021                      (Component_List (Record_Extension_Part (Type_Def)));
1022            end if;
1023         end if;
1024
1025         Rec_Id := Defining_Identifier (N);
1026
1027         if Present (V) and then not Is_Unchecked_Union (Rec_Id) then
1028            Loc := Sloc (N);
1029            Enclosing_Func_Id := Empty;
1030            Build_Dcheck_Functions (V);
1031         end if;
1032
1033         Set_Discr_Check_Funcs_Built (N);
1034      end if;
1035   end Build_Discr_Checking_Funcs;
1036
1037   --------------------------------
1038   -- Build_Discriminant_Formals --
1039   --------------------------------
1040
1041   function Build_Discriminant_Formals
1042     (Rec_Id : Entity_Id;
1043      Use_Dl : Boolean) return List_Id
1044   is
1045      Loc             : Source_Ptr       := Sloc (Rec_Id);
1046      Parameter_List  : constant List_Id := New_List;
1047      D               : Entity_Id;
1048      Formal          : Entity_Id;
1049      Formal_Type     : Entity_Id;
1050      Param_Spec_Node : Node_Id;
1051
1052   begin
1053      if Has_Discriminants (Rec_Id) then
1054         D := First_Discriminant (Rec_Id);
1055         while Present (D) loop
1056            Loc := Sloc (D);
1057
1058            if Use_Dl then
1059               Formal := Discriminal (D);
1060               Formal_Type := Etype (Formal);
1061            else
1062               Formal := Make_Defining_Identifier (Loc, Chars (D));
1063               Formal_Type := Etype (D);
1064            end if;
1065
1066            Param_Spec_Node :=
1067              Make_Parameter_Specification (Loc,
1068                  Defining_Identifier => Formal,
1069                Parameter_Type =>
1070                  New_Occurrence_Of (Formal_Type, Loc));
1071            Append (Param_Spec_Node, Parameter_List);
1072            Next_Discriminant (D);
1073         end loop;
1074      end if;
1075
1076      return Parameter_List;
1077   end Build_Discriminant_Formals;
1078
1079   --------------------------------------
1080   -- Build_Equivalent_Array_Aggregate --
1081   --------------------------------------
1082
1083   function Build_Equivalent_Array_Aggregate (T : Entity_Id) return Node_Id is
1084      Loc        : constant Source_Ptr := Sloc (T);
1085      Comp_Type  : constant Entity_Id := Component_Type (T);
1086      Index_Type : constant Entity_Id := Etype (First_Index (T));
1087      Proc       : constant Entity_Id := Base_Init_Proc (T);
1088      Lo, Hi     : Node_Id;
1089      Aggr       : Node_Id;
1090      Expr       : Node_Id;
1091
1092   begin
1093      if not Is_Constrained (T)
1094        or else Number_Dimensions (T) > 1
1095        or else No (Proc)
1096      then
1097         Initialization_Warning (T);
1098         return Empty;
1099      end if;
1100
1101      Lo := Type_Low_Bound  (Index_Type);
1102      Hi := Type_High_Bound (Index_Type);
1103
1104      if not Compile_Time_Known_Value (Lo)
1105        or else not Compile_Time_Known_Value (Hi)
1106      then
1107         Initialization_Warning (T);
1108         return Empty;
1109      end if;
1110
1111      if Is_Record_Type (Comp_Type)
1112        and then Present (Base_Init_Proc (Comp_Type))
1113      then
1114         Expr := Static_Initialization (Base_Init_Proc (Comp_Type));
1115
1116         if No (Expr) then
1117            Initialization_Warning (T);
1118            return Empty;
1119         end if;
1120
1121      else
1122         Initialization_Warning (T);
1123         return Empty;
1124      end if;
1125
1126      Aggr := Make_Aggregate (Loc, No_List, New_List);
1127      Set_Etype (Aggr, T);
1128      Set_Aggregate_Bounds (Aggr,
1129        Make_Range (Loc,
1130          Low_Bound  => New_Copy (Lo),
1131          High_Bound => New_Copy (Hi)));
1132      Set_Parent (Aggr, Parent (Proc));
1133
1134      Append_To (Component_Associations (Aggr),
1135         Make_Component_Association (Loc,
1136              Choices =>
1137                 New_List (
1138                   Make_Range (Loc,
1139                     Low_Bound  => New_Copy (Lo),
1140                     High_Bound => New_Copy (Hi))),
1141              Expression => Expr));
1142
1143      if Static_Array_Aggregate (Aggr) then
1144         return Aggr;
1145      else
1146         Initialization_Warning (T);
1147         return Empty;
1148      end if;
1149   end Build_Equivalent_Array_Aggregate;
1150
1151   ---------------------------------------
1152   -- Build_Equivalent_Record_Aggregate --
1153   ---------------------------------------
1154
1155   function Build_Equivalent_Record_Aggregate (T : Entity_Id) return Node_Id is
1156      Agg       : Node_Id;
1157      Comp      : Entity_Id;
1158      Comp_Type : Entity_Id;
1159
1160      --  Start of processing for Build_Equivalent_Record_Aggregate
1161
1162   begin
1163      if not Is_Record_Type (T)
1164        or else Has_Discriminants (T)
1165        or else Is_Limited_Type (T)
1166        or else Has_Non_Standard_Rep (T)
1167      then
1168         Initialization_Warning (T);
1169         return Empty;
1170      end if;
1171
1172      Comp := First_Component (T);
1173
1174      --  A null record needs no warning
1175
1176      if No (Comp) then
1177         return Empty;
1178      end if;
1179
1180      while Present (Comp) loop
1181
1182         --  Array components are acceptable if initialized by a positional
1183         --  aggregate with static components.
1184
1185         if Is_Array_Type (Etype (Comp)) then
1186            Comp_Type := Component_Type (Etype (Comp));
1187
1188            if Nkind (Parent (Comp)) /= N_Component_Declaration
1189              or else No (Expression (Parent (Comp)))
1190              or else Nkind (Expression (Parent (Comp))) /= N_Aggregate
1191            then
1192               Initialization_Warning (T);
1193               return Empty;
1194
1195            elsif Is_Scalar_Type (Component_Type (Etype (Comp)))
1196               and then
1197                 (not Compile_Time_Known_Value (Type_Low_Bound  (Comp_Type))
1198                   or else
1199                  not Compile_Time_Known_Value (Type_High_Bound (Comp_Type)))
1200            then
1201               Initialization_Warning (T);
1202               return Empty;
1203
1204            elsif
1205              not Static_Array_Aggregate (Expression (Parent (Comp)))
1206            then
1207               Initialization_Warning (T);
1208               return Empty;
1209            end if;
1210
1211         elsif Is_Scalar_Type (Etype (Comp)) then
1212            Comp_Type := Etype (Comp);
1213
1214            if Nkind (Parent (Comp)) /= N_Component_Declaration
1215              or else No (Expression (Parent (Comp)))
1216              or else not Compile_Time_Known_Value (Expression (Parent (Comp)))
1217              or else not Compile_Time_Known_Value (Type_Low_Bound (Comp_Type))
1218              or else not
1219                Compile_Time_Known_Value (Type_High_Bound (Comp_Type))
1220            then
1221               Initialization_Warning (T);
1222               return Empty;
1223            end if;
1224
1225         --  For now, other types are excluded
1226
1227         else
1228            Initialization_Warning (T);
1229            return Empty;
1230         end if;
1231
1232         Next_Component (Comp);
1233      end loop;
1234
1235      --  All components have static initialization. Build positional aggregate
1236      --  from the given expressions or defaults.
1237
1238      Agg := Make_Aggregate (Sloc (T), New_List, New_List);
1239      Set_Parent (Agg, Parent (T));
1240
1241      Comp := First_Component (T);
1242      while Present (Comp) loop
1243         Append
1244           (New_Copy_Tree (Expression (Parent (Comp))), Expressions (Agg));
1245         Next_Component (Comp);
1246      end loop;
1247
1248      Analyze_And_Resolve (Agg, T);
1249      return Agg;
1250   end Build_Equivalent_Record_Aggregate;
1251
1252   -------------------------------
1253   -- Build_Initialization_Call --
1254   -------------------------------
1255
1256   --  References to a discriminant inside the record type declaration can
1257   --  appear either in the subtype_indication to constrain a record or an
1258   --  array, or as part of a larger expression given for the initial value
1259   --  of a component. In both of these cases N appears in the record
1260   --  initialization procedure and needs to be replaced by the formal
1261   --  parameter of the initialization procedure which corresponds to that
1262   --  discriminant.
1263
1264   --  In the example below, references to discriminants D1 and D2 in proc_1
1265   --  are replaced by references to formals with the same name
1266   --  (discriminals)
1267
1268   --  A similar replacement is done for calls to any record initialization
1269   --  procedure for any components that are themselves of a record type.
1270
1271   --  type R (D1, D2 : Integer) is record
1272   --     X : Integer := F * D1;
1273   --     Y : Integer := F * D2;
1274   --  end record;
1275
1276   --  procedure proc_1 (Out_2 : out R; D1 : Integer; D2 : Integer) is
1277   --  begin
1278   --     Out_2.D1 := D1;
1279   --     Out_2.D2 := D2;
1280   --     Out_2.X := F * D1;
1281   --     Out_2.Y := F * D2;
1282   --  end;
1283
1284   function Build_Initialization_Call
1285     (Loc               : Source_Ptr;
1286      Id_Ref            : Node_Id;
1287      Typ               : Entity_Id;
1288      In_Init_Proc      : Boolean := False;
1289      Enclos_Type       : Entity_Id := Empty;
1290      Discr_Map         : Elist_Id := New_Elmt_List;
1291      With_Default_Init : Boolean := False;
1292      Constructor_Ref   : Node_Id := Empty) return List_Id
1293   is
1294      Res : constant List_Id := New_List;
1295
1296      Full_Type : Entity_Id;
1297
1298      procedure Check_Predicated_Discriminant
1299        (Val   : Node_Id;
1300         Discr : Entity_Id);
1301      --  Discriminants whose subtypes have predicates are checked in two
1302      --  cases:
1303      --    a) When an object is default-initialized and assertions are enabled
1304      --       we check that the value of the discriminant obeys the predicate.
1305
1306      --    b) In all cases, if the discriminant controls a variant and the
1307      --       variant has no others_choice, Constraint_Error must be raised if
1308      --       the predicate is violated, because there is no variant covered
1309      --       by the illegal discriminant value.
1310
1311      -----------------------------------
1312      -- Check_Predicated_Discriminant --
1313      -----------------------------------
1314
1315      procedure Check_Predicated_Discriminant
1316        (Val   : Node_Id;
1317         Discr : Entity_Id)
1318      is
1319         Typ : constant Entity_Id := Etype (Discr);
1320
1321         procedure Check_Missing_Others (V : Node_Id);
1322         --  ???
1323
1324         --------------------------
1325         -- Check_Missing_Others --
1326         --------------------------
1327
1328         procedure Check_Missing_Others (V : Node_Id) is
1329            Alt      : Node_Id;
1330            Choice   : Node_Id;
1331            Last_Var : Node_Id;
1332
1333         begin
1334            Last_Var := Last_Non_Pragma (Variants (V));
1335            Choice   := First (Discrete_Choices (Last_Var));
1336
1337            --  An others_choice is added during expansion for gcc use, but
1338            --  does not cover the illegality.
1339
1340            if Entity (Name (V)) = Discr then
1341               if Present (Choice)
1342                 and then (Nkind (Choice) /= N_Others_Choice
1343                            or else not Comes_From_Source (Choice))
1344               then
1345                  Check_Expression_Against_Static_Predicate (Val, Typ);
1346
1347                  if not Is_Static_Expression (Val) then
1348                     Prepend_To (Res,
1349                        Make_Raise_Constraint_Error (Loc,
1350                          Condition =>
1351                            Make_Op_Not (Loc,
1352                              Right_Opnd => Make_Predicate_Call (Typ, Val)),
1353                          Reason    => CE_Invalid_Data));
1354                  end if;
1355               end if;
1356            end if;
1357
1358            --  Check whether some nested variant is ruled by the predicated
1359            --  discriminant.
1360
1361            Alt := First (Variants (V));
1362            while Present (Alt) loop
1363               if Nkind (Alt) = N_Variant
1364                 and then Present (Variant_Part (Component_List (Alt)))
1365               then
1366                  Check_Missing_Others
1367                    (Variant_Part (Component_List (Alt)));
1368               end if;
1369
1370               Next (Alt);
1371            end loop;
1372         end Check_Missing_Others;
1373
1374         --  Local variables
1375
1376         Def : Node_Id;
1377
1378      --  Start of processing for Check_Predicated_Discriminant
1379
1380      begin
1381         if Ekind (Base_Type (Full_Type)) = E_Record_Type then
1382            Def := Type_Definition (Parent (Base_Type (Full_Type)));
1383         else
1384            return;
1385         end if;
1386
1387         if Policy_In_Effect (Name_Assert) = Name_Check
1388           and then not Predicates_Ignored (Etype (Discr))
1389         then
1390            Prepend_To (Res, Make_Predicate_Check (Typ, Val));
1391         end if;
1392
1393         --  If discriminant controls a variant, verify that predicate is
1394         --  obeyed or else an Others_Choice is present.
1395
1396         if Nkind (Def) = N_Record_Definition
1397           and then Present (Variant_Part (Component_List (Def)))
1398           and then Policy_In_Effect (Name_Assert) = Name_Ignore
1399         then
1400            Check_Missing_Others (Variant_Part (Component_List (Def)));
1401         end if;
1402      end Check_Predicated_Discriminant;
1403
1404      --  Local variables
1405
1406      Arg            : Node_Id;
1407      Args           : List_Id;
1408      Decls          : List_Id;
1409      Decl           : Node_Id;
1410      Discr          : Entity_Id;
1411      First_Arg      : Node_Id;
1412      Full_Init_Type : Entity_Id;
1413      Init_Call      : Node_Id;
1414      Init_Type      : Entity_Id;
1415      Proc           : Entity_Id;
1416
1417   --  Start of processing for Build_Initialization_Call
1418
1419   begin
1420      pragma Assert (Constructor_Ref = Empty
1421        or else Is_CPP_Constructor_Call (Constructor_Ref));
1422
1423      if No (Constructor_Ref) then
1424         Proc := Base_Init_Proc (Typ);
1425      else
1426         Proc := Base_Init_Proc (Typ, Entity (Name (Constructor_Ref)));
1427      end if;
1428
1429      pragma Assert (Present (Proc));
1430      Init_Type      := Etype (First_Formal (Proc));
1431      Full_Init_Type := Underlying_Type (Init_Type);
1432
1433      --  Nothing to do if the Init_Proc is null, unless Initialize_Scalars
1434      --  is active (in which case we make the call anyway, since in the
1435      --  actual compiled client it may be non null).
1436
1437      if Is_Null_Init_Proc (Proc) and then not Init_Or_Norm_Scalars then
1438         return Empty_List;
1439
1440      --  Nothing to do for an array of controlled components that have only
1441      --  the inherited Initialize primitive. This is a useful optimization
1442      --  for CodePeer.
1443
1444      elsif Is_Trivial_Subprogram (Proc)
1445        and then Is_Array_Type (Full_Init_Type)
1446      then
1447         return New_List (Make_Null_Statement (Loc));
1448      end if;
1449
1450      --  Use the [underlying] full view when dealing with a private type. This
1451      --  may require several steps depending on derivations.
1452
1453      Full_Type := Typ;
1454      loop
1455         if Is_Private_Type (Full_Type) then
1456            if Present (Full_View (Full_Type)) then
1457               Full_Type := Full_View (Full_Type);
1458
1459            elsif Present (Underlying_Full_View (Full_Type)) then
1460               Full_Type := Underlying_Full_View (Full_Type);
1461
1462            --  When a private type acts as a generic actual and lacks a full
1463            --  view, use the base type.
1464
1465            elsif Is_Generic_Actual_Type (Full_Type) then
1466               Full_Type := Base_Type (Full_Type);
1467
1468            elsif Ekind (Full_Type) = E_Private_Subtype
1469              and then (not Has_Discriminants (Full_Type)
1470                         or else No (Discriminant_Constraint (Full_Type)))
1471            then
1472               Full_Type := Etype (Full_Type);
1473
1474            --  The loop has recovered the [underlying] full view, stop the
1475            --  traversal.
1476
1477            else
1478               exit;
1479            end if;
1480
1481         --  The type is not private, nothing to do
1482
1483         else
1484            exit;
1485         end if;
1486      end loop;
1487
1488      --  If Typ is derived, the procedure is the initialization procedure for
1489      --  the root type. Wrap the argument in an conversion to make it type
1490      --  honest. Actually it isn't quite type honest, because there can be
1491      --  conflicts of views in the private type case. That is why we set
1492      --  Conversion_OK in the conversion node.
1493
1494      if (Is_Record_Type (Typ)
1495           or else Is_Array_Type (Typ)
1496           or else Is_Private_Type (Typ))
1497        and then Init_Type /= Base_Type (Typ)
1498      then
1499         First_Arg := OK_Convert_To (Etype (Init_Type), Id_Ref);
1500         Set_Etype (First_Arg, Init_Type);
1501
1502      else
1503         First_Arg := Id_Ref;
1504      end if;
1505
1506      Args := New_List (Convert_Concurrent (First_Arg, Typ));
1507
1508      --  In the tasks case, add _Master as the value of the _Master parameter
1509      --  and _Chain as the value of the _Chain parameter. At the outer level,
1510      --  these will be variables holding the corresponding values obtained
1511      --  from GNARL. At inner levels, they will be the parameters passed down
1512      --  through the outer routines.
1513
1514      if Has_Task (Full_Type) then
1515         if Restriction_Active (No_Task_Hierarchy) then
1516            Append_To (Args,
1517              New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
1518         else
1519            Append_To (Args, Make_Identifier (Loc, Name_uMaster));
1520         end if;
1521
1522         --  Add _Chain (not done for sequential elaboration policy, see
1523         --  comment for Create_Restricted_Task_Sequential in s-tarest.ads).
1524
1525         if Partition_Elaboration_Policy /= 'S' then
1526            Append_To (Args, Make_Identifier (Loc, Name_uChain));
1527         end if;
1528
1529         --  Ada 2005 (AI-287): In case of default initialized components
1530         --  with tasks, we generate a null string actual parameter.
1531         --  This is just a workaround that must be improved later???
1532
1533         if With_Default_Init then
1534            Append_To (Args,
1535              Make_String_Literal (Loc,
1536                Strval => ""));
1537
1538         else
1539            Decls :=
1540              Build_Task_Image_Decls (Loc, Id_Ref, Enclos_Type, In_Init_Proc);
1541            Decl  := Last (Decls);
1542
1543            Append_To (Args,
1544              New_Occurrence_Of (Defining_Identifier (Decl), Loc));
1545            Append_List (Decls, Res);
1546         end if;
1547
1548      else
1549         Decls := No_List;
1550         Decl  := Empty;
1551      end if;
1552
1553      --  Add discriminant values if discriminants are present
1554
1555      if Has_Discriminants (Full_Init_Type) then
1556         Discr := First_Discriminant (Full_Init_Type);
1557         while Present (Discr) loop
1558
1559            --  If this is a discriminated concurrent type, the init_proc
1560            --  for the corresponding record is being called. Use that type
1561            --  directly to find the discriminant value, to handle properly
1562            --  intervening renamed discriminants.
1563
1564            declare
1565               T : Entity_Id := Full_Type;
1566
1567            begin
1568               if Is_Protected_Type (T) then
1569                  T := Corresponding_Record_Type (T);
1570               end if;
1571
1572               Arg :=
1573                 Get_Discriminant_Value (
1574                   Discr,
1575                   T,
1576                   Discriminant_Constraint (Full_Type));
1577            end;
1578
1579            --  If the target has access discriminants, and is constrained by
1580            --  an access to the enclosing construct, i.e. a current instance,
1581            --  replace the reference to the type by a reference to the object.
1582
1583            if Nkind (Arg) = N_Attribute_Reference
1584              and then Is_Access_Type (Etype (Arg))
1585              and then Is_Entity_Name (Prefix (Arg))
1586              and then Is_Type (Entity (Prefix (Arg)))
1587            then
1588               Arg :=
1589                 Make_Attribute_Reference (Loc,
1590                   Prefix         => New_Copy (Prefix (Id_Ref)),
1591                   Attribute_Name => Name_Unrestricted_Access);
1592
1593            elsif In_Init_Proc then
1594
1595               --  Replace any possible references to the discriminant in the
1596               --  call to the record initialization procedure with references
1597               --  to the appropriate formal parameter.
1598
1599               if Nkind (Arg) = N_Identifier
1600                 and then Ekind (Entity (Arg)) = E_Discriminant
1601               then
1602                  Arg := New_Occurrence_Of (Discriminal (Entity (Arg)), Loc);
1603
1604               --  Otherwise make a copy of the default expression. Note that
1605               --  we use the current Sloc for this, because we do not want the
1606               --  call to appear to be at the declaration point. Within the
1607               --  expression, replace discriminants with their discriminals.
1608
1609               else
1610                  Arg :=
1611                    New_Copy_Tree (Arg, Map => Discr_Map, New_Sloc => Loc);
1612               end if;
1613
1614            else
1615               if Is_Constrained (Full_Type) then
1616                  Arg := Duplicate_Subexpr_No_Checks (Arg);
1617               else
1618                  --  The constraints come from the discriminant default exps,
1619                  --  they must be reevaluated, so we use New_Copy_Tree but we
1620                  --  ensure the proper Sloc (for any embedded calls).
1621                  --  In addition, if a predicate check is needed on the value
1622                  --  of the discriminant, insert it ahead of the call.
1623
1624                  Arg := New_Copy_Tree (Arg, New_Sloc => Loc);
1625               end if;
1626
1627               if Has_Predicates (Etype (Discr)) then
1628                  Check_Predicated_Discriminant (Arg, Discr);
1629               end if;
1630            end if;
1631
1632            --  Ada 2005 (AI-287): In case of default initialized components,
1633            --  if the component is constrained with a discriminant of the
1634            --  enclosing type, we need to generate the corresponding selected
1635            --  component node to access the discriminant value. In other cases
1636            --  this is not required, either  because we are inside the init
1637            --  proc and we use the corresponding formal, or else because the
1638            --  component is constrained by an expression.
1639
1640            if With_Default_Init
1641              and then Nkind (Id_Ref) = N_Selected_Component
1642              and then Nkind (Arg) = N_Identifier
1643              and then Ekind (Entity (Arg)) = E_Discriminant
1644            then
1645               Append_To (Args,
1646                 Make_Selected_Component (Loc,
1647                   Prefix        => New_Copy_Tree (Prefix (Id_Ref)),
1648                   Selector_Name => Arg));
1649            else
1650               Append_To (Args, Arg);
1651            end if;
1652
1653            Next_Discriminant (Discr);
1654         end loop;
1655      end if;
1656
1657      --  If this is a call to initialize the parent component of a derived
1658      --  tagged type, indicate that the tag should not be set in the parent.
1659
1660      if Is_Tagged_Type (Full_Init_Type)
1661        and then not Is_CPP_Class (Full_Init_Type)
1662        and then Nkind (Id_Ref) = N_Selected_Component
1663        and then Chars (Selector_Name (Id_Ref)) = Name_uParent
1664      then
1665         Append_To (Args, New_Occurrence_Of (Standard_False, Loc));
1666
1667      elsif Present (Constructor_Ref) then
1668         Append_List_To (Args,
1669           New_Copy_List (Parameter_Associations (Constructor_Ref)));
1670      end if;
1671
1672      Append_To (Res,
1673        Make_Procedure_Call_Statement (Loc,
1674          Name                   => New_Occurrence_Of (Proc, Loc),
1675          Parameter_Associations => Args));
1676
1677      if Needs_Finalization (Typ)
1678        and then Nkind (Id_Ref) = N_Selected_Component
1679      then
1680         if Chars (Selector_Name (Id_Ref)) /= Name_uParent then
1681            Init_Call :=
1682              Make_Init_Call
1683                (Obj_Ref => New_Copy_Tree (First_Arg),
1684                 Typ     => Typ);
1685
1686            --  Guard against a missing [Deep_]Initialize when the type was not
1687            --  properly frozen.
1688
1689            if Present (Init_Call) then
1690               Append_To (Res, Init_Call);
1691            end if;
1692         end if;
1693      end if;
1694
1695      return Res;
1696
1697   exception
1698      when RE_Not_Available =>
1699         return Empty_List;
1700   end Build_Initialization_Call;
1701
1702   ----------------------------
1703   -- Build_Record_Init_Proc --
1704   ----------------------------
1705
1706   procedure Build_Record_Init_Proc (N : Node_Id; Rec_Ent : Entity_Id) is
1707      Decls     : constant List_Id  := New_List;
1708      Discr_Map : constant Elist_Id := New_Elmt_List;
1709      Loc       : constant Source_Ptr := Sloc (Rec_Ent);
1710      Counter   : Nat := 0;
1711      Proc_Id   : Entity_Id;
1712      Rec_Type  : Entity_Id;
1713      Set_Tag   : Entity_Id := Empty;
1714
1715      function Build_Assignment
1716        (Id      : Entity_Id;
1717         Default : Node_Id) return List_Id;
1718      --  Build an assignment statement that assigns the default expression to
1719      --  its corresponding record component if defined. The left-hand side of
1720      --  the assignment is marked Assignment_OK so that initialization of
1721      --  limited private records works correctly. This routine may also build
1722      --  an adjustment call if the component is controlled.
1723
1724      procedure Build_Discriminant_Assignments (Statement_List : List_Id);
1725      --  If the record has discriminants, add assignment statements to
1726      --  Statement_List to initialize the discriminant values from the
1727      --  arguments of the initialization procedure.
1728
1729      function Build_Init_Statements (Comp_List : Node_Id) return List_Id;
1730      --  Build a list representing a sequence of statements which initialize
1731      --  components of the given component list. This may involve building
1732      --  case statements for the variant parts. Append any locally declared
1733      --  objects on list Decls.
1734
1735      function Build_Init_Call_Thru (Parameters : List_Id) return List_Id;
1736      --  Given an untagged type-derivation that declares discriminants, e.g.
1737      --
1738      --     type R (R1, R2 : Integer) is record ... end record;
1739      --     type D (D1 : Integer) is new R (1, D1);
1740      --
1741      --  we make the _init_proc of D be
1742      --
1743      --       procedure _init_proc (X : D; D1 : Integer) is
1744      --       begin
1745      --          _init_proc (R (X), 1, D1);
1746      --       end _init_proc;
1747      --
1748      --  This function builds the call statement in this _init_proc.
1749
1750      procedure Build_CPP_Init_Procedure;
1751      --  Build the tree corresponding to the procedure specification and body
1752      --  of the IC procedure that initializes the C++ part of the dispatch
1753      --  table of an Ada tagged type that is a derivation of a CPP type.
1754      --  Install it as the CPP_Init TSS.
1755
1756      procedure Build_Init_Procedure;
1757      --  Build the tree corresponding to the procedure specification and body
1758      --  of the initialization procedure and install it as the _init TSS.
1759
1760      procedure Build_Offset_To_Top_Functions;
1761      --  Ada 2005 (AI-251): Build the tree corresponding to the procedure spec
1762      --  and body of Offset_To_Top, a function used in conjuction with types
1763      --  having secondary dispatch tables.
1764
1765      procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id);
1766      --  Add range checks to components of discriminated records. S is a
1767      --  subtype indication of a record component. Check_List is a list
1768      --  to which the check actions are appended.
1769
1770      function Component_Needs_Simple_Initialization
1771        (T : Entity_Id) return Boolean;
1772      --  Determine if a component needs simple initialization, given its type
1773      --  T. This routine is the same as Needs_Simple_Initialization except for
1774      --  components of type Tag and Interface_Tag. These two access types do
1775      --  not require initialization since they are explicitly initialized by
1776      --  other means.
1777
1778      function Parent_Subtype_Renaming_Discrims return Boolean;
1779      --  Returns True for base types N that rename discriminants, else False
1780
1781      function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean;
1782      --  Determine whether a record initialization procedure needs to be
1783      --  generated for the given record type.
1784
1785      ----------------------
1786      -- Build_Assignment --
1787      ----------------------
1788
1789      function Build_Assignment
1790        (Id      : Entity_Id;
1791         Default : Node_Id) return List_Id
1792      is
1793         Default_Loc : constant Source_Ptr := Sloc (Default);
1794         Typ         : constant Entity_Id  := Underlying_Type (Etype (Id));
1795
1796         Adj_Call : Node_Id;
1797         Exp      : Node_Id   := Default;
1798         Kind     : Node_Kind := Nkind (Default);
1799         Lhs      : Node_Id;
1800         Res      : List_Id;
1801
1802         function Replace_Discr_Ref (N : Node_Id) return Traverse_Result;
1803         --  Analysis of the aggregate has replaced discriminants by their
1804         --  corresponding discriminals, but these are irrelevant when the
1805         --  component has a mutable type and is initialized with an aggregate.
1806         --  Instead, they must be replaced by the values supplied in the
1807         --  aggregate, that will be assigned during the expansion of the
1808         --  assignment.
1809
1810         -----------------------
1811         -- Replace_Discr_Ref --
1812         -----------------------
1813
1814         function Replace_Discr_Ref (N : Node_Id) return Traverse_Result is
1815            Val : Node_Id;
1816
1817         begin
1818            if Is_Entity_Name (N)
1819              and then Present (Entity (N))
1820              and then Is_Formal (Entity (N))
1821              and then Present (Discriminal_Link (Entity (N)))
1822            then
1823               Val :=
1824                 Make_Selected_Component (Default_Loc,
1825                   Prefix        => New_Copy_Tree (Lhs),
1826                   Selector_Name =>
1827                     New_Occurrence_Of
1828                       (Discriminal_Link (Entity (N)), Default_Loc));
1829
1830               if Present (Val) then
1831                  Rewrite (N, New_Copy_Tree (Val));
1832               end if;
1833            end if;
1834
1835            return OK;
1836         end Replace_Discr_Ref;
1837
1838         procedure Replace_Discriminant_References is
1839           new Traverse_Proc (Replace_Discr_Ref);
1840
1841      --  Start of processing for Build_Assignment
1842
1843      begin
1844         Lhs :=
1845           Make_Selected_Component (Default_Loc,
1846             Prefix        => Make_Identifier (Loc, Name_uInit),
1847             Selector_Name => New_Occurrence_Of (Id, Default_Loc));
1848         Set_Assignment_OK (Lhs);
1849
1850         if Nkind (Exp) = N_Aggregate
1851           and then Has_Discriminants (Typ)
1852           and then not Is_Constrained (Base_Type (Typ))
1853         then
1854            --  The aggregate may provide new values for the discriminants
1855            --  of the component, and other components may depend on those
1856            --  discriminants. Previous analysis of those expressions have
1857            --  replaced the discriminants by the formals of the initialization
1858            --  procedure for the type, but these are irrelevant in the
1859            --  enclosing initialization procedure: those discriminant
1860            --  references must be replaced by the values provided in the
1861            --  aggregate.
1862
1863            Replace_Discriminant_References (Exp);
1864         end if;
1865
1866         --  Case of an access attribute applied to the current instance.
1867         --  Replace the reference to the type by a reference to the actual
1868         --  object. (Note that this handles the case of the top level of
1869         --  the expression being given by such an attribute, but does not
1870         --  cover uses nested within an initial value expression. Nested
1871         --  uses are unlikely to occur in practice, but are theoretically
1872         --  possible.) It is not clear how to handle them without fully
1873         --  traversing the expression. ???
1874
1875         if Kind = N_Attribute_Reference
1876           and then Nam_In (Attribute_Name (Default), Name_Unchecked_Access,
1877                                                      Name_Unrestricted_Access)
1878           and then Is_Entity_Name (Prefix (Default))
1879           and then Is_Type (Entity (Prefix (Default)))
1880           and then Entity (Prefix (Default)) = Rec_Type
1881         then
1882            Exp :=
1883              Make_Attribute_Reference (Default_Loc,
1884                Prefix         =>
1885                  Make_Identifier (Default_Loc, Name_uInit),
1886                Attribute_Name => Name_Unrestricted_Access);
1887         end if;
1888
1889         --  Take a copy of Exp to ensure that later copies of this component
1890         --  declaration in derived types see the original tree, not a node
1891         --  rewritten during expansion of the init_proc. If the copy contains
1892         --  itypes, the scope of the new itypes is the init_proc being built.
1893
1894         Exp := New_Copy_Tree (Exp, New_Scope => Proc_Id);
1895
1896         Res := New_List (
1897           Make_Assignment_Statement (Loc,
1898             Name       => Lhs,
1899             Expression => Exp));
1900
1901         Set_No_Ctrl_Actions (First (Res));
1902
1903         --  Adjust the tag if tagged (because of possible view conversions).
1904         --  Suppress the tag adjustment when not Tagged_Type_Expansion because
1905         --  tags are represented implicitly in objects.
1906
1907         if Is_Tagged_Type (Typ) and then Tagged_Type_Expansion then
1908            Append_To (Res,
1909              Make_Assignment_Statement (Default_Loc,
1910                Name       =>
1911                  Make_Selected_Component (Default_Loc,
1912                    Prefix        =>
1913                      New_Copy_Tree (Lhs, New_Scope => Proc_Id),
1914                    Selector_Name =>
1915                      New_Occurrence_Of
1916                        (First_Tag_Component (Typ), Default_Loc)),
1917
1918                Expression =>
1919                  Unchecked_Convert_To (RTE (RE_Tag),
1920                    New_Occurrence_Of
1921                      (Node (First_Elmt (Access_Disp_Table (Underlying_Type
1922                         (Typ)))),
1923                       Default_Loc))));
1924         end if;
1925
1926         --  Adjust the component if controlled except if it is an aggregate
1927         --  that will be expanded inline.
1928
1929         if Kind = N_Qualified_Expression then
1930            Kind := Nkind (Expression (Default));
1931         end if;
1932
1933         if Needs_Finalization (Typ)
1934           and then not (Nkind_In (Kind, N_Aggregate, N_Extension_Aggregate))
1935           and then not Is_Build_In_Place_Function_Call (Exp)
1936         then
1937            Adj_Call :=
1938              Make_Adjust_Call
1939                (Obj_Ref => New_Copy_Tree (Lhs),
1940                 Typ     => Etype (Id));
1941
1942            --  Guard against a missing [Deep_]Adjust when the component type
1943            --  was not properly frozen.
1944
1945            if Present (Adj_Call) then
1946               Append_To (Res, Adj_Call);
1947            end if;
1948         end if;
1949
1950         --  If a component type has a predicate, add check to the component
1951         --  assignment. Discriminants are handled at the point of the call,
1952         --  which provides for a better error message.
1953
1954         if Comes_From_Source (Exp)
1955           and then Has_Predicates (Typ)
1956           and then not Predicate_Checks_Suppressed (Empty)
1957           and then not Predicates_Ignored (Typ)
1958         then
1959            Append (Make_Predicate_Check (Typ, Exp), Res);
1960         end if;
1961
1962         return Res;
1963
1964      exception
1965         when RE_Not_Available =>
1966            return Empty_List;
1967      end Build_Assignment;
1968
1969      ------------------------------------
1970      -- Build_Discriminant_Assignments --
1971      ------------------------------------
1972
1973      procedure Build_Discriminant_Assignments (Statement_List : List_Id) is
1974         Is_Tagged : constant Boolean := Is_Tagged_Type (Rec_Type);
1975         D         : Entity_Id;
1976         D_Loc     : Source_Ptr;
1977
1978      begin
1979         if Has_Discriminants (Rec_Type)
1980           and then not Is_Unchecked_Union (Rec_Type)
1981         then
1982            D := First_Discriminant (Rec_Type);
1983            while Present (D) loop
1984
1985               --  Don't generate the assignment for discriminants in derived
1986               --  tagged types if the discriminant is a renaming of some
1987               --  ancestor discriminant. This initialization will be done
1988               --  when initializing the _parent field of the derived record.
1989
1990               if Is_Tagged
1991                 and then Present (Corresponding_Discriminant (D))
1992               then
1993                  null;
1994
1995               else
1996                  D_Loc := Sloc (D);
1997                  Append_List_To (Statement_List,
1998                    Build_Assignment (D,
1999                      New_Occurrence_Of (Discriminal (D), D_Loc)));
2000               end if;
2001
2002               Next_Discriminant (D);
2003            end loop;
2004         end if;
2005      end Build_Discriminant_Assignments;
2006
2007      --------------------------
2008      -- Build_Init_Call_Thru --
2009      --------------------------
2010
2011      function Build_Init_Call_Thru (Parameters : List_Id) return List_Id is
2012         Parent_Proc : constant Entity_Id :=
2013                         Base_Init_Proc (Etype (Rec_Type));
2014
2015         Parent_Type : constant Entity_Id :=
2016                         Etype (First_Formal (Parent_Proc));
2017
2018         Uparent_Type : constant Entity_Id :=
2019                          Underlying_Type (Parent_Type);
2020
2021         First_Discr_Param : Node_Id;
2022
2023         Arg          : Node_Id;
2024         Args         : List_Id;
2025         First_Arg    : Node_Id;
2026         Parent_Discr : Entity_Id;
2027         Res          : List_Id;
2028
2029      begin
2030         --  First argument (_Init) is the object to be initialized.
2031         --  ??? not sure where to get a reasonable Loc for First_Arg
2032
2033         First_Arg :=
2034           OK_Convert_To (Parent_Type,
2035             New_Occurrence_Of
2036               (Defining_Identifier (First (Parameters)), Loc));
2037
2038         Set_Etype (First_Arg, Parent_Type);
2039
2040         Args := New_List (Convert_Concurrent (First_Arg, Rec_Type));
2041
2042         --  In the tasks case,
2043         --    add _Master as the value of the _Master parameter
2044         --    add _Chain as the value of the _Chain parameter.
2045         --    add _Task_Name as the value of the _Task_Name parameter.
2046         --  At the outer level, these will be variables holding the
2047         --  corresponding values obtained from GNARL or the expander.
2048         --
2049         --  At inner levels, they will be the parameters passed down through
2050         --  the outer routines.
2051
2052         First_Discr_Param := Next (First (Parameters));
2053
2054         if Has_Task (Rec_Type) then
2055            if Restriction_Active (No_Task_Hierarchy) then
2056               Append_To (Args,
2057                 New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
2058            else
2059               Append_To (Args, Make_Identifier (Loc, Name_uMaster));
2060            end if;
2061
2062            --  Add _Chain (not done for sequential elaboration policy, see
2063            --  comment for Create_Restricted_Task_Sequential in s-tarest.ads).
2064
2065            if Partition_Elaboration_Policy /= 'S' then
2066               Append_To (Args, Make_Identifier (Loc, Name_uChain));
2067            end if;
2068
2069            Append_To (Args, Make_Identifier (Loc, Name_uTask_Name));
2070            First_Discr_Param := Next (Next (Next (First_Discr_Param)));
2071         end if;
2072
2073         --  Append discriminant values
2074
2075         if Has_Discriminants (Uparent_Type) then
2076            pragma Assert (not Is_Tagged_Type (Uparent_Type));
2077
2078            Parent_Discr := First_Discriminant (Uparent_Type);
2079            while Present (Parent_Discr) loop
2080
2081               --  Get the initial value for this discriminant
2082               --  ??? needs to be cleaned up to use parent_Discr_Constr
2083               --  directly.
2084
2085               declare
2086                  Discr       : Entity_Id :=
2087                                  First_Stored_Discriminant (Uparent_Type);
2088
2089                  Discr_Value : Elmt_Id :=
2090                                  First_Elmt (Stored_Constraint (Rec_Type));
2091
2092               begin
2093                  while Original_Record_Component (Parent_Discr) /= Discr loop
2094                     Next_Stored_Discriminant (Discr);
2095                     Next_Elmt (Discr_Value);
2096                  end loop;
2097
2098                  Arg := Node (Discr_Value);
2099               end;
2100
2101               --  Append it to the list
2102
2103               if Nkind (Arg) = N_Identifier
2104                 and then Ekind (Entity (Arg)) = E_Discriminant
2105               then
2106                  Append_To (Args,
2107                    New_Occurrence_Of (Discriminal (Entity (Arg)), Loc));
2108
2109               --  Case of access discriminants. We replace the reference
2110               --  to the type by a reference to the actual object.
2111
2112               --  Is above comment right??? Use of New_Copy below seems mighty
2113               --  suspicious ???
2114
2115               else
2116                  Append_To (Args, New_Copy (Arg));
2117               end if;
2118
2119               Next_Discriminant (Parent_Discr);
2120            end loop;
2121         end if;
2122
2123         Res :=
2124           New_List (
2125             Make_Procedure_Call_Statement (Loc,
2126               Name                   =>
2127                 New_Occurrence_Of (Parent_Proc, Loc),
2128               Parameter_Associations => Args));
2129
2130         return Res;
2131      end Build_Init_Call_Thru;
2132
2133      -----------------------------------
2134      -- Build_Offset_To_Top_Functions --
2135      -----------------------------------
2136
2137      procedure Build_Offset_To_Top_Functions is
2138
2139         procedure Build_Offset_To_Top_Function (Iface_Comp : Entity_Id);
2140         --  Generate:
2141         --    function Fxx (O : Address) return Storage_Offset is
2142         --       type Acc is access all <Typ>;
2143         --    begin
2144         --       return Acc!(O).Iface_Comp'Position;
2145         --    end Fxx;
2146
2147         ----------------------------------
2148         -- Build_Offset_To_Top_Function --
2149         ----------------------------------
2150
2151         procedure Build_Offset_To_Top_Function (Iface_Comp : Entity_Id) is
2152            Body_Node : Node_Id;
2153            Func_Id   : Entity_Id;
2154            Spec_Node : Node_Id;
2155            Acc_Type  : Entity_Id;
2156
2157         begin
2158            Func_Id := Make_Temporary (Loc, 'F');
2159            Set_DT_Offset_To_Top_Func (Iface_Comp, Func_Id);
2160
2161            --  Generate
2162            --    function Fxx (O : in Rec_Typ) return Storage_Offset;
2163
2164            Spec_Node := New_Node (N_Function_Specification, Loc);
2165            Set_Defining_Unit_Name (Spec_Node, Func_Id);
2166            Set_Parameter_Specifications (Spec_Node, New_List (
2167              Make_Parameter_Specification (Loc,
2168                Defining_Identifier =>
2169                  Make_Defining_Identifier (Loc, Name_uO),
2170                In_Present          => True,
2171                Parameter_Type      =>
2172                  New_Occurrence_Of (RTE (RE_Address), Loc))));
2173            Set_Result_Definition (Spec_Node,
2174              New_Occurrence_Of (RTE (RE_Storage_Offset), Loc));
2175
2176            --  Generate
2177            --    function Fxx (O : in Rec_Typ) return Storage_Offset is
2178            --    begin
2179            --       return -O.Iface_Comp'Position;
2180            --    end Fxx;
2181
2182            Body_Node := New_Node (N_Subprogram_Body, Loc);
2183            Set_Specification (Body_Node, Spec_Node);
2184
2185            Acc_Type := Make_Temporary (Loc, 'T');
2186            Set_Declarations (Body_Node, New_List (
2187              Make_Full_Type_Declaration (Loc,
2188                Defining_Identifier => Acc_Type,
2189                Type_Definition     =>
2190                  Make_Access_To_Object_Definition (Loc,
2191                    All_Present            => True,
2192                    Null_Exclusion_Present => False,
2193                    Constant_Present       => False,
2194                    Subtype_Indication     =>
2195                      New_Occurrence_Of (Rec_Type, Loc)))));
2196
2197            Set_Handled_Statement_Sequence (Body_Node,
2198              Make_Handled_Sequence_Of_Statements (Loc,
2199                Statements     => New_List (
2200                  Make_Simple_Return_Statement (Loc,
2201                    Expression =>
2202                      Make_Op_Minus (Loc,
2203                        Make_Attribute_Reference (Loc,
2204                          Prefix         =>
2205                            Make_Selected_Component (Loc,
2206                              Prefix        =>
2207                                Unchecked_Convert_To (Acc_Type,
2208                                  Make_Identifier (Loc, Name_uO)),
2209                              Selector_Name =>
2210                                New_Occurrence_Of (Iface_Comp, Loc)),
2211                          Attribute_Name => Name_Position))))));
2212
2213            Set_Ekind       (Func_Id, E_Function);
2214            Set_Mechanism   (Func_Id, Default_Mechanism);
2215            Set_Is_Internal (Func_Id, True);
2216
2217            if not Debug_Generated_Code then
2218               Set_Debug_Info_Off (Func_Id);
2219            end if;
2220
2221            Analyze (Body_Node);
2222
2223            Append_Freeze_Action (Rec_Type, Body_Node);
2224         end Build_Offset_To_Top_Function;
2225
2226         --  Local variables
2227
2228         Iface_Comp       : Node_Id;
2229         Iface_Comp_Elmt  : Elmt_Id;
2230         Ifaces_Comp_List : Elist_Id;
2231
2232      --  Start of processing for Build_Offset_To_Top_Functions
2233
2234      begin
2235         --  Offset_To_Top_Functions are built only for derivations of types
2236         --  with discriminants that cover interface types.
2237         --  Nothing is needed either in case of virtual targets, since
2238         --  interfaces are handled directly by the target.
2239
2240         if not Is_Tagged_Type (Rec_Type)
2241           or else Etype (Rec_Type) = Rec_Type
2242           or else not Has_Discriminants (Etype (Rec_Type))
2243           or else not Tagged_Type_Expansion
2244         then
2245            return;
2246         end if;
2247
2248         Collect_Interface_Components (Rec_Type, Ifaces_Comp_List);
2249
2250         --  For each interface type with secondary dispatch table we generate
2251         --  the Offset_To_Top_Functions (required to displace the pointer in
2252         --  interface conversions)
2253
2254         Iface_Comp_Elmt := First_Elmt (Ifaces_Comp_List);
2255         while Present (Iface_Comp_Elmt) loop
2256            Iface_Comp := Node (Iface_Comp_Elmt);
2257            pragma Assert (Is_Interface (Related_Type (Iface_Comp)));
2258
2259            --  If the interface is a parent of Rec_Type it shares the primary
2260            --  dispatch table and hence there is no need to build the function
2261
2262            if not Is_Ancestor (Related_Type (Iface_Comp), Rec_Type,
2263                                Use_Full_View => True)
2264            then
2265               Build_Offset_To_Top_Function (Iface_Comp);
2266            end if;
2267
2268            Next_Elmt (Iface_Comp_Elmt);
2269         end loop;
2270      end Build_Offset_To_Top_Functions;
2271
2272      ------------------------------
2273      -- Build_CPP_Init_Procedure --
2274      ------------------------------
2275
2276      procedure Build_CPP_Init_Procedure is
2277         Body_Node         : Node_Id;
2278         Body_Stmts        : List_Id;
2279         Flag_Id           : Entity_Id;
2280         Handled_Stmt_Node : Node_Id;
2281         Init_Tags_List    : List_Id;
2282         Proc_Id           : Entity_Id;
2283         Proc_Spec_Node    : Node_Id;
2284
2285      begin
2286         --  Check cases requiring no IC routine
2287
2288         if not Is_CPP_Class (Root_Type (Rec_Type))
2289           or else Is_CPP_Class (Rec_Type)
2290           or else CPP_Num_Prims (Rec_Type) = 0
2291           or else not Tagged_Type_Expansion
2292           or else No_Run_Time_Mode
2293         then
2294            return;
2295         end if;
2296
2297         --  Generate:
2298
2299         --     Flag : Boolean := False;
2300         --
2301         --     procedure Typ_IC is
2302         --     begin
2303         --        if not Flag then
2304         --           Copy C++ dispatch table slots from parent
2305         --           Update C++ slots of overridden primitives
2306         --        end if;
2307         --     end;
2308
2309         Flag_Id := Make_Temporary (Loc, 'F');
2310
2311         Append_Freeze_Action (Rec_Type,
2312           Make_Object_Declaration (Loc,
2313             Defining_Identifier => Flag_Id,
2314             Object_Definition =>
2315               New_Occurrence_Of (Standard_Boolean, Loc),
2316             Expression =>
2317               New_Occurrence_Of (Standard_True, Loc)));
2318
2319         Body_Stmts := New_List;
2320         Body_Node  := New_Node (N_Subprogram_Body, Loc);
2321
2322         Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
2323
2324         Proc_Id :=
2325           Make_Defining_Identifier (Loc,
2326             Chars => Make_TSS_Name (Rec_Type, TSS_CPP_Init_Proc));
2327
2328         Set_Ekind       (Proc_Id, E_Procedure);
2329         Set_Is_Internal (Proc_Id);
2330
2331         Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);
2332
2333         Set_Parameter_Specifications (Proc_Spec_Node, New_List);
2334         Set_Specification (Body_Node, Proc_Spec_Node);
2335         Set_Declarations  (Body_Node, New_List);
2336
2337         Init_Tags_List := Build_Inherit_CPP_Prims (Rec_Type);
2338
2339         Append_To (Init_Tags_List,
2340           Make_Assignment_Statement (Loc,
2341             Name =>
2342               New_Occurrence_Of (Flag_Id, Loc),
2343             Expression =>
2344               New_Occurrence_Of (Standard_False, Loc)));
2345
2346         Append_To (Body_Stmts,
2347           Make_If_Statement (Loc,
2348             Condition => New_Occurrence_Of (Flag_Id, Loc),
2349             Then_Statements => Init_Tags_List));
2350
2351         Handled_Stmt_Node :=
2352           New_Node (N_Handled_Sequence_Of_Statements, Loc);
2353         Set_Statements (Handled_Stmt_Node, Body_Stmts);
2354         Set_Exception_Handlers (Handled_Stmt_Node, No_List);
2355         Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);
2356
2357         if not Debug_Generated_Code then
2358            Set_Debug_Info_Off (Proc_Id);
2359         end if;
2360
2361         --  Associate CPP_Init_Proc with type
2362
2363         Set_Init_Proc (Rec_Type, Proc_Id);
2364      end Build_CPP_Init_Procedure;
2365
2366      --------------------------
2367      -- Build_Init_Procedure --
2368      --------------------------
2369
2370      procedure Build_Init_Procedure is
2371         Body_Stmts            : List_Id;
2372         Body_Node             : Node_Id;
2373         Handled_Stmt_Node     : Node_Id;
2374         Init_Tags_List        : List_Id;
2375         Parameters            : List_Id;
2376         Proc_Spec_Node        : Node_Id;
2377         Record_Extension_Node : Node_Id;
2378
2379      begin
2380         Body_Stmts := New_List;
2381         Body_Node := New_Node (N_Subprogram_Body, Loc);
2382         Set_Ekind (Proc_Id, E_Procedure);
2383
2384         Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
2385         Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);
2386
2387         Parameters := Init_Formals (Rec_Type);
2388         Append_List_To (Parameters,
2389           Build_Discriminant_Formals (Rec_Type, True));
2390
2391         --  For tagged types, we add a flag to indicate whether the routine
2392         --  is called to initialize a parent component in the init_proc of
2393         --  a type extension. If the flag is false, we do not set the tag
2394         --  because it has been set already in the extension.
2395
2396         if Is_Tagged_Type (Rec_Type) then
2397            Set_Tag := Make_Temporary (Loc, 'P');
2398
2399            Append_To (Parameters,
2400              Make_Parameter_Specification (Loc,
2401                Defining_Identifier => Set_Tag,
2402                Parameter_Type =>
2403                  New_Occurrence_Of (Standard_Boolean, Loc),
2404                Expression =>
2405                  New_Occurrence_Of (Standard_True, Loc)));
2406         end if;
2407
2408         Set_Parameter_Specifications (Proc_Spec_Node, Parameters);
2409         Set_Specification (Body_Node, Proc_Spec_Node);
2410         Set_Declarations (Body_Node, Decls);
2411
2412         --  N is a Derived_Type_Definition that renames the parameters of the
2413         --  ancestor type. We initialize it by expanding our discriminants and
2414         --  call the ancestor _init_proc with a type-converted object.
2415
2416         if Parent_Subtype_Renaming_Discrims then
2417            Append_List_To (Body_Stmts, Build_Init_Call_Thru (Parameters));
2418
2419         elsif Nkind (Type_Definition (N)) = N_Record_Definition then
2420            Build_Discriminant_Assignments (Body_Stmts);
2421
2422            if not Null_Present (Type_Definition (N)) then
2423               Append_List_To (Body_Stmts,
2424                 Build_Init_Statements (Component_List (Type_Definition (N))));
2425            end if;
2426
2427         --  N is a Derived_Type_Definition with a possible non-empty
2428         --  extension. The initialization of a type extension consists in the
2429         --  initialization of the components in the extension.
2430
2431         else
2432            Build_Discriminant_Assignments (Body_Stmts);
2433
2434            Record_Extension_Node :=
2435              Record_Extension_Part (Type_Definition (N));
2436
2437            if not Null_Present (Record_Extension_Node) then
2438               declare
2439                  Stmts : constant List_Id :=
2440                            Build_Init_Statements (
2441                              Component_List (Record_Extension_Node));
2442
2443               begin
2444                  --  The parent field must be initialized first because the
2445                  --  offset of the new discriminants may depend on it. This is
2446                  --  not needed if the parent is an interface type because in
2447                  --  such case the initialization of the _parent field was not
2448                  --  generated.
2449
2450                  if not Is_Interface (Etype (Rec_Ent)) then
2451                     declare
2452                        Parent_IP : constant Name_Id :=
2453                                      Make_Init_Proc_Name (Etype (Rec_Ent));
2454                        Stmt      : Node_Id;
2455                        IP_Call   : Node_Id;
2456                        IP_Stmts  : List_Id;
2457
2458                     begin
2459                        --  Look for a call to the parent IP at the beginning
2460                        --  of Stmts associated with the record extension
2461
2462                        Stmt := First (Stmts);
2463                        IP_Call := Empty;
2464                        while Present (Stmt) loop
2465                           if Nkind (Stmt) = N_Procedure_Call_Statement
2466                             and then Chars (Name (Stmt)) = Parent_IP
2467                           then
2468                              IP_Call := Stmt;
2469                              exit;
2470                           end if;
2471
2472                           Next (Stmt);
2473                        end loop;
2474
2475                        --  If found then move it to the beginning of the
2476                        --  statements of this IP routine
2477
2478                        if Present (IP_Call) then
2479                           IP_Stmts := New_List;
2480                           loop
2481                              Stmt := Remove_Head (Stmts);
2482                              Append_To (IP_Stmts, Stmt);
2483                              exit when Stmt = IP_Call;
2484                           end loop;
2485
2486                           Prepend_List_To (Body_Stmts, IP_Stmts);
2487                        end if;
2488                     end;
2489                  end if;
2490
2491                  Append_List_To (Body_Stmts, Stmts);
2492               end;
2493            end if;
2494         end if;
2495
2496         --  Add here the assignment to instantiate the Tag
2497
2498         --  The assignment corresponds to the code:
2499
2500         --     _Init._Tag := Typ'Tag;
2501
2502         --  Suppress the tag assignment when not Tagged_Type_Expansion because
2503         --  tags are represented implicitly in objects. It is also suppressed
2504         --  in case of CPP_Class types because in this case the tag is
2505         --  initialized in the C++ side.
2506
2507         if Is_Tagged_Type (Rec_Type)
2508           and then Tagged_Type_Expansion
2509           and then not No_Run_Time_Mode
2510         then
2511            --  Case 1: Ada tagged types with no CPP ancestor. Set the tags of
2512            --  the actual object and invoke the IP of the parent (in this
2513            --  order). The tag must be initialized before the call to the IP
2514            --  of the parent and the assignments to other components because
2515            --  the initial value of the components may depend on the tag (eg.
2516            --  through a dispatching operation on an access to the current
2517            --  type). The tag assignment is not done when initializing the
2518            --  parent component of a type extension, because in that case the
2519            --  tag is set in the extension.
2520
2521            if not Is_CPP_Class (Root_Type (Rec_Type)) then
2522
2523               --  Initialize the primary tag component
2524
2525               Init_Tags_List := New_List (
2526                 Make_Assignment_Statement (Loc,
2527                   Name =>
2528                     Make_Selected_Component (Loc,
2529                       Prefix        => Make_Identifier (Loc, Name_uInit),
2530                       Selector_Name =>
2531                         New_Occurrence_Of
2532                           (First_Tag_Component (Rec_Type), Loc)),
2533                   Expression =>
2534                     New_Occurrence_Of
2535                       (Node
2536                         (First_Elmt (Access_Disp_Table (Rec_Type))), Loc)));
2537
2538               --  Ada 2005 (AI-251): Initialize the secondary tags components
2539               --  located at fixed positions (tags whose position depends on
2540               --  variable size components are initialized later ---see below)
2541
2542               if Ada_Version >= Ada_2005
2543                 and then not Is_Interface (Rec_Type)
2544                 and then Has_Interfaces (Rec_Type)
2545               then
2546                  declare
2547                     Elab_Sec_DT_Stmts_List : constant List_Id := New_List;
2548                     Elab_List              : List_Id          := New_List;
2549
2550                  begin
2551                     Init_Secondary_Tags
2552                       (Typ            => Rec_Type,
2553                        Target         => Make_Identifier (Loc, Name_uInit),
2554                        Init_Tags_List => Init_Tags_List,
2555                        Stmts_List     => Elab_Sec_DT_Stmts_List,
2556                        Fixed_Comps    => True,
2557                        Variable_Comps => False);
2558
2559                     Elab_List := New_List (
2560                       Make_If_Statement (Loc,
2561                         Condition       => New_Occurrence_Of (Set_Tag, Loc),
2562                         Then_Statements => Init_Tags_List));
2563
2564                     if Elab_Flag_Needed (Rec_Type) then
2565                        Append_To (Elab_Sec_DT_Stmts_List,
2566                          Make_Assignment_Statement (Loc,
2567                            Name       =>
2568                              New_Occurrence_Of
2569                                (Access_Disp_Table_Elab_Flag (Rec_Type),
2570                                 Loc),
2571                            Expression =>
2572                              New_Occurrence_Of (Standard_False, Loc)));
2573
2574                        Append_To (Elab_List,
2575                          Make_If_Statement (Loc,
2576                            Condition       =>
2577                              New_Occurrence_Of
2578                                (Access_Disp_Table_Elab_Flag (Rec_Type), Loc),
2579                            Then_Statements => Elab_Sec_DT_Stmts_List));
2580                     end if;
2581
2582                     Prepend_List_To (Body_Stmts, Elab_List);
2583                  end;
2584               else
2585                  Prepend_To (Body_Stmts,
2586                    Make_If_Statement (Loc,
2587                      Condition       => New_Occurrence_Of (Set_Tag, Loc),
2588                      Then_Statements => Init_Tags_List));
2589               end if;
2590
2591            --  Case 2: CPP type. The imported C++ constructor takes care of
2592            --  tags initialization. No action needed here because the IP
2593            --  is built by Set_CPP_Constructors; in this case the IP is a
2594            --  wrapper that invokes the C++ constructor and copies the C++
2595            --  tags locally. Done to inherit the C++ slots in Ada derivations
2596            --  (see case 3).
2597
2598            elsif Is_CPP_Class (Rec_Type) then
2599               pragma Assert (False);
2600               null;
2601
2602            --  Case 3: Combined hierarchy containing C++ types and Ada tagged
2603            --  type derivations. Derivations of imported C++ classes add a
2604            --  complication, because we cannot inhibit tag setting in the
2605            --  constructor for the parent. Hence we initialize the tag after
2606            --  the call to the parent IP (that is, in reverse order compared
2607            --  with pure Ada hierarchies ---see comment on case 1).
2608
2609            else
2610               --  Initialize the primary tag
2611
2612               Init_Tags_List := New_List (
2613                 Make_Assignment_Statement (Loc,
2614                   Name =>
2615                     Make_Selected_Component (Loc,
2616                       Prefix        => Make_Identifier (Loc, Name_uInit),
2617                       Selector_Name =>
2618                         New_Occurrence_Of
2619                           (First_Tag_Component (Rec_Type), Loc)),
2620                   Expression =>
2621                     New_Occurrence_Of
2622                       (Node
2623                         (First_Elmt (Access_Disp_Table (Rec_Type))), Loc)));
2624
2625               --  Ada 2005 (AI-251): Initialize the secondary tags components
2626               --  located at fixed positions (tags whose position depends on
2627               --  variable size components are initialized later ---see below)
2628
2629               if Ada_Version >= Ada_2005
2630                 and then not Is_Interface (Rec_Type)
2631                 and then Has_Interfaces (Rec_Type)
2632               then
2633                  Init_Secondary_Tags
2634                    (Typ            => Rec_Type,
2635                     Target         => Make_Identifier (Loc, Name_uInit),
2636                     Init_Tags_List => Init_Tags_List,
2637                     Stmts_List     => Init_Tags_List,
2638                     Fixed_Comps    => True,
2639                     Variable_Comps => False);
2640               end if;
2641
2642               --  Initialize the tag component after invocation of parent IP.
2643
2644               --  Generate:
2645               --     parent_IP(_init.parent); // Invokes the C++ constructor
2646               --     [ typIC; ]               // Inherit C++ slots from parent
2647               --     init_tags
2648
2649               declare
2650                  Ins_Nod : Node_Id;
2651
2652               begin
2653                  --  Search for the call to the IP of the parent. We assume
2654                  --  that the first init_proc call is for the parent.
2655
2656                  Ins_Nod := First (Body_Stmts);
2657                  while Present (Next (Ins_Nod))
2658                    and then (Nkind (Ins_Nod) /= N_Procedure_Call_Statement
2659                               or else not Is_Init_Proc (Name (Ins_Nod)))
2660                  loop
2661                     Next (Ins_Nod);
2662                  end loop;
2663
2664                  --  The IC routine copies the inherited slots of the C+ part
2665                  --  of the dispatch table from the parent and updates the
2666                  --  overridden C++ slots.
2667
2668                  if CPP_Num_Prims (Rec_Type) > 0 then
2669                     declare
2670                        Init_DT : Entity_Id;
2671                        New_Nod : Node_Id;
2672
2673                     begin
2674                        Init_DT := CPP_Init_Proc (Rec_Type);
2675                        pragma Assert (Present (Init_DT));
2676
2677                        New_Nod :=
2678                          Make_Procedure_Call_Statement (Loc,
2679                            New_Occurrence_Of (Init_DT, Loc));
2680                        Insert_After (Ins_Nod, New_Nod);
2681
2682                        --  Update location of init tag statements
2683
2684                        Ins_Nod := New_Nod;
2685                     end;
2686                  end if;
2687
2688                  Insert_List_After (Ins_Nod, Init_Tags_List);
2689               end;
2690            end if;
2691
2692            --  Ada 2005 (AI-251): Initialize the secondary tag components
2693            --  located at variable positions. We delay the generation of this
2694            --  code until here because the value of the attribute 'Position
2695            --  applied to variable size components of the parent type that
2696            --  depend on discriminants is only safely read at runtime after
2697            --  the parent components have been initialized.
2698
2699            if Ada_Version >= Ada_2005
2700              and then not Is_Interface (Rec_Type)
2701              and then Has_Interfaces (Rec_Type)
2702              and then Has_Discriminants (Etype (Rec_Type))
2703              and then Is_Variable_Size_Record (Etype (Rec_Type))
2704            then
2705               Init_Tags_List := New_List;
2706
2707               Init_Secondary_Tags
2708                 (Typ            => Rec_Type,
2709                  Target         => Make_Identifier (Loc, Name_uInit),
2710                  Init_Tags_List => Init_Tags_List,
2711                  Stmts_List     => Init_Tags_List,
2712                  Fixed_Comps    => False,
2713                  Variable_Comps => True);
2714
2715               if Is_Non_Empty_List (Init_Tags_List) then
2716                  Append_List_To (Body_Stmts, Init_Tags_List);
2717               end if;
2718            end if;
2719         end if;
2720
2721         Handled_Stmt_Node := New_Node (N_Handled_Sequence_Of_Statements, Loc);
2722         Set_Statements (Handled_Stmt_Node, Body_Stmts);
2723
2724         --  Generate:
2725         --    Deep_Finalize (_init, C1, ..., CN);
2726         --    raise;
2727
2728         if Counter > 0
2729           and then Needs_Finalization (Rec_Type)
2730           and then not Is_Abstract_Type (Rec_Type)
2731           and then not Restriction_Active (No_Exception_Propagation)
2732         then
2733            declare
2734               DF_Call : Node_Id;
2735               DF_Id   : Entity_Id;
2736
2737            begin
2738               --  Create a local version of Deep_Finalize which has indication
2739               --  of partial initialization state.
2740
2741               DF_Id :=
2742                 Make_Defining_Identifier (Loc,
2743                   Chars => New_External_Name (Name_uFinalizer));
2744
2745               Append_To (Decls, Make_Local_Deep_Finalize (Rec_Type, DF_Id));
2746
2747               DF_Call :=
2748                 Make_Procedure_Call_Statement (Loc,
2749                   Name                   => New_Occurrence_Of (DF_Id, Loc),
2750                   Parameter_Associations => New_List (
2751                     Make_Identifier (Loc, Name_uInit),
2752                     New_Occurrence_Of (Standard_False, Loc)));
2753
2754               --  Do not emit warnings related to the elaboration order when a
2755               --  controlled object is declared before the body of Finalize is
2756               --  seen.
2757
2758               if Legacy_Elaboration_Checks then
2759                  Set_No_Elaboration_Check (DF_Call);
2760               end if;
2761
2762               Set_Exception_Handlers (Handled_Stmt_Node, New_List (
2763                 Make_Exception_Handler (Loc,
2764                   Exception_Choices => New_List (
2765                     Make_Others_Choice (Loc)),
2766                   Statements        => New_List (
2767                     DF_Call,
2768                     Make_Raise_Statement (Loc)))));
2769            end;
2770         else
2771            Set_Exception_Handlers (Handled_Stmt_Node, No_List);
2772         end if;
2773
2774         Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);
2775
2776         if not Debug_Generated_Code then
2777            Set_Debug_Info_Off (Proc_Id);
2778         end if;
2779
2780         --  Associate Init_Proc with type, and determine if the procedure
2781         --  is null (happens because of the Initialize_Scalars pragma case,
2782         --  where we have to generate a null procedure in case it is called
2783         --  by a client with Initialize_Scalars set). Such procedures have
2784         --  to be generated, but do not have to be called, so we mark them
2785         --  as null to suppress the call.
2786
2787         Set_Init_Proc (Rec_Type, Proc_Id);
2788
2789         if List_Length (Body_Stmts) = 1
2790
2791           --  We must skip SCIL nodes because they may have been added to this
2792           --  list by Insert_Actions.
2793
2794           and then Nkind (First_Non_SCIL_Node (Body_Stmts)) = N_Null_Statement
2795         then
2796            Set_Is_Null_Init_Proc (Proc_Id);
2797         end if;
2798      end Build_Init_Procedure;
2799
2800      ---------------------------
2801      -- Build_Init_Statements --
2802      ---------------------------
2803
2804      function Build_Init_Statements (Comp_List : Node_Id) return List_Id is
2805         Checks       : constant List_Id := New_List;
2806         Actions      : List_Id          := No_List;
2807         Counter_Id   : Entity_Id        := Empty;
2808         Comp_Loc     : Source_Ptr;
2809         Decl         : Node_Id;
2810         Has_POC      : Boolean;
2811         Id           : Entity_Id;
2812         Parent_Stmts : List_Id;
2813         Stmts        : List_Id;
2814         Typ          : Entity_Id;
2815
2816         procedure Increment_Counter (Loc : Source_Ptr);
2817         --  Generate an "increment by one" statement for the current counter
2818         --  and append it to the list Stmts.
2819
2820         procedure Make_Counter (Loc : Source_Ptr);
2821         --  Create a new counter for the current component list. The routine
2822         --  creates a new defining Id, adds an object declaration and sets
2823         --  the Id generator for the next variant.
2824
2825         -----------------------
2826         -- Increment_Counter --
2827         -----------------------
2828
2829         procedure Increment_Counter (Loc : Source_Ptr) is
2830         begin
2831            --  Generate:
2832            --    Counter := Counter + 1;
2833
2834            Append_To (Stmts,
2835              Make_Assignment_Statement (Loc,
2836                Name       => New_Occurrence_Of (Counter_Id, Loc),
2837                Expression =>
2838                  Make_Op_Add (Loc,
2839                    Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
2840                    Right_Opnd => Make_Integer_Literal (Loc, 1))));
2841         end Increment_Counter;
2842
2843         ------------------
2844         -- Make_Counter --
2845         ------------------
2846
2847         procedure Make_Counter (Loc : Source_Ptr) is
2848         begin
2849            --  Increment the Id generator
2850
2851            Counter := Counter + 1;
2852
2853            --  Create the entity and declaration
2854
2855            Counter_Id :=
2856              Make_Defining_Identifier (Loc,
2857                Chars => New_External_Name ('C', Counter));
2858
2859            --  Generate:
2860            --    Cnn : Integer := 0;
2861
2862            Append_To (Decls,
2863              Make_Object_Declaration (Loc,
2864                Defining_Identifier => Counter_Id,
2865                Object_Definition   =>
2866                  New_Occurrence_Of (Standard_Integer, Loc),
2867                Expression          =>
2868                  Make_Integer_Literal (Loc, 0)));
2869         end Make_Counter;
2870
2871      --  Start of processing for Build_Init_Statements
2872
2873      begin
2874         if Null_Present (Comp_List) then
2875            return New_List (Make_Null_Statement (Loc));
2876         end if;
2877
2878         Parent_Stmts := New_List;
2879         Stmts := New_List;
2880
2881         --  Loop through visible declarations of task types and protected
2882         --  types moving any expanded code from the spec to the body of the
2883         --  init procedure.
2884
2885         if Is_Task_Record_Type (Rec_Type)
2886           or else Is_Protected_Record_Type (Rec_Type)
2887         then
2888            declare
2889               Decl : constant Node_Id :=
2890                        Parent (Corresponding_Concurrent_Type (Rec_Type));
2891               Def  : Node_Id;
2892               N1   : Node_Id;
2893               N2   : Node_Id;
2894
2895            begin
2896               if Is_Task_Record_Type (Rec_Type) then
2897                  Def := Task_Definition (Decl);
2898               else
2899                  Def := Protected_Definition (Decl);
2900               end if;
2901
2902               if Present (Def) then
2903                  N1 := First (Visible_Declarations (Def));
2904                  while Present (N1) loop
2905                     N2 := N1;
2906                     N1 := Next (N1);
2907
2908                     if Nkind (N2) in N_Statement_Other_Than_Procedure_Call
2909                       or else Nkind (N2) in N_Raise_xxx_Error
2910                       or else Nkind (N2) = N_Procedure_Call_Statement
2911                     then
2912                        Append_To (Stmts,
2913                          New_Copy_Tree (N2, New_Scope => Proc_Id));
2914                        Rewrite (N2, Make_Null_Statement (Sloc (N2)));
2915                        Analyze (N2);
2916                     end if;
2917                  end loop;
2918               end if;
2919            end;
2920         end if;
2921
2922         --  Loop through components, skipping pragmas, in 2 steps. The first
2923         --  step deals with regular components. The second step deals with
2924         --  components that have per object constraints and no explicit
2925         --  initialization.
2926
2927         Has_POC := False;
2928
2929         --  First pass : regular components
2930
2931         Decl := First_Non_Pragma (Component_Items (Comp_List));
2932         while Present (Decl) loop
2933            Comp_Loc := Sloc (Decl);
2934            Build_Record_Checks
2935              (Subtype_Indication (Component_Definition (Decl)), Checks);
2936
2937            Id  := Defining_Identifier (Decl);
2938            Typ := Etype (Id);
2939
2940            --  Leave any processing of per-object constrained component for
2941            --  the second pass.
2942
2943            if Has_Access_Constraint (Id) and then No (Expression (Decl)) then
2944               Has_POC := True;
2945
2946            --  Regular component cases
2947
2948            else
2949               --  In the context of the init proc, references to discriminants
2950               --  resolve to denote the discriminals: this is where we can
2951               --  freeze discriminant dependent component subtypes.
2952
2953               if not Is_Frozen (Typ) then
2954                  Append_List_To (Stmts, Freeze_Entity (Typ, N));
2955               end if;
2956
2957               --  Explicit initialization
2958
2959               if Present (Expression (Decl)) then
2960                  if Is_CPP_Constructor_Call (Expression (Decl)) then
2961                     Actions :=
2962                       Build_Initialization_Call
2963                         (Comp_Loc,
2964                          Id_Ref          =>
2965                            Make_Selected_Component (Comp_Loc,
2966                              Prefix        =>
2967                                Make_Identifier (Comp_Loc, Name_uInit),
2968                              Selector_Name =>
2969                                New_Occurrence_Of (Id, Comp_Loc)),
2970                          Typ             => Typ,
2971                          In_Init_Proc    => True,
2972                          Enclos_Type     => Rec_Type,
2973                          Discr_Map       => Discr_Map,
2974                          Constructor_Ref => Expression (Decl));
2975                  else
2976                     Actions := Build_Assignment (Id, Expression (Decl));
2977                  end if;
2978
2979               --  CPU, Dispatching_Domain, Priority, and Secondary_Stack_Size
2980               --  components are filled in with the corresponding rep-item
2981               --  expression of the concurrent type (if any).
2982
2983               elsif Ekind (Scope (Id)) = E_Record_Type
2984                 and then Present (Corresponding_Concurrent_Type (Scope (Id)))
2985                 and then Nam_In (Chars (Id), Name_uCPU,
2986                                              Name_uDispatching_Domain,
2987                                              Name_uPriority,
2988                                              Name_uSecondary_Stack_Size)
2989               then
2990                  declare
2991                     Exp   : Node_Id;
2992                     Nam   : Name_Id;
2993                     pragma Warnings (Off, Nam);
2994                     Ritem : Node_Id;
2995
2996                  begin
2997                     if Chars (Id) = Name_uCPU then
2998                        Nam := Name_CPU;
2999
3000                     elsif Chars (Id) = Name_uDispatching_Domain then
3001                        Nam := Name_Dispatching_Domain;
3002
3003                     elsif Chars (Id) = Name_uPriority then
3004                        Nam := Name_Priority;
3005
3006                     elsif Chars (Id) = Name_uSecondary_Stack_Size then
3007                        Nam := Name_Secondary_Stack_Size;
3008                     end if;
3009
3010                     --  Get the Rep Item (aspect specification, attribute
3011                     --  definition clause or pragma) of the corresponding
3012                     --  concurrent type.
3013
3014                     Ritem :=
3015                       Get_Rep_Item
3016                         (Corresponding_Concurrent_Type (Scope (Id)),
3017                          Nam,
3018                          Check_Parents => False);
3019
3020                     if Present (Ritem) then
3021
3022                        --  Pragma case
3023
3024                        if Nkind (Ritem) = N_Pragma then
3025                           Exp := First (Pragma_Argument_Associations (Ritem));
3026
3027                           if Nkind (Exp) = N_Pragma_Argument_Association then
3028                              Exp := Expression (Exp);
3029                           end if;
3030
3031                           --  Conversion for Priority expression
3032
3033                           if Nam = Name_Priority then
3034                              if Pragma_Name (Ritem) = Name_Priority
3035                                and then not GNAT_Mode
3036                              then
3037                                 Exp := Convert_To (RTE (RE_Priority), Exp);
3038                              else
3039                                 Exp :=
3040                                   Convert_To (RTE (RE_Any_Priority), Exp);
3041                              end if;
3042                           end if;
3043
3044                        --  Aspect/Attribute definition clause case
3045
3046                        else
3047                           Exp := Expression (Ritem);
3048
3049                           --  Conversion for Priority expression
3050
3051                           if Nam = Name_Priority then
3052                              if Chars (Ritem) = Name_Priority
3053                                and then not GNAT_Mode
3054                              then
3055                                 Exp := Convert_To (RTE (RE_Priority), Exp);
3056                              else
3057                                 Exp :=
3058                                   Convert_To (RTE (RE_Any_Priority), Exp);
3059                              end if;
3060                           end if;
3061                        end if;
3062
3063                        --  Conversion for Dispatching_Domain value
3064
3065                        if Nam = Name_Dispatching_Domain then
3066                           Exp :=
3067                             Unchecked_Convert_To
3068                               (RTE (RE_Dispatching_Domain_Access), Exp);
3069
3070                        --  Conversion for Secondary_Stack_Size value
3071
3072                        elsif Nam = Name_Secondary_Stack_Size then
3073                           Exp := Convert_To (RTE (RE_Size_Type), Exp);
3074                        end if;
3075
3076                        Actions := Build_Assignment (Id, Exp);
3077
3078                     --  Nothing needed if no Rep Item
3079
3080                     else
3081                        Actions := No_List;
3082                     end if;
3083                  end;
3084
3085               --  Composite component with its own Init_Proc
3086
3087               elsif not Is_Interface (Typ)
3088                 and then Has_Non_Null_Base_Init_Proc (Typ)
3089               then
3090                  Actions :=
3091                    Build_Initialization_Call
3092                      (Comp_Loc,
3093                       Make_Selected_Component (Comp_Loc,
3094                         Prefix        =>
3095                           Make_Identifier (Comp_Loc, Name_uInit),
3096                         Selector_Name => New_Occurrence_Of (Id, Comp_Loc)),
3097                       Typ,
3098                       In_Init_Proc => True,
3099                       Enclos_Type  => Rec_Type,
3100                       Discr_Map    => Discr_Map);
3101
3102                  Clean_Task_Names (Typ, Proc_Id);
3103
3104               --  Simple initialization
3105
3106               elsif Component_Needs_Simple_Initialization (Typ) then
3107                  Actions :=
3108                    Build_Assignment
3109                      (Id, Get_Simple_Init_Val (Typ, N, Esize (Id)));
3110
3111               --  Nothing needed for this case
3112
3113               else
3114                  Actions := No_List;
3115               end if;
3116
3117               if Present (Checks) then
3118                  if Chars (Id) = Name_uParent then
3119                     Append_List_To (Parent_Stmts, Checks);
3120                  else
3121                     Append_List_To (Stmts, Checks);
3122                  end if;
3123               end if;
3124
3125               if Present (Actions) then
3126                  if Chars (Id) = Name_uParent then
3127                     Append_List_To (Parent_Stmts, Actions);
3128
3129                  else
3130                     Append_List_To (Stmts, Actions);
3131
3132                     --  Preserve initialization state in the current counter
3133
3134                     if Needs_Finalization (Typ) then
3135                        if No (Counter_Id) then
3136                           Make_Counter (Comp_Loc);
3137                        end if;
3138
3139                        Increment_Counter (Comp_Loc);
3140                     end if;
3141                  end if;
3142               end if;
3143            end if;
3144
3145            Next_Non_Pragma (Decl);
3146         end loop;
3147
3148         --  The parent field must be initialized first because variable
3149         --  size components of the parent affect the location of all the
3150         --  new components.
3151
3152         Prepend_List_To (Stmts, Parent_Stmts);
3153
3154         --  Set up tasks and protected object support. This needs to be done
3155         --  before any component with a per-object access discriminant
3156         --  constraint, or any variant part (which may contain such
3157         --  components) is initialized, because the initialization of these
3158         --  components may reference the enclosing concurrent object.
3159
3160         --  For a task record type, add the task create call and calls to bind
3161         --  any interrupt (signal) entries.
3162
3163         if Is_Task_Record_Type (Rec_Type) then
3164
3165            --  In the case of the restricted run time the ATCB has already
3166            --  been preallocated.
3167
3168            if Restricted_Profile then
3169               Append_To (Stmts,
3170                 Make_Assignment_Statement (Loc,
3171                   Name       =>
3172                     Make_Selected_Component (Loc,
3173                       Prefix        => Make_Identifier (Loc, Name_uInit),
3174                       Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
3175                   Expression =>
3176                     Make_Attribute_Reference (Loc,
3177                       Prefix         =>
3178                         Make_Selected_Component (Loc,
3179                           Prefix        => Make_Identifier (Loc, Name_uInit),
3180                           Selector_Name => Make_Identifier (Loc, Name_uATCB)),
3181                       Attribute_Name => Name_Unchecked_Access)));
3182            end if;
3183
3184            Append_To (Stmts, Make_Task_Create_Call (Rec_Type));
3185
3186            declare
3187               Task_Type : constant Entity_Id :=
3188                             Corresponding_Concurrent_Type (Rec_Type);
3189               Task_Decl : constant Node_Id := Parent (Task_Type);
3190               Task_Def  : constant Node_Id := Task_Definition (Task_Decl);
3191               Decl_Loc  : Source_Ptr;
3192               Ent       : Entity_Id;
3193               Vis_Decl  : Node_Id;
3194
3195            begin
3196               if Present (Task_Def) then
3197                  Vis_Decl := First (Visible_Declarations (Task_Def));
3198                  while Present (Vis_Decl) loop
3199                     Decl_Loc := Sloc (Vis_Decl);
3200
3201                     if Nkind (Vis_Decl) = N_Attribute_Definition_Clause then
3202                        if Get_Attribute_Id (Chars (Vis_Decl)) =
3203                                                       Attribute_Address
3204                        then
3205                           Ent := Entity (Name (Vis_Decl));
3206
3207                           if Ekind (Ent) = E_Entry then
3208                              Append_To (Stmts,
3209                                Make_Procedure_Call_Statement (Decl_Loc,
3210                                  Name =>
3211                                    New_Occurrence_Of (RTE (
3212                                      RE_Bind_Interrupt_To_Entry), Decl_Loc),
3213                                  Parameter_Associations => New_List (
3214                                    Make_Selected_Component (Decl_Loc,
3215                                      Prefix        =>
3216                                        Make_Identifier (Decl_Loc, Name_uInit),
3217                                      Selector_Name =>
3218                                        Make_Identifier
3219                                         (Decl_Loc, Name_uTask_Id)),
3220                                    Entry_Index_Expression
3221                                      (Decl_Loc, Ent, Empty, Task_Type),
3222                                    Expression (Vis_Decl))));
3223                           end if;
3224                        end if;
3225                     end if;
3226
3227                     Next (Vis_Decl);
3228                  end loop;
3229               end if;
3230            end;
3231         end if;
3232
3233         --  For a protected type, add statements generated by
3234         --  Make_Initialize_Protection.
3235
3236         if Is_Protected_Record_Type (Rec_Type) then
3237            Append_List_To (Stmts,
3238              Make_Initialize_Protection (Rec_Type));
3239         end if;
3240
3241         --  Second pass: components with per-object constraints
3242
3243         if Has_POC then
3244            Decl := First_Non_Pragma (Component_Items (Comp_List));
3245            while Present (Decl) loop
3246               Comp_Loc := Sloc (Decl);
3247               Id := Defining_Identifier (Decl);
3248               Typ := Etype (Id);
3249
3250               if Has_Access_Constraint (Id)
3251                 and then No (Expression (Decl))
3252               then
3253                  if Has_Non_Null_Base_Init_Proc (Typ) then
3254                     Append_List_To (Stmts,
3255                       Build_Initialization_Call (Comp_Loc,
3256                         Make_Selected_Component (Comp_Loc,
3257                           Prefix        =>
3258                             Make_Identifier (Comp_Loc, Name_uInit),
3259                           Selector_Name => New_Occurrence_Of (Id, Comp_Loc)),
3260                         Typ,
3261                         In_Init_Proc => True,
3262                         Enclos_Type  => Rec_Type,
3263                         Discr_Map    => Discr_Map));
3264
3265                     Clean_Task_Names (Typ, Proc_Id);
3266
3267                     --  Preserve initialization state in the current counter
3268
3269                     if Needs_Finalization (Typ) then
3270                        if No (Counter_Id) then
3271                           Make_Counter (Comp_Loc);
3272                        end if;
3273
3274                        Increment_Counter (Comp_Loc);
3275                     end if;
3276
3277                  elsif Component_Needs_Simple_Initialization (Typ) then
3278                     Append_List_To (Stmts,
3279                       Build_Assignment
3280                         (Id, Get_Simple_Init_Val (Typ, N, Esize (Id))));
3281                  end if;
3282               end if;
3283
3284               Next_Non_Pragma (Decl);
3285            end loop;
3286         end if;
3287
3288         --  Process the variant part
3289
3290         if Present (Variant_Part (Comp_List)) then
3291            declare
3292               Variant_Alts : constant List_Id := New_List;
3293               Var_Loc      : Source_Ptr := No_Location;
3294               Variant      : Node_Id;
3295
3296            begin
3297               Variant :=
3298                 First_Non_Pragma (Variants (Variant_Part (Comp_List)));
3299               while Present (Variant) loop
3300                  Var_Loc := Sloc (Variant);
3301                  Append_To (Variant_Alts,
3302                    Make_Case_Statement_Alternative (Var_Loc,
3303                      Discrete_Choices =>
3304                        New_Copy_List (Discrete_Choices (Variant)),
3305                      Statements =>
3306                        Build_Init_Statements (Component_List (Variant))));
3307                  Next_Non_Pragma (Variant);
3308               end loop;
3309
3310               --  The expression of the case statement which is a reference
3311               --  to one of the discriminants is replaced by the appropriate
3312               --  formal parameter of the initialization procedure.
3313
3314               Append_To (Stmts,
3315                 Make_Case_Statement (Var_Loc,
3316                   Expression =>
3317                     New_Occurrence_Of (Discriminal (
3318                       Entity (Name (Variant_Part (Comp_List)))), Var_Loc),
3319                   Alternatives => Variant_Alts));
3320            end;
3321         end if;
3322
3323         --  If no initializations when generated for component declarations
3324         --  corresponding to this Stmts, append a null statement to Stmts to
3325         --  to make it a valid Ada tree.
3326
3327         if Is_Empty_List (Stmts) then
3328            Append (Make_Null_Statement (Loc), Stmts);
3329         end if;
3330
3331         return Stmts;
3332
3333      exception
3334         when RE_Not_Available =>
3335            return Empty_List;
3336      end Build_Init_Statements;
3337
3338      -------------------------
3339      -- Build_Record_Checks --
3340      -------------------------
3341
3342      procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id) is
3343         Subtype_Mark_Id : Entity_Id;
3344
3345         procedure Constrain_Array
3346           (SI         : Node_Id;
3347            Check_List : List_Id);
3348         --  Apply a list of index constraints to an unconstrained array type.
3349         --  The first parameter is the entity for the resulting subtype.
3350         --  Check_List is a list to which the check actions are appended.
3351
3352         ---------------------
3353         -- Constrain_Array --
3354         ---------------------
3355
3356         procedure Constrain_Array
3357           (SI         : Node_Id;
3358            Check_List : List_Id)
3359         is
3360            C                     : constant Node_Id := Constraint (SI);
3361            Number_Of_Constraints : Nat := 0;
3362            Index                 : Node_Id;
3363            S, T                  : Entity_Id;
3364
3365            procedure Constrain_Index
3366              (Index      : Node_Id;
3367               S          : Node_Id;
3368               Check_List : List_Id);
3369            --  Process an index constraint in a constrained array declaration.
3370            --  The constraint can be either a subtype name or a range with or
3371            --  without an explicit subtype mark. Index is the corresponding
3372            --  index of the unconstrained array. S is the range expression.
3373            --  Check_List is a list to which the check actions are appended.
3374
3375            ---------------------
3376            -- Constrain_Index --
3377            ---------------------
3378
3379            procedure Constrain_Index
3380              (Index        : Node_Id;
3381               S            : Node_Id;
3382               Check_List   : List_Id)
3383            is
3384               T : constant Entity_Id := Etype (Index);
3385
3386            begin
3387               if Nkind (S) = N_Range then
3388                  Process_Range_Expr_In_Decl (S, T, Check_List => Check_List);
3389               end if;
3390            end Constrain_Index;
3391
3392         --  Start of processing for Constrain_Array
3393
3394         begin
3395            T := Entity (Subtype_Mark (SI));
3396
3397            if Is_Access_Type (T) then
3398               T := Designated_Type (T);
3399            end if;
3400
3401            S := First (Constraints (C));
3402            while Present (S) loop
3403               Number_Of_Constraints := Number_Of_Constraints + 1;
3404               Next (S);
3405            end loop;
3406
3407            --  In either case, the index constraint must provide a discrete
3408            --  range for each index of the array type and the type of each
3409            --  discrete range must be the same as that of the corresponding
3410            --  index. (RM 3.6.1)
3411
3412            S := First (Constraints (C));
3413            Index := First_Index (T);
3414            Analyze (Index);
3415
3416            --  Apply constraints to each index type
3417
3418            for J in 1 .. Number_Of_Constraints loop
3419               Constrain_Index (Index, S, Check_List);
3420               Next (Index);
3421               Next (S);
3422            end loop;
3423         end Constrain_Array;
3424
3425      --  Start of processing for Build_Record_Checks
3426
3427      begin
3428         if Nkind (S) = N_Subtype_Indication then
3429            Find_Type (Subtype_Mark (S));
3430            Subtype_Mark_Id := Entity (Subtype_Mark (S));
3431
3432            --  Remaining processing depends on type
3433
3434            case Ekind (Subtype_Mark_Id) is
3435               when Array_Kind =>
3436                  Constrain_Array (S, Check_List);
3437
3438               when others =>
3439                  null;
3440            end case;
3441         end if;
3442      end Build_Record_Checks;
3443
3444      -------------------------------------------
3445      -- Component_Needs_Simple_Initialization --
3446      -------------------------------------------
3447
3448      function Component_Needs_Simple_Initialization
3449        (T : Entity_Id) return Boolean
3450      is
3451      begin
3452         return
3453           Needs_Simple_Initialization (T)
3454             and then not Is_RTE (T, RE_Tag)
3455
3456             --  Ada 2005 (AI-251): Check also the tag of abstract interfaces
3457
3458             and then not Is_RTE (T, RE_Interface_Tag);
3459      end Component_Needs_Simple_Initialization;
3460
3461      --------------------------------------
3462      -- Parent_Subtype_Renaming_Discrims --
3463      --------------------------------------
3464
3465      function Parent_Subtype_Renaming_Discrims return Boolean is
3466         De : Entity_Id;
3467         Dp : Entity_Id;
3468
3469      begin
3470         if Base_Type (Rec_Ent) /= Rec_Ent then
3471            return False;
3472         end if;
3473
3474         if Etype (Rec_Ent) = Rec_Ent
3475           or else not Has_Discriminants (Rec_Ent)
3476           or else Is_Constrained (Rec_Ent)
3477           or else Is_Tagged_Type (Rec_Ent)
3478         then
3479            return False;
3480         end if;
3481
3482         --  If there are no explicit stored discriminants we have inherited
3483         --  the root type discriminants so far, so no renamings occurred.
3484
3485         if First_Discriminant (Rec_Ent) =
3486              First_Stored_Discriminant (Rec_Ent)
3487         then
3488            return False;
3489         end if;
3490
3491         --  Check if we have done some trivial renaming of the parent
3492         --  discriminants, i.e. something like
3493         --
3494         --    type DT (X1, X2: int) is new PT (X1, X2);
3495
3496         De := First_Discriminant (Rec_Ent);
3497         Dp := First_Discriminant (Etype (Rec_Ent));
3498         while Present (De) loop
3499            pragma Assert (Present (Dp));
3500
3501            if Corresponding_Discriminant (De) /= Dp then
3502               return True;
3503            end if;
3504
3505            Next_Discriminant (De);
3506            Next_Discriminant (Dp);
3507         end loop;
3508
3509         return Present (Dp);
3510      end Parent_Subtype_Renaming_Discrims;
3511
3512      ------------------------
3513      -- Requires_Init_Proc --
3514      ------------------------
3515
3516      function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean is
3517         Comp_Decl : Node_Id;
3518         Id        : Entity_Id;
3519         Typ       : Entity_Id;
3520
3521      begin
3522         --  Definitely do not need one if specifically suppressed
3523
3524         if Initialization_Suppressed (Rec_Id) then
3525            return False;
3526         end if;
3527
3528         --  If it is a type derived from a type with unknown discriminants,
3529         --  we cannot build an initialization procedure for it.
3530
3531         if Has_Unknown_Discriminants (Rec_Id)
3532           or else Has_Unknown_Discriminants (Etype (Rec_Id))
3533         then
3534            return False;
3535         end if;
3536
3537         --  Otherwise we need to generate an initialization procedure if
3538         --  Is_CPP_Class is False and at least one of the following applies:
3539
3540         --  1. Discriminants are present, since they need to be initialized
3541         --     with the appropriate discriminant constraint expressions.
3542         --     However, the discriminant of an unchecked union does not
3543         --     count, since the discriminant is not present.
3544
3545         --  2. The type is a tagged type, since the implicit Tag component
3546         --     needs to be initialized with a pointer to the dispatch table.
3547
3548         --  3. The type contains tasks
3549
3550         --  4. One or more components has an initial value
3551
3552         --  5. One or more components is for a type which itself requires
3553         --     an initialization procedure.
3554
3555         --  6. One or more components is a type that requires simple
3556         --     initialization (see Needs_Simple_Initialization), except
3557         --     that types Tag and Interface_Tag are excluded, since fields
3558         --     of these types are initialized by other means.
3559
3560         --  7. The type is the record type built for a task type (since at
3561         --     the very least, Create_Task must be called)
3562
3563         --  8. The type is the record type built for a protected type (since
3564         --     at least Initialize_Protection must be called)
3565
3566         --  9. The type is marked as a public entity. The reason we add this
3567         --     case (even if none of the above apply) is to properly handle
3568         --     Initialize_Scalars. If a package is compiled without an IS
3569         --     pragma, and the client is compiled with an IS pragma, then
3570         --     the client will think an initialization procedure is present
3571         --     and call it, when in fact no such procedure is required, but
3572         --     since the call is generated, there had better be a routine
3573         --     at the other end of the call, even if it does nothing).
3574
3575         --  Note: the reason we exclude the CPP_Class case is because in this
3576         --  case the initialization is performed by the C++ constructors, and
3577         --  the IP is built by Set_CPP_Constructors.
3578
3579         if Is_CPP_Class (Rec_Id) then
3580            return False;
3581
3582         elsif Is_Interface (Rec_Id) then
3583            return False;
3584
3585         elsif (Has_Discriminants (Rec_Id)
3586                 and then not Is_Unchecked_Union (Rec_Id))
3587           or else Is_Tagged_Type (Rec_Id)
3588           or else Is_Concurrent_Record_Type (Rec_Id)
3589           or else Has_Task (Rec_Id)
3590         then
3591            return True;
3592         end if;
3593
3594         Id := First_Component (Rec_Id);
3595         while Present (Id) loop
3596            Comp_Decl := Parent (Id);
3597            Typ := Etype (Id);
3598
3599            if Present (Expression (Comp_Decl))
3600              or else Has_Non_Null_Base_Init_Proc (Typ)
3601              or else Component_Needs_Simple_Initialization (Typ)
3602            then
3603               return True;
3604            end if;
3605
3606            Next_Component (Id);
3607         end loop;
3608
3609         --  As explained above, a record initialization procedure is needed
3610         --  for public types in case Initialize_Scalars applies to a client.
3611         --  However, such a procedure is not needed in the case where either
3612         --  of restrictions No_Initialize_Scalars or No_Default_Initialization
3613         --  applies. No_Initialize_Scalars excludes the possibility of using
3614         --  Initialize_Scalars in any partition, and No_Default_Initialization
3615         --  implies that no initialization should ever be done for objects of
3616         --  the type, so is incompatible with Initialize_Scalars.
3617
3618         if not Restriction_Active (No_Initialize_Scalars)
3619           and then not Restriction_Active (No_Default_Initialization)
3620           and then Is_Public (Rec_Id)
3621         then
3622            return True;
3623         end if;
3624
3625         return False;
3626      end Requires_Init_Proc;
3627
3628   --  Start of processing for Build_Record_Init_Proc
3629
3630   begin
3631      Rec_Type := Defining_Identifier (N);
3632
3633      --  This may be full declaration of a private type, in which case
3634      --  the visible entity is a record, and the private entity has been
3635      --  exchanged with it in the private part of the current package.
3636      --  The initialization procedure is built for the record type, which
3637      --  is retrievable from the private entity.
3638
3639      if Is_Incomplete_Or_Private_Type (Rec_Type) then
3640         Rec_Type := Underlying_Type (Rec_Type);
3641      end if;
3642
3643      --  If we have a variant record with restriction No_Implicit_Conditionals
3644      --  in effect, then we skip building the procedure. This is safe because
3645      --  if we can see the restriction, so can any caller, calls to initialize
3646      --  such records are not allowed for variant records if this restriction
3647      --  is active.
3648
3649      if Has_Variant_Part (Rec_Type)
3650        and then Restriction_Active (No_Implicit_Conditionals)
3651      then
3652         return;
3653      end if;
3654
3655      --  If there are discriminants, build the discriminant map to replace
3656      --  discriminants by their discriminals in complex bound expressions.
3657      --  These only arise for the corresponding records of synchronized types.
3658
3659      if Is_Concurrent_Record_Type (Rec_Type)
3660        and then Has_Discriminants (Rec_Type)
3661      then
3662         declare
3663            Disc : Entity_Id;
3664         begin
3665            Disc := First_Discriminant (Rec_Type);
3666            while Present (Disc) loop
3667               Append_Elmt (Disc, Discr_Map);
3668               Append_Elmt (Discriminal (Disc), Discr_Map);
3669               Next_Discriminant (Disc);
3670            end loop;
3671         end;
3672      end if;
3673
3674      --  Derived types that have no type extension can use the initialization
3675      --  procedure of their parent and do not need a procedure of their own.
3676      --  This is only correct if there are no representation clauses for the
3677      --  type or its parent, and if the parent has in fact been frozen so
3678      --  that its initialization procedure exists.
3679
3680      if Is_Derived_Type (Rec_Type)
3681        and then not Is_Tagged_Type (Rec_Type)
3682        and then not Is_Unchecked_Union (Rec_Type)
3683        and then not Has_New_Non_Standard_Rep (Rec_Type)
3684        and then not Parent_Subtype_Renaming_Discrims
3685        and then Has_Non_Null_Base_Init_Proc (Etype (Rec_Type))
3686      then
3687         Copy_TSS (Base_Init_Proc (Etype (Rec_Type)), Rec_Type);
3688
3689      --  Otherwise if we need an initialization procedure, then build one,
3690      --  mark it as public and inlinable and as having a completion.
3691
3692      elsif Requires_Init_Proc (Rec_Type)
3693        or else Is_Unchecked_Union (Rec_Type)
3694      then
3695         Proc_Id :=
3696           Make_Defining_Identifier (Loc,
3697             Chars => Make_Init_Proc_Name (Rec_Type));
3698
3699         --  If No_Default_Initialization restriction is active, then we don't
3700         --  want to build an init_proc, but we need to mark that an init_proc
3701         --  would be needed if this restriction was not active (so that we can
3702         --  detect attempts to call it), so set a dummy init_proc in place.
3703
3704         if Restriction_Active (No_Default_Initialization) then
3705            Set_Init_Proc (Rec_Type, Proc_Id);
3706            return;
3707         end if;
3708
3709         Build_Offset_To_Top_Functions;
3710         Build_CPP_Init_Procedure;
3711         Build_Init_Procedure;
3712
3713         Set_Is_Public      (Proc_Id, Is_Public (Rec_Ent));
3714         Set_Is_Internal    (Proc_Id);
3715         Set_Has_Completion (Proc_Id);
3716
3717         if not Debug_Generated_Code then
3718            Set_Debug_Info_Off (Proc_Id);
3719         end if;
3720
3721         Set_Is_Inlined (Proc_Id, Inline_Init_Proc (Rec_Type));
3722
3723         --  Do not build an aggregate if Modify_Tree_For_C, this isn't
3724         --  needed and may generate early references to non frozen types
3725         --  since we expand aggregate much more systematically.
3726
3727         if Modify_Tree_For_C then
3728            return;
3729         end if;
3730
3731         declare
3732            Agg : constant Node_Id :=
3733                    Build_Equivalent_Record_Aggregate (Rec_Type);
3734
3735            procedure Collect_Itypes (Comp : Node_Id);
3736            --  Generate references to itypes in the aggregate, because
3737            --  the first use of the aggregate may be in a nested scope.
3738
3739            --------------------
3740            -- Collect_Itypes --
3741            --------------------
3742
3743            procedure Collect_Itypes (Comp : Node_Id) is
3744               Ref      : Node_Id;
3745               Sub_Aggr : Node_Id;
3746               Typ      : constant Entity_Id := Etype (Comp);
3747
3748            begin
3749               if Is_Array_Type (Typ) and then Is_Itype (Typ) then
3750                  Ref := Make_Itype_Reference (Loc);
3751                  Set_Itype (Ref, Typ);
3752                  Append_Freeze_Action (Rec_Type, Ref);
3753
3754                  Ref := Make_Itype_Reference (Loc);
3755                  Set_Itype (Ref, Etype (First_Index (Typ)));
3756                  Append_Freeze_Action (Rec_Type, Ref);
3757
3758                  --  Recurse on nested arrays
3759
3760                  Sub_Aggr := First (Expressions (Comp));
3761                  while Present (Sub_Aggr) loop
3762                     Collect_Itypes (Sub_Aggr);
3763                     Next (Sub_Aggr);
3764                  end loop;
3765               end if;
3766            end Collect_Itypes;
3767
3768         begin
3769            --  If there is a static initialization aggregate for the type,
3770            --  generate itype references for the types of its (sub)components,
3771            --  to prevent out-of-scope errors in the resulting tree.
3772            --  The aggregate may have been rewritten as a Raise node, in which
3773            --  case there are no relevant itypes.
3774
3775            if Present (Agg) and then Nkind (Agg) = N_Aggregate then
3776               Set_Static_Initialization (Proc_Id, Agg);
3777
3778               declare
3779                  Comp  : Node_Id;
3780               begin
3781                  Comp := First (Component_Associations (Agg));
3782                  while Present (Comp) loop
3783                     Collect_Itypes (Expression (Comp));
3784                     Next (Comp);
3785                  end loop;
3786               end;
3787            end if;
3788         end;
3789      end if;
3790   end Build_Record_Init_Proc;
3791
3792   ----------------------------
3793   -- Build_Slice_Assignment --
3794   ----------------------------
3795
3796   --  Generates the following subprogram:
3797
3798   --    procedure Assign
3799   --     (Source,  Target    : Array_Type,
3800   --      Left_Lo, Left_Hi   : Index;
3801   --      Right_Lo, Right_Hi : Index;
3802   --      Rev                : Boolean)
3803   --    is
3804   --       Li1 : Index;
3805   --       Ri1 : Index;
3806
3807   --    begin
3808
3809   --       if Left_Hi < Left_Lo then
3810   --          return;
3811   --       end if;
3812
3813   --       if Rev then
3814   --          Li1 := Left_Hi;
3815   --          Ri1 := Right_Hi;
3816   --       else
3817   --          Li1 := Left_Lo;
3818   --          Ri1 := Right_Lo;
3819   --       end if;
3820
3821   --       loop
3822   --          Target (Li1) := Source (Ri1);
3823
3824   --          if Rev then
3825   --             exit when Li1 = Left_Lo;
3826   --             Li1 := Index'pred (Li1);
3827   --             Ri1 := Index'pred (Ri1);
3828   --          else
3829   --             exit when Li1 = Left_Hi;
3830   --             Li1 := Index'succ (Li1);
3831   --             Ri1 := Index'succ (Ri1);
3832   --          end if;
3833   --       end loop;
3834   --    end Assign;
3835
3836   procedure Build_Slice_Assignment (Typ : Entity_Id) is
3837      Loc   : constant Source_Ptr := Sloc (Typ);
3838      Index : constant Entity_Id  := Base_Type (Etype (First_Index (Typ)));
3839
3840      Larray    : constant Entity_Id := Make_Temporary (Loc, 'A');
3841      Rarray    : constant Entity_Id := Make_Temporary (Loc, 'R');
3842      Left_Lo   : constant Entity_Id := Make_Temporary (Loc, 'L');
3843      Left_Hi   : constant Entity_Id := Make_Temporary (Loc, 'L');
3844      Right_Lo  : constant Entity_Id := Make_Temporary (Loc, 'R');
3845      Right_Hi  : constant Entity_Id := Make_Temporary (Loc, 'R');
3846      Rev       : constant Entity_Id := Make_Temporary (Loc, 'D');
3847      --  Formal parameters of procedure
3848
3849      Proc_Name : constant Entity_Id :=
3850                    Make_Defining_Identifier (Loc,
3851                      Chars => Make_TSS_Name (Typ, TSS_Slice_Assign));
3852
3853      Lnn : constant Entity_Id := Make_Temporary (Loc, 'L');
3854      Rnn : constant Entity_Id := Make_Temporary (Loc, 'R');
3855      --  Subscripts for left and right sides
3856
3857      Decls : List_Id;
3858      Loops : Node_Id;
3859      Stats : List_Id;
3860
3861   begin
3862      --  Build declarations for indexes
3863
3864      Decls := New_List;
3865
3866      Append_To (Decls,
3867         Make_Object_Declaration (Loc,
3868           Defining_Identifier => Lnn,
3869           Object_Definition  =>
3870             New_Occurrence_Of (Index, Loc)));
3871
3872      Append_To (Decls,
3873        Make_Object_Declaration (Loc,
3874          Defining_Identifier => Rnn,
3875          Object_Definition  =>
3876            New_Occurrence_Of (Index, Loc)));
3877
3878      Stats := New_List;
3879
3880      --  Build test for empty slice case
3881
3882      Append_To (Stats,
3883        Make_If_Statement (Loc,
3884          Condition =>
3885             Make_Op_Lt (Loc,
3886               Left_Opnd  => New_Occurrence_Of (Left_Hi, Loc),
3887               Right_Opnd => New_Occurrence_Of (Left_Lo, Loc)),
3888          Then_Statements => New_List (Make_Simple_Return_Statement (Loc))));
3889
3890      --  Build initializations for indexes
3891
3892      declare
3893         F_Init : constant List_Id := New_List;
3894         B_Init : constant List_Id := New_List;
3895
3896      begin
3897         Append_To (F_Init,
3898           Make_Assignment_Statement (Loc,
3899             Name => New_Occurrence_Of (Lnn, Loc),
3900             Expression => New_Occurrence_Of (Left_Lo, Loc)));
3901
3902         Append_To (F_Init,
3903           Make_Assignment_Statement (Loc,
3904             Name => New_Occurrence_Of (Rnn, Loc),
3905             Expression => New_Occurrence_Of (Right_Lo, Loc)));
3906
3907         Append_To (B_Init,
3908           Make_Assignment_Statement (Loc,
3909             Name => New_Occurrence_Of (Lnn, Loc),
3910             Expression => New_Occurrence_Of (Left_Hi, Loc)));
3911
3912         Append_To (B_Init,
3913           Make_Assignment_Statement (Loc,
3914             Name => New_Occurrence_Of (Rnn, Loc),
3915             Expression => New_Occurrence_Of (Right_Hi, Loc)));
3916
3917         Append_To (Stats,
3918           Make_If_Statement (Loc,
3919             Condition => New_Occurrence_Of (Rev, Loc),
3920             Then_Statements => B_Init,
3921             Else_Statements => F_Init));
3922      end;
3923
3924      --  Now construct the assignment statement
3925
3926      Loops :=
3927        Make_Loop_Statement (Loc,
3928          Statements => New_List (
3929            Make_Assignment_Statement (Loc,
3930              Name =>
3931                Make_Indexed_Component (Loc,
3932                  Prefix => New_Occurrence_Of (Larray, Loc),
3933                  Expressions => New_List (New_Occurrence_Of (Lnn, Loc))),
3934              Expression =>
3935                Make_Indexed_Component (Loc,
3936                  Prefix => New_Occurrence_Of (Rarray, Loc),
3937                  Expressions => New_List (New_Occurrence_Of (Rnn, Loc))))),
3938          End_Label  => Empty);
3939
3940      --  Build the exit condition and increment/decrement statements
3941
3942      declare
3943         F_Ass : constant List_Id := New_List;
3944         B_Ass : constant List_Id := New_List;
3945
3946      begin
3947         Append_To (F_Ass,
3948           Make_Exit_Statement (Loc,
3949             Condition =>
3950               Make_Op_Eq (Loc,
3951                 Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
3952                 Right_Opnd => New_Occurrence_Of (Left_Hi, Loc))));
3953
3954         Append_To (F_Ass,
3955           Make_Assignment_Statement (Loc,
3956             Name => New_Occurrence_Of (Lnn, Loc),
3957             Expression =>
3958               Make_Attribute_Reference (Loc,
3959                 Prefix =>
3960                   New_Occurrence_Of (Index, Loc),
3961                 Attribute_Name => Name_Succ,
3962                 Expressions => New_List (
3963                   New_Occurrence_Of (Lnn, Loc)))));
3964
3965         Append_To (F_Ass,
3966           Make_Assignment_Statement (Loc,
3967             Name => New_Occurrence_Of (Rnn, Loc),
3968             Expression =>
3969               Make_Attribute_Reference (Loc,
3970                 Prefix =>
3971                   New_Occurrence_Of (Index, Loc),
3972                 Attribute_Name => Name_Succ,
3973                 Expressions => New_List (
3974                   New_Occurrence_Of (Rnn, Loc)))));
3975
3976         Append_To (B_Ass,
3977           Make_Exit_Statement (Loc,
3978             Condition =>
3979               Make_Op_Eq (Loc,
3980                 Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
3981                 Right_Opnd => New_Occurrence_Of (Left_Lo, Loc))));
3982
3983         Append_To (B_Ass,
3984           Make_Assignment_Statement (Loc,
3985             Name => New_Occurrence_Of (Lnn, Loc),
3986             Expression =>
3987               Make_Attribute_Reference (Loc,
3988                 Prefix =>
3989                   New_Occurrence_Of (Index, Loc),
3990                 Attribute_Name => Name_Pred,
3991                   Expressions => New_List (
3992                     New_Occurrence_Of (Lnn, Loc)))));
3993
3994         Append_To (B_Ass,
3995           Make_Assignment_Statement (Loc,
3996             Name => New_Occurrence_Of (Rnn, Loc),
3997             Expression =>
3998               Make_Attribute_Reference (Loc,
3999                 Prefix =>
4000                   New_Occurrence_Of (Index, Loc),
4001                 Attribute_Name => Name_Pred,
4002                 Expressions => New_List (
4003                   New_Occurrence_Of (Rnn, Loc)))));
4004
4005         Append_To (Statements (Loops),
4006           Make_If_Statement (Loc,
4007             Condition => New_Occurrence_Of (Rev, Loc),
4008             Then_Statements => B_Ass,
4009             Else_Statements => F_Ass));
4010      end;
4011
4012      Append_To (Stats, Loops);
4013
4014      declare
4015         Spec    : Node_Id;
4016         Formals : List_Id := New_List;
4017
4018      begin
4019         Formals := New_List (
4020           Make_Parameter_Specification (Loc,
4021             Defining_Identifier => Larray,
4022             Out_Present => True,
4023             Parameter_Type =>
4024               New_Occurrence_Of (Base_Type (Typ), Loc)),
4025
4026           Make_Parameter_Specification (Loc,
4027             Defining_Identifier => Rarray,
4028             Parameter_Type =>
4029               New_Occurrence_Of (Base_Type (Typ), Loc)),
4030
4031           Make_Parameter_Specification (Loc,
4032             Defining_Identifier => Left_Lo,
4033             Parameter_Type =>
4034               New_Occurrence_Of (Index, Loc)),
4035
4036           Make_Parameter_Specification (Loc,
4037             Defining_Identifier => Left_Hi,
4038             Parameter_Type =>
4039               New_Occurrence_Of (Index, Loc)),
4040
4041           Make_Parameter_Specification (Loc,
4042             Defining_Identifier => Right_Lo,
4043             Parameter_Type =>
4044               New_Occurrence_Of (Index, Loc)),
4045
4046           Make_Parameter_Specification (Loc,
4047             Defining_Identifier => Right_Hi,
4048             Parameter_Type =>
4049               New_Occurrence_Of (Index, Loc)));
4050
4051         Append_To (Formals,
4052           Make_Parameter_Specification (Loc,
4053             Defining_Identifier => Rev,
4054             Parameter_Type =>
4055               New_Occurrence_Of (Standard_Boolean, Loc)));
4056
4057         Spec :=
4058           Make_Procedure_Specification (Loc,
4059             Defining_Unit_Name       => Proc_Name,
4060             Parameter_Specifications => Formals);
4061
4062         Discard_Node (
4063           Make_Subprogram_Body (Loc,
4064             Specification              => Spec,
4065             Declarations               => Decls,
4066             Handled_Statement_Sequence =>
4067               Make_Handled_Sequence_Of_Statements (Loc,
4068                 Statements => Stats)));
4069      end;
4070
4071      Set_TSS (Typ, Proc_Name);
4072      Set_Is_Pure (Proc_Name);
4073   end Build_Slice_Assignment;
4074
4075   -----------------------------
4076   -- Build_Untagged_Equality --
4077   -----------------------------
4078
4079   procedure Build_Untagged_Equality (Typ : Entity_Id) is
4080      Build_Eq : Boolean;
4081      Comp     : Entity_Id;
4082      Decl     : Node_Id;
4083      Op       : Entity_Id;
4084      Prim     : Elmt_Id;
4085      Eq_Op    : Entity_Id;
4086
4087      function User_Defined_Eq (T : Entity_Id) return Entity_Id;
4088      --  Check whether the type T has a user-defined primitive equality. If so
4089      --  return it, else return Empty. If true for a component of Typ, we have
4090      --  to build the primitive equality for it.
4091
4092      ---------------------
4093      -- User_Defined_Eq --
4094      ---------------------
4095
4096      function User_Defined_Eq (T : Entity_Id) return Entity_Id is
4097         Prim : Elmt_Id;
4098         Op   : Entity_Id;
4099
4100      begin
4101         Op := TSS (T, TSS_Composite_Equality);
4102
4103         if Present (Op) then
4104            return Op;
4105         end if;
4106
4107         Prim := First_Elmt (Collect_Primitive_Operations (T));
4108         while Present (Prim) loop
4109            Op := Node (Prim);
4110
4111            if Chars (Op) = Name_Op_Eq
4112              and then Etype (Op) = Standard_Boolean
4113              and then Etype (First_Formal (Op)) = T
4114              and then Etype (Next_Formal (First_Formal (Op))) = T
4115            then
4116               return Op;
4117            end if;
4118
4119            Next_Elmt (Prim);
4120         end loop;
4121
4122         return Empty;
4123      end User_Defined_Eq;
4124
4125   --  Start of processing for Build_Untagged_Equality
4126
4127   begin
4128      --  If a record component has a primitive equality operation, we must
4129      --  build the corresponding one for the current type.
4130
4131      Build_Eq := False;
4132      Comp := First_Component (Typ);
4133      while Present (Comp) loop
4134         if Is_Record_Type (Etype (Comp))
4135           and then Present (User_Defined_Eq (Etype (Comp)))
4136         then
4137            Build_Eq := True;
4138         end if;
4139
4140         Next_Component (Comp);
4141      end loop;
4142
4143      --  If there is a user-defined equality for the type, we do not create
4144      --  the implicit one.
4145
4146      Prim := First_Elmt (Collect_Primitive_Operations (Typ));
4147      Eq_Op := Empty;
4148      while Present (Prim) loop
4149         if Chars (Node (Prim)) = Name_Op_Eq
4150           and then Comes_From_Source (Node (Prim))
4151
4152         --  Don't we also need to check formal types and return type as in
4153         --  User_Defined_Eq above???
4154
4155         then
4156            Eq_Op := Node (Prim);
4157            Build_Eq := False;
4158            exit;
4159         end if;
4160
4161         Next_Elmt (Prim);
4162      end loop;
4163
4164      --  If the type is derived, inherit the operation, if present, from the
4165      --  parent type. It may have been declared after the type derivation. If
4166      --  the parent type itself is derived, it may have inherited an operation
4167      --  that has itself been overridden, so update its alias and related
4168      --  flags. Ditto for inequality.
4169
4170      if No (Eq_Op) and then Is_Derived_Type (Typ) then
4171         Prim := First_Elmt (Collect_Primitive_Operations (Etype (Typ)));
4172         while Present (Prim) loop
4173            if Chars (Node (Prim)) = Name_Op_Eq then
4174               Copy_TSS (Node (Prim), Typ);
4175               Build_Eq := False;
4176
4177               declare
4178                  Op    : constant Entity_Id := User_Defined_Eq (Typ);
4179                  Eq_Op : constant Entity_Id := Node (Prim);
4180                  NE_Op : constant Entity_Id := Next_Entity (Eq_Op);
4181
4182               begin
4183                  if Present (Op) then
4184                     Set_Alias (Op, Eq_Op);
4185                     Set_Is_Abstract_Subprogram
4186                       (Op, Is_Abstract_Subprogram (Eq_Op));
4187
4188                     if Chars (Next_Entity (Op)) = Name_Op_Ne then
4189                        Set_Is_Abstract_Subprogram
4190                          (Next_Entity (Op), Is_Abstract_Subprogram (NE_Op));
4191                     end if;
4192                  end if;
4193               end;
4194
4195               exit;
4196            end if;
4197
4198            Next_Elmt (Prim);
4199         end loop;
4200      end if;
4201
4202      --  If not inherited and not user-defined, build body as for a type with
4203      --  tagged components.
4204
4205      if Build_Eq then
4206         Decl :=
4207           Make_Eq_Body (Typ, Make_TSS_Name (Typ, TSS_Composite_Equality));
4208         Op := Defining_Entity (Decl);
4209         Set_TSS (Typ, Op);
4210         Set_Is_Pure (Op);
4211
4212         if Is_Library_Level_Entity (Typ) then
4213            Set_Is_Public (Op);
4214         end if;
4215      end if;
4216   end Build_Untagged_Equality;
4217
4218   -----------------------------------
4219   -- Build_Variant_Record_Equality --
4220   -----------------------------------
4221
4222   --  Generates:
4223
4224   --    function _Equality (X, Y : T) return Boolean is
4225   --    begin
4226   --       --  Compare discriminants
4227
4228   --       if X.D1 /= Y.D1 or else X.D2 /= Y.D2 or else ... then
4229   --          return False;
4230   --       end if;
4231
4232   --       --  Compare components
4233
4234   --       if X.C1 /= Y.C1 or else X.C2 /= Y.C2 or else ... then
4235   --          return False;
4236   --       end if;
4237
4238   --       --  Compare variant part
4239
4240   --       case X.D1 is
4241   --          when V1 =>
4242   --             if X.C2 /= Y.C2 or else X.C3 /= Y.C3 or else ... then
4243   --                return False;
4244   --             end if;
4245   --          ...
4246   --          when Vn =>
4247   --             if X.Cn /= Y.Cn or else ... then
4248   --                return False;
4249   --             end if;
4250   --       end case;
4251
4252   --       return True;
4253   --    end _Equality;
4254
4255   procedure Build_Variant_Record_Equality (Typ : Entity_Id) is
4256      Loc : constant Source_Ptr := Sloc (Typ);
4257
4258      F : constant Entity_Id :=
4259            Make_Defining_Identifier (Loc,
4260              Chars => Make_TSS_Name (Typ, TSS_Composite_Equality));
4261
4262      X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_X);
4263      Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_Y);
4264
4265      Def    : constant Node_Id := Parent (Typ);
4266      Comps  : constant Node_Id := Component_List (Type_Definition (Def));
4267      Stmts  : constant List_Id := New_List;
4268      Pspecs : constant List_Id := New_List;
4269
4270   begin
4271      --  If we have a variant record with restriction No_Implicit_Conditionals
4272      --  in effect, then we skip building the procedure. This is safe because
4273      --  if we can see the restriction, so can any caller, calls to equality
4274      --  test routines are not allowed for variant records if this restriction
4275      --  is active.
4276
4277      if Restriction_Active (No_Implicit_Conditionals) then
4278         return;
4279      end if;
4280
4281      --  Derived Unchecked_Union types no longer inherit the equality function
4282      --  of their parent.
4283
4284      if Is_Derived_Type (Typ)
4285        and then not Is_Unchecked_Union (Typ)
4286        and then not Has_New_Non_Standard_Rep (Typ)
4287      then
4288         declare
4289            Parent_Eq : constant Entity_Id :=
4290                          TSS (Root_Type (Typ), TSS_Composite_Equality);
4291         begin
4292            if Present (Parent_Eq) then
4293               Copy_TSS (Parent_Eq, Typ);
4294               return;
4295            end if;
4296         end;
4297      end if;
4298
4299      Discard_Node (
4300        Make_Subprogram_Body (Loc,
4301          Specification =>
4302            Make_Function_Specification (Loc,
4303              Defining_Unit_Name       => F,
4304              Parameter_Specifications => Pspecs,
4305              Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),
4306          Declarations               => New_List,
4307          Handled_Statement_Sequence =>
4308            Make_Handled_Sequence_Of_Statements (Loc, Statements => Stmts)));
4309
4310      Append_To (Pspecs,
4311        Make_Parameter_Specification (Loc,
4312          Defining_Identifier => X,
4313          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));
4314
4315      Append_To (Pspecs,
4316        Make_Parameter_Specification (Loc,
4317          Defining_Identifier => Y,
4318          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));
4319
4320      --  Unchecked_Unions require additional machinery to support equality.
4321      --  Two extra parameters (A and B) are added to the equality function
4322      --  parameter list for each discriminant of the type, in order to
4323      --  capture the inferred values of the discriminants in equality calls.
4324      --  The names of the parameters match the names of the corresponding
4325      --  discriminant, with an added suffix.
4326
4327      if Is_Unchecked_Union (Typ) then
4328         declare
4329            Discr      : Entity_Id;
4330            Discr_Type : Entity_Id;
4331            A, B       : Entity_Id;
4332            New_Discrs : Elist_Id;
4333
4334         begin
4335            New_Discrs := New_Elmt_List;
4336
4337            Discr := First_Discriminant (Typ);
4338            while Present (Discr) loop
4339               Discr_Type := Etype (Discr);
4340               A := Make_Defining_Identifier (Loc,
4341                      Chars => New_External_Name (Chars (Discr), 'A'));
4342
4343               B := Make_Defining_Identifier (Loc,
4344                      Chars => New_External_Name (Chars (Discr), 'B'));
4345
4346               --  Add new parameters to the parameter list
4347
4348               Append_To (Pspecs,
4349                 Make_Parameter_Specification (Loc,
4350                   Defining_Identifier => A,
4351                   Parameter_Type      =>
4352                     New_Occurrence_Of (Discr_Type, Loc)));
4353
4354               Append_To (Pspecs,
4355                 Make_Parameter_Specification (Loc,
4356                   Defining_Identifier => B,
4357                   Parameter_Type      =>
4358                     New_Occurrence_Of (Discr_Type, Loc)));
4359
4360               Append_Elmt (A, New_Discrs);
4361
4362               --  Generate the following code to compare each of the inferred
4363               --  discriminants:
4364
4365               --  if a /= b then
4366               --     return False;
4367               --  end if;
4368
4369               Append_To (Stmts,
4370                 Make_If_Statement (Loc,
4371                   Condition       =>
4372                     Make_Op_Ne (Loc,
4373                       Left_Opnd  => New_Occurrence_Of (A, Loc),
4374                       Right_Opnd => New_Occurrence_Of (B, Loc)),
4375                   Then_Statements => New_List (
4376                     Make_Simple_Return_Statement (Loc,
4377                       Expression =>
4378                         New_Occurrence_Of (Standard_False, Loc)))));
4379               Next_Discriminant (Discr);
4380            end loop;
4381
4382            --  Generate component-by-component comparison. Note that we must
4383            --  propagate the inferred discriminants formals to act as
4384            --  the case statement switch. Their value is added when an
4385            --  equality call on unchecked unions is expanded.
4386
4387            Append_List_To (Stmts, Make_Eq_Case (Typ, Comps, New_Discrs));
4388         end;
4389
4390      --  Normal case (not unchecked union)
4391
4392      else
4393         Append_To (Stmts,
4394           Make_Eq_If (Typ, Discriminant_Specifications (Def)));
4395         Append_List_To (Stmts, Make_Eq_Case (Typ, Comps));
4396      end if;
4397
4398      Append_To (Stmts,
4399        Make_Simple_Return_Statement (Loc,
4400          Expression => New_Occurrence_Of (Standard_True, Loc)));
4401
4402      Set_TSS (Typ, F);
4403      Set_Is_Pure (F);
4404
4405      if not Debug_Generated_Code then
4406         Set_Debug_Info_Off (F);
4407      end if;
4408   end Build_Variant_Record_Equality;
4409
4410   -----------------------------
4411   -- Check_Stream_Attributes --
4412   -----------------------------
4413
4414   procedure Check_Stream_Attributes (Typ : Entity_Id) is
4415      Comp      : Entity_Id;
4416      Par_Read  : constant Boolean :=
4417                    Stream_Attribute_Available (Typ, TSS_Stream_Read)
4418                      and then not Has_Specified_Stream_Read (Typ);
4419      Par_Write : constant Boolean :=
4420                    Stream_Attribute_Available (Typ, TSS_Stream_Write)
4421                      and then not Has_Specified_Stream_Write (Typ);
4422
4423      procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type);
4424      --  Check that Comp has a user-specified Nam stream attribute
4425
4426      ----------------
4427      -- Check_Attr --
4428      ----------------
4429
4430      procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type) is
4431      begin
4432         if not Stream_Attribute_Available (Etype (Comp), TSS_Nam) then
4433            Error_Msg_Name_1 := Nam;
4434            Error_Msg_N
4435              ("|component& in limited extension must have% attribute", Comp);
4436         end if;
4437      end Check_Attr;
4438
4439   --  Start of processing for Check_Stream_Attributes
4440
4441   begin
4442      if Par_Read or else Par_Write then
4443         Comp := First_Component (Typ);
4444         while Present (Comp) loop
4445            if Comes_From_Source (Comp)
4446              and then Original_Record_Component (Comp) = Comp
4447              and then Is_Limited_Type (Etype (Comp))
4448            then
4449               if Par_Read then
4450                  Check_Attr (Name_Read, TSS_Stream_Read);
4451               end if;
4452
4453               if Par_Write then
4454                  Check_Attr (Name_Write, TSS_Stream_Write);
4455               end if;
4456            end if;
4457
4458            Next_Component (Comp);
4459         end loop;
4460      end if;
4461   end Check_Stream_Attributes;
4462
4463   ----------------------
4464   -- Clean_Task_Names --
4465   ----------------------
4466
4467   procedure Clean_Task_Names
4468     (Typ     : Entity_Id;
4469      Proc_Id : Entity_Id)
4470   is
4471   begin
4472      if Has_Task (Typ)
4473        and then not Restriction_Active (No_Implicit_Heap_Allocations)
4474        and then not Global_Discard_Names
4475        and then Tagged_Type_Expansion
4476      then
4477         Set_Uses_Sec_Stack (Proc_Id);
4478      end if;
4479   end Clean_Task_Names;
4480
4481   ------------------------------
4482   -- Expand_Freeze_Array_Type --
4483   ------------------------------
4484
4485   procedure Expand_Freeze_Array_Type (N : Node_Id) is
4486      Typ      : constant Entity_Id := Entity (N);
4487      Base     : constant Entity_Id := Base_Type (Typ);
4488      Comp_Typ : constant Entity_Id := Component_Type (Typ);
4489
4490   begin
4491      if not Is_Bit_Packed_Array (Typ) then
4492
4493         --  If the component contains tasks, so does the array type. This may
4494         --  not be indicated in the array type because the component may have
4495         --  been a private type at the point of definition. Same if component
4496         --  type is controlled or contains protected objects.
4497
4498         Propagate_Concurrent_Flags (Base, Comp_Typ);
4499         Set_Has_Controlled_Component
4500           (Base, Has_Controlled_Component (Comp_Typ)
4501                    or else Is_Controlled (Comp_Typ));
4502
4503         if No (Init_Proc (Base)) then
4504
4505            --  If this is an anonymous array created for a declaration with
4506            --  an initial value, its init_proc will never be called. The
4507            --  initial value itself may have been expanded into assignments,
4508            --  in which case the object declaration is carries the
4509            --  No_Initialization flag.
4510
4511            if Is_Itype (Base)
4512              and then Nkind (Associated_Node_For_Itype (Base)) =
4513                                                    N_Object_Declaration
4514              and then
4515                (Present (Expression (Associated_Node_For_Itype (Base)))
4516                  or else No_Initialization (Associated_Node_For_Itype (Base)))
4517            then
4518               null;
4519
4520            --  We do not need an init proc for string or wide [wide] string,
4521            --  since the only time these need initialization in normalize or
4522            --  initialize scalars mode, and these types are treated specially
4523            --  and do not need initialization procedures.
4524
4525            elsif Is_Standard_String_Type (Base) then
4526               null;
4527
4528            --  Otherwise we have to build an init proc for the subtype
4529
4530            else
4531               Build_Array_Init_Proc (Base, N);
4532            end if;
4533         end if;
4534
4535         if Typ = Base and then Has_Controlled_Component (Base) then
4536            Build_Controlling_Procs (Base);
4537
4538            if not Is_Limited_Type (Comp_Typ)
4539              and then Number_Dimensions (Typ) = 1
4540            then
4541               Build_Slice_Assignment (Typ);
4542            end if;
4543         end if;
4544
4545      --  For packed case, default initialization, except if the component type
4546      --  is itself a packed structure with an initialization procedure, or
4547      --  initialize/normalize scalars active, and we have a base type, or the
4548      --  type is public, because in that case a client might specify
4549      --  Normalize_Scalars and there better be a public Init_Proc for it.
4550
4551      elsif (Present (Init_Proc (Component_Type (Base)))
4552              and then No (Base_Init_Proc (Base)))
4553        or else (Init_Or_Norm_Scalars and then Base = Typ)
4554        or else Is_Public (Typ)
4555      then
4556         Build_Array_Init_Proc (Base, N);
4557      end if;
4558   end Expand_Freeze_Array_Type;
4559
4560   -----------------------------------
4561   -- Expand_Freeze_Class_Wide_Type --
4562   -----------------------------------
4563
4564   procedure Expand_Freeze_Class_Wide_Type (N : Node_Id) is
4565      function Is_C_Derivation (Typ : Entity_Id) return Boolean;
4566      --  Given a type, determine whether it is derived from a C or C++ root
4567
4568      ---------------------
4569      -- Is_C_Derivation --
4570      ---------------------
4571
4572      function Is_C_Derivation (Typ : Entity_Id) return Boolean is
4573         T : Entity_Id;
4574
4575      begin
4576         T := Typ;
4577         loop
4578            if Is_CPP_Class (T)
4579              or else Convention (T) = Convention_C
4580              or else Convention (T) = Convention_CPP
4581            then
4582               return True;
4583            end if;
4584
4585            exit when T = Etype (T);
4586
4587            T := Etype (T);
4588         end loop;
4589
4590         return False;
4591      end Is_C_Derivation;
4592
4593      --  Local variables
4594
4595      Typ  : constant Entity_Id := Entity (N);
4596      Root : constant Entity_Id := Root_Type (Typ);
4597
4598   --  Start of processing for Expand_Freeze_Class_Wide_Type
4599
4600   begin
4601      --  Certain run-time configurations and targets do not provide support
4602      --  for controlled types.
4603
4604      if Restriction_Active (No_Finalization) then
4605         return;
4606
4607      --  Do not create TSS routine Finalize_Address when dispatching calls are
4608      --  disabled since the core of the routine is a dispatching call.
4609
4610      elsif Restriction_Active (No_Dispatching_Calls) then
4611         return;
4612
4613      --  Do not create TSS routine Finalize_Address for concurrent class-wide
4614      --  types. Ignore C, C++, CIL and Java types since it is assumed that the
4615      --  non-Ada side will handle their destruction.
4616
4617      elsif Is_Concurrent_Type (Root)
4618        or else Is_C_Derivation (Root)
4619        or else Convention (Typ) = Convention_CPP
4620      then
4621         return;
4622
4623      --  Do not create TSS routine Finalize_Address when compiling in CodePeer
4624      --  mode since the routine contains an Unchecked_Conversion.
4625
4626      elsif CodePeer_Mode then
4627         return;
4628      end if;
4629
4630      --  Create the body of TSS primitive Finalize_Address. This automatically
4631      --  sets the TSS entry for the class-wide type.
4632
4633      Make_Finalize_Address_Body (Typ);
4634   end Expand_Freeze_Class_Wide_Type;
4635
4636   ------------------------------------
4637   -- Expand_Freeze_Enumeration_Type --
4638   ------------------------------------
4639
4640   procedure Expand_Freeze_Enumeration_Type (N : Node_Id) is
4641      Typ : constant Entity_Id  := Entity (N);
4642      Loc : constant Source_Ptr := Sloc (Typ);
4643
4644      Arr           : Entity_Id;
4645      Ent           : Entity_Id;
4646      Fent          : Entity_Id;
4647      Is_Contiguous : Boolean;
4648      Ityp          : Entity_Id;
4649      Last_Repval   : Uint;
4650      Lst           : List_Id;
4651      Num           : Nat;
4652      Pos_Expr      : Node_Id;
4653
4654      Func : Entity_Id;
4655      pragma Warnings (Off, Func);
4656
4657   begin
4658      --  Various optimizations possible if given representation is contiguous
4659
4660      Is_Contiguous := True;
4661
4662      Ent := First_Literal (Typ);
4663      Last_Repval := Enumeration_Rep (Ent);
4664
4665      Next_Literal (Ent);
4666      while Present (Ent) loop
4667         if Enumeration_Rep (Ent) - Last_Repval /= 1 then
4668            Is_Contiguous := False;
4669            exit;
4670         else
4671            Last_Repval := Enumeration_Rep (Ent);
4672         end if;
4673
4674         Next_Literal (Ent);
4675      end loop;
4676
4677      if Is_Contiguous then
4678         Set_Has_Contiguous_Rep (Typ);
4679         Ent := First_Literal (Typ);
4680         Num := 1;
4681         Lst := New_List (New_Occurrence_Of (Ent, Sloc (Ent)));
4682
4683      else
4684         --  Build list of literal references
4685
4686         Lst := New_List;
4687         Num := 0;
4688
4689         Ent := First_Literal (Typ);
4690         while Present (Ent) loop
4691            Append_To (Lst, New_Occurrence_Of (Ent, Sloc (Ent)));
4692            Num := Num + 1;
4693            Next_Literal (Ent);
4694         end loop;
4695      end if;
4696
4697      --  Now build an array declaration
4698
4699      --    typA : array (Natural range 0 .. num - 1) of ctype :=
4700      --             (v, v, v, v, v, ....)
4701
4702      --  where ctype is the corresponding integer type. If the representation
4703      --  is contiguous, we only keep the first literal, which provides the
4704      --  offset for Pos_To_Rep computations.
4705
4706      Arr :=
4707        Make_Defining_Identifier (Loc,
4708          Chars => New_External_Name (Chars (Typ), 'A'));
4709
4710      Append_Freeze_Action (Typ,
4711        Make_Object_Declaration (Loc,
4712          Defining_Identifier => Arr,
4713          Constant_Present    => True,
4714
4715          Object_Definition   =>
4716            Make_Constrained_Array_Definition (Loc,
4717              Discrete_Subtype_Definitions => New_List (
4718                Make_Subtype_Indication (Loc,
4719                  Subtype_Mark => New_Occurrence_Of (Standard_Natural, Loc),
4720                  Constraint   =>
4721                    Make_Range_Constraint (Loc,
4722                      Range_Expression =>
4723                        Make_Range (Loc,
4724                          Low_Bound  =>
4725                            Make_Integer_Literal (Loc, 0),
4726                          High_Bound =>
4727                            Make_Integer_Literal (Loc, Num - 1))))),
4728
4729              Component_Definition =>
4730                Make_Component_Definition (Loc,
4731                  Aliased_Present => False,
4732                  Subtype_Indication => New_Occurrence_Of (Typ, Loc))),
4733
4734          Expression =>
4735            Make_Aggregate (Loc,
4736              Expressions => Lst)));
4737
4738      Set_Enum_Pos_To_Rep (Typ, Arr);
4739
4740      --  Now we build the function that converts representation values to
4741      --  position values. This function has the form:
4742
4743      --    function _Rep_To_Pos (A : etype; F : Boolean) return Integer is
4744      --    begin
4745      --       case ityp!(A) is
4746      --         when enum-lit'Enum_Rep => return posval;
4747      --         when enum-lit'Enum_Rep => return posval;
4748      --         ...
4749      --         when others   =>
4750      --           [raise Constraint_Error when F "invalid data"]
4751      --           return -1;
4752      --       end case;
4753      --    end;
4754
4755      --  Note: the F parameter determines whether the others case (no valid
4756      --  representation) raises Constraint_Error or returns a unique value
4757      --  of minus one. The latter case is used, e.g. in 'Valid code.
4758
4759      --  Note: the reason we use Enum_Rep values in the case here is to avoid
4760      --  the code generator making inappropriate assumptions about the range
4761      --  of the values in the case where the value is invalid. ityp is a
4762      --  signed or unsigned integer type of appropriate width.
4763
4764      --  Note: if exceptions are not supported, then we suppress the raise
4765      --  and return -1 unconditionally (this is an erroneous program in any
4766      --  case and there is no obligation to raise Constraint_Error here). We
4767      --  also do this if pragma Restrictions (No_Exceptions) is active.
4768
4769      --  Is this right??? What about No_Exception_Propagation???
4770
4771      --  Representations are signed
4772
4773      if Enumeration_Rep (First_Literal (Typ)) < 0 then
4774
4775         --  The underlying type is signed. Reset the Is_Unsigned_Type
4776         --  explicitly, because it might have been inherited from
4777         --  parent type.
4778
4779         Set_Is_Unsigned_Type (Typ, False);
4780
4781         if Esize (Typ) <= Standard_Integer_Size then
4782            Ityp := Standard_Integer;
4783         else
4784            Ityp := Universal_Integer;
4785         end if;
4786
4787      --  Representations are unsigned
4788
4789      else
4790         if Esize (Typ) <= Standard_Integer_Size then
4791            Ityp := RTE (RE_Unsigned);
4792         else
4793            Ityp := RTE (RE_Long_Long_Unsigned);
4794         end if;
4795      end if;
4796
4797      --  The body of the function is a case statement. First collect case
4798      --  alternatives, or optimize the contiguous case.
4799
4800      Lst := New_List;
4801
4802      --  If representation is contiguous, Pos is computed by subtracting
4803      --  the representation of the first literal.
4804
4805      if Is_Contiguous then
4806         Ent := First_Literal (Typ);
4807
4808         if Enumeration_Rep (Ent) = Last_Repval then
4809
4810            --  Another special case: for a single literal, Pos is zero
4811
4812            Pos_Expr := Make_Integer_Literal (Loc, Uint_0);
4813
4814         else
4815            Pos_Expr :=
4816              Convert_To (Standard_Integer,
4817                Make_Op_Subtract (Loc,
4818                  Left_Opnd  =>
4819                    Unchecked_Convert_To
4820                     (Ityp, Make_Identifier (Loc, Name_uA)),
4821                  Right_Opnd =>
4822                    Make_Integer_Literal (Loc,
4823                      Intval => Enumeration_Rep (First_Literal (Typ)))));
4824         end if;
4825
4826         Append_To (Lst,
4827           Make_Case_Statement_Alternative (Loc,
4828             Discrete_Choices => New_List (
4829               Make_Range (Sloc (Enumeration_Rep_Expr (Ent)),
4830                 Low_Bound =>
4831                   Make_Integer_Literal (Loc,
4832                    Intval =>  Enumeration_Rep (Ent)),
4833                 High_Bound =>
4834                   Make_Integer_Literal (Loc, Intval => Last_Repval))),
4835
4836             Statements => New_List (
4837               Make_Simple_Return_Statement (Loc,
4838                 Expression => Pos_Expr))));
4839
4840      else
4841         Ent := First_Literal (Typ);
4842         while Present (Ent) loop
4843            Append_To (Lst,
4844              Make_Case_Statement_Alternative (Loc,
4845                Discrete_Choices => New_List (
4846                  Make_Integer_Literal (Sloc (Enumeration_Rep_Expr (Ent)),
4847                    Intval => Enumeration_Rep (Ent))),
4848
4849                Statements => New_List (
4850                  Make_Simple_Return_Statement (Loc,
4851                    Expression =>
4852                      Make_Integer_Literal (Loc,
4853                        Intval => Enumeration_Pos (Ent))))));
4854
4855            Next_Literal (Ent);
4856         end loop;
4857      end if;
4858
4859      --  In normal mode, add the others clause with the test.
4860      --  If Predicates_Ignored is True, validity checks do not apply to
4861      --  the subtype.
4862
4863      if not No_Exception_Handlers_Set
4864        and then not Predicates_Ignored (Typ)
4865      then
4866         Append_To (Lst,
4867           Make_Case_Statement_Alternative (Loc,
4868             Discrete_Choices => New_List (Make_Others_Choice (Loc)),
4869             Statements       => New_List (
4870               Make_Raise_Constraint_Error (Loc,
4871                 Condition => Make_Identifier (Loc, Name_uF),
4872                 Reason    => CE_Invalid_Data),
4873               Make_Simple_Return_Statement (Loc,
4874                 Expression => Make_Integer_Literal (Loc, -1)))));
4875
4876      --  If either of the restrictions No_Exceptions_Handlers/Propagation is
4877      --  active then return -1 (we cannot usefully raise Constraint_Error in
4878      --  this case). See description above for further details.
4879
4880      else
4881         Append_To (Lst,
4882           Make_Case_Statement_Alternative (Loc,
4883             Discrete_Choices => New_List (Make_Others_Choice (Loc)),
4884             Statements       => New_List (
4885               Make_Simple_Return_Statement (Loc,
4886                 Expression => Make_Integer_Literal (Loc, -1)))));
4887      end if;
4888
4889      --  Now we can build the function body
4890
4891      Fent :=
4892        Make_Defining_Identifier (Loc, Make_TSS_Name (Typ, TSS_Rep_To_Pos));
4893
4894      Func :=
4895        Make_Subprogram_Body (Loc,
4896          Specification =>
4897            Make_Function_Specification (Loc,
4898              Defining_Unit_Name       => Fent,
4899              Parameter_Specifications => New_List (
4900                Make_Parameter_Specification (Loc,
4901                  Defining_Identifier =>
4902                    Make_Defining_Identifier (Loc, Name_uA),
4903                  Parameter_Type => New_Occurrence_Of (Typ, Loc)),
4904                Make_Parameter_Specification (Loc,
4905                  Defining_Identifier =>
4906                    Make_Defining_Identifier (Loc, Name_uF),
4907                  Parameter_Type =>
4908                    New_Occurrence_Of (Standard_Boolean, Loc))),
4909
4910              Result_Definition => New_Occurrence_Of (Standard_Integer, Loc)),
4911
4912            Declarations => Empty_List,
4913
4914            Handled_Statement_Sequence =>
4915              Make_Handled_Sequence_Of_Statements (Loc,
4916                Statements => New_List (
4917                  Make_Case_Statement (Loc,
4918                    Expression =>
4919                      Unchecked_Convert_To
4920                        (Ityp, Make_Identifier (Loc, Name_uA)),
4921                    Alternatives => Lst))));
4922
4923      Set_TSS (Typ, Fent);
4924
4925      --  Set Pure flag (it will be reset if the current context is not Pure).
4926      --  We also pretend there was a pragma Pure_Function so that for purposes
4927      --  of optimization and constant-folding, we will consider the function
4928      --  Pure even if we are not in a Pure context).
4929
4930      Set_Is_Pure (Fent);
4931      Set_Has_Pragma_Pure_Function (Fent);
4932
4933      --  Unless we are in -gnatD mode, where we are debugging generated code,
4934      --  this is an internal entity for which we don't need debug info.
4935
4936      if not Debug_Generated_Code then
4937         Set_Debug_Info_Off (Fent);
4938      end if;
4939
4940      Set_Is_Inlined (Fent);
4941
4942   exception
4943      when RE_Not_Available =>
4944         return;
4945   end Expand_Freeze_Enumeration_Type;
4946
4947   -------------------------------
4948   -- Expand_Freeze_Record_Type --
4949   -------------------------------
4950
4951   procedure Expand_Freeze_Record_Type (N : Node_Id) is
4952      Typ      : constant Node_Id := Entity (N);
4953      Typ_Decl : constant Node_Id := Parent (Typ);
4954
4955      Comp        : Entity_Id;
4956      Comp_Typ    : Entity_Id;
4957      Predef_List : List_Id;
4958
4959      Wrapper_Decl_List : List_Id := No_List;
4960      Wrapper_Body_List : List_Id := No_List;
4961
4962      Renamed_Eq : Node_Id := Empty;
4963      --  Defining unit name for the predefined equality function in the case
4964      --  where the type has a primitive operation that is a renaming of
4965      --  predefined equality (but only if there is also an overriding
4966      --  user-defined equality function). Used to pass this entity from
4967      --  Make_Predefined_Primitive_Specs to Predefined_Primitive_Bodies.
4968
4969   --  Start of processing for Expand_Freeze_Record_Type
4970
4971   begin
4972      --  Build discriminant checking functions if not a derived type (for
4973      --  derived types that are not tagged types, always use the discriminant
4974      --  checking functions of the parent type). However, for untagged types
4975      --  the derivation may have taken place before the parent was frozen, so
4976      --  we copy explicitly the discriminant checking functions from the
4977      --  parent into the components of the derived type.
4978
4979      if not Is_Derived_Type (Typ)
4980        or else Has_New_Non_Standard_Rep (Typ)
4981        or else Is_Tagged_Type (Typ)
4982      then
4983         Build_Discr_Checking_Funcs (Typ_Decl);
4984
4985      elsif Is_Derived_Type (Typ)
4986        and then not Is_Tagged_Type (Typ)
4987
4988        --  If we have a derived Unchecked_Union, we do not inherit the
4989        --  discriminant checking functions from the parent type since the
4990        --  discriminants are non existent.
4991
4992        and then not Is_Unchecked_Union (Typ)
4993        and then Has_Discriminants (Typ)
4994      then
4995         declare
4996            Old_Comp : Entity_Id;
4997
4998         begin
4999            Old_Comp :=
5000              First_Component (Base_Type (Underlying_Type (Etype (Typ))));
5001            Comp := First_Component (Typ);
5002            while Present (Comp) loop
5003               if Ekind (Comp) = E_Component
5004                 and then Chars (Comp) = Chars (Old_Comp)
5005               then
5006                  Set_Discriminant_Checking_Func
5007                    (Comp, Discriminant_Checking_Func (Old_Comp));
5008               end if;
5009
5010               Next_Component (Old_Comp);
5011               Next_Component (Comp);
5012            end loop;
5013         end;
5014      end if;
5015
5016      if Is_Derived_Type (Typ)
5017        and then Is_Limited_Type (Typ)
5018        and then Is_Tagged_Type (Typ)
5019      then
5020         Check_Stream_Attributes (Typ);
5021      end if;
5022
5023      --  Update task, protected, and controlled component flags, because some
5024      --  of the component types may have been private at the point of the
5025      --  record declaration. Detect anonymous access-to-controlled components.
5026
5027      Comp := First_Component (Typ);
5028      while Present (Comp) loop
5029         Comp_Typ := Etype (Comp);
5030
5031         Propagate_Concurrent_Flags (Typ, Comp_Typ);
5032
5033         --  Do not set Has_Controlled_Component on a class-wide equivalent
5034         --  type. See Make_CW_Equivalent_Type.
5035
5036         if not Is_Class_Wide_Equivalent_Type (Typ)
5037           and then
5038             (Has_Controlled_Component (Comp_Typ)
5039               or else (Chars (Comp) /= Name_uParent
5040                         and then Is_Controlled (Comp_Typ)))
5041         then
5042            Set_Has_Controlled_Component (Typ);
5043         end if;
5044
5045         Next_Component (Comp);
5046      end loop;
5047
5048      --  Handle constructors of untagged CPP_Class types
5049
5050      if not Is_Tagged_Type (Typ) and then Is_CPP_Class (Typ) then
5051         Set_CPP_Constructors (Typ);
5052      end if;
5053
5054      --  Creation of the Dispatch Table. Note that a Dispatch Table is built
5055      --  for regular tagged types as well as for Ada types deriving from a C++
5056      --  Class, but not for tagged types directly corresponding to C++ classes
5057      --  In the later case we assume that it is created in the C++ side and we
5058      --  just use it.
5059
5060      if Is_Tagged_Type (Typ) then
5061
5062         --  Add the _Tag component
5063
5064         if Underlying_Type (Etype (Typ)) = Typ then
5065            Expand_Tagged_Root (Typ);
5066         end if;
5067
5068         if Is_CPP_Class (Typ) then
5069            Set_All_DT_Position (Typ);
5070
5071            --  Create the tag entities with a minimum decoration
5072
5073            if Tagged_Type_Expansion then
5074               Append_Freeze_Actions (Typ, Make_Tags (Typ));
5075            end if;
5076
5077            Set_CPP_Constructors (Typ);
5078
5079         else
5080            if not Building_Static_DT (Typ) then
5081
5082               --  Usually inherited primitives are not delayed but the first
5083               --  Ada extension of a CPP_Class is an exception since the
5084               --  address of the inherited subprogram has to be inserted in
5085               --  the new Ada Dispatch Table and this is a freezing action.
5086
5087               --  Similarly, if this is an inherited operation whose parent is
5088               --  not frozen yet, it is not in the DT of the parent, and we
5089               --  generate an explicit freeze node for the inherited operation
5090               --  so it is properly inserted in the DT of the current type.
5091
5092               declare
5093                  Elmt : Elmt_Id;
5094                  Subp : Entity_Id;
5095
5096               begin
5097                  Elmt := First_Elmt (Primitive_Operations (Typ));
5098                  while Present (Elmt) loop
5099                     Subp := Node (Elmt);
5100
5101                     if Present (Alias (Subp)) then
5102                        if Is_CPP_Class (Etype (Typ)) then
5103                           Set_Has_Delayed_Freeze (Subp);
5104
5105                        elsif Has_Delayed_Freeze (Alias (Subp))
5106                          and then not Is_Frozen (Alias (Subp))
5107                        then
5108                           Set_Is_Frozen (Subp, False);
5109                           Set_Has_Delayed_Freeze (Subp);
5110                        end if;
5111                     end if;
5112
5113                     Next_Elmt (Elmt);
5114                  end loop;
5115               end;
5116            end if;
5117
5118            --  Unfreeze momentarily the type to add the predefined primitives
5119            --  operations. The reason we unfreeze is so that these predefined
5120            --  operations will indeed end up as primitive operations (which
5121            --  must be before the freeze point).
5122
5123            Set_Is_Frozen (Typ, False);
5124
5125            --  Do not add the spec of predefined primitives in case of
5126            --  CPP tagged type derivations that have convention CPP.
5127
5128            if Is_CPP_Class (Root_Type (Typ))
5129              and then Convention (Typ) = Convention_CPP
5130            then
5131               null;
5132
5133            --  Do not add the spec of the predefined primitives if we are
5134            --  compiling under restriction No_Dispatching_Calls.
5135
5136            elsif not Restriction_Active (No_Dispatching_Calls) then
5137               Make_Predefined_Primitive_Specs (Typ, Predef_List, Renamed_Eq);
5138               Insert_List_Before_And_Analyze (N, Predef_List);
5139            end if;
5140
5141            --  Ada 2005 (AI-391): For a nonabstract null extension, create
5142            --  wrapper functions for each nonoverridden inherited function
5143            --  with a controlling result of the type. The wrapper for such
5144            --  a function returns an extension aggregate that invokes the
5145            --  parent function.
5146
5147            if Ada_Version >= Ada_2005
5148              and then not Is_Abstract_Type (Typ)
5149              and then Is_Null_Extension (Typ)
5150            then
5151               Make_Controlling_Function_Wrappers
5152                 (Typ, Wrapper_Decl_List, Wrapper_Body_List);
5153               Insert_List_Before_And_Analyze (N, Wrapper_Decl_List);
5154            end if;
5155
5156            --  Ada 2005 (AI-251): For a nonabstract type extension, build
5157            --  null procedure declarations for each set of homographic null
5158            --  procedures that are inherited from interface types but not
5159            --  overridden. This is done to ensure that the dispatch table
5160            --  entry associated with such null primitives are properly filled.
5161
5162            if Ada_Version >= Ada_2005
5163              and then Etype (Typ) /= Typ
5164              and then not Is_Abstract_Type (Typ)
5165              and then Has_Interfaces (Typ)
5166            then
5167               Insert_Actions (N, Make_Null_Procedure_Specs (Typ));
5168            end if;
5169
5170            Set_Is_Frozen (Typ);
5171
5172            if not Is_Derived_Type (Typ)
5173              or else Is_Tagged_Type (Etype (Typ))
5174            then
5175               Set_All_DT_Position (Typ);
5176
5177            --  If this is a type derived from an untagged private type whose
5178            --  full view is tagged, the type is marked tagged for layout
5179            --  reasons, but it has no dispatch table.
5180
5181            elsif Is_Derived_Type (Typ)
5182              and then Is_Private_Type (Etype (Typ))
5183              and then not Is_Tagged_Type (Etype (Typ))
5184            then
5185               return;
5186            end if;
5187
5188            --  Create and decorate the tags. Suppress their creation when
5189            --  not Tagged_Type_Expansion because the dispatching mechanism is
5190            --  handled internally by the virtual target.
5191
5192            if Tagged_Type_Expansion then
5193               Append_Freeze_Actions (Typ, Make_Tags (Typ));
5194
5195               --  Generate dispatch table of locally defined tagged type.
5196               --  Dispatch tables of library level tagged types are built
5197               --  later (see Analyze_Declarations).
5198
5199               if not Building_Static_DT (Typ) then
5200                  Append_Freeze_Actions (Typ, Make_DT (Typ));
5201               end if;
5202            end if;
5203
5204            --  If the type has unknown discriminants, propagate dispatching
5205            --  information to its underlying record view, which does not get
5206            --  its own dispatch table.
5207
5208            if Is_Derived_Type (Typ)
5209              and then Has_Unknown_Discriminants (Typ)
5210              and then Present (Underlying_Record_View (Typ))
5211            then
5212               declare
5213                  Rep : constant Entity_Id := Underlying_Record_View (Typ);
5214               begin
5215                  Set_Access_Disp_Table
5216                    (Rep, Access_Disp_Table           (Typ));
5217                  Set_Dispatch_Table_Wrappers
5218                    (Rep, Dispatch_Table_Wrappers     (Typ));
5219                  Set_Direct_Primitive_Operations
5220                    (Rep, Direct_Primitive_Operations (Typ));
5221               end;
5222            end if;
5223
5224            --  Make sure that the primitives Initialize, Adjust and Finalize
5225            --  are Frozen before other TSS subprograms. We don't want them
5226            --  Frozen inside.
5227
5228            if Is_Controlled (Typ) then
5229               if not Is_Limited_Type (Typ) then
5230                  Append_Freeze_Actions (Typ,
5231                    Freeze_Entity (Find_Prim_Op (Typ, Name_Adjust), Typ));
5232               end if;
5233
5234               Append_Freeze_Actions (Typ,
5235                 Freeze_Entity (Find_Prim_Op (Typ, Name_Initialize), Typ));
5236
5237               Append_Freeze_Actions (Typ,
5238                 Freeze_Entity (Find_Prim_Op (Typ, Name_Finalize), Typ));
5239            end if;
5240
5241            --  Freeze rest of primitive operations. There is no need to handle
5242            --  the predefined primitives if we are compiling under restriction
5243            --  No_Dispatching_Calls.
5244
5245            if not Restriction_Active (No_Dispatching_Calls) then
5246               Append_Freeze_Actions (Typ, Predefined_Primitive_Freeze (Typ));
5247            end if;
5248         end if;
5249
5250      --  In the untagged case, ever since Ada 83 an equality function must
5251      --  be  provided for variant records that are not unchecked unions.
5252      --  In Ada 2012 the equality function composes, and thus must be built
5253      --  explicitly just as for tagged records.
5254
5255      elsif Has_Discriminants (Typ)
5256        and then not Is_Limited_Type (Typ)
5257      then
5258         declare
5259            Comps : constant Node_Id :=
5260                      Component_List (Type_Definition (Typ_Decl));
5261         begin
5262            if Present (Comps)
5263              and then Present (Variant_Part (Comps))
5264            then
5265               Build_Variant_Record_Equality (Typ);
5266            end if;
5267         end;
5268
5269      --  Otherwise create primitive equality operation (AI05-0123)
5270
5271      --  This is done unconditionally to ensure that tools can be linked
5272      --  properly with user programs compiled with older language versions.
5273      --  In addition, this is needed because "=" composes for bounded strings
5274      --  in all language versions (see Exp_Ch4.Expand_Composite_Equality).
5275
5276      elsif Comes_From_Source (Typ)
5277        and then Convention (Typ) = Convention_Ada
5278        and then not Is_Limited_Type (Typ)
5279      then
5280         Build_Untagged_Equality (Typ);
5281      end if;
5282
5283      --  Before building the record initialization procedure, if we are
5284      --  dealing with a concurrent record value type, then we must go through
5285      --  the discriminants, exchanging discriminals between the concurrent
5286      --  type and the concurrent record value type. See the section "Handling
5287      --  of Discriminants" in the Einfo spec for details.
5288
5289      if Is_Concurrent_Record_Type (Typ)
5290        and then Has_Discriminants (Typ)
5291      then
5292         declare
5293            Ctyp       : constant Entity_Id :=
5294                           Corresponding_Concurrent_Type (Typ);
5295            Conc_Discr : Entity_Id;
5296            Rec_Discr  : Entity_Id;
5297            Temp       : Entity_Id;
5298
5299         begin
5300            Conc_Discr := First_Discriminant (Ctyp);
5301            Rec_Discr  := First_Discriminant (Typ);
5302            while Present (Conc_Discr) loop
5303               Temp := Discriminal (Conc_Discr);
5304               Set_Discriminal (Conc_Discr, Discriminal (Rec_Discr));
5305               Set_Discriminal (Rec_Discr, Temp);
5306
5307               Set_Discriminal_Link (Discriminal (Conc_Discr), Conc_Discr);
5308               Set_Discriminal_Link (Discriminal (Rec_Discr),  Rec_Discr);
5309
5310               Next_Discriminant (Conc_Discr);
5311               Next_Discriminant (Rec_Discr);
5312            end loop;
5313         end;
5314      end if;
5315
5316      if Has_Controlled_Component (Typ) then
5317         Build_Controlling_Procs (Typ);
5318      end if;
5319
5320      Adjust_Discriminants (Typ);
5321
5322      --  Do not need init for interfaces on virtual targets since they're
5323      --  abstract.
5324
5325      if Tagged_Type_Expansion or else not Is_Interface (Typ) then
5326         Build_Record_Init_Proc (Typ_Decl, Typ);
5327      end if;
5328
5329      --  For tagged type that are not interfaces, build bodies of primitive
5330      --  operations. Note: do this after building the record initialization
5331      --  procedure, since the primitive operations may need the initialization
5332      --  routine. There is no need to add predefined primitives of interfaces
5333      --  because all their predefined primitives are abstract.
5334
5335      if Is_Tagged_Type (Typ) and then not Is_Interface (Typ) then
5336
5337         --  Do not add the body of predefined primitives in case of CPP tagged
5338         --  type derivations that have convention CPP.
5339
5340         if Is_CPP_Class (Root_Type (Typ))
5341           and then Convention (Typ) = Convention_CPP
5342         then
5343            null;
5344
5345         --  Do not add the body of the predefined primitives if we are
5346         --  compiling under restriction No_Dispatching_Calls or if we are
5347         --  compiling a CPP tagged type.
5348
5349         elsif not Restriction_Active (No_Dispatching_Calls) then
5350
5351            --  Create the body of TSS primitive Finalize_Address. This must
5352            --  be done before the bodies of all predefined primitives are
5353            --  created. If Typ is limited, Stream_Input and Stream_Read may
5354            --  produce build-in-place allocations and for those the expander
5355            --  needs Finalize_Address.
5356
5357            Make_Finalize_Address_Body (Typ);
5358            Predef_List := Predefined_Primitive_Bodies (Typ, Renamed_Eq);
5359            Append_Freeze_Actions (Typ, Predef_List);
5360         end if;
5361
5362         --  Ada 2005 (AI-391): If any wrappers were created for nonoverridden
5363         --  inherited functions, then add their bodies to the freeze actions.
5364
5365         if Present (Wrapper_Body_List) then
5366            Append_Freeze_Actions (Typ, Wrapper_Body_List);
5367         end if;
5368
5369         --  Create extra formals for the primitive operations of the type.
5370         --  This must be done before analyzing the body of the initialization
5371         --  procedure, because a self-referential type might call one of these
5372         --  primitives in the body of the init_proc itself.
5373
5374         declare
5375            Elmt : Elmt_Id;
5376            Subp : Entity_Id;
5377
5378         begin
5379            Elmt := First_Elmt (Primitive_Operations (Typ));
5380            while Present (Elmt) loop
5381               Subp := Node (Elmt);
5382               if not Has_Foreign_Convention (Subp)
5383                 and then not Is_Predefined_Dispatching_Operation (Subp)
5384               then
5385                  Create_Extra_Formals (Subp);
5386               end if;
5387
5388               Next_Elmt (Elmt);
5389            end loop;
5390         end;
5391      end if;
5392   end Expand_Freeze_Record_Type;
5393
5394   ------------------------------------
5395   -- Expand_N_Full_Type_Declaration --
5396   ------------------------------------
5397
5398   procedure Expand_N_Full_Type_Declaration (N : Node_Id) is
5399      procedure Build_Master (Ptr_Typ : Entity_Id);
5400      --  Create the master associated with Ptr_Typ
5401
5402      ------------------
5403      -- Build_Master --
5404      ------------------
5405
5406      procedure Build_Master (Ptr_Typ : Entity_Id) is
5407         Desig_Typ : Entity_Id := Designated_Type (Ptr_Typ);
5408
5409      begin
5410         --  If the designated type is an incomplete view coming from a
5411         --  limited-with'ed package, we need to use the nonlimited view in
5412         --  case it has tasks.
5413
5414         if Ekind (Desig_Typ) in Incomplete_Kind
5415           and then Present (Non_Limited_View (Desig_Typ))
5416         then
5417            Desig_Typ := Non_Limited_View (Desig_Typ);
5418         end if;
5419
5420         --  Anonymous access types are created for the components of the
5421         --  record parameter for an entry declaration. No master is created
5422         --  for such a type.
5423
5424         if Comes_From_Source (N) and then Has_Task (Desig_Typ) then
5425            Build_Master_Entity (Ptr_Typ);
5426            Build_Master_Renaming (Ptr_Typ);
5427
5428         --  Create a class-wide master because a Master_Id must be generated
5429         --  for access-to-limited-class-wide types whose root may be extended
5430         --  with task components.
5431
5432         --  Note: This code covers access-to-limited-interfaces because they
5433         --        can be used to reference tasks implementing them.
5434
5435         elsif Is_Limited_Class_Wide_Type (Desig_Typ)
5436           and then Tasking_Allowed
5437         then
5438            Build_Class_Wide_Master (Ptr_Typ);
5439         end if;
5440      end Build_Master;
5441
5442      --  Local declarations
5443
5444      Def_Id : constant Entity_Id := Defining_Identifier (N);
5445      B_Id   : constant Entity_Id := Base_Type (Def_Id);
5446      FN     : Node_Id;
5447      Par_Id : Entity_Id;
5448
5449   --  Start of processing for Expand_N_Full_Type_Declaration
5450
5451   begin
5452      if Is_Access_Type (Def_Id) then
5453         Build_Master (Def_Id);
5454
5455         if Ekind (Def_Id) = E_Access_Protected_Subprogram_Type then
5456            Expand_Access_Protected_Subprogram_Type (N);
5457         end if;
5458
5459      --  Array of anonymous access-to-task pointers
5460
5461      elsif Ada_Version >= Ada_2005
5462        and then Is_Array_Type (Def_Id)
5463        and then Is_Access_Type (Component_Type (Def_Id))
5464        and then Ekind (Component_Type (Def_Id)) = E_Anonymous_Access_Type
5465      then
5466         Build_Master (Component_Type (Def_Id));
5467
5468      elsif Has_Task (Def_Id) then
5469         Expand_Previous_Access_Type (Def_Id);
5470
5471      --  Check the components of a record type or array of records for
5472      --  anonymous access-to-task pointers.
5473
5474      elsif Ada_Version >= Ada_2005
5475        and then (Is_Record_Type (Def_Id)
5476                   or else
5477                     (Is_Array_Type (Def_Id)
5478                       and then Is_Record_Type (Component_Type (Def_Id))))
5479      then
5480         declare
5481            Comp  : Entity_Id;
5482            First : Boolean;
5483            M_Id  : Entity_Id;
5484            Typ   : Entity_Id;
5485
5486         begin
5487            if Is_Array_Type (Def_Id) then
5488               Comp := First_Entity (Component_Type (Def_Id));
5489            else
5490               Comp := First_Entity (Def_Id);
5491            end if;
5492
5493            --  Examine all components looking for anonymous access-to-task
5494            --  types.
5495
5496            First := True;
5497            while Present (Comp) loop
5498               Typ := Etype (Comp);
5499
5500               if Ekind (Typ) = E_Anonymous_Access_Type
5501                 and then Has_Task (Available_View (Designated_Type (Typ)))
5502                 and then No (Master_Id (Typ))
5503               then
5504                  --  Ensure that the record or array type have a _master
5505
5506                  if First then
5507                     Build_Master_Entity (Def_Id);
5508                     Build_Master_Renaming (Typ);
5509                     M_Id := Master_Id (Typ);
5510
5511                     First := False;
5512
5513                  --  Reuse the same master to service any additional types
5514
5515                  else
5516                     Set_Master_Id (Typ, M_Id);
5517                  end if;
5518               end if;
5519
5520               Next_Entity (Comp);
5521            end loop;
5522         end;
5523      end if;
5524
5525      Par_Id := Etype (B_Id);
5526
5527      --  The parent type is private then we need to inherit any TSS operations
5528      --  from the full view.
5529
5530      if Ekind (Par_Id) in Private_Kind
5531        and then Present (Full_View (Par_Id))
5532      then
5533         Par_Id := Base_Type (Full_View (Par_Id));
5534      end if;
5535
5536      if Nkind (Type_Definition (Original_Node (N))) =
5537                                                   N_Derived_Type_Definition
5538        and then not Is_Tagged_Type (Def_Id)
5539        and then Present (Freeze_Node (Par_Id))
5540        and then Present (TSS_Elist (Freeze_Node (Par_Id)))
5541      then
5542         Ensure_Freeze_Node (B_Id);
5543         FN := Freeze_Node (B_Id);
5544
5545         if No (TSS_Elist (FN)) then
5546            Set_TSS_Elist (FN, New_Elmt_List);
5547         end if;
5548
5549         declare
5550            T_E  : constant Elist_Id := TSS_Elist (FN);
5551            Elmt : Elmt_Id;
5552
5553         begin
5554            Elmt := First_Elmt (TSS_Elist (Freeze_Node (Par_Id)));
5555            while Present (Elmt) loop
5556               if Chars (Node (Elmt)) /= Name_uInit then
5557                  Append_Elmt (Node (Elmt), T_E);
5558               end if;
5559
5560               Next_Elmt (Elmt);
5561            end loop;
5562
5563            --  If the derived type itself is private with a full view, then
5564            --  associate the full view with the inherited TSS_Elist as well.
5565
5566            if Ekind (B_Id) in Private_Kind
5567              and then Present (Full_View (B_Id))
5568            then
5569               Ensure_Freeze_Node (Base_Type (Full_View (B_Id)));
5570               Set_TSS_Elist
5571                 (Freeze_Node (Base_Type (Full_View (B_Id))), TSS_Elist (FN));
5572            end if;
5573         end;
5574      end if;
5575   end Expand_N_Full_Type_Declaration;
5576
5577   ---------------------------------
5578   -- Expand_N_Object_Declaration --
5579   ---------------------------------
5580
5581   procedure Expand_N_Object_Declaration (N : Node_Id) is
5582      Loc      : constant Source_Ptr := Sloc (N);
5583      Def_Id   : constant Entity_Id  := Defining_Identifier (N);
5584      Expr     : constant Node_Id    := Expression (N);
5585      Obj_Def  : constant Node_Id    := Object_Definition (N);
5586      Typ      : constant Entity_Id  := Etype (Def_Id);
5587      Base_Typ : constant Entity_Id  := Base_Type (Typ);
5588      Expr_Q   : Node_Id;
5589
5590      function Build_Equivalent_Aggregate return Boolean;
5591      --  If the object has a constrained discriminated type and no initial
5592      --  value, it may be possible to build an equivalent aggregate instead,
5593      --  and prevent an actual call to the initialization procedure.
5594
5595      procedure Check_Large_Modular_Array;
5596      --  Check that the size of the array can be computed without overflow,
5597      --  and generate a Storage_Error otherwise. This is only relevant for
5598      --  array types whose index in a (mod 2**64) type, where wrap-around
5599      --  arithmetic might yield a meaningless value for the length of the
5600      --  array, or its corresponding attribute.
5601
5602      procedure Count_Default_Sized_Task_Stacks
5603        (Typ         : Entity_Id;
5604         Pri_Stacks  : out Int;
5605         Sec_Stacks  : out Int);
5606      --  Count the number of default-sized primary and secondary task stacks
5607      --  required for task objects contained within type Typ. If the number of
5608      --  task objects contained within the type is not known at compile time
5609      --  the procedure will return the stack counts of zero.
5610
5611      procedure Default_Initialize_Object (After : Node_Id);
5612      --  Generate all default initialization actions for object Def_Id. Any
5613      --  new code is inserted after node After.
5614
5615      function Rewrite_As_Renaming return Boolean;
5616      --  Indicate whether to rewrite a declaration with initialization into an
5617      --  object renaming declaration (see below).
5618
5619      --------------------------------
5620      -- Build_Equivalent_Aggregate --
5621      --------------------------------
5622
5623      function Build_Equivalent_Aggregate return Boolean is
5624         Aggr      : Node_Id;
5625         Comp      : Entity_Id;
5626         Discr     : Elmt_Id;
5627         Full_Type : Entity_Id;
5628
5629      begin
5630         Full_Type := Typ;
5631
5632         if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
5633            Full_Type := Full_View (Typ);
5634         end if;
5635
5636         --  Only perform this transformation if Elaboration_Code is forbidden
5637         --  or undesirable, and if this is a global entity of a constrained
5638         --  record type.
5639
5640         --  If Initialize_Scalars might be active this  transformation cannot
5641         --  be performed either, because it will lead to different semantics
5642         --  or because elaboration code will in fact be created.
5643
5644         if Ekind (Full_Type) /= E_Record_Subtype
5645           or else not Has_Discriminants (Full_Type)
5646           or else not Is_Constrained (Full_Type)
5647           or else Is_Controlled (Full_Type)
5648           or else Is_Limited_Type (Full_Type)
5649           or else not Restriction_Active (No_Initialize_Scalars)
5650         then
5651            return False;
5652         end if;
5653
5654         if Ekind (Current_Scope) = E_Package
5655           and then
5656             (Restriction_Active (No_Elaboration_Code)
5657               or else Is_Preelaborated (Current_Scope))
5658         then
5659            --  Building a static aggregate is possible if the discriminants
5660            --  have static values and the other components have static
5661            --  defaults or none.
5662
5663            Discr := First_Elmt (Discriminant_Constraint (Full_Type));
5664            while Present (Discr) loop
5665               if not Is_OK_Static_Expression (Node (Discr)) then
5666                  return False;
5667               end if;
5668
5669               Next_Elmt (Discr);
5670            end loop;
5671
5672            --  Check that initialized components are OK, and that non-
5673            --  initialized components do not require a call to their own
5674            --  initialization procedure.
5675
5676            Comp := First_Component (Full_Type);
5677            while Present (Comp) loop
5678               if Ekind (Comp) = E_Component
5679                 and then Present (Expression (Parent (Comp)))
5680                 and then
5681                   not Is_OK_Static_Expression (Expression (Parent (Comp)))
5682               then
5683                  return False;
5684
5685               elsif Has_Non_Null_Base_Init_Proc (Etype (Comp)) then
5686                  return False;
5687
5688               end if;
5689
5690               Next_Component (Comp);
5691            end loop;
5692
5693            --  Everything is static, assemble the aggregate, discriminant
5694            --  values first.
5695
5696            Aggr :=
5697               Make_Aggregate (Loc,
5698                Expressions            => New_List,
5699                Component_Associations => New_List);
5700
5701            Discr := First_Elmt (Discriminant_Constraint (Full_Type));
5702            while Present (Discr) loop
5703               Append_To (Expressions (Aggr), New_Copy (Node (Discr)));
5704               Next_Elmt (Discr);
5705            end loop;
5706
5707            --  Now collect values of initialized components
5708
5709            Comp := First_Component (Full_Type);
5710            while Present (Comp) loop
5711               if Ekind (Comp) = E_Component
5712                 and then Present (Expression (Parent (Comp)))
5713               then
5714                  Append_To (Component_Associations (Aggr),
5715                    Make_Component_Association (Loc,
5716                      Choices    => New_List (New_Occurrence_Of (Comp, Loc)),
5717                      Expression => New_Copy_Tree
5718                                      (Expression (Parent (Comp)))));
5719               end if;
5720
5721               Next_Component (Comp);
5722            end loop;
5723
5724            --  Finally, box-initialize remaining components
5725
5726            Append_To (Component_Associations (Aggr),
5727              Make_Component_Association (Loc,
5728                Choices    => New_List (Make_Others_Choice (Loc)),
5729                Expression => Empty));
5730            Set_Box_Present (Last (Component_Associations (Aggr)));
5731            Set_Expression (N, Aggr);
5732
5733            if Typ /= Full_Type then
5734               Analyze_And_Resolve (Aggr, Full_View (Base_Type (Full_Type)));
5735               Rewrite (Aggr, Unchecked_Convert_To (Typ, Aggr));
5736               Analyze_And_Resolve (Aggr, Typ);
5737            else
5738               Analyze_And_Resolve (Aggr, Full_Type);
5739            end if;
5740
5741            return True;
5742
5743         else
5744            return False;
5745         end if;
5746      end Build_Equivalent_Aggregate;
5747
5748      -------------------------------
5749      -- Check_Large_Modular_Array --
5750      -------------------------------
5751
5752      procedure Check_Large_Modular_Array is
5753         Index_Typ : Entity_Id;
5754
5755      begin
5756         if Is_Array_Type (Typ)
5757           and then Is_Modular_Integer_Type (Etype (First_Index (Typ)))
5758         then
5759            --  To prevent arithmetic overflow with large values, we raise
5760            --  Storage_Error under the following guard:
5761
5762            --    (Arr'Last / 2 - Arr'First / 2) > (2 ** 30)
5763
5764            --  This takes care of the boundary case, but it is preferable to
5765            --  use a smaller limit, because even on 64-bit architectures an
5766            --  array of more than 2 ** 30 bytes is likely to raise
5767            --  Storage_Error.
5768
5769            Index_Typ := Etype (First_Index (Typ));
5770
5771            if RM_Size (Index_Typ) = RM_Size (Standard_Long_Long_Integer) then
5772               Insert_Action (N,
5773                 Make_Raise_Storage_Error (Loc,
5774                   Condition =>
5775                     Make_Op_Ge (Loc,
5776                       Left_Opnd  =>
5777                         Make_Op_Subtract (Loc,
5778                           Left_Opnd  =>
5779                             Make_Op_Divide (Loc,
5780                               Left_Opnd  =>
5781                                 Make_Attribute_Reference (Loc,
5782                                   Prefix         =>
5783                                     New_Occurrence_Of (Typ, Loc),
5784                                   Attribute_Name => Name_Last),
5785                               Right_Opnd =>
5786                                 Make_Integer_Literal (Loc, Uint_2)),
5787                           Right_Opnd =>
5788                             Make_Op_Divide (Loc,
5789                               Left_Opnd =>
5790                                 Make_Attribute_Reference (Loc,
5791                                   Prefix         =>
5792                                     New_Occurrence_Of (Typ, Loc),
5793                                   Attribute_Name => Name_First),
5794                               Right_Opnd =>
5795                                 Make_Integer_Literal (Loc, Uint_2))),
5796                       Right_Opnd =>
5797                         Make_Integer_Literal (Loc, (Uint_2 ** 30))),
5798                   Reason    => SE_Object_Too_Large));
5799            end if;
5800         end if;
5801      end Check_Large_Modular_Array;
5802
5803      -------------------------------------
5804      -- Count_Default_Sized_Task_Stacks --
5805      -------------------------------------
5806
5807      procedure Count_Default_Sized_Task_Stacks
5808        (Typ         : Entity_Id;
5809         Pri_Stacks  : out Int;
5810         Sec_Stacks  : out Int)
5811      is
5812         Component : Entity_Id;
5813
5814      begin
5815         --  To calculate the number of default-sized task stacks required for
5816         --  an object of Typ, a depth-first recursive traversal of the AST
5817         --  from the Typ entity node is undertaken. Only type nodes containing
5818         --  task objects are visited.
5819
5820         Pri_Stacks := 0;
5821         Sec_Stacks := 0;
5822
5823         if not Has_Task (Typ) then
5824            return;
5825         end if;
5826
5827         case Ekind (Typ) is
5828            when E_Task_Subtype
5829               | E_Task_Type
5830            =>
5831               --  A task type is found marking the bottom of the descent. If
5832               --  the type has no representation aspect for the corresponding
5833               --  stack then that stack is using the default size.
5834
5835               if Present (Get_Rep_Item (Typ, Name_Storage_Size)) then
5836                  Pri_Stacks := 0;
5837               else
5838                  Pri_Stacks := 1;
5839               end if;
5840
5841               if Present (Get_Rep_Item (Typ, Name_Secondary_Stack_Size)) then
5842                  Sec_Stacks := 0;
5843               else
5844                  Sec_Stacks := 1;
5845               end if;
5846
5847            when E_Array_Subtype
5848               | E_Array_Type
5849            =>
5850               --  First find the number of default stacks contained within an
5851               --  array component.
5852
5853               Count_Default_Sized_Task_Stacks
5854                 (Component_Type (Typ),
5855                  Pri_Stacks,
5856                  Sec_Stacks);
5857
5858               --  Then multiply the result by the size of the array
5859
5860               declare
5861                  Quantity : constant Int := Number_Of_Elements_In_Array (Typ);
5862                  --  Number_Of_Elements_In_Array is non-trival, consequently
5863                  --  its result is captured as an optimization.
5864
5865               begin
5866                  Pri_Stacks := Pri_Stacks * Quantity;
5867                  Sec_Stacks := Sec_Stacks * Quantity;
5868               end;
5869
5870            when E_Protected_Subtype
5871               | E_Protected_Type
5872               | E_Record_Subtype
5873               | E_Record_Type
5874            =>
5875               Component := First_Component_Or_Discriminant (Typ);
5876
5877               --  Recursively descend each component of the composite type
5878               --  looking for tasks, but only if the component is marked as
5879               --  having a task.
5880
5881               while Present (Component) loop
5882                  if Has_Task (Etype (Component)) then
5883                     declare
5884                        P : Int;
5885                        S : Int;
5886
5887                     begin
5888                        Count_Default_Sized_Task_Stacks
5889                          (Etype (Component), P, S);
5890                        Pri_Stacks := Pri_Stacks + P;
5891                        Sec_Stacks := Sec_Stacks + S;
5892                     end;
5893                  end if;
5894
5895                  Next_Component_Or_Discriminant (Component);
5896               end loop;
5897
5898            when E_Limited_Private_Subtype
5899               | E_Limited_Private_Type
5900               | E_Record_Subtype_With_Private
5901               | E_Record_Type_With_Private
5902            =>
5903               --  Switch to the full view of the private type to continue
5904               --  search.
5905
5906               Count_Default_Sized_Task_Stacks
5907                 (Full_View (Typ), Pri_Stacks, Sec_Stacks);
5908
5909            --  Other types should not contain tasks
5910
5911            when others =>
5912               raise Program_Error;
5913         end case;
5914      end Count_Default_Sized_Task_Stacks;
5915
5916      -------------------------------
5917      -- Default_Initialize_Object --
5918      -------------------------------
5919
5920      procedure Default_Initialize_Object (After : Node_Id) is
5921         function New_Object_Reference return Node_Id;
5922         --  Return a new reference to Def_Id with attributes Assignment_OK and
5923         --  Must_Not_Freeze already set.
5924
5925         --------------------------
5926         -- New_Object_Reference --
5927         --------------------------
5928
5929         function New_Object_Reference return Node_Id is
5930            Obj_Ref : constant Node_Id := New_Occurrence_Of (Def_Id, Loc);
5931
5932         begin
5933            --  The call to the type init proc or [Deep_]Finalize must not
5934            --  freeze the related object as the call is internally generated.
5935            --  This way legal rep clauses that apply to the object will not be
5936            --  flagged. Note that the initialization call may be removed if
5937            --  pragma Import is encountered or moved to the freeze actions of
5938            --  the object because of an address clause.
5939
5940            Set_Assignment_OK   (Obj_Ref);
5941            Set_Must_Not_Freeze (Obj_Ref);
5942
5943            return Obj_Ref;
5944         end New_Object_Reference;
5945
5946         --  Local variables
5947
5948         Exceptions_OK : constant Boolean :=
5949                           not Restriction_Active (No_Exception_Propagation);
5950
5951         Aggr_Init  : Node_Id;
5952         Comp_Init  : List_Id := No_List;
5953         Fin_Block  : Node_Id;
5954         Fin_Call   : Node_Id;
5955         Init_Stmts : List_Id := No_List;
5956         Obj_Init   : Node_Id := Empty;
5957         Obj_Ref    : Node_Id;
5958
5959      --  Start of processing for Default_Initialize_Object
5960
5961      begin
5962         --  Default initialization is suppressed for objects that are already
5963         --  known to be imported (i.e. whose declaration specifies the Import
5964         --  aspect). Note that for objects with a pragma Import, we generate
5965         --  initialization here, and then remove it downstream when processing
5966         --  the pragma. It is also suppressed for variables for which a pragma
5967         --  Suppress_Initialization has been explicitly given
5968
5969         if Is_Imported (Def_Id) or else Suppress_Initialization (Def_Id) then
5970            return;
5971
5972         --  Nothing to do if the object being initialized is of a task type
5973         --  and restriction No_Tasking is in effect, because this is a direct
5974         --  violation of the restriction.
5975
5976         elsif Is_Task_Type (Base_Typ)
5977           and then Restriction_Active (No_Tasking)
5978         then
5979            return;
5980         end if;
5981
5982         --  The expansion performed by this routine is as follows:
5983
5984         --    begin
5985         --       Abort_Defer;
5986         --       Type_Init_Proc (Obj);
5987
5988         --       begin
5989         --          [Deep_]Initialize (Obj);
5990
5991         --       exception
5992         --          when others =>
5993         --             [Deep_]Finalize (Obj, Self => False);
5994         --             raise;
5995         --       end;
5996         --    at end
5997         --       Abort_Undefer_Direct;
5998         --    end;
5999
6000         --  Initialize the components of the object
6001
6002         if Has_Non_Null_Base_Init_Proc (Typ)
6003           and then not No_Initialization (N)
6004           and then not Initialization_Suppressed (Typ)
6005         then
6006            --  Do not initialize the components if No_Default_Initialization
6007            --  applies as the actual restriction check will occur later
6008            --  when the object is frozen as it is not known yet whether the
6009            --  object is imported or not.
6010
6011            if not Restriction_Active (No_Default_Initialization) then
6012
6013               --  If the values of the components are compile-time known, use
6014               --  their prebuilt aggregate form directly.
6015
6016               Aggr_Init := Static_Initialization (Base_Init_Proc (Typ));
6017
6018               if Present (Aggr_Init) then
6019                  Set_Expression
6020                    (N, New_Copy_Tree (Aggr_Init, New_Scope => Current_Scope));
6021
6022               --  If type has discriminants, try to build an equivalent
6023               --  aggregate using discriminant values from the declaration.
6024               --  This is a useful optimization, in particular if restriction
6025               --  No_Elaboration_Code is active.
6026
6027               elsif Build_Equivalent_Aggregate then
6028                  null;
6029
6030               --  Otherwise invoke the type init proc, generate:
6031               --    Type_Init_Proc (Obj);
6032
6033               else
6034                  Obj_Ref := New_Object_Reference;
6035
6036                  if Comes_From_Source (Def_Id) then
6037                     Initialization_Warning (Obj_Ref);
6038                  end if;
6039
6040                  Comp_Init := Build_Initialization_Call (Loc, Obj_Ref, Typ);
6041               end if;
6042            end if;
6043
6044         --  Provide a default value if the object needs simple initialization
6045         --  and does not already have an initial value. A generated temporary
6046         --  does not require initialization because it will be assigned later.
6047
6048         elsif Needs_Simple_Initialization
6049                 (Typ, Initialize_Scalars
6050                         and then No (Following_Address_Clause (N)))
6051           and then not Is_Internal (Def_Id)
6052           and then not Has_Init_Expression (N)
6053         then
6054            Set_No_Initialization (N, False);
6055            Set_Expression
6056              (N, New_Copy_Tree
6057                    (Get_Simple_Init_Val (Typ, N, Esize (Def_Id)),
6058                     New_Sloc => Sloc (Obj_Def)));
6059            Analyze_And_Resolve (Expression (N), Typ);
6060         end if;
6061
6062         --  Initialize the object, generate:
6063         --    [Deep_]Initialize (Obj);
6064
6065         if Needs_Finalization (Typ) and then not No_Initialization (N) then
6066            Obj_Init :=
6067              Make_Init_Call
6068                (Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
6069                 Typ     => Typ);
6070         end if;
6071
6072         --  Build a special finalization block when both the object and its
6073         --  controlled components are to be initialized. The block finalizes
6074         --  the components if the object initialization fails. Generate:
6075
6076         --    begin
6077         --       <Obj_Init>
6078
6079         --    exception
6080         --       when others =>
6081         --          <Fin_Call>
6082         --          raise;
6083         --    end;
6084
6085         if Has_Controlled_Component (Typ)
6086           and then Present (Comp_Init)
6087           and then Present (Obj_Init)
6088           and then Exceptions_OK
6089         then
6090            Init_Stmts := Comp_Init;
6091
6092            Fin_Call :=
6093              Make_Final_Call
6094                (Obj_Ref   => New_Object_Reference,
6095                 Typ       => Typ,
6096                 Skip_Self => True);
6097
6098            if Present (Fin_Call) then
6099
6100               --  Do not emit warnings related to the elaboration order when a
6101               --  controlled object is declared before the body of Finalize is
6102               --  seen.
6103
6104               if Legacy_Elaboration_Checks then
6105                  Set_No_Elaboration_Check (Fin_Call);
6106               end if;
6107
6108               Fin_Block :=
6109                 Make_Block_Statement (Loc,
6110                   Declarations               => No_List,
6111
6112                   Handled_Statement_Sequence =>
6113                     Make_Handled_Sequence_Of_Statements (Loc,
6114                       Statements         => New_List (Obj_Init),
6115
6116                       Exception_Handlers => New_List (
6117                         Make_Exception_Handler (Loc,
6118                           Exception_Choices => New_List (
6119                             Make_Others_Choice (Loc)),
6120
6121                           Statements        => New_List (
6122                             Fin_Call,
6123                             Make_Raise_Statement (Loc))))));
6124
6125               --  Signal the ABE mechanism that the block carries out
6126               --  initialization actions.
6127
6128               Set_Is_Initialization_Block (Fin_Block);
6129
6130               Append_To (Init_Stmts, Fin_Block);
6131            end if;
6132
6133         --  Otherwise finalization is not required, the initialization calls
6134         --  are passed to the abort block building circuitry, generate:
6135
6136         --    Type_Init_Proc (Obj);
6137         --    [Deep_]Initialize (Obj);
6138
6139         else
6140            if Present (Comp_Init) then
6141               Init_Stmts := Comp_Init;
6142            end if;
6143
6144            if Present (Obj_Init) then
6145               if No (Init_Stmts) then
6146                  Init_Stmts := New_List;
6147               end if;
6148
6149               Append_To (Init_Stmts, Obj_Init);
6150            end if;
6151         end if;
6152
6153         --  Build an abort block to protect the initialization calls
6154
6155         if Abort_Allowed
6156           and then Present (Comp_Init)
6157           and then Present (Obj_Init)
6158         then
6159            --  Generate:
6160            --    Abort_Defer;
6161
6162            Prepend_To (Init_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
6163
6164            --  When exceptions are propagated, abort deferral must take place
6165            --  in the presence of initialization or finalization exceptions.
6166            --  Generate:
6167
6168            --    begin
6169            --       Abort_Defer;
6170            --       <Init_Stmts>
6171            --    at end
6172            --       Abort_Undefer_Direct;
6173            --    end;
6174
6175            if Exceptions_OK then
6176               Init_Stmts := New_List (
6177                 Build_Abort_Undefer_Block (Loc,
6178                   Stmts   => Init_Stmts,
6179                   Context => N));
6180
6181            --  Otherwise exceptions are not propagated. Generate:
6182
6183            --    Abort_Defer;
6184            --    <Init_Stmts>
6185            --    Abort_Undefer;
6186
6187            else
6188               Append_To (Init_Stmts,
6189                 Build_Runtime_Call (Loc, RE_Abort_Undefer));
6190            end if;
6191         end if;
6192
6193         --  Insert the whole initialization sequence into the tree. If the
6194         --  object has a delayed freeze, as will be the case when it has
6195         --  aspect specifications, the initialization sequence is part of
6196         --  the freeze actions.
6197
6198         if Present (Init_Stmts) then
6199            if Has_Delayed_Freeze (Def_Id) then
6200               Append_Freeze_Actions (Def_Id, Init_Stmts);
6201            else
6202               Insert_Actions_After (After, Init_Stmts);
6203            end if;
6204         end if;
6205      end Default_Initialize_Object;
6206
6207      -------------------------
6208      -- Rewrite_As_Renaming --
6209      -------------------------
6210
6211      function Rewrite_As_Renaming return Boolean is
6212      begin
6213         --  If the object declaration appears in the form
6214
6215         --    Obj : Ctrl_Typ := Func (...);
6216
6217         --  where Ctrl_Typ is controlled but not immutably limited type, then
6218         --  the expansion of the function call should use a dereference of the
6219         --  result to reference the value on the secondary stack.
6220
6221         --    Obj : Ctrl_Typ renames Func (...).all;
6222
6223         --  As a result, the call avoids an extra copy. This an optimization,
6224         --  but it is required for passing ACATS tests in some cases where it
6225         --  would otherwise make two copies. The RM allows removing redunant
6226         --  Adjust/Finalize calls, but does not allow insertion of extra ones.
6227
6228         --  This part is disabled for now, because it breaks GPS builds
6229
6230         return (False -- ???
6231             and then Nkind (Expr_Q) = N_Explicit_Dereference
6232             and then not Comes_From_Source (Expr_Q)
6233             and then Nkind (Original_Node (Expr_Q)) = N_Function_Call
6234             and then Nkind (Object_Definition (N)) in N_Has_Entity
6235             and then (Needs_Finalization (Entity (Object_Definition (N)))))
6236
6237           --  If the initializing expression is for a variable with attribute
6238           --  OK_To_Rename set, then transform:
6239
6240           --     Obj : Typ := Expr;
6241
6242           --  into
6243
6244           --     Obj : Typ renames Expr;
6245
6246           --  provided that Obj is not aliased. The aliased case has to be
6247           --  excluded in general because Expr will not be aliased in
6248           --  general.
6249
6250           or else
6251             (not Aliased_Present (N)
6252               and then Is_Entity_Name (Expr_Q)
6253               and then Ekind (Entity (Expr_Q)) = E_Variable
6254               and then OK_To_Rename (Entity (Expr_Q))
6255               and then Is_Entity_Name (Obj_Def));
6256      end Rewrite_As_Renaming;
6257
6258      --  Local variables
6259
6260      Next_N : constant Node_Id := Next (N);
6261
6262      Adj_Call   : Node_Id;
6263      Id_Ref     : Node_Id;
6264      Tag_Assign : Node_Id;
6265
6266      Init_After : Node_Id := N;
6267      --  Node after which the initialization actions are to be inserted. This
6268      --  is normally N, except for the case of a shared passive variable, in
6269      --  which case the init proc call must be inserted only after the bodies
6270      --  of the shared variable procedures have been seen.
6271
6272   --  Start of processing for Expand_N_Object_Declaration
6273
6274   begin
6275      --  Don't do anything for deferred constants. All proper actions will be
6276      --  expanded during the full declaration.
6277
6278      if No (Expr) and Constant_Present (N) then
6279         return;
6280      end if;
6281
6282      --  The type of the object cannot be abstract. This is diagnosed at the
6283      --  point the object is frozen, which happens after the declaration is
6284      --  fully expanded, so simply return now.
6285
6286      if Is_Abstract_Type (Typ) then
6287         return;
6288      end if;
6289
6290      --  No action needed for the internal imported dummy object added by
6291      --  Make_DT to compute the offset of the components that reference
6292      --  secondary dispatch tables; required to avoid never-ending loop
6293      --  processing this internal object declaration.
6294
6295      if Tagged_Type_Expansion
6296        and then Is_Internal (Def_Id)
6297        and then Is_Imported (Def_Id)
6298        and then Related_Type (Def_Id) = Implementation_Base_Type (Typ)
6299      then
6300         return;
6301      end if;
6302
6303      --  First we do special processing for objects of a tagged type where
6304      --  this is the point at which the type is frozen. The creation of the
6305      --  dispatch table and the initialization procedure have to be deferred
6306      --  to this point, since we reference previously declared primitive
6307      --  subprograms.
6308
6309      --  Force construction of dispatch tables of library level tagged types
6310
6311      if Tagged_Type_Expansion
6312        and then Building_Static_Dispatch_Tables
6313        and then Is_Library_Level_Entity (Def_Id)
6314        and then Is_Library_Level_Tagged_Type (Base_Typ)
6315        and then Ekind_In (Base_Typ, E_Record_Type,
6316                                     E_Protected_Type,
6317                                     E_Task_Type)
6318        and then not Has_Dispatch_Table (Base_Typ)
6319      then
6320         declare
6321            New_Nodes : List_Id := No_List;
6322
6323         begin
6324            if Is_Concurrent_Type (Base_Typ) then
6325               New_Nodes := Make_DT (Corresponding_Record_Type (Base_Typ), N);
6326            else
6327               New_Nodes := Make_DT (Base_Typ, N);
6328            end if;
6329
6330            if not Is_Empty_List (New_Nodes) then
6331               Insert_List_Before (N, New_Nodes);
6332            end if;
6333         end;
6334      end if;
6335
6336      --  Make shared memory routines for shared passive variable
6337
6338      if Is_Shared_Passive (Def_Id) then
6339         Init_After := Make_Shared_Var_Procs (N);
6340      end if;
6341
6342      --  If tasks being declared, make sure we have an activation chain
6343      --  defined for the tasks (has no effect if we already have one), and
6344      --  also that a Master variable is established and that the appropriate
6345      --  enclosing construct is established as a task master.
6346
6347      if Has_Task (Typ) then
6348         Build_Activation_Chain_Entity (N);
6349         Build_Master_Entity (Def_Id);
6350      end if;
6351
6352      Check_Large_Modular_Array;
6353
6354      --  If No_Implicit_Heap_Allocations or No_Implicit_Task_Allocations
6355      --  restrictions are active then default-sized secondary stacks are
6356      --  generated by the binder and allocated by SS_Init. To provide the
6357      --  binder the number of stacks to generate, the number of default-sized
6358      --  stacks required for task objects contained within the object
6359      --  declaration N is calculated here as it is at this point where
6360      --  unconstrained types become constrained. The result is stored in the
6361      --  enclosing unit's Unit_Record.
6362
6363      --  Note if N is an array object declaration that has an initialization
6364      --  expression, a second object declaration for the initialization
6365      --  expression is created by the compiler. To prevent double counting
6366      --  of the stacks in this scenario, the stacks of the first array are
6367      --  not counted.
6368
6369      if Has_Task (Typ)
6370        and then not Restriction_Active (No_Secondary_Stack)
6371        and then (Restriction_Active (No_Implicit_Heap_Allocations)
6372          or else Restriction_Active (No_Implicit_Task_Allocations))
6373        and then not (Ekind_In (Ekind (Typ), E_Array_Type, E_Array_Subtype)
6374                      and then (Has_Init_Expression (N)))
6375      then
6376         declare
6377            PS_Count, SS_Count : Int := 0;
6378         begin
6379            Count_Default_Sized_Task_Stacks (Typ, PS_Count, SS_Count);
6380            Increment_Primary_Stack_Count (PS_Count);
6381            Increment_Sec_Stack_Count (SS_Count);
6382         end;
6383      end if;
6384
6385      --  Default initialization required, and no expression present
6386
6387      if No (Expr) then
6388
6389         --  If we have a type with a variant part, the initialization proc
6390         --  will contain implicit tests of the discriminant values, which
6391         --  counts as a violation of the restriction No_Implicit_Conditionals.
6392
6393         if Has_Variant_Part (Typ) then
6394            declare
6395               Msg : Boolean;
6396
6397            begin
6398               Check_Restriction (Msg, No_Implicit_Conditionals, Obj_Def);
6399
6400               if Msg then
6401                  Error_Msg_N
6402                    ("\initialization of variant record tests discriminants",
6403                     Obj_Def);
6404                  return;
6405               end if;
6406            end;
6407         end if;
6408
6409         --  For the default initialization case, if we have a private type
6410         --  with invariants, and invariant checks are enabled, then insert an
6411         --  invariant check after the object declaration. Note that it is OK
6412         --  to clobber the object with an invalid value since if the exception
6413         --  is raised, then the object will go out of scope. In the case where
6414         --  an array object is initialized with an aggregate, the expression
6415         --  is removed. Check flag Has_Init_Expression to avoid generating a
6416         --  junk invariant check and flag No_Initialization to avoid checking
6417         --  an uninitialized object such as a compiler temporary used for an
6418         --  aggregate.
6419
6420         if Has_Invariants (Base_Typ)
6421           and then Present (Invariant_Procedure (Base_Typ))
6422           and then not Has_Init_Expression (N)
6423           and then not No_Initialization (N)
6424         then
6425            --  If entity has an address clause or aspect, make invariant
6426            --  call into a freeze action for the explicit freeze node for
6427            --  object. Otherwise insert invariant check after declaration.
6428
6429            if Present (Following_Address_Clause (N))
6430              or else Has_Aspect (Def_Id, Aspect_Address)
6431            then
6432               Ensure_Freeze_Node (Def_Id);
6433               Set_Has_Delayed_Freeze (Def_Id);
6434               Set_Is_Frozen (Def_Id, False);
6435
6436               if not Partial_View_Has_Unknown_Discr (Typ) then
6437                  Append_Freeze_Action (Def_Id,
6438                    Make_Invariant_Call (New_Occurrence_Of (Def_Id, Loc)));
6439               end if;
6440
6441            elsif not Partial_View_Has_Unknown_Discr (Typ) then
6442               Insert_After (N,
6443                 Make_Invariant_Call (New_Occurrence_Of (Def_Id, Loc)));
6444            end if;
6445         end if;
6446
6447         Default_Initialize_Object (Init_After);
6448
6449         --  Generate attribute for Persistent_BSS if needed
6450
6451         if Persistent_BSS_Mode
6452           and then Comes_From_Source (N)
6453           and then Is_Potentially_Persistent_Type (Typ)
6454           and then not Has_Init_Expression (N)
6455           and then Is_Library_Level_Entity (Def_Id)
6456         then
6457            declare
6458               Prag : Node_Id;
6459            begin
6460               Prag :=
6461                 Make_Linker_Section_Pragma
6462                   (Def_Id, Sloc (N), ".persistent.bss");
6463               Insert_After (N, Prag);
6464               Analyze (Prag);
6465            end;
6466         end if;
6467
6468         --  If access type, then we know it is null if not initialized
6469
6470         if Is_Access_Type (Typ) then
6471            Set_Is_Known_Null (Def_Id);
6472         end if;
6473
6474      --  Explicit initialization present
6475
6476      else
6477         --  Obtain actual expression from qualified expression
6478
6479         if Nkind (Expr) = N_Qualified_Expression then
6480            Expr_Q := Expression (Expr);
6481         else
6482            Expr_Q := Expr;
6483         end if;
6484
6485         --  When we have the appropriate type of aggregate in the expression
6486         --  (it has been determined during analysis of the aggregate by
6487         --  setting the delay flag), let's perform in place assignment and
6488         --  thus avoid creating a temporary.
6489
6490         if Is_Delayed_Aggregate (Expr_Q) then
6491            Convert_Aggr_In_Object_Decl (N);
6492
6493         --  Ada 2005 (AI-318-02): If the initialization expression is a call
6494         --  to a build-in-place function, then access to the declared object
6495         --  must be passed to the function. Currently we limit such functions
6496         --  to those with constrained limited result subtypes, but eventually
6497         --  plan to expand the allowed forms of functions that are treated as
6498         --  build-in-place.
6499
6500         elsif Is_Build_In_Place_Function_Call (Expr_Q) then
6501            Make_Build_In_Place_Call_In_Object_Declaration (N, Expr_Q);
6502
6503            --  The previous call expands the expression initializing the
6504            --  built-in-place object into further code that will be analyzed
6505            --  later. No further expansion needed here.
6506
6507            return;
6508
6509         --  This is the same as the previous 'elsif', except that the call has
6510         --  been transformed by other expansion activities into something like
6511         --  F(...)'Reference.
6512
6513         elsif Nkind (Expr_Q) = N_Reference
6514           and then Is_Build_In_Place_Function_Call (Prefix (Expr_Q))
6515           and then not Is_Expanded_Build_In_Place_Call
6516                          (Unqual_Conv (Prefix (Expr_Q)))
6517         then
6518            Make_Build_In_Place_Call_In_Anonymous_Context (Prefix (Expr_Q));
6519
6520            --  The previous call expands the expression initializing the
6521            --  built-in-place object into further code that will be analyzed
6522            --  later. No further expansion needed here.
6523
6524            return;
6525
6526         --  Ada 2005 (AI-318-02): Specialization of the previous case for
6527         --  expressions containing a build-in-place function call whose
6528         --  returned object covers interface types, and Expr_Q has calls to
6529         --  Ada.Tags.Displace to displace the pointer to the returned build-
6530         --  in-place object to reference the secondary dispatch table of a
6531         --  covered interface type.
6532
6533         elsif Present (Unqual_BIP_Iface_Function_Call (Expr_Q)) then
6534            Make_Build_In_Place_Iface_Call_In_Object_Declaration (N, Expr_Q);
6535
6536            --  The previous call expands the expression initializing the
6537            --  built-in-place object into further code that will be analyzed
6538            --  later. No further expansion needed here.
6539
6540            return;
6541
6542         --  Ada 2005 (AI-251): Rewrite the expression that initializes a
6543         --  class-wide interface object to ensure that we copy the full
6544         --  object, unless we are targetting a VM where interfaces are handled
6545         --  by VM itself. Note that if the root type of Typ is an ancestor of
6546         --  Expr's type, both types share the same dispatch table and there is
6547         --  no need to displace the pointer.
6548
6549         elsif Is_Interface (Typ)
6550
6551           --  Avoid never-ending recursion because if Equivalent_Type is set
6552           --  then we've done it already and must not do it again.
6553
6554           and then not
6555             (Nkind (Obj_Def) = N_Identifier
6556               and then Present (Equivalent_Type (Entity (Obj_Def))))
6557         then
6558            pragma Assert (Is_Class_Wide_Type (Typ));
6559
6560            --  If the object is a return object of an inherently limited type,
6561            --  which implies build-in-place treatment, bypass the special
6562            --  treatment of class-wide interface initialization below. In this
6563            --  case, the expansion of the return statement will take care of
6564            --  creating the object (via allocator) and initializing it.
6565
6566            if Is_Return_Object (Def_Id) and then Is_Limited_View (Typ) then
6567               null;
6568
6569            elsif Tagged_Type_Expansion then
6570               declare
6571                  Iface    : constant Entity_Id := Root_Type (Typ);
6572                  Expr_N   : Node_Id := Expr;
6573                  Expr_Typ : Entity_Id;
6574                  New_Expr : Node_Id;
6575                  Obj_Id   : Entity_Id;
6576                  Tag_Comp : Node_Id;
6577
6578               begin
6579                  --  If the original node of the expression was a conversion
6580                  --  to this specific class-wide interface type then restore
6581                  --  the original node because we must copy the object before
6582                  --  displacing the pointer to reference the secondary tag
6583                  --  component. This code must be kept synchronized with the
6584                  --  expansion done by routine Expand_Interface_Conversion
6585
6586                  if not Comes_From_Source (Expr_N)
6587                    and then Nkind (Expr_N) = N_Explicit_Dereference
6588                    and then Nkind (Original_Node (Expr_N)) = N_Type_Conversion
6589                    and then Etype (Original_Node (Expr_N)) = Typ
6590                  then
6591                     Rewrite (Expr_N, Original_Node (Expression (N)));
6592                  end if;
6593
6594                  --  Avoid expansion of redundant interface conversion
6595
6596                  if Is_Interface (Etype (Expr_N))
6597                    and then Nkind (Expr_N) = N_Type_Conversion
6598                    and then Etype (Expr_N) = Typ
6599                  then
6600                     Expr_N := Expression (Expr_N);
6601                     Set_Expression (N, Expr_N);
6602                  end if;
6603
6604                  Obj_Id   := Make_Temporary (Loc, 'D', Expr_N);
6605                  Expr_Typ := Base_Type (Etype (Expr_N));
6606
6607                  if Is_Class_Wide_Type (Expr_Typ) then
6608                     Expr_Typ := Root_Type (Expr_Typ);
6609                  end if;
6610
6611                  --  Replace
6612                  --     CW : I'Class := Obj;
6613                  --  by
6614                  --     Tmp : T := Obj;
6615                  --     type Ityp is not null access I'Class;
6616                  --     CW  : I'Class renames Ityp (Tmp.I_Tag'Address).all;
6617
6618                  if Comes_From_Source (Expr_N)
6619                    and then Nkind (Expr_N) = N_Identifier
6620                    and then not Is_Interface (Expr_Typ)
6621                    and then Interface_Present_In_Ancestor (Expr_Typ, Typ)
6622                    and then (Expr_Typ = Etype (Expr_Typ)
6623                               or else not
6624                                 Is_Variable_Size_Record (Etype (Expr_Typ)))
6625                  then
6626                     --  Copy the object
6627
6628                     Insert_Action (N,
6629                       Make_Object_Declaration (Loc,
6630                         Defining_Identifier => Obj_Id,
6631                         Object_Definition   =>
6632                           New_Occurrence_Of (Expr_Typ, Loc),
6633                         Expression          => Relocate_Node (Expr_N)));
6634
6635                     --  Statically reference the tag associated with the
6636                     --  interface
6637
6638                     Tag_Comp :=
6639                       Make_Selected_Component (Loc,
6640                         Prefix        => New_Occurrence_Of (Obj_Id, Loc),
6641                         Selector_Name =>
6642                           New_Occurrence_Of
6643                             (Find_Interface_Tag (Expr_Typ, Iface), Loc));
6644
6645                  --  Replace
6646                  --     IW : I'Class := Obj;
6647                  --  by
6648                  --     type Equiv_Record is record ... end record;
6649                  --     implicit subtype CW is <Class_Wide_Subtype>;
6650                  --     Tmp : CW := CW!(Obj);
6651                  --     type Ityp is not null access I'Class;
6652                  --     IW : I'Class renames
6653                  --            Ityp!(Displace (Temp'Address, I'Tag)).all;
6654
6655                  else
6656                     --  Generate the equivalent record type and update the
6657                     --  subtype indication to reference it.
6658
6659                     Expand_Subtype_From_Expr
6660                       (N             => N,
6661                        Unc_Type      => Typ,
6662                        Subtype_Indic => Obj_Def,
6663                        Exp           => Expr_N);
6664
6665                     if not Is_Interface (Etype (Expr_N)) then
6666                        New_Expr := Relocate_Node (Expr_N);
6667
6668                     --  For interface types we use 'Address which displaces
6669                     --  the pointer to the base of the object (if required)
6670
6671                     else
6672                        New_Expr :=
6673                          Unchecked_Convert_To (Etype (Obj_Def),
6674                            Make_Explicit_Dereference (Loc,
6675                              Unchecked_Convert_To (RTE (RE_Tag_Ptr),
6676                                Make_Attribute_Reference (Loc,
6677                                  Prefix => Relocate_Node (Expr_N),
6678                                  Attribute_Name => Name_Address))));
6679                     end if;
6680
6681                     --  Copy the object
6682
6683                     if not Is_Limited_Record (Expr_Typ) then
6684                        Insert_Action (N,
6685                          Make_Object_Declaration (Loc,
6686                            Defining_Identifier => Obj_Id,
6687                            Object_Definition   =>
6688                              New_Occurrence_Of (Etype (Obj_Def), Loc),
6689                            Expression => New_Expr));
6690
6691                     --  Rename limited type object since they cannot be copied
6692                     --  This case occurs when the initialization expression
6693                     --  has been previously expanded into a temporary object.
6694
6695                     else pragma Assert (not Comes_From_Source (Expr_Q));
6696                        Insert_Action (N,
6697                          Make_Object_Renaming_Declaration (Loc,
6698                            Defining_Identifier => Obj_Id,
6699                            Subtype_Mark        =>
6700                              New_Occurrence_Of (Etype (Obj_Def), Loc),
6701                            Name                =>
6702                              Unchecked_Convert_To
6703                                (Etype (Obj_Def), New_Expr)));
6704                     end if;
6705
6706                     --  Dynamically reference the tag associated with the
6707                     --  interface.
6708
6709                     Tag_Comp :=
6710                       Make_Function_Call (Loc,
6711                         Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
6712                         Parameter_Associations => New_List (
6713                           Make_Attribute_Reference (Loc,
6714                             Prefix => New_Occurrence_Of (Obj_Id, Loc),
6715                             Attribute_Name => Name_Address),
6716                           New_Occurrence_Of
6717                             (Node (First_Elmt (Access_Disp_Table (Iface))),
6718                              Loc)));
6719                  end if;
6720
6721                  Rewrite (N,
6722                    Make_Object_Renaming_Declaration (Loc,
6723                      Defining_Identifier => Make_Temporary (Loc, 'D'),
6724                      Subtype_Mark        => New_Occurrence_Of (Typ, Loc),
6725                      Name                =>
6726                        Convert_Tag_To_Interface (Typ, Tag_Comp)));
6727
6728                  --  If the original entity comes from source, then mark the
6729                  --  new entity as needing debug information, even though it's
6730                  --  defined by a generated renaming that does not come from
6731                  --  source, so that Materialize_Entity will be set on the
6732                  --  entity when Debug_Renaming_Declaration is called during
6733                  --  analysis.
6734
6735                  if Comes_From_Source (Def_Id) then
6736                     Set_Debug_Info_Needed (Defining_Identifier (N));
6737                  end if;
6738
6739                  Analyze (N, Suppress => All_Checks);
6740
6741                  --  Replace internal identifier of rewritten node by the
6742                  --  identifier found in the sources. We also have to exchange
6743                  --  entities containing their defining identifiers to ensure
6744                  --  the correct replacement of the object declaration by this
6745                  --  object renaming declaration because these identifiers
6746                  --  were previously added by Enter_Name to the current scope.
6747                  --  We must preserve the homonym chain of the source entity
6748                  --  as well. We must also preserve the kind of the entity,
6749                  --  which may be a constant. Preserve entity chain because
6750                  --  itypes may have been generated already, and the full
6751                  --  chain must be preserved for final freezing. Finally,
6752                  --  preserve Comes_From_Source setting, so that debugging
6753                  --  and cross-referencing information is properly kept, and
6754                  --  preserve source location, to prevent spurious errors when
6755                  --  entities are declared (they must have their own Sloc).
6756
6757                  declare
6758                     New_Id    : constant Entity_Id := Defining_Identifier (N);
6759                     Next_Temp : constant Entity_Id := Next_Entity (New_Id);
6760                     Save_CFS  : constant Boolean   :=
6761                                   Comes_From_Source (Def_Id);
6762                     Save_SP   : constant Node_Id   := SPARK_Pragma (Def_Id);
6763                     Save_SPI  : constant Boolean   :=
6764                                   SPARK_Pragma_Inherited (Def_Id);
6765
6766                  begin
6767                     Set_Next_Entity (New_Id, Next_Entity (Def_Id));
6768                     Set_Next_Entity (Def_Id, Next_Temp);
6769
6770                     Set_Chars   (Defining_Identifier (N), Chars   (Def_Id));
6771                     Set_Homonym (Defining_Identifier (N), Homonym (Def_Id));
6772                     Set_Ekind   (Defining_Identifier (N), Ekind   (Def_Id));
6773                     Set_Sloc    (Defining_Identifier (N), Sloc    (Def_Id));
6774
6775                     Set_Comes_From_Source (Def_Id, False);
6776
6777                     --  ??? This is extremely dangerous!!! Exchanging entities
6778                     --  is very low level, and as a result it resets flags and
6779                     --  fields which belong to the original Def_Id. Several of
6780                     --  these attributes are saved and restored, but there may
6781                     --  be many more that need to be preserverd.
6782
6783                     Exchange_Entities (Defining_Identifier (N), Def_Id);
6784
6785                     --  Restore clobbered attributes
6786
6787                     Set_Comes_From_Source      (Def_Id, Save_CFS);
6788                     Set_SPARK_Pragma           (Def_Id, Save_SP);
6789                     Set_SPARK_Pragma_Inherited (Def_Id, Save_SPI);
6790                  end;
6791               end;
6792            end if;
6793
6794            return;
6795
6796         --  Common case of explicit object initialization
6797
6798         else
6799            --  In most cases, we must check that the initial value meets any
6800            --  constraint imposed by the declared type. However, there is one
6801            --  very important exception to this rule. If the entity has an
6802            --  unconstrained nominal subtype, then it acquired its constraints
6803            --  from the expression in the first place, and not only does this
6804            --  mean that the constraint check is not needed, but an attempt to
6805            --  perform the constraint check can cause order of elaboration
6806            --  problems.
6807
6808            if not Is_Constr_Subt_For_U_Nominal (Typ) then
6809
6810               --  If this is an allocator for an aggregate that has been
6811               --  allocated in place, delay checks until assignments are
6812               --  made, because the discriminants are not initialized.
6813
6814               if Nkind (Expr) = N_Allocator
6815                 and then No_Initialization (Expr)
6816               then
6817                  null;
6818
6819               --  Otherwise apply a constraint check now if no prev error
6820
6821               elsif Nkind (Expr) /= N_Error then
6822                  Apply_Constraint_Check (Expr, Typ);
6823
6824                  --  Deal with possible range check
6825
6826                  if Do_Range_Check (Expr) then
6827
6828                     --  If assignment checks are suppressed, turn off flag
6829
6830                     if Suppress_Assignment_Checks (N) then
6831                        Set_Do_Range_Check (Expr, False);
6832
6833                     --  Otherwise generate the range check
6834
6835                     else
6836                        Generate_Range_Check
6837                          (Expr, Typ, CE_Range_Check_Failed);
6838                     end if;
6839                  end if;
6840               end if;
6841            end if;
6842
6843            --  If the type is controlled and not inherently limited, then
6844            --  the target is adjusted after the copy and attached to the
6845            --  finalization list. However, no adjustment is done in the case
6846            --  where the object was initialized by a call to a function whose
6847            --  result is built in place, since no copy occurred. Similarly, no
6848            --  adjustment is required if we are going to rewrite the object
6849            --  declaration into a renaming declaration.
6850
6851            if Needs_Finalization (Typ)
6852              and then not Is_Limited_View (Typ)
6853              and then not Rewrite_As_Renaming
6854            then
6855               Adj_Call :=
6856                 Make_Adjust_Call (
6857                   Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
6858                   Typ     => Base_Typ);
6859
6860               --  Guard against a missing [Deep_]Adjust when the base type
6861               --  was not properly frozen.
6862
6863               if Present (Adj_Call) then
6864                  Insert_Action_After (Init_After, Adj_Call);
6865               end if;
6866            end if;
6867
6868            --  For tagged types, when an init value is given, the tag has to
6869            --  be re-initialized separately in order to avoid the propagation
6870            --  of a wrong tag coming from a view conversion unless the type
6871            --  is class wide (in this case the tag comes from the init value).
6872            --  Suppress the tag assignment when not Tagged_Type_Expansion
6873            --  because tags are represented implicitly in objects. Ditto for
6874            --  types that are CPP_CLASS, and for initializations that are
6875            --  aggregates, because they have to have the right tag.
6876
6877            --  The re-assignment of the tag has to be done even if the object
6878            --  is a constant. The assignment must be analyzed after the
6879            --  declaration. If an address clause follows, this is handled as
6880            --  part of the freeze actions for the object, otherwise insert
6881            --  tag assignment here.
6882
6883            Tag_Assign := Make_Tag_Assignment (N);
6884
6885            if Present (Tag_Assign) then
6886               if Present (Following_Address_Clause (N)) then
6887                  Ensure_Freeze_Node (Def_Id);
6888
6889               else
6890                  Insert_Action_After (Init_After, Tag_Assign);
6891               end if;
6892
6893            --  Handle C++ constructor calls. Note that we do not check that
6894            --  Typ is a tagged type since the equivalent Ada type of a C++
6895            --  class that has no virtual methods is an untagged limited
6896            --  record type.
6897
6898            elsif Is_CPP_Constructor_Call (Expr) then
6899
6900               --  The call to the initialization procedure does NOT freeze the
6901               --  object being initialized.
6902
6903               Id_Ref := New_Occurrence_Of (Def_Id, Loc);
6904               Set_Must_Not_Freeze (Id_Ref);
6905               Set_Assignment_OK (Id_Ref);
6906
6907               Insert_Actions_After (Init_After,
6908                 Build_Initialization_Call (Loc, Id_Ref, Typ,
6909                   Constructor_Ref => Expr));
6910
6911               --  We remove here the original call to the constructor
6912               --  to avoid its management in the backend
6913
6914               Set_Expression (N, Empty);
6915               return;
6916
6917            --  Handle initialization of limited tagged types
6918
6919            elsif Is_Tagged_Type (Typ)
6920              and then Is_Class_Wide_Type (Typ)
6921              and then Is_Limited_Record (Typ)
6922              and then not Is_Limited_Interface (Typ)
6923            then
6924               --  Given that the type is limited we cannot perform a copy. If
6925               --  Expr_Q is the reference to a variable we mark the variable
6926               --  as OK_To_Rename to expand this declaration into a renaming
6927               --  declaration (see bellow).
6928
6929               if Is_Entity_Name (Expr_Q) then
6930                  Set_OK_To_Rename (Entity (Expr_Q));
6931
6932               --  If we cannot convert the expression into a renaming we must
6933               --  consider it an internal error because the backend does not
6934               --  have support to handle it.
6935
6936               else
6937                  pragma Assert (False);
6938                  raise Program_Error;
6939               end if;
6940
6941            --  For discrete types, set the Is_Known_Valid flag if the
6942            --  initializing value is known to be valid. Only do this for
6943            --  source assignments, since otherwise we can end up turning
6944            --  on the known valid flag prematurely from inserted code.
6945
6946            elsif Comes_From_Source (N)
6947              and then Is_Discrete_Type (Typ)
6948              and then Expr_Known_Valid (Expr)
6949            then
6950               Set_Is_Known_Valid (Def_Id);
6951
6952            elsif Is_Access_Type (Typ) then
6953
6954               --  For access types set the Is_Known_Non_Null flag if the
6955               --  initializing value is known to be non-null. We can also set
6956               --  Can_Never_Be_Null if this is a constant.
6957
6958               if Known_Non_Null (Expr) then
6959                  Set_Is_Known_Non_Null (Def_Id, True);
6960
6961                  if Constant_Present (N) then
6962                     Set_Can_Never_Be_Null (Def_Id);
6963                  end if;
6964               end if;
6965            end if;
6966
6967            --  If validity checking on copies, validate initial expression.
6968            --  But skip this if declaration is for a generic type, since it
6969            --  makes no sense to validate generic types. Not clear if this
6970            --  can happen for legal programs, but it definitely can arise
6971            --  from previous instantiation errors.
6972
6973            if Validity_Checks_On
6974              and then Comes_From_Source (N)
6975              and then Validity_Check_Copies
6976              and then not Is_Generic_Type (Etype (Def_Id))
6977            then
6978               Ensure_Valid (Expr);
6979               Set_Is_Known_Valid (Def_Id);
6980            end if;
6981         end if;
6982
6983         --  Cases where the back end cannot handle the initialization
6984         --  directly. In such cases, we expand an assignment that will
6985         --  be appropriately handled by Expand_N_Assignment_Statement.
6986
6987         --  The exclusion of the unconstrained case is wrong, but for now it
6988         --  is too much trouble ???
6989
6990         if (Is_Possibly_Unaligned_Slice (Expr)
6991              or else (Is_Possibly_Unaligned_Object (Expr)
6992                        and then not Represented_As_Scalar (Etype (Expr))))
6993           and then not (Is_Array_Type (Etype (Expr))
6994                          and then not Is_Constrained (Etype (Expr)))
6995         then
6996            declare
6997               Stat : constant Node_Id :=
6998                       Make_Assignment_Statement (Loc,
6999                         Name       => New_Occurrence_Of (Def_Id, Loc),
7000                         Expression => Relocate_Node (Expr));
7001            begin
7002               Set_Expression (N, Empty);
7003               Set_No_Initialization (N);
7004               Set_Assignment_OK (Name (Stat));
7005               Set_No_Ctrl_Actions (Stat);
7006               Insert_After_And_Analyze (Init_After, Stat);
7007            end;
7008         end if;
7009      end if;
7010
7011      if Nkind (Obj_Def) = N_Access_Definition
7012        and then not Is_Local_Anonymous_Access (Etype (Def_Id))
7013      then
7014         --  An Ada 2012 stand-alone object of an anonymous access type
7015
7016         declare
7017            Loc : constant Source_Ptr := Sloc (N);
7018
7019            Level : constant Entity_Id :=
7020                      Make_Defining_Identifier (Sloc (N),
7021                        Chars =>
7022                          New_External_Name (Chars (Def_Id), Suffix => "L"));
7023
7024            Level_Expr : Node_Id;
7025            Level_Decl : Node_Id;
7026
7027         begin
7028            Set_Ekind (Level, Ekind (Def_Id));
7029            Set_Etype (Level, Standard_Natural);
7030            Set_Scope (Level, Scope (Def_Id));
7031
7032            if No (Expr) then
7033
7034               --  Set accessibility level of null
7035
7036               Level_Expr :=
7037                 Make_Integer_Literal (Loc, Scope_Depth (Standard_Standard));
7038
7039            else
7040               Level_Expr := Dynamic_Accessibility_Level (Expr);
7041            end if;
7042
7043            Level_Decl :=
7044              Make_Object_Declaration (Loc,
7045                Defining_Identifier => Level,
7046                Object_Definition   =>
7047                  New_Occurrence_Of (Standard_Natural, Loc),
7048                Expression          => Level_Expr,
7049                Constant_Present    => Constant_Present (N),
7050                Has_Init_Expression => True);
7051
7052            Insert_Action_After (Init_After, Level_Decl);
7053
7054            Set_Extra_Accessibility (Def_Id, Level);
7055         end;
7056      end if;
7057
7058      --  If the object is default initialized and its type is subject to
7059      --  pragma Default_Initial_Condition, add a runtime check to verify
7060      --  the assumption of the pragma (SPARK RM 7.3.3). Generate:
7061
7062      --    <Base_Typ>DIC (<Base_Typ> (Def_Id));
7063
7064      --  Note that the check is generated for source objects only
7065
7066      if Comes_From_Source (Def_Id)
7067        and then Has_DIC (Typ)
7068        and then Present (DIC_Procedure (Typ))
7069        and then not Has_Init_Expression (N)
7070      then
7071         declare
7072            DIC_Call : constant Node_Id := Build_DIC_Call (Loc, Def_Id, Typ);
7073
7074         begin
7075            if Present (Next_N) then
7076               Insert_Before_And_Analyze (Next_N, DIC_Call);
7077
7078            --  The object declaration is the last node in a declarative or a
7079            --  statement list.
7080
7081            else
7082               Append_To (List_Containing (N), DIC_Call);
7083               Analyze (DIC_Call);
7084            end if;
7085         end;
7086      end if;
7087
7088      --  Final transformation - turn the object declaration into a renaming
7089      --  if appropriate. If this is the completion of a deferred constant
7090      --  declaration, then this transformation generates what would be
7091      --  illegal code if written by hand, but that's OK.
7092
7093      if Present (Expr) then
7094         if Rewrite_As_Renaming then
7095            Rewrite (N,
7096              Make_Object_Renaming_Declaration (Loc,
7097                Defining_Identifier => Defining_Identifier (N),
7098                Subtype_Mark        => Obj_Def,
7099                Name                => Expr_Q));
7100
7101            --  We do not analyze this renaming declaration, because all its
7102            --  components have already been analyzed, and if we were to go
7103            --  ahead and analyze it, we would in effect be trying to generate
7104            --  another declaration of X, which won't do.
7105
7106            Set_Renamed_Object (Defining_Identifier (N), Expr_Q);
7107            Set_Analyzed (N);
7108
7109            --  We do need to deal with debug issues for this renaming
7110
7111            --  First, if entity comes from source, then mark it as needing
7112            --  debug information, even though it is defined by a generated
7113            --  renaming that does not come from source.
7114
7115            if Comes_From_Source (Defining_Identifier (N)) then
7116               Set_Debug_Info_Needed (Defining_Identifier (N));
7117            end if;
7118
7119            --  Now call the routine to generate debug info for the renaming
7120
7121            declare
7122               Decl : constant Node_Id := Debug_Renaming_Declaration (N);
7123            begin
7124               if Present (Decl) then
7125                  Insert_Action (N, Decl);
7126               end if;
7127            end;
7128         end if;
7129      end if;
7130
7131   --  Exception on library entity not available
7132
7133   exception
7134      when RE_Not_Available =>
7135         return;
7136   end Expand_N_Object_Declaration;
7137
7138   ---------------------------------
7139   -- Expand_N_Subtype_Indication --
7140   ---------------------------------
7141
7142   --  Add a check on the range of the subtype. The static case is partially
7143   --  duplicated by Process_Range_Expr_In_Decl in Sem_Ch3, but we still need
7144   --  to check here for the static case in order to avoid generating
7145   --  extraneous expanded code. Also deal with validity checking.
7146
7147   procedure Expand_N_Subtype_Indication (N : Node_Id) is
7148      Ran : constant Node_Id   := Range_Expression (Constraint (N));
7149      Typ : constant Entity_Id := Entity (Subtype_Mark (N));
7150
7151   begin
7152      if Nkind (Constraint (N)) = N_Range_Constraint then
7153         Validity_Check_Range (Range_Expression (Constraint (N)));
7154      end if;
7155
7156      if Nkind_In (Parent (N), N_Constrained_Array_Definition, N_Slice) then
7157         Apply_Range_Check (Ran, Typ);
7158      end if;
7159   end Expand_N_Subtype_Indication;
7160
7161   ---------------------------
7162   -- Expand_N_Variant_Part --
7163   ---------------------------
7164
7165   --  Note: this procedure no longer has any effect. It used to be that we
7166   --  would replace the choices in the last variant by a when others, and
7167   --  also expanded static predicates in variant choices here, but both of
7168   --  those activities were being done too early, since we can't check the
7169   --  choices until the statically predicated subtypes are frozen, which can
7170   --  happen as late as the free point of the record, and we can't change the
7171   --  last choice to an others before checking the choices, which is now done
7172   --  at the freeze point of the record.
7173
7174   procedure Expand_N_Variant_Part (N : Node_Id) is
7175   begin
7176      null;
7177   end Expand_N_Variant_Part;
7178
7179   ---------------------------------
7180   -- Expand_Previous_Access_Type --
7181   ---------------------------------
7182
7183   procedure Expand_Previous_Access_Type (Def_Id : Entity_Id) is
7184      Ptr_Typ : Entity_Id;
7185
7186   begin
7187      --  Find all access types in the current scope whose designated type is
7188      --  Def_Id and build master renamings for them.
7189
7190      Ptr_Typ := First_Entity (Current_Scope);
7191      while Present (Ptr_Typ) loop
7192         if Is_Access_Type (Ptr_Typ)
7193           and then Designated_Type (Ptr_Typ) = Def_Id
7194           and then No (Master_Id (Ptr_Typ))
7195         then
7196            --  Ensure that the designated type has a master
7197
7198            Build_Master_Entity (Def_Id);
7199
7200            --  Private and incomplete types complicate the insertion of master
7201            --  renamings because the access type may precede the full view of
7202            --  the designated type. For this reason, the master renamings are
7203            --  inserted relative to the designated type.
7204
7205            Build_Master_Renaming (Ptr_Typ, Ins_Nod => Parent (Def_Id));
7206         end if;
7207
7208         Next_Entity (Ptr_Typ);
7209      end loop;
7210   end Expand_Previous_Access_Type;
7211
7212   -----------------------------
7213   -- Expand_Record_Extension --
7214   -----------------------------
7215
7216   --  Add a field _parent at the beginning of the record extension. This is
7217   --  used to implement inheritance. Here are some examples of expansion:
7218
7219   --  1. no discriminants
7220   --      type T2 is new T1 with null record;
7221   --   gives
7222   --      type T2 is new T1 with record
7223   --        _Parent : T1;
7224   --      end record;
7225
7226   --  2. renamed discriminants
7227   --    type T2 (B, C : Int) is new T1 (A => B) with record
7228   --       _Parent : T1 (A => B);
7229   --       D : Int;
7230   --    end;
7231
7232   --  3. inherited discriminants
7233   --    type T2 is new T1 with record -- discriminant A inherited
7234   --       _Parent : T1 (A);
7235   --       D : Int;
7236   --    end;
7237
7238   procedure Expand_Record_Extension (T : Entity_Id; Def : Node_Id) is
7239      Indic        : constant Node_Id    := Subtype_Indication (Def);
7240      Loc          : constant Source_Ptr := Sloc (Def);
7241      Rec_Ext_Part : Node_Id             := Record_Extension_Part (Def);
7242      Par_Subtype  : Entity_Id;
7243      Comp_List    : Node_Id;
7244      Comp_Decl    : Node_Id;
7245      Parent_N     : Node_Id;
7246      D            : Entity_Id;
7247      List_Constr  : constant List_Id    := New_List;
7248
7249   begin
7250      --  Expand_Record_Extension is called directly from the semantics, so
7251      --  we must check to see whether expansion is active before proceeding,
7252      --  because this affects the visibility of selected components in bodies
7253      --  of instances.
7254
7255      if not Expander_Active then
7256         return;
7257      end if;
7258
7259      --  This may be a derivation of an untagged private type whose full
7260      --  view is tagged, in which case the Derived_Type_Definition has no
7261      --  extension part. Build an empty one now.
7262
7263      if No (Rec_Ext_Part) then
7264         Rec_Ext_Part :=
7265           Make_Record_Definition (Loc,
7266             End_Label      => Empty,
7267             Component_List => Empty,
7268             Null_Present   => True);
7269
7270         Set_Record_Extension_Part (Def, Rec_Ext_Part);
7271         Mark_Rewrite_Insertion (Rec_Ext_Part);
7272      end if;
7273
7274      Comp_List := Component_List (Rec_Ext_Part);
7275
7276      Parent_N := Make_Defining_Identifier (Loc, Name_uParent);
7277
7278      --  If the derived type inherits its discriminants the type of the
7279      --  _parent field must be constrained by the inherited discriminants
7280
7281      if Has_Discriminants (T)
7282        and then Nkind (Indic) /= N_Subtype_Indication
7283        and then not Is_Constrained (Entity (Indic))
7284      then
7285         D := First_Discriminant (T);
7286         while Present (D) loop
7287            Append_To (List_Constr, New_Occurrence_Of (D, Loc));
7288            Next_Discriminant (D);
7289         end loop;
7290
7291         Par_Subtype :=
7292           Process_Subtype (
7293             Make_Subtype_Indication (Loc,
7294               Subtype_Mark => New_Occurrence_Of (Entity (Indic), Loc),
7295               Constraint   =>
7296                 Make_Index_Or_Discriminant_Constraint (Loc,
7297                   Constraints => List_Constr)),
7298             Def);
7299
7300      --  Otherwise the original subtype_indication is just what is needed
7301
7302      else
7303         Par_Subtype := Process_Subtype (New_Copy_Tree (Indic), Def);
7304      end if;
7305
7306      Set_Parent_Subtype (T, Par_Subtype);
7307
7308      Comp_Decl :=
7309        Make_Component_Declaration (Loc,
7310          Defining_Identifier => Parent_N,
7311          Component_Definition =>
7312            Make_Component_Definition (Loc,
7313              Aliased_Present => False,
7314              Subtype_Indication => New_Occurrence_Of (Par_Subtype, Loc)));
7315
7316      if Null_Present (Rec_Ext_Part) then
7317         Set_Component_List (Rec_Ext_Part,
7318           Make_Component_List (Loc,
7319             Component_Items => New_List (Comp_Decl),
7320             Variant_Part => Empty,
7321             Null_Present => False));
7322         Set_Null_Present (Rec_Ext_Part, False);
7323
7324      elsif Null_Present (Comp_List)
7325        or else Is_Empty_List (Component_Items (Comp_List))
7326      then
7327         Set_Component_Items (Comp_List, New_List (Comp_Decl));
7328         Set_Null_Present (Comp_List, False);
7329
7330      else
7331         Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
7332      end if;
7333
7334      Analyze (Comp_Decl);
7335   end Expand_Record_Extension;
7336
7337   ------------------------
7338   -- Expand_Tagged_Root --
7339   ------------------------
7340
7341   procedure Expand_Tagged_Root (T : Entity_Id) is
7342      Def       : constant Node_Id := Type_Definition (Parent (T));
7343      Comp_List : Node_Id;
7344      Comp_Decl : Node_Id;
7345      Sloc_N    : Source_Ptr;
7346
7347   begin
7348      if Null_Present (Def) then
7349         Set_Component_List (Def,
7350           Make_Component_List (Sloc (Def),
7351             Component_Items => Empty_List,
7352             Variant_Part => Empty,
7353             Null_Present => True));
7354      end if;
7355
7356      Comp_List := Component_List (Def);
7357
7358      if Null_Present (Comp_List)
7359        or else Is_Empty_List (Component_Items (Comp_List))
7360      then
7361         Sloc_N := Sloc (Comp_List);
7362      else
7363         Sloc_N := Sloc (First (Component_Items (Comp_List)));
7364      end if;
7365
7366      Comp_Decl :=
7367        Make_Component_Declaration (Sloc_N,
7368          Defining_Identifier => First_Tag_Component (T),
7369          Component_Definition =>
7370            Make_Component_Definition (Sloc_N,
7371              Aliased_Present => False,
7372              Subtype_Indication => New_Occurrence_Of (RTE (RE_Tag), Sloc_N)));
7373
7374      if Null_Present (Comp_List)
7375        or else Is_Empty_List (Component_Items (Comp_List))
7376      then
7377         Set_Component_Items (Comp_List, New_List (Comp_Decl));
7378         Set_Null_Present (Comp_List, False);
7379
7380      else
7381         Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
7382      end if;
7383
7384      --  We don't Analyze the whole expansion because the tag component has
7385      --  already been analyzed previously. Here we just insure that the tree
7386      --  is coherent with the semantic decoration
7387
7388      Find_Type (Subtype_Indication (Component_Definition (Comp_Decl)));
7389
7390   exception
7391      when RE_Not_Available =>
7392         return;
7393   end Expand_Tagged_Root;
7394
7395   ------------------------------
7396   -- Freeze_Stream_Operations --
7397   ------------------------------
7398
7399   procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id) is
7400      Names     : constant array (1 .. 4) of TSS_Name_Type :=
7401                    (TSS_Stream_Input,
7402                     TSS_Stream_Output,
7403                     TSS_Stream_Read,
7404                     TSS_Stream_Write);
7405      Stream_Op : Entity_Id;
7406
7407   begin
7408      --  Primitive operations of tagged types are frozen when the dispatch
7409      --  table is constructed.
7410
7411      if not Comes_From_Source (Typ) or else Is_Tagged_Type (Typ) then
7412         return;
7413      end if;
7414
7415      for J in Names'Range loop
7416         Stream_Op := TSS (Typ, Names (J));
7417
7418         if Present (Stream_Op)
7419           and then Is_Subprogram (Stream_Op)
7420           and then Nkind (Unit_Declaration_Node (Stream_Op)) =
7421                                                    N_Subprogram_Declaration
7422           and then not Is_Frozen (Stream_Op)
7423         then
7424            Append_Freeze_Actions (Typ, Freeze_Entity (Stream_Op, N));
7425         end if;
7426      end loop;
7427   end Freeze_Stream_Operations;
7428
7429   -----------------
7430   -- Freeze_Type --
7431   -----------------
7432
7433   --  Full type declarations are expanded at the point at which the type is
7434   --  frozen. The formal N is the Freeze_Node for the type. Any statements or
7435   --  declarations generated by the freezing (e.g. the procedure generated
7436   --  for initialization) are chained in the Actions field list of the freeze
7437   --  node using Append_Freeze_Actions.
7438
7439   --  WARNING: This routine manages Ghost regions. Return statements must be
7440   --  replaced by gotos which jump to the end of the routine and restore the
7441   --  Ghost mode.
7442
7443   function Freeze_Type (N : Node_Id) return Boolean is
7444      procedure Process_RACW_Types (Typ : Entity_Id);
7445      --  Validate and generate stubs for all RACW types associated with type
7446      --  Typ.
7447
7448      procedure Process_Pending_Access_Types (Typ : Entity_Id);
7449      --  Associate type Typ's Finalize_Address primitive with the finalization
7450      --  masters of pending access-to-Typ types.
7451
7452      ------------------------
7453      -- Process_RACW_Types --
7454      ------------------------
7455
7456      procedure Process_RACW_Types (Typ : Entity_Id) is
7457         List : constant Elist_Id := Access_Types_To_Process (N);
7458         E    : Elmt_Id;
7459         Seen : Boolean := False;
7460
7461      begin
7462         if Present (List) then
7463            E := First_Elmt (List);
7464            while Present (E) loop
7465               if Is_Remote_Access_To_Class_Wide_Type (Node (E)) then
7466                  Validate_RACW_Primitives (Node (E));
7467                  Seen := True;
7468               end if;
7469
7470               Next_Elmt (E);
7471            end loop;
7472         end if;
7473
7474         --  If there are RACWs designating this type, make stubs now
7475
7476         if Seen then
7477            Remote_Types_Tagged_Full_View_Encountered (Typ);
7478         end if;
7479      end Process_RACW_Types;
7480
7481      ----------------------------------
7482      -- Process_Pending_Access_Types --
7483      ----------------------------------
7484
7485      procedure Process_Pending_Access_Types (Typ : Entity_Id) is
7486         E : Elmt_Id;
7487
7488      begin
7489         --  Finalize_Address is not generated in CodePeer mode because the
7490         --  body contains address arithmetic. This processing is disabled.
7491
7492         if CodePeer_Mode then
7493            null;
7494
7495         --  Certain itypes are generated for contexts that cannot allocate
7496         --  objects and should not set primitive Finalize_Address.
7497
7498         elsif Is_Itype (Typ)
7499           and then Nkind (Associated_Node_For_Itype (Typ)) =
7500                      N_Explicit_Dereference
7501         then
7502            null;
7503
7504         --  When an access type is declared after the incomplete view of a
7505         --  Taft-amendment type, the access type is considered pending in
7506         --  case the full view of the Taft-amendment type is controlled. If
7507         --  this is indeed the case, associate the Finalize_Address routine
7508         --  of the full view with the finalization masters of all pending
7509         --  access types. This scenario applies to anonymous access types as
7510         --  well.
7511
7512         elsif Needs_Finalization (Typ)
7513           and then Present (Pending_Access_Types (Typ))
7514         then
7515            E := First_Elmt (Pending_Access_Types (Typ));
7516            while Present (E) loop
7517
7518               --  Generate:
7519               --    Set_Finalize_Address
7520               --      (Ptr_Typ, <Typ>FD'Unrestricted_Access);
7521
7522               Append_Freeze_Action (Typ,
7523                 Make_Set_Finalize_Address_Call
7524                   (Loc     => Sloc (N),
7525                    Ptr_Typ => Node (E)));
7526
7527               Next_Elmt (E);
7528            end loop;
7529         end if;
7530      end Process_Pending_Access_Types;
7531
7532      --  Local variables
7533
7534      Def_Id : constant Entity_Id := Entity (N);
7535
7536      Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
7537      --  Save the Ghost mode to restore on exit
7538
7539      Result : Boolean := False;
7540
7541   --  Start of processing for Freeze_Type
7542
7543   begin
7544      --  The type being frozen may be subject to pragma Ghost. Set the mode
7545      --  now to ensure that any nodes generated during freezing are properly
7546      --  marked as Ghost.
7547
7548      Set_Ghost_Mode (Def_Id);
7549
7550      --  Process any remote access-to-class-wide types designating the type
7551      --  being frozen.
7552
7553      Process_RACW_Types (Def_Id);
7554
7555      --  Freeze processing for record types
7556
7557      if Is_Record_Type (Def_Id) then
7558         if Ekind (Def_Id) = E_Record_Type then
7559            Expand_Freeze_Record_Type (N);
7560         elsif Is_Class_Wide_Type (Def_Id) then
7561            Expand_Freeze_Class_Wide_Type (N);
7562         end if;
7563
7564      --  Freeze processing for array types
7565
7566      elsif Is_Array_Type (Def_Id) then
7567         Expand_Freeze_Array_Type (N);
7568
7569      --  Freeze processing for access types
7570
7571      --  For pool-specific access types, find out the pool object used for
7572      --  this type, needs actual expansion of it in some cases. Here are the
7573      --  different cases :
7574
7575      --  1. Rep Clause "for Def_Id'Storage_Size use 0;"
7576      --      ---> don't use any storage pool
7577
7578      --  2. Rep Clause : for Def_Id'Storage_Size use Expr.
7579      --     Expand:
7580      --      Def_Id__Pool : Stack_Bounded_Pool (Expr, DT'Size, DT'Alignment);
7581
7582      --  3. Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
7583      --      ---> Storage Pool is the specified one
7584
7585      --  See GNAT Pool packages in the Run-Time for more details
7586
7587      elsif Ekind_In (Def_Id, E_Access_Type, E_General_Access_Type) then
7588         declare
7589            Loc        : constant Source_Ptr := Sloc (N);
7590            Desig_Type : constant Entity_Id  := Designated_Type (Def_Id);
7591
7592            Freeze_Action_Typ : Entity_Id;
7593            Pool_Object       : Entity_Id;
7594
7595         begin
7596            --  Case 1
7597
7598            --    Rep Clause "for Def_Id'Storage_Size use 0;"
7599            --    ---> don't use any storage pool
7600
7601            if No_Pool_Assigned (Def_Id) then
7602               null;
7603
7604            --  Case 2
7605
7606            --    Rep Clause : for Def_Id'Storage_Size use Expr.
7607            --    ---> Expand:
7608            --           Def_Id__Pool : Stack_Bounded_Pool
7609            --                            (Expr, DT'Size, DT'Alignment);
7610
7611            elsif Has_Storage_Size_Clause (Def_Id) then
7612               declare
7613                  DT_Align : Node_Id;
7614                  DT_Size  : Node_Id;
7615
7616               begin
7617                  --  For unconstrained composite types we give a size of zero
7618                  --  so that the pool knows that it needs a special algorithm
7619                  --  for variable size object allocation.
7620
7621                  if Is_Composite_Type (Desig_Type)
7622                    and then not Is_Constrained (Desig_Type)
7623                  then
7624                     DT_Size  := Make_Integer_Literal (Loc, 0);
7625                     DT_Align := Make_Integer_Literal (Loc, Maximum_Alignment);
7626
7627                  else
7628                     DT_Size :=
7629                       Make_Attribute_Reference (Loc,
7630                         Prefix         => New_Occurrence_Of (Desig_Type, Loc),
7631                         Attribute_Name => Name_Max_Size_In_Storage_Elements);
7632
7633                     DT_Align :=
7634                       Make_Attribute_Reference (Loc,
7635                         Prefix         => New_Occurrence_Of (Desig_Type, Loc),
7636                         Attribute_Name => Name_Alignment);
7637                  end if;
7638
7639                  Pool_Object :=
7640                    Make_Defining_Identifier (Loc,
7641                      Chars => New_External_Name (Chars (Def_Id), 'P'));
7642
7643                  --  We put the code associated with the pools in the entity
7644                  --  that has the later freeze node, usually the access type
7645                  --  but it can also be the designated_type; because the pool
7646                  --  code requires both those types to be frozen
7647
7648                  if Is_Frozen (Desig_Type)
7649                    and then (No (Freeze_Node (Desig_Type))
7650                               or else Analyzed (Freeze_Node (Desig_Type)))
7651                  then
7652                     Freeze_Action_Typ := Def_Id;
7653
7654                  --  A Taft amendment type cannot get the freeze actions
7655                  --  since the full view is not there.
7656
7657                  elsif Is_Incomplete_Or_Private_Type (Desig_Type)
7658                    and then No (Full_View (Desig_Type))
7659                  then
7660                     Freeze_Action_Typ := Def_Id;
7661
7662                  else
7663                     Freeze_Action_Typ := Desig_Type;
7664                  end if;
7665
7666                  Append_Freeze_Action (Freeze_Action_Typ,
7667                    Make_Object_Declaration (Loc,
7668                      Defining_Identifier => Pool_Object,
7669                      Object_Definition   =>
7670                        Make_Subtype_Indication (Loc,
7671                          Subtype_Mark =>
7672                            New_Occurrence_Of
7673                              (RTE (RE_Stack_Bounded_Pool), Loc),
7674
7675                          Constraint   =>
7676                            Make_Index_Or_Discriminant_Constraint (Loc,
7677                              Constraints => New_List (
7678
7679                                --  First discriminant is the Pool Size
7680
7681                                New_Occurrence_Of (
7682                                  Storage_Size_Variable (Def_Id), Loc),
7683
7684                                --  Second discriminant is the element size
7685
7686                                DT_Size,
7687
7688                                --  Third discriminant is the alignment
7689
7690                                DT_Align)))));
7691               end;
7692
7693               Set_Associated_Storage_Pool (Def_Id, Pool_Object);
7694
7695            --  Case 3
7696
7697            --    Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
7698            --    ---> Storage Pool is the specified one
7699
7700            --  When compiling in Ada 2012 mode, ensure that the accessibility
7701            --  level of the subpool access type is not deeper than that of the
7702            --  pool_with_subpools.
7703
7704            elsif Ada_Version >= Ada_2012
7705              and then Present (Associated_Storage_Pool (Def_Id))
7706
7707              --  Omit this check for the case of a configurable run-time that
7708              --  does not provide package System.Storage_Pools.Subpools.
7709
7710              and then RTE_Available (RE_Root_Storage_Pool_With_Subpools)
7711            then
7712               declare
7713                  Loc   : constant Source_Ptr := Sloc (Def_Id);
7714                  Pool  : constant Entity_Id :=
7715                            Associated_Storage_Pool (Def_Id);
7716                  RSPWS : constant Entity_Id :=
7717                            RTE (RE_Root_Storage_Pool_With_Subpools);
7718
7719               begin
7720                  --  It is known that the accessibility level of the access
7721                  --  type is deeper than that of the pool.
7722
7723                  if Type_Access_Level (Def_Id) > Object_Access_Level (Pool)
7724                    and then not Accessibility_Checks_Suppressed (Def_Id)
7725                    and then not Accessibility_Checks_Suppressed (Pool)
7726                  then
7727                     --  Static case: the pool is known to be a descendant of
7728                     --  Root_Storage_Pool_With_Subpools.
7729
7730                     if Is_Ancestor (RSPWS, Etype (Pool)) then
7731                        Error_Msg_N
7732                          ("??subpool access type has deeper accessibility "
7733                           & "level than pool", Def_Id);
7734
7735                        Append_Freeze_Action (Def_Id,
7736                          Make_Raise_Program_Error (Loc,
7737                            Reason => PE_Accessibility_Check_Failed));
7738
7739                     --  Dynamic case: when the pool is of a class-wide type,
7740                     --  it may or may not support subpools depending on the
7741                     --  path of derivation. Generate:
7742
7743                     --    if Def_Id in RSPWS'Class then
7744                     --       raise Program_Error;
7745                     --    end if;
7746
7747                     elsif Is_Class_Wide_Type (Etype (Pool)) then
7748                        Append_Freeze_Action (Def_Id,
7749                          Make_If_Statement (Loc,
7750                            Condition       =>
7751                              Make_In (Loc,
7752                                Left_Opnd  => New_Occurrence_Of (Pool, Loc),
7753                                Right_Opnd =>
7754                                  New_Occurrence_Of
7755                                    (Class_Wide_Type (RSPWS), Loc)),
7756
7757                            Then_Statements => New_List (
7758                              Make_Raise_Program_Error (Loc,
7759                                Reason => PE_Accessibility_Check_Failed))));
7760                     end if;
7761                  end if;
7762               end;
7763            end if;
7764
7765            --  For access-to-controlled types (including class-wide types and
7766            --  Taft-amendment types, which potentially have controlled
7767            --  components), expand the list controller object that will store
7768            --  the dynamically allocated objects. Don't do this transformation
7769            --  for expander-generated access types, but do it for types that
7770            --  are the full view of types derived from other private types.
7771            --  Also suppress the list controller in the case of a designated
7772            --  type with convention Java, since this is used when binding to
7773            --  Java API specs, where there's no equivalent of a finalization
7774            --  list and we don't want to pull in the finalization support if
7775            --  not needed.
7776
7777            if not Comes_From_Source (Def_Id)
7778              and then not Has_Private_Declaration (Def_Id)
7779            then
7780               null;
7781
7782            --  An exception is made for types defined in the run-time because
7783            --  Ada.Tags.Tag itself is such a type and cannot afford this
7784            --  unnecessary overhead that would generates a loop in the
7785            --  expansion scheme. Another exception is if Restrictions
7786            --  (No_Finalization) is active, since then we know nothing is
7787            --  controlled.
7788
7789            elsif Restriction_Active (No_Finalization)
7790              or else In_Runtime (Def_Id)
7791            then
7792               null;
7793
7794            --  Create a finalization master for an access-to-controlled type
7795            --  or an access-to-incomplete type. It is assumed that the full
7796            --  view will be controlled.
7797
7798            elsif Needs_Finalization (Desig_Type)
7799              or else (Is_Incomplete_Type (Desig_Type)
7800                        and then No (Full_View (Desig_Type)))
7801            then
7802               Build_Finalization_Master (Def_Id);
7803
7804            --  Create a finalization master when the designated type contains
7805            --  a private component. It is assumed that the full view will be
7806            --  controlled.
7807
7808            elsif Has_Private_Component (Desig_Type) then
7809               Build_Finalization_Master
7810                 (Typ            => Def_Id,
7811                  For_Private    => True,
7812                  Context_Scope  => Scope (Def_Id),
7813                  Insertion_Node => Declaration_Node (Desig_Type));
7814            end if;
7815         end;
7816
7817      --  Freeze processing for enumeration types
7818
7819      elsif Ekind (Def_Id) = E_Enumeration_Type then
7820
7821         --  We only have something to do if we have a non-standard
7822         --  representation (i.e. at least one literal whose pos value
7823         --  is not the same as its representation)
7824
7825         if Has_Non_Standard_Rep (Def_Id) then
7826            Expand_Freeze_Enumeration_Type (N);
7827         end if;
7828
7829      --  Private types that are completed by a derivation from a private
7830      --  type have an internally generated full view, that needs to be
7831      --  frozen. This must be done explicitly because the two views share
7832      --  the freeze node, and the underlying full view is not visible when
7833      --  the freeze node is analyzed.
7834
7835      elsif Is_Private_Type (Def_Id)
7836        and then Is_Derived_Type (Def_Id)
7837        and then Present (Full_View (Def_Id))
7838        and then Is_Itype (Full_View (Def_Id))
7839        and then Has_Private_Declaration (Full_View (Def_Id))
7840        and then Freeze_Node (Full_View (Def_Id)) = N
7841      then
7842         Set_Entity (N, Full_View (Def_Id));
7843         Result := Freeze_Type (N);
7844         Set_Entity (N, Def_Id);
7845
7846      --  All other types require no expander action. There are such cases
7847      --  (e.g. task types and protected types). In such cases, the freeze
7848      --  nodes are there for use by Gigi.
7849
7850      end if;
7851
7852      --  Complete the initialization of all pending access types' finalization
7853      --  masters now that the designated type has been is frozen and primitive
7854      --  Finalize_Address generated.
7855
7856      Process_Pending_Access_Types (Def_Id);
7857      Freeze_Stream_Operations (N, Def_Id);
7858
7859      --  Generate the [spec and] body of the procedure tasked with the runtime
7860      --  verification of pragma Default_Initial_Condition's expression.
7861
7862      if Has_DIC (Def_Id) then
7863         Build_DIC_Procedure_Body (Def_Id, For_Freeze => True);
7864      end if;
7865
7866      --  Generate the [spec and] body of the invariant procedure tasked with
7867      --  the runtime verification of all invariants that pertain to the type.
7868      --  This includes invariants on the partial and full view, inherited
7869      --  class-wide invariants from parent types or interfaces, and invariants
7870      --  on array elements or record components.
7871
7872      if Is_Interface (Def_Id) then
7873
7874         --  Interfaces are treated as the partial view of a private type in
7875         --  order to achieve uniformity with the general case. As a result, an
7876         --  interface receives only a "partial" invariant procedure which is
7877         --  never called.
7878
7879         if Has_Own_Invariants (Def_Id) then
7880            Build_Invariant_Procedure_Body
7881              (Typ               => Def_Id,
7882               Partial_Invariant => Is_Interface (Def_Id));
7883         end if;
7884
7885      --  Non-interface types
7886
7887      --  Do not generate invariant procedure within other assertion
7888      --  subprograms, which may involve local declarations of local
7889      --  subtypes to which these checks do not apply.
7890
7891      elsif Has_Invariants (Def_Id) then
7892         if Within_Internal_Subprogram
7893           or else (Ekind (Current_Scope) = E_Function
7894                     and then Is_Predicate_Function (Current_Scope))
7895         then
7896            null;
7897         else
7898            Build_Invariant_Procedure_Body (Def_Id);
7899         end if;
7900      end if;
7901
7902      Restore_Ghost_Mode (Saved_GM);
7903
7904      return Result;
7905
7906   exception
7907      when RE_Not_Available =>
7908         Restore_Ghost_Mode (Saved_GM);
7909
7910         return False;
7911   end Freeze_Type;
7912
7913   -------------------------
7914   -- Get_Simple_Init_Val --
7915   -------------------------
7916
7917   function Get_Simple_Init_Val
7918     (T    : Entity_Id;
7919      N    : Node_Id;
7920      Size : Uint := No_Uint) return Node_Id
7921   is
7922      Loc    : constant Source_Ptr := Sloc (N);
7923      Val    : Node_Id;
7924      Result : Node_Id;
7925      Val_RE : RE_Id;
7926
7927      Size_To_Use : Uint;
7928      --  This is the size to be used for computation of the appropriate
7929      --  initial value for the Normalize_Scalars and Initialize_Scalars case.
7930
7931      IV_Attribute : constant Boolean :=
7932                       Nkind (N) = N_Attribute_Reference
7933                         and then Attribute_Name (N) = Name_Invalid_Value;
7934
7935      Lo_Bound : Uint;
7936      Hi_Bound : Uint;
7937      --  These are the values computed by the procedure Check_Subtype_Bounds
7938
7939      procedure Check_Subtype_Bounds;
7940      --  This procedure examines the subtype T, and its ancestor subtypes and
7941      --  derived types to determine the best known information about the
7942      --  bounds of the subtype. After the call Lo_Bound is set either to
7943      --  No_Uint if no information can be determined, or to a value which
7944      --  represents a known low bound, i.e. a valid value of the subtype can
7945      --  not be less than this value. Hi_Bound is similarly set to a known
7946      --  high bound (valid value cannot be greater than this).
7947
7948      --------------------------
7949      -- Check_Subtype_Bounds --
7950      --------------------------
7951
7952      procedure Check_Subtype_Bounds is
7953         ST1  : Entity_Id;
7954         ST2  : Entity_Id;
7955         Lo   : Node_Id;
7956         Hi   : Node_Id;
7957         Loval : Uint;
7958         Hival : Uint;
7959
7960      begin
7961         Lo_Bound := No_Uint;
7962         Hi_Bound := No_Uint;
7963
7964         --  Loop to climb ancestor subtypes and derived types
7965
7966         ST1 := T;
7967         loop
7968            if not Is_Discrete_Type (ST1) then
7969               return;
7970            end if;
7971
7972            Lo := Type_Low_Bound (ST1);
7973            Hi := Type_High_Bound (ST1);
7974
7975            if Compile_Time_Known_Value (Lo) then
7976               Loval := Expr_Value (Lo);
7977
7978               if Lo_Bound = No_Uint or else Lo_Bound < Loval then
7979                  Lo_Bound := Loval;
7980               end if;
7981            end if;
7982
7983            if Compile_Time_Known_Value (Hi) then
7984               Hival := Expr_Value (Hi);
7985
7986               if Hi_Bound = No_Uint or else Hi_Bound > Hival then
7987                  Hi_Bound := Hival;
7988               end if;
7989            end if;
7990
7991            ST2 := Ancestor_Subtype (ST1);
7992
7993            if No (ST2) then
7994               ST2 := Etype (ST1);
7995            end if;
7996
7997            exit when ST1 = ST2;
7998            ST1 := ST2;
7999         end loop;
8000      end Check_Subtype_Bounds;
8001
8002   --  Start of processing for Get_Simple_Init_Val
8003
8004   begin
8005      --  For a private type, we should always have an underlying type (because
8006      --  this was already checked in Needs_Simple_Initialization). What we do
8007      --  is to get the value for the underlying type and then do an unchecked
8008      --  conversion to the private type.
8009
8010      if Is_Private_Type (T) then
8011         Val := Get_Simple_Init_Val (Underlying_Type (T), N, Size);
8012
8013         --  A special case, if the underlying value is null, then qualify it
8014         --  with the underlying type, so that the null is properly typed.
8015         --  Similarly, if it is an aggregate it must be qualified, because an
8016         --  unchecked conversion does not provide a context for it.
8017
8018         if Nkind_In (Val, N_Null, N_Aggregate) then
8019            Val :=
8020              Make_Qualified_Expression (Loc,
8021                Subtype_Mark =>
8022                  New_Occurrence_Of (Underlying_Type (T), Loc),
8023                Expression => Val);
8024         end if;
8025
8026         Result := Unchecked_Convert_To (T, Val);
8027
8028         --  Don't truncate result (important for Initialize/Normalize_Scalars)
8029
8030         if Nkind (Result) = N_Unchecked_Type_Conversion
8031           and then Is_Scalar_Type (Underlying_Type (T))
8032         then
8033            Set_No_Truncation (Result);
8034         end if;
8035
8036         return Result;
8037
8038      --  Scalars with Default_Value aspect. The first subtype may now be
8039      --  private, so retrieve value from underlying type.
8040
8041      elsif Is_Scalar_Type (T) and then Has_Default_Aspect (T) then
8042         if Is_Private_Type (First_Subtype (T)) then
8043            return Unchecked_Convert_To (T,
8044              Default_Aspect_Value (Full_View (First_Subtype (T))));
8045         else
8046            return
8047              Convert_To (T, Default_Aspect_Value (First_Subtype (T)));
8048         end if;
8049
8050      --  Otherwise, for scalars, we must have normalize/initialize scalars
8051      --  case, or if the node N is an 'Invalid_Value attribute node.
8052
8053      elsif Is_Scalar_Type (T) then
8054         pragma Assert (Init_Or_Norm_Scalars or IV_Attribute);
8055
8056         --  Compute size of object. If it is given by the caller, we can use
8057         --  it directly, otherwise we use Esize (T) as an estimate. As far as
8058         --  we know this covers all cases correctly.
8059
8060         if Size = No_Uint or else Size <= Uint_0 then
8061            Size_To_Use := UI_Max (Uint_1, Esize (T));
8062         else
8063            Size_To_Use := Size;
8064         end if;
8065
8066         --  Maximum size to use is 64 bits, since we will create values of
8067         --  type Unsigned_64 and the range must fit this type.
8068
8069         if Size_To_Use /= No_Uint and then Size_To_Use > Uint_64 then
8070            Size_To_Use := Uint_64;
8071         end if;
8072
8073         --  Check known bounds of subtype
8074
8075         Check_Subtype_Bounds;
8076
8077         --  Processing for Normalize_Scalars case
8078
8079         if Normalize_Scalars and then not IV_Attribute then
8080
8081            --  If zero is invalid, it is a convenient value to use that is
8082            --  for sure an appropriate invalid value in all situations.
8083
8084            if Lo_Bound /= No_Uint and then Lo_Bound > Uint_0 then
8085               Val := Make_Integer_Literal (Loc, 0);
8086
8087            --  Cases where all one bits is the appropriate invalid value
8088
8089            --  For modular types, all 1 bits is either invalid or valid. If
8090            --  it is valid, then there is nothing that can be done since there
8091            --  are no invalid values (we ruled out zero already).
8092
8093            --  For signed integer types that have no negative values, either
8094            --  there is room for negative values, or there is not. If there
8095            --  is, then all 1-bits may be interpreted as minus one, which is
8096            --  certainly invalid. Alternatively it is treated as the largest
8097            --  positive value, in which case the observation for modular types
8098            --  still applies.
8099
8100            --  For float types, all 1-bits is a NaN (not a number), which is
8101            --  certainly an appropriately invalid value.
8102
8103            elsif Is_Unsigned_Type (T)
8104              or else Is_Floating_Point_Type (T)
8105              or else Is_Enumeration_Type (T)
8106            then
8107               Val := Make_Integer_Literal (Loc, 2 ** Size_To_Use - 1);
8108
8109               --  Resolve as Unsigned_64, because the largest number we can
8110               --  generate is out of range of universal integer.
8111
8112               Analyze_And_Resolve (Val, RTE (RE_Unsigned_64));
8113
8114            --  Case of signed types
8115
8116            else
8117               declare
8118                  Signed_Size : constant Uint :=
8119                                  UI_Min (Uint_63, Size_To_Use - 1);
8120
8121               begin
8122                  --  Normally we like to use the most negative number. The one
8123                  --  exception is when this number is in the known subtype
8124                  --  range and the largest positive number is not in the known
8125                  --  subtype range.
8126
8127                  --  For this exceptional case, use largest positive value
8128
8129                  if Lo_Bound /= No_Uint and then Hi_Bound /= No_Uint
8130                    and then Lo_Bound <= (-(2 ** Signed_Size))
8131                    and then Hi_Bound < 2 ** Signed_Size
8132                  then
8133                     Val := Make_Integer_Literal (Loc, 2 ** Signed_Size - 1);
8134
8135                  --  Normal case of largest negative value
8136
8137                  else
8138                     Val := Make_Integer_Literal (Loc, -(2 ** Signed_Size));
8139                  end if;
8140               end;
8141            end if;
8142
8143         --  Here for Initialize_Scalars case (or Invalid_Value attribute used)
8144
8145         else
8146            --  For float types, use float values from System.Scalar_Values
8147
8148            if Is_Floating_Point_Type (T) then
8149               if Root_Type (T) = Standard_Short_Float then
8150                  Val_RE := RE_IS_Isf;
8151               elsif Root_Type (T) = Standard_Float then
8152                  Val_RE := RE_IS_Ifl;
8153               elsif Root_Type (T) = Standard_Long_Float then
8154                  Val_RE := RE_IS_Ilf;
8155               else pragma Assert (Root_Type (T) = Standard_Long_Long_Float);
8156                  Val_RE := RE_IS_Ill;
8157               end if;
8158
8159            --  If zero is invalid, use zero values from System.Scalar_Values
8160
8161            elsif Lo_Bound /= No_Uint and then Lo_Bound > Uint_0 then
8162               if Size_To_Use <= 8 then
8163                  Val_RE := RE_IS_Iz1;
8164               elsif Size_To_Use <= 16 then
8165                  Val_RE := RE_IS_Iz2;
8166               elsif Size_To_Use <= 32 then
8167                  Val_RE := RE_IS_Iz4;
8168               else
8169                  Val_RE := RE_IS_Iz8;
8170               end if;
8171
8172            --  For unsigned, use unsigned values from System.Scalar_Values
8173
8174            elsif Is_Unsigned_Type (T) then
8175               if Size_To_Use <= 8 then
8176                  Val_RE := RE_IS_Iu1;
8177               elsif Size_To_Use <= 16 then
8178                  Val_RE := RE_IS_Iu2;
8179               elsif Size_To_Use <= 32 then
8180                  Val_RE := RE_IS_Iu4;
8181               else
8182                  Val_RE := RE_IS_Iu8;
8183               end if;
8184
8185            --  For signed, use signed values from System.Scalar_Values
8186
8187            else
8188               if Size_To_Use <= 8 then
8189                  Val_RE := RE_IS_Is1;
8190               elsif Size_To_Use <= 16 then
8191                  Val_RE := RE_IS_Is2;
8192               elsif Size_To_Use <= 32 then
8193                  Val_RE := RE_IS_Is4;
8194               else
8195                  Val_RE := RE_IS_Is8;
8196               end if;
8197            end if;
8198
8199            Val := New_Occurrence_Of (RTE (Val_RE), Loc);
8200         end if;
8201
8202         --  The final expression is obtained by doing an unchecked conversion
8203         --  of this result to the base type of the required subtype. Use the
8204         --  base type to prevent the unchecked conversion from chopping bits,
8205         --  and then we set Kill_Range_Check to preserve the "bad" value.
8206
8207         Result := Unchecked_Convert_To (Base_Type (T), Val);
8208
8209         --  Ensure result is not truncated, since we want the "bad" bits, and
8210         --  also kill range check on result.
8211
8212         if Nkind (Result) = N_Unchecked_Type_Conversion then
8213            Set_No_Truncation (Result);
8214            Set_Kill_Range_Check (Result, True);
8215         end if;
8216
8217         return Result;
8218
8219      --  String or Wide_[Wide]_String (must have Initialize_Scalars set)
8220
8221      elsif Is_Standard_String_Type (T) then
8222         pragma Assert (Init_Or_Norm_Scalars);
8223
8224         return
8225           Make_Aggregate (Loc,
8226             Component_Associations => New_List (
8227               Make_Component_Association (Loc,
8228                 Choices    => New_List (
8229                   Make_Others_Choice (Loc)),
8230                 Expression =>
8231                   Get_Simple_Init_Val
8232                     (Component_Type (T), N, Esize (Root_Type (T))))));
8233
8234      --  Access type is initialized to null
8235
8236      elsif Is_Access_Type (T) then
8237         return Make_Null (Loc);
8238
8239      --  No other possibilities should arise, since we should only be calling
8240      --  Get_Simple_Init_Val if Needs_Simple_Initialization returned True,
8241      --  indicating one of the above cases held.
8242
8243      else
8244         raise Program_Error;
8245      end if;
8246
8247   exception
8248      when RE_Not_Available =>
8249         return Empty;
8250   end Get_Simple_Init_Val;
8251
8252   ------------------------------
8253   -- Has_New_Non_Standard_Rep --
8254   ------------------------------
8255
8256   function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean is
8257   begin
8258      if not Is_Derived_Type (T) then
8259         return Has_Non_Standard_Rep (T)
8260           or else Has_Non_Standard_Rep (Root_Type (T));
8261
8262      --  If Has_Non_Standard_Rep is not set on the derived type, the
8263      --  representation is fully inherited.
8264
8265      elsif not Has_Non_Standard_Rep (T) then
8266         return False;
8267
8268      else
8269         return First_Rep_Item (T) /= First_Rep_Item (Root_Type (T));
8270
8271         --  May need a more precise check here: the First_Rep_Item may be a
8272         --  stream attribute, which does not affect the representation of the
8273         --  type ???
8274
8275      end if;
8276   end Has_New_Non_Standard_Rep;
8277
8278   ----------------------
8279   -- Inline_Init_Proc --
8280   ----------------------
8281
8282   function Inline_Init_Proc (Typ : Entity_Id) return Boolean is
8283   begin
8284      --  The initialization proc of protected records is not worth inlining.
8285      --  In addition, when compiled for another unit for inlining purposes,
8286      --  it may make reference to entities that have not been elaborated yet.
8287      --  The initialization proc of records that need finalization contains
8288      --  a nested clean-up procedure that makes it impractical to inline as
8289      --  well, except for simple controlled types themselves. And similar
8290      --  considerations apply to task types.
8291
8292      if Is_Concurrent_Type (Typ) then
8293         return False;
8294
8295      elsif Needs_Finalization (Typ) and then not Is_Controlled (Typ) then
8296         return False;
8297
8298      elsif Has_Task (Typ) then
8299         return False;
8300
8301      else
8302         return True;
8303      end if;
8304   end Inline_Init_Proc;
8305
8306   ----------------
8307   -- In_Runtime --
8308   ----------------
8309
8310   function In_Runtime (E : Entity_Id) return Boolean is
8311      S1 : Entity_Id;
8312
8313   begin
8314      S1 := Scope (E);
8315      while Scope (S1) /= Standard_Standard loop
8316         S1 := Scope (S1);
8317      end loop;
8318
8319      return Is_RTU (S1, System) or else Is_RTU (S1, Ada);
8320   end In_Runtime;
8321
8322   ----------------------------
8323   -- Initialization_Warning --
8324   ----------------------------
8325
8326   procedure Initialization_Warning (E : Entity_Id) is
8327      Warning_Needed : Boolean;
8328
8329   begin
8330      Warning_Needed := False;
8331
8332      if Ekind (Current_Scope) = E_Package
8333        and then Static_Elaboration_Desired (Current_Scope)
8334      then
8335         if Is_Type (E) then
8336            if Is_Record_Type (E) then
8337               if Has_Discriminants (E)
8338                 or else Is_Limited_Type (E)
8339                 or else Has_Non_Standard_Rep (E)
8340               then
8341                  Warning_Needed := True;
8342
8343               else
8344                  --  Verify that at least one component has an initialization
8345                  --  expression. No need for a warning on a type if all its
8346                  --  components have no initialization.
8347
8348                  declare
8349                     Comp : Entity_Id;
8350
8351                  begin
8352                     Comp := First_Component (E);
8353                     while Present (Comp) loop
8354                        if Ekind (Comp) = E_Discriminant
8355                          or else
8356                            (Nkind (Parent (Comp)) = N_Component_Declaration
8357                              and then Present (Expression (Parent (Comp))))
8358                        then
8359                           Warning_Needed := True;
8360                           exit;
8361                        end if;
8362
8363                        Next_Component (Comp);
8364                     end loop;
8365                  end;
8366               end if;
8367
8368               if Warning_Needed then
8369                  Error_Msg_N
8370                    ("Objects of the type cannot be initialized statically "
8371                     & "by default??", Parent (E));
8372               end if;
8373            end if;
8374
8375         else
8376            Error_Msg_N ("Object cannot be initialized statically??", E);
8377         end if;
8378      end if;
8379   end Initialization_Warning;
8380
8381   ------------------
8382   -- Init_Formals --
8383   ------------------
8384
8385   function Init_Formals (Typ : Entity_Id) return List_Id is
8386      Loc     : constant Source_Ptr := Sloc (Typ);
8387      Formals : List_Id;
8388
8389   begin
8390      --  First parameter is always _Init : in out typ. Note that we need this
8391      --  to be in/out because in the case of the task record value, there
8392      --  are default record fields (_Priority, _Size, -Task_Info) that may
8393      --  be referenced in the generated initialization routine.
8394
8395      Formals := New_List (
8396        Make_Parameter_Specification (Loc,
8397          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uInit),
8398          In_Present          => True,
8399          Out_Present         => True,
8400          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));
8401
8402      --  For task record value, or type that contains tasks, add two more
8403      --  formals, _Master : Master_Id and _Chain : in out Activation_Chain
8404      --  We also add these parameters for the task record type case.
8405
8406      if Has_Task (Typ)
8407        or else (Is_Record_Type (Typ) and then Is_Task_Record_Type (Typ))
8408      then
8409         Append_To (Formals,
8410           Make_Parameter_Specification (Loc,
8411             Defining_Identifier =>
8412               Make_Defining_Identifier (Loc, Name_uMaster),
8413             Parameter_Type      =>
8414               New_Occurrence_Of (RTE (RE_Master_Id), Loc)));
8415
8416         --  Add _Chain (not done for sequential elaboration policy, see
8417         --  comment for Create_Restricted_Task_Sequential in s-tarest.ads).
8418
8419         if Partition_Elaboration_Policy /= 'S' then
8420            Append_To (Formals,
8421              Make_Parameter_Specification (Loc,
8422                Defining_Identifier =>
8423                  Make_Defining_Identifier (Loc, Name_uChain),
8424                In_Present          => True,
8425                Out_Present         => True,
8426                Parameter_Type      =>
8427                  New_Occurrence_Of (RTE (RE_Activation_Chain), Loc)));
8428         end if;
8429
8430         Append_To (Formals,
8431           Make_Parameter_Specification (Loc,
8432             Defining_Identifier =>
8433               Make_Defining_Identifier (Loc, Name_uTask_Name),
8434             In_Present          => True,
8435             Parameter_Type      => New_Occurrence_Of (Standard_String, Loc)));
8436      end if;
8437
8438      return Formals;
8439
8440   exception
8441      when RE_Not_Available =>
8442         return Empty_List;
8443   end Init_Formals;
8444
8445   -------------------------
8446   -- Init_Secondary_Tags --
8447   -------------------------
8448
8449   procedure Init_Secondary_Tags
8450     (Typ            : Entity_Id;
8451      Target         : Node_Id;
8452      Init_Tags_List : List_Id;
8453      Stmts_List     : List_Id;
8454      Fixed_Comps    : Boolean := True;
8455      Variable_Comps : Boolean := True)
8456   is
8457      Loc : constant Source_Ptr := Sloc (Target);
8458
8459      --  Inherit the C++ tag of the secondary dispatch table of Typ associated
8460      --  with Iface. Tag_Comp is the component of Typ that stores Iface_Tag.
8461
8462      procedure Initialize_Tag
8463        (Typ       : Entity_Id;
8464         Iface     : Entity_Id;
8465         Tag_Comp  : Entity_Id;
8466         Iface_Tag : Node_Id);
8467      --  Initialize the tag of the secondary dispatch table of Typ associated
8468      --  with Iface. Tag_Comp is the component of Typ that stores Iface_Tag.
8469      --  Compiling under the CPP full ABI compatibility mode, if the ancestor
8470      --  of Typ CPP tagged type we generate code to inherit the contents of
8471      --  the dispatch table directly from the ancestor.
8472
8473      --------------------
8474      -- Initialize_Tag --
8475      --------------------
8476
8477      procedure Initialize_Tag
8478        (Typ       : Entity_Id;
8479         Iface     : Entity_Id;
8480         Tag_Comp  : Entity_Id;
8481         Iface_Tag : Node_Id)
8482      is
8483         Comp_Typ           : Entity_Id;
8484         Offset_To_Top_Comp : Entity_Id := Empty;
8485
8486      begin
8487         --  Initialize pointer to secondary DT associated with the interface
8488
8489         if not Is_Ancestor (Iface, Typ, Use_Full_View => True) then
8490            Append_To (Init_Tags_List,
8491              Make_Assignment_Statement (Loc,
8492                Name       =>
8493                  Make_Selected_Component (Loc,
8494                    Prefix        => New_Copy_Tree (Target),
8495                    Selector_Name => New_Occurrence_Of (Tag_Comp, Loc)),
8496                Expression =>
8497                  New_Occurrence_Of (Iface_Tag, Loc)));
8498         end if;
8499
8500         Comp_Typ := Scope (Tag_Comp);
8501
8502         --  Initialize the entries of the table of interfaces. We generate a
8503         --  different call when the parent of the type has variable size
8504         --  components.
8505
8506         if Comp_Typ /= Etype (Comp_Typ)
8507           and then Is_Variable_Size_Record (Etype (Comp_Typ))
8508           and then Chars (Tag_Comp) /= Name_uTag
8509         then
8510            pragma Assert (Present (DT_Offset_To_Top_Func (Tag_Comp)));
8511
8512            --  Issue error if Set_Dynamic_Offset_To_Top is not available in a
8513            --  configurable run-time environment.
8514
8515            if not RTE_Available (RE_Set_Dynamic_Offset_To_Top) then
8516               Error_Msg_CRT
8517                 ("variable size record with interface types", Typ);
8518               return;
8519            end if;
8520
8521            --  Generate:
8522            --    Set_Dynamic_Offset_To_Top
8523            --      (This         => Init,
8524            --       Prim_T       => Typ'Tag,
8525            --       Interface_T  => Iface'Tag,
8526            --       Offset_Value => n,
8527            --       Offset_Func  => Fn'Address)
8528
8529            Append_To (Stmts_List,
8530              Make_Procedure_Call_Statement (Loc,
8531                Name                   =>
8532                  New_Occurrence_Of (RTE (RE_Set_Dynamic_Offset_To_Top), Loc),
8533                Parameter_Associations => New_List (
8534                  Make_Attribute_Reference (Loc,
8535                    Prefix         => New_Copy_Tree (Target),
8536                    Attribute_Name => Name_Address),
8537
8538                  Unchecked_Convert_To (RTE (RE_Tag),
8539                    New_Occurrence_Of
8540                      (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)),
8541
8542                  Unchecked_Convert_To (RTE (RE_Tag),
8543                    New_Occurrence_Of
8544                      (Node (First_Elmt (Access_Disp_Table (Iface))),
8545                       Loc)),
8546
8547                  Unchecked_Convert_To
8548                    (RTE (RE_Storage_Offset),
8549                     Make_Op_Minus (Loc,
8550                       Make_Attribute_Reference (Loc,
8551                         Prefix         =>
8552                           Make_Selected_Component (Loc,
8553                             Prefix        => New_Copy_Tree (Target),
8554                             Selector_Name =>
8555                               New_Occurrence_Of (Tag_Comp, Loc)),
8556                         Attribute_Name => Name_Position))),
8557
8558                  Unchecked_Convert_To (RTE (RE_Offset_To_Top_Function_Ptr),
8559                    Make_Attribute_Reference (Loc,
8560                      Prefix => New_Occurrence_Of
8561                                  (DT_Offset_To_Top_Func (Tag_Comp), Loc),
8562                      Attribute_Name => Name_Address)))));
8563
8564            --  In this case the next component stores the value of the offset
8565            --  to the top.
8566
8567            Offset_To_Top_Comp := Next_Entity (Tag_Comp);
8568            pragma Assert (Present (Offset_To_Top_Comp));
8569
8570            Append_To (Init_Tags_List,
8571              Make_Assignment_Statement (Loc,
8572                Name       =>
8573                  Make_Selected_Component (Loc,
8574                    Prefix        => New_Copy_Tree (Target),
8575                    Selector_Name =>
8576                      New_Occurrence_Of (Offset_To_Top_Comp, Loc)),
8577
8578                Expression =>
8579                  Make_Op_Minus (Loc,
8580                    Make_Attribute_Reference (Loc,
8581                      Prefix       =>
8582                        Make_Selected_Component (Loc,
8583                          Prefix        => New_Copy_Tree (Target),
8584                          Selector_Name => New_Occurrence_Of (Tag_Comp, Loc)),
8585                    Attribute_Name => Name_Position))));
8586
8587         --  Normal case: No discriminants in the parent type
8588
8589         else
8590            --  Don't need to set any value if the offset-to-top field is
8591            --  statically set or if this interface shares the primary
8592            --  dispatch table.
8593
8594            if not Building_Static_Secondary_DT (Typ)
8595              and then not Is_Ancestor (Iface, Typ, Use_Full_View => True)
8596            then
8597               Append_To (Stmts_List,
8598                 Build_Set_Static_Offset_To_Top (Loc,
8599                   Iface_Tag    => New_Occurrence_Of (Iface_Tag, Loc),
8600                   Offset_Value =>
8601                     Unchecked_Convert_To (RTE (RE_Storage_Offset),
8602                       Make_Op_Minus (Loc,
8603                         Make_Attribute_Reference (Loc,
8604                           Prefix         =>
8605                             Make_Selected_Component (Loc,
8606                               Prefix        => New_Copy_Tree (Target),
8607                               Selector_Name =>
8608                                 New_Occurrence_Of (Tag_Comp, Loc)),
8609                           Attribute_Name => Name_Position)))));
8610            end if;
8611
8612            --  Generate:
8613            --    Register_Interface_Offset
8614            --      (Prim_T       => Typ'Tag,
8615            --       Interface_T  => Iface'Tag,
8616            --       Is_Constant  => True,
8617            --       Offset_Value => n,
8618            --       Offset_Func  => null);
8619
8620            if not Building_Static_Secondary_DT (Typ)
8621              and then RTE_Available (RE_Register_Interface_Offset)
8622            then
8623               Append_To (Stmts_List,
8624                 Make_Procedure_Call_Statement (Loc,
8625                   Name                   =>
8626                     New_Occurrence_Of
8627                       (RTE (RE_Register_Interface_Offset), Loc),
8628                   Parameter_Associations => New_List (
8629                     Unchecked_Convert_To (RTE (RE_Tag),
8630                       New_Occurrence_Of
8631                         (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)),
8632
8633                     Unchecked_Convert_To (RTE (RE_Tag),
8634                       New_Occurrence_Of
8635                         (Node (First_Elmt (Access_Disp_Table (Iface))), Loc)),
8636
8637                     New_Occurrence_Of (Standard_True, Loc),
8638
8639                     Unchecked_Convert_To (RTE (RE_Storage_Offset),
8640                       Make_Op_Minus (Loc,
8641                         Make_Attribute_Reference (Loc,
8642                           Prefix         =>
8643                             Make_Selected_Component (Loc,
8644                               Prefix         => New_Copy_Tree (Target),
8645                               Selector_Name  =>
8646                                 New_Occurrence_Of (Tag_Comp, Loc)),
8647                           Attribute_Name => Name_Position))),
8648
8649                     Make_Null (Loc))));
8650            end if;
8651         end if;
8652      end Initialize_Tag;
8653
8654      --  Local variables
8655
8656      Full_Typ         : Entity_Id;
8657      Ifaces_List      : Elist_Id;
8658      Ifaces_Comp_List : Elist_Id;
8659      Ifaces_Tag_List  : Elist_Id;
8660      Iface_Elmt       : Elmt_Id;
8661      Iface_Comp_Elmt  : Elmt_Id;
8662      Iface_Tag_Elmt   : Elmt_Id;
8663      Tag_Comp         : Node_Id;
8664      In_Variable_Pos  : Boolean;
8665
8666   --  Start of processing for Init_Secondary_Tags
8667
8668   begin
8669      --  Handle private types
8670
8671      if Present (Full_View (Typ)) then
8672         Full_Typ := Full_View (Typ);
8673      else
8674         Full_Typ := Typ;
8675      end if;
8676
8677      Collect_Interfaces_Info
8678        (Full_Typ, Ifaces_List, Ifaces_Comp_List, Ifaces_Tag_List);
8679
8680      Iface_Elmt      := First_Elmt (Ifaces_List);
8681      Iface_Comp_Elmt := First_Elmt (Ifaces_Comp_List);
8682      Iface_Tag_Elmt  := First_Elmt (Ifaces_Tag_List);
8683      while Present (Iface_Elmt) loop
8684         Tag_Comp := Node (Iface_Comp_Elmt);
8685
8686         --  Check if parent of record type has variable size components
8687
8688         In_Variable_Pos := Scope (Tag_Comp) /= Etype (Scope (Tag_Comp))
8689           and then Is_Variable_Size_Record (Etype (Scope (Tag_Comp)));
8690
8691         --  If we are compiling under the CPP full ABI compatibility mode and
8692         --  the ancestor is a CPP_Pragma tagged type then we generate code to
8693         --  initialize the secondary tag components from tags that reference
8694         --  secondary tables filled with copy of parent slots.
8695
8696         if Is_CPP_Class (Root_Type (Full_Typ)) then
8697
8698            --  Reject interface components located at variable offset in
8699            --  C++ derivations. This is currently unsupported.
8700
8701            if not Fixed_Comps and then In_Variable_Pos then
8702
8703               --  Locate the first dynamic component of the record. Done to
8704               --  improve the text of the warning.
8705
8706               declare
8707                  Comp     : Entity_Id;
8708                  Comp_Typ : Entity_Id;
8709
8710               begin
8711                  Comp := First_Entity (Typ);
8712                  while Present (Comp) loop
8713                     Comp_Typ := Etype (Comp);
8714
8715                     if Ekind (Comp) /= E_Discriminant
8716                       and then not Is_Tag (Comp)
8717                     then
8718                        exit when
8719                          (Is_Record_Type (Comp_Typ)
8720                            and then
8721                              Is_Variable_Size_Record (Base_Type (Comp_Typ)))
8722                         or else
8723                           (Is_Array_Type (Comp_Typ)
8724                             and then Is_Variable_Size_Array (Comp_Typ));
8725                     end if;
8726
8727                     Next_Entity (Comp);
8728                  end loop;
8729
8730                  pragma Assert (Present (Comp));
8731                  Error_Msg_Node_2 := Comp;
8732                  Error_Msg_NE
8733                    ("parent type & with dynamic component & cannot be parent"
8734                     & " of 'C'P'P derivation if new interfaces are present",
8735                     Typ, Scope (Original_Record_Component (Comp)));
8736
8737                  Error_Msg_Sloc :=
8738                    Sloc (Scope (Original_Record_Component (Comp)));
8739                  Error_Msg_NE
8740                    ("type derived from 'C'P'P type & defined #",
8741                     Typ, Scope (Original_Record_Component (Comp)));
8742
8743                  --  Avoid duplicated warnings
8744
8745                  exit;
8746               end;
8747
8748            --  Initialize secondary tags
8749
8750            else
8751               Initialize_Tag
8752                 (Typ       => Full_Typ,
8753                  Iface     => Node (Iface_Elmt),
8754                  Tag_Comp  => Tag_Comp,
8755                  Iface_Tag => Node (Iface_Tag_Elmt));
8756            end if;
8757
8758         --  Otherwise generate code to initialize the tag
8759
8760         else
8761            if (In_Variable_Pos and then Variable_Comps)
8762              or else (not In_Variable_Pos and then Fixed_Comps)
8763            then
8764               Initialize_Tag
8765                 (Typ       => Full_Typ,
8766                  Iface     => Node (Iface_Elmt),
8767                  Tag_Comp  => Tag_Comp,
8768                  Iface_Tag => Node (Iface_Tag_Elmt));
8769            end if;
8770         end if;
8771
8772         Next_Elmt (Iface_Elmt);
8773         Next_Elmt (Iface_Comp_Elmt);
8774         Next_Elmt (Iface_Tag_Elmt);
8775      end loop;
8776   end Init_Secondary_Tags;
8777
8778   ------------------------
8779   -- Is_User_Defined_Eq --
8780   ------------------------
8781
8782   function Is_User_Defined_Equality (Prim : Node_Id) return Boolean is
8783   begin
8784      return Chars (Prim) = Name_Op_Eq
8785        and then Etype (First_Formal (Prim)) =
8786                 Etype (Next_Formal (First_Formal (Prim)))
8787        and then Base_Type (Etype (Prim)) = Standard_Boolean;
8788   end Is_User_Defined_Equality;
8789
8790   ----------------------------------------
8791   -- Make_Controlling_Function_Wrappers --
8792   ----------------------------------------
8793
8794   procedure Make_Controlling_Function_Wrappers
8795     (Tag_Typ   : Entity_Id;
8796      Decl_List : out List_Id;
8797      Body_List : out List_Id)
8798   is
8799      Loc         : constant Source_Ptr := Sloc (Tag_Typ);
8800      Prim_Elmt   : Elmt_Id;
8801      Subp        : Entity_Id;
8802      Actual_List : List_Id;
8803      Formal_List : List_Id;
8804      Formal      : Entity_Id;
8805      Par_Formal  : Entity_Id;
8806      Formal_Node : Node_Id;
8807      Func_Body   : Node_Id;
8808      Func_Decl   : Node_Id;
8809      Func_Spec   : Node_Id;
8810      Return_Stmt : Node_Id;
8811
8812   begin
8813      Decl_List := New_List;
8814      Body_List := New_List;
8815
8816      Prim_Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
8817      while Present (Prim_Elmt) loop
8818         Subp := Node (Prim_Elmt);
8819
8820         --  If a primitive function with a controlling result of the type has
8821         --  not been overridden by the user, then we must create a wrapper
8822         --  function here that effectively overrides it and invokes the
8823         --  (non-abstract) parent function. This can only occur for a null
8824         --  extension. Note that functions with anonymous controlling access
8825         --  results don't qualify and must be overridden. We also exclude
8826         --  Input attributes, since each type will have its own version of
8827         --  Input constructed by the expander. The test for Comes_From_Source
8828         --  is needed to distinguish inherited operations from renamings
8829         --  (which also have Alias set). We exclude internal entities with
8830         --  Interface_Alias to avoid generating duplicated wrappers since
8831         --  the primitive which covers the interface is also available in
8832         --  the list of primitive operations.
8833
8834         --  The function may be abstract, or require_Overriding may be set
8835         --  for it, because tests for null extensions may already have reset
8836         --  the Is_Abstract_Subprogram_Flag. If Requires_Overriding is not
8837         --  set, functions that need wrappers are recognized by having an
8838         --  alias that returns the parent type.
8839
8840         if Comes_From_Source (Subp)
8841           or else No (Alias (Subp))
8842           or else Present (Interface_Alias (Subp))
8843           or else Ekind (Subp) /= E_Function
8844           or else not Has_Controlling_Result (Subp)
8845           or else Is_Access_Type (Etype (Subp))
8846           or else Is_Abstract_Subprogram (Alias (Subp))
8847           or else Is_TSS (Subp, TSS_Stream_Input)
8848         then
8849            goto Next_Prim;
8850
8851         elsif Is_Abstract_Subprogram (Subp)
8852           or else Requires_Overriding (Subp)
8853           or else
8854             (Is_Null_Extension (Etype (Subp))
8855               and then Etype (Alias (Subp)) /= Etype (Subp))
8856         then
8857            Formal_List := No_List;
8858            Formal := First_Formal (Subp);
8859
8860            if Present (Formal) then
8861               Formal_List := New_List;
8862
8863               while Present (Formal) loop
8864                  Append
8865                    (Make_Parameter_Specification
8866                       (Loc,
8867                        Defining_Identifier =>
8868                          Make_Defining_Identifier (Sloc (Formal),
8869                            Chars => Chars (Formal)),
8870                        In_Present  => In_Present (Parent (Formal)),
8871                        Out_Present => Out_Present (Parent (Formal)),
8872                        Null_Exclusion_Present =>
8873                          Null_Exclusion_Present (Parent (Formal)),
8874                        Parameter_Type =>
8875                          New_Occurrence_Of (Etype (Formal), Loc),
8876                        Expression =>
8877                          New_Copy_Tree (Expression (Parent (Formal)))),
8878                     Formal_List);
8879
8880                  Next_Formal (Formal);
8881               end loop;
8882            end if;
8883
8884            Func_Spec :=
8885              Make_Function_Specification (Loc,
8886                Defining_Unit_Name       =>
8887                  Make_Defining_Identifier (Loc,
8888                    Chars => Chars (Subp)),
8889                Parameter_Specifications => Formal_List,
8890                Result_Definition        =>
8891                  New_Occurrence_Of (Etype (Subp), Loc));
8892
8893            Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
8894            Append_To (Decl_List, Func_Decl);
8895
8896            --  Build a wrapper body that calls the parent function. The body
8897            --  contains a single return statement that returns an extension
8898            --  aggregate whose ancestor part is a call to the parent function,
8899            --  passing the formals as actuals (with any controlling arguments
8900            --  converted to the types of the corresponding formals of the
8901            --  parent function, which might be anonymous access types), and
8902            --  having a null extension.
8903
8904            Formal      := First_Formal (Subp);
8905            Par_Formal  := First_Formal (Alias (Subp));
8906            Formal_Node := First (Formal_List);
8907
8908            if Present (Formal) then
8909               Actual_List := New_List;
8910            else
8911               Actual_List := No_List;
8912            end if;
8913
8914            while Present (Formal) loop
8915               if Is_Controlling_Formal (Formal) then
8916                  Append_To (Actual_List,
8917                    Make_Type_Conversion (Loc,
8918                      Subtype_Mark =>
8919                        New_Occurrence_Of (Etype (Par_Formal), Loc),
8920                      Expression   =>
8921                        New_Occurrence_Of
8922                          (Defining_Identifier (Formal_Node), Loc)));
8923               else
8924                  Append_To
8925                    (Actual_List,
8926                     New_Occurrence_Of
8927                       (Defining_Identifier (Formal_Node), Loc));
8928               end if;
8929
8930               Next_Formal (Formal);
8931               Next_Formal (Par_Formal);
8932               Next (Formal_Node);
8933            end loop;
8934
8935            Return_Stmt :=
8936              Make_Simple_Return_Statement (Loc,
8937                Expression =>
8938                  Make_Extension_Aggregate (Loc,
8939                    Ancestor_Part       =>
8940                      Make_Function_Call (Loc,
8941                        Name                   =>
8942                          New_Occurrence_Of (Alias (Subp), Loc),
8943                        Parameter_Associations => Actual_List),
8944                    Null_Record_Present => True));
8945
8946            Func_Body :=
8947              Make_Subprogram_Body (Loc,
8948                Specification              => New_Copy_Tree (Func_Spec),
8949                Declarations               => Empty_List,
8950                Handled_Statement_Sequence =>
8951                  Make_Handled_Sequence_Of_Statements (Loc,
8952                    Statements => New_List (Return_Stmt)));
8953
8954            Set_Defining_Unit_Name
8955              (Specification (Func_Body),
8956                Make_Defining_Identifier (Loc, Chars (Subp)));
8957
8958            Append_To (Body_List, Func_Body);
8959
8960            --  Replace the inherited function with the wrapper function in the
8961            --  primitive operations list. We add the minimum decoration needed
8962            --  to override interface primitives.
8963
8964            Set_Ekind (Defining_Unit_Name (Func_Spec), E_Function);
8965
8966            Override_Dispatching_Operation
8967              (Tag_Typ, Subp, New_Op => Defining_Unit_Name (Func_Spec),
8968               Is_Wrapper => True);
8969         end if;
8970
8971      <<Next_Prim>>
8972         Next_Elmt (Prim_Elmt);
8973      end loop;
8974   end Make_Controlling_Function_Wrappers;
8975
8976   -------------------
8977   --  Make_Eq_Body --
8978   -------------------
8979
8980   function Make_Eq_Body
8981     (Typ     : Entity_Id;
8982      Eq_Name : Name_Id) return Node_Id
8983   is
8984      Loc          : constant Source_Ptr := Sloc (Parent (Typ));
8985      Decl         : Node_Id;
8986      Def          : constant Node_Id := Parent (Typ);
8987      Stmts        : constant List_Id := New_List;
8988      Variant_Case : Boolean := Has_Discriminants (Typ);
8989      Comps        : Node_Id := Empty;
8990      Typ_Def      : Node_Id := Type_Definition (Def);
8991
8992   begin
8993      Decl :=
8994        Predef_Spec_Or_Body (Loc,
8995          Tag_Typ => Typ,
8996          Name    => Eq_Name,
8997          Profile => New_List (
8998            Make_Parameter_Specification (Loc,
8999              Defining_Identifier =>
9000                Make_Defining_Identifier (Loc, Name_X),
9001              Parameter_Type      => New_Occurrence_Of (Typ, Loc)),
9002
9003            Make_Parameter_Specification (Loc,
9004              Defining_Identifier =>
9005                Make_Defining_Identifier (Loc, Name_Y),
9006              Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
9007
9008          Ret_Type => Standard_Boolean,
9009          For_Body => True);
9010
9011      if Variant_Case then
9012         if Nkind (Typ_Def) = N_Derived_Type_Definition then
9013            Typ_Def := Record_Extension_Part (Typ_Def);
9014         end if;
9015
9016         if Present (Typ_Def) then
9017            Comps := Component_List (Typ_Def);
9018         end if;
9019
9020         Variant_Case :=
9021           Present (Comps) and then Present (Variant_Part (Comps));
9022      end if;
9023
9024      if Variant_Case then
9025         Append_To (Stmts,
9026           Make_Eq_If (Typ, Discriminant_Specifications (Def)));
9027         Append_List_To (Stmts, Make_Eq_Case (Typ, Comps));
9028         Append_To (Stmts,
9029           Make_Simple_Return_Statement (Loc,
9030             Expression => New_Occurrence_Of (Standard_True, Loc)));
9031
9032      else
9033         Append_To (Stmts,
9034           Make_Simple_Return_Statement (Loc,
9035             Expression =>
9036               Expand_Record_Equality
9037                 (Typ,
9038                  Typ    => Typ,
9039                  Lhs    => Make_Identifier (Loc, Name_X),
9040                  Rhs    => Make_Identifier (Loc, Name_Y),
9041                  Bodies => Declarations (Decl))));
9042      end if;
9043
9044      Set_Handled_Statement_Sequence
9045        (Decl, Make_Handled_Sequence_Of_Statements (Loc, Stmts));
9046      return Decl;
9047   end Make_Eq_Body;
9048
9049   ------------------
9050   -- Make_Eq_Case --
9051   ------------------
9052
9053   --  <Make_Eq_If shared components>
9054
9055   --  case X.D1 is
9056   --     when V1 => <Make_Eq_Case> on subcomponents
9057   --     ...
9058   --     when Vn => <Make_Eq_Case> on subcomponents
9059   --  end case;
9060
9061   function Make_Eq_Case
9062     (E      : Entity_Id;
9063      CL     : Node_Id;
9064      Discrs : Elist_Id := New_Elmt_List) return List_Id
9065   is
9066      Loc      : constant Source_Ptr := Sloc (E);
9067      Result   : constant List_Id    := New_List;
9068      Variant  : Node_Id;
9069      Alt_List : List_Id;
9070
9071      function Corresponding_Formal (C : Node_Id) return Entity_Id;
9072      --  Given the discriminant that controls a given variant of an unchecked
9073      --  union, find the formal of the equality function that carries the
9074      --  inferred value of the discriminant.
9075
9076      function External_Name (E : Entity_Id) return Name_Id;
9077      --  The value of a given discriminant is conveyed in the corresponding
9078      --  formal parameter of the equality routine. The name of this formal
9079      --  parameter carries a one-character suffix which is removed here.
9080
9081      --------------------------
9082      -- Corresponding_Formal --
9083      --------------------------
9084
9085      function Corresponding_Formal (C : Node_Id) return Entity_Id is
9086         Discr : constant Entity_Id := Entity (Name (Variant_Part (C)));
9087         Elm   : Elmt_Id;
9088
9089      begin
9090         Elm := First_Elmt (Discrs);
9091         while Present (Elm) loop
9092            if Chars (Discr) = External_Name (Node (Elm)) then
9093               return Node (Elm);
9094            end if;
9095
9096            Next_Elmt (Elm);
9097         end loop;
9098
9099         --  A formal of the proper name must be found
9100
9101         raise Program_Error;
9102      end Corresponding_Formal;
9103
9104      -------------------
9105      -- External_Name --
9106      -------------------
9107
9108      function External_Name (E : Entity_Id) return Name_Id is
9109      begin
9110         Get_Name_String (Chars (E));
9111         Name_Len := Name_Len - 1;
9112         return Name_Find;
9113      end External_Name;
9114
9115   --  Start of processing for Make_Eq_Case
9116
9117   begin
9118      Append_To (Result, Make_Eq_If (E, Component_Items (CL)));
9119
9120      if No (Variant_Part (CL)) then
9121         return Result;
9122      end if;
9123
9124      Variant := First_Non_Pragma (Variants (Variant_Part (CL)));
9125
9126      if No (Variant) then
9127         return Result;
9128      end if;
9129
9130      Alt_List := New_List;
9131      while Present (Variant) loop
9132         Append_To (Alt_List,
9133           Make_Case_Statement_Alternative (Loc,
9134             Discrete_Choices => New_Copy_List (Discrete_Choices (Variant)),
9135             Statements =>
9136               Make_Eq_Case (E, Component_List (Variant), Discrs)));
9137         Next_Non_Pragma (Variant);
9138      end loop;
9139
9140      --  If we have an Unchecked_Union, use one of the parameters of the
9141      --  enclosing equality routine that captures the discriminant, to use
9142      --  as the expression in the generated case statement.
9143
9144      if Is_Unchecked_Union (E) then
9145         Append_To (Result,
9146           Make_Case_Statement (Loc,
9147             Expression =>
9148               New_Occurrence_Of (Corresponding_Formal (CL), Loc),
9149             Alternatives => Alt_List));
9150
9151      else
9152         Append_To (Result,
9153           Make_Case_Statement (Loc,
9154             Expression =>
9155               Make_Selected_Component (Loc,
9156                 Prefix        => Make_Identifier (Loc, Name_X),
9157                 Selector_Name => New_Copy (Name (Variant_Part (CL)))),
9158             Alternatives => Alt_List));
9159      end if;
9160
9161      return Result;
9162   end Make_Eq_Case;
9163
9164   ----------------
9165   -- Make_Eq_If --
9166   ----------------
9167
9168   --  Generates:
9169
9170   --    if
9171   --      X.C1 /= Y.C1
9172   --        or else
9173   --      X.C2 /= Y.C2
9174   --        ...
9175   --    then
9176   --       return False;
9177   --    end if;
9178
9179   --  or a null statement if the list L is empty
9180
9181   function Make_Eq_If
9182     (E : Entity_Id;
9183      L : List_Id) return Node_Id
9184   is
9185      Loc        : constant Source_Ptr := Sloc (E);
9186      C          : Node_Id;
9187      Field_Name : Name_Id;
9188      Cond       : Node_Id;
9189
9190   begin
9191      if No (L) then
9192         return Make_Null_Statement (Loc);
9193
9194      else
9195         Cond := Empty;
9196
9197         C := First_Non_Pragma (L);
9198         while Present (C) loop
9199            Field_Name := Chars (Defining_Identifier (C));
9200
9201            --  The tags must not be compared: they are not part of the value.
9202            --  Ditto for parent interfaces because their equality operator is
9203            --  abstract.
9204
9205            --  Note also that in the following, we use Make_Identifier for
9206            --  the component names. Use of New_Occurrence_Of to identify the
9207            --  components would be incorrect because the wrong entities for
9208            --  discriminants could be picked up in the private type case.
9209
9210            if Field_Name = Name_uParent
9211              and then Is_Interface (Etype (Defining_Identifier (C)))
9212            then
9213               null;
9214
9215            elsif Field_Name /= Name_uTag then
9216               Evolve_Or_Else (Cond,
9217                 Make_Op_Ne (Loc,
9218                   Left_Opnd =>
9219                     Make_Selected_Component (Loc,
9220                       Prefix        => Make_Identifier (Loc, Name_X),
9221                       Selector_Name => Make_Identifier (Loc, Field_Name)),
9222
9223                   Right_Opnd =>
9224                     Make_Selected_Component (Loc,
9225                       Prefix        => Make_Identifier (Loc, Name_Y),
9226                       Selector_Name => Make_Identifier (Loc, Field_Name))));
9227            end if;
9228
9229            Next_Non_Pragma (C);
9230         end loop;
9231
9232         if No (Cond) then
9233            return Make_Null_Statement (Loc);
9234
9235         else
9236            return
9237              Make_Implicit_If_Statement (E,
9238                Condition       => Cond,
9239                Then_Statements => New_List (
9240                  Make_Simple_Return_Statement (Loc,
9241                    Expression => New_Occurrence_Of (Standard_False, Loc))));
9242         end if;
9243      end if;
9244   end Make_Eq_If;
9245
9246   -------------------
9247   -- Make_Neq_Body --
9248   -------------------
9249
9250   function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id is
9251
9252      function Is_Predefined_Neq_Renaming (Prim : Node_Id) return Boolean;
9253      --  Returns true if Prim is a renaming of an unresolved predefined
9254      --  inequality operation.
9255
9256      --------------------------------
9257      -- Is_Predefined_Neq_Renaming --
9258      --------------------------------
9259
9260      function Is_Predefined_Neq_Renaming (Prim : Node_Id) return Boolean is
9261      begin
9262         return Chars (Prim) /= Name_Op_Ne
9263           and then Present (Alias (Prim))
9264           and then Comes_From_Source (Prim)
9265           and then Is_Intrinsic_Subprogram (Alias (Prim))
9266           and then Chars (Alias (Prim)) = Name_Op_Ne;
9267      end Is_Predefined_Neq_Renaming;
9268
9269      --  Local variables
9270
9271      Loc           : constant Source_Ptr := Sloc (Parent (Tag_Typ));
9272      Stmts         : constant List_Id    := New_List;
9273      Decl          : Node_Id;
9274      Eq_Prim       : Entity_Id;
9275      Left_Op       : Entity_Id;
9276      Renaming_Prim : Entity_Id;
9277      Right_Op      : Entity_Id;
9278      Target        : Entity_Id;
9279
9280   --  Start of processing for Make_Neq_Body
9281
9282   begin
9283      --  For a call on a renaming of a dispatching subprogram that is
9284      --  overridden, if the overriding occurred before the renaming, then
9285      --  the body executed is that of the overriding declaration, even if the
9286      --  overriding declaration is not visible at the place of the renaming;
9287      --  otherwise, the inherited or predefined subprogram is called, see
9288      --  (RM 8.5.4(8))
9289
9290      --  Stage 1: Search for a renaming of the inequality primitive and also
9291      --  search for an overriding of the equality primitive located before the
9292      --  renaming declaration.
9293
9294      declare
9295         Elmt : Elmt_Id;
9296         Prim : Node_Id;
9297
9298      begin
9299         Eq_Prim       := Empty;
9300         Renaming_Prim := Empty;
9301
9302         Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
9303         while Present (Elmt) loop
9304            Prim := Node (Elmt);
9305
9306            if Is_User_Defined_Equality (Prim) and then No (Alias (Prim)) then
9307               if No (Renaming_Prim) then
9308                  pragma Assert (No (Eq_Prim));
9309                  Eq_Prim := Prim;
9310               end if;
9311
9312            elsif Is_Predefined_Neq_Renaming (Prim) then
9313               Renaming_Prim := Prim;
9314            end if;
9315
9316            Next_Elmt (Elmt);
9317         end loop;
9318      end;
9319
9320      --  No further action needed if no renaming was found
9321
9322      if No (Renaming_Prim) then
9323         return Empty;
9324      end if;
9325
9326      --  Stage 2: Replace the renaming declaration by a subprogram declaration
9327      --  (required to add its body)
9328
9329      Decl := Parent (Parent (Renaming_Prim));
9330      Rewrite (Decl,
9331        Make_Subprogram_Declaration (Loc,
9332          Specification => Specification (Decl)));
9333      Set_Analyzed (Decl);
9334
9335      --  Remove the decoration of intrinsic renaming subprogram
9336
9337      Set_Is_Intrinsic_Subprogram (Renaming_Prim, False);
9338      Set_Convention (Renaming_Prim, Convention_Ada);
9339      Set_Alias (Renaming_Prim, Empty);
9340      Set_Has_Completion (Renaming_Prim, False);
9341
9342      --  Stage 3: Build the corresponding body
9343
9344      Left_Op  := First_Formal (Renaming_Prim);
9345      Right_Op := Next_Formal (Left_Op);
9346
9347      Decl :=
9348        Predef_Spec_Or_Body (Loc,
9349          Tag_Typ => Tag_Typ,
9350          Name    => Chars (Renaming_Prim),
9351          Profile => New_List (
9352            Make_Parameter_Specification (Loc,
9353              Defining_Identifier =>
9354                Make_Defining_Identifier (Loc, Chars (Left_Op)),
9355              Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),
9356
9357            Make_Parameter_Specification (Loc,
9358              Defining_Identifier =>
9359                Make_Defining_Identifier (Loc, Chars (Right_Op)),
9360              Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
9361
9362          Ret_Type => Standard_Boolean,
9363          For_Body => True);
9364
9365      --  If the overriding of the equality primitive occurred before the
9366      --  renaming, then generate:
9367
9368      --    function <Neq_Name> (X : Y : Typ) return Boolean is
9369      --    begin
9370      --       return not Oeq (X, Y);
9371      --    end;
9372
9373      if Present (Eq_Prim) then
9374         Target := Eq_Prim;
9375
9376      --  Otherwise build a nested subprogram which performs the predefined
9377      --  evaluation of the equality operator. That is, generate:
9378
9379      --    function <Neq_Name> (X : Y : Typ) return Boolean is
9380      --       function Oeq (X : Y) return Boolean is
9381      --       begin
9382      --          <<body of default implementation>>
9383      --       end;
9384      --    begin
9385      --       return not Oeq (X, Y);
9386      --    end;
9387
9388      else
9389         declare
9390            Local_Subp : Node_Id;
9391         begin
9392            Local_Subp := Make_Eq_Body (Tag_Typ, Name_Op_Eq);
9393            Set_Declarations (Decl, New_List (Local_Subp));
9394            Target := Defining_Entity (Local_Subp);
9395         end;
9396      end if;
9397
9398      Append_To (Stmts,
9399        Make_Simple_Return_Statement (Loc,
9400          Expression =>
9401            Make_Op_Not (Loc,
9402              Make_Function_Call (Loc,
9403                Name                   => New_Occurrence_Of (Target, Loc),
9404                Parameter_Associations => New_List (
9405                  Make_Identifier (Loc, Chars (Left_Op)),
9406                  Make_Identifier (Loc, Chars (Right_Op)))))));
9407
9408      Set_Handled_Statement_Sequence
9409        (Decl, Make_Handled_Sequence_Of_Statements (Loc, Stmts));
9410      return Decl;
9411   end Make_Neq_Body;
9412
9413   -------------------------------
9414   -- Make_Null_Procedure_Specs --
9415   -------------------------------
9416
9417   function Make_Null_Procedure_Specs (Tag_Typ : Entity_Id) return List_Id is
9418      Decl_List      : constant List_Id    := New_List;
9419      Loc            : constant Source_Ptr := Sloc (Tag_Typ);
9420      Formal         : Entity_Id;
9421      Formal_List    : List_Id;
9422      New_Param_Spec : Node_Id;
9423      Parent_Subp    : Entity_Id;
9424      Prim_Elmt      : Elmt_Id;
9425      Subp           : Entity_Id;
9426
9427   begin
9428      Prim_Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
9429      while Present (Prim_Elmt) loop
9430         Subp := Node (Prim_Elmt);
9431
9432         --  If a null procedure inherited from an interface has not been
9433         --  overridden, then we build a null procedure declaration to
9434         --  override the inherited procedure.
9435
9436         Parent_Subp := Alias (Subp);
9437
9438         if Present (Parent_Subp)
9439           and then Is_Null_Interface_Primitive (Parent_Subp)
9440         then
9441            Formal_List := No_List;
9442            Formal := First_Formal (Subp);
9443
9444            if Present (Formal) then
9445               Formal_List := New_List;
9446
9447               while Present (Formal) loop
9448
9449                  --  Copy the parameter spec including default expressions
9450
9451                  New_Param_Spec :=
9452                    New_Copy_Tree (Parent (Formal), New_Sloc => Loc);
9453
9454                  --  Generate a new defining identifier for the new formal.
9455                  --  required because New_Copy_Tree does not duplicate
9456                  --  semantic fields (except itypes).
9457
9458                  Set_Defining_Identifier (New_Param_Spec,
9459                    Make_Defining_Identifier (Sloc (Formal),
9460                      Chars => Chars (Formal)));
9461
9462                  --  For controlling arguments we must change their
9463                  --  parameter type to reference the tagged type (instead
9464                  --  of the interface type)
9465
9466                  if Is_Controlling_Formal (Formal) then
9467                     if Nkind (Parameter_Type (Parent (Formal))) = N_Identifier
9468                     then
9469                        Set_Parameter_Type (New_Param_Spec,
9470                          New_Occurrence_Of (Tag_Typ, Loc));
9471
9472                     else pragma Assert
9473                            (Nkind (Parameter_Type (Parent (Formal))) =
9474                                                        N_Access_Definition);
9475                        Set_Subtype_Mark (Parameter_Type (New_Param_Spec),
9476                          New_Occurrence_Of (Tag_Typ, Loc));
9477                     end if;
9478                  end if;
9479
9480                  Append (New_Param_Spec, Formal_List);
9481
9482                  Next_Formal (Formal);
9483               end loop;
9484            end if;
9485
9486            Append_To (Decl_List,
9487              Make_Subprogram_Declaration (Loc,
9488                Make_Procedure_Specification (Loc,
9489                  Defining_Unit_Name       =>
9490                    Make_Defining_Identifier (Loc, Chars (Subp)),
9491                  Parameter_Specifications => Formal_List,
9492                  Null_Present             => True)));
9493         end if;
9494
9495         Next_Elmt (Prim_Elmt);
9496      end loop;
9497
9498      return Decl_List;
9499   end Make_Null_Procedure_Specs;
9500
9501   -------------------------------------
9502   -- Make_Predefined_Primitive_Specs --
9503   -------------------------------------
9504
9505   procedure Make_Predefined_Primitive_Specs
9506     (Tag_Typ     : Entity_Id;
9507      Predef_List : out List_Id;
9508      Renamed_Eq  : out Entity_Id)
9509   is
9510      function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean;
9511      --  Returns true if Prim is a renaming of an unresolved predefined
9512      --  equality operation.
9513
9514      -------------------------------
9515      -- Is_Predefined_Eq_Renaming --
9516      -------------------------------
9517
9518      function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean is
9519      begin
9520         return Chars (Prim) /= Name_Op_Eq
9521           and then Present (Alias (Prim))
9522           and then Comes_From_Source (Prim)
9523           and then Is_Intrinsic_Subprogram (Alias (Prim))
9524           and then Chars (Alias (Prim)) = Name_Op_Eq;
9525      end Is_Predefined_Eq_Renaming;
9526
9527      --  Local variables
9528
9529      Loc       : constant Source_Ptr := Sloc (Tag_Typ);
9530      Res       : constant List_Id    := New_List;
9531      Eq_Name   : Name_Id             := Name_Op_Eq;
9532      Eq_Needed : Boolean;
9533      Eq_Spec   : Node_Id;
9534      Prim      : Elmt_Id;
9535
9536      Has_Predef_Eq_Renaming : Boolean := False;
9537      --  Set to True if Tag_Typ has a primitive that renames the predefined
9538      --  equality operator. Used to implement (RM 8-5-4(8)).
9539
9540   --  Start of processing for Make_Predefined_Primitive_Specs
9541
9542   begin
9543      Renamed_Eq := Empty;
9544
9545      --  Spec of _Size
9546
9547      Append_To (Res, Predef_Spec_Or_Body (Loc,
9548        Tag_Typ => Tag_Typ,
9549        Name    => Name_uSize,
9550        Profile => New_List (
9551          Make_Parameter_Specification (Loc,
9552            Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
9553            Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
9554
9555        Ret_Type => Standard_Long_Long_Integer));
9556
9557      --  Specs for dispatching stream attributes
9558
9559      declare
9560         Stream_Op_TSS_Names :
9561           constant array (Positive range <>) of TSS_Name_Type :=
9562             (TSS_Stream_Read,
9563              TSS_Stream_Write,
9564              TSS_Stream_Input,
9565              TSS_Stream_Output);
9566
9567      begin
9568         for Op in Stream_Op_TSS_Names'Range loop
9569            if Stream_Operation_OK (Tag_Typ, Stream_Op_TSS_Names (Op)) then
9570               Append_To (Res,
9571                 Predef_Stream_Attr_Spec (Loc, Tag_Typ,
9572                  Stream_Op_TSS_Names (Op)));
9573            end if;
9574         end loop;
9575      end;
9576
9577      --  Spec of "=" is expanded if the type is not limited and if a user
9578      --  defined "=" was not already declared for the non-full view of a
9579      --  private extension
9580
9581      if not Is_Limited_Type (Tag_Typ) then
9582         Eq_Needed := True;
9583         Prim := First_Elmt (Primitive_Operations (Tag_Typ));
9584         while Present (Prim) loop
9585
9586            --  If a primitive is encountered that renames the predefined
9587            --  equality operator before reaching any explicit equality
9588            --  primitive, then we still need to create a predefined equality
9589            --  function, because calls to it can occur via the renaming. A
9590            --  new name is created for the equality to avoid conflicting with
9591            --  any user-defined equality. (Note that this doesn't account for
9592            --  renamings of equality nested within subpackages???)
9593
9594            if Is_Predefined_Eq_Renaming (Node (Prim)) then
9595               Has_Predef_Eq_Renaming := True;
9596               Eq_Name := New_External_Name (Chars (Node (Prim)), 'E');
9597
9598            --  User-defined equality
9599
9600            elsif Is_User_Defined_Equality (Node (Prim)) then
9601               if No (Alias (Node (Prim)))
9602                 or else Nkind (Unit_Declaration_Node (Node (Prim))) =
9603                           N_Subprogram_Renaming_Declaration
9604               then
9605                  Eq_Needed := False;
9606                  exit;
9607
9608               --  If the parent is not an interface type and has an abstract
9609               --  equality function explicitly defined in the sources, then
9610               --  the inherited equality is abstract as well, and no body can
9611               --  be created for it.
9612
9613               elsif not Is_Interface (Etype (Tag_Typ))
9614                 and then Present (Alias (Node (Prim)))
9615                 and then Comes_From_Source (Alias (Node (Prim)))
9616                 and then Is_Abstract_Subprogram (Alias (Node (Prim)))
9617               then
9618                  Eq_Needed := False;
9619                  exit;
9620
9621               --  If the type has an equality function corresponding with
9622               --  a primitive defined in an interface type, the inherited
9623               --  equality is abstract as well, and no body can be created
9624               --  for it.
9625
9626               elsif Present (Alias (Node (Prim)))
9627                 and then Comes_From_Source (Ultimate_Alias (Node (Prim)))
9628                 and then
9629                   Is_Interface
9630                     (Find_Dispatching_Type (Ultimate_Alias (Node (Prim))))
9631               then
9632                  Eq_Needed := False;
9633                  exit;
9634               end if;
9635            end if;
9636
9637            Next_Elmt (Prim);
9638         end loop;
9639
9640         --  If a renaming of predefined equality was found but there was no
9641         --  user-defined equality (so Eq_Needed is still true), then set the
9642         --  name back to Name_Op_Eq. But in the case where a user-defined
9643         --  equality was located after such a renaming, then the predefined
9644         --  equality function is still needed, so Eq_Needed must be set back
9645         --  to True.
9646
9647         if Eq_Name /= Name_Op_Eq then
9648            if Eq_Needed then
9649               Eq_Name := Name_Op_Eq;
9650            else
9651               Eq_Needed := True;
9652            end if;
9653         end if;
9654
9655         if Eq_Needed then
9656            Eq_Spec := Predef_Spec_Or_Body (Loc,
9657              Tag_Typ => Tag_Typ,
9658              Name    => Eq_Name,
9659              Profile => New_List (
9660                Make_Parameter_Specification (Loc,
9661                  Defining_Identifier =>
9662                    Make_Defining_Identifier (Loc, Name_X),
9663                  Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),
9664
9665                Make_Parameter_Specification (Loc,
9666                  Defining_Identifier =>
9667                    Make_Defining_Identifier (Loc, Name_Y),
9668                  Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
9669                Ret_Type => Standard_Boolean);
9670            Append_To (Res, Eq_Spec);
9671
9672            if Has_Predef_Eq_Renaming then
9673               Renamed_Eq := Defining_Unit_Name (Specification (Eq_Spec));
9674
9675               Prim := First_Elmt (Primitive_Operations (Tag_Typ));
9676               while Present (Prim) loop
9677
9678                  --  Any renamings of equality that appeared before an
9679                  --  overriding equality must be updated to refer to the
9680                  --  entity for the predefined equality, otherwise calls via
9681                  --  the renaming would get incorrectly resolved to call the
9682                  --  user-defined equality function.
9683
9684                  if Is_Predefined_Eq_Renaming (Node (Prim)) then
9685                     Set_Alias (Node (Prim), Renamed_Eq);
9686
9687                  --  Exit upon encountering a user-defined equality
9688
9689                  elsif Chars (Node (Prim)) = Name_Op_Eq
9690                    and then No (Alias (Node (Prim)))
9691                  then
9692                     exit;
9693                  end if;
9694
9695                  Next_Elmt (Prim);
9696               end loop;
9697            end if;
9698         end if;
9699
9700         --  Spec for dispatching assignment
9701
9702         Append_To (Res, Predef_Spec_Or_Body (Loc,
9703           Tag_Typ => Tag_Typ,
9704           Name    => Name_uAssign,
9705           Profile => New_List (
9706             Make_Parameter_Specification (Loc,
9707               Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
9708               Out_Present         => True,
9709               Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),
9710
9711             Make_Parameter_Specification (Loc,
9712               Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
9713               Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)))));
9714      end if;
9715
9716      --  Ada 2005: Generate declarations for the following primitive
9717      --  operations for limited interfaces and synchronized types that
9718      --  implement a limited interface.
9719
9720      --    Disp_Asynchronous_Select
9721      --    Disp_Conditional_Select
9722      --    Disp_Get_Prim_Op_Kind
9723      --    Disp_Get_Task_Id
9724      --    Disp_Requeue
9725      --    Disp_Timed_Select
9726
9727      --  Disable the generation of these bodies if No_Dispatching_Calls,
9728      --  Ravenscar or ZFP is active.
9729
9730      if Ada_Version >= Ada_2005
9731        and then not Restriction_Active (No_Dispatching_Calls)
9732        and then not Restriction_Active (No_Select_Statements)
9733        and then RTE_Available (RE_Select_Specific_Data)
9734      then
9735         --  These primitives are defined abstract in interface types
9736
9737         if Is_Interface (Tag_Typ)
9738           and then Is_Limited_Record (Tag_Typ)
9739         then
9740            Append_To (Res,
9741              Make_Abstract_Subprogram_Declaration (Loc,
9742                Specification =>
9743                  Make_Disp_Asynchronous_Select_Spec (Tag_Typ)));
9744
9745            Append_To (Res,
9746              Make_Abstract_Subprogram_Declaration (Loc,
9747                Specification =>
9748                  Make_Disp_Conditional_Select_Spec (Tag_Typ)));
9749
9750            Append_To (Res,
9751              Make_Abstract_Subprogram_Declaration (Loc,
9752                Specification =>
9753                  Make_Disp_Get_Prim_Op_Kind_Spec (Tag_Typ)));
9754
9755            Append_To (Res,
9756              Make_Abstract_Subprogram_Declaration (Loc,
9757                Specification =>
9758                  Make_Disp_Get_Task_Id_Spec (Tag_Typ)));
9759
9760            Append_To (Res,
9761              Make_Abstract_Subprogram_Declaration (Loc,
9762                Specification =>
9763                  Make_Disp_Requeue_Spec (Tag_Typ)));
9764
9765            Append_To (Res,
9766              Make_Abstract_Subprogram_Declaration (Loc,
9767                Specification =>
9768                  Make_Disp_Timed_Select_Spec (Tag_Typ)));
9769
9770         --  If ancestor is an interface type, declare non-abstract primitives
9771         --  to override the abstract primitives of the interface type.
9772
9773         --  In VM targets we define these primitives in all root tagged types
9774         --  that are not interface types. Done because in VM targets we don't
9775         --  have secondary dispatch tables and any derivation of Tag_Typ may
9776         --  cover limited interfaces (which always have these primitives since
9777         --  they may be ancestors of synchronized interface types).
9778
9779         elsif (not Is_Interface (Tag_Typ)
9780                 and then Is_Interface (Etype (Tag_Typ))
9781                 and then Is_Limited_Record (Etype (Tag_Typ)))
9782             or else
9783               (Is_Concurrent_Record_Type (Tag_Typ)
9784                 and then Has_Interfaces (Tag_Typ))
9785             or else
9786               (not Tagged_Type_Expansion
9787                 and then not Is_Interface (Tag_Typ)
9788                 and then Tag_Typ = Root_Type (Tag_Typ))
9789         then
9790            Append_To (Res,
9791              Make_Subprogram_Declaration (Loc,
9792                Specification =>
9793                  Make_Disp_Asynchronous_Select_Spec (Tag_Typ)));
9794
9795            Append_To (Res,
9796              Make_Subprogram_Declaration (Loc,
9797                Specification =>
9798                  Make_Disp_Conditional_Select_Spec (Tag_Typ)));
9799
9800            Append_To (Res,
9801              Make_Subprogram_Declaration (Loc,
9802                Specification =>
9803                  Make_Disp_Get_Prim_Op_Kind_Spec (Tag_Typ)));
9804
9805            Append_To (Res,
9806              Make_Subprogram_Declaration (Loc,
9807                Specification =>
9808                  Make_Disp_Get_Task_Id_Spec (Tag_Typ)));
9809
9810            Append_To (Res,
9811              Make_Subprogram_Declaration (Loc,
9812                Specification =>
9813                  Make_Disp_Requeue_Spec (Tag_Typ)));
9814
9815            Append_To (Res,
9816              Make_Subprogram_Declaration (Loc,
9817                Specification =>
9818                  Make_Disp_Timed_Select_Spec (Tag_Typ)));
9819         end if;
9820      end if;
9821
9822      --  All tagged types receive their own Deep_Adjust and Deep_Finalize
9823      --  regardless of whether they are controlled or may contain controlled
9824      --  components.
9825
9826      --  Do not generate the routines if finalization is disabled
9827
9828      if Restriction_Active (No_Finalization) then
9829         null;
9830
9831      else
9832         if not Is_Limited_Type (Tag_Typ) then
9833            Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust));
9834         end if;
9835
9836         Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize));
9837      end if;
9838
9839      Predef_List := Res;
9840   end Make_Predefined_Primitive_Specs;
9841
9842   -------------------------
9843   -- Make_Tag_Assignment --
9844   -------------------------
9845
9846   function Make_Tag_Assignment (N : Node_Id) return Node_Id is
9847      Loc      : constant Source_Ptr := Sloc (N);
9848      Def_If   : constant Entity_Id := Defining_Identifier (N);
9849      Expr     : constant Node_Id := Expression (N);
9850      Typ      : constant Entity_Id := Etype (Def_If);
9851      Full_Typ : constant Entity_Id := Underlying_Type (Typ);
9852      New_Ref  : Node_Id;
9853
9854   begin
9855      --  This expansion activity is called during analysis, but cannot
9856      --  be applied in ASIS mode when other expansion is disabled.
9857
9858      if Is_Tagged_Type (Typ)
9859       and then not Is_Class_Wide_Type (Typ)
9860       and then not Is_CPP_Class (Typ)
9861       and then Tagged_Type_Expansion
9862       and then Nkind (Expr) /= N_Aggregate
9863       and then not ASIS_Mode
9864       and then (Nkind (Expr) /= N_Qualified_Expression
9865                  or else Nkind (Expression (Expr)) /= N_Aggregate)
9866      then
9867         New_Ref :=
9868           Make_Selected_Component (Loc,
9869              Prefix        => New_Occurrence_Of (Def_If, Loc),
9870              Selector_Name =>
9871                New_Occurrence_Of (First_Tag_Component (Full_Typ), Loc));
9872         Set_Assignment_OK (New_Ref);
9873
9874         return
9875           Make_Assignment_Statement (Loc,
9876              Name       => New_Ref,
9877              Expression =>
9878                Unchecked_Convert_To (RTE (RE_Tag),
9879                  New_Occurrence_Of (Node
9880                      (First_Elmt (Access_Disp_Table (Full_Typ))), Loc)));
9881      else
9882         return Empty;
9883      end if;
9884   end Make_Tag_Assignment;
9885
9886   ---------------------------------
9887   -- Needs_Simple_Initialization --
9888   ---------------------------------
9889
9890   function Needs_Simple_Initialization
9891     (T           : Entity_Id;
9892      Consider_IS : Boolean := True) return Boolean
9893   is
9894      Consider_IS_NS : constant Boolean :=
9895        Normalize_Scalars or (Initialize_Scalars and Consider_IS);
9896
9897   begin
9898      --  Never need initialization if it is suppressed
9899
9900      if Initialization_Suppressed (T) then
9901         return False;
9902      end if;
9903
9904      --  Check for private type, in which case test applies to the underlying
9905      --  type of the private type.
9906
9907      if Is_Private_Type (T) then
9908         declare
9909            RT : constant Entity_Id := Underlying_Type (T);
9910         begin
9911            if Present (RT) then
9912               return Needs_Simple_Initialization (RT);
9913            else
9914               return False;
9915            end if;
9916         end;
9917
9918      --  Scalar type with Default_Value aspect requires initialization
9919
9920      elsif Is_Scalar_Type (T) and then Has_Default_Aspect (T) then
9921         return True;
9922
9923      --  Cases needing simple initialization are access types, and, if pragma
9924      --  Normalize_Scalars or Initialize_Scalars is in effect, then all scalar
9925      --  types.
9926
9927      elsif Is_Access_Type (T)
9928        or else (Consider_IS_NS and then (Is_Scalar_Type (T)))
9929      then
9930         return True;
9931
9932      --  If Initialize/Normalize_Scalars is in effect, string objects also
9933      --  need initialization, unless they are created in the course of
9934      --  expanding an aggregate (since in the latter case they will be
9935      --  filled with appropriate initializing values before they are used).
9936
9937      elsif Consider_IS_NS
9938        and then Is_Standard_String_Type (T)
9939        and then
9940          (not Is_Itype (T)
9941            or else Nkind (Associated_Node_For_Itype (T)) /= N_Aggregate)
9942      then
9943         return True;
9944
9945      else
9946         return False;
9947      end if;
9948   end Needs_Simple_Initialization;
9949
9950   ----------------------
9951   -- Predef_Deep_Spec --
9952   ----------------------
9953
9954   function Predef_Deep_Spec
9955     (Loc      : Source_Ptr;
9956      Tag_Typ  : Entity_Id;
9957      Name     : TSS_Name_Type;
9958      For_Body : Boolean := False) return Node_Id
9959   is
9960      Formals : List_Id;
9961
9962   begin
9963      --  V : in out Tag_Typ
9964
9965      Formals := New_List (
9966        Make_Parameter_Specification (Loc,
9967          Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
9968          In_Present          => True,
9969          Out_Present         => True,
9970          Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)));
9971
9972      --  F : Boolean := True
9973
9974      if Name = TSS_Deep_Adjust
9975        or else Name = TSS_Deep_Finalize
9976      then
9977         Append_To (Formals,
9978           Make_Parameter_Specification (Loc,
9979             Defining_Identifier => Make_Defining_Identifier (Loc, Name_F),
9980             Parameter_Type      => New_Occurrence_Of (Standard_Boolean, Loc),
9981             Expression          => New_Occurrence_Of (Standard_True, Loc)));
9982      end if;
9983
9984      return
9985        Predef_Spec_Or_Body (Loc,
9986          Name     => Make_TSS_Name (Tag_Typ, Name),
9987          Tag_Typ  => Tag_Typ,
9988          Profile  => Formals,
9989          For_Body => For_Body);
9990
9991   exception
9992      when RE_Not_Available =>
9993         return Empty;
9994   end Predef_Deep_Spec;
9995
9996   -------------------------
9997   -- Predef_Spec_Or_Body --
9998   -------------------------
9999
10000   function Predef_Spec_Or_Body
10001     (Loc      : Source_Ptr;
10002      Tag_Typ  : Entity_Id;
10003      Name     : Name_Id;
10004      Profile  : List_Id;
10005      Ret_Type : Entity_Id := Empty;
10006      For_Body : Boolean := False) return Node_Id
10007   is
10008      Id   : constant Entity_Id := Make_Defining_Identifier (Loc, Name);
10009      Spec : Node_Id;
10010
10011   begin
10012      Set_Is_Public (Id, Is_Public (Tag_Typ));
10013
10014      --  The internal flag is set to mark these declarations because they have
10015      --  specific properties. First, they are primitives even if they are not
10016      --  defined in the type scope (the freezing point is not necessarily in
10017      --  the same scope). Second, the predefined equality can be overridden by
10018      --  a user-defined equality, no body will be generated in this case.
10019
10020      Set_Is_Internal (Id);
10021
10022      if not Debug_Generated_Code then
10023         Set_Debug_Info_Off (Id);
10024      end if;
10025
10026      if No (Ret_Type) then
10027         Spec :=
10028           Make_Procedure_Specification (Loc,
10029             Defining_Unit_Name       => Id,
10030             Parameter_Specifications => Profile);
10031      else
10032         Spec :=
10033           Make_Function_Specification (Loc,
10034             Defining_Unit_Name       => Id,
10035             Parameter_Specifications => Profile,
10036             Result_Definition        => New_Occurrence_Of (Ret_Type, Loc));
10037      end if;
10038
10039      if Is_Interface (Tag_Typ) then
10040         return Make_Abstract_Subprogram_Declaration (Loc, Spec);
10041
10042      --  If body case, return empty subprogram body. Note that this is ill-
10043      --  formed, because there is not even a null statement, and certainly not
10044      --  a return in the function case. The caller is expected to do surgery
10045      --  on the body to add the appropriate stuff.
10046
10047      elsif For_Body then
10048         return Make_Subprogram_Body (Loc, Spec, Empty_List, Empty);
10049
10050      --  For the case of an Input attribute predefined for an abstract type,
10051      --  generate an abstract specification. This will never be called, but we
10052      --  need the slot allocated in the dispatching table so that attributes
10053      --  typ'Class'Input and typ'Class'Output will work properly.
10054
10055      elsif Is_TSS (Name, TSS_Stream_Input)
10056        and then Is_Abstract_Type (Tag_Typ)
10057      then
10058         return Make_Abstract_Subprogram_Declaration (Loc, Spec);
10059
10060      --  Normal spec case, where we return a subprogram declaration
10061
10062      else
10063         return Make_Subprogram_Declaration (Loc, Spec);
10064      end if;
10065   end Predef_Spec_Or_Body;
10066
10067   -----------------------------
10068   -- Predef_Stream_Attr_Spec --
10069   -----------------------------
10070
10071   function Predef_Stream_Attr_Spec
10072     (Loc      : Source_Ptr;
10073      Tag_Typ  : Entity_Id;
10074      Name     : TSS_Name_Type;
10075      For_Body : Boolean := False) return Node_Id
10076   is
10077      Ret_Type : Entity_Id;
10078
10079   begin
10080      if Name = TSS_Stream_Input then
10081         Ret_Type := Tag_Typ;
10082      else
10083         Ret_Type := Empty;
10084      end if;
10085
10086      return
10087        Predef_Spec_Or_Body
10088          (Loc,
10089           Name     => Make_TSS_Name (Tag_Typ, Name),
10090           Tag_Typ  => Tag_Typ,
10091           Profile  => Build_Stream_Attr_Profile (Loc, Tag_Typ, Name),
10092           Ret_Type => Ret_Type,
10093           For_Body => For_Body);
10094   end Predef_Stream_Attr_Spec;
10095
10096   ---------------------------------
10097   -- Predefined_Primitive_Bodies --
10098   ---------------------------------
10099
10100   function Predefined_Primitive_Bodies
10101     (Tag_Typ    : Entity_Id;
10102      Renamed_Eq : Entity_Id) return List_Id
10103   is
10104      Loc       : constant Source_Ptr := Sloc (Tag_Typ);
10105      Res       : constant List_Id    := New_List;
10106      Adj_Call  : Node_Id;
10107      Decl      : Node_Id;
10108      Fin_Call  : Node_Id;
10109      Prim      : Elmt_Id;
10110      Eq_Needed : Boolean;
10111      Eq_Name   : Name_Id;
10112      Ent       : Entity_Id;
10113
10114      pragma Warnings (Off, Ent);
10115
10116   begin
10117      pragma Assert (not Is_Interface (Tag_Typ));
10118
10119      --  See if we have a predefined "=" operator
10120
10121      if Present (Renamed_Eq) then
10122         Eq_Needed := True;
10123         Eq_Name   := Chars (Renamed_Eq);
10124
10125      --  If the parent is an interface type then it has defined all the
10126      --  predefined primitives abstract and we need to check if the type
10127      --  has some user defined "=" function which matches the profile of
10128      --  the Ada predefined equality operator to avoid generating it.
10129
10130      elsif Is_Interface (Etype (Tag_Typ)) then
10131         Eq_Needed := True;
10132         Eq_Name := Name_Op_Eq;
10133
10134         Prim := First_Elmt (Primitive_Operations (Tag_Typ));
10135         while Present (Prim) loop
10136            if Chars (Node (Prim)) = Name_Op_Eq
10137              and then not Is_Internal (Node (Prim))
10138              and then Present (First_Entity (Node (Prim)))
10139
10140              --  The predefined equality primitive must have exactly two
10141              --  formals whose type is this tagged type
10142
10143              and then Present (Last_Entity (Node (Prim)))
10144              and then Next_Entity (First_Entity (Node (Prim)))
10145                         = Last_Entity (Node (Prim))
10146              and then Etype (First_Entity (Node (Prim))) = Tag_Typ
10147              and then Etype (Last_Entity (Node (Prim))) = Tag_Typ
10148            then
10149               Eq_Needed := False;
10150               Eq_Name := No_Name;
10151               exit;
10152            end if;
10153
10154            Next_Elmt (Prim);
10155         end loop;
10156
10157      else
10158         Eq_Needed := False;
10159         Eq_Name   := No_Name;
10160
10161         Prim := First_Elmt (Primitive_Operations (Tag_Typ));
10162         while Present (Prim) loop
10163            if Chars (Node (Prim)) = Name_Op_Eq
10164              and then Is_Internal (Node (Prim))
10165            then
10166               Eq_Needed := True;
10167               Eq_Name := Name_Op_Eq;
10168               exit;
10169            end if;
10170
10171            Next_Elmt (Prim);
10172         end loop;
10173      end if;
10174
10175      --  Body of _Size
10176
10177      Decl := Predef_Spec_Or_Body (Loc,
10178        Tag_Typ => Tag_Typ,
10179        Name    => Name_uSize,
10180        Profile => New_List (
10181          Make_Parameter_Specification (Loc,
10182            Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
10183            Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
10184
10185        Ret_Type => Standard_Long_Long_Integer,
10186        For_Body => True);
10187
10188      Set_Handled_Statement_Sequence (Decl,
10189        Make_Handled_Sequence_Of_Statements (Loc, New_List (
10190          Make_Simple_Return_Statement (Loc,
10191            Expression =>
10192              Make_Attribute_Reference (Loc,
10193                Prefix          => Make_Identifier (Loc, Name_X),
10194                Attribute_Name  => Name_Size)))));
10195
10196      Append_To (Res, Decl);
10197
10198      --  Bodies for Dispatching stream IO routines. We need these only for
10199      --  non-limited types (in the limited case there is no dispatching).
10200      --  We also skip them if dispatching or finalization are not available
10201      --  or if stream operations are prohibited by restriction No_Streams or
10202      --  from use of pragma/aspect No_Tagged_Streams.
10203
10204      if Stream_Operation_OK (Tag_Typ, TSS_Stream_Read)
10205        and then No (TSS (Tag_Typ, TSS_Stream_Read))
10206      then
10207         Build_Record_Read_Procedure (Loc, Tag_Typ, Decl, Ent);
10208         Append_To (Res, Decl);
10209      end if;
10210
10211      if Stream_Operation_OK (Tag_Typ, TSS_Stream_Write)
10212        and then No (TSS (Tag_Typ, TSS_Stream_Write))
10213      then
10214         Build_Record_Write_Procedure (Loc, Tag_Typ, Decl, Ent);
10215         Append_To (Res, Decl);
10216      end if;
10217
10218      --  Skip body of _Input for the abstract case, since the corresponding
10219      --  spec is abstract (see Predef_Spec_Or_Body).
10220
10221      if not Is_Abstract_Type (Tag_Typ)
10222        and then Stream_Operation_OK (Tag_Typ, TSS_Stream_Input)
10223        and then No (TSS (Tag_Typ, TSS_Stream_Input))
10224      then
10225         Build_Record_Or_Elementary_Input_Function
10226           (Loc, Tag_Typ, Decl, Ent);
10227         Append_To (Res, Decl);
10228      end if;
10229
10230      if Stream_Operation_OK (Tag_Typ, TSS_Stream_Output)
10231        and then No (TSS (Tag_Typ, TSS_Stream_Output))
10232      then
10233         Build_Record_Or_Elementary_Output_Procedure (Loc, Tag_Typ, Decl, Ent);
10234         Append_To (Res, Decl);
10235      end if;
10236
10237      --  Ada 2005: Generate bodies for the following primitive operations for
10238      --  limited interfaces and synchronized types that implement a limited
10239      --  interface.
10240
10241      --    disp_asynchronous_select
10242      --    disp_conditional_select
10243      --    disp_get_prim_op_kind
10244      --    disp_get_task_id
10245      --    disp_timed_select
10246
10247      --  The interface versions will have null bodies
10248
10249      --  Disable the generation of these bodies if No_Dispatching_Calls,
10250      --  Ravenscar or ZFP is active.
10251
10252      --  In VM targets we define these primitives in all root tagged types
10253      --  that are not interface types. Done because in VM targets we don't
10254      --  have secondary dispatch tables and any derivation of Tag_Typ may
10255      --  cover limited interfaces (which always have these primitives since
10256      --  they may be ancestors of synchronized interface types).
10257
10258      if Ada_Version >= Ada_2005
10259        and then not Is_Interface (Tag_Typ)
10260        and then
10261          ((Is_Interface (Etype (Tag_Typ))
10262             and then Is_Limited_Record (Etype (Tag_Typ)))
10263           or else
10264             (Is_Concurrent_Record_Type (Tag_Typ)
10265               and then Has_Interfaces (Tag_Typ))
10266           or else
10267             (not Tagged_Type_Expansion
10268               and then Tag_Typ = Root_Type (Tag_Typ)))
10269        and then not Restriction_Active (No_Dispatching_Calls)
10270        and then not Restriction_Active (No_Select_Statements)
10271        and then RTE_Available (RE_Select_Specific_Data)
10272      then
10273         Append_To (Res, Make_Disp_Asynchronous_Select_Body (Tag_Typ));
10274         Append_To (Res, Make_Disp_Conditional_Select_Body  (Tag_Typ));
10275         Append_To (Res, Make_Disp_Get_Prim_Op_Kind_Body    (Tag_Typ));
10276         Append_To (Res, Make_Disp_Get_Task_Id_Body         (Tag_Typ));
10277         Append_To (Res, Make_Disp_Requeue_Body             (Tag_Typ));
10278         Append_To (Res, Make_Disp_Timed_Select_Body        (Tag_Typ));
10279      end if;
10280
10281      if not Is_Limited_Type (Tag_Typ) and then not Is_Interface (Tag_Typ) then
10282
10283         --  Body for equality
10284
10285         if Eq_Needed then
10286            Decl := Make_Eq_Body (Tag_Typ, Eq_Name);
10287            Append_To (Res, Decl);
10288         end if;
10289
10290         --  Body for inequality (if required)
10291
10292         Decl := Make_Neq_Body (Tag_Typ);
10293
10294         if Present (Decl) then
10295            Append_To (Res, Decl);
10296         end if;
10297
10298         --  Body for dispatching assignment
10299
10300         Decl :=
10301           Predef_Spec_Or_Body (Loc,
10302             Tag_Typ => Tag_Typ,
10303             Name    => Name_uAssign,
10304             Profile => New_List (
10305               Make_Parameter_Specification (Loc,
10306                 Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
10307                 Out_Present         => True,
10308                 Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),
10309
10310               Make_Parameter_Specification (Loc,
10311                 Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
10312                 Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
10313             For_Body => True);
10314
10315         Set_Handled_Statement_Sequence (Decl,
10316           Make_Handled_Sequence_Of_Statements (Loc, New_List (
10317             Make_Assignment_Statement (Loc,
10318               Name       => Make_Identifier (Loc, Name_X),
10319               Expression => Make_Identifier (Loc, Name_Y)))));
10320
10321         Append_To (Res, Decl);
10322      end if;
10323
10324      --  Generate empty bodies of routines Deep_Adjust and Deep_Finalize for
10325      --  tagged types which do not contain controlled components.
10326
10327      --  Do not generate the routines if finalization is disabled
10328
10329      if Restriction_Active (No_Finalization) then
10330         null;
10331
10332      elsif not Has_Controlled_Component (Tag_Typ) then
10333         if not Is_Limited_Type (Tag_Typ) then
10334            Adj_Call := Empty;
10335            Decl     := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust, True);
10336
10337            if Is_Controlled (Tag_Typ) then
10338               Adj_Call :=
10339                 Make_Adjust_Call (
10340                   Obj_Ref => Make_Identifier (Loc, Name_V),
10341                   Typ     => Tag_Typ);
10342            end if;
10343
10344            if No (Adj_Call) then
10345               Adj_Call := Make_Null_Statement (Loc);
10346            end if;
10347
10348            Set_Handled_Statement_Sequence (Decl,
10349              Make_Handled_Sequence_Of_Statements (Loc,
10350                Statements => New_List (Adj_Call)));
10351
10352            Append_To (Res, Decl);
10353         end if;
10354
10355         Fin_Call := Empty;
10356         Decl     := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True);
10357
10358         if Is_Controlled (Tag_Typ) then
10359            Fin_Call :=
10360              Make_Final_Call
10361                (Obj_Ref => Make_Identifier (Loc, Name_V),
10362                 Typ     => Tag_Typ);
10363         end if;
10364
10365         if No (Fin_Call) then
10366            Fin_Call := Make_Null_Statement (Loc);
10367         end if;
10368
10369         Set_Handled_Statement_Sequence (Decl,
10370           Make_Handled_Sequence_Of_Statements (Loc,
10371             Statements => New_List (Fin_Call)));
10372
10373         Append_To (Res, Decl);
10374      end if;
10375
10376      return Res;
10377   end Predefined_Primitive_Bodies;
10378
10379   ---------------------------------
10380   -- Predefined_Primitive_Freeze --
10381   ---------------------------------
10382
10383   function Predefined_Primitive_Freeze
10384     (Tag_Typ : Entity_Id) return List_Id
10385   is
10386      Res     : constant List_Id := New_List;
10387      Prim    : Elmt_Id;
10388      Frnodes : List_Id;
10389
10390   begin
10391      Prim := First_Elmt (Primitive_Operations (Tag_Typ));
10392      while Present (Prim) loop
10393         if Is_Predefined_Dispatching_Operation (Node (Prim)) then
10394            Frnodes := Freeze_Entity (Node (Prim), Tag_Typ);
10395
10396            if Present (Frnodes) then
10397               Append_List_To (Res, Frnodes);
10398            end if;
10399         end if;
10400
10401         Next_Elmt (Prim);
10402      end loop;
10403
10404      return Res;
10405   end Predefined_Primitive_Freeze;
10406
10407   -------------------------
10408   -- Stream_Operation_OK --
10409   -------------------------
10410
10411   function Stream_Operation_OK
10412     (Typ       : Entity_Id;
10413      Operation : TSS_Name_Type) return Boolean
10414   is
10415      Has_Predefined_Or_Specified_Stream_Attribute : Boolean := False;
10416
10417   begin
10418      --  Special case of a limited type extension: a default implementation
10419      --  of the stream attributes Read or Write exists if that attribute
10420      --  has been specified or is available for an ancestor type; a default
10421      --  implementation of the attribute Output (resp. Input) exists if the
10422      --  attribute has been specified or Write (resp. Read) is available for
10423      --  an ancestor type. The last condition only applies under Ada 2005.
10424
10425      if Is_Limited_Type (Typ) and then Is_Tagged_Type (Typ) then
10426         if Operation = TSS_Stream_Read then
10427            Has_Predefined_Or_Specified_Stream_Attribute :=
10428              Has_Specified_Stream_Read (Typ);
10429
10430         elsif Operation = TSS_Stream_Write then
10431            Has_Predefined_Or_Specified_Stream_Attribute :=
10432              Has_Specified_Stream_Write (Typ);
10433
10434         elsif Operation = TSS_Stream_Input then
10435            Has_Predefined_Or_Specified_Stream_Attribute :=
10436              Has_Specified_Stream_Input (Typ)
10437                or else
10438                  (Ada_Version >= Ada_2005
10439                    and then Stream_Operation_OK (Typ, TSS_Stream_Read));
10440
10441         elsif Operation = TSS_Stream_Output then
10442            Has_Predefined_Or_Specified_Stream_Attribute :=
10443              Has_Specified_Stream_Output (Typ)
10444                or else
10445                  (Ada_Version >= Ada_2005
10446                    and then Stream_Operation_OK (Typ, TSS_Stream_Write));
10447         end if;
10448
10449         --  Case of inherited TSS_Stream_Read or TSS_Stream_Write
10450
10451         if not Has_Predefined_Or_Specified_Stream_Attribute
10452           and then Is_Derived_Type (Typ)
10453           and then (Operation = TSS_Stream_Read
10454                      or else Operation = TSS_Stream_Write)
10455         then
10456            Has_Predefined_Or_Specified_Stream_Attribute :=
10457              Present
10458                (Find_Inherited_TSS (Base_Type (Etype (Typ)), Operation));
10459         end if;
10460      end if;
10461
10462      --  If the type is not limited, or else is limited but the attribute is
10463      --  explicitly specified or is predefined for the type, then return True,
10464      --  unless other conditions prevail, such as restrictions prohibiting
10465      --  streams or dispatching operations. We also return True for limited
10466      --  interfaces, because they may be extended by nonlimited types and
10467      --  permit inheritance in this case (addresses cases where an abstract
10468      --  extension doesn't get 'Input declared, as per comments below, but
10469      --  'Class'Input must still be allowed). Note that attempts to apply
10470      --  stream attributes to a limited interface or its class-wide type
10471      --  (or limited extensions thereof) will still get properly rejected
10472      --  by Check_Stream_Attribute.
10473
10474      --  We exclude the Input operation from being a predefined subprogram in
10475      --  the case where the associated type is an abstract extension, because
10476      --  the attribute is not callable in that case, per 13.13.2(49/2). Also,
10477      --  we don't want an abstract version created because types derived from
10478      --  the abstract type may not even have Input available (for example if
10479      --  derived from a private view of the abstract type that doesn't have
10480      --  a visible Input).
10481
10482      --  Do not generate stream routines for type Finalization_Master because
10483      --  a master may never appear in types and therefore cannot be read or
10484      --  written.
10485
10486      return
10487          (not Is_Limited_Type (Typ)
10488            or else Is_Interface (Typ)
10489            or else Has_Predefined_Or_Specified_Stream_Attribute)
10490        and then
10491          (Operation /= TSS_Stream_Input
10492            or else not Is_Abstract_Type (Typ)
10493            or else not Is_Derived_Type (Typ))
10494        and then not Has_Unknown_Discriminants (Typ)
10495        and then not
10496          (Is_Interface (Typ)
10497            and then
10498              (Is_Task_Interface (Typ)
10499                or else Is_Protected_Interface (Typ)
10500                or else Is_Synchronized_Interface (Typ)))
10501        and then not Restriction_Active (No_Streams)
10502        and then not Restriction_Active (No_Dispatch)
10503        and then No (No_Tagged_Streams_Pragma (Typ))
10504        and then not No_Run_Time_Mode
10505        and then RTE_Available (RE_Tag)
10506        and then No (Type_Without_Stream_Operation (Typ))
10507        and then RTE_Available (RE_Root_Stream_Type)
10508        and then not Is_RTE (Typ, RE_Finalization_Master);
10509   end Stream_Operation_OK;
10510
10511end Exp_Ch3;
10512