1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                             E X P _ U T I L                              --
6--                                                                          --
7--                                 B o d y                                  --
8--                                                                          --
9--          Copyright (C) 1992-2020, 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 Casing;   use Casing;
29with Checks;   use Checks;
30with Debug;    use Debug;
31with Einfo;    use Einfo;
32with Elists;   use Elists;
33with Errout;   use Errout;
34with Exp_Aggr; use Exp_Aggr;
35with Exp_Ch6;  use Exp_Ch6;
36with Exp_Ch7;  use Exp_Ch7;
37with Exp_Ch11; use Exp_Ch11;
38with Ghost;    use Ghost;
39with Inline;   use Inline;
40with Itypes;   use Itypes;
41with Lib;      use Lib;
42with Nlists;   use Nlists;
43with Nmake;    use Nmake;
44with Opt;      use Opt;
45with Restrict; use Restrict;
46with Rident;   use Rident;
47with Sem;      use Sem;
48with Sem_Aux;  use Sem_Aux;
49with Sem_Ch3;  use Sem_Ch3;
50with Sem_Ch6;  use Sem_Ch6;
51with Sem_Ch8;  use Sem_Ch8;
52with Sem_Ch12; use Sem_Ch12;
53with Sem_Ch13; use Sem_Ch13;
54with Sem_Disp; use Sem_Disp;
55with Sem_Elab; use Sem_Elab;
56with Sem_Eval; use Sem_Eval;
57with Sem_Res;  use Sem_Res;
58with Sem_Type; use Sem_Type;
59with Sem_Util; use Sem_Util;
60with Snames;   use Snames;
61with Stand;    use Stand;
62with Stringt;  use Stringt;
63with Tbuild;   use Tbuild;
64with Ttypes;   use Ttypes;
65with Validsw;  use Validsw;
66
67with GNAT.HTable;
68package body Exp_Util is
69
70   ---------------------------------------------------------
71   -- Handling of inherited class-wide pre/postconditions --
72   ---------------------------------------------------------
73
74   --  Following AI12-0113, the expression for a class-wide condition is
75   --  transformed for a subprogram that inherits it, by replacing calls
76   --  to primitive operations of the original controlling type into the
77   --  corresponding overriding operations of the derived type. The following
78   --  hash table manages this mapping, and is expanded on demand whenever
79   --  such inherited expression needs to be constructed.
80
81   --  The mapping is also used to check whether an inherited operation has
82   --  a condition that depends on overridden operations. For such an
83   --  operation we must create a wrapper that is then treated as a normal
84   --  overriding. In SPARK mode such operations are illegal.
85
86   --  For a given root type there may be several type extensions with their
87   --  own overriding operations, so at various times a given operation of
88   --  the root will be mapped into different overridings. The root type is
89   --  also mapped into the current type extension to indicate that its
90   --  operations are mapped into the overriding operations of that current
91   --  type extension.
92
93   --  The contents of the map are as follows:
94
95   --    Key                                Value
96
97   --    Discriminant (Entity_Id)           Discriminant (Entity_Id)
98   --    Discriminant (Entity_Id)           Non-discriminant name (Entity_Id)
99   --    Discriminant (Entity_Id)           Expression (Node_Id)
100   --    Primitive subprogram (Entity_Id)   Primitive subprogram (Entity_Id)
101   --    Type (Entity_Id)                   Type (Entity_Id)
102
103   Type_Map_Size : constant := 511;
104
105   subtype Type_Map_Header is Integer range 0 .. Type_Map_Size - 1;
106   function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header;
107
108   package Type_Map is new GNAT.HTable.Simple_HTable
109     (Header_Num => Type_Map_Header,
110      Key        => Entity_Id,
111      Element    => Node_Or_Entity_Id,
112      No_element => Empty,
113      Hash       => Type_Map_Hash,
114      Equal      => "=");
115
116   -----------------------
117   -- Local Subprograms --
118   -----------------------
119
120   function Build_Task_Array_Image
121     (Loc    : Source_Ptr;
122      Id_Ref : Node_Id;
123      A_Type : Entity_Id;
124      Dyn    : Boolean := False) return Node_Id;
125   --  Build function to generate the image string for a task that is an array
126   --  component, concatenating the images of each index. To avoid storage
127   --  leaks, the string is built with successive slice assignments. The flag
128   --  Dyn indicates whether this is called for the initialization procedure of
129   --  an array of tasks, or for the name of a dynamically created task that is
130   --  assigned to an indexed component.
131
132   function Build_Task_Image_Function
133     (Loc   : Source_Ptr;
134      Decls : List_Id;
135      Stats : List_Id;
136      Res   : Entity_Id) return Node_Id;
137   --  Common processing for Task_Array_Image and Task_Record_Image. Build
138   --  function body that computes image.
139
140   procedure Build_Task_Image_Prefix
141      (Loc    : Source_Ptr;
142       Len    : out Entity_Id;
143       Res    : out Entity_Id;
144       Pos    : out Entity_Id;
145       Prefix : Entity_Id;
146       Sum    : Node_Id;
147       Decls  : List_Id;
148       Stats  : List_Id);
149   --  Common processing for Task_Array_Image and Task_Record_Image. Create
150   --  local variables and assign prefix of name to result string.
151
152   function Build_Task_Record_Image
153     (Loc    : Source_Ptr;
154      Id_Ref : Node_Id;
155      Dyn    : Boolean := False) return Node_Id;
156   --  Build function to generate the image string for a task that is a record
157   --  component. Concatenate name of variable with that of selector. The flag
158   --  Dyn indicates whether this is called for the initialization procedure of
159   --  record with task components, or for a dynamically created task that is
160   --  assigned to a selected component.
161
162   procedure Evaluate_Slice_Bounds (Slice : Node_Id);
163   --  Force evaluation of bounds of a slice, which may be given by a range
164   --  or by a subtype indication with or without a constraint.
165
166   function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean;
167   --  Determine whether pragma Default_Initial_Condition denoted by Prag has
168   --  an assertion expression that should be verified at run time.
169
170   function Is_Uninitialized_Aggregate
171     (Exp : Node_Id;
172      T   : Entity_Id) return Boolean;
173   --  Determine whether an array aggregate used in an object declaration
174   --  is uninitialized, when the aggregate is declared with a box and
175   --  the component type has no default value. Such an aggregate can be
176   --  optimized away to prevent the copying of uninitialized data, and
177   --  the bounds of the aggregate can be propagated directly to the
178   --  object declaration.
179
180   function Make_CW_Equivalent_Type
181     (T : Entity_Id;
182      E : Node_Id) return Entity_Id;
183   --  T is a class-wide type entity, E is the initial expression node that
184   --  constrains T in case such as: " X: T := E" or "new T'(E)". This function
185   --  returns the entity of the Equivalent type and inserts on the fly the
186   --  necessary declaration such as:
187   --
188   --    type anon is record
189   --       _parent : Root_Type (T); constrained with E discriminants (if any)
190   --       Extension : String (1 .. expr to match size of E);
191   --    end record;
192   --
193   --  This record is compatible with any object of the class of T thanks to
194   --  the first field and has the same size as E thanks to the second.
195
196   function Make_Literal_Range
197     (Loc         : Source_Ptr;
198      Literal_Typ : Entity_Id) return Node_Id;
199   --  Produce a Range node whose bounds are:
200   --    Low_Bound (Literal_Type) ..
201   --        Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
202   --  this is used for expanding declarations like X : String := "sdfgdfg";
203   --
204   --  If the index type of the target array is not integer, we generate:
205   --     Low_Bound (Literal_Type) ..
206   --        Literal_Type'Val
207   --          (Literal_Type'Pos (Low_Bound (Literal_Type))
208   --             + (Length (Literal_Typ) -1))
209
210   function Make_Non_Empty_Check
211     (Loc : Source_Ptr;
212      N   : Node_Id) return Node_Id;
213   --  Produce a boolean expression checking that the unidimensional array
214   --  node N is not empty.
215
216   function New_Class_Wide_Subtype
217     (CW_Typ : Entity_Id;
218      N      : Node_Id) return Entity_Id;
219   --  Create an implicit subtype of CW_Typ attached to node N
220
221   function Requires_Cleanup_Actions
222     (L                 : List_Id;
223      Lib_Level         : Boolean;
224      Nested_Constructs : Boolean) return Boolean;
225   --  Given a list L, determine whether it contains one of the following:
226   --
227   --    1) controlled objects
228   --    2) library-level tagged types
229   --
230   --  Lib_Level is True when the list comes from a construct at the library
231   --  level, and False otherwise. Nested_Constructs is True when any nested
232   --  packages declared in L must be processed, and False otherwise.
233
234   function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean;
235   --  Return True if the evaluation of the given attribute is considered
236   --  side-effect free, independently of its prefix and expressions.
237
238   -------------------------------------
239   -- Activate_Atomic_Synchronization --
240   -------------------------------------
241
242   procedure Activate_Atomic_Synchronization (N : Node_Id) is
243      Msg_Node : Node_Id;
244
245   begin
246      case Nkind (Parent (N)) is
247
248         --  Check for cases of appearing in the prefix of a construct where we
249         --  don't need atomic synchronization for this kind of usage.
250
251         when
252            --  Nothing to do if we are the prefix of an attribute, since we
253            --  do not want an atomic sync operation for things like 'Size.
254
255              N_Attribute_Reference
256
257            --  The N_Reference node is like an attribute
258
259            | N_Reference
260
261            --  Nothing to do for a reference to a component (or components)
262            --  of a composite object. Only reads and updates of the object
263            --  as a whole require atomic synchronization (RM C.6 (15)).
264
265            | N_Indexed_Component
266            | N_Selected_Component
267            | N_Slice
268         =>
269            --  For all the above cases, nothing to do if we are the prefix
270
271            if Prefix (Parent (N)) = N then
272               return;
273            end if;
274
275         when others =>
276            null;
277      end case;
278
279      --  Nothing to do for the identifier in an object renaming declaration,
280      --  the renaming itself does not need atomic synchronization.
281
282      if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
283         return;
284      end if;
285
286      --  Go ahead and set the flag
287
288      Set_Atomic_Sync_Required (N);
289
290      --  Generate info message if requested
291
292      if Warn_On_Atomic_Synchronization then
293         case Nkind (N) is
294            when N_Identifier =>
295               Msg_Node := N;
296
297            when N_Expanded_Name
298               | N_Selected_Component
299            =>
300               Msg_Node := Selector_Name (N);
301
302            when N_Explicit_Dereference
303               | N_Indexed_Component
304            =>
305               Msg_Node := Empty;
306
307            when others =>
308               pragma Assert (False);
309               return;
310         end case;
311
312         if Present (Msg_Node) then
313            Error_Msg_N
314              ("info: atomic synchronization set for &?N?", Msg_Node);
315         else
316            Error_Msg_N
317              ("info: atomic synchronization set?N?", N);
318         end if;
319      end if;
320   end Activate_Atomic_Synchronization;
321
322   ----------------------
323   -- Adjust_Condition --
324   ----------------------
325
326   procedure Adjust_Condition (N : Node_Id) is
327   begin
328      if No (N) then
329         return;
330      end if;
331
332      declare
333         Loc : constant Source_Ptr := Sloc (N);
334         T   : constant Entity_Id  := Etype (N);
335
336      begin
337         --  Defend against a call where the argument has no type, or has a
338         --  type that is not Boolean. This can occur because of prior errors.
339
340         if No (T) or else not Is_Boolean_Type (T) then
341            return;
342         end if;
343
344         --  Apply validity checking if needed
345
346         if Validity_Checks_On and Validity_Check_Tests then
347            Ensure_Valid (N);
348         end if;
349
350         --  Immediate return if standard boolean, the most common case,
351         --  where nothing needs to be done.
352
353         if Base_Type (T) = Standard_Boolean then
354            return;
355         end if;
356
357         --  Case of zero/nonzero semantics or nonstandard enumeration
358         --  representation. In each case, we rewrite the node as:
359
360         --      ityp!(N) /= False'Enum_Rep
361
362         --  where ityp is an integer type with large enough size to hold any
363         --  value of type T.
364
365         if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
366            Rewrite (N,
367              Make_Op_Ne (Loc,
368                Left_Opnd  =>
369                  Unchecked_Convert_To
370                    (Integer_Type_For (Esize (T), Uns => False), N),
371                Right_Opnd =>
372                  Make_Attribute_Reference (Loc,
373                    Attribute_Name => Name_Enum_Rep,
374                    Prefix         =>
375                      New_Occurrence_Of (First_Literal (T), Loc))));
376            Analyze_And_Resolve (N, Standard_Boolean);
377
378         else
379            Rewrite (N, Convert_To (Standard_Boolean, N));
380            Analyze_And_Resolve (N, Standard_Boolean);
381         end if;
382      end;
383   end Adjust_Condition;
384
385   ------------------------
386   -- Adjust_Result_Type --
387   ------------------------
388
389   procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
390   begin
391      --  Ignore call if current type is not Standard.Boolean
392
393      if Etype (N) /= Standard_Boolean then
394         return;
395      end if;
396
397      --  If result is already of correct type, nothing to do. Note that
398      --  this will get the most common case where everything has a type
399      --  of Standard.Boolean.
400
401      if Base_Type (T) = Standard_Boolean then
402         return;
403
404      else
405         declare
406            KP : constant Node_Kind := Nkind (Parent (N));
407
408         begin
409            --  If result is to be used as a Condition in the syntax, no need
410            --  to convert it back, since if it was changed to Standard.Boolean
411            --  using Adjust_Condition, that is just fine for this usage.
412
413            if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
414               return;
415
416            --  If result is an operand of another logical operation, no need
417            --  to reset its type, since Standard.Boolean is just fine, and
418            --  such operations always do Adjust_Condition on their operands.
419
420            elsif     KP in N_Op_Boolean
421              or else KP in N_Short_Circuit
422              or else KP = N_Op_Not
423            then
424               return;
425
426            --  Otherwise we perform a conversion from the current type, which
427            --  must be Standard.Boolean, to the desired type. Use the base
428            --  type to prevent spurious constraint checks that are extraneous
429            --  to the transformation. The type and its base have the same
430            --  representation, standard or otherwise.
431
432            else
433               Set_Analyzed (N);
434               Rewrite (N, Convert_To (Base_Type (T), N));
435               Analyze_And_Resolve (N, Base_Type (T));
436            end if;
437         end;
438      end if;
439   end Adjust_Result_Type;
440
441   --------------------------
442   -- Append_Freeze_Action --
443   --------------------------
444
445   procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
446      Fnode : Node_Id;
447
448   begin
449      Ensure_Freeze_Node (T);
450      Fnode := Freeze_Node (T);
451
452      if No (Actions (Fnode)) then
453         Set_Actions (Fnode, New_List (N));
454      else
455         Append (N, Actions (Fnode));
456      end if;
457
458   end Append_Freeze_Action;
459
460   ---------------------------
461   -- Append_Freeze_Actions --
462   ---------------------------
463
464   procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
465      Fnode : Node_Id;
466
467   begin
468      if No (L) then
469         return;
470      end if;
471
472      Ensure_Freeze_Node (T);
473      Fnode := Freeze_Node (T);
474
475      if No (Actions (Fnode)) then
476         Set_Actions (Fnode, L);
477      else
478         Append_List (L, Actions (Fnode));
479      end if;
480   end Append_Freeze_Actions;
481
482   ----------------------------------------
483   -- Attribute_Constrained_Static_Value --
484   ----------------------------------------
485
486   function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean
487   is
488      Ptyp       : constant Entity_Id := Etype (Pref);
489      Formal_Ent : constant Entity_Id := Param_Entity (Pref);
490
491      function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean;
492      --  Ada 2005 (AI-363): Returns True if the object name Obj denotes a
493      --  view of an aliased object whose subtype is constrained.
494
495      ---------------------------------
496      -- Is_Constrained_Aliased_View --
497      ---------------------------------
498
499      function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is
500         E : Entity_Id;
501
502      begin
503         if Is_Entity_Name (Obj) then
504            E := Entity (Obj);
505
506            if Present (Renamed_Object (E)) then
507               return Is_Constrained_Aliased_View (Renamed_Object (E));
508            else
509               return Is_Aliased (E) and then Is_Constrained (Etype (E));
510            end if;
511
512         else
513            return Is_Aliased_View (Obj)
514              and then
515                (Is_Constrained (Etype (Obj))
516                 or else
517                   (Nkind (Obj) = N_Explicit_Dereference
518                    and then
519                      not Object_Type_Has_Constrained_Partial_View
520                        (Typ  => Base_Type (Etype (Obj)),
521                         Scop => Current_Scope)));
522         end if;
523      end Is_Constrained_Aliased_View;
524
525   --  Start of processing for Attribute_Constrained_Static_Value
526
527   begin
528      --  We are in a case where the attribute is known statically, and
529      --  implicit dereferences have been rewritten.
530
531      pragma Assert
532        (not (Present (Formal_Ent)
533              and then Ekind (Formal_Ent) /= E_Constant
534              and then Present (Extra_Constrained (Formal_Ent)))
535         and then
536           not (Is_Access_Type (Etype (Pref))
537                and then (not Is_Entity_Name (Pref)
538                          or else Is_Object (Entity (Pref))))
539         and then
540           not (Nkind (Pref) = N_Identifier
541                and then Ekind (Entity (Pref)) = E_Variable
542                and then Present (Extra_Constrained (Entity (Pref)))));
543
544      if Is_Entity_Name (Pref) then
545         declare
546            Ent : constant Entity_Id := Entity (Pref);
547            Res : Boolean;
548
549         begin
550            --  (RM J.4) obsolescent cases
551
552            if Is_Type (Ent) then
553
554               --  Private type
555
556               if Is_Private_Type (Ent) then
557                  Res := not Has_Discriminants (Ent)
558                    or else Is_Constrained (Ent);
559
560               --  It not a private type, must be a generic actual type
561               --  that corresponded to a private type. We know that this
562               --  correspondence holds, since otherwise the reference
563               --  within the generic template would have been illegal.
564
565               else
566                  if Is_Composite_Type (Underlying_Type (Ent)) then
567                     Res := Is_Constrained (Ent);
568                  else
569                     Res := True;
570                  end if;
571               end if;
572
573            else
574
575               --  If the prefix is not a variable or is aliased, then
576               --  definitely true; if it's a formal parameter without an
577               --  associated extra formal, then treat it as constrained.
578
579               --  Ada 2005 (AI-363): An aliased prefix must be known to be
580               --  constrained in order to set the attribute to True.
581
582               if not Is_Variable (Pref)
583                 or else Present (Formal_Ent)
584                 or else (Ada_Version < Ada_2005
585                          and then Is_Aliased_View (Pref))
586                 or else (Ada_Version >= Ada_2005
587                          and then Is_Constrained_Aliased_View (Pref))
588               then
589                  Res := True;
590
591               --  Variable case, look at type to see if it is constrained.
592               --  Note that the one case where this is not accurate (the
593               --  procedure formal case), has been handled above.
594
595               --  We use the Underlying_Type here (and below) in case the
596               --  type is private without discriminants, but the full type
597               --  has discriminants. This case is illegal, but we generate
598               --  it internally for passing to the Extra_Constrained
599               --  parameter.
600
601               else
602                  --  In Ada 2012, test for case of a limited tagged type,
603                  --  in which case the attribute is always required to
604                  --  return True. The underlying type is tested, to make
605                  --  sure we also return True for cases where there is an
606                  --  unconstrained object with an untagged limited partial
607                  --  view which has defaulted discriminants (such objects
608                  --  always produce a False in earlier versions of
609                  --  Ada). (Ada 2012: AI05-0214)
610
611                  Res :=
612                    Is_Constrained (Underlying_Type (Etype (Ent)))
613                    or else
614                      (Ada_Version >= Ada_2012
615                       and then Is_Tagged_Type (Underlying_Type (Ptyp))
616                       and then Is_Limited_Type (Ptyp));
617               end if;
618            end if;
619
620            return Res;
621         end;
622
623      --  Prefix is not an entity name. These are also cases where we can
624      --  always tell at compile time by looking at the form and type of the
625      --  prefix. If an explicit dereference of an object with constrained
626      --  partial view, this is unconstrained (Ada 2005: AI95-0363). If the
627      --  underlying type is a limited tagged type, then Constrained is
628      --  required to always return True (Ada 2012: AI05-0214).
629
630      else
631         return not Is_Variable (Pref)
632           or else
633             (Nkind (Pref) = N_Explicit_Dereference
634              and then
635                not Object_Type_Has_Constrained_Partial_View
636                  (Typ  => Base_Type (Ptyp),
637                   Scop => Current_Scope))
638           or else Is_Constrained (Underlying_Type (Ptyp))
639           or else (Ada_Version >= Ada_2012
640                    and then Is_Tagged_Type (Underlying_Type (Ptyp))
641                    and then Is_Limited_Type (Ptyp));
642      end if;
643   end Attribute_Constrained_Static_Value;
644
645   ------------------------------------
646   -- Build_Allocate_Deallocate_Proc --
647   ------------------------------------
648
649   procedure Build_Allocate_Deallocate_Proc
650     (N           : Node_Id;
651      Is_Allocate : Boolean)
652   is
653      function Find_Object (E : Node_Id) return Node_Id;
654      --  Given an arbitrary expression of an allocator, try to find an object
655      --  reference in it, otherwise return the original expression.
656
657      function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
658      --  Determine whether subprogram Subp denotes a custom allocate or
659      --  deallocate.
660
661      -----------------
662      -- Find_Object --
663      -----------------
664
665      function Find_Object (E : Node_Id) return Node_Id is
666         Expr : Node_Id;
667
668      begin
669         pragma Assert (Is_Allocate);
670
671         Expr := E;
672         loop
673            if Nkind (Expr) = N_Explicit_Dereference then
674               Expr := Prefix (Expr);
675
676            elsif Nkind (Expr) = N_Qualified_Expression then
677               Expr := Expression (Expr);
678
679            elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
680
681               --  When interface class-wide types are involved in allocation,
682               --  the expander introduces several levels of address arithmetic
683               --  to perform dispatch table displacement. In this scenario the
684               --  object appears as:
685
686               --    Tag_Ptr (Base_Address (<object>'Address))
687
688               --  Detect this case and utilize the whole expression as the
689               --  "object" since it now points to the proper dispatch table.
690
691               if Is_RTE (Etype (Expr), RE_Tag_Ptr) then
692                  exit;
693
694               --  Continue to strip the object
695
696               else
697                  Expr := Expression (Expr);
698               end if;
699
700            else
701               exit;
702            end if;
703         end loop;
704
705         return Expr;
706      end Find_Object;
707
708      ---------------------------------
709      -- Is_Allocate_Deallocate_Proc --
710      ---------------------------------
711
712      function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
713      begin
714         --  Look for a subprogram body with only one statement which is a
715         --  call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
716
717         if Ekind (Subp) = E_Procedure
718           and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
719         then
720            declare
721               HSS  : constant Node_Id :=
722                        Handled_Statement_Sequence (Parent (Parent (Subp)));
723               Proc : Entity_Id;
724
725            begin
726               if Present (Statements (HSS))
727                 and then Nkind (First (Statements (HSS))) =
728                            N_Procedure_Call_Statement
729               then
730                  Proc := Entity (Name (First (Statements (HSS))));
731
732                  return
733                    Is_RTE (Proc, RE_Allocate_Any_Controlled)
734                      or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
735               end if;
736            end;
737         end if;
738
739         return False;
740      end Is_Allocate_Deallocate_Proc;
741
742      --  Local variables
743
744      Desig_Typ                : Entity_Id;
745      Expr                     : Node_Id;
746      Needs_Fin                : Boolean;
747      Pool_Id                  : Entity_Id;
748      Proc_To_Call             : Node_Id := Empty;
749      Ptr_Typ                  : Entity_Id;
750      Use_Secondary_Stack_Pool : Boolean;
751
752   --  Start of processing for Build_Allocate_Deallocate_Proc
753
754   begin
755      --  Obtain the attributes of the allocation / deallocation
756
757      if Nkind (N) = N_Free_Statement then
758         Expr := Expression (N);
759         Ptr_Typ := Base_Type (Etype (Expr));
760         Proc_To_Call := Procedure_To_Call (N);
761
762      else
763         if Nkind (N) = N_Object_Declaration then
764            Expr := Expression (N);
765         else
766            Expr := N;
767         end if;
768
769         --  In certain cases an allocator with a qualified expression may
770         --  be relocated and used as the initialization expression of a
771         --  temporary:
772
773         --    before:
774         --       Obj : Ptr_Typ := new Desig_Typ'(...);
775
776         --    after:
777         --       Tmp : Ptr_Typ := new Desig_Typ'(...);
778         --       Obj : Ptr_Typ := Tmp;
779
780         --  Since the allocator is always marked as analyzed to avoid infinite
781         --  expansion, it will never be processed by this routine given that
782         --  the designated type needs finalization actions. Detect this case
783         --  and complete the expansion of the allocator.
784
785         if Nkind (Expr) = N_Identifier
786           and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
787           and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
788         then
789            Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
790            return;
791         end if;
792
793         --  The allocator may have been rewritten into something else in which
794         --  case the expansion performed by this routine does not apply.
795
796         if Nkind (Expr) /= N_Allocator then
797            return;
798         end if;
799
800         Ptr_Typ := Base_Type (Etype (Expr));
801         Proc_To_Call := Procedure_To_Call (Expr);
802      end if;
803
804      Pool_Id := Associated_Storage_Pool (Ptr_Typ);
805      Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
806
807      --  Handle concurrent types
808
809      if Is_Concurrent_Type (Desig_Typ)
810        and then Present (Corresponding_Record_Type (Desig_Typ))
811      then
812         Desig_Typ := Corresponding_Record_Type (Desig_Typ);
813      end if;
814
815      Use_Secondary_Stack_Pool :=
816        Is_RTE (Pool_Id, RE_SS_Pool)
817          or else (Nkind (Expr) = N_Allocator
818                    and then Is_RTE (Storage_Pool (Expr), RE_SS_Pool));
819
820      --  Do not process allocations / deallocations without a pool
821
822      if No (Pool_Id) then
823         return;
824
825      --  Do not process allocations on / deallocations from the secondary
826      --  stack, except for access types used to implement indirect temps.
827
828      elsif Use_Secondary_Stack_Pool
829        and then not Old_Attr_Util.Indirect_Temps
830                       .Is_Access_Type_For_Indirect_Temp (Ptr_Typ)
831      then
832         return;
833
834      --  Optimize the case where we are using the default Global_Pool_Object,
835      --  and we don't need the heavy finalization machinery.
836
837      elsif Pool_Id = RTE (RE_Global_Pool_Object)
838        and then not Needs_Finalization (Desig_Typ)
839      then
840         return;
841
842      --  Do not replicate the machinery if the allocator / free has already
843      --  been expanded and has a custom Allocate / Deallocate.
844
845      elsif Present (Proc_To_Call)
846        and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
847      then
848         return;
849      end if;
850
851      --  Finalization actions are required when the object to be allocated or
852      --  deallocated needs these actions and the associated access type is not
853      --  subject to pragma No_Heap_Finalization.
854
855      Needs_Fin :=
856        Needs_Finalization (Desig_Typ)
857          and then not No_Heap_Finalization (Ptr_Typ);
858
859      if Needs_Fin then
860
861         --  Do nothing if the access type may never allocate / deallocate
862         --  objects.
863
864         if No_Pool_Assigned (Ptr_Typ) then
865            return;
866         end if;
867
868         --  The allocation / deallocation of a controlled object must be
869         --  chained on / detached from a finalization master.
870
871         pragma Assert (Present (Finalization_Master (Ptr_Typ)));
872
873      --  The only other kind of allocation / deallocation supported by this
874      --  routine is on / from a subpool.
875
876      elsif Nkind (Expr) = N_Allocator
877        and then No (Subpool_Handle_Name (Expr))
878      then
879         return;
880      end if;
881
882      declare
883         Loc     : constant Source_Ptr := Sloc (N);
884         Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
885         Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
886         Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
887         Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
888
889         Actuals      : List_Id;
890         Fin_Addr_Id  : Entity_Id;
891         Fin_Mas_Act  : Node_Id;
892         Fin_Mas_Id   : Entity_Id;
893         Proc_To_Call : Entity_Id;
894         Subpool      : Node_Id := Empty;
895
896      begin
897         --  Step 1: Construct all the actuals for the call to library routine
898         --  Allocate_Any_Controlled / Deallocate_Any_Controlled.
899
900         --  a) Storage pool
901
902         Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc));
903
904         if Is_Allocate then
905
906            --  b) Subpool
907
908            if Nkind (Expr) = N_Allocator then
909               Subpool := Subpool_Handle_Name (Expr);
910            end if;
911
912            --  If a subpool is present it can be an arbitrary name, so make
913            --  the actual by copying the tree.
914
915            if Present (Subpool) then
916               Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
917            else
918               Append_To (Actuals, Make_Null (Loc));
919            end if;
920
921            --  c) Finalization master
922
923            if Needs_Fin then
924               Fin_Mas_Id  := Finalization_Master (Ptr_Typ);
925               Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc);
926
927               --  Handle the case where the master is actually a pointer to a
928               --  master. This case arises in build-in-place functions.
929
930               if Is_Access_Type (Etype (Fin_Mas_Id)) then
931                  Append_To (Actuals, Fin_Mas_Act);
932               else
933                  Append_To (Actuals,
934                    Make_Attribute_Reference (Loc,
935                      Prefix         => Fin_Mas_Act,
936                      Attribute_Name => Name_Unrestricted_Access));
937               end if;
938            else
939               Append_To (Actuals, Make_Null (Loc));
940            end if;
941
942            --  d) Finalize_Address
943
944            --  Primitive Finalize_Address is never generated in CodePeer mode
945            --  since it contains an Unchecked_Conversion.
946
947            if Needs_Fin and then not CodePeer_Mode then
948               Fin_Addr_Id := Finalize_Address (Desig_Typ);
949               pragma Assert (Present (Fin_Addr_Id));
950
951               Append_To (Actuals,
952                 Make_Attribute_Reference (Loc,
953                   Prefix         => New_Occurrence_Of (Fin_Addr_Id, Loc),
954                   Attribute_Name => Name_Unrestricted_Access));
955            else
956               Append_To (Actuals, Make_Null (Loc));
957            end if;
958         end if;
959
960         --  e) Address
961         --  f) Storage_Size
962         --  g) Alignment
963
964         Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc));
965         Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc));
966
967         if (Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ))
968           and then not Use_Secondary_Stack_Pool
969         then
970            Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc));
971
972         --  For deallocation of class-wide types we obtain the value of
973         --  alignment from the Type Specific Record of the deallocated object.
974         --  This is needed because the frontend expansion of class-wide types
975         --  into equivalent types confuses the back end.
976
977         else
978            --  Generate:
979            --     Obj.all'Alignment
980
981            --  ... because 'Alignment applied to class-wide types is expanded
982            --  into the code that reads the value of alignment from the TSD
983            --  (see Expand_N_Attribute_Reference)
984
985            --  In the Use_Secondary_Stack_Pool case, Alig_Id is not
986            --  passed in and therefore must not be referenced.
987
988            Append_To (Actuals,
989              Unchecked_Convert_To (RTE (RE_Storage_Offset),
990                Make_Attribute_Reference (Loc,
991                  Prefix         =>
992                    Make_Explicit_Dereference (Loc, Relocate_Node (Expr)),
993                  Attribute_Name => Name_Alignment)));
994         end if;
995
996         --  h) Is_Controlled
997
998         if Needs_Fin then
999            Is_Controlled : declare
1000               Flag_Id   : constant Entity_Id := Make_Temporary (Loc, 'F');
1001               Flag_Expr : Node_Id;
1002               Param     : Node_Id;
1003               Pref      : Node_Id;
1004               Temp      : Node_Id;
1005
1006            begin
1007               if Is_Allocate then
1008                  Temp := Find_Object (Expression (Expr));
1009               else
1010                  Temp := Expr;
1011               end if;
1012
1013               --  Processing for allocations where the expression is a subtype
1014               --  indication.
1015
1016               if Is_Allocate
1017                 and then Is_Entity_Name (Temp)
1018                 and then Is_Type (Entity (Temp))
1019               then
1020                  Flag_Expr :=
1021                    New_Occurrence_Of
1022                      (Boolean_Literals
1023                         (Needs_Finalization (Entity (Temp))), Loc);
1024
1025               --  The allocation / deallocation of a class-wide object relies
1026               --  on a runtime check to determine whether the object is truly
1027               --  controlled or not. Depending on this check, the finalization
1028               --  machinery will request or reclaim extra storage reserved for
1029               --  a list header.
1030
1031               elsif Is_Class_Wide_Type (Desig_Typ) then
1032
1033                  --  Detect a special case where interface class-wide types
1034                  --  are involved as the object appears as:
1035
1036                  --    Tag_Ptr (Base_Address (<object>'Address))
1037
1038                  --  The expression already yields the proper tag, generate:
1039
1040                  --    Temp.all
1041
1042                  if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
1043                     Param :=
1044                       Make_Explicit_Dereference (Loc,
1045                         Prefix => Relocate_Node (Temp));
1046
1047                  --  In the default case, obtain the tag of the object about
1048                  --  to be allocated / deallocated. Generate:
1049
1050                  --    Temp'Tag
1051
1052                  --  If the object is an unchecked conversion (typically to
1053                  --  an access to class-wide type), we must preserve the
1054                  --  conversion to ensure that the object is seen as tagged
1055                  --  in the code that follows.
1056
1057                  else
1058                     Pref := Temp;
1059
1060                     if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion
1061                     then
1062                        Pref := Parent (Pref);
1063                     end if;
1064
1065                     Param :=
1066                       Make_Attribute_Reference (Loc,
1067                         Prefix         => Relocate_Node (Pref),
1068                         Attribute_Name => Name_Tag);
1069                  end if;
1070
1071                  --  Generate:
1072                  --    Needs_Finalization (<Param>)
1073
1074                  Flag_Expr :=
1075                    Make_Function_Call (Loc,
1076                      Name                   =>
1077                        New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
1078                      Parameter_Associations => New_List (Param));
1079
1080               --  Processing for generic actuals
1081
1082               elsif Is_Generic_Actual_Type (Desig_Typ) then
1083                  Flag_Expr :=
1084                    New_Occurrence_Of (Boolean_Literals
1085                      (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
1086
1087               --  The object does not require any specialized checks, it is
1088               --  known to be controlled.
1089
1090               else
1091                  Flag_Expr := New_Occurrence_Of (Standard_True, Loc);
1092               end if;
1093
1094               --  Create the temporary which represents the finalization state
1095               --  of the expression. Generate:
1096               --
1097               --    F : constant Boolean := <Flag_Expr>;
1098
1099               Insert_Action (N,
1100                 Make_Object_Declaration (Loc,
1101                   Defining_Identifier => Flag_Id,
1102                   Constant_Present    => True,
1103                   Object_Definition   =>
1104                     New_Occurrence_Of (Standard_Boolean, Loc),
1105                    Expression          => Flag_Expr));
1106
1107               Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc));
1108            end Is_Controlled;
1109
1110         --  The object is not controlled
1111
1112         else
1113            Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc));
1114         end if;
1115
1116         --  i) On_Subpool
1117
1118         if Is_Allocate then
1119            Append_To (Actuals,
1120              New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc));
1121         end if;
1122
1123         --  Step 2: Build a wrapper Allocate / Deallocate which internally
1124         --  calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
1125
1126         --  Select the proper routine to call
1127
1128         if Is_Allocate then
1129            Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
1130         else
1131            Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
1132         end if;
1133
1134         --  Create a custom Allocate / Deallocate routine which has identical
1135         --  profile to that of System.Storage_Pools.
1136
1137         declare
1138            --  P : Root_Storage_Pool
1139            function Pool_Param return Node_Id is (
1140              Make_Parameter_Specification (Loc,
1141                Defining_Identifier => Make_Temporary (Loc, 'P'),
1142                Parameter_Type      =>
1143                  New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc)));
1144
1145            --  A : [out] Address
1146            function Address_Param return Node_Id is (
1147              Make_Parameter_Specification (Loc,
1148                Defining_Identifier => Addr_Id,
1149                Out_Present         => Is_Allocate,
1150                Parameter_Type      =>
1151                  New_Occurrence_Of (RTE (RE_Address), Loc)));
1152
1153            --  S : Storage_Count
1154            function Size_Param return Node_Id is (
1155              Make_Parameter_Specification (Loc,
1156                Defining_Identifier => Size_Id,
1157                Parameter_Type      =>
1158                  New_Occurrence_Of (RTE (RE_Storage_Count), Loc)));
1159
1160            --  L : Storage_Count
1161            function Alignment_Param return Node_Id is (
1162              Make_Parameter_Specification (Loc,
1163                Defining_Identifier => Alig_Id,
1164                Parameter_Type      =>
1165                  New_Occurrence_Of (RTE (RE_Storage_Count), Loc)));
1166
1167            Formal_Params : List_Id;
1168         begin
1169            if Use_Secondary_Stack_Pool then
1170               --  Gigi expects a different profile in the Secondary_Stack_Pool
1171               --  case. There must be no uses of the two missing formals
1172               --  (i.e., Pool_Param and Alignment_Param) in this case.
1173               Formal_Params := New_List (Address_Param, Size_Param);
1174            else
1175               Formal_Params := New_List (
1176                 Pool_Param, Address_Param, Size_Param, Alignment_Param);
1177            end if;
1178
1179            Insert_Action (N,
1180              Make_Subprogram_Body (Loc,
1181                Specification              =>
1182                  --  procedure Pnn
1183                  Make_Procedure_Specification (Loc,
1184                    Defining_Unit_Name       => Proc_Id,
1185                    Parameter_Specifications => Formal_Params),
1186
1187                Declarations               => No_List,
1188
1189                Handled_Statement_Sequence =>
1190                  Make_Handled_Sequence_Of_Statements (Loc,
1191                    Statements => New_List (
1192                      Make_Procedure_Call_Statement (Loc,
1193                        Name                   =>
1194                          New_Occurrence_Of (Proc_To_Call, Loc),
1195                        Parameter_Associations => Actuals)))),
1196              Suppress => All_Checks);
1197         end;
1198
1199         --  The newly generated Allocate / Deallocate becomes the default
1200         --  procedure to call when the back end processes the allocation /
1201         --  deallocation.
1202
1203         if Is_Allocate then
1204            Set_Procedure_To_Call (Expr, Proc_Id);
1205         else
1206            Set_Procedure_To_Call (N, Proc_Id);
1207         end if;
1208      end;
1209   end Build_Allocate_Deallocate_Proc;
1210
1211   -------------------------------
1212   -- Build_Abort_Undefer_Block --
1213   -------------------------------
1214
1215   function Build_Abort_Undefer_Block
1216     (Loc     : Source_Ptr;
1217      Stmts   : List_Id;
1218      Context : Node_Id) return Node_Id
1219   is
1220      Exceptions_OK : constant Boolean :=
1221                        not Restriction_Active (No_Exception_Propagation);
1222
1223      AUD    : Entity_Id;
1224      Blk    : Node_Id;
1225      Blk_Id : Entity_Id;
1226      HSS    : Node_Id;
1227
1228   begin
1229      --  The block should be generated only when undeferring abort in the
1230      --  context of a potential exception.
1231
1232      pragma Assert (Abort_Allowed and Exceptions_OK);
1233
1234      --  Generate:
1235      --    begin
1236      --       <Stmts>
1237      --    at end
1238      --       Abort_Undefer_Direct;
1239      --    end;
1240
1241      AUD := RTE (RE_Abort_Undefer_Direct);
1242
1243      HSS :=
1244        Make_Handled_Sequence_Of_Statements (Loc,
1245          Statements  => Stmts,
1246          At_End_Proc => New_Occurrence_Of (AUD, Loc));
1247
1248      Blk :=
1249        Make_Block_Statement (Loc,
1250          Handled_Statement_Sequence => HSS);
1251      Set_Is_Abort_Block (Blk);
1252
1253      Add_Block_Identifier  (Blk, Blk_Id);
1254      Expand_At_End_Handler (HSS, Blk_Id);
1255
1256      --  Present the Abort_Undefer_Direct function to the back end to inline
1257      --  the call to the routine.
1258
1259      Add_Inlined_Body (AUD, Context);
1260
1261      return Blk;
1262   end Build_Abort_Undefer_Block;
1263
1264   ---------------------------------
1265   -- Build_Class_Wide_Expression --
1266   ---------------------------------
1267
1268   procedure Build_Class_Wide_Expression
1269     (Prag          : Node_Id;
1270      Subp          : Entity_Id;
1271      Par_Subp      : Entity_Id;
1272      Adjust_Sloc   : Boolean;
1273      Needs_Wrapper : out Boolean)
1274   is
1275      function Replace_Entity (N : Node_Id) return Traverse_Result;
1276      --  Replace reference to formal of inherited operation or to primitive
1277      --  operation of root type, with corresponding entity for derived type,
1278      --  when constructing the class-wide condition of an overriding
1279      --  subprogram.
1280
1281      --------------------
1282      -- Replace_Entity --
1283      --------------------
1284
1285      function Replace_Entity (N : Node_Id) return Traverse_Result is
1286         New_E : Entity_Id;
1287
1288      begin
1289         if Adjust_Sloc then
1290            Adjust_Inherited_Pragma_Sloc (N);
1291         end if;
1292
1293         if Nkind (N) = N_Identifier
1294           and then Present (Entity (N))
1295           and then
1296             (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
1297           and then
1298             (Nkind (Parent (N)) /= N_Attribute_Reference
1299               or else Attribute_Name (Parent (N)) /= Name_Class)
1300         then
1301            --  The replacement does not apply to dispatching calls within the
1302            --  condition, but only to calls whose static tag is that of the
1303            --  parent type.
1304
1305            if Is_Subprogram (Entity (N))
1306              and then Nkind (Parent (N)) = N_Function_Call
1307              and then Present (Controlling_Argument (Parent (N)))
1308            then
1309               return OK;
1310            end if;
1311
1312            --  Determine whether entity has a renaming
1313
1314            New_E := Type_Map.Get (Entity (N));
1315
1316            if Present (New_E) then
1317               Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
1318
1319               --  AI12-0166: a precondition for a protected operation
1320               --  cannot include an internal call to a protected function
1321               --  of the type. In the case of an inherited condition for an
1322               --  overriding operation, both the operation and the function
1323               --  are given by primitive wrappers.
1324               --  Move this check to sem???
1325
1326               if Ekind (New_E) = E_Function
1327                 and then Is_Primitive_Wrapper (New_E)
1328                 and then Is_Primitive_Wrapper (Subp)
1329                 and then Scope (Subp) = Scope (New_E)
1330               then
1331                  Error_Msg_Node_2 := Wrapped_Entity (Subp);
1332                  Error_Msg_NE
1333                    ("internal call to& cannot appear in inherited "
1334                     & "precondition of protected operation&",
1335                     N, Wrapped_Entity (New_E));
1336               end if;
1337
1338               --  If the entity is an overridden primitive and we are not
1339               --  in GNATprove mode, we must build a wrapper for the current
1340               --  inherited operation. If the reference is the prefix of an
1341               --  attribute such as 'Result (or others ???) there is no need
1342               --  for a wrapper: the condition is just rewritten in terms of
1343               --  the inherited subprogram.
1344
1345               if Is_Subprogram (New_E)
1346                  and then Nkind (Parent (N)) /= N_Attribute_Reference
1347                  and then not GNATprove_Mode
1348               then
1349                  Needs_Wrapper := True;
1350               end if;
1351            end if;
1352
1353            --  Check that there are no calls left to abstract operations if
1354            --  the current subprogram is not abstract.
1355            --  Move this check to sem???
1356
1357            if Nkind (Parent (N)) = N_Function_Call
1358              and then N = Name (Parent (N))
1359            then
1360               if not Is_Abstract_Subprogram (Subp)
1361                 and then Is_Abstract_Subprogram (Entity (N))
1362               then
1363                  Error_Msg_Sloc   := Sloc (Current_Scope);
1364                  Error_Msg_Node_2 := Subp;
1365                  if Comes_From_Source (Subp) then
1366                     Error_Msg_NE
1367                       ("cannot call abstract subprogram & in inherited "
1368                        & "condition for&#", Subp, Entity (N));
1369                  else
1370                     Error_Msg_NE
1371                       ("cannot call abstract subprogram & in inherited "
1372                        & "condition for inherited&#", Subp, Entity (N));
1373                  end if;
1374
1375               --  In SPARK mode, reject an inherited condition for an
1376               --  inherited operation if it contains a call to an overriding
1377               --  operation, because this implies that the pre/postconditions
1378               --  of the inherited operation have changed silently.
1379
1380               elsif SPARK_Mode = On
1381                 and then Warn_On_Suspicious_Contract
1382                 and then Present (Alias (Subp))
1383                 and then Present (New_E)
1384                 and then Comes_From_Source (New_E)
1385               then
1386                  Error_Msg_N
1387                    ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
1388                     Parent (Subp));
1389                  Error_Msg_Sloc   := Sloc (New_E);
1390                  Error_Msg_Node_2 := Subp;
1391                  Error_Msg_NE
1392                    ("\overriding of&# forces overriding of&",
1393                     Parent (Subp), New_E);
1394               end if;
1395            end if;
1396
1397            --  Update type of function call node, which should be the same as
1398            --  the function's return type.
1399
1400            if Is_Subprogram (Entity (N))
1401              and then Nkind (Parent (N)) = N_Function_Call
1402            then
1403               Set_Etype (Parent (N), Etype (Entity (N)));
1404            end if;
1405
1406         --  The whole expression will be reanalyzed
1407
1408         elsif Nkind (N) in N_Has_Etype then
1409            Set_Analyzed (N, False);
1410         end if;
1411
1412         return OK;
1413      end Replace_Entity;
1414
1415      procedure Replace_Condition_Entities is
1416        new Traverse_Proc (Replace_Entity);
1417
1418      --  Local variables
1419
1420      Par_Formal  : Entity_Id;
1421      Subp_Formal : Entity_Id;
1422
1423   --  Start of processing for Build_Class_Wide_Expression
1424
1425   begin
1426      Needs_Wrapper := False;
1427
1428      --  Add mapping from old formals to new formals
1429
1430      Par_Formal  := First_Formal (Par_Subp);
1431      Subp_Formal := First_Formal (Subp);
1432
1433      while Present (Par_Formal) and then Present (Subp_Formal) loop
1434         Type_Map.Set (Par_Formal, Subp_Formal);
1435         Next_Formal (Par_Formal);
1436         Next_Formal (Subp_Formal);
1437      end loop;
1438
1439      Replace_Condition_Entities (Prag);
1440   end Build_Class_Wide_Expression;
1441
1442   --------------------
1443   -- Build_DIC_Call --
1444   --------------------
1445
1446   function Build_DIC_Call
1447     (Loc      : Source_Ptr;
1448      Obj_Name : Node_Id;
1449      Typ      : Entity_Id) return Node_Id
1450   is
1451      Proc_Id    : constant Entity_Id := DIC_Procedure (Typ);
1452      Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
1453
1454   begin
1455      --  The DIC procedure has a null body if assertions are disabled or
1456      --  Assertion_Policy Ignore is in effect. In that case, it would be
1457      --  nice to generate a null statement instead of a call to the DIC
1458      --  procedure, but doing that seems to interfere with the determination
1459      --  of ECRs (early call regions) in SPARK. ???
1460
1461      return
1462        Make_Procedure_Call_Statement (Loc,
1463          Name                   => New_Occurrence_Of (Proc_Id, Loc),
1464          Parameter_Associations => New_List (
1465            Make_Unchecked_Type_Conversion (Loc,
1466              Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc),
1467              Expression   => Obj_Name)));
1468   end Build_DIC_Call;
1469
1470   ------------------------------
1471   -- Build_DIC_Procedure_Body --
1472   ------------------------------
1473
1474   --  WARNING: This routine manages Ghost regions. Return statements must be
1475   --  replaced by gotos which jump to the end of the routine and restore the
1476   --  Ghost mode.
1477
1478   procedure Build_DIC_Procedure_Body
1479     (Typ         : Entity_Id;
1480      Partial_DIC : Boolean := False)
1481   is
1482      Pragmas_Seen : Elist_Id := No_Elist;
1483      --  This list contains all DIC pragmas processed so far. The list is used
1484      --  to avoid redundant Default_Initial_Condition checks.
1485
1486      procedure Add_DIC_Check
1487        (DIC_Prag : Node_Id;
1488         DIC_Expr : Node_Id;
1489         Stmts    : in out List_Id);
1490      --  Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify
1491      --  assertion expression DIC_Expr of pragma DIC_Prag. All generated code
1492      --  is added to list Stmts.
1493
1494      procedure Add_Inherited_DIC
1495        (DIC_Prag  : Node_Id;
1496         Par_Typ   : Entity_Id;
1497         Deriv_Typ : Entity_Id;
1498         Stmts     : in out List_Id);
1499      --  Add a runtime check to verify the assertion expression of inherited
1500      --  pragma DIC_Prag. Par_Typ is parent type, which is also the owner of
1501      --  the DIC pragma. Deriv_Typ is the derived type inheriting the DIC
1502      --  pragma. All generated code is added to list Stmts.
1503
1504      procedure Add_Inherited_Tagged_DIC
1505        (DIC_Prag : Node_Id;
1506         Expr     : Node_Id;
1507         Stmts    : in out List_Id);
1508      --  Add a runtime check to verify assertion expression DIC_Expr of
1509      --  inherited pragma DIC_Prag. This routine applies class-wide pre-
1510      --  and postcondition-like runtime semantics to the check. Expr is
1511      --  the assertion expression after substitition has been performed
1512      --  (via Replace_References). All generated code is added to list Stmts.
1513
1514      procedure Add_Inherited_DICs
1515        (T         : Entity_Id;
1516         Priv_Typ  : Entity_Id;
1517         Full_Typ  : Entity_Id;
1518         Obj_Id    : Entity_Id;
1519         Checks    : in out List_Id);
1520      --  Generate a DIC check for each inherited Default_Initial_Condition
1521      --  coming from all parent types of type T. Priv_Typ and Full_Typ denote
1522      --  the partial and full view of the parent type. Obj_Id denotes the
1523      --  entity of the _object formal parameter of the DIC procedure. All
1524      --  created checks are added to list Checks.
1525
1526      procedure Add_Own_DIC
1527        (DIC_Prag : Node_Id;
1528         DIC_Typ  : Entity_Id;
1529         Obj_Id   : Entity_Id;
1530         Stmts    : in out List_Id);
1531      --  Add a runtime check to verify the assertion expression of pragma
1532      --  DIC_Prag. DIC_Typ is the owner of the DIC pragma. Obj_Id is the
1533      --  object to substitute in the assertion expression for any references
1534      --  to the current instance of the type All generated code is added to
1535      --  list Stmts.
1536
1537      procedure Add_Parent_DICs
1538        (T      : Entity_Id;
1539         Obj_Id : Entity_Id;
1540         Checks : in out List_Id);
1541      --  Generate a Default_Initial_Condition check for each inherited DIC
1542      --  aspect coming from all parent types of type T. Obj_Id denotes the
1543      --  entity of the _object formal parameter of the DIC procedure. All
1544      --  created checks are added to list Checks.
1545
1546      -------------------
1547      -- Add_DIC_Check --
1548      -------------------
1549
1550      procedure Add_DIC_Check
1551        (DIC_Prag : Node_Id;
1552         DIC_Expr : Node_Id;
1553         Stmts    : in out List_Id)
1554      is
1555         Loc : constant Source_Ptr := Sloc (DIC_Prag);
1556         Nam : constant Name_Id    := Original_Aspect_Pragma_Name (DIC_Prag);
1557
1558      begin
1559         --  The DIC pragma is ignored, nothing left to do
1560
1561         if Is_Ignored (DIC_Prag) then
1562            null;
1563
1564         --  Otherwise the DIC expression must be checked at run time.
1565         --  Generate:
1566
1567         --    pragma Check (<Nam>, <DIC_Expr>);
1568
1569         else
1570            Append_New_To (Stmts,
1571              Make_Pragma (Loc,
1572                Pragma_Identifier            =>
1573                  Make_Identifier (Loc, Name_Check),
1574
1575                Pragma_Argument_Associations => New_List (
1576                  Make_Pragma_Argument_Association (Loc,
1577                    Expression => Make_Identifier (Loc, Nam)),
1578
1579                  Make_Pragma_Argument_Association (Loc,
1580                    Expression => DIC_Expr))));
1581         end if;
1582
1583         --  Add the pragma to the list of processed pragmas
1584
1585         Append_New_Elmt (DIC_Prag, Pragmas_Seen);
1586      end Add_DIC_Check;
1587
1588      -----------------------
1589      -- Add_Inherited_DIC --
1590      -----------------------
1591
1592      procedure Add_Inherited_DIC
1593        (DIC_Prag  : Node_Id;
1594         Par_Typ   : Entity_Id;
1595         Deriv_Typ : Entity_Id;
1596         Stmts     : in out List_Id)
1597      is
1598         Deriv_Proc : constant Entity_Id  := DIC_Procedure (Deriv_Typ);
1599         Deriv_Obj  : constant Entity_Id  := First_Entity  (Deriv_Proc);
1600         Par_Proc   : constant Entity_Id  := DIC_Procedure (Par_Typ);
1601         Par_Obj    : constant Entity_Id  := First_Entity  (Par_Proc);
1602         Loc        : constant Source_Ptr := Sloc (DIC_Prag);
1603
1604      begin
1605         pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
1606
1607         --  Verify the inherited DIC assertion expression by calling the DIC
1608         --  procedure of the parent type.
1609
1610         --  Generate:
1611         --    <Par_Typ>DIC (Par_Typ (_object));
1612
1613         Append_New_To (Stmts,
1614           Make_Procedure_Call_Statement (Loc,
1615             Name                   => New_Occurrence_Of (Par_Proc, Loc),
1616             Parameter_Associations => New_List (
1617               Convert_To
1618                 (Typ  => Etype (Par_Obj),
1619                  Expr => New_Occurrence_Of (Deriv_Obj, Loc)))));
1620      end Add_Inherited_DIC;
1621
1622      ------------------------------
1623      -- Add_Inherited_Tagged_DIC --
1624      ------------------------------
1625
1626      procedure Add_Inherited_Tagged_DIC
1627        (DIC_Prag : Node_Id;
1628         Expr     : Node_Id;
1629         Stmts    : in out List_Id)
1630      is
1631      begin
1632         --  Once the DIC assertion expression is fully processed, add a check
1633         --  to the statements of the DIC procedure.
1634
1635         Add_DIC_Check
1636           (DIC_Prag => DIC_Prag,
1637            DIC_Expr => Expr,
1638            Stmts    => Stmts);
1639      end Add_Inherited_Tagged_DIC;
1640
1641      ------------------------
1642      -- Add_Inherited_DICs --
1643      ------------------------
1644
1645      procedure Add_Inherited_DICs
1646        (T         : Entity_Id;
1647         Priv_Typ  : Entity_Id;
1648         Full_Typ  : Entity_Id;
1649         Obj_Id    : Entity_Id;
1650         Checks    : in out List_Id)
1651      is
1652         Deriv_Typ     : Entity_Id;
1653         Expr          : Node_Id;
1654         Prag          : Node_Id;
1655         Prag_Expr     : Node_Id;
1656         Prag_Expr_Arg : Node_Id;
1657         Prag_Typ      : Node_Id;
1658         Prag_Typ_Arg  : Node_Id;
1659
1660         Par_Proc : Entity_Id;
1661         --  The "partial" invariant procedure of Par_Typ
1662
1663         Par_Typ : Entity_Id;
1664         --  The suitable view of the parent type used in the substitution of
1665         --  type attributes.
1666
1667      begin
1668         if not Present (Priv_Typ) and then not Present (Full_Typ) then
1669            return;
1670         end if;
1671
1672         --  When the type inheriting the class-wide invariant is a concurrent
1673         --  type, use the corresponding record type because it contains all
1674         --  primitive operations of the concurrent type and allows for proper
1675         --  substitution.
1676
1677         if Is_Concurrent_Type (T) then
1678            Deriv_Typ := Corresponding_Record_Type (T);
1679         else
1680            Deriv_Typ := T;
1681         end if;
1682
1683         pragma Assert (Present (Deriv_Typ));
1684
1685         --  Determine which rep item chain to use. Precedence is given to that
1686         --  of the parent type's partial view since it usually carries all the
1687         --  class-wide invariants.
1688
1689         if Present (Priv_Typ) then
1690            Prag := First_Rep_Item (Priv_Typ);
1691         else
1692            Prag := First_Rep_Item (Full_Typ);
1693         end if;
1694
1695         while Present (Prag) loop
1696            if Nkind (Prag) = N_Pragma
1697              and then Pragma_Name (Prag) = Name_Default_Initial_Condition
1698            then
1699               --  Nothing to do if the pragma was already processed
1700
1701               if Contains (Pragmas_Seen, Prag) then
1702                  return;
1703               end if;
1704
1705               --  Extract arguments of the Default_Initial_Condition pragma
1706
1707               Prag_Expr_Arg := First (Pragma_Argument_Associations (Prag));
1708               Prag_Expr     := Expression_Copy (Prag_Expr_Arg);
1709
1710               --  Pick up the implicit second argument of the pragma, which
1711               --  indicates the type that the pragma applies to.
1712
1713               Prag_Typ_Arg  := Next (Prag_Expr_Arg);
1714               if Present (Prag_Typ_Arg) then
1715                  Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
1716               else
1717                  Prag_Typ := Empty;
1718               end if;
1719
1720               --  The pragma applies to the partial view of the parent type
1721
1722               if Present (Priv_Typ)
1723                 and then Present (Prag_Typ)
1724                 and then Entity (Prag_Typ) = Priv_Typ
1725               then
1726                  Par_Typ := Priv_Typ;
1727
1728               --  The pragma applies to the full view of the parent type
1729
1730               elsif Present (Full_Typ)
1731                 and then Present (Prag_Typ)
1732                 and then Entity (Prag_Typ) = Full_Typ
1733               then
1734                  Par_Typ := Full_Typ;
1735
1736               --  Otherwise the pragma does not belong to the parent type and
1737               --  should not be considered.
1738
1739               else
1740                  return;
1741               end if;
1742
1743               --  Substitute references in the DIC expression that are related
1744               --  to the partial type with corresponding references related to
1745               --  the derived type (call to Replace_References below).
1746
1747               Expr := New_Copy_Tree (Prag_Expr);
1748
1749               Par_Proc := Partial_DIC_Procedure (Par_Typ);
1750
1751               --  If there's not a partial DIC procedure (such as when a
1752               --  full type doesn't have its own DIC, but is inherited from
1753               --  a type with DIC), get the full DIC procedure.
1754
1755               if not Present (Par_Proc) then
1756                  Par_Proc := DIC_Procedure (Par_Typ);
1757               end if;
1758
1759               Replace_References
1760                 (Expr      => Expr,
1761                  Par_Typ   => Par_Typ,
1762                  Deriv_Typ => Deriv_Typ,
1763                  Par_Obj   => First_Formal (Par_Proc),
1764                  Deriv_Obj => Obj_Id);
1765
1766               --  Why are there different actions depending on whether T is
1767               --  tagged? Can these be unified? ???
1768
1769               if Is_Tagged_Type (T) then
1770                  Add_Inherited_Tagged_DIC
1771                    (DIC_Prag  => Prag,
1772                     Expr      => Expr,
1773                     Stmts     => Checks);
1774
1775               else
1776                  Add_Inherited_DIC
1777                    (DIC_Prag  => Prag,
1778                     Par_Typ   => Par_Typ,
1779                     Deriv_Typ => Deriv_Typ,
1780                     Stmts     => Checks);
1781               end if;
1782
1783               --  Leave as soon as we get a DIC pragma, since we'll visit
1784               --  the pragmas of the parents, so will get to any "inherited"
1785               --  pragmas that way.
1786
1787               return;
1788            end if;
1789
1790            Next_Rep_Item (Prag);
1791         end loop;
1792      end Add_Inherited_DICs;
1793
1794      -----------------
1795      -- Add_Own_DIC --
1796      -----------------
1797
1798      procedure Add_Own_DIC
1799        (DIC_Prag : Node_Id;
1800         DIC_Typ  : Entity_Id;
1801         Obj_Id   : Entity_Id;
1802         Stmts    : in out List_Id)
1803      is
1804         DIC_Args : constant List_Id   :=
1805                      Pragma_Argument_Associations (DIC_Prag);
1806         DIC_Arg  : constant Node_Id   := First (DIC_Args);
1807         DIC_Asp  : constant Node_Id   := Corresponding_Aspect (DIC_Prag);
1808         DIC_Expr : constant Node_Id   := Get_Pragma_Arg (DIC_Arg);
1809
1810         --  Local variables
1811
1812         Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ);
1813
1814         Expr : Node_Id;
1815
1816      --  Start of processing for Add_Own_DIC
1817
1818      begin
1819         pragma Assert (Present (DIC_Expr));
1820         Expr := New_Copy_Tree (DIC_Expr);
1821
1822         --  Perform the following substitution:
1823
1824         --    * Replace the current instance of DIC_Typ with a reference to
1825         --    the _object formal parameter of the DIC procedure.
1826
1827         Replace_Type_References
1828           (Expr   => Expr,
1829            Typ    => DIC_Typ,
1830            Obj_Id => Obj_Id);
1831
1832         --  Preanalyze the DIC expression to detect errors and at the same
1833         --  time capture the visibility of the proper package part.
1834
1835         Set_Parent (Expr, Typ_Decl);
1836         Preanalyze_Assert_Expression (Expr, Any_Boolean);
1837
1838         --  Save a copy of the expression with all replacements and analysis
1839         --  already taken place in case a derived type inherits the pragma.
1840         --  The copy will be used as the foundation of the derived type's own
1841         --  version of the DIC assertion expression.
1842
1843         if Is_Tagged_Type (DIC_Typ) then
1844            Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr));
1845         end if;
1846
1847         --  If the pragma comes from an aspect specification, replace the
1848         --  saved expression because all type references must be substituted
1849         --  for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx
1850         --  routines.
1851
1852         if Present (DIC_Asp) then
1853            Set_Entity (Identifier (DIC_Asp), New_Copy_Tree (Expr));
1854         end if;
1855
1856         --  Once the DIC assertion expression is fully processed, add a check
1857         --  to the statements of the DIC procedure.
1858
1859         Add_DIC_Check
1860           (DIC_Prag => DIC_Prag,
1861            DIC_Expr => Expr,
1862            Stmts    => Stmts);
1863      end Add_Own_DIC;
1864
1865      ---------------------
1866      -- Add_Parent_DICs --
1867      ---------------------
1868
1869      procedure Add_Parent_DICs
1870        (T      : Entity_Id;
1871         Obj_Id : Entity_Id;
1872         Checks : in out List_Id)
1873      is
1874         Dummy_1 : Entity_Id;
1875         Dummy_2 : Entity_Id;
1876
1877         Curr_Typ : Entity_Id;
1878         --  The entity of the current type being examined
1879
1880         Full_Typ : Entity_Id;
1881         --  The full view of Par_Typ
1882
1883         Par_Typ : Entity_Id;
1884         --  The entity of the parent type
1885
1886         Priv_Typ : Entity_Id;
1887         --  The partial view of Par_Typ
1888
1889      begin
1890         --  Climb the parent type chain
1891
1892         Curr_Typ := T;
1893         loop
1894            --  Do not consider subtypes, as they inherit the DICs from their
1895            --  base types.
1896
1897            Par_Typ := Base_Type (Etype (Base_Type (Curr_Typ)));
1898
1899            --  Stop the climb once the root of the parent chain is
1900            --  reached.
1901
1902            exit when Curr_Typ = Par_Typ;
1903
1904            --  Process the DICs of the parent type
1905
1906            Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
1907
1908            --  Only try to inherit a DIC pragma from the parent type Par_Typ
1909            --  if it Has_Own_DIC pragma. The loop will proceed up the parent
1910            --  chain to find all types that have their own DIC.
1911
1912            if Has_Own_DIC (Par_Typ) then
1913               Add_Inherited_DICs
1914                 (T         => T,
1915                  Priv_Typ  => Priv_Typ,
1916                  Full_Typ  => Full_Typ,
1917                  Obj_Id    => Obj_Id,
1918                  Checks    => Checks);
1919            end if;
1920
1921            Curr_Typ := Par_Typ;
1922         end loop;
1923      end Add_Parent_DICs;
1924
1925      --  Local variables
1926
1927      Loc : constant Source_Ptr := Sloc (Typ);
1928
1929      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
1930      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
1931      --  Save the Ghost-related attributes to restore on exit
1932
1933      DIC_Prag     : Node_Id;
1934      DIC_Typ      : Entity_Id;
1935      Dummy_1      : Entity_Id;
1936      Dummy_2      : Entity_Id;
1937      Proc_Body    : Node_Id;
1938      Proc_Body_Id : Entity_Id;
1939      Proc_Decl    : Node_Id;
1940      Proc_Id      : Entity_Id;
1941      Stmts        : List_Id := No_List;
1942
1943      CRec_Typ : Entity_Id := Empty;
1944      --  The corresponding record type of Full_Typ
1945
1946      Full_Typ : Entity_Id := Empty;
1947      --  The full view of the working type
1948
1949      Obj_Id : Entity_Id := Empty;
1950      --  The _object formal parameter of the invariant procedure
1951
1952      Part_Proc : Entity_Id := Empty;
1953      --  The entity of the "partial" invariant procedure
1954
1955      Priv_Typ : Entity_Id := Empty;
1956      --  The partial view of the working type
1957
1958      Work_Typ : Entity_Id;
1959      --  The working type
1960
1961   --  Start of processing for Build_DIC_Procedure_Body
1962
1963   begin
1964      Work_Typ := Base_Type (Typ);
1965
1966      --  Do not process class-wide types as these are Itypes, but lack a first
1967      --  subtype (see below).
1968
1969      if Is_Class_Wide_Type (Work_Typ) then
1970         return;
1971
1972      --  Do not process the underlying full view of a private type. There is
1973      --  no way to get back to the partial view, plus the body will be built
1974      --  by the full view or the base type.
1975
1976      elsif Is_Underlying_Full_View (Work_Typ) then
1977         return;
1978
1979      --  Use the first subtype when dealing with various base types
1980
1981      elsif Is_Itype (Work_Typ) then
1982         Work_Typ := First_Subtype (Work_Typ);
1983
1984      --  The input denotes the corresponding record type of a protected or a
1985      --  task type. Work with the concurrent type because the corresponding
1986      --  record type may not be visible to clients of the type.
1987
1988      elsif Ekind (Work_Typ) = E_Record_Type
1989        and then Is_Concurrent_Record_Type (Work_Typ)
1990      then
1991         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
1992      end if;
1993
1994      --  The working type may be subject to pragma Ghost. Set the mode now to
1995      --  ensure that the DIC procedure is properly marked as Ghost.
1996
1997      Set_Ghost_Mode (Work_Typ);
1998
1999      --  The working type must be either define a DIC pragma of its own or
2000      --  inherit one from a parent type.
2001
2002      pragma Assert (Has_DIC (Work_Typ));
2003
2004      --  Recover the type which defines the DIC pragma. This is either the
2005      --  working type itself or a parent type when the pragma is inherited.
2006
2007      DIC_Typ := Find_DIC_Type (Work_Typ);
2008      pragma Assert (Present (DIC_Typ));
2009
2010      DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2011      pragma Assert (Present (DIC_Prag));
2012
2013      --  Nothing to do if pragma DIC appears without an argument or its sole
2014      --  argument is "null".
2015
2016      if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
2017         goto Leave;
2018      end if;
2019
2020      --  Obtain both views of the type
2021
2022      Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy_1, CRec_Typ);
2023
2024      --  The caller requests a body for the partial DIC procedure
2025
2026      if Partial_DIC then
2027         Proc_Id   := Partial_DIC_Procedure (Work_Typ);
2028
2029         --  The "full" DIC procedure body was already created
2030
2031         --  Create a declaration for the "partial" DIC procedure if it
2032         --  is not available.
2033
2034         if No (Proc_Id) then
2035            Build_DIC_Procedure_Declaration
2036              (Typ         => Work_Typ,
2037               Partial_DIC => True);
2038
2039            Proc_Id := Partial_DIC_Procedure (Work_Typ);
2040         end if;
2041
2042      --  The caller requests a body for the "full" DIC procedure
2043
2044      else
2045         Proc_Id   := DIC_Procedure (Work_Typ);
2046         Part_Proc := Partial_DIC_Procedure (Work_Typ);
2047
2048         --  Create a declaration for the "full" DIC procedure if it is
2049         --  not available.
2050
2051         if No (Proc_Id) then
2052            Build_DIC_Procedure_Declaration (Work_Typ);
2053            Proc_Id := DIC_Procedure (Work_Typ);
2054         end if;
2055      end if;
2056
2057      --  At this point there should be a DIC procedure declaration
2058
2059      pragma Assert (Present (Proc_Id));
2060      Proc_Decl := Unit_Declaration_Node (Proc_Id);
2061
2062      --  Nothing to do if the DIC procedure already has a body
2063
2064      if Present (Corresponding_Body (Proc_Decl)) then
2065         goto Leave;
2066      end if;
2067
2068      --  Emulate the environment of the DIC procedure by installing its scope
2069      --  and formal parameters.
2070
2071      Push_Scope (Proc_Id);
2072      Install_Formals (Proc_Id);
2073
2074      Obj_Id := First_Formal (Proc_Id);
2075      pragma Assert (Present (Obj_Id));
2076
2077      --  The "partial" DIC procedure verifies the DICs of the partial view
2078      --  only.
2079
2080      if Partial_DIC then
2081         pragma Assert (Present (Priv_Typ));
2082
2083         if Has_Own_DIC (Work_Typ) then  -- If we're testing this then maybe
2084            Add_Own_DIC        -- we shouldn't be calling Find_DIC_Typ above???
2085              (DIC_Prag => DIC_Prag,
2086               DIC_Typ  => DIC_Typ,  -- Should this just be Work_Typ???
2087               Obj_Id   => Obj_Id,
2088               Stmts    => Stmts);
2089         end if;
2090
2091      --  Otherwise the "full" DIC procedure verifies the DICs of the full
2092      --  view, well as DICs inherited from parent types. In addition, it
2093      --  indirectly verifies the DICs of the partial view by calling the
2094      --  "partial" DIC procedure.
2095
2096      else
2097         pragma Assert (Present (Full_Typ));
2098
2099         --  Check the DIC of the partial view by calling the "partial" DIC
2100         --  procedure, unless the partial DIC body is empty. Generate:
2101
2102         --    <Work_Typ>Partial_DIC (_object);
2103
2104         if Present (Part_Proc) and then not Has_Null_Body (Part_Proc) then
2105            Append_New_To (Stmts,
2106              Make_Procedure_Call_Statement (Loc,
2107                Name                   => New_Occurrence_Of (Part_Proc, Loc),
2108                Parameter_Associations => New_List (
2109                  New_Occurrence_Of (Obj_Id, Loc))));
2110         end if;
2111
2112         --  Derived subtypes do not have a partial view
2113
2114         if Present (Priv_Typ) then
2115
2116            --  The processing of the "full" DIC procedure intentionally
2117            --  skips the partial view because a) this may result in changes of
2118            --  visibility and b) lead to duplicate checks. However, when the
2119            --  full view is the underlying full view of an untagged derived
2120            --  type whose parent type is private, partial DICs appear on
2121            --  the rep item chain of the partial view only.
2122
2123            --    package Pack_1 is
2124            --       type Root ... is private;
2125            --    private
2126            --       <full view of Root>
2127            --    end Pack_1;
2128
2129            --    with Pack_1;
2130            --    package Pack_2 is
2131            --       type Child is new Pack_1.Root with Type_DIC => ...;
2132            --       <underlying full view of Child>
2133            --    end Pack_2;
2134
2135            --  As a result, the processing of the full view must also consider
2136            --  all DICs of the partial view.
2137
2138            if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
2139               null;
2140
2141            --  Otherwise the DICs of the partial view are ignored
2142
2143            else
2144               --  Ignore the DICs of the partial view by eliminating the view
2145
2146               Priv_Typ := Empty;
2147            end if;
2148         end if;
2149
2150         --  Process inherited Default_Initial_Conditions for all parent types
2151
2152         Add_Parent_DICs (Work_Typ, Obj_Id, Stmts);
2153      end if;
2154
2155      End_Scope;
2156
2157      --  Produce an empty completing body in the following cases:
2158      --    * Assertions are disabled
2159      --    * The DIC Assertion_Policy is Ignore
2160
2161      if No (Stmts) then
2162         Stmts := New_List (Make_Null_Statement (Loc));
2163      end if;
2164
2165      --  Generate:
2166      --    procedure <Work_Typ>DIC (_object : <Work_Typ>) is
2167      --    begin
2168      --       <Stmts>
2169      --    end <Work_Typ>DIC;
2170
2171      Proc_Body :=
2172        Make_Subprogram_Body (Loc,
2173          Specification                =>
2174            Copy_Subprogram_Spec (Parent (Proc_Id)),
2175          Declarations                 => Empty_List,
2176            Handled_Statement_Sequence =>
2177              Make_Handled_Sequence_Of_Statements (Loc,
2178                Statements => Stmts));
2179      Proc_Body_Id := Defining_Entity (Proc_Body);
2180
2181      --  Perform minor decoration in case the body is not analyzed
2182
2183      Set_Ekind        (Proc_Body_Id, E_Subprogram_Body);
2184      Set_Etype        (Proc_Body_Id, Standard_Void_Type);
2185      Set_Scope        (Proc_Body_Id, Current_Scope);
2186      Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id));
2187      Set_SPARK_Pragma_Inherited
2188                       (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id));
2189
2190      --  Link both spec and body to avoid generating duplicates
2191
2192      Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
2193      Set_Corresponding_Spec (Proc_Body, Proc_Id);
2194
2195      --  The body should not be inserted into the tree when the context
2196      --  is a generic unit because it is not part of the template.
2197      --  Note that the body must still be generated in order to resolve the
2198      --  DIC assertion expression.
2199
2200      if Inside_A_Generic then
2201         null;
2202
2203      --  Semi-insert the body into the tree for GNATprove by setting its
2204      --  Parent field. This allows for proper upstream tree traversals.
2205
2206      elsif GNATprove_Mode then
2207         Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
2208
2209      --  Otherwise the body is part of the freezing actions of the working
2210      --  type.
2211
2212      else
2213         Append_Freeze_Action (Work_Typ, Proc_Body);
2214      end if;
2215
2216   <<Leave>>
2217      Restore_Ghost_Region (Saved_GM, Saved_IGR);
2218   end Build_DIC_Procedure_Body;
2219
2220   -------------------------------------
2221   -- Build_DIC_Procedure_Declaration --
2222   -------------------------------------
2223
2224   --  WARNING: This routine manages Ghost regions. Return statements must be
2225   --  replaced by gotos which jump to the end of the routine and restore the
2226   --  Ghost mode.
2227
2228   procedure Build_DIC_Procedure_Declaration
2229     (Typ         : Entity_Id;
2230      Partial_DIC : Boolean := False)
2231   is
2232      Loc : constant Source_Ptr := Sloc (Typ);
2233
2234      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
2235      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
2236      --  Save the Ghost-related attributes to restore on exit
2237
2238      DIC_Prag  : Node_Id;
2239      DIC_Typ   : Entity_Id;
2240      Proc_Decl : Node_Id;
2241      Proc_Id   : Entity_Id;
2242      Proc_Nam  : Name_Id;
2243      Typ_Decl  : Node_Id;
2244
2245      CRec_Typ : Entity_Id;
2246      --  The corresponding record type of Full_Typ
2247
2248      Full_Typ : Entity_Id;
2249      --  The full view of working type
2250
2251      Obj_Id : Entity_Id;
2252      --  The _object formal parameter of the DIC procedure
2253
2254      Priv_Typ : Entity_Id;
2255      --  The partial view of working type
2256
2257      UFull_Typ : Entity_Id;
2258      --  The underlying full view of Full_Typ
2259
2260      Work_Typ : Entity_Id;
2261      --  The working type
2262
2263   begin
2264      Work_Typ := Base_Type (Typ);
2265
2266      --  Do not process class-wide types as these are Itypes, but lack a first
2267      --  subtype (see below).
2268
2269      if Is_Class_Wide_Type (Work_Typ) then
2270         return;
2271
2272      --  Do not process the underlying full view of a private type. There is
2273      --  no way to get back to the partial view, plus the body will be built
2274      --  by the full view or the base type.
2275
2276      elsif Is_Underlying_Full_View (Work_Typ) then
2277         return;
2278
2279      --  Use the first subtype when dealing with various base types
2280
2281      elsif Is_Itype (Work_Typ) then
2282         Work_Typ := First_Subtype (Work_Typ);
2283
2284      --  The input denotes the corresponding record type of a protected or a
2285      --  task type. Work with the concurrent type because the corresponding
2286      --  record type may not be visible to clients of the type.
2287
2288      elsif Ekind (Work_Typ) = E_Record_Type
2289        and then Is_Concurrent_Record_Type (Work_Typ)
2290      then
2291         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
2292      end if;
2293
2294      --  The working type may be subject to pragma Ghost. Set the mode now to
2295      --  ensure that the DIC procedure is properly marked as Ghost.
2296
2297      Set_Ghost_Mode (Work_Typ);
2298
2299      --  The type must be either subject to a DIC pragma or inherit one from a
2300      --  parent type.
2301
2302      pragma Assert (Has_DIC (Work_Typ));
2303
2304      --  Recover the type which defines the DIC pragma. This is either the
2305      --  working type itself or a parent type when the pragma is inherited.
2306
2307      DIC_Typ := Find_DIC_Type (Work_Typ);
2308      pragma Assert (Present (DIC_Typ));
2309
2310      DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2311      pragma Assert (Present (DIC_Prag));
2312
2313      --  Nothing to do if pragma DIC appears without an argument or its sole
2314      --  argument is "null".
2315
2316      if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
2317         goto Leave;
2318      end if;
2319
2320      --  Nothing to do if the type already has a "partial" DIC procedure
2321
2322      if Partial_DIC then
2323         if Present (Partial_DIC_Procedure (Work_Typ)) then
2324            goto Leave;
2325         end if;
2326
2327      --  Nothing to do if the type already has a "full" DIC procedure
2328
2329      elsif Present (DIC_Procedure (Work_Typ)) then
2330         goto Leave;
2331      end if;
2332
2333      --  The caller requests the declaration of the "partial" DIC procedure
2334
2335      if Partial_DIC then
2336         Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_DIC");
2337
2338      --  Otherwise the caller requests the declaration of the "full" DIC
2339      --  procedure.
2340
2341      else
2342         Proc_Nam := New_External_Name (Chars (Work_Typ), "DIC");
2343      end if;
2344
2345      Proc_Id :=
2346        Make_Defining_Identifier (Loc, Chars => Proc_Nam);
2347
2348      --  Perform minor decoration in case the declaration is not analyzed
2349
2350      Set_Ekind                  (Proc_Id, E_Procedure);
2351      Set_Etype                  (Proc_Id, Standard_Void_Type);
2352      Set_Is_DIC_Procedure       (Proc_Id);
2353      Set_Scope                  (Proc_Id, Current_Scope);
2354      Set_SPARK_Pragma           (Proc_Id, SPARK_Mode_Pragma);
2355      Set_SPARK_Pragma_Inherited (Proc_Id);
2356
2357      Set_DIC_Procedure (Work_Typ, Proc_Id);
2358
2359      --  The DIC procedure requires debug info when the assertion expression
2360      --  is subject to Source Coverage Obligations.
2361
2362      if Generate_SCO then
2363         Set_Debug_Info_Needed (Proc_Id);
2364      end if;
2365
2366      --  Obtain all views of the input type
2367
2368      Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);
2369
2370      --  Associate the DIC procedure and various flags with all views
2371
2372      Propagate_DIC_Attributes (Priv_Typ,  From_Typ => Work_Typ);
2373      Propagate_DIC_Attributes (Full_Typ,  From_Typ => Work_Typ);
2374      Propagate_DIC_Attributes (UFull_Typ, From_Typ => Work_Typ);
2375      Propagate_DIC_Attributes (CRec_Typ,  From_Typ => Work_Typ);
2376
2377      --  The declaration of the DIC procedure must be inserted after the
2378      --  declaration of the partial view as this allows for proper external
2379      --  visibility.
2380
2381      if Present (Priv_Typ) then
2382         Typ_Decl := Declaration_Node (Priv_Typ);
2383
2384      --  Derived types with the full view as parent do not have a partial
2385      --  view. Insert the DIC procedure after the derived type.
2386
2387      else
2388         Typ_Decl := Declaration_Node (Full_Typ);
2389      end if;
2390
2391      --  The type should have a declarative node
2392
2393      pragma Assert (Present (Typ_Decl));
2394
2395      --  Create the formal parameter which emulates the variable-like behavior
2396      --  of the type's current instance.
2397
2398      Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
2399
2400      --  Perform minor decoration in case the declaration is not analyzed
2401
2402      Set_Ekind (Obj_Id, E_In_Parameter);
2403      Set_Etype (Obj_Id, Work_Typ);
2404      Set_Scope (Obj_Id, Proc_Id);
2405
2406      Set_First_Entity (Proc_Id, Obj_Id);
2407      Set_Last_Entity  (Proc_Id, Obj_Id);
2408
2409      --  Generate:
2410      --    procedure <Work_Typ>DIC (_object : <Work_Typ>);
2411
2412      Proc_Decl :=
2413        Make_Subprogram_Declaration (Loc,
2414          Specification =>
2415            Make_Procedure_Specification (Loc,
2416              Defining_Unit_Name       => Proc_Id,
2417              Parameter_Specifications => New_List (
2418                Make_Parameter_Specification (Loc,
2419                  Defining_Identifier => Obj_Id,
2420                  Parameter_Type      =>
2421                    New_Occurrence_Of (Work_Typ, Loc)))));
2422
2423      --  The declaration should not be inserted into the tree when the context
2424      --  is a generic unit because it is not part of the template.
2425
2426      if Inside_A_Generic then
2427         null;
2428
2429      --  Semi-insert the declaration into the tree for GNATprove by setting
2430      --  its Parent field. This allows for proper upstream tree traversals.
2431
2432      elsif GNATprove_Mode then
2433         Set_Parent (Proc_Decl, Parent (Typ_Decl));
2434
2435      --  Otherwise insert the declaration
2436
2437      else
2438         Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
2439      end if;
2440
2441   <<Leave>>
2442      Restore_Ghost_Region (Saved_GM, Saved_IGR);
2443   end Build_DIC_Procedure_Declaration;
2444
2445   ------------------------------------
2446   -- Build_Invariant_Procedure_Body --
2447   ------------------------------------
2448
2449   --  WARNING: This routine manages Ghost regions. Return statements must be
2450   --  replaced by gotos which jump to the end of the routine and restore the
2451   --  Ghost mode.
2452
2453   procedure Build_Invariant_Procedure_Body
2454     (Typ               : Entity_Id;
2455      Partial_Invariant : Boolean := False)
2456   is
2457      Loc : constant Source_Ptr := Sloc (Typ);
2458
2459      Pragmas_Seen : Elist_Id := No_Elist;
2460      --  This list contains all invariant pragmas processed so far. The list
2461      --  is used to avoid generating redundant invariant checks.
2462
2463      Produced_Check : Boolean := False;
2464      --  This flag tracks whether the type has produced at least one invariant
2465      --  check. The flag is used as a sanity check at the end of the routine.
2466
2467      --  NOTE: most of the routines in Build_Invariant_Procedure_Body are
2468      --  intentionally unnested to avoid deep indentation of code.
2469
2470      --  NOTE: all Add_xxx_Invariants routines are reactive. In other words
2471      --  they emit checks, loops (for arrays) and case statements (for record
2472      --  variant parts) only when there are invariants to verify. This keeps
2473      --  the body of the invariant procedure free of useless code.
2474
2475      procedure Add_Array_Component_Invariants
2476        (T      : Entity_Id;
2477         Obj_Id : Entity_Id;
2478         Checks : in out List_Id);
2479      --  Generate an invariant check for each component of array type T.
2480      --  Obj_Id denotes the entity of the _object formal parameter of the
2481      --  invariant procedure. All created checks are added to list Checks.
2482
2483      procedure Add_Inherited_Invariants
2484        (T         : Entity_Id;
2485         Priv_Typ  : Entity_Id;
2486         Full_Typ  : Entity_Id;
2487         Obj_Id    : Entity_Id;
2488         Checks    : in out List_Id);
2489      --  Generate an invariant check for each inherited class-wide invariant
2490      --  coming from all parent types of type T. Priv_Typ and Full_Typ denote
2491      --  the partial and full view of the parent type. Obj_Id denotes the
2492      --  entity of the _object formal parameter of the invariant procedure.
2493      --  All created checks are added to list Checks.
2494
2495      procedure Add_Interface_Invariants
2496        (T      : Entity_Id;
2497         Obj_Id : Entity_Id;
2498         Checks : in out List_Id);
2499      --  Generate an invariant check for each inherited class-wide invariant
2500      --  coming from all interfaces implemented by type T. Obj_Id denotes the
2501      --  entity of the _object formal parameter of the invariant procedure.
2502      --  All created checks are added to list Checks.
2503
2504      procedure Add_Invariant_Check
2505        (Prag      : Node_Id;
2506         Expr      : Node_Id;
2507         Checks    : in out List_Id;
2508         Inherited : Boolean := False);
2509      --  Subsidiary to all Add_xxx_Invariant routines. Add a runtime check to
2510      --  verify assertion expression Expr of pragma Prag. All generated code
2511      --  is added to list Checks. Flag Inherited should be set when the pragma
2512      --  is inherited from a parent or interface type.
2513
2514      procedure Add_Own_Invariants
2515        (T         : Entity_Id;
2516         Obj_Id    : Entity_Id;
2517         Checks    : in out List_Id;
2518         Priv_Item : Node_Id := Empty);
2519      --  Generate an invariant check for each invariant found for type T.
2520      --  Obj_Id denotes the entity of the _object formal parameter of the
2521      --  invariant procedure. All created checks are added to list Checks.
2522      --  Priv_Item denotes the first rep item of the private type.
2523
2524      procedure Add_Parent_Invariants
2525        (T      : Entity_Id;
2526         Obj_Id : Entity_Id;
2527         Checks : in out List_Id);
2528      --  Generate an invariant check for each inherited class-wide invariant
2529      --  coming from all parent types of type T. Obj_Id denotes the entity of
2530      --  the _object formal parameter of the invariant procedure. All created
2531      --  checks are added to list Checks.
2532
2533      procedure Add_Record_Component_Invariants
2534        (T      : Entity_Id;
2535         Obj_Id : Entity_Id;
2536         Checks : in out List_Id);
2537      --  Generate an invariant check for each component of record type T.
2538      --  Obj_Id denotes the entity of the _object formal parameter of the
2539      --  invariant procedure. All created checks are added to list Checks.
2540
2541      ------------------------------------
2542      -- Add_Array_Component_Invariants --
2543      ------------------------------------
2544
2545      procedure Add_Array_Component_Invariants
2546        (T      : Entity_Id;
2547         Obj_Id : Entity_Id;
2548         Checks : in out List_Id)
2549      is
2550         Comp_Typ : constant Entity_Id := Component_Type (T);
2551         Dims     : constant Pos       := Number_Dimensions (T);
2552
2553         procedure Process_Array_Component
2554           (Indices     : List_Id;
2555            Comp_Checks : in out List_Id);
2556         --  Generate an invariant check for an array component identified by
2557         --  the indices in list Indices. All created checks are added to list
2558         --  Comp_Checks.
2559
2560         procedure Process_One_Dimension
2561           (Dim        : Pos;
2562            Indices    : List_Id;
2563            Dim_Checks : in out List_Id);
2564         --  Generate a loop over the Nth dimension Dim of an array type. List
2565         --  Indices contains all array indices for the dimension. All created
2566         --  checks are added to list Dim_Checks.
2567
2568         -----------------------------
2569         -- Process_Array_Component --
2570         -----------------------------
2571
2572         procedure Process_Array_Component
2573           (Indices     : List_Id;
2574            Comp_Checks : in out List_Id)
2575         is
2576            Proc_Id : Entity_Id;
2577
2578         begin
2579            if Has_Invariants (Comp_Typ) then
2580
2581               --  In GNATprove mode, the component invariants are checked by
2582               --  other means. They should not be added to the array type
2583               --  invariant procedure, so that the procedure can be used to
2584               --  check the array type invariants if any.
2585
2586               if GNATprove_Mode then
2587                  null;
2588
2589               else
2590                  Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
2591
2592                  --  The component type should have an invariant procedure
2593                  --  if it has invariants of its own or inherits class-wide
2594                  --  invariants from parent or interface types.
2595
2596                  pragma Assert (Present (Proc_Id));
2597
2598                  --  Generate:
2599                  --    <Comp_Typ>Invariant (_object (<Indices>));
2600
2601                  --  The invariant procedure has a null body if assertions are
2602                  --  disabled or Assertion_Policy Ignore is in effect.
2603
2604                  if not Has_Null_Body (Proc_Id) then
2605                     Append_New_To (Comp_Checks,
2606                       Make_Procedure_Call_Statement (Loc,
2607                         Name                   =>
2608                           New_Occurrence_Of (Proc_Id, Loc),
2609                         Parameter_Associations => New_List (
2610                           Make_Indexed_Component (Loc,
2611                             Prefix      => New_Occurrence_Of (Obj_Id, Loc),
2612                             Expressions => New_Copy_List (Indices)))));
2613                  end if;
2614               end if;
2615
2616               Produced_Check := True;
2617            end if;
2618         end Process_Array_Component;
2619
2620         ---------------------------
2621         -- Process_One_Dimension --
2622         ---------------------------
2623
2624         procedure Process_One_Dimension
2625           (Dim        : Pos;
2626            Indices    : List_Id;
2627            Dim_Checks : in out List_Id)
2628         is
2629            Comp_Checks : List_Id := No_List;
2630            Index       : Entity_Id;
2631
2632         begin
2633            --  Generate the invariant checks for the array component after all
2634            --  dimensions have produced their respective loops.
2635
2636            if Dim > Dims then
2637               Process_Array_Component
2638                 (Indices     => Indices,
2639                  Comp_Checks => Dim_Checks);
2640
2641            --  Otherwise create a loop for the current dimension
2642
2643            else
2644               --  Create a new loop variable for each dimension
2645
2646               Index :=
2647                 Make_Defining_Identifier (Loc,
2648                   Chars => New_External_Name ('I', Dim));
2649               Append_To (Indices, New_Occurrence_Of (Index, Loc));
2650
2651               Process_One_Dimension
2652                 (Dim        => Dim + 1,
2653                  Indices    => Indices,
2654                  Dim_Checks => Comp_Checks);
2655
2656               --  Generate:
2657               --    for I<Dim> in _object'Range (<Dim>) loop
2658               --       <Comp_Checks>
2659               --    end loop;
2660
2661               --  Note that the invariant procedure may have a null body if
2662               --  assertions are disabled or Assertion_Policy Ignore is in
2663               --  effect.
2664
2665               if Present (Comp_Checks) then
2666                  Append_New_To (Dim_Checks,
2667                    Make_Implicit_Loop_Statement (T,
2668                      Identifier       => Empty,
2669                      Iteration_Scheme =>
2670                        Make_Iteration_Scheme (Loc,
2671                          Loop_Parameter_Specification =>
2672                            Make_Loop_Parameter_Specification (Loc,
2673                              Defining_Identifier         => Index,
2674                              Discrete_Subtype_Definition =>
2675                                Make_Attribute_Reference (Loc,
2676                                  Prefix         =>
2677                                    New_Occurrence_Of (Obj_Id, Loc),
2678                                  Attribute_Name => Name_Range,
2679                                  Expressions    => New_List (
2680                                    Make_Integer_Literal (Loc, Dim))))),
2681                      Statements       => Comp_Checks));
2682               end if;
2683            end if;
2684         end Process_One_Dimension;
2685
2686      --  Start of processing for Add_Array_Component_Invariants
2687
2688      begin
2689         Process_One_Dimension
2690           (Dim        => 1,
2691            Indices    => New_List,
2692            Dim_Checks => Checks);
2693      end Add_Array_Component_Invariants;
2694
2695      ------------------------------
2696      -- Add_Inherited_Invariants --
2697      ------------------------------
2698
2699      procedure Add_Inherited_Invariants
2700        (T         : Entity_Id;
2701         Priv_Typ  : Entity_Id;
2702         Full_Typ  : Entity_Id;
2703         Obj_Id    : Entity_Id;
2704         Checks    : in out List_Id)
2705      is
2706         Deriv_Typ     : Entity_Id;
2707         Expr          : Node_Id;
2708         Prag          : Node_Id;
2709         Prag_Expr     : Node_Id;
2710         Prag_Expr_Arg : Node_Id;
2711         Prag_Typ      : Node_Id;
2712         Prag_Typ_Arg  : Node_Id;
2713
2714         Par_Proc : Entity_Id;
2715         --  The "partial" invariant procedure of Par_Typ
2716
2717         Par_Typ : Entity_Id;
2718         --  The suitable view of the parent type used in the substitution of
2719         --  type attributes.
2720
2721      begin
2722         if not Present (Priv_Typ) and then not Present (Full_Typ) then
2723            return;
2724         end if;
2725
2726         --  When the type inheriting the class-wide invariant is a concurrent
2727         --  type, use the corresponding record type because it contains all
2728         --  primitive operations of the concurrent type and allows for proper
2729         --  substitution.
2730
2731         if Is_Concurrent_Type (T) then
2732            Deriv_Typ := Corresponding_Record_Type (T);
2733         else
2734            Deriv_Typ := T;
2735         end if;
2736
2737         pragma Assert (Present (Deriv_Typ));
2738
2739         --  Determine which rep item chain to use. Precedence is given to that
2740         --  of the parent type's partial view since it usually carries all the
2741         --  class-wide invariants.
2742
2743         if Present (Priv_Typ) then
2744            Prag := First_Rep_Item (Priv_Typ);
2745         else
2746            Prag := First_Rep_Item (Full_Typ);
2747         end if;
2748
2749         while Present (Prag) loop
2750            if Nkind (Prag) = N_Pragma
2751              and then Pragma_Name (Prag) = Name_Invariant
2752            then
2753               --  Nothing to do if the pragma was already processed
2754
2755               if Contains (Pragmas_Seen, Prag) then
2756                  return;
2757
2758               --  Nothing to do when the caller requests the processing of all
2759               --  inherited class-wide invariants, but the pragma does not
2760               --  fall in this category.
2761
2762               elsif not Class_Present (Prag) then
2763                  return;
2764               end if;
2765
2766               --  Extract the arguments of the invariant pragma
2767
2768               Prag_Typ_Arg  := First (Pragma_Argument_Associations (Prag));
2769               Prag_Expr_Arg := Next (Prag_Typ_Arg);
2770               Prag_Expr     := Expression_Copy (Prag_Expr_Arg);
2771               Prag_Typ      := Get_Pragma_Arg (Prag_Typ_Arg);
2772
2773               --  The pragma applies to the partial view of the parent type
2774
2775               if Present (Priv_Typ)
2776                 and then Entity (Prag_Typ) = Priv_Typ
2777               then
2778                  Par_Typ := Priv_Typ;
2779
2780               --  The pragma applies to the full view of the parent type
2781
2782               elsif Present (Full_Typ)
2783                 and then Entity (Prag_Typ) = Full_Typ
2784               then
2785                  Par_Typ := Full_Typ;
2786
2787               --  Otherwise the pragma does not belong to the parent type and
2788               --  should not be considered.
2789
2790               else
2791                  return;
2792               end if;
2793
2794               --  Perform the following substitutions:
2795
2796               --    * Replace a reference to the _object parameter of the
2797               --      parent type's partial invariant procedure with a
2798               --      reference to the _object parameter of the derived
2799               --      type's full invariant procedure.
2800
2801               --    * Replace a reference to a discriminant of the parent type
2802               --      with a suitable value from the point of view of the
2803               --      derived type.
2804
2805               --    * Replace a call to an overridden parent primitive with a
2806               --      call to the overriding derived type primitive.
2807
2808               --    * Replace a call to an inherited parent primitive with a
2809               --      call to the internally-generated inherited derived type
2810               --      primitive.
2811
2812               Expr := New_Copy_Tree (Prag_Expr);
2813
2814               --  The parent type must have a "partial" invariant procedure
2815               --  because class-wide invariants are captured exclusively by
2816               --  it.
2817
2818               Par_Proc := Partial_Invariant_Procedure (Par_Typ);
2819               pragma Assert (Present (Par_Proc));
2820
2821               Replace_References
2822                 (Expr      => Expr,
2823                  Par_Typ   => Par_Typ,
2824                  Deriv_Typ => Deriv_Typ,
2825                  Par_Obj   => First_Formal (Par_Proc),
2826                  Deriv_Obj => Obj_Id);
2827
2828               Add_Invariant_Check (Prag, Expr, Checks, Inherited => True);
2829            end if;
2830
2831            Next_Rep_Item (Prag);
2832         end loop;
2833      end Add_Inherited_Invariants;
2834
2835      ------------------------------
2836      -- Add_Interface_Invariants --
2837      ------------------------------
2838
2839      procedure Add_Interface_Invariants
2840        (T      : Entity_Id;
2841         Obj_Id : Entity_Id;
2842         Checks : in out List_Id)
2843      is
2844         Iface_Elmt : Elmt_Id;
2845         Ifaces     : Elist_Id;
2846
2847      begin
2848         --  Generate an invariant check for each class-wide invariant coming
2849         --  from all interfaces implemented by type T.
2850
2851         if Is_Tagged_Type (T) then
2852            Collect_Interfaces (T, Ifaces);
2853
2854            --  Process the class-wide invariants of all implemented interfaces
2855
2856            Iface_Elmt := First_Elmt (Ifaces);
2857            while Present (Iface_Elmt) loop
2858
2859               --  The Full_Typ parameter is intentionally left Empty because
2860               --  interfaces are treated as the partial view of a private type
2861               --  in order to achieve uniformity with the general case.
2862
2863               Add_Inherited_Invariants
2864                 (T         => T,
2865                  Priv_Typ  => Node (Iface_Elmt),
2866                  Full_Typ  => Empty,
2867                  Obj_Id    => Obj_Id,
2868                  Checks    => Checks);
2869
2870               Next_Elmt (Iface_Elmt);
2871            end loop;
2872         end if;
2873      end Add_Interface_Invariants;
2874
2875      -------------------------
2876      -- Add_Invariant_Check --
2877      -------------------------
2878
2879      procedure Add_Invariant_Check
2880        (Prag      : Node_Id;
2881         Expr      : Node_Id;
2882         Checks    : in out List_Id;
2883         Inherited : Boolean := False)
2884      is
2885         Args    : constant List_Id    := Pragma_Argument_Associations (Prag);
2886         Nam     : constant Name_Id    := Original_Aspect_Pragma_Name (Prag);
2887         Ploc    : constant Source_Ptr := Sloc (Prag);
2888         Str_Arg : constant Node_Id    := Next (Next (First (Args)));
2889
2890         Assoc : List_Id;
2891         Str   : String_Id;
2892
2893      begin
2894         --  The invariant is ignored, nothing left to do
2895
2896         if Is_Ignored (Prag) then
2897            null;
2898
2899         --  Otherwise the invariant is checked. Build a pragma Check to verify
2900         --  the expression at run time.
2901
2902         else
2903            Assoc := New_List (
2904              Make_Pragma_Argument_Association (Ploc,
2905                Expression => Make_Identifier (Ploc, Nam)),
2906              Make_Pragma_Argument_Association (Ploc,
2907                Expression => Expr));
2908
2909            --  Handle the String argument (if any)
2910
2911            if Present (Str_Arg) then
2912               Str := Strval (Get_Pragma_Arg (Str_Arg));
2913
2914               --  When inheriting an invariant, modify the message from
2915               --  "failed invariant" to "failed inherited invariant".
2916
2917               if Inherited then
2918                  String_To_Name_Buffer (Str);
2919
2920                  if Name_Buffer (1 .. 16) = "failed invariant" then
2921                     Insert_Str_In_Name_Buffer ("inherited ", 8);
2922                     Str := String_From_Name_Buffer;
2923                  end if;
2924               end if;
2925
2926               Append_To (Assoc,
2927                 Make_Pragma_Argument_Association (Ploc,
2928                   Expression => Make_String_Literal (Ploc, Str)));
2929            end if;
2930
2931            --  Generate:
2932            --    pragma Check (<Nam>, <Expr>, <Str>);
2933
2934            Append_New_To (Checks,
2935              Make_Pragma (Ploc,
2936                Chars                        => Name_Check,
2937                Pragma_Argument_Associations => Assoc));
2938         end if;
2939
2940         --  Output an info message when inheriting an invariant and the
2941         --  listing option is enabled.
2942
2943         if Inherited and Opt.List_Inherited_Aspects then
2944            Error_Msg_Sloc := Sloc (Prag);
2945            Error_Msg_N
2946              ("info: & inherits `Invariant''Class` aspect from #?L?", Typ);
2947         end if;
2948
2949         --  Add the pragma to the list of processed pragmas
2950
2951         Append_New_Elmt (Prag, Pragmas_Seen);
2952         Produced_Check := True;
2953      end Add_Invariant_Check;
2954
2955      ---------------------------
2956      -- Add_Parent_Invariants --
2957      ---------------------------
2958
2959      procedure Add_Parent_Invariants
2960        (T      : Entity_Id;
2961         Obj_Id : Entity_Id;
2962         Checks : in out List_Id)
2963      is
2964         Dummy_1 : Entity_Id;
2965         Dummy_2 : Entity_Id;
2966
2967         Curr_Typ : Entity_Id;
2968         --  The entity of the current type being examined
2969
2970         Full_Typ : Entity_Id;
2971         --  The full view of Par_Typ
2972
2973         Par_Typ : Entity_Id;
2974         --  The entity of the parent type
2975
2976         Priv_Typ : Entity_Id;
2977         --  The partial view of Par_Typ
2978
2979      begin
2980         --  Do not process array types because they cannot have true parent
2981         --  types. This also prevents the generation of a duplicate invariant
2982         --  check when the input type is an array base type because its Etype
2983         --  denotes the first subtype, both of which share the same component
2984         --  type.
2985
2986         if Is_Array_Type (T) then
2987            return;
2988         end if;
2989
2990         --  Climb the parent type chain
2991
2992         Curr_Typ := T;
2993         loop
2994            --  Do not consider subtypes as they inherit the invariants
2995            --  from their base types.
2996
2997            Par_Typ := Base_Type (Etype (Curr_Typ));
2998
2999            --  Stop the climb once the root of the parent chain is
3000            --  reached.
3001
3002            exit when Curr_Typ = Par_Typ;
3003
3004            --  Process the class-wide invariants of the parent type
3005
3006            Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
3007
3008            --  Process the elements of an array type
3009
3010            if Is_Array_Type (Full_Typ) then
3011               Add_Array_Component_Invariants (Full_Typ, Obj_Id, Checks);
3012
3013            --  Process the components of a record type
3014
3015            elsif Ekind (Full_Typ) = E_Record_Type then
3016               Add_Record_Component_Invariants (Full_Typ, Obj_Id, Checks);
3017            end if;
3018
3019            Add_Inherited_Invariants
3020              (T         => T,
3021               Priv_Typ  => Priv_Typ,
3022               Full_Typ  => Full_Typ,
3023               Obj_Id    => Obj_Id,
3024               Checks    => Checks);
3025
3026            Curr_Typ := Par_Typ;
3027         end loop;
3028      end Add_Parent_Invariants;
3029
3030      ------------------------
3031      -- Add_Own_Invariants --
3032      ------------------------
3033
3034      procedure Add_Own_Invariants
3035        (T         : Entity_Id;
3036         Obj_Id    : Entity_Id;
3037         Checks    : in out List_Id;
3038         Priv_Item : Node_Id := Empty)
3039      is
3040         Expr          : Node_Id;
3041         Prag          : Node_Id;
3042         Prag_Asp      : Node_Id;
3043         Prag_Expr     : Node_Id;
3044         Prag_Expr_Arg : Node_Id;
3045         Prag_Typ      : Node_Id;
3046         Prag_Typ_Arg  : Node_Id;
3047
3048      begin
3049         if not Present (T) then
3050            return;
3051         end if;
3052
3053         Prag := First_Rep_Item (T);
3054         while Present (Prag) loop
3055            if Nkind (Prag) = N_Pragma
3056              and then Pragma_Name (Prag) = Name_Invariant
3057            then
3058               --  Stop the traversal of the rep item chain once a specific
3059               --  item is encountered.
3060
3061               if Present (Priv_Item) and then Prag = Priv_Item then
3062                  exit;
3063               end if;
3064
3065               --  Nothing to do if the pragma was already processed
3066
3067               if Contains (Pragmas_Seen, Prag) then
3068                  return;
3069               end if;
3070
3071               --  Extract the arguments of the invariant pragma
3072
3073               Prag_Typ_Arg  := First (Pragma_Argument_Associations (Prag));
3074               Prag_Expr_Arg := Next (Prag_Typ_Arg);
3075               Prag_Expr     := Get_Pragma_Arg (Prag_Expr_Arg);
3076               Prag_Typ      := Get_Pragma_Arg (Prag_Typ_Arg);
3077               Prag_Asp      := Corresponding_Aspect (Prag);
3078
3079               --  Verify the pragma belongs to T, otherwise the pragma applies
3080               --  to a parent type in which case it will be processed later by
3081               --  Add_Parent_Invariants or Add_Interface_Invariants.
3082
3083               if Entity (Prag_Typ) /= T then
3084                  return;
3085               end if;
3086
3087               Expr := New_Copy_Tree (Prag_Expr);
3088
3089               --  Substitute all references to type T with references to the
3090               --  _object formal parameter.
3091
3092               Replace_Type_References (Expr, T, Obj_Id);
3093
3094               --  Preanalyze the invariant expression to detect errors and at
3095               --  the same time capture the visibility of the proper package
3096               --  part.
3097
3098               Set_Parent (Expr, Parent (Prag_Expr));
3099               Preanalyze_Assert_Expression (Expr, Any_Boolean);
3100
3101               --  Save a copy of the expression when T is tagged to detect
3102               --  errors and capture the visibility of the proper package part
3103               --  for the generation of inherited type invariants.
3104
3105               if Is_Tagged_Type (T) then
3106                  Set_Expression_Copy (Prag_Expr_Arg, New_Copy_Tree (Expr));
3107               end if;
3108
3109               --  If the pragma comes from an aspect specification, replace
3110               --  the saved expression because all type references must be
3111               --  substituted for the call to Preanalyze_Spec_Expression in
3112               --  Check_Aspect_At_xxx routines.
3113
3114               if Present (Prag_Asp) then
3115                  Set_Entity (Identifier (Prag_Asp), New_Copy_Tree (Expr));
3116               end if;
3117
3118               Add_Invariant_Check (Prag, Expr, Checks);
3119            end if;
3120
3121            Next_Rep_Item (Prag);
3122         end loop;
3123      end Add_Own_Invariants;
3124
3125      -------------------------------------
3126      -- Add_Record_Component_Invariants --
3127      -------------------------------------
3128
3129      procedure Add_Record_Component_Invariants
3130        (T      : Entity_Id;
3131         Obj_Id : Entity_Id;
3132         Checks : in out List_Id)
3133      is
3134         procedure Process_Component_List
3135           (Comp_List : Node_Id;
3136            CL_Checks : in out List_Id);
3137         --  Generate invariant checks for all record components found in
3138         --  component list Comp_List, including variant parts. All created
3139         --  checks are added to list CL_Checks.
3140
3141         procedure Process_Record_Component
3142           (Comp_Id     : Entity_Id;
3143            Comp_Checks : in out List_Id);
3144         --  Generate an invariant check for a record component identified by
3145         --  Comp_Id. All created checks are added to list Comp_Checks.
3146
3147         ----------------------------
3148         -- Process_Component_List --
3149         ----------------------------
3150
3151         procedure Process_Component_List
3152           (Comp_List : Node_Id;
3153            CL_Checks : in out List_Id)
3154         is
3155            Comp       : Node_Id;
3156            Var        : Node_Id;
3157            Var_Alts   : List_Id := No_List;
3158            Var_Checks : List_Id := No_List;
3159            Var_Stmts  : List_Id;
3160
3161            Produced_Variant_Check : Boolean := False;
3162            --  This flag tracks whether the component has produced at least
3163            --  one invariant check.
3164
3165         begin
3166            --  Traverse the component items
3167
3168            Comp := First (Component_Items (Comp_List));
3169            while Present (Comp) loop
3170               if Nkind (Comp) = N_Component_Declaration then
3171
3172                  --  Generate the component invariant check
3173
3174                  Process_Record_Component
3175                    (Comp_Id     => Defining_Entity (Comp),
3176                     Comp_Checks => CL_Checks);
3177               end if;
3178
3179               Next (Comp);
3180            end loop;
3181
3182            --  Traverse the variant part
3183
3184            if Present (Variant_Part (Comp_List)) then
3185               Var := First (Variants (Variant_Part (Comp_List)));
3186               while Present (Var) loop
3187                  Var_Checks := No_List;
3188
3189                  --  Generate invariant checks for all components and variant
3190                  --  parts that qualify.
3191
3192                  Process_Component_List
3193                    (Comp_List => Component_List (Var),
3194                     CL_Checks => Var_Checks);
3195
3196                  --  The components of the current variant produced at least
3197                  --  one invariant check.
3198
3199                  if Present (Var_Checks) then
3200                     Var_Stmts := Var_Checks;
3201                     Produced_Variant_Check := True;
3202
3203                  --  Otherwise there are either no components with invariants,
3204                  --  assertions are disabled, or Assertion_Policy Ignore is in
3205                  --  effect.
3206
3207                  else
3208                     Var_Stmts := New_List (Make_Null_Statement (Loc));
3209                  end if;
3210
3211                  Append_New_To (Var_Alts,
3212                    Make_Case_Statement_Alternative (Loc,
3213                      Discrete_Choices =>
3214                        New_Copy_List (Discrete_Choices (Var)),
3215                      Statements       => Var_Stmts));
3216
3217                  Next (Var);
3218               end loop;
3219
3220               --  Create a case statement which verifies the invariant checks
3221               --  of a particular component list depending on the discriminant
3222               --  values only when there is at least one real invariant check.
3223
3224               if Produced_Variant_Check then
3225                  Append_New_To (CL_Checks,
3226                    Make_Case_Statement (Loc,
3227                      Expression   =>
3228                        Make_Selected_Component (Loc,
3229                          Prefix        => New_Occurrence_Of (Obj_Id, Loc),
3230                          Selector_Name =>
3231                            New_Occurrence_Of
3232                              (Entity (Name (Variant_Part (Comp_List))), Loc)),
3233                      Alternatives => Var_Alts));
3234               end if;
3235            end if;
3236         end Process_Component_List;
3237
3238         ------------------------------
3239         -- Process_Record_Component --
3240         ------------------------------
3241
3242         procedure Process_Record_Component
3243           (Comp_Id     : Entity_Id;
3244            Comp_Checks : in out List_Id)
3245         is
3246            Comp_Typ : constant Entity_Id := Etype (Comp_Id);
3247            Proc_Id  : Entity_Id;
3248
3249            Produced_Component_Check : Boolean := False;
3250            --  This flag tracks whether the component has produced at least
3251            --  one invariant check.
3252
3253         begin
3254            --  Nothing to do for internal component _parent. Note that it is
3255            --  not desirable to check whether the component comes from source
3256            --  because protected type components are relocated to an internal
3257            --  corresponding record, but still need processing.
3258
3259            if Chars (Comp_Id) = Name_uParent then
3260               return;
3261            end if;
3262
3263            --  Verify the invariant of the component. Note that an access
3264            --  type may have an invariant when it acts as the full view of a
3265            --  private type and the invariant appears on the partial view. In
3266            --  this case verify the access value itself.
3267
3268            if Has_Invariants (Comp_Typ) then
3269
3270               --  In GNATprove mode, the component invariants are checked by
3271               --  other means. They should not be added to the record type
3272               --  invariant procedure, so that the procedure can be used to
3273               --  check the record type invariants if any.
3274
3275               if GNATprove_Mode then
3276                  null;
3277
3278               else
3279                  Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
3280
3281                  --  The component type should have an invariant procedure
3282                  --  if it has invariants of its own or inherits class-wide
3283                  --  invariants from parent or interface types.
3284
3285                  pragma Assert (Present (Proc_Id));
3286
3287                  --  Generate:
3288                  --    <Comp_Typ>Invariant (T (_object).<Comp_Id>);
3289
3290                  --  Note that the invariant procedure may have a null body if
3291                  --  assertions are disabled or Assertion_Policy Ignore is in
3292                  --  effect.
3293
3294                  if not Has_Null_Body (Proc_Id) then
3295                     Append_New_To (Comp_Checks,
3296                       Make_Procedure_Call_Statement (Loc,
3297                         Name                   =>
3298                           New_Occurrence_Of (Proc_Id, Loc),
3299                         Parameter_Associations => New_List (
3300                           Make_Selected_Component (Loc,
3301                             Prefix        =>
3302                               Unchecked_Convert_To
3303                                 (T, New_Occurrence_Of (Obj_Id, Loc)),
3304                             Selector_Name =>
3305                               New_Occurrence_Of (Comp_Id, Loc)))));
3306                  end if;
3307               end if;
3308
3309               Produced_Check           := True;
3310               Produced_Component_Check := True;
3311            end if;
3312
3313            if Produced_Component_Check and then Has_Unchecked_Union (T) then
3314               Error_Msg_NE
3315                 ("invariants cannot be checked on components of "
3316                  & "unchecked_union type &??", Comp_Id, T);
3317            end if;
3318         end Process_Record_Component;
3319
3320         --  Local variables
3321
3322         Comps : Node_Id;
3323         Def   : Node_Id;
3324
3325      --  Start of processing for Add_Record_Component_Invariants
3326
3327      begin
3328         --  An untagged derived type inherits the components of its parent
3329         --  type. In order to avoid creating redundant invariant checks, do
3330         --  not process the components now. Instead wait until the ultimate
3331         --  parent of the untagged derivation chain is reached.
3332
3333         if not Is_Untagged_Derivation (T) then
3334            Def := Type_Definition (Parent (T));
3335
3336            if Nkind (Def) = N_Derived_Type_Definition then
3337               Def := Record_Extension_Part (Def);
3338            end if;
3339
3340            pragma Assert (Nkind (Def) = N_Record_Definition);
3341            Comps := Component_List (Def);
3342
3343            if Present (Comps) then
3344               Process_Component_List
3345                 (Comp_List => Comps,
3346                  CL_Checks => Checks);
3347            end if;
3348         end if;
3349      end Add_Record_Component_Invariants;
3350
3351      --  Local variables
3352
3353      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
3354      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
3355      --  Save the Ghost-related attributes to restore on exit
3356
3357      Dummy        : Entity_Id;
3358      Priv_Item    : Node_Id;
3359      Proc_Body    : Node_Id;
3360      Proc_Body_Id : Entity_Id;
3361      Proc_Decl    : Node_Id;
3362      Proc_Id      : Entity_Id;
3363      Stmts        : List_Id := No_List;
3364
3365      CRec_Typ : Entity_Id := Empty;
3366      --  The corresponding record type of Full_Typ
3367
3368      Full_Proc : Entity_Id := Empty;
3369      --  The entity of the "full" invariant procedure
3370
3371      Full_Typ : Entity_Id := Empty;
3372      --  The full view of the working type
3373
3374      Obj_Id : Entity_Id := Empty;
3375      --  The _object formal parameter of the invariant procedure
3376
3377      Part_Proc : Entity_Id := Empty;
3378      --  The entity of the "partial" invariant procedure
3379
3380      Priv_Typ : Entity_Id := Empty;
3381      --  The partial view of the working type
3382
3383      Work_Typ : Entity_Id := Empty;
3384      --  The working type
3385
3386   --  Start of processing for Build_Invariant_Procedure_Body
3387
3388   begin
3389      Work_Typ := Typ;
3390
3391      --  Do not process the underlying full view of a private type. There is
3392      --  no way to get back to the partial view, plus the body will be built
3393      --  by the full view or the base type.
3394
3395      if Is_Underlying_Full_View (Work_Typ) then
3396         return;
3397
3398      --  The input type denotes the implementation base type of a constrained
3399      --  array type. Work with the first subtype as all invariant pragmas are
3400      --  on its rep item chain.
3401
3402      elsif Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3403         Work_Typ := First_Subtype (Work_Typ);
3404
3405      --  The input type denotes the corresponding record type of a protected
3406      --  or task type. Work with the concurrent type because the corresponding
3407      --  record type may not be visible to clients of the type.
3408
3409      elsif Ekind (Work_Typ) = E_Record_Type
3410        and then Is_Concurrent_Record_Type (Work_Typ)
3411      then
3412         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3413      end if;
3414
3415      --  The working type may be subject to pragma Ghost. Set the mode now to
3416      --  ensure that the invariant procedure is properly marked as Ghost.
3417
3418      Set_Ghost_Mode (Work_Typ);
3419
3420      --  The type must either have invariants of its own, inherit class-wide
3421      --  invariants from parent types or interfaces, or be an array or record
3422      --  type whose components have invariants.
3423
3424      pragma Assert (Has_Invariants (Work_Typ));
3425
3426      --  Interfaces are treated as the partial view of a private type in order
3427      --  to achieve uniformity with the general case.
3428
3429      if Is_Interface (Work_Typ) then
3430         Priv_Typ := Work_Typ;
3431
3432      --  Otherwise obtain both views of the type
3433
3434      else
3435         Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy, CRec_Typ);
3436      end if;
3437
3438      --  The caller requests a body for the partial invariant procedure
3439
3440      if Partial_Invariant then
3441         Full_Proc := Invariant_Procedure (Work_Typ);
3442         Proc_Id   := Partial_Invariant_Procedure (Work_Typ);
3443
3444         --  The "full" invariant procedure body was already created
3445
3446         if Present (Full_Proc)
3447           and then Present
3448                      (Corresponding_Body (Unit_Declaration_Node (Full_Proc)))
3449         then
3450            --  This scenario happens only when the type is an untagged
3451            --  derivation from a private parent and the underlying full
3452            --  view was processed before the partial view.
3453
3454            pragma Assert
3455              (Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ));
3456
3457            --  Nothing to do because the processing of the underlying full
3458            --  view already checked the invariants of the partial view.
3459
3460            goto Leave;
3461         end if;
3462
3463         --  Create a declaration for the "partial" invariant procedure if it
3464         --  is not available.
3465
3466         if No (Proc_Id) then
3467            Build_Invariant_Procedure_Declaration
3468              (Typ               => Work_Typ,
3469               Partial_Invariant => True);
3470
3471            Proc_Id := Partial_Invariant_Procedure (Work_Typ);
3472         end if;
3473
3474      --  The caller requests a body for the "full" invariant procedure
3475
3476      else
3477         Proc_Id   := Invariant_Procedure (Work_Typ);
3478         Part_Proc := Partial_Invariant_Procedure (Work_Typ);
3479
3480         --  Create a declaration for the "full" invariant procedure if it is
3481         --  not available.
3482
3483         if No (Proc_Id) then
3484            Build_Invariant_Procedure_Declaration (Work_Typ);
3485            Proc_Id := Invariant_Procedure (Work_Typ);
3486         end if;
3487      end if;
3488
3489      --  At this point there should be an invariant procedure declaration
3490
3491      pragma Assert (Present (Proc_Id));
3492      Proc_Decl := Unit_Declaration_Node (Proc_Id);
3493
3494      --  Nothing to do if the invariant procedure already has a body
3495
3496      if Present (Corresponding_Body (Proc_Decl)) then
3497         goto Leave;
3498      end if;
3499
3500      --  Emulate the environment of the invariant procedure by installing its
3501      --  scope and formal parameters. Note that this is not needed, but having
3502      --  the scope installed helps with the detection of invariant-related
3503      --  errors.
3504
3505      Push_Scope (Proc_Id);
3506      Install_Formals (Proc_Id);
3507
3508      Obj_Id := First_Formal (Proc_Id);
3509      pragma Assert (Present (Obj_Id));
3510
3511      --  The "partial" invariant procedure verifies the invariants of the
3512      --  partial view only.
3513
3514      if Partial_Invariant then
3515         pragma Assert (Present (Priv_Typ));
3516
3517         Add_Own_Invariants
3518           (T      => Priv_Typ,
3519            Obj_Id => Obj_Id,
3520            Checks => Stmts);
3521
3522      --  Otherwise the "full" invariant procedure verifies the invariants of
3523      --  the full view, all array or record components, as well as class-wide
3524      --  invariants inherited from parent types or interfaces. In addition, it
3525      --  indirectly verifies the invariants of the partial view by calling the
3526      --  "partial" invariant procedure.
3527
3528      else
3529         pragma Assert (Present (Full_Typ));
3530
3531         --  Check the invariants of the partial view by calling the "partial"
3532         --  invariant procedure. Generate:
3533
3534         --    <Work_Typ>Partial_Invariant (_object);
3535
3536         if Present (Part_Proc) then
3537            Append_New_To (Stmts,
3538              Make_Procedure_Call_Statement (Loc,
3539                Name                   => New_Occurrence_Of (Part_Proc, Loc),
3540                Parameter_Associations => New_List (
3541                  New_Occurrence_Of (Obj_Id, Loc))));
3542
3543            Produced_Check := True;
3544         end if;
3545
3546         Priv_Item := Empty;
3547
3548         --  Derived subtypes do not have a partial view
3549
3550         if Present (Priv_Typ) then
3551
3552            --  The processing of the "full" invariant procedure intentionally
3553            --  skips the partial view because a) this may result in changes of
3554            --  visibility and b) lead to duplicate checks. However, when the
3555            --  full view is the underlying full view of an untagged derived
3556            --  type whose parent type is private, partial invariants appear on
3557            --  the rep item chain of the partial view only.
3558
3559            --    package Pack_1 is
3560            --       type Root ... is private;
3561            --    private
3562            --       <full view of Root>
3563            --    end Pack_1;
3564
3565            --    with Pack_1;
3566            --    package Pack_2 is
3567            --       type Child is new Pack_1.Root with Type_Invariant => ...;
3568            --       <underlying full view of Child>
3569            --    end Pack_2;
3570
3571            --  As a result, the processing of the full view must also consider
3572            --  all invariants of the partial view.
3573
3574            if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
3575               null;
3576
3577            --  Otherwise the invariants of the partial view are ignored
3578
3579            else
3580               --  Note that the rep item chain is shared between the partial
3581               --  and full views of a type. To avoid processing the invariants
3582               --  of the partial view, signal the logic to stop when the first
3583               --  rep item of the partial view has been reached.
3584
3585               Priv_Item := First_Rep_Item (Priv_Typ);
3586
3587               --  Ignore the invariants of the partial view by eliminating the
3588               --  view.
3589
3590               Priv_Typ := Empty;
3591            end if;
3592         end if;
3593
3594         --  Process the invariants of the full view and in certain cases those
3595         --  of the partial view. This also handles any invariants on array or
3596         --  record components.
3597
3598         Add_Own_Invariants
3599           (T         => Priv_Typ,
3600            Obj_Id    => Obj_Id,
3601            Checks    => Stmts,
3602            Priv_Item => Priv_Item);
3603
3604         Add_Own_Invariants
3605           (T         => Full_Typ,
3606            Obj_Id    => Obj_Id,
3607            Checks    => Stmts,
3608            Priv_Item => Priv_Item);
3609
3610         --  Process the elements of an array type
3611
3612         if Is_Array_Type (Full_Typ) then
3613            Add_Array_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3614
3615         --  Process the components of a record type
3616
3617         elsif Ekind (Full_Typ) = E_Record_Type then
3618            Add_Record_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3619
3620         --  Process the components of a corresponding record
3621
3622         elsif Present (CRec_Typ) then
3623            Add_Record_Component_Invariants (CRec_Typ, Obj_Id, Stmts);
3624         end if;
3625
3626         --  Process the inherited class-wide invariants of all parent types.
3627         --  This also handles any invariants on record components.
3628
3629         Add_Parent_Invariants (Full_Typ, Obj_Id, Stmts);
3630
3631         --  Process the inherited class-wide invariants of all implemented
3632         --  interface types.
3633
3634         Add_Interface_Invariants (Full_Typ, Obj_Id, Stmts);
3635      end if;
3636
3637      End_Scope;
3638
3639      --  At this point there should be at least one invariant check. If this
3640      --  is not the case, then the invariant-related flags were not properly
3641      --  set, or there is a missing invariant procedure on one of the array
3642      --  or record components.
3643
3644      pragma Assert (Produced_Check);
3645
3646      --  Account for the case where assertions are disabled or all invariant
3647      --  checks are subject to Assertion_Policy Ignore. Produce a completing
3648      --  empty body.
3649
3650      if No (Stmts) then
3651         Stmts := New_List (Make_Null_Statement (Loc));
3652      end if;
3653
3654      --  Generate:
3655      --    procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>) is
3656      --    begin
3657      --       <Stmts>
3658      --    end <Work_Typ>[Partial_]Invariant;
3659
3660      Proc_Body :=
3661        Make_Subprogram_Body (Loc,
3662          Specification                =>
3663            Copy_Subprogram_Spec (Parent (Proc_Id)),
3664          Declarations                 => Empty_List,
3665            Handled_Statement_Sequence =>
3666              Make_Handled_Sequence_Of_Statements (Loc,
3667                Statements => Stmts));
3668      Proc_Body_Id := Defining_Entity (Proc_Body);
3669
3670      --  Perform minor decoration in case the body is not analyzed
3671
3672      Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
3673      Set_Etype (Proc_Body_Id, Standard_Void_Type);
3674      Set_Scope (Proc_Body_Id, Current_Scope);
3675
3676      --  Link both spec and body to avoid generating duplicates
3677
3678      Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
3679      Set_Corresponding_Spec (Proc_Body, Proc_Id);
3680
3681      --  The body should not be inserted into the tree when the context is
3682      --  a generic unit because it is not part of the template. Note
3683      --  that the body must still be generated in order to resolve the
3684      --  invariants.
3685
3686      if Inside_A_Generic then
3687         null;
3688
3689      --  Semi-insert the body into the tree for GNATprove by setting its
3690      --  Parent field. This allows for proper upstream tree traversals.
3691
3692      elsif GNATprove_Mode then
3693         Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
3694
3695      --  Otherwise the body is part of the freezing actions of the type
3696
3697      else
3698         Append_Freeze_Action (Work_Typ, Proc_Body);
3699      end if;
3700
3701   <<Leave>>
3702      Restore_Ghost_Region (Saved_GM, Saved_IGR);
3703   end Build_Invariant_Procedure_Body;
3704
3705   -------------------------------------------
3706   -- Build_Invariant_Procedure_Declaration --
3707   -------------------------------------------
3708
3709   --  WARNING: This routine manages Ghost regions. Return statements must be
3710   --  replaced by gotos which jump to the end of the routine and restore the
3711   --  Ghost mode.
3712
3713   procedure Build_Invariant_Procedure_Declaration
3714     (Typ               : Entity_Id;
3715      Partial_Invariant : Boolean := False)
3716   is
3717      Loc : constant Source_Ptr := Sloc (Typ);
3718
3719      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
3720      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
3721      --  Save the Ghost-related attributes to restore on exit
3722
3723      Proc_Decl : Node_Id;
3724      Proc_Id   : Entity_Id;
3725      Proc_Nam  : Name_Id;
3726      Typ_Decl  : Node_Id;
3727
3728      CRec_Typ : Entity_Id;
3729      --  The corresponding record type of Full_Typ
3730
3731      Full_Typ : Entity_Id;
3732      --  The full view of working type
3733
3734      Obj_Id : Entity_Id;
3735      --  The _object formal parameter of the invariant procedure
3736
3737      Obj_Typ : Entity_Id;
3738      --  The type of the _object formal parameter
3739
3740      Priv_Typ : Entity_Id;
3741      --  The partial view of working type
3742
3743      UFull_Typ : Entity_Id;
3744      --  The underlying full view of Full_Typ
3745
3746      Work_Typ : Entity_Id;
3747      --  The working type
3748
3749   begin
3750      Work_Typ := Typ;
3751
3752      --  The input type denotes the implementation base type of a constrained
3753      --  array type. Work with the first subtype as all invariant pragmas are
3754      --  on its rep item chain.
3755
3756      if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3757         Work_Typ := First_Subtype (Work_Typ);
3758
3759      --  The input denotes the corresponding record type of a protected or a
3760      --  task type. Work with the concurrent type because the corresponding
3761      --  record type may not be visible to clients of the type.
3762
3763      elsif Ekind (Work_Typ) = E_Record_Type
3764        and then Is_Concurrent_Record_Type (Work_Typ)
3765      then
3766         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3767      end if;
3768
3769      --  The working type may be subject to pragma Ghost. Set the mode now to
3770      --  ensure that the invariant procedure is properly marked as Ghost.
3771
3772      Set_Ghost_Mode (Work_Typ);
3773
3774      --  The type must either have invariants of its own, inherit class-wide
3775      --  invariants from parent or interface types, or be an array or record
3776      --  type whose components have invariants.
3777
3778      pragma Assert (Has_Invariants (Work_Typ));
3779
3780      --  Nothing to do if the type already has a "partial" invariant procedure
3781
3782      if Partial_Invariant then
3783         if Present (Partial_Invariant_Procedure (Work_Typ)) then
3784            goto Leave;
3785         end if;
3786
3787      --  Nothing to do if the type already has a "full" invariant procedure
3788
3789      elsif Present (Invariant_Procedure (Work_Typ)) then
3790         goto Leave;
3791      end if;
3792
3793      --  The caller requests the declaration of the "partial" invariant
3794      --  procedure.
3795
3796      if Partial_Invariant then
3797         Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_Invariant");
3798
3799      --  Otherwise the caller requests the declaration of the "full" invariant
3800      --  procedure.
3801
3802      else
3803         Proc_Nam := New_External_Name (Chars (Work_Typ), "Invariant");
3804      end if;
3805
3806      Proc_Id := Make_Defining_Identifier (Loc, Chars => Proc_Nam);
3807
3808      --  Perform minor decoration in case the declaration is not analyzed
3809
3810      Set_Ekind (Proc_Id, E_Procedure);
3811      Set_Etype (Proc_Id, Standard_Void_Type);
3812      Set_Scope (Proc_Id, Current_Scope);
3813
3814      if Partial_Invariant then
3815         Set_Is_Partial_Invariant_Procedure (Proc_Id);
3816         Set_Partial_Invariant_Procedure (Work_Typ, Proc_Id);
3817      else
3818         Set_Is_Invariant_Procedure (Proc_Id);
3819         Set_Invariant_Procedure (Work_Typ, Proc_Id);
3820      end if;
3821
3822      --  The invariant procedure requires debug info when the invariants are
3823      --  subject to Source Coverage Obligations.
3824
3825      if Generate_SCO then
3826         Set_Debug_Info_Needed (Proc_Id);
3827      end if;
3828
3829      --  Obtain all views of the input type
3830
3831      Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);
3832
3833      --  Associate the invariant procedure and various flags with all views
3834
3835      Propagate_Invariant_Attributes (Priv_Typ,  From_Typ => Work_Typ);
3836      Propagate_Invariant_Attributes (Full_Typ,  From_Typ => Work_Typ);
3837      Propagate_Invariant_Attributes (UFull_Typ, From_Typ => Work_Typ);
3838      Propagate_Invariant_Attributes (CRec_Typ,  From_Typ => Work_Typ);
3839
3840      --  The declaration of the invariant procedure is inserted after the
3841      --  declaration of the partial view as this allows for proper external
3842      --  visibility.
3843
3844      if Present (Priv_Typ) then
3845         Typ_Decl := Declaration_Node (Priv_Typ);
3846
3847      --  Anonymous arrays in object declarations have no explicit declaration
3848      --  so use the related object declaration as the insertion point.
3849
3850      elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ)  then
3851         Typ_Decl := Associated_Node_For_Itype (Work_Typ);
3852
3853      --  Derived types with the full view as parent do not have a partial
3854      --  view. Insert the invariant procedure after the derived type.
3855
3856      else
3857         Typ_Decl := Declaration_Node (Full_Typ);
3858      end if;
3859
3860      --  The type should have a declarative node
3861
3862      pragma Assert (Present (Typ_Decl));
3863
3864      --  Create the formal parameter which emulates the variable-like behavior
3865      --  of the current type instance.
3866
3867      Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
3868
3869      --  When generating an invariant procedure declaration for an abstract
3870      --  type (including interfaces), use the class-wide type as the _object
3871      --  type. This has several desirable effects:
3872
3873      --    * The invariant procedure does not become a primitive of the type.
3874      --      This eliminates the need to either special case the treatment of
3875      --      invariant procedures, or to make it a predefined primitive and
3876      --      force every derived type to potentially provide an empty body.
3877
3878      --    * The invariant procedure does not need to be declared as abstract.
3879      --      This allows for a proper body, which in turn avoids redundant
3880      --      processing of the same invariants for types with multiple views.
3881
3882      --    * The class-wide type allows for calls to abstract primitives
3883      --      within a nonabstract subprogram. The calls are treated as
3884      --      dispatching and require additional processing when they are
3885      --      remapped to call primitives of derived types. See routine
3886      --      Replace_References for details.
3887
3888      if Is_Abstract_Type (Work_Typ) then
3889         Obj_Typ := Class_Wide_Type (Work_Typ);
3890      else
3891         Obj_Typ := Work_Typ;
3892      end if;
3893
3894      --  Perform minor decoration in case the declaration is not analyzed
3895
3896      Set_Ekind (Obj_Id, E_In_Parameter);
3897      Set_Etype (Obj_Id, Obj_Typ);
3898      Set_Scope (Obj_Id, Proc_Id);
3899
3900      Set_First_Entity (Proc_Id, Obj_Id);
3901      Set_Last_Entity  (Proc_Id, Obj_Id);
3902
3903      --  Generate:
3904      --    procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>);
3905
3906      Proc_Decl :=
3907        Make_Subprogram_Declaration (Loc,
3908          Specification =>
3909            Make_Procedure_Specification (Loc,
3910              Defining_Unit_Name       => Proc_Id,
3911              Parameter_Specifications => New_List (
3912                Make_Parameter_Specification (Loc,
3913                  Defining_Identifier => Obj_Id,
3914                  Parameter_Type      => New_Occurrence_Of (Obj_Typ, Loc)))));
3915
3916      --  The declaration should not be inserted into the tree when the context
3917      --  is a generic unit because it is not part of the template.
3918
3919      if Inside_A_Generic then
3920         null;
3921
3922      --  Semi-insert the declaration into the tree for GNATprove by setting
3923      --  its Parent field. This allows for proper upstream tree traversals.
3924
3925      elsif GNATprove_Mode then
3926         Set_Parent (Proc_Decl, Parent (Typ_Decl));
3927
3928      --  Otherwise insert the declaration
3929
3930      else
3931         pragma Assert (Present (Typ_Decl));
3932         Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
3933      end if;
3934
3935   <<Leave>>
3936      Restore_Ghost_Region (Saved_GM, Saved_IGR);
3937   end Build_Invariant_Procedure_Declaration;
3938
3939   --------------------------
3940   -- Build_Procedure_Form --
3941   --------------------------
3942
3943   procedure Build_Procedure_Form (N : Node_Id) is
3944      Loc  : constant Source_Ptr := Sloc (N);
3945      Subp : constant Entity_Id := Defining_Entity (N);
3946
3947      Func_Formal  : Entity_Id;
3948      Proc_Formals : List_Id;
3949      Proc_Decl    : Node_Id;
3950
3951   begin
3952      --  No action needed if this transformation was already done, or in case
3953      --  of subprogram renaming declarations.
3954
3955      if Nkind (Specification (N)) = N_Procedure_Specification
3956        or else Nkind (N) = N_Subprogram_Renaming_Declaration
3957      then
3958         return;
3959      end if;
3960
3961      --  Ditto when dealing with an expression function, where both the
3962      --  original expression and the generated declaration end up being
3963      --  expanded here.
3964
3965      if Rewritten_For_C (Subp) then
3966         return;
3967      end if;
3968
3969      Proc_Formals := New_List;
3970
3971      --  Create a list of formal parameters with the same types as the
3972      --  function.
3973
3974      Func_Formal := First_Formal (Subp);
3975      while Present (Func_Formal) loop
3976         Append_To (Proc_Formals,
3977           Make_Parameter_Specification (Loc,
3978             Defining_Identifier =>
3979               Make_Defining_Identifier (Loc, Chars (Func_Formal)),
3980             Parameter_Type      =>
3981               New_Occurrence_Of (Etype (Func_Formal), Loc)));
3982
3983         Next_Formal (Func_Formal);
3984      end loop;
3985
3986      --  Add an extra out parameter to carry the function result
3987
3988      Append_To (Proc_Formals,
3989        Make_Parameter_Specification (Loc,
3990          Defining_Identifier =>
3991            Make_Defining_Identifier (Loc, Name_UP_RESULT),
3992          Out_Present         => True,
3993          Parameter_Type      => New_Occurrence_Of (Etype (Subp), Loc)));
3994
3995      --  The new procedure declaration is inserted before the function
3996      --  declaration. The processing in Build_Procedure_Body_Form relies on
3997      --  this order. Note that we insert before because in the case of a
3998      --  function body with no separate spec, we do not want to insert the
3999      --  new spec after the body which will later get rewritten.
4000
4001      Proc_Decl :=
4002        Make_Subprogram_Declaration (Loc,
4003          Specification =>
4004            Make_Procedure_Specification (Loc,
4005              Defining_Unit_Name       =>
4006                Make_Defining_Identifier (Loc, Chars (Subp)),
4007              Parameter_Specifications => Proc_Formals));
4008
4009      Insert_Before_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
4010
4011      --  Entity of procedure must remain invisible so that it does not
4012      --  overload subsequent references to the original function.
4013
4014      Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False);
4015
4016      --  Mark the function as having a procedure form and link the function
4017      --  and its internally built procedure.
4018
4019      Set_Rewritten_For_C (Subp);
4020      Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl));
4021      Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp);
4022   end Build_Procedure_Form;
4023
4024   ------------------------
4025   -- Build_Runtime_Call --
4026   ------------------------
4027
4028   function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
4029   begin
4030      --  If entity is not available, we can skip making the call (this avoids
4031      --  junk duplicated error messages in a number of cases).
4032
4033      if not RTE_Available (RE) then
4034         return Make_Null_Statement (Loc);
4035      else
4036         return
4037           Make_Procedure_Call_Statement (Loc,
4038             Name => New_Occurrence_Of (RTE (RE), Loc));
4039      end if;
4040   end Build_Runtime_Call;
4041
4042   ------------------------
4043   -- Build_SS_Mark_Call --
4044   ------------------------
4045
4046   function Build_SS_Mark_Call
4047     (Loc  : Source_Ptr;
4048      Mark : Entity_Id) return Node_Id
4049   is
4050   begin
4051      --  Generate:
4052      --    Mark : constant Mark_Id := SS_Mark;
4053
4054      return
4055        Make_Object_Declaration (Loc,
4056          Defining_Identifier => Mark,
4057          Constant_Present    => True,
4058          Object_Definition   =>
4059            New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
4060          Expression          =>
4061            Make_Function_Call (Loc,
4062              Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc)));
4063   end Build_SS_Mark_Call;
4064
4065   ---------------------------
4066   -- Build_SS_Release_Call --
4067   ---------------------------
4068
4069   function Build_SS_Release_Call
4070     (Loc  : Source_Ptr;
4071      Mark : Entity_Id) return Node_Id
4072   is
4073   begin
4074      --  Generate:
4075      --    SS_Release (Mark);
4076
4077      return
4078        Make_Procedure_Call_Statement (Loc,
4079          Name                   =>
4080            New_Occurrence_Of (RTE (RE_SS_Release), Loc),
4081          Parameter_Associations => New_List (
4082            New_Occurrence_Of (Mark, Loc)));
4083   end Build_SS_Release_Call;
4084
4085   ----------------------------
4086   -- Build_Task_Array_Image --
4087   ----------------------------
4088
4089   --  This function generates the body for a function that constructs the
4090   --  image string for a task that is an array component. The function is
4091   --  local to the init proc for the array type, and is called for each one
4092   --  of the components. The constructed image has the form of an indexed
4093   --  component, whose prefix is the outer variable of the array type.
4094   --  The n-dimensional array type has known indexes Index, Index2...
4095
4096   --  Id_Ref is an indexed component form created by the enclosing init proc.
4097   --  Its successive indexes are Val1, Val2, ... which are the loop variables
4098   --  in the loops that call the individual task init proc on each component.
4099
4100   --  The generated function has the following structure:
4101
4102   --  function F return String is
4103   --     Pref : string renames Task_Name;
4104   --     T1   : String := Index1'Image (Val1);
4105   --     ...
4106   --     Tn   : String := indexn'image (Valn);
4107   --     Len  : Integer := T1'Length + ... + Tn'Length + n + 1;
4108   --     --  Len includes commas and the end parentheses.
4109   --     Res  : String (1..Len);
4110   --     Pos  : Integer := Pref'Length;
4111   --
4112   --  begin
4113   --     Res (1 .. Pos) := Pref;
4114   --     Pos := Pos + 1;
4115   --     Res (Pos)    := '(';
4116   --     Pos := Pos + 1;
4117   --     Res (Pos .. Pos + T1'Length - 1) := T1;
4118   --     Pos := Pos + T1'Length;
4119   --     Res (Pos) := '.';
4120   --     Pos := Pos + 1;
4121   --     ...
4122   --     Res (Pos .. Pos + Tn'Length - 1) := Tn;
4123   --     Res (Len) := ')';
4124   --
4125   --     return Res;
4126   --  end F;
4127   --
4128   --  Needless to say, multidimensional arrays of tasks are rare enough that
4129   --  the bulkiness of this code is not really a concern.
4130
4131   function Build_Task_Array_Image
4132     (Loc    : Source_Ptr;
4133      Id_Ref : Node_Id;
4134      A_Type : Entity_Id;
4135      Dyn    : Boolean := False) return Node_Id
4136   is
4137      Dims : constant Nat := Number_Dimensions (A_Type);
4138      --  Number of dimensions for array of tasks
4139
4140      Temps : array (1 .. Dims) of Entity_Id;
4141      --  Array of temporaries to hold string for each index
4142
4143      Indx : Node_Id;
4144      --  Index expression
4145
4146      Len : Entity_Id;
4147      --  Total length of generated name
4148
4149      Pos : Entity_Id;
4150      --  Running index for substring assignments
4151
4152      Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
4153      --  Name of enclosing variable, prefix of resulting name
4154
4155      Res : Entity_Id;
4156      --  String to hold result
4157
4158      Val : Node_Id;
4159      --  Value of successive indexes
4160
4161      Sum : Node_Id;
4162      --  Expression to compute total size of string
4163
4164      T : Entity_Id;
4165      --  Entity for name at one index position
4166
4167      Decls : constant List_Id := New_List;
4168      Stats : constant List_Id := New_List;
4169
4170   begin
4171      --  For a dynamic task, the name comes from the target variable. For a
4172      --  static one it is a formal of the enclosing init proc.
4173
4174      if Dyn then
4175         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
4176         Append_To (Decls,
4177           Make_Object_Declaration (Loc,
4178             Defining_Identifier => Pref,
4179             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4180             Expression =>
4181               Make_String_Literal (Loc,
4182                 Strval => String_From_Name_Buffer)));
4183
4184      else
4185         Append_To (Decls,
4186           Make_Object_Renaming_Declaration (Loc,
4187             Defining_Identifier => Pref,
4188             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
4189             Name                => Make_Identifier (Loc, Name_uTask_Name)));
4190      end if;
4191
4192      Indx := First_Index (A_Type);
4193      Val  := First (Expressions (Id_Ref));
4194
4195      for J in 1 .. Dims loop
4196         T := Make_Temporary (Loc, 'T');
4197         Temps (J) := T;
4198
4199         Append_To (Decls,
4200           Make_Object_Declaration (Loc,
4201             Defining_Identifier => T,
4202             Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
4203             Expression          =>
4204               Make_Attribute_Reference (Loc,
4205                 Attribute_Name => Name_Image,
4206                 Prefix         => New_Occurrence_Of (Etype (Indx), Loc),
4207                 Expressions    => New_List (New_Copy_Tree (Val)))));
4208
4209         Next_Index (Indx);
4210         Next (Val);
4211      end loop;
4212
4213      Sum := Make_Integer_Literal (Loc, Dims + 1);
4214
4215      Sum :=
4216        Make_Op_Add (Loc,
4217          Left_Opnd => Sum,
4218          Right_Opnd =>
4219            Make_Attribute_Reference (Loc,
4220              Attribute_Name => Name_Length,
4221              Prefix         => New_Occurrence_Of (Pref, Loc),
4222              Expressions    => New_List (Make_Integer_Literal (Loc, 1))));
4223
4224      for J in 1 .. Dims loop
4225         Sum :=
4226           Make_Op_Add (Loc,
4227             Left_Opnd  => Sum,
4228             Right_Opnd =>
4229               Make_Attribute_Reference (Loc,
4230                 Attribute_Name => Name_Length,
4231                 Prefix         =>
4232                  New_Occurrence_Of (Temps (J), Loc),
4233                Expressions     => New_List (Make_Integer_Literal (Loc, 1))));
4234      end loop;
4235
4236      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
4237
4238      Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
4239
4240      Append_To (Stats,
4241        Make_Assignment_Statement (Loc,
4242          Name       =>
4243            Make_Indexed_Component (Loc,
4244              Prefix      => New_Occurrence_Of (Res, Loc),
4245              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4246          Expression =>
4247            Make_Character_Literal (Loc,
4248              Chars              => Name_Find,
4249              Char_Literal_Value => UI_From_Int (Character'Pos ('(')))));
4250
4251      Append_To (Stats,
4252        Make_Assignment_Statement (Loc,
4253          Name       => New_Occurrence_Of (Pos, Loc),
4254          Expression =>
4255            Make_Op_Add (Loc,
4256              Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4257              Right_Opnd => Make_Integer_Literal (Loc, 1))));
4258
4259      for J in 1 .. Dims loop
4260
4261         Append_To (Stats,
4262           Make_Assignment_Statement (Loc,
4263             Name =>
4264               Make_Slice (Loc,
4265                 Prefix          => New_Occurrence_Of (Res, Loc),
4266                 Discrete_Range  =>
4267                   Make_Range (Loc,
4268                     Low_Bound  => New_Occurrence_Of  (Pos, Loc),
4269                     High_Bound =>
4270                       Make_Op_Subtract (Loc,
4271                         Left_Opnd  =>
4272                           Make_Op_Add (Loc,
4273                             Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4274                             Right_Opnd =>
4275                               Make_Attribute_Reference (Loc,
4276                                 Attribute_Name => Name_Length,
4277                                 Prefix         =>
4278                                   New_Occurrence_Of (Temps (J), Loc),
4279                                 Expressions    =>
4280                                   New_List (Make_Integer_Literal (Loc, 1)))),
4281                         Right_Opnd => Make_Integer_Literal (Loc, 1)))),
4282
4283              Expression => New_Occurrence_Of (Temps (J), Loc)));
4284
4285         if J < Dims then
4286            Append_To (Stats,
4287               Make_Assignment_Statement (Loc,
4288                  Name       => New_Occurrence_Of (Pos, Loc),
4289                  Expression =>
4290                    Make_Op_Add (Loc,
4291                      Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4292                      Right_Opnd =>
4293                        Make_Attribute_Reference (Loc,
4294                          Attribute_Name => Name_Length,
4295                          Prefix         => New_Occurrence_Of (Temps (J), Loc),
4296                          Expressions    =>
4297                            New_List (Make_Integer_Literal (Loc, 1))))));
4298
4299            Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
4300
4301            Append_To (Stats,
4302              Make_Assignment_Statement (Loc,
4303                Name => Make_Indexed_Component (Loc,
4304                   Prefix => New_Occurrence_Of (Res, Loc),
4305                   Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4306                Expression =>
4307                  Make_Character_Literal (Loc,
4308                    Chars              => Name_Find,
4309                    Char_Literal_Value => UI_From_Int (Character'Pos (',')))));
4310
4311            Append_To (Stats,
4312              Make_Assignment_Statement (Loc,
4313                Name         => New_Occurrence_Of (Pos, Loc),
4314                  Expression =>
4315                    Make_Op_Add (Loc,
4316                      Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4317                      Right_Opnd => Make_Integer_Literal (Loc, 1))));
4318         end if;
4319      end loop;
4320
4321      Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
4322
4323      Append_To (Stats,
4324        Make_Assignment_Statement (Loc,
4325          Name        =>
4326            Make_Indexed_Component (Loc,
4327              Prefix      => New_Occurrence_Of (Res, Loc),
4328              Expressions => New_List (New_Occurrence_Of (Len, Loc))),
4329           Expression =>
4330             Make_Character_Literal (Loc,
4331               Chars              => Name_Find,
4332               Char_Literal_Value => UI_From_Int (Character'Pos (')')))));
4333      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4334   end Build_Task_Array_Image;
4335
4336   ----------------------------
4337   -- Build_Task_Image_Decls --
4338   ----------------------------
4339
4340   function Build_Task_Image_Decls
4341     (Loc          : Source_Ptr;
4342      Id_Ref       : Node_Id;
4343      A_Type       : Entity_Id;
4344      In_Init_Proc : Boolean := False) return List_Id
4345   is
4346      Decls  : constant List_Id   := New_List;
4347      T_Id   : Entity_Id := Empty;
4348      Decl   : Node_Id;
4349      Expr   : Node_Id   := Empty;
4350      Fun    : Node_Id   := Empty;
4351      Is_Dyn : constant Boolean :=
4352                 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
4353                   and then
4354                 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
4355
4356   begin
4357      --  If Discard_Names or No_Implicit_Heap_Allocations are in effect,
4358      --  generate a dummy declaration only.
4359
4360      if Restriction_Active (No_Implicit_Heap_Allocations)
4361        or else Global_Discard_Names
4362      then
4363         T_Id := Make_Temporary (Loc, 'J');
4364         Name_Len := 0;
4365
4366         return
4367           New_List (
4368             Make_Object_Declaration (Loc,
4369               Defining_Identifier => T_Id,
4370               Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4371               Expression =>
4372                 Make_String_Literal (Loc,
4373                   Strval => String_From_Name_Buffer)));
4374
4375      else
4376         if Nkind (Id_Ref) = N_Identifier
4377           or else Nkind (Id_Ref) = N_Defining_Identifier
4378         then
4379            --  For a simple variable, the image of the task is built from
4380            --  the name of the variable. To avoid possible conflict with the
4381            --  anonymous type created for a single protected object, add a
4382            --  numeric suffix.
4383
4384            T_Id :=
4385              Make_Defining_Identifier (Loc,
4386                New_External_Name (Chars (Id_Ref), 'T', 1));
4387
4388            Get_Name_String (Chars (Id_Ref));
4389
4390            Expr :=
4391              Make_String_Literal (Loc,
4392                Strval => String_From_Name_Buffer);
4393
4394         elsif Nkind (Id_Ref) = N_Selected_Component then
4395            T_Id :=
4396              Make_Defining_Identifier (Loc,
4397                New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
4398            Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
4399
4400         elsif Nkind (Id_Ref) = N_Indexed_Component then
4401            T_Id :=
4402              Make_Defining_Identifier (Loc,
4403                New_External_Name (Chars (A_Type), 'N'));
4404
4405            Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
4406         end if;
4407      end if;
4408
4409      if Present (Fun) then
4410         Append (Fun, Decls);
4411         Expr := Make_Function_Call (Loc,
4412           Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
4413
4414         if not In_Init_Proc then
4415            Set_Uses_Sec_Stack (Defining_Entity (Fun));
4416         end if;
4417      end if;
4418
4419      Decl := Make_Object_Declaration (Loc,
4420        Defining_Identifier => T_Id,
4421        Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
4422        Constant_Present    => True,
4423        Expression          => Expr);
4424
4425      Append (Decl, Decls);
4426      return Decls;
4427   end Build_Task_Image_Decls;
4428
4429   -------------------------------
4430   -- Build_Task_Image_Function --
4431   -------------------------------
4432
4433   function Build_Task_Image_Function
4434     (Loc   : Source_Ptr;
4435      Decls : List_Id;
4436      Stats : List_Id;
4437      Res   : Entity_Id) return Node_Id
4438   is
4439      Spec : Node_Id;
4440
4441   begin
4442      Append_To (Stats,
4443        Make_Simple_Return_Statement (Loc,
4444          Expression => New_Occurrence_Of (Res, Loc)));
4445
4446      Spec := Make_Function_Specification (Loc,
4447        Defining_Unit_Name => Make_Temporary (Loc, 'F'),
4448        Result_Definition  => New_Occurrence_Of (Standard_String, Loc));
4449
4450      --  Calls to 'Image use the secondary stack, which must be cleaned up
4451      --  after the task name is built.
4452
4453      return Make_Subprogram_Body (Loc,
4454         Specification => Spec,
4455         Declarations => Decls,
4456         Handled_Statement_Sequence =>
4457           Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
4458   end Build_Task_Image_Function;
4459
4460   -----------------------------
4461   -- Build_Task_Image_Prefix --
4462   -----------------------------
4463
4464   procedure Build_Task_Image_Prefix
4465      (Loc    : Source_Ptr;
4466       Len    : out Entity_Id;
4467       Res    : out Entity_Id;
4468       Pos    : out Entity_Id;
4469       Prefix : Entity_Id;
4470       Sum    : Node_Id;
4471       Decls  : List_Id;
4472       Stats  : List_Id)
4473   is
4474   begin
4475      Len := Make_Temporary (Loc, 'L', Sum);
4476
4477      Append_To (Decls,
4478        Make_Object_Declaration (Loc,
4479          Defining_Identifier => Len,
4480          Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc),
4481          Expression          => Sum));
4482
4483      Res := Make_Temporary (Loc, 'R');
4484
4485      Append_To (Decls,
4486         Make_Object_Declaration (Loc,
4487            Defining_Identifier => Res,
4488            Object_Definition =>
4489               Make_Subtype_Indication (Loc,
4490                  Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4491               Constraint =>
4492                 Make_Index_Or_Discriminant_Constraint (Loc,
4493                   Constraints =>
4494                     New_List (
4495                       Make_Range (Loc,
4496                         Low_Bound => Make_Integer_Literal (Loc, 1),
4497                         High_Bound => New_Occurrence_Of (Len, Loc)))))));
4498
4499      --  Indicate that the result is an internal temporary, so it does not
4500      --  receive a bogus initialization when declaration is expanded. This
4501      --  is both efficient, and prevents anomalies in the handling of
4502      --  dynamic objects on the secondary stack.
4503
4504      Set_Is_Internal (Res);
4505      Pos := Make_Temporary (Loc, 'P');
4506
4507      Append_To (Decls,
4508         Make_Object_Declaration (Loc,
4509            Defining_Identifier => Pos,
4510            Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc)));
4511
4512      --  Pos := Prefix'Length;
4513
4514      Append_To (Stats,
4515         Make_Assignment_Statement (Loc,
4516            Name => New_Occurrence_Of (Pos, Loc),
4517            Expression =>
4518              Make_Attribute_Reference (Loc,
4519                Attribute_Name => Name_Length,
4520                Prefix         => New_Occurrence_Of (Prefix, Loc),
4521                Expressions    => New_List (Make_Integer_Literal (Loc, 1)))));
4522
4523      --  Res (1 .. Pos) := Prefix;
4524
4525      Append_To (Stats,
4526        Make_Assignment_Statement (Loc,
4527          Name =>
4528            Make_Slice (Loc,
4529              Prefix          => New_Occurrence_Of (Res, Loc),
4530              Discrete_Range  =>
4531                Make_Range (Loc,
4532                   Low_Bound  => Make_Integer_Literal (Loc, 1),
4533                   High_Bound => New_Occurrence_Of (Pos, Loc))),
4534
4535          Expression => New_Occurrence_Of (Prefix, Loc)));
4536
4537      Append_To (Stats,
4538         Make_Assignment_Statement (Loc,
4539            Name       => New_Occurrence_Of (Pos, Loc),
4540            Expression =>
4541              Make_Op_Add (Loc,
4542                Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4543                Right_Opnd => Make_Integer_Literal (Loc, 1))));
4544   end Build_Task_Image_Prefix;
4545
4546   -----------------------------
4547   -- Build_Task_Record_Image --
4548   -----------------------------
4549
4550   function Build_Task_Record_Image
4551     (Loc    : Source_Ptr;
4552      Id_Ref : Node_Id;
4553      Dyn    : Boolean := False) return Node_Id
4554   is
4555      Len : Entity_Id;
4556      --  Total length of generated name
4557
4558      Pos : Entity_Id;
4559      --  Index into result
4560
4561      Res : Entity_Id;
4562      --  String to hold result
4563
4564      Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
4565      --  Name of enclosing variable, prefix of resulting name
4566
4567      Sum : Node_Id;
4568      --  Expression to compute total size of string
4569
4570      Sel : Entity_Id;
4571      --  Entity for selector name
4572
4573      Decls : constant List_Id := New_List;
4574      Stats : constant List_Id := New_List;
4575
4576   begin
4577      --  For a dynamic task, the name comes from the target variable. For a
4578      --  static one it is a formal of the enclosing init proc.
4579
4580      if Dyn then
4581         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
4582         Append_To (Decls,
4583           Make_Object_Declaration (Loc,
4584             Defining_Identifier => Pref,
4585             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4586             Expression =>
4587               Make_String_Literal (Loc,
4588                 Strval => String_From_Name_Buffer)));
4589
4590      else
4591         Append_To (Decls,
4592           Make_Object_Renaming_Declaration (Loc,
4593             Defining_Identifier => Pref,
4594             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
4595             Name                => Make_Identifier (Loc, Name_uTask_Name)));
4596      end if;
4597
4598      Sel := Make_Temporary (Loc, 'S');
4599
4600      Get_Name_String (Chars (Selector_Name (Id_Ref)));
4601
4602      Append_To (Decls,
4603         Make_Object_Declaration (Loc,
4604           Defining_Identifier => Sel,
4605           Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
4606           Expression          =>
4607             Make_String_Literal (Loc,
4608               Strval => String_From_Name_Buffer)));
4609
4610      Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
4611
4612      Sum :=
4613        Make_Op_Add (Loc,
4614          Left_Opnd => Sum,
4615          Right_Opnd =>
4616           Make_Attribute_Reference (Loc,
4617             Attribute_Name => Name_Length,
4618             Prefix =>
4619               New_Occurrence_Of (Pref, Loc),
4620             Expressions => New_List (Make_Integer_Literal (Loc, 1))));
4621
4622      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
4623
4624      Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
4625
4626      --  Res (Pos) := '.';
4627
4628      Append_To (Stats,
4629         Make_Assignment_Statement (Loc,
4630           Name => Make_Indexed_Component (Loc,
4631              Prefix => New_Occurrence_Of (Res, Loc),
4632              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4633           Expression =>
4634             Make_Character_Literal (Loc,
4635               Chars => Name_Find,
4636               Char_Literal_Value =>
4637                 UI_From_Int (Character'Pos ('.')))));
4638
4639      Append_To (Stats,
4640        Make_Assignment_Statement (Loc,
4641          Name => New_Occurrence_Of (Pos, Loc),
4642          Expression =>
4643            Make_Op_Add (Loc,
4644              Left_Opnd => New_Occurrence_Of (Pos, Loc),
4645              Right_Opnd => Make_Integer_Literal (Loc, 1))));
4646
4647      --  Res (Pos .. Len) := Selector;
4648
4649      Append_To (Stats,
4650        Make_Assignment_Statement (Loc,
4651          Name => Make_Slice (Loc,
4652             Prefix => New_Occurrence_Of (Res, Loc),
4653             Discrete_Range  =>
4654               Make_Range (Loc,
4655                 Low_Bound  => New_Occurrence_Of (Pos, Loc),
4656                 High_Bound => New_Occurrence_Of (Len, Loc))),
4657          Expression => New_Occurrence_Of (Sel, Loc)));
4658
4659      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4660   end Build_Task_Record_Image;
4661
4662   ---------------------------------------
4663   -- Build_Transient_Object_Statements --
4664   ---------------------------------------
4665
4666   procedure Build_Transient_Object_Statements
4667     (Obj_Decl     : Node_Id;
4668      Fin_Call     : out Node_Id;
4669      Hook_Assign  : out Node_Id;
4670      Hook_Clear   : out Node_Id;
4671      Hook_Decl    : out Node_Id;
4672      Ptr_Decl     : out Node_Id;
4673      Finalize_Obj : Boolean := True)
4674   is
4675      Loc     : constant Source_Ptr := Sloc (Obj_Decl);
4676      Obj_Id  : constant Entity_Id  := Defining_Entity (Obj_Decl);
4677      Obj_Typ : constant Entity_Id  := Base_Type (Etype (Obj_Id));
4678
4679      Desig_Typ : Entity_Id;
4680      Hook_Expr : Node_Id;
4681      Hook_Id   : Entity_Id;
4682      Obj_Ref   : Node_Id;
4683      Ptr_Typ   : Entity_Id;
4684
4685   begin
4686      --  Recover the type of the object
4687
4688      Desig_Typ := Obj_Typ;
4689
4690      if Is_Access_Type (Desig_Typ) then
4691         Desig_Typ := Available_View (Designated_Type (Desig_Typ));
4692      end if;
4693
4694      --  Create an access type which provides a reference to the transient
4695      --  object. Generate:
4696
4697      --    type Ptr_Typ is access all Desig_Typ;
4698
4699      Ptr_Typ := Make_Temporary (Loc, 'A');
4700      Set_Ekind (Ptr_Typ, E_General_Access_Type);
4701      Set_Directly_Designated_Type (Ptr_Typ, Desig_Typ);
4702
4703      Ptr_Decl :=
4704        Make_Full_Type_Declaration (Loc,
4705          Defining_Identifier => Ptr_Typ,
4706          Type_Definition     =>
4707            Make_Access_To_Object_Definition (Loc,
4708              All_Present        => True,
4709              Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc)));
4710
4711      --  Create a temporary check which acts as a hook to the transient
4712      --  object. Generate:
4713
4714      --    Hook : Ptr_Typ := null;
4715
4716      Hook_Id := Make_Temporary (Loc, 'T');
4717      Set_Ekind (Hook_Id, E_Variable);
4718      Set_Etype (Hook_Id, Ptr_Typ);
4719
4720      Hook_Decl :=
4721        Make_Object_Declaration (Loc,
4722          Defining_Identifier => Hook_Id,
4723          Object_Definition   => New_Occurrence_Of (Ptr_Typ, Loc),
4724          Expression          => Make_Null (Loc));
4725
4726      --  Mark the temporary as a hook. This signals the machinery in
4727      --  Build_Finalizer to recognize this special case.
4728
4729      Set_Status_Flag_Or_Transient_Decl (Hook_Id, Obj_Decl);
4730
4731      --  Hook the transient object to the temporary. Generate:
4732
4733      --    Hook := Ptr_Typ (Obj_Id);
4734      --      <or>
4735      --    Hool := Obj_Id'Unrestricted_Access;
4736
4737      if Is_Access_Type (Obj_Typ) then
4738         Hook_Expr :=
4739           Unchecked_Convert_To (Ptr_Typ, New_Occurrence_Of (Obj_Id, Loc));
4740      else
4741         Hook_Expr :=
4742           Make_Attribute_Reference (Loc,
4743             Prefix         => New_Occurrence_Of (Obj_Id, Loc),
4744             Attribute_Name => Name_Unrestricted_Access);
4745      end if;
4746
4747      Hook_Assign :=
4748        Make_Assignment_Statement (Loc,
4749          Name       => New_Occurrence_Of (Hook_Id, Loc),
4750          Expression => Hook_Expr);
4751
4752      --  Crear the hook prior to finalizing the object. Generate:
4753
4754      --    Hook := null;
4755
4756      Hook_Clear :=
4757        Make_Assignment_Statement (Loc,
4758          Name       => New_Occurrence_Of (Hook_Id, Loc),
4759          Expression => Make_Null (Loc));
4760
4761      --  Finalize the object. Generate:
4762
4763      --    [Deep_]Finalize (Obj_Ref[.all]);
4764
4765      if Finalize_Obj then
4766         Obj_Ref := New_Occurrence_Of (Obj_Id, Loc);
4767
4768         if Is_Access_Type (Obj_Typ) then
4769            Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref);
4770            Set_Etype (Obj_Ref, Desig_Typ);
4771         end if;
4772
4773         Fin_Call :=
4774           Make_Final_Call
4775             (Obj_Ref => Obj_Ref,
4776              Typ     => Desig_Typ);
4777
4778      --  Otherwise finalize the hook. Generate:
4779
4780      --    [Deep_]Finalize (Hook.all);
4781
4782      else
4783         Fin_Call :=
4784           Make_Final_Call (
4785             Obj_Ref =>
4786               Make_Explicit_Dereference (Loc,
4787                 Prefix => New_Occurrence_Of (Hook_Id, Loc)),
4788             Typ     => Desig_Typ);
4789      end if;
4790   end Build_Transient_Object_Statements;
4791
4792   -----------------------------
4793   -- Check_Float_Op_Overflow --
4794   -----------------------------
4795
4796   procedure Check_Float_Op_Overflow (N : Node_Id) is
4797   begin
4798      --  Return if no check needed
4799
4800      if not Is_Floating_Point_Type (Etype (N))
4801        or else not (Do_Overflow_Check (N) and then Check_Float_Overflow)
4802
4803        --  In CodePeer_Mode, rely on the overflow check flag being set instead
4804        --  and do not expand the code for float overflow checking.
4805
4806        or else CodePeer_Mode
4807      then
4808         return;
4809      end if;
4810
4811      --  Otherwise we replace the expression by
4812
4813      --  do Tnn : constant ftype := expression;
4814      --     constraint_error when not Tnn'Valid;
4815      --  in Tnn;
4816
4817      declare
4818         Loc : constant Source_Ptr := Sloc (N);
4819         Tnn : constant Entity_Id  := Make_Temporary (Loc, 'T', N);
4820         Typ : constant Entity_Id  := Etype (N);
4821
4822      begin
4823         --  Turn off the Do_Overflow_Check flag, since we are doing that work
4824         --  right here. We also set the node as analyzed to prevent infinite
4825         --  recursion from repeating the operation in the expansion.
4826
4827         Set_Do_Overflow_Check (N, False);
4828         Set_Analyzed (N, True);
4829
4830         --  Do the rewrite to include the check
4831
4832         Rewrite (N,
4833           Make_Expression_With_Actions (Loc,
4834             Actions    => New_List (
4835               Make_Object_Declaration (Loc,
4836                 Defining_Identifier => Tnn,
4837                 Object_Definition   => New_Occurrence_Of (Typ, Loc),
4838                 Constant_Present    => True,
4839                 Expression          => Relocate_Node (N)),
4840               Make_Raise_Constraint_Error (Loc,
4841                 Condition =>
4842                   Make_Op_Not (Loc,
4843                     Right_Opnd =>
4844                       Make_Attribute_Reference (Loc,
4845                         Prefix         => New_Occurrence_Of (Tnn, Loc),
4846                         Attribute_Name => Name_Valid)),
4847                 Reason    => CE_Overflow_Check_Failed)),
4848             Expression => New_Occurrence_Of (Tnn, Loc)));
4849
4850         Analyze_And_Resolve (N, Typ);
4851      end;
4852   end Check_Float_Op_Overflow;
4853
4854   ----------------------------------
4855   -- Component_May_Be_Bit_Aligned --
4856   ----------------------------------
4857
4858   function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
4859      UT : Entity_Id;
4860
4861   begin
4862      --  If no component clause, then everything is fine, since the back end
4863      --  never misaligns from byte boundaries by default, even if there is a
4864      --  pragma Pack for the record.
4865
4866      if No (Comp) or else No (Component_Clause (Comp)) then
4867         return False;
4868      end if;
4869
4870      UT := Underlying_Type (Etype (Comp));
4871
4872      --  It is only array and record types that cause trouble
4873
4874      if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then
4875         return False;
4876
4877      --  If we know that we have a small (at most the maximum integer size)
4878      --  record or bit-packed array, then everything is fine, since the back
4879      --  end can handle these cases correctly.
4880
4881      elsif Esize (Comp) <= System_Max_Integer_Size
4882        and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
4883      then
4884         return False;
4885
4886      --  Otherwise if the component is not byte aligned, we know we have the
4887      --  nasty unaligned case.
4888
4889      elsif Normalized_First_Bit (Comp) /= Uint_0
4890        or else Esize (Comp) mod System_Storage_Unit /= Uint_0
4891      then
4892         return True;
4893
4894      --  If we are large and byte aligned, then OK at this level
4895
4896      else
4897         return False;
4898      end if;
4899   end Component_May_Be_Bit_Aligned;
4900
4901   -------------------------------
4902   -- Convert_To_Actual_Subtype --
4903   -------------------------------
4904
4905   procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
4906      Act_ST : Entity_Id;
4907
4908   begin
4909      Act_ST := Get_Actual_Subtype (Exp);
4910
4911      if Act_ST = Etype (Exp) then
4912         return;
4913      else
4914         Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
4915         Analyze_And_Resolve (Exp, Act_ST);
4916      end if;
4917   end Convert_To_Actual_Subtype;
4918
4919   -----------------------------------
4920   -- Corresponding_Runtime_Package --
4921   -----------------------------------
4922
4923   function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
4924      function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean;
4925      --  Return True if protected type T has one entry and the maximum queue
4926      --  length is one.
4927
4928      --------------------------------
4929      -- Has_One_Entry_And_No_Queue --
4930      --------------------------------
4931
4932      function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean is
4933         Item     : Entity_Id;
4934         Is_First : Boolean := True;
4935
4936      begin
4937         Item := First_Entity (T);
4938         while Present (Item) loop
4939            if Is_Entry (Item) then
4940
4941               --  The protected type has more than one entry
4942
4943               if not Is_First then
4944                  return False;
4945               end if;
4946
4947               --  The queue length is not one
4948
4949               if not Restriction_Active (No_Entry_Queue)
4950                 and then Get_Max_Queue_Length (Item) /= Uint_1
4951               then
4952                  return False;
4953               end if;
4954
4955               Is_First := False;
4956            end if;
4957
4958            Next_Entity (Item);
4959         end loop;
4960
4961         return True;
4962      end Has_One_Entry_And_No_Queue;
4963
4964      --  Local variables
4965
4966      Pkg_Id : RTU_Id := RTU_Null;
4967
4968   --  Start of processing for Corresponding_Runtime_Package
4969
4970   begin
4971      pragma Assert (Is_Concurrent_Type (Typ));
4972
4973      if Is_Protected_Type (Typ) then
4974         if Has_Entries (Typ)
4975
4976            --  A protected type without entries that covers an interface and
4977            --  overrides the abstract routines with protected procedures is
4978            --  considered equivalent to a protected type with entries in the
4979            --  context of dispatching select statements. It is sufficient to
4980            --  check for the presence of an interface list in the declaration
4981            --  node to recognize this case.
4982
4983           or else Present (Interface_List (Parent (Typ)))
4984
4985            --  Protected types with interrupt handlers (when not using a
4986            --  restricted profile) are also considered equivalent to
4987            --  protected types with entries. The types which are used
4988            --  (Static_Interrupt_Protection and Dynamic_Interrupt_Protection)
4989            --  are derived from Protection_Entries.
4990
4991           or else (Has_Attach_Handler (Typ) and then not Restricted_Profile)
4992           or else Has_Interrupt_Handler (Typ)
4993         then
4994            if Abort_Allowed
4995              or else Restriction_Active (No_Select_Statements) = False
4996              or else not Has_One_Entry_And_No_Queue (Typ)
4997              or else (Has_Attach_Handler (Typ)
4998                        and then not Restricted_Profile)
4999            then
5000               Pkg_Id := System_Tasking_Protected_Objects_Entries;
5001            else
5002               Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
5003            end if;
5004
5005         else
5006            Pkg_Id := System_Tasking_Protected_Objects;
5007         end if;
5008      end if;
5009
5010      return Pkg_Id;
5011   end Corresponding_Runtime_Package;
5012
5013   -----------------------------------
5014   -- Current_Sem_Unit_Declarations --
5015   -----------------------------------
5016
5017   function Current_Sem_Unit_Declarations return List_Id is
5018      U     : Node_Id := Unit (Cunit (Current_Sem_Unit));
5019      Decls : List_Id;
5020
5021   begin
5022      --  If the current unit is a package body, locate the visible
5023      --  declarations of the package spec.
5024
5025      if Nkind (U) = N_Package_Body then
5026         U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
5027      end if;
5028
5029      if Nkind (U) = N_Package_Declaration then
5030         U := Specification (U);
5031         Decls := Visible_Declarations (U);
5032
5033         if No (Decls) then
5034            Decls := New_List;
5035            Set_Visible_Declarations (U, Decls);
5036         end if;
5037
5038      else
5039         Decls := Declarations (U);
5040
5041         if No (Decls) then
5042            Decls := New_List;
5043            Set_Declarations (U, Decls);
5044         end if;
5045      end if;
5046
5047      return Decls;
5048   end Current_Sem_Unit_Declarations;
5049
5050   -----------------------
5051   -- Duplicate_Subexpr --
5052   -----------------------
5053
5054   function Duplicate_Subexpr
5055     (Exp          : Node_Id;
5056      Name_Req     : Boolean := False;
5057      Renaming_Req : Boolean := False) return Node_Id
5058   is
5059   begin
5060      Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
5061      return New_Copy_Tree (Exp);
5062   end Duplicate_Subexpr;
5063
5064   ---------------------------------
5065   -- Duplicate_Subexpr_No_Checks --
5066   ---------------------------------
5067
5068   function Duplicate_Subexpr_No_Checks
5069     (Exp           : Node_Id;
5070      Name_Req      : Boolean   := False;
5071      Renaming_Req  : Boolean   := False;
5072      Related_Id    : Entity_Id := Empty;
5073      Is_Low_Bound  : Boolean   := False;
5074      Is_High_Bound : Boolean   := False) return Node_Id
5075   is
5076      New_Exp : Node_Id;
5077
5078   begin
5079      Remove_Side_Effects
5080        (Exp           => Exp,
5081         Name_Req      => Name_Req,
5082         Renaming_Req  => Renaming_Req,
5083         Related_Id    => Related_Id,
5084         Is_Low_Bound  => Is_Low_Bound,
5085         Is_High_Bound => Is_High_Bound);
5086
5087      New_Exp := New_Copy_Tree (Exp);
5088      Remove_Checks (New_Exp);
5089      return New_Exp;
5090   end Duplicate_Subexpr_No_Checks;
5091
5092   -----------------------------------
5093   -- Duplicate_Subexpr_Move_Checks --
5094   -----------------------------------
5095
5096   function Duplicate_Subexpr_Move_Checks
5097     (Exp          : Node_Id;
5098      Name_Req     : Boolean := False;
5099      Renaming_Req : Boolean := False) return Node_Id
5100   is
5101      New_Exp : Node_Id;
5102
5103   begin
5104      Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
5105      New_Exp := New_Copy_Tree (Exp);
5106      Remove_Checks (Exp);
5107      return New_Exp;
5108   end Duplicate_Subexpr_Move_Checks;
5109
5110   -------------------------
5111   -- Enclosing_Init_Proc --
5112   -------------------------
5113
5114   function Enclosing_Init_Proc return Entity_Id is
5115      S : Entity_Id;
5116
5117   begin
5118      S := Current_Scope;
5119      while Present (S) and then S /= Standard_Standard loop
5120         if Is_Init_Proc (S) then
5121            return S;
5122         else
5123            S := Scope (S);
5124         end if;
5125      end loop;
5126
5127      return Empty;
5128   end Enclosing_Init_Proc;
5129
5130   --------------------
5131   -- Ensure_Defined --
5132   --------------------
5133
5134   procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
5135      IR : Node_Id;
5136
5137   begin
5138      --  An itype reference must only be created if this is a local itype, so
5139      --  that gigi can elaborate it on the proper objstack.
5140
5141      if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then
5142         IR := Make_Itype_Reference (Sloc (N));
5143         Set_Itype (IR, Typ);
5144         Insert_Action (N, IR);
5145      end if;
5146   end Ensure_Defined;
5147
5148   --------------------
5149   -- Entry_Names_OK --
5150   --------------------
5151
5152   function Entry_Names_OK return Boolean is
5153   begin
5154      return
5155        not Restricted_Profile
5156          and then not Global_Discard_Names
5157          and then not Restriction_Active (No_Implicit_Heap_Allocations)
5158          and then not Restriction_Active (No_Local_Allocators);
5159   end Entry_Names_OK;
5160
5161   -------------------
5162   -- Evaluate_Name --
5163   -------------------
5164
5165   procedure Evaluate_Name (Nam : Node_Id) is
5166   begin
5167      case Nkind (Nam) is
5168         --  For an aggregate, force its evaluation
5169
5170         when N_Aggregate =>
5171            Force_Evaluation (Nam);
5172
5173         --  For an attribute reference or an indexed component, evaluate the
5174         --  prefix, which is itself a name, recursively, and then force the
5175         --  evaluation of all the subscripts (or attribute expressions).
5176
5177         when N_Attribute_Reference
5178            | N_Indexed_Component
5179         =>
5180            Evaluate_Name (Prefix (Nam));
5181
5182            declare
5183               E : Node_Id;
5184
5185            begin
5186               E := First (Expressions (Nam));
5187               while Present (E) loop
5188                  Force_Evaluation (E);
5189
5190                  if Is_Rewrite_Substitution (E) then
5191                     Set_Do_Range_Check
5192                       (E, Do_Range_Check (Original_Node (E)));
5193                  end if;
5194
5195                  Next (E);
5196               end loop;
5197            end;
5198
5199         --  For an explicit dereference, we simply force the evaluation of
5200         --  the name expression. The dereference provides a value that is the
5201         --  address for the renamed object, and it is precisely this value
5202         --  that we want to preserve.
5203
5204         when N_Explicit_Dereference =>
5205            Force_Evaluation (Prefix (Nam));
5206
5207         --  For a function call, we evaluate the call; same for an operator
5208
5209         when N_Function_Call
5210            | N_Op
5211         =>
5212            Force_Evaluation (Nam);
5213
5214         --  For a qualified expression, we evaluate the expression
5215
5216         when N_Qualified_Expression =>
5217            Evaluate_Name (Expression (Nam));
5218
5219         --  For a selected component, we simply evaluate the prefix
5220
5221         when N_Selected_Component =>
5222            Evaluate_Name (Prefix (Nam));
5223
5224         --  For a slice, we evaluate the prefix, as for the indexed component
5225         --  case and then, if there is a range present, either directly or as
5226         --  the constraint of a discrete subtype indication, we evaluate the
5227         --  two bounds of this range.
5228
5229         when N_Slice =>
5230            Evaluate_Name (Prefix (Nam));
5231            Evaluate_Slice_Bounds (Nam);
5232
5233         --  For a type conversion, the expression of the conversion must be
5234         --  the name of an object, and we simply need to evaluate this name.
5235
5236         when N_Type_Conversion =>
5237            Evaluate_Name (Expression (Nam));
5238
5239         --  The remaining cases are direct name and character literal. In all
5240         --  these cases, we do nothing, since we want to reevaluate each time
5241         --  the renamed object is used. ??? There are more remaining cases, at
5242         --  least in the GNATprove_Mode, where this routine is called in more
5243         --  contexts than in GNAT.
5244
5245         when others =>
5246            null;
5247      end case;
5248   end Evaluate_Name;
5249
5250   ---------------------------
5251   -- Evaluate_Slice_Bounds --
5252   ---------------------------
5253
5254   procedure Evaluate_Slice_Bounds (Slice : Node_Id) is
5255      DR     : constant Node_Id := Discrete_Range (Slice);
5256      Constr : Node_Id;
5257      Rexpr  : Node_Id;
5258
5259   begin
5260      if Nkind (DR) = N_Range then
5261         Force_Evaluation (Low_Bound (DR));
5262         Force_Evaluation (High_Bound (DR));
5263
5264      elsif Nkind (DR) = N_Subtype_Indication then
5265         Constr := Constraint (DR);
5266
5267         if Nkind (Constr) = N_Range_Constraint then
5268            Rexpr := Range_Expression (Constr);
5269
5270            Force_Evaluation (Low_Bound (Rexpr));
5271            Force_Evaluation (High_Bound (Rexpr));
5272         end if;
5273      end if;
5274   end Evaluate_Slice_Bounds;
5275
5276   ---------------------
5277   -- Evolve_And_Then --
5278   ---------------------
5279
5280   procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
5281   begin
5282      if No (Cond) then
5283         Cond := Cond1;
5284      else
5285         Cond :=
5286           Make_And_Then (Sloc (Cond1),
5287             Left_Opnd  => Cond,
5288             Right_Opnd => Cond1);
5289      end if;
5290   end Evolve_And_Then;
5291
5292   --------------------
5293   -- Evolve_Or_Else --
5294   --------------------
5295
5296   procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
5297   begin
5298      if No (Cond) then
5299         Cond := Cond1;
5300      else
5301         Cond :=
5302           Make_Or_Else (Sloc (Cond1),
5303             Left_Opnd  => Cond,
5304             Right_Opnd => Cond1);
5305      end if;
5306   end Evolve_Or_Else;
5307
5308   -----------------------------------------
5309   -- Expand_Static_Predicates_In_Choices --
5310   -----------------------------------------
5311
5312   procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is
5313      pragma Assert (Nkind (N) in N_Case_Statement_Alternative | N_Variant);
5314
5315      Choices : constant List_Id := Discrete_Choices (N);
5316
5317      Choice : Node_Id;
5318      Next_C : Node_Id;
5319      P      : Node_Id;
5320      C      : Node_Id;
5321
5322   begin
5323      Choice := First (Choices);
5324      while Present (Choice) loop
5325         Next_C := Next (Choice);
5326
5327         --  Check for name of subtype with static predicate
5328
5329         if Is_Entity_Name (Choice)
5330           and then Is_Type (Entity (Choice))
5331           and then Has_Predicates (Entity (Choice))
5332         then
5333            --  Loop through entries in predicate list, converting to choices
5334            --  and inserting in the list before the current choice. Note that
5335            --  if the list is empty, corresponding to a False predicate, then
5336            --  no choices are inserted.
5337
5338            P := First (Static_Discrete_Predicate (Entity (Choice)));
5339            while Present (P) loop
5340
5341               --  If low bound and high bounds are equal, copy simple choice
5342
5343               if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then
5344                  C := New_Copy (Low_Bound (P));
5345
5346               --  Otherwise copy a range
5347
5348               else
5349                  C := New_Copy (P);
5350               end if;
5351
5352               --  Change Sloc to referencing choice (rather than the Sloc of
5353               --  the predicate declaration element itself).
5354
5355               Set_Sloc (C, Sloc (Choice));
5356               Insert_Before (Choice, C);
5357               Next (P);
5358            end loop;
5359
5360            --  Delete the predicated entry
5361
5362            Remove (Choice);
5363         end if;
5364
5365         --  Move to next choice to check
5366
5367         Choice := Next_C;
5368      end loop;
5369
5370      Set_Has_SP_Choice (N, False);
5371   end Expand_Static_Predicates_In_Choices;
5372
5373   ------------------------------
5374   -- Expand_Subtype_From_Expr --
5375   ------------------------------
5376
5377   --  This function is applicable for both static and dynamic allocation of
5378   --  objects which are constrained by an initial expression. Basically it
5379   --  transforms an unconstrained subtype indication into a constrained one.
5380
5381   --  The expression may also be transformed in certain cases in order to
5382   --  avoid multiple evaluation. In the static allocation case, the general
5383   --  scheme is:
5384
5385   --     Val : T := Expr;
5386
5387   --        is transformed into
5388
5389   --     Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr;
5390   --
5391   --  Here are the main cases :
5392   --
5393   --  <if Expr is a Slice>
5394   --    Val : T ([Index_Subtype (Expr)]) := Expr;
5395   --
5396   --  <elsif Expr is a String Literal>
5397   --    Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
5398   --
5399   --  <elsif Expr is Constrained>
5400   --    subtype T is Type_Of_Expr
5401   --    Val : T := Expr;
5402   --
5403   --  <elsif Expr is an entity_name>
5404   --    Val : T (constraints taken from Expr) := Expr;
5405   --
5406   --  <else>
5407   --    type Axxx is access all T;
5408   --    Rval : Axxx := Expr'ref;
5409   --    Val  : T (constraints taken from Rval) := Rval.all;
5410
5411   --    ??? note: when the Expression is allocated in the secondary stack
5412   --              we could use it directly instead of copying it by declaring
5413   --              Val : T (...) renames Rval.all
5414
5415   procedure Expand_Subtype_From_Expr
5416     (N             : Node_Id;
5417      Unc_Type      : Entity_Id;
5418      Subtype_Indic : Node_Id;
5419      Exp           : Node_Id;
5420      Related_Id    : Entity_Id := Empty)
5421   is
5422      Loc     : constant Source_Ptr := Sloc (N);
5423      Exp_Typ : constant Entity_Id  := Etype (Exp);
5424      T       : Entity_Id;
5425
5426   begin
5427      --  In general we cannot build the subtype if expansion is disabled,
5428      --  because internal entities may not have been defined. However, to
5429      --  avoid some cascaded errors, we try to continue when the expression is
5430      --  an array (or string), because it is safe to compute the bounds. It is
5431      --  in fact required to do so even in a generic context, because there
5432      --  may be constants that depend on the bounds of a string literal, both
5433      --  standard string types and more generally arrays of characters.
5434
5435      --  In GNATprove mode, these extra subtypes are not needed, unless Exp is
5436      --  a static expression. In that case, the subtype will be constrained
5437      --  while the original type might be unconstrained, so expanding the type
5438      --  is necessary both for passing legality checks in GNAT and for precise
5439      --  analysis in GNATprove.
5440
5441      if GNATprove_Mode and then not Is_Static_Expression (Exp) then
5442         return;
5443      end if;
5444
5445      if not Expander_Active
5446        and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp)))
5447      then
5448         return;
5449      end if;
5450
5451      if Nkind (Exp) = N_Slice then
5452         declare
5453            Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
5454
5455         begin
5456            Rewrite (Subtype_Indic,
5457              Make_Subtype_Indication (Loc,
5458                Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
5459                Constraint =>
5460                  Make_Index_Or_Discriminant_Constraint (Loc,
5461                    Constraints => New_List
5462                      (New_Occurrence_Of (Slice_Type, Loc)))));
5463
5464            --  This subtype indication may be used later for constraint checks
5465            --  we better make sure that if a variable was used as a bound of
5466            --  the original slice, its value is frozen.
5467
5468            Evaluate_Slice_Bounds (Exp);
5469         end;
5470
5471      elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
5472         Rewrite (Subtype_Indic,
5473           Make_Subtype_Indication (Loc,
5474             Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
5475             Constraint =>
5476               Make_Index_Or_Discriminant_Constraint (Loc,
5477                 Constraints => New_List (
5478                   Make_Literal_Range (Loc,
5479                     Literal_Typ => Exp_Typ)))));
5480
5481      --  If the type of the expression is an internally generated type it
5482      --  may not be necessary to create a new subtype. However there are two
5483      --  exceptions: references to the current instances, and aliased array
5484      --  object declarations for which the back end has to create a template.
5485
5486      elsif Is_Constrained (Exp_Typ)
5487        and then not Is_Class_Wide_Type (Unc_Type)
5488        and then
5489          (Nkind (N) /= N_Object_Declaration
5490            or else not Is_Entity_Name (Expression (N))
5491            or else not Comes_From_Source (Entity (Expression (N)))
5492            or else not Is_Array_Type (Exp_Typ)
5493            or else not Aliased_Present (N))
5494      then
5495         if Is_Itype (Exp_Typ) then
5496
5497            --  Within an initialization procedure, a selected component
5498            --  denotes a component of the enclosing record, and it appears as
5499            --  an actual in a call to its own initialization procedure. If
5500            --  this component depends on the outer discriminant, we must
5501            --  generate the proper actual subtype for it.
5502
5503            if Nkind (Exp) = N_Selected_Component
5504              and then Within_Init_Proc
5505            then
5506               declare
5507                  Decl : constant Node_Id :=
5508                           Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
5509               begin
5510                  if Present (Decl) then
5511                     Insert_Action (N, Decl);
5512                     T := Defining_Identifier (Decl);
5513                  else
5514                     T := Exp_Typ;
5515                  end if;
5516               end;
5517
5518            --  No need to generate a new subtype
5519
5520            else
5521               T := Exp_Typ;
5522            end if;
5523
5524         else
5525            T := Make_Temporary (Loc, 'T');
5526
5527            Insert_Action (N,
5528              Make_Subtype_Declaration (Loc,
5529                Defining_Identifier => T,
5530                Subtype_Indication  => New_Occurrence_Of (Exp_Typ, Loc)));
5531
5532            --  This type is marked as an itype even though it has an explicit
5533            --  declaration since otherwise Is_Generic_Actual_Type can get
5534            --  set, resulting in the generation of spurious errors. (See
5535            --  sem_ch8.Analyze_Package_Renaming and sem_type.covers)
5536
5537            Set_Is_Itype (T);
5538            Set_Associated_Node_For_Itype (T, Exp);
5539         end if;
5540
5541         Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc));
5542
5543      --  Nothing needs to be done for private types with unknown discriminants
5544      --  if the underlying type is not an unconstrained composite type or it
5545      --  is an unchecked union.
5546
5547      elsif Is_Private_Type (Unc_Type)
5548        and then Has_Unknown_Discriminants (Unc_Type)
5549        and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
5550                   or else Is_Constrained (Underlying_Type (Unc_Type))
5551                   or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
5552      then
5553         null;
5554
5555      --  Case of derived type with unknown discriminants where the parent type
5556      --  also has unknown discriminants.
5557
5558      elsif Is_Record_Type (Unc_Type)
5559        and then not Is_Class_Wide_Type (Unc_Type)
5560        and then Has_Unknown_Discriminants (Unc_Type)
5561        and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
5562      then
5563         --  Nothing to be done if no underlying record view available
5564
5565         --  If this is a limited type derived from a type with unknown
5566         --  discriminants, do not expand either, so that subsequent expansion
5567         --  of the call can add build-in-place parameters to call.
5568
5569         if No (Underlying_Record_View (Unc_Type))
5570           or else Is_Limited_Type (Unc_Type)
5571         then
5572            null;
5573
5574         --  Otherwise use the Underlying_Record_View to create the proper
5575         --  constrained subtype for an object of a derived type with unknown
5576         --  discriminants.
5577
5578         else
5579            Remove_Side_Effects (Exp);
5580            Rewrite (Subtype_Indic,
5581              Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
5582         end if;
5583
5584      --  Renamings of class-wide interface types require no equivalent
5585      --  constrained type declarations because we only need to reference
5586      --  the tag component associated with the interface. The same is
5587      --  presumably true for class-wide types in general, so this test
5588      --  is broadened to include all class-wide renamings, which also
5589      --  avoids cases of unbounded recursion in Remove_Side_Effects.
5590      --  (Is this really correct, or are there some cases of class-wide
5591      --  renamings that require action in this procedure???)
5592
5593      elsif Present (N)
5594        and then Nkind (N) = N_Object_Renaming_Declaration
5595        and then Is_Class_Wide_Type (Unc_Type)
5596      then
5597         null;
5598
5599      --  In Ada 95 nothing to be done if the type of the expression is limited
5600      --  because in this case the expression cannot be copied, and its use can
5601      --  only be by reference.
5602
5603      --  In Ada 2005 the context can be an object declaration whose expression
5604      --  is a function that returns in place. If the nominal subtype has
5605      --  unknown discriminants, the call still provides constraints on the
5606      --  object, and we have to create an actual subtype from it.
5607
5608      --  If the type is class-wide, the expression is dynamically tagged and
5609      --  we do not create an actual subtype either. Ditto for an interface.
5610      --  For now this applies only if the type is immutably limited, and the
5611      --  function being called is build-in-place. This will have to be revised
5612      --  when build-in-place functions are generalized to other types.
5613
5614      elsif Is_Limited_View (Exp_Typ)
5615        and then
5616         (Is_Class_Wide_Type (Exp_Typ)
5617           or else Is_Interface (Exp_Typ)
5618           or else not Has_Unknown_Discriminants (Exp_Typ)
5619           or else not Is_Composite_Type (Unc_Type))
5620      then
5621         null;
5622
5623      --  For limited objects initialized with build-in-place function calls,
5624      --  nothing to be done; otherwise we prematurely introduce an N_Reference
5625      --  node in the expression initializing the object, which breaks the
5626      --  circuitry that detects and adds the additional arguments to the
5627      --  called function.
5628
5629      elsif Is_Build_In_Place_Function_Call (Exp) then
5630         null;
5631
5632     --  If the expression is an uninitialized aggregate, no need to build
5633     --  a subtype from the expression, because this may require the use of
5634     --  dynamic memory to create the object.
5635
5636      elsif Is_Uninitialized_Aggregate (Exp, Exp_Typ) then
5637         Rewrite (Subtype_Indic, New_Occurrence_Of (Etype (Exp), Sloc (N)));
5638         if Nkind (N) = N_Object_Declaration then
5639            Set_Expression (N, Empty);
5640            Set_No_Initialization (N);
5641         end if;
5642
5643      else
5644         Remove_Side_Effects (Exp);
5645         Rewrite (Subtype_Indic,
5646           Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id));
5647      end if;
5648   end Expand_Subtype_From_Expr;
5649
5650   ---------------------------------------------
5651   -- Expression_Contains_Primitives_Calls_Of --
5652   ---------------------------------------------
5653
5654   function Expression_Contains_Primitives_Calls_Of
5655     (Expr : Node_Id;
5656      Typ  : Entity_Id) return Boolean
5657   is
5658      U_Typ : constant Entity_Id := Unique_Entity (Typ);
5659
5660      Calls_OK : Boolean := False;
5661      --  This flag is set to True when expression Expr contains at least one
5662      --  call to a nondispatching primitive function of Typ.
5663
5664      function Search_Primitive_Calls (N : Node_Id) return Traverse_Result;
5665      --  Search for nondispatching calls to primitive functions of type Typ
5666
5667      ----------------------------
5668      -- Search_Primitive_Calls --
5669      ----------------------------
5670
5671      function Search_Primitive_Calls (N : Node_Id) return Traverse_Result is
5672         Disp_Typ : Entity_Id;
5673         Subp     : Entity_Id;
5674
5675      begin
5676         --  Detect a function call that could denote a nondispatching
5677         --  primitive of the input type.
5678
5679         if Nkind (N) = N_Function_Call
5680           and then Is_Entity_Name (Name (N))
5681         then
5682            Subp := Entity (Name (N));
5683
5684            --  Do not consider function calls with a controlling argument, as
5685            --  those are always dispatching calls.
5686
5687            if Is_Dispatching_Operation (Subp)
5688              and then No (Controlling_Argument (N))
5689            then
5690               Disp_Typ := Find_Dispatching_Type (Subp);
5691
5692               --  To qualify as a suitable primitive, the dispatching type of
5693               --  the function must be the input type.
5694
5695               if Present (Disp_Typ)
5696                 and then Unique_Entity (Disp_Typ) = U_Typ
5697               then
5698                  Calls_OK := True;
5699
5700                  --  There is no need to continue the traversal, as one such
5701                  --  call suffices.
5702
5703                  return Abandon;
5704               end if;
5705            end if;
5706         end if;
5707
5708         return OK;
5709      end Search_Primitive_Calls;
5710
5711      procedure Search_Calls is new Traverse_Proc (Search_Primitive_Calls);
5712
5713   --  Start of processing for Expression_Contains_Primitives_Calls_Of_Type
5714
5715   begin
5716      Search_Calls (Expr);
5717      return Calls_OK;
5718   end Expression_Contains_Primitives_Calls_Of;
5719
5720   ----------------------
5721   -- Finalize_Address --
5722   ----------------------
5723
5724   function Finalize_Address (Typ : Entity_Id) return Entity_Id is
5725      Btyp : constant Entity_Id := Base_Type (Typ);
5726      Utyp : Entity_Id := Typ;
5727
5728   begin
5729      --  Handle protected class-wide or task class-wide types
5730
5731      if Is_Class_Wide_Type (Utyp) then
5732         if Is_Concurrent_Type (Root_Type (Utyp)) then
5733            Utyp := Root_Type (Utyp);
5734
5735         elsif Is_Private_Type (Root_Type (Utyp))
5736           and then Present (Full_View (Root_Type (Utyp)))
5737           and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
5738         then
5739            Utyp := Full_View (Root_Type (Utyp));
5740         end if;
5741      end if;
5742
5743      --  Handle private types
5744
5745      if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then
5746         Utyp := Full_View (Utyp);
5747      end if;
5748
5749      --  Handle protected and task types
5750
5751      if Is_Concurrent_Type (Utyp)
5752        and then Present (Corresponding_Record_Type (Utyp))
5753      then
5754         Utyp := Corresponding_Record_Type (Utyp);
5755      end if;
5756
5757      Utyp := Underlying_Type (Base_Type (Utyp));
5758
5759      --  Deal with untagged derivation of private views. If the parent is
5760      --  now known to be protected, the finalization routine is the one
5761      --  defined on the corresponding record of the ancestor (corresponding
5762      --  records do not automatically inherit operations, but maybe they
5763      --  should???)
5764
5765      if Is_Untagged_Derivation (Btyp) then
5766         if Is_Protected_Type (Btyp) then
5767            Utyp := Corresponding_Record_Type (Root_Type (Btyp));
5768
5769         else
5770            Utyp := Underlying_Type (Root_Type (Btyp));
5771
5772            if Is_Protected_Type (Utyp) then
5773               Utyp := Corresponding_Record_Type (Utyp);
5774            end if;
5775         end if;
5776      end if;
5777
5778      --  If the underlying_type is a subtype, we are dealing with the
5779      --  completion of a private type. We need to access the base type and
5780      --  generate a conversion to it.
5781
5782      if Utyp /= Base_Type (Utyp) then
5783         pragma Assert (Is_Private_Type (Typ));
5784
5785         Utyp := Base_Type (Utyp);
5786      end if;
5787
5788      --  When dealing with an internally built full view for a type with
5789      --  unknown discriminants, use the original record type.
5790
5791      if Is_Underlying_Record_View (Utyp) then
5792         Utyp := Etype (Utyp);
5793      end if;
5794
5795      return TSS (Utyp, TSS_Finalize_Address);
5796   end Finalize_Address;
5797
5798   ------------------------
5799   -- Find_Interface_ADT --
5800   ------------------------
5801
5802   function Find_Interface_ADT
5803     (T     : Entity_Id;
5804      Iface : Entity_Id) return Elmt_Id
5805   is
5806      ADT : Elmt_Id;
5807      Typ : Entity_Id := T;
5808
5809   begin
5810      pragma Assert (Is_Interface (Iface));
5811
5812      --  Handle private types
5813
5814      if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
5815         Typ := Full_View (Typ);
5816      end if;
5817
5818      --  Handle access types
5819
5820      if Is_Access_Type (Typ) then
5821         Typ := Designated_Type (Typ);
5822      end if;
5823
5824      --  Handle task and protected types implementing interfaces
5825
5826      if Is_Concurrent_Type (Typ) then
5827         Typ := Corresponding_Record_Type (Typ);
5828      end if;
5829
5830      pragma Assert
5831        (not Is_Class_Wide_Type (Typ)
5832          and then Ekind (Typ) /= E_Incomplete_Type);
5833
5834      if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
5835         return First_Elmt (Access_Disp_Table (Typ));
5836
5837      else
5838         ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
5839         while Present (ADT)
5840           and then Present (Related_Type (Node (ADT)))
5841           and then Related_Type (Node (ADT)) /= Iface
5842           and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
5843                                     Use_Full_View => True)
5844         loop
5845            Next_Elmt (ADT);
5846         end loop;
5847
5848         pragma Assert (Present (Related_Type (Node (ADT))));
5849         return ADT;
5850      end if;
5851   end Find_Interface_ADT;
5852
5853   ------------------------
5854   -- Find_Interface_Tag --
5855   ------------------------
5856
5857   function Find_Interface_Tag
5858     (T     : Entity_Id;
5859      Iface : Entity_Id) return Entity_Id
5860   is
5861      AI_Tag : Entity_Id := Empty;
5862      Found  : Boolean   := False;
5863      Typ    : Entity_Id := T;
5864
5865      procedure Find_Tag (Typ : Entity_Id);
5866      --  Internal subprogram used to recursively climb to the ancestors
5867
5868      --------------
5869      -- Find_Tag --
5870      --------------
5871
5872      procedure Find_Tag (Typ : Entity_Id) is
5873         AI_Elmt : Elmt_Id;
5874         AI      : Node_Id;
5875
5876      begin
5877         --  This routine does not handle the case in which the interface is an
5878         --  ancestor of Typ. That case is handled by the enclosing subprogram.
5879
5880         pragma Assert (Typ /= Iface);
5881
5882         --  Climb to the root type handling private types
5883
5884         if Present (Full_View (Etype (Typ))) then
5885            if Full_View (Etype (Typ)) /= Typ then
5886               Find_Tag (Full_View (Etype (Typ)));
5887            end if;
5888
5889         elsif Etype (Typ) /= Typ then
5890            Find_Tag (Etype (Typ));
5891         end if;
5892
5893         --  Traverse the list of interfaces implemented by the type
5894
5895         if not Found
5896           and then Present (Interfaces (Typ))
5897           and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
5898         then
5899            --  Skip the tag associated with the primary table
5900
5901            AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
5902            pragma Assert (Present (AI_Tag));
5903
5904            AI_Elmt := First_Elmt (Interfaces (Typ));
5905            while Present (AI_Elmt) loop
5906               AI := Node (AI_Elmt);
5907
5908               if AI = Iface
5909                 or else Is_Ancestor (Iface, AI, Use_Full_View => True)
5910               then
5911                  Found := True;
5912                  return;
5913               end if;
5914
5915               AI_Tag := Next_Tag_Component (AI_Tag);
5916               Next_Elmt (AI_Elmt);
5917            end loop;
5918         end if;
5919      end Find_Tag;
5920
5921   --  Start of processing for Find_Interface_Tag
5922
5923   begin
5924      pragma Assert (Is_Interface (Iface));
5925
5926      --  Handle access types
5927
5928      if Is_Access_Type (Typ) then
5929         Typ := Designated_Type (Typ);
5930      end if;
5931
5932      --  Handle class-wide types
5933
5934      if Is_Class_Wide_Type (Typ) then
5935         Typ := Root_Type (Typ);
5936      end if;
5937
5938      --  Handle private types
5939
5940      if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
5941         Typ := Full_View (Typ);
5942      end if;
5943
5944      --  Handle entities from the limited view
5945
5946      if Ekind (Typ) = E_Incomplete_Type then
5947         pragma Assert (Present (Non_Limited_View (Typ)));
5948         Typ := Non_Limited_View (Typ);
5949      end if;
5950
5951      --  Handle task and protected types implementing interfaces
5952
5953      if Is_Concurrent_Type (Typ) then
5954         Typ := Corresponding_Record_Type (Typ);
5955      end if;
5956
5957      --  If the interface is an ancestor of the type, then it shared the
5958      --  primary dispatch table.
5959
5960      if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
5961         return First_Tag_Component (Typ);
5962
5963      --  Otherwise we need to search for its associated tag component
5964
5965      else
5966         Find_Tag (Typ);
5967         return AI_Tag;
5968      end if;
5969   end Find_Interface_Tag;
5970
5971   ---------------------------
5972   -- Find_Optional_Prim_Op --
5973   ---------------------------
5974
5975   function Find_Optional_Prim_Op
5976     (T : Entity_Id; Name : Name_Id) return Entity_Id
5977   is
5978      Prim : Elmt_Id;
5979      Typ  : Entity_Id := T;
5980      Op   : Entity_Id;
5981
5982   begin
5983      if Is_Class_Wide_Type (Typ) then
5984         Typ := Root_Type (Typ);
5985      end if;
5986
5987      Typ := Underlying_Type (Typ);
5988
5989      --  Loop through primitive operations
5990
5991      Prim := First_Elmt (Primitive_Operations (Typ));
5992      while Present (Prim) loop
5993         Op := Node (Prim);
5994
5995         --  We can retrieve primitive operations by name if it is an internal
5996         --  name. For equality we must check that both of its operands have
5997         --  the same type, to avoid confusion with user-defined equalities
5998         --  than may have a asymmetric signature.
5999
6000         exit when Chars (Op) = Name
6001           and then
6002             (Name /= Name_Op_Eq
6003               or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
6004
6005         Next_Elmt (Prim);
6006      end loop;
6007
6008      return Node (Prim); -- Empty if not found
6009   end Find_Optional_Prim_Op;
6010
6011   ---------------------------
6012   -- Find_Optional_Prim_Op --
6013   ---------------------------
6014
6015   function Find_Optional_Prim_Op
6016     (T    : Entity_Id;
6017      Name : TSS_Name_Type) return Entity_Id
6018   is
6019      Inher_Op  : Entity_Id := Empty;
6020      Own_Op    : Entity_Id := Empty;
6021      Prim_Elmt : Elmt_Id;
6022      Prim_Id   : Entity_Id;
6023      Typ       : Entity_Id := T;
6024
6025   begin
6026      if Is_Class_Wide_Type (Typ) then
6027         Typ := Root_Type (Typ);
6028      end if;
6029
6030      Typ := Underlying_Type (Typ);
6031
6032      --  This search is based on the assertion that the dispatching version
6033      --  of the TSS routine always precedes the real primitive.
6034
6035      Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6036      while Present (Prim_Elmt) loop
6037         Prim_Id := Node (Prim_Elmt);
6038
6039         if Is_TSS (Prim_Id, Name) then
6040            if Present (Alias (Prim_Id)) then
6041               Inher_Op := Prim_Id;
6042            else
6043               Own_Op := Prim_Id;
6044            end if;
6045         end if;
6046
6047         Next_Elmt (Prim_Elmt);
6048      end loop;
6049
6050      if Present (Own_Op) then
6051         return Own_Op;
6052      elsif Present (Inher_Op) then
6053         return Inher_Op;
6054      else
6055         return Empty;
6056      end if;
6057   end Find_Optional_Prim_Op;
6058
6059   ------------------
6060   -- Find_Prim_Op --
6061   ------------------
6062
6063   function Find_Prim_Op
6064     (T : Entity_Id; Name : Name_Id) return Entity_Id
6065   is
6066      Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
6067   begin
6068      if No (Result) then
6069         raise Program_Error;
6070      end if;
6071
6072      return Result;
6073   end Find_Prim_Op;
6074
6075   ------------------
6076   -- Find_Prim_Op --
6077   ------------------
6078
6079   function Find_Prim_Op
6080     (T    : Entity_Id;
6081      Name : TSS_Name_Type) return Entity_Id
6082   is
6083      Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
6084   begin
6085      if No (Result) then
6086         raise Program_Error;
6087      end if;
6088
6089      return Result;
6090   end Find_Prim_Op;
6091
6092   ----------------------------
6093   -- Find_Protection_Object --
6094   ----------------------------
6095
6096   function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
6097      S : Entity_Id;
6098
6099   begin
6100      S := Scop;
6101      while Present (S) loop
6102         if Ekind (S) in E_Entry | E_Entry_Family | E_Function | E_Procedure
6103           and then Present (Protection_Object (S))
6104         then
6105            return Protection_Object (S);
6106         end if;
6107
6108         S := Scope (S);
6109      end loop;
6110
6111      --  If we do not find a Protection object in the scope chain, then
6112      --  something has gone wrong, most likely the object was never created.
6113
6114      raise Program_Error;
6115   end Find_Protection_Object;
6116
6117   --------------------------
6118   -- Find_Protection_Type --
6119   --------------------------
6120
6121   function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
6122      Comp : Entity_Id;
6123      Typ  : Entity_Id := Conc_Typ;
6124
6125   begin
6126      if Is_Concurrent_Type (Typ) then
6127         Typ := Corresponding_Record_Type (Typ);
6128      end if;
6129
6130      --  Since restriction violations are not considered serious errors, the
6131      --  expander remains active, but may leave the corresponding record type
6132      --  malformed. In such cases, component _object is not available so do
6133      --  not look for it.
6134
6135      if not Analyzed (Typ) then
6136         return Empty;
6137      end if;
6138
6139      Comp := First_Component (Typ);
6140      while Present (Comp) loop
6141         if Chars (Comp) = Name_uObject then
6142            return Base_Type (Etype (Comp));
6143         end if;
6144
6145         Next_Component (Comp);
6146      end loop;
6147
6148      --  The corresponding record of a protected type should always have an
6149      --  _object field.
6150
6151      raise Program_Error;
6152   end Find_Protection_Type;
6153
6154   -----------------------
6155   -- Find_Hook_Context --
6156   -----------------------
6157
6158   function Find_Hook_Context (N : Node_Id) return Node_Id is
6159      Par : Node_Id;
6160      Top : Node_Id;
6161
6162      Wrapped_Node : Node_Id;
6163      --  Note: if we are in a transient scope, we want to reuse it as
6164      --  the context for actions insertion, if possible. But if N is itself
6165      --  part of the stored actions for the current transient scope,
6166      --  then we need to insert at the appropriate (inner) location in
6167      --  the not as an action on Node_To_Be_Wrapped.
6168
6169      In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N);
6170
6171   begin
6172      --  When the node is inside a case/if expression, the lifetime of any
6173      --  temporary controlled object is extended. Find a suitable insertion
6174      --  node by locating the topmost case or if expressions.
6175
6176      if In_Cond_Expr then
6177         Par := N;
6178         Top := N;
6179         while Present (Par) loop
6180            if Nkind (Original_Node (Par)) in
6181                 N_Case_Expression | N_If_Expression
6182            then
6183               Top := Par;
6184
6185            --  Prevent the search from going too far
6186
6187            elsif Is_Body_Or_Package_Declaration (Par) then
6188               exit;
6189            end if;
6190
6191            Par := Parent (Par);
6192         end loop;
6193
6194         --  The topmost case or if expression is now recovered, but it may
6195         --  still not be the correct place to add generated code. Climb to
6196         --  find a parent that is part of a declarative or statement list,
6197         --  and is not a list of actuals in a call.
6198
6199         Par := Top;
6200         while Present (Par) loop
6201            if Is_List_Member (Par)
6202              and then Nkind (Par) not in N_Component_Association
6203                                        | N_Discriminant_Association
6204                                        | N_Parameter_Association
6205                                        | N_Pragma_Argument_Association
6206              and then Nkind (Parent (Par)) not in N_Function_Call
6207                                                 | N_Procedure_Call_Statement
6208                                                 | N_Entry_Call_Statement
6209
6210            then
6211               return Par;
6212
6213            --  Prevent the search from going too far
6214
6215            elsif Is_Body_Or_Package_Declaration (Par) then
6216               exit;
6217            end if;
6218
6219            Par := Parent (Par);
6220         end loop;
6221
6222         return Par;
6223
6224      else
6225         Par := N;
6226         while Present (Par) loop
6227
6228            --  Keep climbing past various operators
6229
6230            if Nkind (Parent (Par)) in N_Op
6231              or else Nkind (Parent (Par)) in N_And_Then | N_Or_Else
6232            then
6233               Par := Parent (Par);
6234            else
6235               exit;
6236            end if;
6237         end loop;
6238
6239         Top := Par;
6240
6241         --  The node may be located in a pragma in which case return the
6242         --  pragma itself:
6243
6244         --    pragma Precondition (... and then Ctrl_Func_Call ...);
6245
6246         --  Similar case occurs when the node is related to an object
6247         --  declaration or assignment:
6248
6249         --    Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...;
6250
6251         --  Another case to consider is when the node is part of a return
6252         --  statement:
6253
6254         --    return ... and then Ctrl_Func_Call ...;
6255
6256         --  Another case is when the node acts as a formal in a procedure
6257         --  call statement:
6258
6259         --    Proc (... and then Ctrl_Func_Call ...);
6260
6261         if Scope_Is_Transient then
6262            Wrapped_Node := Node_To_Be_Wrapped;
6263         else
6264            Wrapped_Node := Empty;
6265         end if;
6266
6267         while Present (Par) loop
6268            if Par = Wrapped_Node
6269              or else Nkind (Par) in N_Assignment_Statement
6270                                   | N_Object_Declaration
6271                                   | N_Pragma
6272                                   | N_Procedure_Call_Statement
6273                                   | N_Simple_Return_Statement
6274            then
6275               return Par;
6276
6277            --  Prevent the search from going too far
6278
6279            elsif Is_Body_Or_Package_Declaration (Par) then
6280               exit;
6281            end if;
6282
6283            Par := Parent (Par);
6284         end loop;
6285
6286         --  Return the topmost short circuit operator
6287
6288         return Top;
6289      end if;
6290   end Find_Hook_Context;
6291
6292   ------------------------------
6293   -- Following_Address_Clause --
6294   ------------------------------
6295
6296   function Following_Address_Clause (D : Node_Id) return Node_Id is
6297      Id     : constant Entity_Id := Defining_Identifier (D);
6298      Result : Node_Id;
6299      Par    : Node_Id;
6300
6301      function Check_Decls (D : Node_Id) return Node_Id;
6302      --  This internal function differs from the main function in that it
6303      --  gets called to deal with a following package private part, and
6304      --  it checks declarations starting with D (the main function checks
6305      --  declarations following D). If D is Empty, then Empty is returned.
6306
6307      -----------------
6308      -- Check_Decls --
6309      -----------------
6310
6311      function Check_Decls (D : Node_Id) return Node_Id is
6312         Decl : Node_Id;
6313
6314      begin
6315         Decl := D;
6316         while Present (Decl) loop
6317            if Nkind (Decl) = N_At_Clause
6318              and then Chars (Identifier (Decl)) = Chars (Id)
6319            then
6320               return Decl;
6321
6322            elsif Nkind (Decl) = N_Attribute_Definition_Clause
6323              and then Chars (Decl) = Name_Address
6324              and then Chars (Name (Decl)) = Chars (Id)
6325            then
6326               return Decl;
6327            end if;
6328
6329            Next (Decl);
6330         end loop;
6331
6332         --  Otherwise not found, return Empty
6333
6334         return Empty;
6335      end Check_Decls;
6336
6337      --  Start of processing for Following_Address_Clause
6338
6339   begin
6340      --  If parser detected no address clause for the identifier in question,
6341      --  then the answer is a quick NO, without the need for a search.
6342
6343      if not Get_Name_Table_Boolean1 (Chars (Id)) then
6344         return Empty;
6345      end if;
6346
6347      --  Otherwise search current declarative unit
6348
6349      Result := Check_Decls (Next (D));
6350
6351      if Present (Result) then
6352         return Result;
6353      end if;
6354
6355      --  Check for possible package private part following
6356
6357      Par := Parent (D);
6358
6359      if Nkind (Par) = N_Package_Specification
6360        and then Visible_Declarations (Par) = List_Containing (D)
6361        and then Present (Private_Declarations (Par))
6362      then
6363         --  Private part present, check declarations there
6364
6365         return Check_Decls (First (Private_Declarations (Par)));
6366
6367      else
6368         --  No private part, clause not found, return Empty
6369
6370         return Empty;
6371      end if;
6372   end Following_Address_Clause;
6373
6374   ----------------------
6375   -- Force_Evaluation --
6376   ----------------------
6377
6378   procedure Force_Evaluation
6379     (Exp           : Node_Id;
6380      Name_Req      : Boolean   := False;
6381      Related_Id    : Entity_Id := Empty;
6382      Is_Low_Bound  : Boolean   := False;
6383      Is_High_Bound : Boolean   := False;
6384      Mode          : Force_Evaluation_Mode := Relaxed)
6385   is
6386   begin
6387      Remove_Side_Effects
6388        (Exp                => Exp,
6389         Name_Req           => Name_Req,
6390         Variable_Ref       => True,
6391         Renaming_Req       => False,
6392         Related_Id         => Related_Id,
6393         Is_Low_Bound       => Is_Low_Bound,
6394         Is_High_Bound      => Is_High_Bound,
6395         Check_Side_Effects =>
6396           Is_Static_Expression (Exp)
6397             or else Mode = Relaxed);
6398   end Force_Evaluation;
6399
6400   ---------------------------------
6401   -- Fully_Qualified_Name_String --
6402   ---------------------------------
6403
6404   function Fully_Qualified_Name_String
6405     (E          : Entity_Id;
6406      Append_NUL : Boolean := True) return String_Id
6407   is
6408      procedure Internal_Full_Qualified_Name (E : Entity_Id);
6409      --  Compute recursively the qualified name without NUL at the end, adding
6410      --  it to the currently started string being generated
6411
6412      ----------------------------------
6413      -- Internal_Full_Qualified_Name --
6414      ----------------------------------
6415
6416      procedure Internal_Full_Qualified_Name (E : Entity_Id) is
6417         Ent : Entity_Id;
6418
6419      begin
6420         --  Deal properly with child units
6421
6422         if Nkind (E) = N_Defining_Program_Unit_Name then
6423            Ent := Defining_Identifier (E);
6424         else
6425            Ent := E;
6426         end if;
6427
6428         --  Compute qualification recursively (only "Standard" has no scope)
6429
6430         if Present (Scope (Scope (Ent))) then
6431            Internal_Full_Qualified_Name (Scope (Ent));
6432            Store_String_Char (Get_Char_Code ('.'));
6433         end if;
6434
6435         --  Every entity should have a name except some expanded blocks
6436         --  don't bother about those.
6437
6438         if Chars (Ent) = No_Name then
6439            return;
6440         end if;
6441
6442         --  Generates the entity name in upper case
6443
6444         Get_Decoded_Name_String (Chars (Ent));
6445         Set_All_Upper_Case;
6446         Store_String_Chars (Name_Buffer (1 .. Name_Len));
6447         return;
6448      end Internal_Full_Qualified_Name;
6449
6450   --  Start of processing for Full_Qualified_Name
6451
6452   begin
6453      Start_String;
6454      Internal_Full_Qualified_Name (E);
6455
6456      if Append_NUL then
6457         Store_String_Char (Get_Char_Code (ASCII.NUL));
6458      end if;
6459
6460      return End_String;
6461   end Fully_Qualified_Name_String;
6462
6463   ---------------------------------
6464   -- Get_Current_Value_Condition --
6465   ---------------------------------
6466
6467   --  Note: the implementation of this procedure is very closely tied to the
6468   --  implementation of Set_Current_Value_Condition. In the Get procedure, we
6469   --  interpret Current_Value fields set by the Set procedure, so the two
6470   --  procedures need to be closely coordinated.
6471
6472   procedure Get_Current_Value_Condition
6473     (Var : Node_Id;
6474      Op  : out Node_Kind;
6475      Val : out Node_Id)
6476   is
6477      Loc : constant Source_Ptr := Sloc (Var);
6478      Ent : constant Entity_Id  := Entity (Var);
6479
6480      procedure Process_Current_Value_Condition (N : Node_Id; S : Boolean);
6481      --  N is an expression which holds either True (S = True) or False (S =
6482      --  False) in the condition. This procedure digs out the expression and
6483      --  if it refers to Ent, sets Op and Val appropriately.
6484
6485      -------------------------------------
6486      -- Process_Current_Value_Condition --
6487      -------------------------------------
6488
6489      procedure Process_Current_Value_Condition
6490        (N : Node_Id;
6491         S : Boolean)
6492      is
6493         Cond      : Node_Id;
6494         Prev_Cond : Node_Id;
6495         Sens      : Boolean;
6496
6497      begin
6498         Cond := N;
6499         Sens := S;
6500
6501         loop
6502            Prev_Cond := Cond;
6503
6504            --  Deal with NOT operators, inverting sense
6505
6506            while Nkind (Cond) = N_Op_Not loop
6507               Cond := Right_Opnd (Cond);
6508               Sens := not Sens;
6509            end loop;
6510
6511            --  Deal with conversions, qualifications, and expressions with
6512            --  actions.
6513
6514            while Nkind (Cond) in N_Type_Conversion
6515                                | N_Qualified_Expression
6516                                | N_Expression_With_Actions
6517            loop
6518               Cond := Expression (Cond);
6519            end loop;
6520
6521            exit when Cond = Prev_Cond;
6522         end loop;
6523
6524         --  Deal with AND THEN and AND cases
6525
6526         if Nkind (Cond) in N_And_Then | N_Op_And then
6527
6528            --  Don't ever try to invert a condition that is of the form of an
6529            --  AND or AND THEN (since we are not doing sufficiently general
6530            --  processing to allow this).
6531
6532            if Sens = False then
6533               Op  := N_Empty;
6534               Val := Empty;
6535               return;
6536            end if;
6537
6538            --  Recursively process AND and AND THEN branches
6539
6540            Process_Current_Value_Condition (Left_Opnd (Cond), True);
6541            pragma Assert (Op'Valid);
6542
6543            if Op /= N_Empty then
6544               return;
6545            end if;
6546
6547            Process_Current_Value_Condition (Right_Opnd (Cond), True);
6548            return;
6549
6550         --  Case of relational operator
6551
6552         elsif Nkind (Cond) in N_Op_Compare then
6553            Op := Nkind (Cond);
6554
6555            --  Invert sense of test if inverted test
6556
6557            if Sens = False then
6558               case Op is
6559                  when N_Op_Eq => Op := N_Op_Ne;
6560                  when N_Op_Ne => Op := N_Op_Eq;
6561                  when N_Op_Lt => Op := N_Op_Ge;
6562                  when N_Op_Gt => Op := N_Op_Le;
6563                  when N_Op_Le => Op := N_Op_Gt;
6564                  when N_Op_Ge => Op := N_Op_Lt;
6565                  when others  => raise Program_Error;
6566               end case;
6567            end if;
6568
6569            --  Case of entity op value
6570
6571            if Is_Entity_Name (Left_Opnd (Cond))
6572              and then Ent = Entity (Left_Opnd (Cond))
6573              and then Compile_Time_Known_Value (Right_Opnd (Cond))
6574            then
6575               Val := Right_Opnd (Cond);
6576
6577            --  Case of value op entity
6578
6579            elsif Is_Entity_Name (Right_Opnd (Cond))
6580              and then Ent = Entity (Right_Opnd (Cond))
6581              and then Compile_Time_Known_Value (Left_Opnd (Cond))
6582            then
6583               Val := Left_Opnd (Cond);
6584
6585               --  We are effectively swapping operands
6586
6587               case Op is
6588                  when N_Op_Eq => null;
6589                  when N_Op_Ne => null;
6590                  when N_Op_Lt => Op := N_Op_Gt;
6591                  when N_Op_Gt => Op := N_Op_Lt;
6592                  when N_Op_Le => Op := N_Op_Ge;
6593                  when N_Op_Ge => Op := N_Op_Le;
6594                  when others  => raise Program_Error;
6595               end case;
6596
6597            else
6598               Op := N_Empty;
6599            end if;
6600
6601            return;
6602
6603         elsif Nkind (Cond) in N_Type_Conversion
6604                             | N_Qualified_Expression
6605                             | N_Expression_With_Actions
6606         then
6607            Cond := Expression (Cond);
6608
6609         --  Case of Boolean variable reference, return as though the
6610         --  reference had said var = True.
6611
6612         else
6613            if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then
6614               Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
6615
6616               if Sens = False then
6617                  Op := N_Op_Ne;
6618               else
6619                  Op := N_Op_Eq;
6620               end if;
6621            end if;
6622         end if;
6623      end Process_Current_Value_Condition;
6624
6625   --  Start of processing for Get_Current_Value_Condition
6626
6627   begin
6628      Op  := N_Empty;
6629      Val := Empty;
6630
6631      --  Immediate return, nothing doing, if this is not an object
6632
6633      if not Is_Object (Ent) then
6634         return;
6635      end if;
6636
6637      --  In GNATprove mode we don't want to use current value optimizer, in
6638      --  particular for loop invariant expressions and other assertions that
6639      --  act as cut points for proof. The optimizer often folds expressions
6640      --  into True/False where they trivially follow from the previous
6641      --  assignments, but this deprives proof from the information needed to
6642      --  discharge checks that are beyond the scope of the value optimizer.
6643
6644      if GNATprove_Mode then
6645         return;
6646      end if;
6647
6648      --  Otherwise examine current value
6649
6650      declare
6651         CV   : constant Node_Id := Current_Value (Ent);
6652         Sens : Boolean;
6653         Stm  : Node_Id;
6654
6655      begin
6656         --  If statement. Condition is known true in THEN section, known False
6657         --  in any ELSIF or ELSE part, and unknown outside the IF statement.
6658
6659         if Nkind (CV) = N_If_Statement then
6660
6661            --  Before start of IF statement
6662
6663            if Loc < Sloc (CV) then
6664               return;
6665
6666            --  After end of IF statement
6667
6668            elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
6669               return;
6670            end if;
6671
6672            --  At this stage we know that we are within the IF statement, but
6673            --  unfortunately, the tree does not record the SLOC of the ELSE so
6674            --  we cannot use a simple SLOC comparison to distinguish between
6675            --  the then/else statements, so we have to climb the tree.
6676
6677            declare
6678               N : Node_Id;
6679
6680            begin
6681               N := Parent (Var);
6682               while Parent (N) /= CV loop
6683                  N := Parent (N);
6684
6685                  --  If we fall off the top of the tree, then that's odd, but
6686                  --  perhaps it could occur in some error situation, and the
6687                  --  safest response is simply to assume that the outcome of
6688                  --  the condition is unknown. No point in bombing during an
6689                  --  attempt to optimize things.
6690
6691                  if No (N) then
6692                     return;
6693                  end if;
6694               end loop;
6695
6696               --  Now we have N pointing to a node whose parent is the IF
6697               --  statement in question, so now we can tell if we are within
6698               --  the THEN statements.
6699
6700               if Is_List_Member (N)
6701                 and then List_Containing (N) = Then_Statements (CV)
6702               then
6703                  Sens := True;
6704
6705               --  If the variable reference does not come from source, we
6706               --  cannot reliably tell whether it appears in the else part.
6707               --  In particular, if it appears in generated code for a node
6708               --  that requires finalization, it may be attached to a list
6709               --  that has not been yet inserted into the code. For now,
6710               --  treat it as unknown.
6711
6712               elsif not Comes_From_Source (N) then
6713                  return;
6714
6715               --  Otherwise we must be in ELSIF or ELSE part
6716
6717               else
6718                  Sens := False;
6719               end if;
6720            end;
6721
6722            --  ELSIF part. Condition is known true within the referenced
6723            --  ELSIF, known False in any subsequent ELSIF or ELSE part,
6724            --  and unknown before the ELSE part or after the IF statement.
6725
6726         elsif Nkind (CV) = N_Elsif_Part then
6727
6728            --  if the Elsif_Part had condition_actions, the elsif has been
6729            --  rewritten as a nested if, and the original elsif_part is
6730            --  detached from the tree, so there is no way to obtain useful
6731            --  information on the current value of the variable.
6732            --  Can this be improved ???
6733
6734            if No (Parent (CV)) then
6735               return;
6736            end if;
6737
6738            Stm := Parent (CV);
6739
6740            --  If the tree has been otherwise rewritten there is nothing
6741            --  else to be done either.
6742
6743            if Nkind (Stm) /= N_If_Statement then
6744               return;
6745            end if;
6746
6747            --  Before start of ELSIF part
6748
6749            if Loc < Sloc (CV) then
6750               return;
6751
6752               --  After end of IF statement
6753
6754            elsif Loc >= Sloc (Stm) +
6755              Text_Ptr (UI_To_Int (End_Span (Stm)))
6756            then
6757               return;
6758            end if;
6759
6760            --  Again we lack the SLOC of the ELSE, so we need to climb the
6761            --  tree to see if we are within the ELSIF part in question.
6762
6763            declare
6764               N : Node_Id;
6765
6766            begin
6767               N := Parent (Var);
6768               while Parent (N) /= Stm loop
6769                  N := Parent (N);
6770
6771                  --  If we fall off the top of the tree, then that's odd, but
6772                  --  perhaps it could occur in some error situation, and the
6773                  --  safest response is simply to assume that the outcome of
6774                  --  the condition is unknown. No point in bombing during an
6775                  --  attempt to optimize things.
6776
6777                  if No (N) then
6778                     return;
6779                  end if;
6780               end loop;
6781
6782               --  Now we have N pointing to a node whose parent is the IF
6783               --  statement in question, so see if is the ELSIF part we want.
6784               --  the THEN statements.
6785
6786               if N = CV then
6787                  Sens := True;
6788
6789                  --  Otherwise we must be in subsequent ELSIF or ELSE part
6790
6791               else
6792                  Sens := False;
6793               end if;
6794            end;
6795
6796         --  Iteration scheme of while loop. The condition is known to be
6797         --  true within the body of the loop.
6798
6799         elsif Nkind (CV) = N_Iteration_Scheme then
6800            declare
6801               Loop_Stmt : constant Node_Id := Parent (CV);
6802
6803            begin
6804               --  Before start of body of loop
6805
6806               if Loc < Sloc (Loop_Stmt) then
6807                  return;
6808
6809               --  After end of LOOP statement
6810
6811               elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
6812                  return;
6813
6814               --  We are within the body of the loop
6815
6816               else
6817                  Sens := True;
6818               end if;
6819            end;
6820
6821         --  All other cases of Current_Value settings
6822
6823         else
6824            return;
6825         end if;
6826
6827         --  If we fall through here, then we have a reportable condition, Sens
6828         --  is True if the condition is true and False if it needs inverting.
6829
6830         Process_Current_Value_Condition (Condition (CV), Sens);
6831      end;
6832   end Get_Current_Value_Condition;
6833
6834   -----------------------
6835   -- Get_Index_Subtype --
6836   -----------------------
6837
6838   function Get_Index_Subtype (N : Node_Id) return Node_Id is
6839      P_Type : Entity_Id := Etype (Prefix (N));
6840      Indx   : Node_Id;
6841      J      : Int;
6842
6843   begin
6844      if Is_Access_Type (P_Type) then
6845         P_Type := Designated_Type (P_Type);
6846      end if;
6847
6848      if No (Expressions (N)) then
6849         J := 1;
6850      else
6851         J := UI_To_Int (Expr_Value (First (Expressions (N))));
6852      end if;
6853
6854      Indx := First_Index (P_Type);
6855      while J > 1 loop
6856         Next_Index (Indx);
6857         J := J - 1;
6858      end loop;
6859
6860      return Etype (Indx);
6861   end Get_Index_Subtype;
6862
6863   ---------------------
6864   -- Get_Stream_Size --
6865   ---------------------
6866
6867   function Get_Stream_Size (E : Entity_Id) return Uint is
6868   begin
6869      --  If we have a Stream_Size clause for this type use it
6870
6871      if Has_Stream_Size_Clause (E) then
6872         return Static_Integer (Expression (Stream_Size_Clause (E)));
6873
6874      --  Otherwise the Stream_Size is the size of the type
6875
6876      else
6877         return Esize (E);
6878      end if;
6879   end Get_Stream_Size;
6880
6881   ---------------------------
6882   -- Has_Access_Constraint --
6883   ---------------------------
6884
6885   function Has_Access_Constraint (E : Entity_Id) return Boolean is
6886      Disc : Entity_Id;
6887      T    : constant Entity_Id := Etype (E);
6888
6889   begin
6890      if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then
6891         Disc := First_Discriminant (T);
6892         while Present (Disc) loop
6893            if Is_Access_Type (Etype (Disc)) then
6894               return True;
6895            end if;
6896
6897            Next_Discriminant (Disc);
6898         end loop;
6899
6900         return False;
6901      else
6902         return False;
6903      end if;
6904   end Has_Access_Constraint;
6905
6906   --------------------
6907   -- Homonym_Number --
6908   --------------------
6909
6910   function Homonym_Number (Subp : Entity_Id) return Pos is
6911      Hom   : Entity_Id := Homonym (Subp);
6912      Count : Pos := 1;
6913
6914   begin
6915      while Present (Hom) loop
6916         if Scope (Hom) = Scope (Subp) then
6917            Count := Count + 1;
6918         end if;
6919
6920         Hom := Homonym (Hom);
6921      end loop;
6922
6923      return Count;
6924   end Homonym_Number;
6925
6926   -----------------------------------
6927   -- In_Library_Level_Package_Body --
6928   -----------------------------------
6929
6930   function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
6931   begin
6932      --  First determine whether the entity appears at the library level, then
6933      --  look at the containing unit.
6934
6935      if Is_Library_Level_Entity (Id) then
6936         declare
6937            Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
6938
6939         begin
6940            return Nkind (Unit (Container)) = N_Package_Body;
6941         end;
6942      end if;
6943
6944      return False;
6945   end In_Library_Level_Package_Body;
6946
6947   ------------------------------
6948   -- In_Unconditional_Context --
6949   ------------------------------
6950
6951   function In_Unconditional_Context (Node : Node_Id) return Boolean is
6952      P : Node_Id;
6953
6954   begin
6955      P := Node;
6956      while Present (P) loop
6957         case Nkind (P) is
6958            when N_Subprogram_Body => return True;
6959            when N_If_Statement    => return False;
6960            when N_Loop_Statement  => return False;
6961            when N_Case_Statement  => return False;
6962            when others            => P := Parent (P);
6963         end case;
6964      end loop;
6965
6966      return False;
6967   end In_Unconditional_Context;
6968
6969   -------------------
6970   -- Insert_Action --
6971   -------------------
6972
6973   procedure Insert_Action
6974     (Assoc_Node   : Node_Id;
6975      Ins_Action   : Node_Id;
6976      Spec_Expr_OK : Boolean := False)
6977   is
6978   begin
6979      if Present (Ins_Action) then
6980         Insert_Actions
6981           (Assoc_Node   => Assoc_Node,
6982            Ins_Actions  => New_List (Ins_Action),
6983            Spec_Expr_OK => Spec_Expr_OK);
6984      end if;
6985   end Insert_Action;
6986
6987   --  Version with check(s) suppressed
6988
6989   procedure Insert_Action
6990     (Assoc_Node   : Node_Id;
6991      Ins_Action   : Node_Id;
6992      Suppress     : Check_Id;
6993      Spec_Expr_OK : Boolean := False)
6994   is
6995   begin
6996      Insert_Actions
6997        (Assoc_Node   => Assoc_Node,
6998         Ins_Actions  => New_List (Ins_Action),
6999         Suppress     => Suppress,
7000         Spec_Expr_OK => Spec_Expr_OK);
7001   end Insert_Action;
7002
7003   -------------------------
7004   -- Insert_Action_After --
7005   -------------------------
7006
7007   procedure Insert_Action_After
7008     (Assoc_Node : Node_Id;
7009      Ins_Action : Node_Id)
7010   is
7011   begin
7012      Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
7013   end Insert_Action_After;
7014
7015   --------------------
7016   -- Insert_Actions --
7017   --------------------
7018
7019   procedure Insert_Actions
7020     (Assoc_Node   : Node_Id;
7021      Ins_Actions  : List_Id;
7022      Spec_Expr_OK : Boolean := False)
7023   is
7024      N : Node_Id;
7025      P : Node_Id;
7026
7027      Wrapped_Node : Node_Id := Empty;
7028
7029   begin
7030      if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
7031         return;
7032      end if;
7033
7034      --  Insert the action when the context is "Handling of Default and Per-
7035      --  Object Expressions" only when requested by the caller.
7036
7037      if Spec_Expr_OK then
7038         null;
7039
7040      --  Ignore insert of actions from inside default expression (or other
7041      --  similar "spec expression") in the special spec-expression analyze
7042      --  mode. Any insertions at this point have no relevance, since we are
7043      --  only doing the analyze to freeze the types of any static expressions.
7044      --  See section "Handling of Default and Per-Object Expressions" in the
7045      --  spec of package Sem for further details.
7046
7047      elsif In_Spec_Expression then
7048         return;
7049      end if;
7050
7051      --  If the action derives from stuff inside a record, then the actions
7052      --  are attached to the current scope, to be inserted and analyzed on
7053      --  exit from the scope. The reason for this is that we may also be
7054      --  generating freeze actions at the same time, and they must eventually
7055      --  be elaborated in the correct order.
7056
7057      if Is_Record_Type (Current_Scope)
7058        and then not Is_Frozen (Current_Scope)
7059      then
7060         if No (Scope_Stack.Table
7061                  (Scope_Stack.Last).Pending_Freeze_Actions)
7062         then
7063            Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
7064              Ins_Actions;
7065         else
7066            Append_List
7067              (Ins_Actions,
7068               Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
7069         end if;
7070
7071         return;
7072      end if;
7073
7074      --  We now intend to climb up the tree to find the right point to
7075      --  insert the actions. We start at Assoc_Node, unless this node is a
7076      --  subexpression in which case we start with its parent. We do this for
7077      --  two reasons. First it speeds things up. Second, if Assoc_Node is
7078      --  itself one of the special nodes like N_And_Then, then we assume that
7079      --  an initial request to insert actions for such a node does not expect
7080      --  the actions to get deposited in the node for later handling when the
7081      --  node is expanded, since clearly the node is being dealt with by the
7082      --  caller. Note that in the subexpression case, N is always the child we
7083      --  came from.
7084
7085      --  N_Raise_xxx_Error is an annoying special case, it is a statement
7086      --  if it has type Standard_Void_Type, and a subexpression otherwise.
7087      --  Procedure calls, and similarly procedure attribute references, are
7088      --  also statements.
7089
7090      if Nkind (Assoc_Node) in N_Subexpr
7091        and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
7092                   or else Etype (Assoc_Node) /= Standard_Void_Type)
7093        and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
7094        and then (Nkind (Assoc_Node) /= N_Attribute_Reference
7095                   or else not Is_Procedure_Attribute_Name
7096                                 (Attribute_Name (Assoc_Node)))
7097      then
7098         N := Assoc_Node;
7099         P := Parent (Assoc_Node);
7100
7101      --  Nonsubexpression case. Note that N is initially Empty in this case
7102      --  (N is only guaranteed non-Empty in the subexpr case).
7103
7104      else
7105         N := Empty;
7106         P := Assoc_Node;
7107      end if;
7108
7109      --  Capture root of the transient scope
7110
7111      if Scope_Is_Transient then
7112         Wrapped_Node := Node_To_Be_Wrapped;
7113      end if;
7114
7115      loop
7116         pragma Assert (Present (P));
7117
7118         --  Make sure that inserted actions stay in the transient scope
7119
7120         if Present (Wrapped_Node) and then N = Wrapped_Node then
7121            Store_Before_Actions_In_Scope (Ins_Actions);
7122            return;
7123         end if;
7124
7125         case Nkind (P) is
7126
7127            --  Case of right operand of AND THEN or OR ELSE. Put the actions
7128            --  in the Actions field of the right operand. They will be moved
7129            --  out further when the AND THEN or OR ELSE operator is expanded.
7130            --  Nothing special needs to be done for the left operand since
7131            --  in that case the actions are executed unconditionally.
7132
7133            when N_Short_Circuit =>
7134               if N = Right_Opnd (P) then
7135
7136                  --  We are now going to either append the actions to the
7137                  --  actions field of the short-circuit operation. We will
7138                  --  also analyze the actions now.
7139
7140                  --  This analysis is really too early, the proper thing would
7141                  --  be to just park them there now, and only analyze them if
7142                  --  we find we really need them, and to it at the proper
7143                  --  final insertion point. However attempting to this proved
7144                  --  tricky, so for now we just kill current values before and
7145                  --  after the analyze call to make sure we avoid peculiar
7146                  --  optimizations from this out of order insertion.
7147
7148                  Kill_Current_Values;
7149
7150                  --  If P has already been expanded, we can't park new actions
7151                  --  on it, so we need to expand them immediately, introducing
7152                  --  an Expression_With_Actions. N can't be an expression
7153                  --  with actions, or else then the actions would have been
7154                  --  inserted at an inner level.
7155
7156                  if Analyzed (P) then
7157                     pragma Assert (Nkind (N) /= N_Expression_With_Actions);
7158                     Rewrite (N,
7159                       Make_Expression_With_Actions (Sloc (N),
7160                         Actions    => Ins_Actions,
7161                         Expression => Relocate_Node (N)));
7162                     Analyze_And_Resolve (N);
7163
7164                  elsif Present (Actions (P)) then
7165                     Insert_List_After_And_Analyze
7166                       (Last (Actions (P)), Ins_Actions);
7167                  else
7168                     Set_Actions (P, Ins_Actions);
7169                     Analyze_List (Actions (P));
7170                  end if;
7171
7172                  Kill_Current_Values;
7173
7174                  return;
7175               end if;
7176
7177            --  Then or Else dependent expression of an if expression. Add
7178            --  actions to Then_Actions or Else_Actions field as appropriate.
7179            --  The actions will be moved further out when the if is expanded.
7180
7181            when N_If_Expression =>
7182               declare
7183                  ThenX : constant Node_Id := Next (First (Expressions (P)));
7184                  ElseX : constant Node_Id := Next (ThenX);
7185
7186               begin
7187                  --  If the enclosing expression is already analyzed, as
7188                  --  is the case for nested elaboration checks, insert the
7189                  --  conditional further out.
7190
7191                  if Analyzed (P) then
7192                     null;
7193
7194                  --  Actions belong to the then expression, temporarily place
7195                  --  them as Then_Actions of the if expression. They will be
7196                  --  moved to the proper place later when the if expression
7197                  --  is expanded.
7198
7199                  elsif N = ThenX then
7200                     if Present (Then_Actions (P)) then
7201                        Insert_List_After_And_Analyze
7202                          (Last (Then_Actions (P)), Ins_Actions);
7203                     else
7204                        Set_Then_Actions (P, Ins_Actions);
7205                        Analyze_List (Then_Actions (P));
7206                     end if;
7207
7208                     return;
7209
7210                  --  Actions belong to the else expression, temporarily place
7211                  --  them as Else_Actions of the if expression. They will be
7212                  --  moved to the proper place later when the if expression
7213                  --  is expanded.
7214
7215                  elsif N = ElseX then
7216                     if Present (Else_Actions (P)) then
7217                        Insert_List_After_And_Analyze
7218                          (Last (Else_Actions (P)), Ins_Actions);
7219                     else
7220                        Set_Else_Actions (P, Ins_Actions);
7221                        Analyze_List (Else_Actions (P));
7222                     end if;
7223
7224                     return;
7225
7226                  --  Actions belong to the condition. In this case they are
7227                  --  unconditionally executed, and so we can continue the
7228                  --  search for the proper insert point.
7229
7230                  else
7231                     null;
7232                  end if;
7233               end;
7234
7235            --  Alternative of case expression, we place the action in the
7236            --  Actions field of the case expression alternative, this will
7237            --  be handled when the case expression is expanded.
7238
7239            when N_Case_Expression_Alternative =>
7240               if Present (Actions (P)) then
7241                  Insert_List_After_And_Analyze
7242                    (Last (Actions (P)), Ins_Actions);
7243               else
7244                  Set_Actions (P, Ins_Actions);
7245                  Analyze_List (Actions (P));
7246               end if;
7247
7248               return;
7249
7250            --  Case of appearing within an Expressions_With_Actions node. When
7251            --  the new actions come from the expression of the expression with
7252            --  actions, they must be added to the existing actions. The other
7253            --  alternative is when the new actions are related to one of the
7254            --  existing actions of the expression with actions, and should
7255            --  never reach here: if actions are inserted on a statement
7256            --  within the Actions of an expression with actions, or on some
7257            --  subexpression of such a statement, then the outermost proper
7258            --  insertion point is right before the statement, and we should
7259            --  never climb up as far as the N_Expression_With_Actions itself.
7260
7261            when N_Expression_With_Actions =>
7262               if N = Expression (P) then
7263                  if Is_Empty_List (Actions (P)) then
7264                     Append_List_To (Actions (P), Ins_Actions);
7265                     Analyze_List (Actions (P));
7266                  else
7267                     Insert_List_After_And_Analyze
7268                       (Last (Actions (P)), Ins_Actions);
7269                  end if;
7270
7271                  return;
7272
7273               else
7274                  raise Program_Error;
7275               end if;
7276
7277            --  Case of appearing in the condition of a while expression or
7278            --  elsif. We insert the actions into the Condition_Actions field.
7279            --  They will be moved further out when the while loop or elsif
7280            --  is analyzed.
7281
7282            when N_Elsif_Part
7283               | N_Iteration_Scheme
7284            =>
7285               if N = Condition (P) then
7286                  if Present (Condition_Actions (P)) then
7287                     Insert_List_After_And_Analyze
7288                       (Last (Condition_Actions (P)), Ins_Actions);
7289                  else
7290                     Set_Condition_Actions (P, Ins_Actions);
7291
7292                     --  Set the parent of the insert actions explicitly. This
7293                     --  is not a syntactic field, but we need the parent field
7294                     --  set, in particular so that freeze can understand that
7295                     --  it is dealing with condition actions, and properly
7296                     --  insert the freezing actions.
7297
7298                     Set_Parent (Ins_Actions, P);
7299                     Analyze_List (Condition_Actions (P));
7300                  end if;
7301
7302                  return;
7303               end if;
7304
7305            --  Statements, declarations, pragmas, representation clauses
7306
7307            when
7308               --  Statements
7309
7310                 N_Procedure_Call_Statement
7311               | N_Statement_Other_Than_Procedure_Call
7312
7313               --  Pragmas
7314
7315               | N_Pragma
7316
7317               --  Representation_Clause
7318
7319               | N_At_Clause
7320               | N_Attribute_Definition_Clause
7321               | N_Enumeration_Representation_Clause
7322               | N_Record_Representation_Clause
7323
7324               --  Declarations
7325
7326               | N_Abstract_Subprogram_Declaration
7327               | N_Entry_Body
7328               | N_Exception_Declaration
7329               | N_Exception_Renaming_Declaration
7330               | N_Expression_Function
7331               | N_Formal_Abstract_Subprogram_Declaration
7332               | N_Formal_Concrete_Subprogram_Declaration
7333               | N_Formal_Object_Declaration
7334               | N_Formal_Type_Declaration
7335               | N_Full_Type_Declaration
7336               | N_Function_Instantiation
7337               | N_Generic_Function_Renaming_Declaration
7338               | N_Generic_Package_Declaration
7339               | N_Generic_Package_Renaming_Declaration
7340               | N_Generic_Procedure_Renaming_Declaration
7341               | N_Generic_Subprogram_Declaration
7342               | N_Implicit_Label_Declaration
7343               | N_Incomplete_Type_Declaration
7344               | N_Number_Declaration
7345               | N_Object_Declaration
7346               | N_Object_Renaming_Declaration
7347               | N_Package_Body
7348               | N_Package_Body_Stub
7349               | N_Package_Declaration
7350               | N_Package_Instantiation
7351               | N_Package_Renaming_Declaration
7352               | N_Private_Extension_Declaration
7353               | N_Private_Type_Declaration
7354               | N_Procedure_Instantiation
7355               | N_Protected_Body
7356               | N_Protected_Body_Stub
7357               | N_Single_Task_Declaration
7358               | N_Subprogram_Body
7359               | N_Subprogram_Body_Stub
7360               | N_Subprogram_Declaration
7361               | N_Subprogram_Renaming_Declaration
7362               | N_Subtype_Declaration
7363               | N_Task_Body
7364               | N_Task_Body_Stub
7365
7366               --  Use clauses can appear in lists of declarations
7367
7368               | N_Use_Package_Clause
7369               | N_Use_Type_Clause
7370
7371               --  Freeze entity behaves like a declaration or statement
7372
7373               | N_Freeze_Entity
7374               | N_Freeze_Generic_Entity
7375            =>
7376               --  Do not insert here if the item is not a list member (this
7377               --  happens for example with a triggering statement, and the
7378               --  proper approach is to insert before the entire select).
7379
7380               if not Is_List_Member (P) then
7381                  null;
7382
7383               --  Do not insert if parent of P is an N_Component_Association
7384               --  node (i.e. we are in the context of an N_Aggregate or
7385               --  N_Extension_Aggregate node. In this case we want to insert
7386               --  before the entire aggregate.
7387
7388               elsif Nkind (Parent (P)) = N_Component_Association then
7389                  null;
7390
7391               --  Do not insert if the parent of P is either an N_Variant node
7392               --  or an N_Record_Definition node, meaning in either case that
7393               --  P is a member of a component list, and that therefore the
7394               --  actions should be inserted outside the complete record
7395               --  declaration.
7396
7397               elsif Nkind (Parent (P)) in N_Variant | N_Record_Definition then
7398                  null;
7399
7400               --  Do not insert freeze nodes within the loop generated for
7401               --  an aggregate, because they may be elaborated too late for
7402               --  subsequent use in the back end: within a package spec the
7403               --  loop is part of the elaboration procedure and is only
7404               --  elaborated during the second pass.
7405
7406               --  If the loop comes from source, or the entity is local to the
7407               --  loop itself it must remain within.
7408
7409               elsif Nkind (Parent (P)) = N_Loop_Statement
7410                 and then not Comes_From_Source (Parent (P))
7411                 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
7412                 and then
7413                   Scope (Entity (First (Ins_Actions))) /= Current_Scope
7414               then
7415                  null;
7416
7417               --  Otherwise we can go ahead and do the insertion
7418
7419               elsif P = Wrapped_Node then
7420                  Store_Before_Actions_In_Scope (Ins_Actions);
7421                  return;
7422
7423               else
7424                  Insert_List_Before_And_Analyze (P, Ins_Actions);
7425                  return;
7426               end if;
7427
7428            --  the expansion of Task and protected type declarations can
7429            --  create declarations for temporaries which, like other actions
7430            --  are inserted and analyzed before the current declaraation.
7431            --  However, the current scope is the synchronized type, and
7432            --  for unnesting it is critical that the proper scope for these
7433            --  generated entities be the enclosing one.
7434
7435            when N_Task_Type_Declaration
7436               | N_Protected_Type_Declaration =>
7437
7438               Push_Scope (Scope (Current_Scope));
7439               Insert_List_Before_And_Analyze (P, Ins_Actions);
7440               Pop_Scope;
7441               return;
7442
7443            --  A special case, N_Raise_xxx_Error can act either as a statement
7444            --  or a subexpression. We tell the difference by looking at the
7445            --  Etype. It is set to Standard_Void_Type in the statement case.
7446
7447            when N_Raise_xxx_Error =>
7448               if Etype (P) = Standard_Void_Type then
7449                  if P = Wrapped_Node then
7450                     Store_Before_Actions_In_Scope (Ins_Actions);
7451                  else
7452                     Insert_List_Before_And_Analyze (P, Ins_Actions);
7453                  end if;
7454
7455                  return;
7456
7457               --  In the subexpression case, keep climbing
7458
7459               else
7460                  null;
7461               end if;
7462
7463            --  If a component association appears within a loop created for
7464            --  an array aggregate, attach the actions to the association so
7465            --  they can be subsequently inserted within the loop. For other
7466            --  component associations insert outside of the aggregate. For
7467            --  an association that will generate a loop, its Loop_Actions
7468            --  attribute is already initialized (see exp_aggr.adb).
7469
7470            --  The list of Loop_Actions can in turn generate additional ones,
7471            --  that are inserted before the associated node. If the associated
7472            --  node is outside the aggregate, the new actions are collected
7473            --  at the end of the Loop_Actions, to respect the order in which
7474            --  they are to be elaborated.
7475
7476            when N_Component_Association
7477               | N_Iterated_Component_Association
7478               | N_Iterated_Element_Association
7479            =>
7480               if Nkind (Parent (P)) = N_Aggregate
7481                 and then Present (Loop_Actions (P))
7482               then
7483                  if Is_Empty_List (Loop_Actions (P)) then
7484                     Set_Loop_Actions (P, Ins_Actions);
7485                     Analyze_List (Ins_Actions);
7486                  else
7487                     declare
7488                        Decl : Node_Id;
7489
7490                     begin
7491                        --  Check whether these actions were generated by a
7492                        --  declaration that is part of the Loop_Actions for
7493                        --  the component_association.
7494
7495                        Decl := Assoc_Node;
7496                        while Present (Decl) loop
7497                           exit when Parent (Decl) = P
7498                             and then Is_List_Member (Decl)
7499                             and then
7500                               List_Containing (Decl) = Loop_Actions (P);
7501                           Decl := Parent (Decl);
7502                        end loop;
7503
7504                        if Present (Decl) then
7505                           Insert_List_Before_And_Analyze
7506                             (Decl, Ins_Actions);
7507                        else
7508                           Insert_List_After_And_Analyze
7509                             (Last (Loop_Actions (P)), Ins_Actions);
7510                        end if;
7511                     end;
7512                  end if;
7513
7514                  return;
7515
7516               else
7517                  null;
7518               end if;
7519
7520            --  Special case: an attribute denoting a procedure call
7521
7522            when N_Attribute_Reference =>
7523               if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
7524                  if P = Wrapped_Node then
7525                     Store_Before_Actions_In_Scope (Ins_Actions);
7526                  else
7527                     Insert_List_Before_And_Analyze (P, Ins_Actions);
7528                  end if;
7529
7530                  return;
7531
7532               --  In the subexpression case, keep climbing
7533
7534               else
7535                  null;
7536               end if;
7537
7538            --  Special case: a marker
7539
7540            when N_Call_Marker
7541               | N_Variable_Reference_Marker
7542            =>
7543               if Is_List_Member (P) then
7544                  Insert_List_Before_And_Analyze (P, Ins_Actions);
7545                  return;
7546               end if;
7547
7548            --  A contract node should not belong to the tree
7549
7550            when N_Contract =>
7551               raise Program_Error;
7552
7553            --  For all other node types, keep climbing tree
7554
7555            when N_Abortable_Part
7556               | N_Accept_Alternative
7557               | N_Access_Definition
7558               | N_Access_Function_Definition
7559               | N_Access_Procedure_Definition
7560               | N_Access_To_Object_Definition
7561               | N_Aggregate
7562               | N_Allocator
7563               | N_Aspect_Specification
7564               | N_Case_Expression
7565               | N_Case_Statement_Alternative
7566               | N_Character_Literal
7567               | N_Compilation_Unit
7568               | N_Compilation_Unit_Aux
7569               | N_Component_Clause
7570               | N_Component_Declaration
7571               | N_Component_Definition
7572               | N_Component_List
7573               | N_Constrained_Array_Definition
7574               | N_Decimal_Fixed_Point_Definition
7575               | N_Defining_Character_Literal
7576               | N_Defining_Identifier
7577               | N_Defining_Operator_Symbol
7578               | N_Defining_Program_Unit_Name
7579               | N_Delay_Alternative
7580               | N_Delta_Aggregate
7581               | N_Delta_Constraint
7582               | N_Derived_Type_Definition
7583               | N_Designator
7584               | N_Digits_Constraint
7585               | N_Discriminant_Association
7586               | N_Discriminant_Specification
7587               | N_Empty
7588               | N_Entry_Body_Formal_Part
7589               | N_Entry_Call_Alternative
7590               | N_Entry_Declaration
7591               | N_Entry_Index_Specification
7592               | N_Enumeration_Type_Definition
7593               | N_Error
7594               | N_Exception_Handler
7595               | N_Expanded_Name
7596               | N_Explicit_Dereference
7597               | N_Extension_Aggregate
7598               | N_Floating_Point_Definition
7599               | N_Formal_Decimal_Fixed_Point_Definition
7600               | N_Formal_Derived_Type_Definition
7601               | N_Formal_Discrete_Type_Definition
7602               | N_Formal_Floating_Point_Definition
7603               | N_Formal_Modular_Type_Definition
7604               | N_Formal_Ordinary_Fixed_Point_Definition
7605               | N_Formal_Package_Declaration
7606               | N_Formal_Private_Type_Definition
7607               | N_Formal_Incomplete_Type_Definition
7608               | N_Formal_Signed_Integer_Type_Definition
7609               | N_Function_Call
7610               | N_Function_Specification
7611               | N_Generic_Association
7612               | N_Handled_Sequence_Of_Statements
7613               | N_Identifier
7614               | N_In
7615               | N_Index_Or_Discriminant_Constraint
7616               | N_Indexed_Component
7617               | N_Integer_Literal
7618               | N_Iterator_Specification
7619               | N_Itype_Reference
7620               | N_Label
7621               | N_Loop_Parameter_Specification
7622               | N_Mod_Clause
7623               | N_Modular_Type_Definition
7624               | N_Not_In
7625               | N_Null
7626               | N_Op_Abs
7627               | N_Op_Add
7628               | N_Op_And
7629               | N_Op_Concat
7630               | N_Op_Divide
7631               | N_Op_Eq
7632               | N_Op_Expon
7633               | N_Op_Ge
7634               | N_Op_Gt
7635               | N_Op_Le
7636               | N_Op_Lt
7637               | N_Op_Minus
7638               | N_Op_Mod
7639               | N_Op_Multiply
7640               | N_Op_Ne
7641               | N_Op_Not
7642               | N_Op_Or
7643               | N_Op_Plus
7644               | N_Op_Rem
7645               | N_Op_Rotate_Left
7646               | N_Op_Rotate_Right
7647               | N_Op_Shift_Left
7648               | N_Op_Shift_Right
7649               | N_Op_Shift_Right_Arithmetic
7650               | N_Op_Subtract
7651               | N_Op_Xor
7652               | N_Operator_Symbol
7653               | N_Ordinary_Fixed_Point_Definition
7654               | N_Others_Choice
7655               | N_Package_Specification
7656               | N_Parameter_Association
7657               | N_Parameter_Specification
7658               | N_Pop_Constraint_Error_Label
7659               | N_Pop_Program_Error_Label
7660               | N_Pop_Storage_Error_Label
7661               | N_Pragma_Argument_Association
7662               | N_Procedure_Specification
7663               | N_Protected_Definition
7664               | N_Push_Constraint_Error_Label
7665               | N_Push_Program_Error_Label
7666               | N_Push_Storage_Error_Label
7667               | N_Qualified_Expression
7668               | N_Quantified_Expression
7669               | N_Raise_Expression
7670               | N_Range
7671               | N_Range_Constraint
7672               | N_Real_Literal
7673               | N_Real_Range_Specification
7674               | N_Record_Definition
7675               | N_Reference
7676               | N_SCIL_Dispatch_Table_Tag_Init
7677               | N_SCIL_Dispatching_Call
7678               | N_SCIL_Membership_Test
7679               | N_Selected_Component
7680               | N_Signed_Integer_Type_Definition
7681               | N_Single_Protected_Declaration
7682               | N_Slice
7683               | N_String_Literal
7684               | N_Subtype_Indication
7685               | N_Subunit
7686               | N_Target_Name
7687               | N_Task_Definition
7688               | N_Terminate_Alternative
7689               | N_Triggering_Alternative
7690               | N_Type_Conversion
7691               | N_Unchecked_Expression
7692               | N_Unchecked_Type_Conversion
7693               | N_Unconstrained_Array_Definition
7694               | N_Unused_At_End
7695               | N_Unused_At_Start
7696               | N_Variant
7697               | N_Variant_Part
7698               | N_Validate_Unchecked_Conversion
7699               | N_With_Clause
7700            =>
7701               null;
7702         end case;
7703
7704         --  If we fall through above tests, keep climbing tree
7705
7706         N := P;
7707
7708         if Nkind (Parent (N)) = N_Subunit then
7709
7710            --  This is the proper body corresponding to a stub. Insertion must
7711            --  be done at the point of the stub, which is in the declarative
7712            --  part of the parent unit.
7713
7714            P := Corresponding_Stub (Parent (N));
7715
7716         else
7717            P := Parent (N);
7718         end if;
7719      end loop;
7720   end Insert_Actions;
7721
7722   --  Version with check(s) suppressed
7723
7724   procedure Insert_Actions
7725     (Assoc_Node   : Node_Id;
7726      Ins_Actions  : List_Id;
7727      Suppress     : Check_Id;
7728      Spec_Expr_OK : Boolean := False)
7729   is
7730   begin
7731      if Suppress = All_Checks then
7732         declare
7733            Sva : constant Suppress_Array := Scope_Suppress.Suppress;
7734         begin
7735            Scope_Suppress.Suppress := (others => True);
7736            Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
7737            Scope_Suppress.Suppress := Sva;
7738         end;
7739
7740      else
7741         declare
7742            Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
7743         begin
7744            Scope_Suppress.Suppress (Suppress) := True;
7745            Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
7746            Scope_Suppress.Suppress (Suppress) := Svg;
7747         end;
7748      end if;
7749   end Insert_Actions;
7750
7751   --------------------------
7752   -- Insert_Actions_After --
7753   --------------------------
7754
7755   procedure Insert_Actions_After
7756     (Assoc_Node  : Node_Id;
7757      Ins_Actions : List_Id)
7758   is
7759   begin
7760      if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then
7761         Store_After_Actions_In_Scope (Ins_Actions);
7762      else
7763         Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
7764      end if;
7765   end Insert_Actions_After;
7766
7767   ------------------------
7768   -- Insert_Declaration --
7769   ------------------------
7770
7771   procedure Insert_Declaration (N : Node_Id; Decl : Node_Id) is
7772      P : Node_Id;
7773
7774   begin
7775      pragma Assert (Nkind (N) in N_Subexpr);
7776
7777      --  Climb until we find a procedure or a package
7778
7779      P := N;
7780      loop
7781         pragma Assert (Present (Parent (P)));
7782         P := Parent (P);
7783
7784         if Is_List_Member (P) then
7785            exit when Nkind (Parent (P)) in
7786                        N_Package_Specification | N_Subprogram_Body;
7787
7788            --  Special handling for handled sequence of statements, we must
7789            --  insert in the statements not the exception handlers!
7790
7791            if Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements then
7792               P := First (Statements (Parent (P)));
7793               exit;
7794            end if;
7795         end if;
7796      end loop;
7797
7798      --  Now do the insertion
7799
7800      Insert_Before (P, Decl);
7801      Analyze (Decl);
7802   end Insert_Declaration;
7803
7804   ---------------------------------
7805   -- Insert_Library_Level_Action --
7806   ---------------------------------
7807
7808   procedure Insert_Library_Level_Action (N : Node_Id) is
7809      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
7810
7811   begin
7812      Push_Scope (Cunit_Entity (Current_Sem_Unit));
7813      --  And not Main_Unit as previously. If the main unit is a body,
7814      --  the scope needed to analyze the actions is the entity of the
7815      --  corresponding declaration.
7816
7817      if No (Actions (Aux)) then
7818         Set_Actions (Aux, New_List (N));
7819      else
7820         Append (N, Actions (Aux));
7821      end if;
7822
7823      Analyze (N);
7824      Pop_Scope;
7825   end Insert_Library_Level_Action;
7826
7827   ----------------------------------
7828   -- Insert_Library_Level_Actions --
7829   ----------------------------------
7830
7831   procedure Insert_Library_Level_Actions (L : List_Id) is
7832      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
7833
7834   begin
7835      if Is_Non_Empty_List (L) then
7836         Push_Scope (Cunit_Entity (Main_Unit));
7837         --  ??? should this be Current_Sem_Unit instead of Main_Unit?
7838
7839         if No (Actions (Aux)) then
7840            Set_Actions (Aux, L);
7841            Analyze_List (L);
7842         else
7843            Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
7844         end if;
7845
7846         Pop_Scope;
7847      end if;
7848   end Insert_Library_Level_Actions;
7849
7850   ----------------------
7851   -- Inside_Init_Proc --
7852   ----------------------
7853
7854   function Inside_Init_Proc return Boolean is
7855      Proc : constant Entity_Id := Enclosing_Init_Proc;
7856
7857   begin
7858      return Proc /= Empty;
7859   end Inside_Init_Proc;
7860
7861   ----------------------
7862   -- Integer_Type_For --
7863   ----------------------
7864
7865   function Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id is
7866   begin
7867      pragma Assert (S <= System_Max_Integer_Size);
7868
7869      --  This is the canonical 32-bit type
7870
7871      if S <= Standard_Integer_Size then
7872         if Uns then
7873            return Standard_Unsigned;
7874         else
7875            return Standard_Integer;
7876         end if;
7877
7878      --  This is the canonical 64-bit type
7879
7880      elsif S <= Standard_Long_Long_Integer_Size then
7881         if Uns then
7882            return Standard_Long_Long_Unsigned;
7883         else
7884            return Standard_Long_Long_Integer;
7885         end if;
7886
7887      --  This is the canonical 128-bit type
7888
7889      elsif S <= Standard_Long_Long_Long_Integer_Size then
7890         if Uns then
7891            return Standard_Long_Long_Long_Unsigned;
7892         else
7893            return Standard_Long_Long_Long_Integer;
7894         end if;
7895
7896      else
7897         raise Program_Error;
7898      end if;
7899   end Integer_Type_For;
7900
7901   --------------------------------------------------
7902   -- Is_Displacement_Of_Object_Or_Function_Result --
7903   --------------------------------------------------
7904
7905   function Is_Displacement_Of_Object_Or_Function_Result
7906     (Obj_Id : Entity_Id) return Boolean
7907   is
7908      function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
7909      --  Determine whether node N denotes a controlled function call
7910
7911      function Is_Controlled_Indexing (N : Node_Id) return Boolean;
7912      --  Determine whether node N denotes a generalized indexing form which
7913      --  involves a controlled result.
7914
7915      function Is_Displace_Call (N : Node_Id) return Boolean;
7916      --  Determine whether node N denotes a call to Ada.Tags.Displace
7917
7918      function Is_Source_Object (N : Node_Id) return Boolean;
7919      --  Determine whether a particular node denotes a source object
7920
7921      function Strip (N : Node_Id) return Node_Id;
7922      --  Examine arbitrary node N by stripping various indirections and return
7923      --  the "real" node.
7924
7925      ---------------------------------
7926      -- Is_Controlled_Function_Call --
7927      ---------------------------------
7928
7929      function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
7930         Expr : Node_Id;
7931
7932      begin
7933         --  When a function call appears in Object.Operation format, the
7934         --  original representation has several possible forms depending on
7935         --  the availability and form of actual parameters:
7936
7937         --    Obj.Func                    N_Selected_Component
7938         --    Obj.Func (Actual)           N_Indexed_Component
7939         --    Obj.Func (Formal => Actual) N_Function_Call, whose Name is an
7940         --                                N_Selected_Component
7941
7942         Expr := Original_Node (N);
7943         loop
7944            if Nkind (Expr) = N_Function_Call then
7945               Expr := Name (Expr);
7946
7947            --  "Obj.Func (Actual)" case
7948
7949            elsif Nkind (Expr) = N_Indexed_Component then
7950               Expr := Prefix (Expr);
7951
7952            --  "Obj.Func" or "Obj.Func (Formal => Actual) case
7953
7954            elsif Nkind (Expr) = N_Selected_Component then
7955               Expr := Selector_Name (Expr);
7956
7957            else
7958               exit;
7959            end if;
7960         end loop;
7961
7962         return
7963           Nkind (Expr) in N_Has_Entity
7964             and then Present (Entity (Expr))
7965             and then Ekind (Entity (Expr)) = E_Function
7966             and then Needs_Finalization (Etype (Entity (Expr)));
7967      end Is_Controlled_Function_Call;
7968
7969      ----------------------------
7970      -- Is_Controlled_Indexing --
7971      ----------------------------
7972
7973      function Is_Controlled_Indexing (N : Node_Id) return Boolean is
7974         Expr : constant Node_Id := Original_Node (N);
7975
7976      begin
7977         return
7978           Nkind (Expr) = N_Indexed_Component
7979             and then Present (Generalized_Indexing (Expr))
7980             and then Needs_Finalization (Etype (Expr));
7981      end Is_Controlled_Indexing;
7982
7983      ----------------------
7984      -- Is_Displace_Call --
7985      ----------------------
7986
7987      function Is_Displace_Call (N : Node_Id) return Boolean is
7988         Call : constant Node_Id := Strip (N);
7989
7990      begin
7991         return
7992           Present (Call)
7993             and then Nkind (Call) = N_Function_Call
7994             and then Nkind (Name (Call)) in N_Has_Entity
7995             and then Is_RTE (Entity (Name (Call)), RE_Displace);
7996      end Is_Displace_Call;
7997
7998      ----------------------
7999      -- Is_Source_Object --
8000      ----------------------
8001
8002      function Is_Source_Object (N : Node_Id) return Boolean is
8003         Obj : constant Node_Id := Strip (N);
8004
8005      begin
8006         return
8007           Present (Obj)
8008             and then Comes_From_Source (Obj)
8009             and then Nkind (Obj) in N_Has_Entity
8010             and then Is_Object (Entity (Obj));
8011      end Is_Source_Object;
8012
8013      -----------
8014      -- Strip --
8015      -----------
8016
8017      function Strip (N : Node_Id) return Node_Id is
8018         Result : Node_Id;
8019
8020      begin
8021         Result := N;
8022         loop
8023            if Nkind (Result) = N_Explicit_Dereference then
8024               Result := Prefix (Result);
8025
8026            elsif Nkind (Result) in
8027                    N_Type_Conversion | N_Unchecked_Type_Conversion
8028            then
8029               Result := Expression (Result);
8030
8031            else
8032               exit;
8033            end if;
8034         end loop;
8035
8036         return Result;
8037      end Strip;
8038
8039      --  Local variables
8040
8041      Obj_Decl  : constant Node_Id   := Declaration_Node (Obj_Id);
8042      Obj_Typ   : constant Entity_Id := Base_Type (Etype (Obj_Id));
8043      Orig_Decl : constant Node_Id   := Original_Node (Obj_Decl);
8044      Orig_Expr : Node_Id;
8045
8046   --  Start of processing for Is_Displacement_Of_Object_Or_Function_Result
8047
8048   begin
8049      --  Case 1:
8050
8051      --     Obj : CW_Type := Function_Call (...);
8052
8053      --  is rewritten into:
8054
8055      --     Temp : ... := Function_Call (...)'reference;
8056      --     Obj  : CW_Type renames (... Ada.Tags.Displace (Temp));
8057
8058      --  where the return type of the function and the class-wide type require
8059      --  dispatch table pointer displacement.
8060
8061      --  Case 2:
8062
8063      --     Obj : CW_Type := Container (...);
8064
8065      --  is rewritten into:
8066
8067      --     Temp : ... := Function_Call (Container, ...)'reference;
8068      --     Obj  : CW_Type renames (... Ada.Tags.Displace (Temp));
8069
8070      --  where the container element type and the class-wide type require
8071      --  dispatch table pointer dispacement.
8072
8073      --  Case 3:
8074
8075      --     Obj : CW_Type := Src_Obj;
8076
8077      --  is rewritten into:
8078
8079      --     Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
8080
8081      --  where the type of the source object and the class-wide type require
8082      --  dispatch table pointer displacement.
8083
8084      if Nkind (Obj_Decl) = N_Object_Renaming_Declaration
8085        and then Is_Class_Wide_Type (Obj_Typ)
8086        and then Is_Displace_Call (Renamed_Object (Obj_Id))
8087        and then Nkind (Orig_Decl) = N_Object_Declaration
8088        and then Comes_From_Source (Orig_Decl)
8089      then
8090         Orig_Expr := Expression (Orig_Decl);
8091
8092         return
8093           Is_Controlled_Function_Call (Orig_Expr)
8094             or else Is_Controlled_Indexing (Orig_Expr)
8095             or else Is_Source_Object (Orig_Expr);
8096      end if;
8097
8098      return False;
8099   end Is_Displacement_Of_Object_Or_Function_Result;
8100
8101   ------------------------------
8102   -- Is_Finalizable_Transient --
8103   ------------------------------
8104
8105   function Is_Finalizable_Transient
8106     (Decl     : Node_Id;
8107      Rel_Node : Node_Id) return Boolean
8108   is
8109      Obj_Id  : constant Entity_Id := Defining_Identifier (Decl);
8110      Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
8111
8112      function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
8113      --  Determine whether transient object Trans_Id is initialized either
8114      --  by a function call which returns an access type or simply renames
8115      --  another pointer.
8116
8117      function Initialized_By_Aliased_BIP_Func_Call
8118        (Trans_Id : Entity_Id) return Boolean;
8119      --  Determine whether transient object Trans_Id is initialized by a
8120      --  build-in-place function call where the BIPalloc parameter is of
8121      --  value 1 and BIPaccess is not null. This case creates an aliasing
8122      --  between the returned value and the value denoted by BIPaccess.
8123
8124      function Is_Aliased
8125        (Trans_Id   : Entity_Id;
8126         First_Stmt : Node_Id) return Boolean;
8127      --  Determine whether transient object Trans_Id has been renamed or
8128      --  aliased through 'reference in the statement list starting from
8129      --  First_Stmt.
8130
8131      function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
8132      --  Determine whether transient object Trans_Id is allocated on the heap
8133
8134      function Is_Iterated_Container
8135        (Trans_Id   : Entity_Id;
8136         First_Stmt : Node_Id) return Boolean;
8137      --  Determine whether transient object Trans_Id denotes a container which
8138      --  is in the process of being iterated in the statement list starting
8139      --  from First_Stmt.
8140
8141      function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean;
8142      --  Return True if N is directly part of a build-in-place return
8143      --  statement.
8144
8145      ---------------------------
8146      -- Initialized_By_Access --
8147      ---------------------------
8148
8149      function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
8150         Expr : constant Node_Id := Expression (Parent (Trans_Id));
8151
8152      begin
8153         return
8154           Present (Expr)
8155             and then Nkind (Expr) /= N_Reference
8156             and then Is_Access_Type (Etype (Expr));
8157      end Initialized_By_Access;
8158
8159      ------------------------------------------
8160      -- Initialized_By_Aliased_BIP_Func_Call --
8161      ------------------------------------------
8162
8163      function Initialized_By_Aliased_BIP_Func_Call
8164        (Trans_Id : Entity_Id) return Boolean
8165      is
8166         Call : Node_Id := Expression (Parent (Trans_Id));
8167
8168      begin
8169         --  Build-in-place calls usually appear in 'reference format
8170
8171         if Nkind (Call) = N_Reference then
8172            Call := Prefix (Call);
8173         end if;
8174
8175         Call := Unqual_Conv (Call);
8176
8177         if Is_Build_In_Place_Function_Call (Call) then
8178            declare
8179               Access_Nam : Name_Id := No_Name;
8180               Access_OK  : Boolean := False;
8181               Actual     : Node_Id;
8182               Alloc_Nam  : Name_Id := No_Name;
8183               Alloc_OK   : Boolean := False;
8184               Formal     : Node_Id;
8185               Func_Id    : Entity_Id;
8186               Param      : Node_Id;
8187
8188            begin
8189               --  Examine all parameter associations of the function call
8190
8191               Param := First (Parameter_Associations (Call));
8192               while Present (Param) loop
8193                  if Nkind (Param) = N_Parameter_Association
8194                    and then Nkind (Selector_Name (Param)) = N_Identifier
8195                  then
8196                     Actual := Explicit_Actual_Parameter (Param);
8197                     Formal := Selector_Name (Param);
8198
8199                     --  Construct the names of formals BIPaccess and BIPalloc
8200                     --  using the function name retrieved from an arbitrary
8201                     --  formal.
8202
8203                     if Access_Nam = No_Name
8204                       and then Alloc_Nam = No_Name
8205                       and then Present (Entity (Formal))
8206                     then
8207                        Func_Id := Scope (Entity (Formal));
8208
8209                        Access_Nam :=
8210                          New_External_Name (Chars (Func_Id),
8211                            BIP_Formal_Suffix (BIP_Object_Access));
8212
8213                        Alloc_Nam :=
8214                          New_External_Name (Chars (Func_Id),
8215                            BIP_Formal_Suffix (BIP_Alloc_Form));
8216                     end if;
8217
8218                     --  A match for BIPaccess => Temp has been found
8219
8220                     if Chars (Formal) = Access_Nam
8221                       and then Nkind (Actual) /= N_Null
8222                     then
8223                        Access_OK := True;
8224                     end if;
8225
8226                     --  A match for BIPalloc => 1 has been found
8227
8228                     if Chars (Formal) = Alloc_Nam
8229                       and then Nkind (Actual) = N_Integer_Literal
8230                       and then Intval (Actual) = Uint_1
8231                     then
8232                        Alloc_OK := True;
8233                     end if;
8234                  end if;
8235
8236                  Next (Param);
8237               end loop;
8238
8239               return Access_OK and Alloc_OK;
8240            end;
8241         end if;
8242
8243         return False;
8244      end Initialized_By_Aliased_BIP_Func_Call;
8245
8246      ----------------
8247      -- Is_Aliased --
8248      ----------------
8249
8250      function Is_Aliased
8251        (Trans_Id   : Entity_Id;
8252         First_Stmt : Node_Id) return Boolean
8253      is
8254         function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
8255         --  Given an object renaming declaration, retrieve the entity of the
8256         --  renamed name. Return Empty if the renamed name is anything other
8257         --  than a variable or a constant.
8258
8259         -------------------------
8260         -- Find_Renamed_Object --
8261         -------------------------
8262
8263         function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
8264            Ren_Obj : Node_Id := Empty;
8265
8266            function Find_Object (N : Node_Id) return Traverse_Result;
8267            --  Try to detect an object which is either a constant or a
8268            --  variable.
8269
8270            -----------------
8271            -- Find_Object --
8272            -----------------
8273
8274            function Find_Object (N : Node_Id) return Traverse_Result is
8275            begin
8276               --  Stop the search once a constant or a variable has been
8277               --  detected.
8278
8279               if Nkind (N) = N_Identifier
8280                 and then Present (Entity (N))
8281                 and then Ekind (Entity (N)) in E_Constant | E_Variable
8282               then
8283                  Ren_Obj := Entity (N);
8284                  return Abandon;
8285               end if;
8286
8287               return OK;
8288            end Find_Object;
8289
8290            procedure Search is new Traverse_Proc (Find_Object);
8291
8292            --  Local variables
8293
8294            Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
8295
8296         --  Start of processing for Find_Renamed_Object
8297
8298         begin
8299            --  Actions related to dispatching calls may appear as renamings of
8300            --  tags. Do not process this type of renaming because it does not
8301            --  use the actual value of the object.
8302
8303            if not Is_RTE (Typ, RE_Tag_Ptr) then
8304               Search (Name (Ren_Decl));
8305            end if;
8306
8307            return Ren_Obj;
8308         end Find_Renamed_Object;
8309
8310         --  Local variables
8311
8312         Expr    : Node_Id;
8313         Ren_Obj : Entity_Id;
8314         Stmt    : Node_Id;
8315
8316      --  Start of processing for Is_Aliased
8317
8318      begin
8319         --  A controlled transient object is not considered aliased when it
8320         --  appears inside an expression_with_actions node even when there are
8321         --  explicit aliases of it:
8322
8323         --    do
8324         --       Trans_Id : Ctrl_Typ ...;  --  transient object
8325         --       Alias : ... := Trans_Id;  --  object is aliased
8326         --       Val : constant Boolean :=
8327         --               ... Alias ...;    --  aliasing ends
8328         --       <finalize Trans_Id>       --  object safe to finalize
8329         --    in Val end;
8330
8331         --  Expansion ensures that all aliases are encapsulated in the actions
8332         --  list and do not leak to the expression by forcing the evaluation
8333         --  of the expression.
8334
8335         if Nkind (Rel_Node) = N_Expression_With_Actions then
8336            return False;
8337
8338         --  Otherwise examine the statements after the controlled transient
8339         --  object and look for various forms of aliasing.
8340
8341         else
8342            Stmt := First_Stmt;
8343            while Present (Stmt) loop
8344               if Nkind (Stmt) = N_Object_Declaration then
8345                  Expr := Expression (Stmt);
8346
8347                  --  Aliasing of the form:
8348                  --    Obj : ... := Trans_Id'reference;
8349
8350                  if Present (Expr)
8351                    and then Nkind (Expr) = N_Reference
8352                    and then Nkind (Prefix (Expr)) = N_Identifier
8353                    and then Entity (Prefix (Expr)) = Trans_Id
8354                  then
8355                     return True;
8356                  end if;
8357
8358               elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
8359                  Ren_Obj := Find_Renamed_Object (Stmt);
8360
8361                  --  Aliasing of the form:
8362                  --    Obj : ... renames ... Trans_Id ...;
8363
8364                  if Present (Ren_Obj) and then Ren_Obj = Trans_Id then
8365                     return True;
8366                  end if;
8367               end if;
8368
8369               Next (Stmt);
8370            end loop;
8371
8372            return False;
8373         end if;
8374      end Is_Aliased;
8375
8376      ------------------
8377      -- Is_Allocated --
8378      ------------------
8379
8380      function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
8381         Expr : constant Node_Id := Expression (Parent (Trans_Id));
8382      begin
8383         return
8384           Is_Access_Type (Etype (Trans_Id))
8385             and then Present (Expr)
8386             and then Nkind (Expr) = N_Allocator;
8387      end Is_Allocated;
8388
8389      ---------------------------
8390      -- Is_Iterated_Container --
8391      ---------------------------
8392
8393      function Is_Iterated_Container
8394        (Trans_Id   : Entity_Id;
8395         First_Stmt : Node_Id) return Boolean
8396      is
8397         Aspect : Node_Id;
8398         Call   : Node_Id;
8399         Iter   : Entity_Id;
8400         Param  : Node_Id;
8401         Stmt   : Node_Id;
8402         Typ    : Entity_Id;
8403
8404      begin
8405         --  It is not possible to iterate over containers in non-Ada 2012 code
8406
8407         if Ada_Version < Ada_2012 then
8408            return False;
8409         end if;
8410
8411         Typ := Etype (Trans_Id);
8412
8413         --  Handle access type created for secondary stack use
8414
8415         if Is_Access_Type (Typ) then
8416            Typ := Designated_Type (Typ);
8417         end if;
8418
8419         --  Look for aspect Default_Iterator. It may be part of a type
8420         --  declaration for a container, or inherited from a base type
8421         --  or parent type.
8422
8423         Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator);
8424
8425         if Present (Aspect) then
8426            Iter := Entity (Aspect);
8427
8428            --  Examine the statements following the container object and
8429            --  look for a call to the default iterate routine where the
8430            --  first parameter is the transient. Such a call appears as:
8431
8432            --     It : Access_To_CW_Iterator :=
8433            --            Iterate (Tran_Id.all, ...)'reference;
8434
8435            Stmt := First_Stmt;
8436            while Present (Stmt) loop
8437
8438               --  Detect an object declaration which is initialized by a
8439               --  secondary stack function call.
8440
8441               if Nkind (Stmt) = N_Object_Declaration
8442                 and then Present (Expression (Stmt))
8443                 and then Nkind (Expression (Stmt)) = N_Reference
8444                 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call
8445               then
8446                  Call := Prefix (Expression (Stmt));
8447
8448                  --  The call must invoke the default iterate routine of
8449                  --  the container and the transient object must appear as
8450                  --  the first actual parameter. Skip any calls whose names
8451                  --  are not entities.
8452
8453                  if Is_Entity_Name (Name (Call))
8454                    and then Entity (Name (Call)) = Iter
8455                    and then Present (Parameter_Associations (Call))
8456                  then
8457                     Param := First (Parameter_Associations (Call));
8458
8459                     if Nkind (Param) = N_Explicit_Dereference
8460                       and then Entity (Prefix (Param)) = Trans_Id
8461                     then
8462                        return True;
8463                     end if;
8464                  end if;
8465               end if;
8466
8467               Next (Stmt);
8468            end loop;
8469         end if;
8470
8471         return False;
8472      end Is_Iterated_Container;
8473
8474      -------------------------------------
8475      -- Is_Part_Of_BIP_Return_Statement --
8476      -------------------------------------
8477
8478      function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean is
8479         Subp    : constant Entity_Id := Current_Subprogram;
8480         Context : Node_Id;
8481      begin
8482         --  First check if N is part of a BIP function
8483
8484         if No (Subp)
8485           or else not Is_Build_In_Place_Function (Subp)
8486         then
8487            return False;
8488         end if;
8489
8490         --  Then check whether N is a complete part of a return statement
8491         --  Should we consider other node kinds to go up the tree???
8492
8493         Context := N;
8494         loop
8495            case Nkind (Context) is
8496               when N_Expression_With_Actions => Context := Parent (Context);
8497               when N_Simple_Return_Statement => return True;
8498               when others                    => return False;
8499            end case;
8500         end loop;
8501      end Is_Part_Of_BIP_Return_Statement;
8502
8503      --  Local variables
8504
8505      Desig : Entity_Id := Obj_Typ;
8506
8507   --  Start of processing for Is_Finalizable_Transient
8508
8509   begin
8510      --  Handle access types
8511
8512      if Is_Access_Type (Desig) then
8513         Desig := Available_View (Designated_Type (Desig));
8514      end if;
8515
8516      return
8517        Ekind (Obj_Id) in E_Constant | E_Variable
8518          and then Needs_Finalization (Desig)
8519          and then Requires_Transient_Scope (Desig)
8520          and then Nkind (Rel_Node) /= N_Simple_Return_Statement
8521          and then not Is_Part_Of_BIP_Return_Statement (Rel_Node)
8522
8523          --  Do not consider a transient object that was already processed
8524
8525          and then not Is_Finalized_Transient (Obj_Id)
8526
8527          --  Do not consider renamed or 'reference-d transient objects because
8528          --  the act of renaming extends the object's lifetime.
8529
8530          and then not Is_Aliased (Obj_Id, Decl)
8531
8532          --  Do not consider transient objects allocated on the heap since
8533          --  they are attached to a finalization master.
8534
8535          and then not Is_Allocated (Obj_Id)
8536
8537          --  If the transient object is a pointer, check that it is not
8538          --  initialized by a function that returns a pointer or acts as a
8539          --  renaming of another pointer.
8540
8541          and then not
8542            (Is_Access_Type (Obj_Typ) and then Initialized_By_Access (Obj_Id))
8543
8544          --  Do not consider transient objects which act as indirect aliases
8545          --  of build-in-place function results.
8546
8547          and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
8548
8549          --  Do not consider conversions of tags to class-wide types
8550
8551          and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
8552
8553          --  Do not consider iterators because those are treated as normal
8554          --  controlled objects and are processed by the usual finalization
8555          --  machinery. This avoids the double finalization of an iterator.
8556
8557          and then not Is_Iterator (Desig)
8558
8559          --  Do not consider containers in the context of iterator loops. Such
8560          --  transient objects must exist for as long as the loop is around,
8561          --  otherwise any operation carried out by the iterator will fail.
8562
8563          and then not Is_Iterated_Container (Obj_Id, Decl);
8564   end Is_Finalizable_Transient;
8565
8566   ---------------------------------
8567   -- Is_Fully_Repped_Tagged_Type --
8568   ---------------------------------
8569
8570   function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
8571      U    : constant Entity_Id := Underlying_Type (T);
8572      Comp : Entity_Id;
8573
8574   begin
8575      if No (U) or else not Is_Tagged_Type (U) then
8576         return False;
8577      elsif Has_Discriminants (U) then
8578         return False;
8579      elsif not Has_Specified_Layout (U) then
8580         return False;
8581      end if;
8582
8583      --  Here we have a tagged type, see if it has any component (other than
8584      --  tag and parent) with no component_clause. If so, we return False.
8585
8586      Comp := First_Component (U);
8587      while Present (Comp) loop
8588         if not Is_Tag (Comp)
8589           and then Chars (Comp) /= Name_uParent
8590           and then No (Component_Clause (Comp))
8591         then
8592            return False;
8593         else
8594            Next_Component (Comp);
8595         end if;
8596      end loop;
8597
8598      --  All components have clauses
8599
8600      return True;
8601   end Is_Fully_Repped_Tagged_Type;
8602
8603   ----------------------------------
8604   -- Is_Library_Level_Tagged_Type --
8605   ----------------------------------
8606
8607   function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
8608   begin
8609      return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ);
8610   end Is_Library_Level_Tagged_Type;
8611
8612   --------------------------
8613   -- Is_Non_BIP_Func_Call --
8614   --------------------------
8615
8616   function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
8617   begin
8618      --  The expected call is of the format
8619      --
8620      --    Func_Call'reference
8621
8622      return
8623        Nkind (Expr) = N_Reference
8624          and then Nkind (Prefix (Expr)) = N_Function_Call
8625          and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
8626   end Is_Non_BIP_Func_Call;
8627
8628   ----------------------------------
8629   -- Is_Possibly_Unaligned_Object --
8630   ----------------------------------
8631
8632   function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
8633      T  : constant Entity_Id := Etype (N);
8634
8635   begin
8636      --  If renamed object, apply test to underlying object
8637
8638      if Is_Entity_Name (N)
8639        and then Is_Object (Entity (N))
8640        and then Present (Renamed_Object (Entity (N)))
8641      then
8642         return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
8643      end if;
8644
8645      --  Tagged and controlled types and aliased types are always aligned, as
8646      --  are concurrent types.
8647
8648      if Is_Aliased (T)
8649        or else Has_Controlled_Component (T)
8650        or else Is_Concurrent_Type (T)
8651        or else Is_Tagged_Type (T)
8652        or else Is_Controlled (T)
8653      then
8654         return False;
8655      end if;
8656
8657      --  If this is an element of a packed array, may be unaligned
8658
8659      if Is_Ref_To_Bit_Packed_Array (N) then
8660         return True;
8661      end if;
8662
8663      --  Case of indexed component reference: test whether prefix is unaligned
8664
8665      if Nkind (N) = N_Indexed_Component then
8666         return Is_Possibly_Unaligned_Object (Prefix (N));
8667
8668      --  Case of selected component reference
8669
8670      elsif Nkind (N) = N_Selected_Component then
8671         declare
8672            P : constant Node_Id   := Prefix (N);
8673            C : constant Entity_Id := Entity (Selector_Name (N));
8674            M : Nat;
8675            S : Nat;
8676
8677         begin
8678            --  If component reference is for an array with nonstatic bounds,
8679            --  then it is always aligned: we can only process unaligned arrays
8680            --  with static bounds (more precisely compile time known bounds).
8681
8682            if Is_Array_Type (T)
8683              and then not Compile_Time_Known_Bounds (T)
8684            then
8685               return False;
8686            end if;
8687
8688            --  If component is aliased, it is definitely properly aligned
8689
8690            if Is_Aliased (C) then
8691               return False;
8692            end if;
8693
8694            --  If component is for a type implemented as a scalar, and the
8695            --  record is packed, and the component is other than the first
8696            --  component of the record, then the component may be unaligned.
8697
8698            if Is_Packed (Etype (P))
8699              and then Represented_As_Scalar (Etype (C))
8700              and then First_Entity (Scope (C)) /= C
8701            then
8702               return True;
8703            end if;
8704
8705            --  Compute maximum possible alignment for T
8706
8707            --  If alignment is known, then that settles things
8708
8709            if Known_Alignment (T) then
8710               M := UI_To_Int (Alignment (T));
8711
8712            --  If alignment is not known, tentatively set max alignment
8713
8714            else
8715               M := Ttypes.Maximum_Alignment;
8716
8717               --  We can reduce this if the Esize is known since the default
8718               --  alignment will never be more than the smallest power of 2
8719               --  that does not exceed this Esize value.
8720
8721               if Known_Esize (T) then
8722                  S := UI_To_Int (Esize (T));
8723
8724                  while (M / 2) >= S loop
8725                     M := M / 2;
8726                  end loop;
8727               end if;
8728            end if;
8729
8730            --  The following code is historical, it used to be present but it
8731            --  is too cautious, because the front-end does not know the proper
8732            --  default alignments for the target. Also, if the alignment is
8733            --  not known, the front end can't know in any case. If a copy is
8734            --  needed, the back-end will take care of it. This whole section
8735            --  including this comment can be removed later ???
8736
8737            --  If the component reference is for a record that has a specified
8738            --  alignment, and we either know it is too small, or cannot tell,
8739            --  then the component may be unaligned.
8740
8741            --  What is the following commented out code ???
8742
8743            --  if Known_Alignment (Etype (P))
8744            --    and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
8745            --    and then M > Alignment (Etype (P))
8746            --  then
8747            --     return True;
8748            --  end if;
8749
8750            --  Case of component clause present which may specify an
8751            --  unaligned position.
8752
8753            if Present (Component_Clause (C)) then
8754
8755               --  Otherwise we can do a test to make sure that the actual
8756               --  start position in the record, and the length, are both
8757               --  consistent with the required alignment. If not, we know
8758               --  that we are unaligned.
8759
8760               declare
8761                  Align_In_Bits : constant Nat := M * System_Storage_Unit;
8762                  Comp : Entity_Id;
8763
8764               begin
8765                  Comp := C;
8766
8767                  --  For a component inherited in a record extension, the
8768                  --  clause is inherited but position and size are not set.
8769
8770                  if Is_Base_Type (Etype (P))
8771                    and then Is_Tagged_Type (Etype (P))
8772                    and then Present (Original_Record_Component (Comp))
8773                  then
8774                     Comp := Original_Record_Component (Comp);
8775                  end if;
8776
8777                  if Component_Bit_Offset (Comp) mod Align_In_Bits /= 0
8778                    or else Esize (Comp) mod Align_In_Bits /= 0
8779                  then
8780                     return True;
8781                  end if;
8782               end;
8783            end if;
8784
8785            --  Otherwise, for a component reference, test prefix
8786
8787            return Is_Possibly_Unaligned_Object (P);
8788         end;
8789
8790      --  If not a component reference, must be aligned
8791
8792      else
8793         return False;
8794      end if;
8795   end Is_Possibly_Unaligned_Object;
8796
8797   ---------------------------------
8798   -- Is_Possibly_Unaligned_Slice --
8799   ---------------------------------
8800
8801   function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
8802   begin
8803      --  Go to renamed object
8804
8805      if Is_Entity_Name (N)
8806        and then Is_Object (Entity (N))
8807        and then Present (Renamed_Object (Entity (N)))
8808      then
8809         return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
8810      end if;
8811
8812      --  The reference must be a slice
8813
8814      if Nkind (N) /= N_Slice then
8815         return False;
8816      end if;
8817
8818      --  If it is a slice, then look at the array type being sliced
8819
8820      declare
8821         Sarr : constant Node_Id := Prefix (N);
8822         --  Prefix of the slice, i.e. the array being sliced
8823
8824         Styp : constant Entity_Id := Etype (Prefix (N));
8825         --  Type of the array being sliced
8826
8827         Pref : Node_Id;
8828         Ptyp : Entity_Id;
8829
8830      begin
8831         --  The problems arise if the array object that is being sliced
8832         --  is a component of a record or array, and we cannot guarantee
8833         --  the alignment of the array within its containing object.
8834
8835         --  To investigate this, we look at successive prefixes to see
8836         --  if we have a worrisome indexed or selected component.
8837
8838         Pref := Sarr;
8839         loop
8840            --  Case of array is part of an indexed component reference
8841
8842            if Nkind (Pref) = N_Indexed_Component then
8843               Ptyp := Etype (Prefix (Pref));
8844
8845               --  The only problematic case is when the array is packed, in
8846               --  which case we really know nothing about the alignment of
8847               --  individual components.
8848
8849               if Is_Bit_Packed_Array (Ptyp) then
8850                  return True;
8851               end if;
8852
8853            --  Case of array is part of a selected component reference
8854
8855            elsif Nkind (Pref) = N_Selected_Component then
8856               Ptyp := Etype (Prefix (Pref));
8857
8858               --  We are definitely in trouble if the record in question
8859               --  has an alignment, and either we know this alignment is
8860               --  inconsistent with the alignment of the slice, or we don't
8861               --  know what the alignment of the slice should be. But this
8862               --  really matters only if the target has strict alignment.
8863
8864               if Target_Strict_Alignment
8865                 and then Known_Alignment (Ptyp)
8866                 and then (Unknown_Alignment (Styp)
8867                            or else Alignment (Styp) > Alignment (Ptyp))
8868               then
8869                  return True;
8870               end if;
8871
8872               --  We are in potential trouble if the record type is packed.
8873               --  We could special case when we know that the array is the
8874               --  first component, but that's not such a simple case ???
8875
8876               if Is_Packed (Ptyp) then
8877                  return True;
8878               end if;
8879
8880               --  We are in trouble if there is a component clause, and
8881               --  either we do not know the alignment of the slice, or
8882               --  the alignment of the slice is inconsistent with the
8883               --  bit position specified by the component clause.
8884
8885               declare
8886                  Field : constant Entity_Id := Entity (Selector_Name (Pref));
8887               begin
8888                  if Present (Component_Clause (Field))
8889                    and then
8890                      (Unknown_Alignment (Styp)
8891                        or else
8892                         (Component_Bit_Offset (Field) mod
8893                           (System_Storage_Unit * Alignment (Styp))) /= 0)
8894                  then
8895                     return True;
8896                  end if;
8897               end;
8898
8899            --  For cases other than selected or indexed components we know we
8900            --  are OK, since no issues arise over alignment.
8901
8902            else
8903               return False;
8904            end if;
8905
8906            --  We processed an indexed component or selected component
8907            --  reference that looked safe, so keep checking prefixes.
8908
8909            Pref := Prefix (Pref);
8910         end loop;
8911      end;
8912   end Is_Possibly_Unaligned_Slice;
8913
8914   -------------------------------
8915   -- Is_Related_To_Func_Return --
8916   -------------------------------
8917
8918   function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
8919      Expr : constant Node_Id := Related_Expression (Id);
8920   begin
8921      --  In the case of a function with a class-wide result that returns
8922      --  a call to a function with a specific result, we introduce a
8923      --  type conversion for the return expression. We do not want that
8924      --  type conversion to influence the result of this function.
8925
8926      return
8927        Present (Expr)
8928          and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference
8929          and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
8930   end Is_Related_To_Func_Return;
8931
8932   --------------------------------
8933   -- Is_Ref_To_Bit_Packed_Array --
8934   --------------------------------
8935
8936   function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
8937      Result : Boolean;
8938      Expr   : Node_Id;
8939
8940   begin
8941      if Is_Entity_Name (N)
8942        and then Is_Object (Entity (N))
8943        and then Present (Renamed_Object (Entity (N)))
8944      then
8945         return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
8946      end if;
8947
8948      if Nkind (N) in N_Indexed_Component | N_Selected_Component then
8949         if Is_Bit_Packed_Array (Etype (Prefix (N))) then
8950            Result := True;
8951         else
8952            Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
8953         end if;
8954
8955         if Result and then Nkind (N) = N_Indexed_Component then
8956            Expr := First (Expressions (N));
8957            while Present (Expr) loop
8958               Force_Evaluation (Expr);
8959               Next (Expr);
8960            end loop;
8961         end if;
8962
8963         return Result;
8964
8965      else
8966         return False;
8967      end if;
8968   end Is_Ref_To_Bit_Packed_Array;
8969
8970   --------------------------------
8971   -- Is_Ref_To_Bit_Packed_Slice --
8972   --------------------------------
8973
8974   function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
8975   begin
8976      if Nkind (N) = N_Type_Conversion then
8977         return Is_Ref_To_Bit_Packed_Slice (Expression (N));
8978
8979      elsif Is_Entity_Name (N)
8980        and then Is_Object (Entity (N))
8981        and then Present (Renamed_Object (Entity (N)))
8982      then
8983         return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
8984
8985      elsif Nkind (N) = N_Slice
8986        and then Is_Bit_Packed_Array (Etype (Prefix (N)))
8987      then
8988         return True;
8989
8990      elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
8991         return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
8992
8993      else
8994         return False;
8995      end if;
8996   end Is_Ref_To_Bit_Packed_Slice;
8997
8998   -----------------------
8999   -- Is_Renamed_Object --
9000   -----------------------
9001
9002   function Is_Renamed_Object (N : Node_Id) return Boolean is
9003      Pnod : constant Node_Id   := Parent (N);
9004      Kind : constant Node_Kind := Nkind (Pnod);
9005   begin
9006      if Kind = N_Object_Renaming_Declaration then
9007         return True;
9008      elsif Kind in N_Indexed_Component | N_Selected_Component then
9009         return Is_Renamed_Object (Pnod);
9010      else
9011         return False;
9012      end if;
9013   end Is_Renamed_Object;
9014
9015   --------------------------------------
9016   -- Is_Secondary_Stack_BIP_Func_Call --
9017   --------------------------------------
9018
9019   function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
9020      Actual    : Node_Id;
9021      Call      : Node_Id := Expr;
9022      Formal    : Node_Id;
9023      Param     : Node_Id;
9024
9025   begin
9026      --  Build-in-place calls usually appear in 'reference format. Note that
9027      --  the accessibility check machinery may add an extra 'reference due to
9028      --  side effect removal.
9029
9030      while Nkind (Call) = N_Reference loop
9031         Call := Prefix (Call);
9032      end loop;
9033
9034      Call := Unqual_Conv (Call);
9035
9036      if Is_Build_In_Place_Function_Call (Call) then
9037
9038         --  Examine all parameter associations of the function call
9039
9040         Param := First (Parameter_Associations (Call));
9041         while Present (Param) loop
9042            if Nkind (Param) = N_Parameter_Association then
9043               Formal := Selector_Name (Param);
9044               Actual := Explicit_Actual_Parameter (Param);
9045
9046               --  A match for BIPalloc => 2 has been found
9047
9048               if Is_Build_In_Place_Entity (Formal)
9049                 and then BIP_Suffix_Kind (Formal) = BIP_Alloc_Form
9050                 and then Nkind (Actual) = N_Integer_Literal
9051                 and then Intval (Actual) = Uint_2
9052               then
9053                  return True;
9054               end if;
9055            end if;
9056
9057            Next (Param);
9058         end loop;
9059      end if;
9060
9061      return False;
9062   end Is_Secondary_Stack_BIP_Func_Call;
9063
9064   -------------------------------------
9065   -- Is_Tag_To_Class_Wide_Conversion --
9066   -------------------------------------
9067
9068   function Is_Tag_To_Class_Wide_Conversion
9069     (Obj_Id : Entity_Id) return Boolean
9070   is
9071      Expr : constant Node_Id := Expression (Parent (Obj_Id));
9072
9073   begin
9074      return
9075        Is_Class_Wide_Type (Etype (Obj_Id))
9076          and then Present (Expr)
9077          and then Nkind (Expr) = N_Unchecked_Type_Conversion
9078          and then Etype (Expression (Expr)) = RTE (RE_Tag);
9079   end Is_Tag_To_Class_Wide_Conversion;
9080
9081   --------------------------------
9082   -- Is_Uninitialized_Aggregate --
9083   --------------------------------
9084
9085   function Is_Uninitialized_Aggregate
9086     (Exp : Node_Id;
9087      T   : Entity_Id) return Boolean
9088   is
9089      Comp      : Node_Id;
9090      Comp_Type : Entity_Id;
9091      Typ       : Entity_Id;
9092
9093   begin
9094      if Nkind (Exp) /= N_Aggregate then
9095         return False;
9096      end if;
9097
9098      Preanalyze_And_Resolve (Exp, T);
9099      Typ  := Etype (Exp);
9100
9101      if No (Typ)
9102        or else Ekind (Typ) /= E_Array_Subtype
9103        or else Present (Expressions (Exp))
9104        or else No (Component_Associations (Exp))
9105      then
9106         return False;
9107      else
9108         Comp_Type := Component_Type (Typ);
9109         Comp := First (Component_Associations (Exp));
9110
9111         if not Box_Present (Comp)
9112           or else Present (Next (Comp))
9113         then
9114            return False;
9115         end if;
9116
9117         return Is_Scalar_Type (Comp_Type)
9118           and then No (Default_Aspect_Component_Value (Typ));
9119      end if;
9120   end Is_Uninitialized_Aggregate;
9121
9122   ----------------------------
9123   -- Is_Untagged_Derivation --
9124   ----------------------------
9125
9126   function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
9127   begin
9128      return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
9129               or else
9130                 (Is_Private_Type (T) and then Present (Full_View (T))
9131                   and then not Is_Tagged_Type (Full_View (T))
9132                   and then Is_Derived_Type (Full_View (T))
9133                   and then Etype (Full_View (T)) /= T);
9134   end Is_Untagged_Derivation;
9135
9136   ------------------------------------
9137   -- Is_Untagged_Private_Derivation --
9138   ------------------------------------
9139
9140   function Is_Untagged_Private_Derivation
9141     (Priv_Typ : Entity_Id;
9142      Full_Typ : Entity_Id) return Boolean
9143   is
9144   begin
9145      return
9146        Present (Priv_Typ)
9147          and then Is_Untagged_Derivation (Priv_Typ)
9148          and then Is_Private_Type (Etype (Priv_Typ))
9149          and then Present (Full_Typ)
9150          and then Is_Itype (Full_Typ);
9151   end Is_Untagged_Private_Derivation;
9152
9153   ------------------------------
9154   -- Is_Verifiable_DIC_Pragma --
9155   ------------------------------
9156
9157   function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is
9158      Args : constant List_Id := Pragma_Argument_Associations (Prag);
9159
9160   begin
9161      --  To qualify as verifiable, a DIC pragma must have a non-null argument
9162
9163      return
9164        Present (Args)
9165
9166          --  If there are args, but the first arg is Empty, then treat the
9167          --  pragma the same as having no args (there may be a second arg that
9168          --  is an implicitly added type arg, and Empty is a placeholder).
9169
9170          and then Present (Get_Pragma_Arg (First (Args)))
9171
9172          and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null;
9173   end Is_Verifiable_DIC_Pragma;
9174
9175   ---------------------------
9176   -- Is_Volatile_Reference --
9177   ---------------------------
9178
9179   function Is_Volatile_Reference (N : Node_Id) return Boolean is
9180   begin
9181      --  Only source references are to be treated as volatile, internally
9182      --  generated stuff cannot have volatile external effects.
9183
9184      if not Comes_From_Source (N) then
9185         return False;
9186
9187      --  Never true for reference to a type
9188
9189      elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
9190         return False;
9191
9192      --  Never true for a compile time known constant
9193
9194      elsif Compile_Time_Known_Value (N) then
9195         return False;
9196
9197      --  True if object reference with volatile type
9198
9199      elsif Is_Volatile_Object (N) then
9200         return True;
9201
9202      --  True if reference to volatile entity
9203
9204      elsif Is_Entity_Name (N) then
9205         return Treat_As_Volatile (Entity (N));
9206
9207      --  True for slice of volatile array
9208
9209      elsif Nkind (N) = N_Slice then
9210         return Is_Volatile_Reference (Prefix (N));
9211
9212      --  True if volatile component
9213
9214      elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
9215         if (Is_Entity_Name (Prefix (N))
9216              and then Has_Volatile_Components (Entity (Prefix (N))))
9217           or else (Present (Etype (Prefix (N)))
9218                     and then Has_Volatile_Components (Etype (Prefix (N))))
9219         then
9220            return True;
9221         else
9222            return Is_Volatile_Reference (Prefix (N));
9223         end if;
9224
9225      --  Otherwise false
9226
9227      else
9228         return False;
9229      end if;
9230   end Is_Volatile_Reference;
9231
9232   --------------------
9233   -- Kill_Dead_Code --
9234   --------------------
9235
9236   procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
9237      W : Boolean := Warn;
9238      --  Set False if warnings suppressed
9239
9240   begin
9241      if Present (N) then
9242         Remove_Warning_Messages (N);
9243
9244         --  Update the internal structures of the ABE mechanism in case the
9245         --  dead node is an elaboration scenario.
9246
9247         Kill_Elaboration_Scenario (N);
9248
9249         --  Generate warning if appropriate
9250
9251         if W then
9252
9253            --  We suppress the warning if this code is under control of an
9254            --  if statement, whose condition is a simple identifier, and
9255            --  either we are in an instance, or warnings off is set for this
9256            --  identifier. The reason for killing it in the instance case is
9257            --  that it is common and reasonable for code to be deleted in
9258            --  instances for various reasons.
9259
9260            --  Could we use Is_Statically_Unevaluated here???
9261
9262            if Nkind (Parent (N)) = N_If_Statement then
9263               declare
9264                  C : constant Node_Id := Condition (Parent (N));
9265               begin
9266                  if Nkind (C) = N_Identifier
9267                    and then
9268                      (In_Instance
9269                        or else (Present (Entity (C))
9270                                  and then Has_Warnings_Off (Entity (C))))
9271                  then
9272                     W := False;
9273                  end if;
9274               end;
9275            end if;
9276
9277            --  Generate warning if not suppressed
9278
9279            if W then
9280               Error_Msg_F
9281                 ("?t?this code can never be executed and has been deleted!",
9282                  N);
9283            end if;
9284         end if;
9285
9286         --  Recurse into block statements and bodies to process declarations
9287         --  and statements.
9288
9289         if Nkind (N) = N_Block_Statement
9290           or else Nkind (N) = N_Subprogram_Body
9291           or else Nkind (N) = N_Package_Body
9292         then
9293            Kill_Dead_Code (Declarations (N), False);
9294            Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
9295
9296            if Nkind (N) = N_Subprogram_Body then
9297               Set_Is_Eliminated (Defining_Entity (N));
9298            end if;
9299
9300         elsif Nkind (N) = N_Package_Declaration then
9301            Kill_Dead_Code (Visible_Declarations (Specification (N)));
9302            Kill_Dead_Code (Private_Declarations (Specification (N)));
9303
9304            --  ??? After this point, Delete_Tree has been called on all
9305            --  declarations in Specification (N), so references to entities
9306            --  therein look suspicious.
9307
9308            declare
9309               E : Entity_Id := First_Entity (Defining_Entity (N));
9310
9311            begin
9312               while Present (E) loop
9313                  if Ekind (E) = E_Operator then
9314                     Set_Is_Eliminated (E);
9315                  end if;
9316
9317                  Next_Entity (E);
9318               end loop;
9319            end;
9320
9321         --  Recurse into composite statement to kill individual statements in
9322         --  particular instantiations.
9323
9324         elsif Nkind (N) = N_If_Statement then
9325            Kill_Dead_Code (Then_Statements (N));
9326            Kill_Dead_Code (Elsif_Parts     (N));
9327            Kill_Dead_Code (Else_Statements (N));
9328
9329         elsif Nkind (N) = N_Loop_Statement then
9330            Kill_Dead_Code (Statements (N));
9331
9332         elsif Nkind (N) = N_Case_Statement then
9333            declare
9334               Alt : Node_Id;
9335            begin
9336               Alt := First (Alternatives (N));
9337               while Present (Alt) loop
9338                  Kill_Dead_Code (Statements (Alt));
9339                  Next (Alt);
9340               end loop;
9341            end;
9342
9343         elsif Nkind (N) = N_Case_Statement_Alternative then
9344            Kill_Dead_Code (Statements (N));
9345
9346         --  Deal with dead instances caused by deleting instantiations
9347
9348         elsif Nkind (N) in N_Generic_Instantiation then
9349            Remove_Dead_Instance (N);
9350         end if;
9351      end if;
9352   end Kill_Dead_Code;
9353
9354   --  Case where argument is a list of nodes to be killed
9355
9356   procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
9357      N : Node_Id;
9358      W : Boolean;
9359
9360   begin
9361      W := Warn;
9362
9363      if Is_Non_Empty_List (L) then
9364         N := First (L);
9365         while Present (N) loop
9366            Kill_Dead_Code (N, W);
9367            W := False;
9368            Next (N);
9369         end loop;
9370      end if;
9371   end Kill_Dead_Code;
9372
9373   -----------------------------
9374   -- Make_CW_Equivalent_Type --
9375   -----------------------------
9376
9377   --  Create a record type used as an equivalent of any member of the class
9378   --  which takes its size from exp.
9379
9380   --  Generate the following code:
9381
9382   --   type Equiv_T is record
9383   --     _parent : T (List of discriminant constraints taken from Exp);
9384   --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
9385   --   end Equiv_T;
9386   --
9387   --  ??? Note that this type does not guarantee same alignment as all
9388   --  derived types
9389   --
9390   --  Note: for the freezing circuitry, this looks like a record extension,
9391   --  and so we need to make sure that the scalar storage order is the same
9392   --  as that of the parent type. (This does not change anything for the
9393   --  representation of the extension part.)
9394
9395   function Make_CW_Equivalent_Type
9396     (T : Entity_Id;
9397      E : Node_Id) return Entity_Id
9398   is
9399      Loc         : constant Source_Ptr := Sloc (E);
9400      Root_Typ    : constant Entity_Id  := Root_Type (T);
9401      Root_Utyp   : constant Entity_Id  := Underlying_Type (Root_Typ);
9402      List_Def    : constant List_Id    := Empty_List;
9403      Comp_List   : constant List_Id    := New_List;
9404      Equiv_Type  : Entity_Id;
9405      Range_Type  : Entity_Id;
9406      Str_Type    : Entity_Id;
9407      Constr_Root : Entity_Id;
9408      Sizexpr     : Node_Id;
9409
9410   begin
9411      --  If the root type is already constrained, there are no discriminants
9412      --  in the expression.
9413
9414      if not Has_Discriminants (Root_Typ)
9415        or else Is_Constrained (Root_Typ)
9416      then
9417         Constr_Root := Root_Typ;
9418
9419         --  At this point in the expansion, nonlimited view of the type
9420         --  must be available, otherwise the error will be reported later.
9421
9422         if From_Limited_With (Constr_Root)
9423           and then Present (Non_Limited_View (Constr_Root))
9424         then
9425            Constr_Root := Non_Limited_View (Constr_Root);
9426         end if;
9427
9428      else
9429         Constr_Root := Make_Temporary (Loc, 'R');
9430
9431         --  subtype cstr__n is T (List of discr constraints taken from Exp)
9432
9433         Append_To (List_Def,
9434           Make_Subtype_Declaration (Loc,
9435             Defining_Identifier => Constr_Root,
9436             Subtype_Indication  => Make_Subtype_From_Expr (E, Root_Typ)));
9437      end if;
9438
9439      --  Generate the range subtype declaration
9440
9441      Range_Type := Make_Temporary (Loc, 'G');
9442
9443      if not Is_Interface (Root_Typ) then
9444
9445         --  subtype rg__xx is
9446         --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
9447
9448         Sizexpr :=
9449           Make_Op_Subtract (Loc,
9450             Left_Opnd =>
9451               Make_Attribute_Reference (Loc,
9452                 Prefix =>
9453                   OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9454                 Attribute_Name => Name_Size),
9455             Right_Opnd =>
9456               Make_Attribute_Reference (Loc,
9457                 Prefix => New_Occurrence_Of (Constr_Root, Loc),
9458                 Attribute_Name => Name_Object_Size));
9459      else
9460         --  subtype rg__xx is
9461         --    Storage_Offset range 1 .. Expr'size / Storage_Unit
9462
9463         Sizexpr :=
9464           Make_Attribute_Reference (Loc,
9465             Prefix =>
9466               OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9467             Attribute_Name => Name_Size);
9468      end if;
9469
9470      Set_Paren_Count (Sizexpr, 1);
9471
9472      Append_To (List_Def,
9473        Make_Subtype_Declaration (Loc,
9474          Defining_Identifier => Range_Type,
9475          Subtype_Indication =>
9476            Make_Subtype_Indication (Loc,
9477              Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
9478              Constraint => Make_Range_Constraint (Loc,
9479                Range_Expression =>
9480                  Make_Range (Loc,
9481                    Low_Bound => Make_Integer_Literal (Loc, 1),
9482                    High_Bound =>
9483                      Make_Op_Divide (Loc,
9484                        Left_Opnd => Sizexpr,
9485                        Right_Opnd => Make_Integer_Literal (Loc,
9486                            Intval => System_Storage_Unit)))))));
9487
9488      --  subtype str__nn is Storage_Array (rg__x);
9489
9490      Str_Type := Make_Temporary (Loc, 'S');
9491      Append_To (List_Def,
9492        Make_Subtype_Declaration (Loc,
9493          Defining_Identifier => Str_Type,
9494          Subtype_Indication =>
9495            Make_Subtype_Indication (Loc,
9496              Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc),
9497              Constraint =>
9498                Make_Index_Or_Discriminant_Constraint (Loc,
9499                  Constraints =>
9500                    New_List (New_Occurrence_Of (Range_Type, Loc))))));
9501
9502      --  type Equiv_T is record
9503      --    [ _parent : Tnn; ]
9504      --    E : Str_Type;
9505      --  end Equiv_T;
9506
9507      Equiv_Type := Make_Temporary (Loc, 'T');
9508      Set_Ekind (Equiv_Type, E_Record_Type);
9509      Set_Parent_Subtype (Equiv_Type, Constr_Root);
9510
9511      --  Set Is_Class_Wide_Equivalent_Type very early to trigger the special
9512      --  treatment for this type. In particular, even though _parent's type
9513      --  is a controlled type or contains controlled components, we do not
9514      --  want to set Has_Controlled_Component on it to avoid making it gain
9515      --  an unwanted _controller component.
9516
9517      Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
9518
9519      --  A class-wide equivalent type does not require initialization
9520
9521      Set_Suppress_Initialization (Equiv_Type);
9522
9523      if not Is_Interface (Root_Typ) then
9524         Append_To (Comp_List,
9525           Make_Component_Declaration (Loc,
9526             Defining_Identifier  =>
9527               Make_Defining_Identifier (Loc, Name_uParent),
9528             Component_Definition =>
9529               Make_Component_Definition (Loc,
9530                 Aliased_Present    => False,
9531                 Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc))));
9532
9533         Set_Reverse_Storage_Order
9534           (Equiv_Type, Reverse_Storage_Order (Base_Type (Root_Utyp)));
9535         Set_Reverse_Bit_Order
9536           (Equiv_Type, Reverse_Bit_Order (Base_Type (Root_Utyp)));
9537      end if;
9538
9539      Append_To (Comp_List,
9540        Make_Component_Declaration (Loc,
9541          Defining_Identifier  => Make_Temporary (Loc, 'C'),
9542          Component_Definition =>
9543            Make_Component_Definition (Loc,
9544              Aliased_Present    => False,
9545              Subtype_Indication => New_Occurrence_Of (Str_Type, Loc))));
9546
9547      Append_To (List_Def,
9548        Make_Full_Type_Declaration (Loc,
9549          Defining_Identifier => Equiv_Type,
9550          Type_Definition     =>
9551            Make_Record_Definition (Loc,
9552              Component_List  =>
9553                Make_Component_List (Loc,
9554                  Component_Items => Comp_List,
9555                  Variant_Part    => Empty))));
9556
9557      --  Suppress all checks during the analysis of the expanded code to avoid
9558      --  the generation of spurious warnings under ZFP run-time.
9559
9560      Insert_Actions (E, List_Def, Suppress => All_Checks);
9561      return Equiv_Type;
9562   end Make_CW_Equivalent_Type;
9563
9564   -------------------------
9565   -- Make_Invariant_Call --
9566   -------------------------
9567
9568   function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
9569      Loc : constant Source_Ptr := Sloc (Expr);
9570      Typ : constant Entity_Id  := Base_Type (Etype (Expr));
9571      pragma Assert (Has_Invariants (Typ));
9572      Proc_Id : constant Entity_Id := Invariant_Procedure (Typ);
9573      pragma Assert (Present (Proc_Id));
9574   begin
9575      --  The invariant procedure has a null body if assertions are disabled or
9576      --  Assertion_Policy Ignore is in effect. In that case, generate a null
9577      --  statement instead of a call to the invariant procedure.
9578
9579      if Has_Null_Body (Proc_Id) then
9580         return Make_Null_Statement (Loc);
9581      else
9582         return
9583           Make_Procedure_Call_Statement (Loc,
9584             Name                   => New_Occurrence_Of (Proc_Id, Loc),
9585             Parameter_Associations => New_List (Relocate_Node (Expr)));
9586      end if;
9587   end Make_Invariant_Call;
9588
9589   ------------------------
9590   -- Make_Literal_Range --
9591   ------------------------
9592
9593   function Make_Literal_Range
9594     (Loc         : Source_Ptr;
9595      Literal_Typ : Entity_Id) return Node_Id
9596   is
9597      Lo          : constant Node_Id :=
9598                      New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
9599      Index       : constant Entity_Id := Etype (Lo);
9600      Length_Expr : constant Node_Id :=
9601                      Make_Op_Subtract (Loc,
9602                        Left_Opnd  =>
9603                          Make_Integer_Literal (Loc,
9604                            Intval => String_Literal_Length (Literal_Typ)),
9605                        Right_Opnd => Make_Integer_Literal (Loc, 1));
9606
9607      Hi : Node_Id;
9608
9609   begin
9610      Set_Analyzed (Lo, False);
9611
9612      if Is_Integer_Type (Index) then
9613         Hi :=
9614           Make_Op_Add (Loc,
9615             Left_Opnd  => New_Copy_Tree (Lo),
9616             Right_Opnd => Length_Expr);
9617      else
9618         Hi :=
9619           Make_Attribute_Reference (Loc,
9620             Attribute_Name => Name_Val,
9621             Prefix         => New_Occurrence_Of (Index, Loc),
9622             Expressions    => New_List (
9623               Make_Op_Add (Loc,
9624                 Left_Opnd  =>
9625                   Make_Attribute_Reference (Loc,
9626                     Attribute_Name => Name_Pos,
9627                     Prefix         => New_Occurrence_Of (Index, Loc),
9628                     Expressions    => New_List (New_Copy_Tree (Lo))),
9629                 Right_Opnd => Length_Expr)));
9630      end if;
9631
9632      return
9633        Make_Range (Loc,
9634          Low_Bound  => Lo,
9635          High_Bound => Hi);
9636   end Make_Literal_Range;
9637
9638   --------------------------
9639   -- Make_Non_Empty_Check --
9640   --------------------------
9641
9642   function Make_Non_Empty_Check
9643     (Loc : Source_Ptr;
9644      N   : Node_Id) return Node_Id
9645   is
9646   begin
9647      return
9648        Make_Op_Ne (Loc,
9649          Left_Opnd =>
9650            Make_Attribute_Reference (Loc,
9651              Attribute_Name => Name_Length,
9652              Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
9653          Right_Opnd =>
9654            Make_Integer_Literal (Loc, 0));
9655   end Make_Non_Empty_Check;
9656
9657   -------------------------
9658   -- Make_Predicate_Call --
9659   -------------------------
9660
9661   --  WARNING: This routine manages Ghost regions. Return statements must be
9662   --  replaced by gotos which jump to the end of the routine and restore the
9663   --  Ghost mode.
9664
9665   function Make_Predicate_Call
9666     (Typ  : Entity_Id;
9667      Expr : Node_Id;
9668      Mem  : Boolean := False) return Node_Id
9669   is
9670      Loc : constant Source_Ptr := Sloc (Expr);
9671
9672      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
9673      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
9674      --  Save the Ghost-related attributes to restore on exit
9675
9676      Call    : Node_Id;
9677      Func_Id : Entity_Id;
9678
9679   begin
9680      Func_Id := Predicate_Function (Typ);
9681      pragma Assert (Present (Func_Id));
9682
9683      --  The related type may be subject to pragma Ghost. Set the mode now to
9684      --  ensure that the call is properly marked as Ghost.
9685
9686      Set_Ghost_Mode (Typ);
9687
9688      --  Call special membership version if requested and available
9689
9690      if Mem and then Present (Predicate_Function_M (Typ)) then
9691         Func_Id := Predicate_Function_M (Typ);
9692      end if;
9693
9694      --  Case of calling normal predicate function
9695
9696      --  If the type is tagged, the expression may be class-wide, in which
9697      --  case it has to be converted to its root type, given that the
9698      --  generated predicate function is not dispatching. The conversion is
9699      --  type-safe and does not need validation, which matters when private
9700      --  extensions are involved.
9701
9702      if Is_Tagged_Type (Typ) then
9703         Call :=
9704           Make_Function_Call (Loc,
9705             Name                   => New_Occurrence_Of (Func_Id, Loc),
9706             Parameter_Associations =>
9707               New_List (OK_Convert_To (Typ, Relocate_Node (Expr))));
9708      else
9709         Call :=
9710           Make_Function_Call (Loc,
9711             Name                   => New_Occurrence_Of (Func_Id, Loc),
9712             Parameter_Associations => New_List (Relocate_Node (Expr)));
9713      end if;
9714
9715      Restore_Ghost_Region (Saved_GM, Saved_IGR);
9716
9717      return Call;
9718   end Make_Predicate_Call;
9719
9720   --------------------------
9721   -- Make_Predicate_Check --
9722   --------------------------
9723
9724   function Make_Predicate_Check
9725     (Typ  : Entity_Id;
9726      Expr : Node_Id) return Node_Id
9727   is
9728      Loc : constant Source_Ptr := Sloc (Expr);
9729
9730      procedure Add_Failure_Expression (Args : List_Id);
9731      --  Add the failure expression of pragma Predicate_Failure (if any) to
9732      --  list Args.
9733
9734      ----------------------------
9735      -- Add_Failure_Expression --
9736      ----------------------------
9737
9738      procedure Add_Failure_Expression (Args : List_Id) is
9739         function Failure_Expression return Node_Id;
9740         pragma Inline (Failure_Expression);
9741         --  Find aspect or pragma Predicate_Failure that applies to type Typ
9742         --  and return its expression. Return Empty if no such annotation is
9743         --  available.
9744
9745         function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean;
9746         pragma Inline (Is_OK_PF_Aspect);
9747         --  Determine whether aspect Asp is a suitable Predicate_Failure
9748         --  aspect that applies to type Typ.
9749
9750         function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean;
9751         pragma Inline (Is_OK_PF_Pragma);
9752         --  Determine whether pragma Prag is a suitable Predicate_Failure
9753         --  pragma that applies to type Typ.
9754
9755         procedure Replace_Subtype_Reference (N : Node_Id);
9756         --  Replace the current instance of type Typ denoted by N with
9757         --  expression Expr.
9758
9759         ------------------------
9760         -- Failure_Expression --
9761         ------------------------
9762
9763         function Failure_Expression return Node_Id is
9764            Item : Node_Id;
9765
9766         begin
9767            --  The management of the rep item chain involves "inheritance" of
9768            --  parent type chains. If a parent [sub]type is already subject to
9769            --  pragma Predicate_Failure, then the pragma will also appear in
9770            --  the chain of the child [sub]type, which in turn may possess a
9771            --  pragma of its own. Avoid order-dependent issues by inspecting
9772            --  the rep item chain directly. Note that routine Get_Pragma may
9773            --  return a parent pragma.
9774
9775            Item := First_Rep_Item (Typ);
9776            while Present (Item) loop
9777
9778               --  Predicate_Failure appears as an aspect
9779
9780               if Nkind (Item) = N_Aspect_Specification
9781                 and then Is_OK_PF_Aspect (Item)
9782               then
9783                  return Expression (Item);
9784
9785               --  Predicate_Failure appears as a pragma
9786
9787               elsif Nkind (Item) = N_Pragma
9788                 and then Is_OK_PF_Pragma (Item)
9789               then
9790                  return
9791                    Get_Pragma_Arg
9792                      (Next (First (Pragma_Argument_Associations (Item))));
9793               end if;
9794
9795               Next_Rep_Item (Item);
9796            end loop;
9797
9798            return Empty;
9799         end Failure_Expression;
9800
9801         ---------------------
9802         -- Is_OK_PF_Aspect --
9803         ---------------------
9804
9805         function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean is
9806         begin
9807            --  To qualify, the aspect must apply to the type subjected to the
9808            --  predicate check.
9809
9810            return
9811              Chars (Identifier (Asp)) = Name_Predicate_Failure
9812                and then Present (Entity (Asp))
9813                and then Entity (Asp) = Typ;
9814         end Is_OK_PF_Aspect;
9815
9816         ---------------------
9817         -- Is_OK_PF_Pragma --
9818         ---------------------
9819
9820         function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean is
9821            Args    : constant List_Id := Pragma_Argument_Associations (Prag);
9822            Typ_Arg : Node_Id;
9823
9824         begin
9825            --  Nothing to do when the pragma does not denote Predicate_Failure
9826
9827            if Pragma_Name (Prag) /= Name_Predicate_Failure then
9828               return False;
9829
9830            --  Nothing to do when the pragma lacks arguments, in which case it
9831            --  is illegal.
9832
9833            elsif No (Args) or else Is_Empty_List (Args) then
9834               return False;
9835            end if;
9836
9837            Typ_Arg := Get_Pragma_Arg (First (Args));
9838
9839            --  To qualify, the local name argument of the pragma must denote
9840            --  the type subjected to the predicate check.
9841
9842            return
9843              Is_Entity_Name (Typ_Arg)
9844                and then Present (Entity (Typ_Arg))
9845                and then Entity (Typ_Arg) = Typ;
9846         end Is_OK_PF_Pragma;
9847
9848         --------------------------------
9849         --  Replace_Subtype_Reference --
9850         --------------------------------
9851
9852         procedure Replace_Subtype_Reference (N : Node_Id) is
9853         begin
9854            Rewrite (N, New_Copy_Tree (Expr));
9855         end Replace_Subtype_Reference;
9856
9857         procedure Replace_Subtype_References is
9858           new Replace_Type_References_Generic (Replace_Subtype_Reference);
9859
9860         --  Local variables
9861
9862         PF_Expr : constant Node_Id := Failure_Expression;
9863         Expr    : Node_Id;
9864
9865      --  Start of processing for Add_Failure_Expression
9866
9867      begin
9868         if Present (PF_Expr) then
9869
9870            --  Replace any occurrences of the current instance of the type
9871            --  with the object subjected to the predicate check.
9872
9873            Expr := New_Copy_Tree (PF_Expr);
9874            Replace_Subtype_References (Expr, Typ);
9875
9876            --  The failure expression appears as the third argument of the
9877            --  Check pragma.
9878
9879            Append_To (Args,
9880              Make_Pragma_Argument_Association (Loc,
9881                Expression => Expr));
9882         end if;
9883      end Add_Failure_Expression;
9884
9885      --  Local variables
9886
9887      Args : List_Id;
9888      Nam  : Name_Id;
9889
9890   --  Start of processing for Make_Predicate_Check
9891
9892   begin
9893      --  If predicate checks are suppressed, then return a null statement. For
9894      --  this call, we check only the scope setting. If the caller wants to
9895      --  check a specific entity's setting, they must do it manually.
9896
9897      if Predicate_Checks_Suppressed (Empty) then
9898         return Make_Null_Statement (Loc);
9899      end if;
9900
9901      --  Do not generate a check within stream functions and the like.
9902
9903      if not Predicate_Check_In_Scope (Expr) then
9904         return Make_Null_Statement (Loc);
9905      end if;
9906
9907      --  Compute proper name to use, we need to get this right so that the
9908      --  right set of check policies apply to the Check pragma we are making.
9909
9910      if Has_Dynamic_Predicate_Aspect (Typ) then
9911         Nam := Name_Dynamic_Predicate;
9912      elsif Has_Static_Predicate_Aspect (Typ) then
9913         Nam := Name_Static_Predicate;
9914      else
9915         Nam := Name_Predicate;
9916      end if;
9917
9918      Args := New_List (
9919        Make_Pragma_Argument_Association (Loc,
9920          Expression => Make_Identifier (Loc, Nam)),
9921        Make_Pragma_Argument_Association (Loc,
9922          Expression => Make_Predicate_Call (Typ, Expr)));
9923
9924      --  If the subtype is subject to pragma Predicate_Failure, add the
9925      --  failure expression as an additional parameter.
9926
9927      Add_Failure_Expression (Args);
9928
9929      return
9930        Make_Pragma (Loc,
9931          Chars                        => Name_Check,
9932          Pragma_Argument_Associations => Args);
9933   end Make_Predicate_Check;
9934
9935   ----------------------------
9936   -- Make_Subtype_From_Expr --
9937   ----------------------------
9938
9939   --  1. If Expr is an unconstrained array expression, creates
9940   --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
9941
9942   --  2. If Expr is a unconstrained discriminated type expression, creates
9943   --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
9944
9945   --  3. If Expr is class-wide, creates an implicit class-wide subtype
9946
9947   function Make_Subtype_From_Expr
9948     (E          : Node_Id;
9949      Unc_Typ    : Entity_Id;
9950      Related_Id : Entity_Id := Empty) return Node_Id
9951   is
9952      List_Constr : constant List_Id    := New_List;
9953      Loc         : constant Source_Ptr := Sloc (E);
9954      D           : Entity_Id;
9955      Full_Exp    : Node_Id;
9956      Full_Subtyp : Entity_Id;
9957      High_Bound  : Entity_Id;
9958      Index_Typ   : Entity_Id;
9959      Low_Bound   : Entity_Id;
9960      Priv_Subtyp : Entity_Id;
9961      Utyp        : Entity_Id;
9962
9963   begin
9964      if Is_Private_Type (Unc_Typ)
9965        and then Has_Unknown_Discriminants (Unc_Typ)
9966      then
9967         --  The caller requests a unique external name for both the private
9968         --  and the full subtype.
9969
9970         if Present (Related_Id) then
9971            Full_Subtyp :=
9972              Make_Defining_Identifier (Loc,
9973                Chars => New_External_Name (Chars (Related_Id), 'C'));
9974            Priv_Subtyp :=
9975              Make_Defining_Identifier (Loc,
9976                Chars => New_External_Name (Chars (Related_Id), 'P'));
9977
9978         else
9979            Full_Subtyp := Make_Temporary (Loc, 'C');
9980            Priv_Subtyp := Make_Temporary (Loc, 'P');
9981         end if;
9982
9983         --  Prepare the subtype completion. Use the base type to find the
9984         --  underlying type because the type may be a generic actual or an
9985         --  explicit subtype.
9986
9987         Utyp := Underlying_Type (Base_Type (Unc_Typ));
9988
9989         Full_Exp :=
9990           Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
9991         Set_Parent (Full_Exp, Parent (E));
9992
9993         Insert_Action (E,
9994           Make_Subtype_Declaration (Loc,
9995             Defining_Identifier => Full_Subtyp,
9996             Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
9997
9998         --  Define the dummy private subtype
9999
10000         Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
10001         Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
10002         Set_Scope          (Priv_Subtyp, Full_Subtyp);
10003         Set_Is_Constrained (Priv_Subtyp);
10004         Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
10005         Set_Is_Itype       (Priv_Subtyp);
10006         Set_Associated_Node_For_Itype (Priv_Subtyp, E);
10007
10008         if Is_Tagged_Type  (Priv_Subtyp) then
10009            Set_Class_Wide_Type
10010              (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
10011            Set_Direct_Primitive_Operations (Priv_Subtyp,
10012              Direct_Primitive_Operations (Unc_Typ));
10013         end if;
10014
10015         Set_Full_View (Priv_Subtyp, Full_Subtyp);
10016
10017         return New_Occurrence_Of (Priv_Subtyp, Loc);
10018
10019      elsif Is_Array_Type (Unc_Typ) then
10020         Index_Typ := First_Index (Unc_Typ);
10021         for J in 1 .. Number_Dimensions (Unc_Typ) loop
10022
10023            --  Capture the bounds of each index constraint in case the context
10024            --  is an object declaration of an unconstrained type initialized
10025            --  by a function call:
10026
10027            --    Obj : Unconstr_Typ := Func_Call;
10028
10029            --  This scenario requires secondary scope management and the index
10030            --  constraint cannot depend on the temporary used to capture the
10031            --  result of the function call.
10032
10033            --    SS_Mark;
10034            --    Temp : Unconstr_Typ_Ptr := Func_Call'reference;
10035            --    subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last);
10036            --    Obj : S := Temp.all;
10037            --    SS_Release;  --  Temp is gone at this point, bounds of S are
10038            --                 --  non existent.
10039
10040            --  Generate:
10041            --    Low_Bound : constant Base_Type (Index_Typ) := E'First (J);
10042
10043            Low_Bound := Make_Temporary (Loc, 'B');
10044            Insert_Action (E,
10045              Make_Object_Declaration (Loc,
10046                Defining_Identifier => Low_Bound,
10047                Object_Definition   =>
10048                  New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
10049                Constant_Present    => True,
10050                Expression          =>
10051                  Make_Attribute_Reference (Loc,
10052                    Prefix         => Duplicate_Subexpr_No_Checks (E),
10053                    Attribute_Name => Name_First,
10054                    Expressions    => New_List (
10055                      Make_Integer_Literal (Loc, J)))));
10056
10057            --  Generate:
10058            --    High_Bound : constant Base_Type (Index_Typ) := E'Last (J);
10059
10060            High_Bound := Make_Temporary (Loc, 'B');
10061            Insert_Action (E,
10062              Make_Object_Declaration (Loc,
10063                Defining_Identifier => High_Bound,
10064                Object_Definition   =>
10065                  New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
10066                Constant_Present    => True,
10067                Expression          =>
10068                  Make_Attribute_Reference (Loc,
10069                    Prefix         => Duplicate_Subexpr_No_Checks (E),
10070                    Attribute_Name => Name_Last,
10071                    Expressions    => New_List (
10072                      Make_Integer_Literal (Loc, J)))));
10073
10074            Append_To (List_Constr,
10075              Make_Range (Loc,
10076                Low_Bound  => New_Occurrence_Of (Low_Bound,  Loc),
10077                High_Bound => New_Occurrence_Of (High_Bound, Loc)));
10078
10079            Next_Index (Index_Typ);
10080         end loop;
10081
10082      elsif Is_Class_Wide_Type (Unc_Typ) then
10083         declare
10084            CW_Subtype : Entity_Id;
10085            EQ_Typ     : Entity_Id := Empty;
10086
10087         begin
10088            --  A class-wide equivalent type is not needed on VM targets
10089            --  because the VM back-ends handle the class-wide object
10090            --  initialization itself (and doesn't need or want the
10091            --  additional intermediate type to handle the assignment).
10092
10093            if Expander_Active and then Tagged_Type_Expansion then
10094
10095               --  If this is the class-wide type of a completion that is a
10096               --  record subtype, set the type of the class-wide type to be
10097               --  the full base type, for use in the expanded code for the
10098               --  equivalent type. Should this be done earlier when the
10099               --  completion is analyzed ???
10100
10101               if Is_Private_Type (Etype (Unc_Typ))
10102                 and then
10103                   Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
10104               then
10105                  Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
10106               end if;
10107
10108               EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
10109            end if;
10110
10111            CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
10112            Set_Equivalent_Type (CW_Subtype, EQ_Typ);
10113            Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
10114
10115            return New_Occurrence_Of (CW_Subtype, Loc);
10116         end;
10117
10118      --  Indefinite record type with discriminants
10119
10120      else
10121         D := First_Discriminant (Unc_Typ);
10122         while Present (D) loop
10123            Append_To (List_Constr,
10124              Make_Selected_Component (Loc,
10125                Prefix        => Duplicate_Subexpr_No_Checks (E),
10126                Selector_Name => New_Occurrence_Of (D, Loc)));
10127
10128            Next_Discriminant (D);
10129         end loop;
10130      end if;
10131
10132      return
10133        Make_Subtype_Indication (Loc,
10134          Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc),
10135          Constraint   =>
10136            Make_Index_Or_Discriminant_Constraint (Loc,
10137              Constraints => List_Constr));
10138   end Make_Subtype_From_Expr;
10139
10140   -----------------------------
10141   -- Make_Variant_Comparison --
10142   -----------------------------
10143
10144   function Make_Variant_Comparison
10145     (Loc      : Source_Ptr;
10146      Mode     : Name_Id;
10147      Curr_Val : Node_Id;
10148      Old_Val  : Node_Id) return Node_Id
10149   is
10150   begin
10151      if Mode = Name_Increases then
10152         return Make_Op_Gt (Loc, Curr_Val, Old_Val);
10153      else pragma Assert (Mode = Name_Decreases);
10154         return Make_Op_Lt (Loc, Curr_Val, Old_Val);
10155      end if;
10156   end Make_Variant_Comparison;
10157
10158   ---------------
10159   -- Map_Types --
10160   ---------------
10161
10162   procedure Map_Types (Parent_Type : Entity_Id; Derived_Type : Entity_Id) is
10163
10164      --  NOTE: Most of the routines in Map_Types are intentionally unnested to
10165      --  avoid deep indentation of code.
10166
10167      --  NOTE: Routines which deal with discriminant mapping operate on the
10168      --  [underlying/record] full view of various types because those views
10169      --  contain all discriminants and stored constraints.
10170
10171      procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id);
10172      --  Subsidiary to Map_Primitives. Find a primitive in the inheritance or
10173      --  overriding chain starting from Prim whose dispatching type is parent
10174      --  type Par_Typ and add a mapping between the result and primitive Prim.
10175
10176      function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id;
10177      --  Subsidiary to Map_Primitives. Return the next ancestor primitive in
10178      --  the inheritance or overriding chain of subprogram Subp. Return Empty
10179      --  if no such primitive is available.
10180
10181      function Build_Chain
10182        (Par_Typ   : Entity_Id;
10183         Deriv_Typ : Entity_Id) return Elist_Id;
10184      --  Subsidiary to Map_Discriminants. Recreate the derivation chain from
10185      --  parent type Par_Typ leading down towards derived type Deriv_Typ. The
10186      --  list has the form:
10187      --
10188      --    head                                              tail
10189      --    v                                                 v
10190      --    <Ancestor_N> -> <Ancestor_N-1> -> <Ancestor_1> -> Deriv_Typ
10191      --
10192      --  Note that Par_Typ is not part of the resulting derivation chain
10193
10194      function Discriminated_View (Typ : Entity_Id) return Entity_Id;
10195      --  Return the view of type Typ which could potentially contains either
10196      --  the discriminants or stored constraints of the type.
10197
10198      function Find_Discriminant_Value
10199        (Discr     : Entity_Id;
10200         Par_Typ   : Entity_Id;
10201         Deriv_Typ : Entity_Id;
10202         Typ_Elmt  : Elmt_Id) return Node_Or_Entity_Id;
10203      --  Subsidiary to Map_Discriminants. Find the value of discriminant Discr
10204      --  in the derivation chain starting from parent type Par_Typ leading to
10205      --  derived type Deriv_Typ. The returned value is one of the following:
10206      --
10207      --    * An entity which is either a discriminant or a nondiscriminant
10208      --      name, and renames/constraints Discr.
10209      --
10210      --    * An expression which constraints Discr
10211      --
10212      --  Typ_Elmt is an element of the derivation chain created by routine
10213      --  Build_Chain and denotes the current ancestor being examined.
10214
10215      procedure Map_Discriminants
10216        (Par_Typ   : Entity_Id;
10217         Deriv_Typ : Entity_Id);
10218      --  Map each discriminant of type Par_Typ to a meaningful constraint
10219      --  from the point of view of type Deriv_Typ.
10220
10221      procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id);
10222      --  Map each primitive of type Par_Typ to a corresponding primitive of
10223      --  type Deriv_Typ.
10224
10225      -------------------
10226      -- Add_Primitive --
10227      -------------------
10228
10229      procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id) is
10230         Par_Prim : Entity_Id;
10231
10232      begin
10233         --  Inspect the inheritance chain through the Alias attribute and the
10234         --  overriding chain through the Overridden_Operation looking for an
10235         --  ancestor primitive with the appropriate dispatching type.
10236
10237         Par_Prim := Prim;
10238         while Present (Par_Prim) loop
10239            exit when Find_Dispatching_Type (Par_Prim) = Par_Typ;
10240            Par_Prim := Ancestor_Primitive (Par_Prim);
10241         end loop;
10242
10243         --  Create a mapping of the form:
10244
10245         --    parent type primitive -> derived type primitive
10246
10247         if Present (Par_Prim) then
10248            Type_Map.Set (Par_Prim, Prim);
10249         end if;
10250      end Add_Primitive;
10251
10252      ------------------------
10253      -- Ancestor_Primitive --
10254      ------------------------
10255
10256      function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is
10257         Inher_Prim : constant Entity_Id := Alias (Subp);
10258         Over_Prim  : constant Entity_Id := Overridden_Operation (Subp);
10259
10260      begin
10261         --  The current subprogram overrides an ancestor primitive
10262
10263         if Present (Over_Prim) then
10264            return Over_Prim;
10265
10266         --  The current subprogram is an internally generated alias of an
10267         --  inherited ancestor primitive.
10268
10269         elsif Present (Inher_Prim) then
10270            return Inher_Prim;
10271
10272         --  Otherwise the current subprogram is the root of the inheritance or
10273         --  overriding chain.
10274
10275         else
10276            return Empty;
10277         end if;
10278      end Ancestor_Primitive;
10279
10280      -----------------
10281      -- Build_Chain --
10282      -----------------
10283
10284      function Build_Chain
10285        (Par_Typ   : Entity_Id;
10286         Deriv_Typ : Entity_Id) return Elist_Id
10287      is
10288         Anc_Typ  : Entity_Id;
10289         Chain    : Elist_Id;
10290         Curr_Typ : Entity_Id;
10291
10292      begin
10293         Chain := New_Elmt_List;
10294
10295         --  Add the derived type to the derivation chain
10296
10297         Prepend_Elmt (Deriv_Typ, Chain);
10298
10299         --  Examine all ancestors starting from the derived type climbing
10300         --  towards parent type Par_Typ.
10301
10302         Curr_Typ := Deriv_Typ;
10303         loop
10304            --  Handle the case where the current type is a record which
10305            --  derives from a subtype.
10306
10307            --    subtype Sub_Typ is Par_Typ ...
10308            --    type Deriv_Typ is Sub_Typ ...
10309
10310            if Ekind (Curr_Typ) = E_Record_Type
10311              and then Present (Parent_Subtype (Curr_Typ))
10312            then
10313               Anc_Typ := Parent_Subtype (Curr_Typ);
10314
10315            --  Handle the case where the current type is a record subtype of
10316            --  another subtype.
10317
10318            --    subtype Sub_Typ1 is Par_Typ ...
10319            --    subtype Sub_Typ2 is Sub_Typ1 ...
10320
10321            elsif Ekind (Curr_Typ) = E_Record_Subtype
10322              and then Present (Cloned_Subtype (Curr_Typ))
10323            then
10324               Anc_Typ := Cloned_Subtype (Curr_Typ);
10325
10326            --  Otherwise use the direct parent type
10327
10328            else
10329               Anc_Typ := Etype (Curr_Typ);
10330            end if;
10331
10332            --  Use the first subtype when dealing with itypes
10333
10334            if Is_Itype (Anc_Typ) then
10335               Anc_Typ := First_Subtype (Anc_Typ);
10336            end if;
10337
10338            --  Work with the view which contains the discriminants and stored
10339            --  constraints.
10340
10341            Anc_Typ := Discriminated_View (Anc_Typ);
10342
10343            --  Stop the climb when either the parent type has been reached or
10344            --  there are no more ancestors left to examine.
10345
10346            exit when Anc_Typ = Curr_Typ or else Anc_Typ = Par_Typ;
10347
10348            Prepend_Unique_Elmt (Anc_Typ, Chain);
10349            Curr_Typ := Anc_Typ;
10350         end loop;
10351
10352         return Chain;
10353      end Build_Chain;
10354
10355      ------------------------
10356      -- Discriminated_View --
10357      ------------------------
10358
10359      function Discriminated_View (Typ : Entity_Id) return Entity_Id is
10360         T : Entity_Id;
10361
10362      begin
10363         T := Typ;
10364
10365         --  Use the [underlying] full view when dealing with private types
10366         --  because the view contains all inherited discriminants or stored
10367         --  constraints.
10368
10369         if Is_Private_Type (T) then
10370            if Present (Underlying_Full_View (T)) then
10371               T := Underlying_Full_View (T);
10372
10373            elsif Present (Full_View (T)) then
10374               T := Full_View (T);
10375            end if;
10376         end if;
10377
10378         --  Use the underlying record view when the type is an extenstion of
10379         --  a parent type with unknown discriminants because the view contains
10380         --  all inherited discriminants or stored constraints.
10381
10382         if Ekind (T) = E_Record_Type
10383           and then Present (Underlying_Record_View (T))
10384         then
10385            T := Underlying_Record_View (T);
10386         end if;
10387
10388         return T;
10389      end Discriminated_View;
10390
10391      -----------------------------
10392      -- Find_Discriminant_Value --
10393      -----------------------------
10394
10395      function Find_Discriminant_Value
10396        (Discr     : Entity_Id;
10397         Par_Typ   : Entity_Id;
10398         Deriv_Typ : Entity_Id;
10399         Typ_Elmt  : Elmt_Id) return Node_Or_Entity_Id
10400      is
10401         Discr_Pos : constant Uint      := Discriminant_Number (Discr);
10402         Typ       : constant Entity_Id := Node (Typ_Elmt);
10403
10404         function Find_Constraint_Value
10405           (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id;
10406         --  Given constraint Constr, find what it denotes. This is either:
10407         --
10408         --    * An entity which is either a discriminant or a name
10409         --
10410         --    * An expression
10411
10412         ---------------------------
10413         -- Find_Constraint_Value --
10414         ---------------------------
10415
10416         function Find_Constraint_Value
10417           (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id
10418         is
10419         begin
10420            if Nkind (Constr) in N_Entity then
10421
10422               --  The constraint denotes a discriminant of the curren type
10423               --  which renames the ancestor discriminant:
10424
10425               --              vv
10426               --    type Typ (D1 : ...; DN : ...) is
10427               --      new Anc (Discr => D1) with ...
10428               --                        ^^
10429
10430               if Ekind (Constr) = E_Discriminant then
10431
10432                  --  The discriminant belongs to derived type Deriv_Typ. This
10433                  --  is the final value for the ancestor discriminant as the
10434                  --  derivations chain has been fully exhausted.
10435
10436                  if Typ = Deriv_Typ then
10437                     return Constr;
10438
10439                  --  Otherwise the discriminant may be renamed or constrained
10440                  --  at a lower level. Continue looking down the derivation
10441                  --  chain.
10442
10443                  else
10444                     return
10445                       Find_Discriminant_Value
10446                         (Discr     => Constr,
10447                          Par_Typ   => Par_Typ,
10448                          Deriv_Typ => Deriv_Typ,
10449                          Typ_Elmt  => Next_Elmt (Typ_Elmt));
10450                  end if;
10451
10452               --  Otherwise the constraint denotes a reference to some name
10453               --  which results in a Girder discriminant:
10454
10455               --    vvvv
10456               --    Name : ...;
10457               --    type Typ (D1 : ...; DN : ...) is
10458               --      new Anc (Discr => Name) with ...
10459               --                        ^^^^
10460
10461               --  Return the name as this is the proper constraint of the
10462               --  discriminant.
10463
10464               else
10465                  return Constr;
10466               end if;
10467
10468            --  The constraint denotes a reference to a name
10469
10470            elsif Is_Entity_Name (Constr) then
10471               return Find_Constraint_Value (Entity (Constr));
10472
10473            --  Otherwise the current constraint is an expression which yields
10474            --  a Girder discriminant:
10475
10476            --    type Typ (D1 : ...; DN : ...) is
10477            --      new Anc (Discr => <expression>) with ...
10478            --                         ^^^^^^^^^^
10479
10480            --  Return the expression as this is the proper constraint of the
10481            --  discriminant.
10482
10483            else
10484               return Constr;
10485            end if;
10486         end Find_Constraint_Value;
10487
10488         --  Local variables
10489
10490         Constrs : constant Elist_Id := Stored_Constraint (Typ);
10491
10492         Constr_Elmt : Elmt_Id;
10493         Pos         : Uint;
10494         Typ_Discr   : Entity_Id;
10495
10496      --  Start of processing for Find_Discriminant_Value
10497
10498      begin
10499         --  The algorithm for finding the value of a discriminant works as
10500         --  follows. First, it recreates the derivation chain from Par_Typ
10501         --  to Deriv_Typ as a list:
10502
10503         --     Par_Typ      (shown for completeness)
10504         --        v
10505         --    Ancestor_N  <-- head of chain
10506         --        v
10507         --    Ancestor_1
10508         --        v
10509         --    Deriv_Typ   <--  tail of chain
10510
10511         --  The algorithm then traces the fate of a parent discriminant down
10512         --  the derivation chain. At each derivation level, the discriminant
10513         --  may be either inherited or constrained.
10514
10515         --    1) Discriminant is inherited: there are two cases, depending on
10516         --    which type is inheriting.
10517
10518         --    1.1) Deriv_Typ is inheriting:
10519
10520         --      type Ancestor (D_1 : ...) is tagged ...
10521         --      type Deriv_Typ is new Ancestor ...
10522
10523         --    In this case the inherited discriminant is the final value of
10524         --    the parent discriminant because the end of the derivation chain
10525         --    has been reached.
10526
10527         --    1.2) Some other type is inheriting:
10528
10529         --      type Ancestor_1 (D_1 : ...) is tagged ...
10530         --      type Ancestor_2 is new Ancestor_1 ...
10531
10532         --    In this case the algorithm continues to trace the fate of the
10533         --    inherited discriminant down the derivation chain because it may
10534         --    be further inherited or constrained.
10535
10536         --    2) Discriminant is constrained: there are three cases, depending
10537         --    on what the constraint is.
10538
10539         --    2.1) The constraint is another discriminant (aka renaming):
10540
10541         --      type Ancestor_1 (D_1 : ...) is tagged ...
10542         --      type Ancestor_2 (D_2 : ...) is new Ancestor_1 (D_1 => D_2) ...
10543
10544         --    In this case the constraining discriminant becomes the one to
10545         --    track down the derivation chain. The algorithm already knows
10546         --    that D_2 constrains D_1, therefore if the algorithm finds the
10547         --    value of D_2, then this would also be the value for D_1.
10548
10549         --    2.2) The constraint is a name (aka Girder):
10550
10551         --      Name : ...
10552         --      type Ancestor_1 (D_1 : ...) is tagged ...
10553         --      type Ancestor_2 is new Ancestor_1 (D_1 => Name) ...
10554
10555         --    In this case the name is the final value of D_1 because the
10556         --    discriminant cannot be further constrained.
10557
10558         --    2.3) The constraint is an expression (aka Girder):
10559
10560         --      type Ancestor_1 (D_1 : ...) is tagged ...
10561         --      type Ancestor_2 is new Ancestor_1 (D_1 => 1 + 2) ...
10562
10563         --    Similar to 2.2, the expression is the final value of D_1
10564
10565         Pos := Uint_1;
10566
10567         --  When a derived type constrains its parent type, all constaints
10568         --  appear in the Stored_Constraint list. Examine the list looking
10569         --  for a positional match.
10570
10571         if Present (Constrs) then
10572            Constr_Elmt := First_Elmt (Constrs);
10573            while Present (Constr_Elmt) loop
10574
10575               --  The position of the current constraint matches that of the
10576               --  ancestor discriminant.
10577
10578               if Pos = Discr_Pos then
10579                  return Find_Constraint_Value (Node (Constr_Elmt));
10580               end if;
10581
10582               Next_Elmt (Constr_Elmt);
10583               Pos := Pos + 1;
10584            end loop;
10585
10586         --  Otherwise the derived type does not constraint its parent type in
10587         --  which case it inherits the parent discriminants.
10588
10589         else
10590            Typ_Discr := First_Discriminant (Typ);
10591            while Present (Typ_Discr) loop
10592
10593               --  The position of the current discriminant matches that of the
10594               --  ancestor discriminant.
10595
10596               if Pos = Discr_Pos then
10597                  return Find_Constraint_Value (Typ_Discr);
10598               end if;
10599
10600               Next_Discriminant (Typ_Discr);
10601               Pos := Pos + 1;
10602            end loop;
10603         end if;
10604
10605         --  A discriminant must always have a corresponding value. This is
10606         --  either another discriminant, a name, or an expression. If this
10607         --  point is reached, them most likely the derivation chain employs
10608         --  the wrong views of types.
10609
10610         pragma Assert (False);
10611
10612         return Empty;
10613      end Find_Discriminant_Value;
10614
10615      -----------------------
10616      -- Map_Discriminants --
10617      -----------------------
10618
10619      procedure Map_Discriminants
10620        (Par_Typ   : Entity_Id;
10621         Deriv_Typ : Entity_Id)
10622      is
10623         Deriv_Chain : constant Elist_Id := Build_Chain (Par_Typ, Deriv_Typ);
10624
10625         Discr     : Entity_Id;
10626         Discr_Val : Node_Or_Entity_Id;
10627
10628      begin
10629         --  Examine each discriminant of parent type Par_Typ and find a
10630         --  suitable value for it from the point of view of derived type
10631         --  Deriv_Typ.
10632
10633         if Has_Discriminants (Par_Typ) then
10634            Discr := First_Discriminant (Par_Typ);
10635            while Present (Discr) loop
10636               Discr_Val :=
10637                 Find_Discriminant_Value
10638                   (Discr     => Discr,
10639                    Par_Typ   => Par_Typ,
10640                    Deriv_Typ => Deriv_Typ,
10641                    Typ_Elmt  => First_Elmt (Deriv_Chain));
10642
10643               --  Create a mapping of the form:
10644
10645               --    parent type discriminant -> value
10646
10647               Type_Map.Set (Discr, Discr_Val);
10648
10649               Next_Discriminant (Discr);
10650            end loop;
10651         end if;
10652      end Map_Discriminants;
10653
10654      --------------------
10655      -- Map_Primitives --
10656      --------------------
10657
10658      procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id) is
10659         Deriv_Prim : Entity_Id;
10660         Par_Prim   : Entity_Id;
10661         Par_Prims  : Elist_Id;
10662         Prim_Elmt  : Elmt_Id;
10663
10664      begin
10665         --  Inspect the primitives of the derived type and determine whether
10666         --  they relate to the primitives of the parent type. If there is a
10667         --  meaningful relation, create a mapping of the form:
10668
10669         --    parent type primitive -> perived type primitive
10670
10671         if Present (Direct_Primitive_Operations (Deriv_Typ)) then
10672            Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ));
10673            while Present (Prim_Elmt) loop
10674               Deriv_Prim := Node (Prim_Elmt);
10675
10676               if Is_Subprogram (Deriv_Prim)
10677                 and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ
10678               then
10679                  Add_Primitive (Deriv_Prim, Par_Typ);
10680               end if;
10681
10682               Next_Elmt (Prim_Elmt);
10683            end loop;
10684         end if;
10685
10686         --  If the parent operation is an interface operation, the overriding
10687         --  indicator is not present. Instead, we get from the interface
10688         --  operation the primitive of the current type that implements it.
10689
10690         if Is_Interface (Par_Typ) then
10691            Par_Prims := Collect_Primitive_Operations (Par_Typ);
10692
10693            if Present (Par_Prims) then
10694               Prim_Elmt := First_Elmt (Par_Prims);
10695
10696               while Present (Prim_Elmt) loop
10697                  Par_Prim   := Node (Prim_Elmt);
10698                  Deriv_Prim :=
10699                    Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim);
10700
10701                  if Present (Deriv_Prim) then
10702                     Type_Map.Set (Par_Prim, Deriv_Prim);
10703                  end if;
10704
10705                  Next_Elmt (Prim_Elmt);
10706               end loop;
10707            end if;
10708         end if;
10709      end Map_Primitives;
10710
10711   --  Start of processing for Map_Types
10712
10713   begin
10714      --  Nothing to do if there are no types to work with
10715
10716      if No (Parent_Type) or else No (Derived_Type) then
10717         return;
10718
10719      --  Nothing to do if the mapping already exists
10720
10721      elsif Type_Map.Get (Parent_Type) = Derived_Type then
10722         return;
10723
10724      --  Nothing to do if both types are not tagged. Note that untagged types
10725      --  do not have primitive operations and their discriminants are already
10726      --  handled by gigi.
10727
10728      elsif not Is_Tagged_Type (Parent_Type)
10729        or else not Is_Tagged_Type (Derived_Type)
10730      then
10731         return;
10732      end if;
10733
10734      --  Create a mapping of the form
10735
10736      --    parent type -> derived type
10737
10738      --  to prevent any subsequent attempts to produce the same relations
10739
10740      Type_Map.Set (Parent_Type, Derived_Type);
10741
10742      --  Create mappings of the form
10743
10744      --    parent type discriminant -> derived type discriminant
10745      --      <or>
10746      --    parent type discriminant -> constraint
10747
10748      --  Note that mapping of discriminants breaks privacy because it needs to
10749      --  work with those views which contains the discriminants and any stored
10750      --  constraints.
10751
10752      Map_Discriminants
10753        (Par_Typ   => Discriminated_View (Parent_Type),
10754         Deriv_Typ => Discriminated_View (Derived_Type));
10755
10756      --  Create mappings of the form
10757
10758      --    parent type primitive -> derived type primitive
10759
10760      Map_Primitives
10761        (Par_Typ   => Parent_Type,
10762         Deriv_Typ => Derived_Type);
10763   end Map_Types;
10764
10765   ----------------------------
10766   -- Matching_Standard_Type --
10767   ----------------------------
10768
10769   function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is
10770      pragma Assert (Is_Scalar_Type (Typ));
10771      Siz : constant Uint := Esize (Typ);
10772
10773   begin
10774      --  Floating-point cases
10775
10776      if Is_Floating_Point_Type (Typ) then
10777         if Siz <= Esize (Standard_Short_Float) then
10778            return Standard_Short_Float;
10779         elsif Siz <= Esize (Standard_Float) then
10780            return Standard_Float;
10781         elsif Siz <= Esize (Standard_Long_Float) then
10782            return Standard_Long_Float;
10783         elsif Siz <= Esize (Standard_Long_Long_Float) then
10784            return Standard_Long_Long_Float;
10785         else
10786            raise Program_Error;
10787         end if;
10788
10789      --  Integer cases (includes fixed-point types)
10790
10791      --  Unsigned integer cases (includes normal enumeration types)
10792
10793      else
10794         return Small_Integer_Type_For (Siz, Is_Unsigned_Type (Typ));
10795      end if;
10796   end Matching_Standard_Type;
10797
10798   -----------------------------
10799   -- May_Generate_Large_Temp --
10800   -----------------------------
10801
10802   --  At the current time, the only types that we return False for (i.e. where
10803   --  we decide we know they cannot generate large temps) are ones where we
10804   --  know the size is 256 bits or less at compile time, and we are still not
10805   --  doing a thorough job on arrays and records ???
10806
10807   function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
10808   begin
10809      if not Size_Known_At_Compile_Time (Typ) then
10810         return False;
10811
10812      elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
10813         return False;
10814
10815      elsif Is_Array_Type (Typ)
10816        and then Present (Packed_Array_Impl_Type (Typ))
10817      then
10818         return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ));
10819
10820      --  We could do more here to find other small types ???
10821
10822      else
10823         return True;
10824      end if;
10825   end May_Generate_Large_Temp;
10826
10827   --------------------------------------------
10828   -- Needs_Conditional_Null_Excluding_Check --
10829   --------------------------------------------
10830
10831   function Needs_Conditional_Null_Excluding_Check
10832     (Typ : Entity_Id) return Boolean
10833   is
10834   begin
10835      return
10836        Is_Array_Type (Typ) and then Can_Never_Be_Null (Component_Type (Typ));
10837   end Needs_Conditional_Null_Excluding_Check;
10838
10839   ----------------------------
10840   -- Needs_Constant_Address --
10841   ----------------------------
10842
10843   function Needs_Constant_Address
10844     (Decl : Node_Id;
10845      Typ  : Entity_Id) return Boolean
10846   is
10847   begin
10848      --  If we have no initialization of any kind, then we don't need to place
10849      --  any restrictions on the address clause, because the object will be
10850      --  elaborated after the address clause is evaluated. This happens if the
10851      --  declaration has no initial expression, or the type has no implicit
10852      --  initialization, or the object is imported.
10853
10854      --  The same holds for all initialized scalar types and all access types.
10855      --  Packed bit array types of size up to the maximum integer size are
10856      --  represented using a modular type with an initialization (to zero) and
10857      --  can be processed like other initialized scalar types.
10858
10859      --  If the type is controlled, code to attach the object to a
10860      --  finalization chain is generated at the point of declaration, and
10861      --  therefore the elaboration of the object cannot be delayed: the
10862      --  address expression must be a constant.
10863
10864      if No (Expression (Decl))
10865        and then not Needs_Finalization (Typ)
10866        and then
10867          (not Has_Non_Null_Base_Init_Proc (Typ)
10868            or else Is_Imported (Defining_Identifier (Decl)))
10869      then
10870         return False;
10871
10872      elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
10873        or else Is_Access_Type (Typ)
10874        or else
10875          (Is_Bit_Packed_Array (Typ)
10876            and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)))
10877      then
10878         return False;
10879
10880      else
10881         --  Otherwise, we require the address clause to be constant because
10882         --  the call to the initialization procedure (or the attach code) has
10883         --  to happen at the point of the declaration.
10884
10885         --  Actually the IP call has been moved to the freeze actions anyway,
10886         --  so maybe we can relax this restriction???
10887
10888         return True;
10889      end if;
10890   end Needs_Constant_Address;
10891
10892   ----------------------------
10893   -- New_Class_Wide_Subtype --
10894   ----------------------------
10895
10896   function New_Class_Wide_Subtype
10897     (CW_Typ : Entity_Id;
10898      N      : Node_Id) return Entity_Id
10899   is
10900      Res : constant Entity_Id := Create_Itype (E_Void, N);
10901
10902      --  Capture relevant attributes of the class-wide subtype which must be
10903      --  restored after the copy.
10904
10905      Res_Chars  : constant Name_Id   := Chars (Res);
10906      Res_Is_CGE : constant Boolean   := Is_Checked_Ghost_Entity (Res);
10907      Res_Is_IGE : constant Boolean   := Is_Ignored_Ghost_Entity (Res);
10908      Res_Is_IGN : constant Boolean   := Is_Ignored_Ghost_Node   (Res);
10909      Res_Scope  : constant Entity_Id := Scope (Res);
10910
10911   begin
10912      Copy_Node (CW_Typ, Res);
10913
10914      --  Restore the relevant attributes of the class-wide subtype
10915
10916      Set_Chars                   (Res, Res_Chars);
10917      Set_Is_Checked_Ghost_Entity (Res, Res_Is_CGE);
10918      Set_Is_Ignored_Ghost_Entity (Res, Res_Is_IGE);
10919      Set_Is_Ignored_Ghost_Node   (Res, Res_Is_IGN);
10920      Set_Scope                   (Res, Res_Scope);
10921
10922      --  Decorate the class-wide subtype
10923
10924      Set_Associated_Node_For_Itype (Res, N);
10925      Set_Comes_From_Source         (Res, False);
10926      Set_Ekind                     (Res, E_Class_Wide_Subtype);
10927      Set_Etype                     (Res, Base_Type (CW_Typ));
10928      Set_Freeze_Node               (Res, Empty);
10929      Set_Is_Frozen                 (Res, False);
10930      Set_Is_Itype                  (Res);
10931      Set_Is_Public                 (Res, False);
10932      Set_Next_Entity               (Res, Empty);
10933      Set_Prev_Entity               (Res, Empty);
10934      Set_Sloc                      (Res, Sloc (N));
10935
10936      Set_Public_Status (Res);
10937
10938      return Res;
10939   end New_Class_Wide_Subtype;
10940
10941   -----------------------------------
10942   -- OK_To_Do_Constant_Replacement --
10943   -----------------------------------
10944
10945   function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
10946      ES : constant Entity_Id := Scope (E);
10947      CS : Entity_Id;
10948
10949   begin
10950      --  Do not replace statically allocated objects, because they may be
10951      --  modified outside the current scope.
10952
10953      if Is_Statically_Allocated (E) then
10954         return False;
10955
10956      --  Do not replace aliased or volatile objects, since we don't know what
10957      --  else might change the value.
10958
10959      elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
10960         return False;
10961
10962      --  Debug flag -gnatdM disconnects this optimization
10963
10964      elsif Debug_Flag_MM then
10965         return False;
10966
10967      --  Otherwise check scopes
10968
10969      else
10970         CS := Current_Scope;
10971
10972         loop
10973            --  If we are in right scope, replacement is safe
10974
10975            if CS = ES then
10976               return True;
10977
10978            --  Packages do not affect the determination of safety
10979
10980            elsif Ekind (CS) = E_Package then
10981               exit when CS = Standard_Standard;
10982               CS := Scope (CS);
10983
10984            --  Blocks do not affect the determination of safety
10985
10986            elsif Ekind (CS) = E_Block then
10987               CS := Scope (CS);
10988
10989            --  Loops do not affect the determination of safety. Note that we
10990            --  kill all current values on entry to a loop, so we are just
10991            --  talking about processing within a loop here.
10992
10993            elsif Ekind (CS) = E_Loop then
10994               CS := Scope (CS);
10995
10996            --  Otherwise, the reference is dubious, and we cannot be sure that
10997            --  it is safe to do the replacement.
10998
10999            else
11000               exit;
11001            end if;
11002         end loop;
11003
11004         return False;
11005      end if;
11006   end OK_To_Do_Constant_Replacement;
11007
11008   ------------------------------------
11009   -- Possible_Bit_Aligned_Component --
11010   ------------------------------------
11011
11012   function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
11013   begin
11014      --  Do not process an unanalyzed node because it is not yet decorated and
11015      --  most checks performed below will fail.
11016
11017      if not Analyzed (N) then
11018         return False;
11019      end if;
11020
11021      --  There are never alignment issues in CodePeer mode
11022
11023      if CodePeer_Mode then
11024         return False;
11025      end if;
11026
11027      case Nkind (N) is
11028
11029         --  Case of indexed component
11030
11031         when N_Indexed_Component =>
11032            declare
11033               P    : constant Node_Id   := Prefix (N);
11034               Ptyp : constant Entity_Id := Etype (P);
11035
11036            begin
11037               --  If we know the component size and it is not larger than the
11038               --  maximum integer size, then we are OK. The back end does the
11039               --  assignment of small misaligned objects correctly.
11040
11041               if Known_Static_Component_Size (Ptyp)
11042                 and then Component_Size (Ptyp) <= System_Max_Integer_Size
11043               then
11044                  return False;
11045
11046               --  Otherwise, we need to test the prefix, to see if we are
11047               --  indexing from a possibly unaligned component.
11048
11049               else
11050                  return Possible_Bit_Aligned_Component (P);
11051               end if;
11052            end;
11053
11054         --  Case of selected component
11055
11056         when N_Selected_Component =>
11057            declare
11058               P    : constant Node_Id   := Prefix (N);
11059               Comp : constant Entity_Id := Entity (Selector_Name (N));
11060
11061            begin
11062               --  This is the crucial test: if the component itself causes
11063               --  trouble, then we can stop and return True.
11064
11065               if Component_May_Be_Bit_Aligned (Comp) then
11066                  return True;
11067
11068               --  Otherwise, we need to test the prefix, to see if we are
11069               --  selecting from a possibly unaligned component.
11070
11071               else
11072                  return Possible_Bit_Aligned_Component (P);
11073               end if;
11074            end;
11075
11076         --  For a slice, test the prefix, if that is possibly misaligned,
11077         --  then for sure the slice is.
11078
11079         when N_Slice =>
11080            return Possible_Bit_Aligned_Component (Prefix (N));
11081
11082         --  For an unchecked conversion, check whether the expression may
11083         --  be bit aligned.
11084
11085         when N_Unchecked_Type_Conversion =>
11086            return Possible_Bit_Aligned_Component (Expression (N));
11087
11088         --  If we have none of the above, it means that we have fallen off the
11089         --  top testing prefixes recursively, and we now have a stand alone
11090         --  object, where we don't have a problem, unless this is a renaming,
11091         --  in which case we need to look into the renamed object.
11092
11093         when others =>
11094            if Is_Entity_Name (N)
11095              and then Present (Renamed_Object (Entity (N)))
11096            then
11097               return
11098                 Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
11099            else
11100               return False;
11101            end if;
11102      end case;
11103   end Possible_Bit_Aligned_Component;
11104
11105   -----------------------------------------------
11106   -- Process_Statements_For_Controlled_Objects --
11107   -----------------------------------------------
11108
11109   procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
11110      Loc : constant Source_Ptr := Sloc (N);
11111
11112      function Are_Wrapped (L : List_Id) return Boolean;
11113      --  Determine whether list L contains only one statement which is a block
11114
11115      function Wrap_Statements_In_Block
11116        (L    : List_Id;
11117         Scop : Entity_Id := Current_Scope) return Node_Id;
11118      --  Given a list of statements L, wrap it in a block statement and return
11119      --  the generated node. Scop is either the current scope or the scope of
11120      --  the context (if applicable).
11121
11122      -----------------
11123      -- Are_Wrapped --
11124      -----------------
11125
11126      function Are_Wrapped (L : List_Id) return Boolean is
11127         Stmt : constant Node_Id := First (L);
11128      begin
11129         return
11130           Present (Stmt)
11131             and then No (Next (Stmt))
11132             and then Nkind (Stmt) = N_Block_Statement;
11133      end Are_Wrapped;
11134
11135      ------------------------------
11136      -- Wrap_Statements_In_Block --
11137      ------------------------------
11138
11139      function Wrap_Statements_In_Block
11140        (L    : List_Id;
11141         Scop : Entity_Id := Current_Scope) return Node_Id
11142      is
11143         Block_Id  : Entity_Id;
11144         Block_Nod : Node_Id;
11145         Iter_Loop : Entity_Id;
11146
11147      begin
11148         Block_Nod :=
11149           Make_Block_Statement (Loc,
11150             Declarations               => No_List,
11151             Handled_Statement_Sequence =>
11152               Make_Handled_Sequence_Of_Statements (Loc,
11153                 Statements => L));
11154
11155         --  Create a label for the block in case the block needs to manage the
11156         --  secondary stack. A label allows for flag Uses_Sec_Stack to be set.
11157
11158         Add_Block_Identifier (Block_Nod, Block_Id);
11159
11160         --  When wrapping the statements of an iterator loop, check whether
11161         --  the loop requires secondary stack management and if so, propagate
11162         --  the appropriate flags to the block. This ensures that the cursor
11163         --  is properly cleaned up at each iteration of the loop.
11164
11165         Iter_Loop := Find_Enclosing_Iterator_Loop (Scop);
11166
11167         if Present (Iter_Loop) then
11168            Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop));
11169
11170            --  Secondary stack reclamation is suppressed when the associated
11171            --  iterator loop contains a return statement which uses the stack.
11172
11173            Set_Sec_Stack_Needed_For_Return
11174              (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop));
11175         end if;
11176
11177         return Block_Nod;
11178      end Wrap_Statements_In_Block;
11179
11180      --  Local variables
11181
11182      Block : Node_Id;
11183
11184   --  Start of processing for Process_Statements_For_Controlled_Objects
11185
11186   begin
11187      --  Whenever a non-handled statement list is wrapped in a block, the
11188      --  block must be explicitly analyzed to redecorate all entities in the
11189      --  list and ensure that a finalizer is properly built.
11190
11191      case Nkind (N) is
11192         when N_Conditional_Entry_Call
11193            | N_Elsif_Part
11194            | N_If_Statement
11195            | N_Selective_Accept
11196         =>
11197            --  Check the "then statements" for elsif parts and if statements
11198
11199            if Nkind (N) in N_Elsif_Part | N_If_Statement
11200              and then not Is_Empty_List (Then_Statements (N))
11201              and then not Are_Wrapped (Then_Statements (N))
11202              and then Requires_Cleanup_Actions
11203                         (L                 => Then_Statements (N),
11204                          Lib_Level         => False,
11205                          Nested_Constructs => False)
11206            then
11207               Block := Wrap_Statements_In_Block (Then_Statements (N));
11208               Set_Then_Statements (N, New_List (Block));
11209
11210               Analyze (Block);
11211            end if;
11212
11213            --  Check the "else statements" for conditional entry calls, if
11214            --  statements and selective accepts.
11215
11216            if Nkind (N) in
11217                 N_Conditional_Entry_Call | N_If_Statement | N_Selective_Accept
11218              and then not Is_Empty_List (Else_Statements (N))
11219              and then not Are_Wrapped (Else_Statements (N))
11220              and then Requires_Cleanup_Actions
11221                         (L                 => Else_Statements (N),
11222                          Lib_Level         => False,
11223                          Nested_Constructs => False)
11224            then
11225               Block := Wrap_Statements_In_Block (Else_Statements (N));
11226               Set_Else_Statements (N, New_List (Block));
11227
11228               Analyze (Block);
11229            end if;
11230
11231         when N_Abortable_Part
11232            | N_Accept_Alternative
11233            | N_Case_Statement_Alternative
11234            | N_Delay_Alternative
11235            | N_Entry_Call_Alternative
11236            | N_Exception_Handler
11237            | N_Loop_Statement
11238            | N_Triggering_Alternative
11239         =>
11240            if not Is_Empty_List (Statements (N))
11241              and then not Are_Wrapped (Statements (N))
11242              and then Requires_Cleanup_Actions
11243                         (L                 => Statements (N),
11244                          Lib_Level         => False,
11245                          Nested_Constructs => False)
11246            then
11247               if Nkind (N) = N_Loop_Statement
11248                 and then Present (Identifier (N))
11249               then
11250                  Block :=
11251                    Wrap_Statements_In_Block
11252                      (L    => Statements (N),
11253                       Scop => Entity (Identifier (N)));
11254               else
11255                  Block := Wrap_Statements_In_Block (Statements (N));
11256               end if;
11257
11258               Set_Statements (N, New_List (Block));
11259               Analyze (Block);
11260            end if;
11261
11262         --  Could be e.g. a loop that was transformed into a block or null
11263         --  statement. Do nothing for terminate alternatives.
11264
11265         when N_Block_Statement
11266            | N_Null_Statement
11267            | N_Terminate_Alternative
11268         =>
11269            null;
11270
11271         when others =>
11272            raise Program_Error;
11273      end case;
11274   end Process_Statements_For_Controlled_Objects;
11275
11276   ------------------
11277   -- Power_Of_Two --
11278   ------------------
11279
11280   function Power_Of_Two (N : Node_Id) return Nat is
11281      Typ : constant Entity_Id := Etype (N);
11282      pragma Assert (Is_Integer_Type (Typ));
11283
11284      Siz : constant Nat := UI_To_Int (Esize (Typ));
11285      Val : Uint;
11286
11287   begin
11288      if not Compile_Time_Known_Value (N) then
11289         return 0;
11290
11291      else
11292         Val := Expr_Value (N);
11293         for J in 1 .. Siz - 1 loop
11294            if Val = Uint_2 ** J then
11295               return J;
11296            end if;
11297         end loop;
11298
11299         return 0;
11300      end if;
11301   end Power_Of_Two;
11302
11303   ----------------------
11304   -- Remove_Init_Call --
11305   ----------------------
11306
11307   function Remove_Init_Call
11308     (Var        : Entity_Id;
11309      Rep_Clause : Node_Id) return Node_Id
11310   is
11311      Par : constant Node_Id   := Parent (Var);
11312      Typ : constant Entity_Id := Etype (Var);
11313
11314      Init_Proc : Entity_Id;
11315      --  Initialization procedure for Typ
11316
11317      function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
11318      --  Look for init call for Var starting at From and scanning the
11319      --  enclosing list until Rep_Clause or the end of the list is reached.
11320
11321      ----------------------------
11322      -- Find_Init_Call_In_List --
11323      ----------------------------
11324
11325      function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
11326         Init_Call : Node_Id;
11327
11328      begin
11329         Init_Call := From;
11330         while Present (Init_Call) and then Init_Call /= Rep_Clause loop
11331            if Nkind (Init_Call) = N_Procedure_Call_Statement
11332              and then Is_Entity_Name (Name (Init_Call))
11333              and then Entity (Name (Init_Call)) = Init_Proc
11334            then
11335               return Init_Call;
11336            end if;
11337
11338            Next (Init_Call);
11339         end loop;
11340
11341         return Empty;
11342      end Find_Init_Call_In_List;
11343
11344      Init_Call : Node_Id;
11345
11346   --  Start of processing for Find_Init_Call
11347
11348   begin
11349      if Present (Initialization_Statements (Var)) then
11350         Init_Call := Initialization_Statements (Var);
11351         Set_Initialization_Statements (Var, Empty);
11352
11353      elsif not Has_Non_Null_Base_Init_Proc (Typ) then
11354
11355         --  No init proc for the type, so obviously no call to be found
11356
11357         return Empty;
11358
11359      else
11360         --  We might be able to handle other cases below by just properly
11361         --  setting Initialization_Statements at the point where the init proc
11362         --  call is generated???
11363
11364         Init_Proc := Base_Init_Proc (Typ);
11365
11366         --  First scan the list containing the declaration of Var
11367
11368         Init_Call := Find_Init_Call_In_List (From => Next (Par));
11369
11370         --  If not found, also look on Var's freeze actions list, if any,
11371         --  since the init call may have been moved there (case of an address
11372         --  clause applying to Var).
11373
11374         if No (Init_Call) and then Present (Freeze_Node (Var)) then
11375            Init_Call :=
11376              Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
11377         end if;
11378
11379         --  If the initialization call has actuals that use the secondary
11380         --  stack, the call may have been wrapped into a temporary block, in
11381         --  which case the block itself has to be removed.
11382
11383         if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
11384            declare
11385               Blk : constant Node_Id := Next (Par);
11386            begin
11387               if Present
11388                    (Find_Init_Call_In_List
11389                      (First (Statements (Handled_Statement_Sequence (Blk)))))
11390               then
11391                  Init_Call := Blk;
11392               end if;
11393            end;
11394         end if;
11395      end if;
11396
11397      if Present (Init_Call) then
11398         Remove (Init_Call);
11399      end if;
11400      return Init_Call;
11401   end Remove_Init_Call;
11402
11403   -------------------------
11404   -- Remove_Side_Effects --
11405   -------------------------
11406
11407   procedure Remove_Side_Effects
11408     (Exp                : Node_Id;
11409      Name_Req           : Boolean   := False;
11410      Renaming_Req       : Boolean   := False;
11411      Variable_Ref       : Boolean   := False;
11412      Related_Id         : Entity_Id := Empty;
11413      Is_Low_Bound       : Boolean   := False;
11414      Is_High_Bound      : Boolean   := False;
11415      Check_Side_Effects : Boolean   := True)
11416   is
11417      function Build_Temporary
11418        (Loc         : Source_Ptr;
11419         Id          : Character;
11420         Related_Nod : Node_Id := Empty) return Entity_Id;
11421      --  Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod
11422      --  is present (xxx is taken from the Chars field of Related_Nod),
11423      --  otherwise it generates an internal temporary. The created temporary
11424      --  entity is marked as internal.
11425
11426      function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean;
11427      --  Computes whether a side effect is possible in SPARK, which should
11428      --  be handled by removing it from the expression for GNATprove. Note
11429      --  that other side effects related to volatile variables are handled
11430      --  separately.
11431
11432      ---------------------
11433      -- Build_Temporary --
11434      ---------------------
11435
11436      function Build_Temporary
11437        (Loc         : Source_Ptr;
11438         Id          : Character;
11439         Related_Nod : Node_Id := Empty) return Entity_Id
11440      is
11441         Temp_Id  : Entity_Id;
11442         Temp_Nam : Name_Id;
11443
11444      begin
11445         --  The context requires an external symbol
11446
11447         if Present (Related_Id) then
11448            if Is_Low_Bound then
11449               Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST");
11450            else pragma Assert (Is_High_Bound);
11451               Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST");
11452            end if;
11453
11454            Temp_Id := Make_Defining_Identifier (Loc, Temp_Nam);
11455
11456         --  Otherwise generate an internal temporary
11457
11458         else
11459            Temp_Id := Make_Temporary (Loc, Id, Related_Nod);
11460         end if;
11461
11462         Set_Is_Internal (Temp_Id);
11463
11464         return Temp_Id;
11465      end Build_Temporary;
11466
11467      -----------------------------------
11468      -- Possible_Side_Effect_In_SPARK --
11469      -----------------------------------
11470
11471      function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean is
11472      begin
11473        --  Side-effect removal in SPARK should only occur when not inside a
11474        --  generic and not doing a preanalysis, inside an object renaming or
11475        --  a type declaration or a for-loop iteration scheme.
11476
11477         return not Inside_A_Generic
11478           and then Full_Analysis
11479           and then Nkind (Enclosing_Declaration (Exp)) in
11480                      N_Full_Type_Declaration
11481                    | N_Iterator_Specification
11482                    | N_Loop_Parameter_Specification
11483                    | N_Object_Renaming_Declaration
11484                    | N_Subtype_Declaration;
11485      end Possible_Side_Effect_In_SPARK;
11486
11487      --  Local variables
11488
11489      Loc          : constant Source_Ptr      := Sloc (Exp);
11490      Exp_Type     : constant Entity_Id       := Etype (Exp);
11491      Svg_Suppress : constant Suppress_Record := Scope_Suppress;
11492      Def_Id       : Entity_Id;
11493      E            : Node_Id;
11494      New_Exp      : Node_Id;
11495      Ptr_Typ_Decl : Node_Id;
11496      Ref_Type     : Entity_Id;
11497      Res          : Node_Id;
11498
11499   --  Start of processing for Remove_Side_Effects
11500
11501   begin
11502      --  Handle cases in which there is nothing to do. In GNATprove mode,
11503      --  removal of side effects is useful for the light expansion of
11504      --  renamings.
11505
11506      if not Expander_Active
11507        and then not
11508          (GNATprove_Mode and then Possible_Side_Effect_In_SPARK (Exp))
11509      then
11510         return;
11511
11512      --  Cannot generate temporaries if the invocation to remove side effects
11513      --  was issued too early and the type of the expression is not resolved
11514      --  (this happens because routines Duplicate_Subexpr_XX implicitly invoke
11515      --  Remove_Side_Effects).
11516
11517      elsif No (Exp_Type)
11518        or else Ekind (Exp_Type) = E_Access_Attribute_Type
11519      then
11520         return;
11521
11522      --  Nothing to do if prior expansion determined that a function call does
11523      --  not require side effect removal.
11524
11525      elsif Nkind (Exp) = N_Function_Call
11526        and then No_Side_Effect_Removal (Exp)
11527      then
11528         return;
11529
11530      --  No action needed for side-effect free expressions
11531
11532      elsif Check_Side_Effects
11533        and then Side_Effect_Free (Exp, Name_Req, Variable_Ref)
11534      then
11535         return;
11536
11537      --  Generating C code we cannot remove side effect of function returning
11538      --  class-wide types since there is no secondary stack (required to use
11539      --  'reference).
11540
11541      elsif Modify_Tree_For_C
11542        and then Nkind (Exp) = N_Function_Call
11543        and then Is_Class_Wide_Type (Etype (Exp))
11544      then
11545         return;
11546      end if;
11547
11548      --  The remaining processing is done with all checks suppressed
11549
11550      --  Note: from now on, don't use return statements, instead do a goto
11551      --  Leave, to ensure that we properly restore Scope_Suppress.Suppress.
11552
11553      Scope_Suppress.Suppress := (others => True);
11554
11555      --  If this is a side-effect free attribute reference whose expressions
11556      --  are also side-effect free and whose prefix is not a name, remove the
11557      --  side effects of the prefix. A copy of the prefix is required in this
11558      --  case and it is better not to make an additional one for the attribute
11559      --  itself, because the return type of many of them is universal integer,
11560      --  which is a very large type for a temporary.
11561
11562      if Nkind (Exp) = N_Attribute_Reference
11563        and then Side_Effect_Free_Attribute (Attribute_Name (Exp))
11564        and then Side_Effect_Free (Expressions (Exp), Name_Req, Variable_Ref)
11565        and then not Is_Name_Reference (Prefix (Exp))
11566      then
11567         Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
11568         goto Leave;
11569
11570      --  If this is an elementary or a small not-by-reference record type, and
11571      --  we need to capture the value, just make a constant; this is cheap and
11572      --  objects of both kinds of types can be bit aligned, so it might not be
11573      --  possible to generate a reference to them. Likewise if this is not a
11574      --  name reference, except for a type conversion, because we would enter
11575      --  an infinite recursion with Checks.Apply_Predicate_Check if the target
11576      --  type has predicates (and type conversions need a specific treatment
11577      --  anyway, see below). Also do it if we have a volatile reference and
11578      --  Name_Req is not set (see comments for Side_Effect_Free).
11579
11580      elsif (Is_Elementary_Type (Exp_Type)
11581              or else (Is_Record_Type (Exp_Type)
11582                        and then Known_Static_RM_Size (Exp_Type)
11583                        and then RM_Size (Exp_Type) <= System_Max_Integer_Size
11584                        and then not Has_Discriminants (Exp_Type)
11585                        and then not Is_By_Reference_Type (Exp_Type)))
11586        and then (Variable_Ref
11587                   or else (not Is_Name_Reference (Exp)
11588                             and then Nkind (Exp) /= N_Type_Conversion)
11589                   or else (not Name_Req
11590                             and then Is_Volatile_Reference (Exp)))
11591      then
11592         Def_Id := Build_Temporary (Loc, 'R', Exp);
11593         Set_Etype (Def_Id, Exp_Type);
11594         Res := New_Occurrence_Of (Def_Id, Loc);
11595
11596         --  If the expression is a packed reference, it must be reanalyzed and
11597         --  expanded, depending on context. This is the case for actuals where
11598         --  a constraint check may capture the actual before expansion of the
11599         --  call is complete.
11600
11601         if Nkind (Exp) = N_Indexed_Component
11602           and then Is_Packed (Etype (Prefix (Exp)))
11603         then
11604            Set_Analyzed (Exp, False);
11605            Set_Analyzed (Prefix (Exp), False);
11606         end if;
11607
11608         --  Generate:
11609         --    Rnn : Exp_Type renames Expr;
11610
11611         --  In GNATprove mode, we prefer to use renamings for intermediate
11612         --  variables to definition of constants, due to the implicit move
11613         --  operation that such a constant definition causes as part of the
11614         --  support in GNATprove for ownership pointers. Hence, we generate
11615         --  a renaming for a reference to an object of a nonscalar type.
11616
11617         if Renaming_Req
11618           or else (GNATprove_Mode
11619                     and then Is_Object_Reference (Exp)
11620                     and then not Is_Scalar_Type (Exp_Type))
11621         then
11622            E :=
11623              Make_Object_Renaming_Declaration (Loc,
11624                Defining_Identifier => Def_Id,
11625                Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11626                Name                => Relocate_Node (Exp));
11627
11628         --  Generate:
11629         --    Rnn : constant Exp_Type := Expr;
11630
11631         else
11632            E :=
11633              Make_Object_Declaration (Loc,
11634                Defining_Identifier => Def_Id,
11635                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11636                Constant_Present    => True,
11637                Expression          => Relocate_Node (Exp));
11638
11639            Set_Assignment_OK (E);
11640         end if;
11641
11642         Insert_Action (Exp, E);
11643
11644      --  If the expression has the form v.all then we can just capture the
11645      --  pointer, and then do an explicit dereference on the result, but
11646      --  this is not right if this is a volatile reference.
11647
11648      elsif Nkind (Exp) = N_Explicit_Dereference
11649        and then not Is_Volatile_Reference (Exp)
11650      then
11651         Def_Id := Build_Temporary (Loc, 'R', Exp);
11652         Res :=
11653           Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc));
11654
11655         Insert_Action (Exp,
11656           Make_Object_Declaration (Loc,
11657             Defining_Identifier => Def_Id,
11658             Object_Definition   =>
11659               New_Occurrence_Of (Etype (Prefix (Exp)), Loc),
11660             Constant_Present    => True,
11661             Expression          => Relocate_Node (Prefix (Exp))));
11662
11663      --  Similar processing for an unchecked conversion of an expression of
11664      --  the form v.all, where we want the same kind of treatment.
11665
11666      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
11667        and then Nkind (Expression (Exp)) = N_Explicit_Dereference
11668      then
11669         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
11670         goto Leave;
11671
11672      --  If this is a type conversion, leave the type conversion and remove
11673      --  side effects in the expression, unless it is of universal integer,
11674      --  which is a very large type for a temporary. This is important in
11675      --  several circumstances: for change of representations and also when
11676      --  this is a view conversion to a smaller object, where gigi can end
11677      --  up creating its own temporary of the wrong size.
11678
11679      elsif Nkind (Exp) = N_Type_Conversion
11680        and then Etype (Expression (Exp)) /= Universal_Integer
11681      then
11682         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
11683
11684         --  Generating C code the type conversion of an access to constrained
11685         --  array type into an access to unconstrained array type involves
11686         --  initializing a fat pointer and the expression must be free of
11687         --  side effects to safely compute its bounds.
11688
11689         if Modify_Tree_For_C
11690           and then Is_Access_Type (Etype (Exp))
11691           and then Is_Array_Type (Designated_Type (Etype (Exp)))
11692           and then not Is_Constrained (Designated_Type (Etype (Exp)))
11693         then
11694            Def_Id := Build_Temporary (Loc, 'R', Exp);
11695            Set_Etype (Def_Id, Exp_Type);
11696            Res := New_Occurrence_Of (Def_Id, Loc);
11697
11698            Insert_Action (Exp,
11699              Make_Object_Declaration (Loc,
11700                Defining_Identifier => Def_Id,
11701                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11702                Constant_Present    => True,
11703                Expression          => Relocate_Node (Exp)));
11704         else
11705            goto Leave;
11706         end if;
11707
11708      --  If this is an unchecked conversion that Gigi can't handle, make
11709      --  a copy or a use a renaming to capture the value.
11710
11711      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
11712        and then not Safe_Unchecked_Type_Conversion (Exp)
11713      then
11714         if CW_Or_Has_Controlled_Part (Exp_Type) then
11715
11716            --  Use a renaming to capture the expression, rather than create
11717            --  a controlled temporary.
11718
11719            Def_Id := Build_Temporary (Loc, 'R', Exp);
11720            Res    := New_Occurrence_Of (Def_Id, Loc);
11721
11722            Insert_Action (Exp,
11723              Make_Object_Renaming_Declaration (Loc,
11724                Defining_Identifier => Def_Id,
11725                Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11726                Name                => Relocate_Node (Exp)));
11727
11728         else
11729            Def_Id := Build_Temporary (Loc, 'R', Exp);
11730            Set_Etype (Def_Id, Exp_Type);
11731            Res    := New_Occurrence_Of (Def_Id, Loc);
11732
11733            E :=
11734              Make_Object_Declaration (Loc,
11735                Defining_Identifier => Def_Id,
11736                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11737                Constant_Present    => not Is_Variable (Exp),
11738                Expression          => Relocate_Node (Exp));
11739
11740            Set_Assignment_OK (E);
11741            Insert_Action (Exp, E);
11742         end if;
11743
11744      --  If this is a packed array component or a selected component with a
11745      --  nonstandard representation, we cannot generate a reference because
11746      --  the component may be unaligned, so we must use a renaming and this
11747      --  renaming is handled by the front end, as the back end may balk at
11748      --  the nonstandard representation (see Evaluation_Required in Exp_Ch8).
11749
11750      elsif Nkind (Exp) in N_Indexed_Component | N_Selected_Component
11751        and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
11752      then
11753         Def_Id := Build_Temporary (Loc, 'R', Exp);
11754         Res := New_Occurrence_Of (Def_Id, Loc);
11755
11756         Insert_Action (Exp,
11757           Make_Object_Renaming_Declaration (Loc,
11758             Defining_Identifier => Def_Id,
11759             Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11760             Name                => Relocate_Node (Exp)));
11761
11762      --  For an expression that denotes a name, we can use a renaming scheme.
11763      --  This is needed for correctness in the case of a volatile object of
11764      --  a nonvolatile type because the Make_Reference call of the "default"
11765      --  approach would generate an illegal access value (an access value
11766      --  cannot designate such an object - see Analyze_Reference).
11767
11768      elsif Is_Name_Reference (Exp)
11769
11770        --  We skip using this scheme if we have an object of a volatile
11771        --  type and we do not have Name_Req set true (see comments for
11772        --  Side_Effect_Free).
11773
11774        and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
11775      then
11776         Def_Id := Build_Temporary (Loc, 'R', Exp);
11777         Res := New_Occurrence_Of (Def_Id, Loc);
11778
11779         Insert_Action (Exp,
11780           Make_Object_Renaming_Declaration (Loc,
11781             Defining_Identifier => Def_Id,
11782             Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11783             Name                => Relocate_Node (Exp)));
11784
11785      --  Avoid generating a variable-sized temporary, by generating the
11786      --  reference just for the function call. The transformation could be
11787      --  refined to apply only when the array component is constrained by a
11788      --  discriminant???
11789
11790      elsif Nkind (Exp) = N_Selected_Component
11791        and then Nkind (Prefix (Exp)) = N_Function_Call
11792        and then Is_Array_Type (Exp_Type)
11793      then
11794         Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
11795         goto Leave;
11796
11797      --  Otherwise we generate a reference to the expression
11798
11799      else
11800         --  When generating C code we cannot consider side effect free object
11801         --  declarations that have discriminants and are initialized by means
11802         --  of a function call since on this target there is no secondary
11803         --  stack to store the return value and the expander may generate an
11804         --  extra call to the function to compute the discriminant value. In
11805         --  addition, for targets that have secondary stack, the expansion of
11806         --  functions with side effects involves the generation of an access
11807         --  type to capture the return value stored in the secondary stack;
11808         --  by contrast when generating C code such expansion generates an
11809         --  internal object declaration (no access type involved) which must
11810         --  be identified here to avoid entering into a never-ending loop
11811         --  generating internal object declarations.
11812
11813         if Modify_Tree_For_C
11814           and then Nkind (Parent (Exp)) = N_Object_Declaration
11815           and then
11816             (Nkind (Exp) /= N_Function_Call
11817                or else not Has_Discriminants (Exp_Type)
11818                or else Is_Internal_Name
11819                          (Chars (Defining_Identifier (Parent (Exp)))))
11820         then
11821            goto Leave;
11822         end if;
11823
11824         --  Special processing for function calls that return a limited type.
11825         --  We need to build a declaration that will enable build-in-place
11826         --  expansion of the call. This is not done if the context is already
11827         --  an object declaration, to prevent infinite recursion.
11828
11829         --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
11830         --  to accommodate functions returning limited objects by reference.
11831
11832         if Ada_Version >= Ada_2005
11833           and then Nkind (Exp) = N_Function_Call
11834           and then Is_Limited_View (Etype (Exp))
11835           and then Nkind (Parent (Exp)) /= N_Object_Declaration
11836         then
11837            declare
11838               Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
11839               Decl : Node_Id;
11840
11841            begin
11842               Decl :=
11843                 Make_Object_Declaration (Loc,
11844                   Defining_Identifier => Obj,
11845                   Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11846                   Expression          => Relocate_Node (Exp));
11847
11848               Insert_Action (Exp, Decl);
11849               Set_Etype (Obj, Exp_Type);
11850               Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
11851               goto Leave;
11852            end;
11853         end if;
11854
11855         Def_Id := Build_Temporary (Loc, 'R', Exp);
11856
11857         --  The regular expansion of functions with side effects involves the
11858         --  generation of an access type to capture the return value found on
11859         --  the secondary stack. Since SPARK (and why) cannot process access
11860         --  types, use a different approach which ignores the secondary stack
11861         --  and "copies" the returned object.
11862         --  When generating C code, no need for a 'reference since the
11863         --  secondary stack is not supported.
11864
11865         if GNATprove_Mode or Modify_Tree_For_C then
11866            Res := New_Occurrence_Of (Def_Id, Loc);
11867            Ref_Type := Exp_Type;
11868
11869         --  Regular expansion utilizing an access type and 'reference
11870
11871         else
11872            Res :=
11873              Make_Explicit_Dereference (Loc,
11874                Prefix => New_Occurrence_Of (Def_Id, Loc));
11875
11876            --  Generate:
11877            --    type Ann is access all <Exp_Type>;
11878
11879            Ref_Type := Make_Temporary (Loc, 'A');
11880
11881            Ptr_Typ_Decl :=
11882              Make_Full_Type_Declaration (Loc,
11883                Defining_Identifier => Ref_Type,
11884                Type_Definition     =>
11885                  Make_Access_To_Object_Definition (Loc,
11886                    All_Present        => True,
11887                    Subtype_Indication =>
11888                      New_Occurrence_Of (Exp_Type, Loc)));
11889
11890            Insert_Action (Exp, Ptr_Typ_Decl);
11891         end if;
11892
11893         E := Exp;
11894         if Nkind (E) = N_Explicit_Dereference then
11895            New_Exp := Relocate_Node (Prefix (E));
11896
11897         else
11898            E := Relocate_Node (E);
11899
11900            --  Do not generate a 'reference in SPARK mode or C generation
11901            --  since the access type is not created in the first place.
11902
11903            if GNATprove_Mode or Modify_Tree_For_C then
11904               New_Exp := E;
11905
11906            --  Otherwise generate reference, marking the value as non-null
11907            --  since we know it cannot be null and we don't want a check.
11908
11909            else
11910               New_Exp := Make_Reference (Loc, E);
11911               Set_Is_Known_Non_Null (Def_Id);
11912            end if;
11913         end if;
11914
11915         if Is_Delayed_Aggregate (E) then
11916
11917            --  The expansion of nested aggregates is delayed until the
11918            --  enclosing aggregate is expanded. As aggregates are often
11919            --  qualified, the predicate applies to qualified expressions as
11920            --  well, indicating that the enclosing aggregate has not been
11921            --  expanded yet. At this point the aggregate is part of a
11922            --  stand-alone declaration, and must be fully expanded.
11923
11924            if Nkind (E) = N_Qualified_Expression then
11925               Set_Expansion_Delayed (Expression (E), False);
11926               Set_Analyzed (Expression (E), False);
11927            else
11928               Set_Expansion_Delayed (E, False);
11929            end if;
11930
11931            Set_Analyzed (E, False);
11932         end if;
11933
11934         --  Generating C code of object declarations that have discriminants
11935         --  and are initialized by means of a function call we propagate the
11936         --  discriminants of the parent type to the internally built object.
11937         --  This is needed to avoid generating an extra call to the called
11938         --  function.
11939
11940         --  For example, if we generate here the following declaration, it
11941         --  will be expanded later adding an extra call to evaluate the value
11942         --  of the discriminant (needed to compute the size of the object).
11943         --
11944         --     type Rec (D : Integer) is ...
11945         --     Obj : constant Rec := SomeFunc;
11946
11947         if Modify_Tree_For_C
11948           and then Nkind (Parent (Exp)) = N_Object_Declaration
11949           and then Has_Discriminants (Exp_Type)
11950           and then Nkind (Exp) = N_Function_Call
11951         then
11952            Insert_Action (Exp,
11953              Make_Object_Declaration (Loc,
11954                Defining_Identifier => Def_Id,
11955                Object_Definition   => New_Copy_Tree
11956                                         (Object_Definition (Parent (Exp))),
11957                Constant_Present    => True,
11958                Expression          => New_Exp));
11959         else
11960            Insert_Action (Exp,
11961              Make_Object_Declaration (Loc,
11962                Defining_Identifier => Def_Id,
11963                Object_Definition   => New_Occurrence_Of (Ref_Type, Loc),
11964                Constant_Present    => True,
11965                Expression          => New_Exp));
11966         end if;
11967      end if;
11968
11969      --  Preserve the Assignment_OK flag in all copies, since at least one
11970      --  copy may be used in a context where this flag must be set (otherwise
11971      --  why would the flag be set in the first place).
11972
11973      Set_Assignment_OK (Res, Assignment_OK (Exp));
11974
11975      --  Preserve the Do_Range_Check flag in all copies
11976
11977      Set_Do_Range_Check (Res, Do_Range_Check (Exp));
11978
11979      --  Finally rewrite the original expression and we are done
11980
11981      Rewrite (Exp, Res);
11982      Analyze_And_Resolve (Exp, Exp_Type);
11983
11984   <<Leave>>
11985      Scope_Suppress := Svg_Suppress;
11986   end Remove_Side_Effects;
11987
11988   ------------------------
11989   -- Replace_References --
11990   ------------------------
11991
11992   procedure Replace_References
11993     (Expr      : Node_Id;
11994      Par_Typ   : Entity_Id;
11995      Deriv_Typ : Entity_Id;
11996      Par_Obj   : Entity_Id := Empty;
11997      Deriv_Obj : Entity_Id := Empty)
11998   is
11999      function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean;
12000      --  Determine whether node Ref denotes some component of Deriv_Obj
12001
12002      function Replace_Ref (Ref : Node_Id) return Traverse_Result;
12003      --  Substitute a reference to an entity with the corresponding value
12004      --  stored in table Type_Map.
12005
12006      function Type_Of_Formal
12007        (Call   : Node_Id;
12008         Actual : Node_Id) return Entity_Id;
12009      --  Find the type of the formal parameter which corresponds to actual
12010      --  parameter Actual in subprogram call Call.
12011
12012      ----------------------
12013      -- Is_Deriv_Obj_Ref --
12014      ----------------------
12015
12016      function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean is
12017         Par : constant Node_Id := Parent (Ref);
12018
12019      begin
12020         --  Detect the folowing selected component form:
12021
12022         --    Deriv_Obj.(something)
12023
12024         return
12025           Nkind (Par) = N_Selected_Component
12026             and then Is_Entity_Name (Prefix (Par))
12027             and then Entity (Prefix (Par)) = Deriv_Obj;
12028      end Is_Deriv_Obj_Ref;
12029
12030      -----------------
12031      -- Replace_Ref --
12032      -----------------
12033
12034      function Replace_Ref (Ref : Node_Id) return Traverse_Result is
12035         procedure Remove_Controlling_Arguments (From_Arg : Node_Id);
12036         --  Reset the Controlling_Argument of all function calls that
12037         --  encapsulate node From_Arg.
12038
12039         ----------------------------------
12040         -- Remove_Controlling_Arguments --
12041         ----------------------------------
12042
12043         procedure Remove_Controlling_Arguments (From_Arg : Node_Id) is
12044            Par : Node_Id;
12045
12046         begin
12047            Par := From_Arg;
12048            while Present (Par) loop
12049               if Nkind (Par) = N_Function_Call
12050                 and then Present (Controlling_Argument (Par))
12051               then
12052                  Set_Controlling_Argument (Par, Empty);
12053
12054               --  Prevent the search from going too far
12055
12056               elsif Is_Body_Or_Package_Declaration (Par) then
12057                  exit;
12058               end if;
12059
12060               Par := Parent (Par);
12061            end loop;
12062         end Remove_Controlling_Arguments;
12063
12064         --  Local variables
12065
12066         Context : constant Node_Id    := Parent (Ref);
12067         Loc     : constant Source_Ptr := Sloc (Ref);
12068         Ref_Id  : Entity_Id;
12069         Result  : Traverse_Result;
12070
12071         New_Ref : Node_Id;
12072         --  The new reference which is intended to substitute the old one
12073
12074         Old_Ref : Node_Id;
12075         --  The reference designated for replacement. In certain cases this
12076         --  may be a node other than Ref.
12077
12078         Val : Node_Or_Entity_Id;
12079         --  The corresponding value of Ref from the type map
12080
12081      --  Start of processing for Replace_Ref
12082
12083      begin
12084         --  Assume that the input reference is to be replaced and that the
12085         --  traversal should examine the children of the reference.
12086
12087         Old_Ref := Ref;
12088         Result  := OK;
12089
12090         --  The input denotes a meaningful reference
12091
12092         if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then
12093            Ref_Id := Entity (Ref);
12094            Val    := Type_Map.Get (Ref_Id);
12095
12096            --  The reference has a corresponding value in the type map, a
12097            --  substitution is possible.
12098
12099            if Present (Val) then
12100
12101               --  The reference denotes a discriminant
12102
12103               if Ekind (Ref_Id) = E_Discriminant then
12104                  if Nkind (Val) in N_Entity then
12105
12106                     --  The value denotes another discriminant. Replace as
12107                     --  follows:
12108
12109                     --    _object.Discr -> _object.Val
12110
12111                     if Ekind (Val) = E_Discriminant then
12112                        New_Ref := New_Occurrence_Of (Val, Loc);
12113
12114                     --  Otherwise the value denotes the entity of a name which
12115                     --  constraints the discriminant. Replace as follows:
12116
12117                     --    _object.Discr -> Val
12118
12119                     else
12120                        pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
12121
12122                        New_Ref := New_Occurrence_Of (Val, Loc);
12123                        Old_Ref := Parent (Old_Ref);
12124                     end if;
12125
12126                  --  Otherwise the value denotes an arbitrary expression which
12127                  --  constraints the discriminant. Replace as follows:
12128
12129                  --    _object.Discr -> Val
12130
12131                  else
12132                     pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
12133
12134                     New_Ref := New_Copy_Tree (Val);
12135                     Old_Ref := Parent (Old_Ref);
12136                  end if;
12137
12138               --  Otherwise the reference denotes a primitive. Replace as
12139               --  follows:
12140
12141               --    Primitive -> Val
12142
12143               else
12144                  pragma Assert (Nkind (Val) in N_Entity);
12145                  New_Ref := New_Occurrence_Of (Val, Loc);
12146               end if;
12147
12148            --  The reference mentions the _object parameter of the parent
12149            --  type's DIC or type invariant procedure. Replace as follows:
12150
12151            --    _object -> _object
12152
12153            elsif Present (Par_Obj)
12154              and then Present (Deriv_Obj)
12155              and then Ref_Id = Par_Obj
12156            then
12157               New_Ref := New_Occurrence_Of (Deriv_Obj, Loc);
12158
12159               --  The type of the _object parameter is class-wide when the
12160               --  expression comes from an assertion pragma that applies to
12161               --  an abstract parent type or an interface. The class-wide type
12162               --  facilitates the preanalysis of the expression by treating
12163               --  calls to abstract primitives that mention the current
12164               --  instance of the type as dispatching. Once the calls are
12165               --  remapped to invoke overriding or inherited primitives, the
12166               --  calls no longer need to be dispatching. Examine all function
12167               --  calls that encapsulate the _object parameter and reset their
12168               --  Controlling_Argument attribute.
12169
12170               if Is_Class_Wide_Type (Etype (Par_Obj))
12171                 and then Is_Abstract_Type (Root_Type (Etype (Par_Obj)))
12172               then
12173                  Remove_Controlling_Arguments (Old_Ref);
12174               end if;
12175
12176               --  The reference to _object acts as an actual parameter in a
12177               --  subprogram call which may be invoking a primitive of the
12178               --  parent type:
12179
12180               --    Primitive (... _object ...);
12181
12182               --  The parent type primitive may not be overridden nor
12183               --  inherited when it is declared after the derived type
12184               --  definition:
12185
12186               --    type Parent is tagged private;
12187               --    type Child is new Parent with private;
12188               --    procedure Primitive (Obj : Parent);
12189
12190               --  In this scenario the _object parameter is converted to the
12191               --  parent type. Due to complications with partial/full views
12192               --  and view swaps, the parent type is taken from the formal
12193               --  parameter of the subprogram being called.
12194
12195               if Nkind (Context) in N_Subprogram_Call
12196                 and then No (Type_Map.Get (Entity (Name (Context))))
12197               then
12198                  New_Ref :=
12199                    Convert_To (Type_Of_Formal (Context, Old_Ref), New_Ref);
12200
12201                  --  Do not process the generated type conversion because
12202                  --  both the parent type and the derived type are in the
12203                  --  Type_Map table. This will clobber the type conversion
12204                  --  by resetting its subtype mark.
12205
12206                  Result := Skip;
12207               end if;
12208
12209            --  Otherwise there is nothing to replace
12210
12211            else
12212               New_Ref := Empty;
12213            end if;
12214
12215            if Present (New_Ref) then
12216               Rewrite (Old_Ref, New_Ref);
12217
12218               --  Update the return type when the context of the reference
12219               --  acts as the name of a function call. Note that the update
12220               --  should not be performed when the reference appears as an
12221               --  actual in the call.
12222
12223               if Nkind (Context) = N_Function_Call
12224                 and then Name (Context) = Old_Ref
12225               then
12226                  Set_Etype (Context, Etype (Val));
12227               end if;
12228            end if;
12229         end if;
12230
12231         --  Reanalyze the reference due to potential replacements
12232
12233         if Nkind (Old_Ref) in N_Has_Etype then
12234            Set_Analyzed (Old_Ref, False);
12235         end if;
12236
12237         return Result;
12238      end Replace_Ref;
12239
12240      procedure Replace_Refs is new Traverse_Proc (Replace_Ref);
12241
12242      --------------------
12243      -- Type_Of_Formal --
12244      --------------------
12245
12246      function Type_Of_Formal
12247        (Call   : Node_Id;
12248         Actual : Node_Id) return Entity_Id
12249      is
12250         A : Node_Id;
12251         F : Entity_Id;
12252
12253      begin
12254         --  Examine the list of actual and formal parameters in parallel
12255
12256         A := First (Parameter_Associations (Call));
12257         F := First_Formal (Entity (Name (Call)));
12258         while Present (A) and then Present (F) loop
12259            if A = Actual then
12260               return Etype (F);
12261            end if;
12262
12263            Next (A);
12264            Next_Formal (F);
12265         end loop;
12266
12267         --  The actual parameter must always have a corresponding formal
12268
12269         pragma Assert (False);
12270
12271         return Empty;
12272      end Type_Of_Formal;
12273
12274   --  Start of processing for Replace_References
12275
12276   begin
12277      --  Map the attributes of the parent type to the proper corresponding
12278      --  attributes of the derived type.
12279
12280      Map_Types
12281        (Parent_Type  => Par_Typ,
12282         Derived_Type => Deriv_Typ);
12283
12284      --  Inspect the input expression and perform substitutions where
12285      --  necessary.
12286
12287      Replace_Refs (Expr);
12288   end Replace_References;
12289
12290   -----------------------------
12291   -- Replace_Type_References --
12292   -----------------------------
12293
12294   procedure Replace_Type_References
12295     (Expr   : Node_Id;
12296      Typ    : Entity_Id;
12297      Obj_Id : Entity_Id)
12298   is
12299      procedure Replace_Type_Ref (N : Node_Id);
12300      --  Substitute a single reference of the current instance of type Typ
12301      --  with a reference to Obj_Id.
12302
12303      ----------------------
12304      -- Replace_Type_Ref --
12305      ----------------------
12306
12307      procedure Replace_Type_Ref (N : Node_Id) is
12308      begin
12309         --  Decorate the reference to Typ even though it may be rewritten
12310         --  further down. This is done so that routines which examine
12311         --  properties of the Original_Node have some semantic information.
12312
12313         if Nkind (N) = N_Identifier then
12314            Set_Entity (N, Typ);
12315            Set_Etype  (N, Typ);
12316
12317         elsif Nkind (N) = N_Selected_Component then
12318            Analyze (Prefix (N));
12319            Set_Entity (Selector_Name (N), Typ);
12320            Set_Etype  (Selector_Name (N), Typ);
12321         end if;
12322
12323         --  Perform the following substitution:
12324
12325         --    Typ --> _object
12326
12327         Rewrite (N, New_Occurrence_Of (Obj_Id, Sloc (N)));
12328         Set_Comes_From_Source (N, True);
12329      end Replace_Type_Ref;
12330
12331      procedure Replace_Type_Refs is
12332        new Replace_Type_References_Generic (Replace_Type_Ref);
12333
12334   --  Start of processing for Replace_Type_References
12335
12336   begin
12337      Replace_Type_Refs (Expr, Typ);
12338   end Replace_Type_References;
12339
12340   ---------------------------
12341   -- Represented_As_Scalar --
12342   ---------------------------
12343
12344   function Represented_As_Scalar (T : Entity_Id) return Boolean is
12345      UT : constant Entity_Id := Underlying_Type (T);
12346   begin
12347      return Is_Scalar_Type (UT)
12348        or else (Is_Bit_Packed_Array (UT)
12349                  and then Is_Scalar_Type (Packed_Array_Impl_Type (UT)));
12350   end Represented_As_Scalar;
12351
12352   ------------------------------
12353   -- Requires_Cleanup_Actions --
12354   ------------------------------
12355
12356   function Requires_Cleanup_Actions
12357     (N         : Node_Id;
12358      Lib_Level : Boolean) return Boolean
12359   is
12360      At_Lib_Level : constant Boolean :=
12361        Lib_Level
12362          and then Nkind (N) in N_Package_Body | N_Package_Specification;
12363      --  N is at the library level if the top-most context is a package and
12364      --  the path taken to reach N does not include nonpackage constructs.
12365
12366   begin
12367      case Nkind (N) is
12368         when N_Accept_Statement
12369            | N_Block_Statement
12370            | N_Entry_Body
12371            | N_Package_Body
12372            | N_Protected_Body
12373            | N_Subprogram_Body
12374            | N_Task_Body
12375         =>
12376            return
12377                Requires_Cleanup_Actions
12378                  (L                 => Declarations (N),
12379                   Lib_Level         => At_Lib_Level,
12380                   Nested_Constructs => True)
12381              or else
12382                (Present (Handled_Statement_Sequence (N))
12383                  and then
12384                    Requires_Cleanup_Actions
12385                      (L                 =>
12386                         Statements (Handled_Statement_Sequence (N)),
12387                       Lib_Level         => At_Lib_Level,
12388                       Nested_Constructs => True));
12389
12390         --  Extended return statements are the same as the above, except that
12391         --  there is no Declarations field. We do not want to clean up the
12392         --  Return_Object_Declarations.
12393
12394         when N_Extended_Return_Statement =>
12395            return
12396              Present (Handled_Statement_Sequence (N))
12397                and then Requires_Cleanup_Actions
12398                           (L                 =>
12399                              Statements (Handled_Statement_Sequence (N)),
12400                            Lib_Level         => At_Lib_Level,
12401                            Nested_Constructs => True);
12402
12403         when N_Package_Specification =>
12404            return
12405                Requires_Cleanup_Actions
12406                  (L                 => Visible_Declarations (N),
12407                   Lib_Level         => At_Lib_Level,
12408                   Nested_Constructs => True)
12409              or else
12410                Requires_Cleanup_Actions
12411                  (L                 => Private_Declarations (N),
12412                   Lib_Level         => At_Lib_Level,
12413                   Nested_Constructs => True);
12414
12415         when others =>
12416            raise Program_Error;
12417      end case;
12418   end Requires_Cleanup_Actions;
12419
12420   ------------------------------
12421   -- Requires_Cleanup_Actions --
12422   ------------------------------
12423
12424   function Requires_Cleanup_Actions
12425     (L                 : List_Id;
12426      Lib_Level         : Boolean;
12427      Nested_Constructs : Boolean) return Boolean
12428   is
12429      Decl    : Node_Id;
12430      Expr    : Node_Id;
12431      Obj_Id  : Entity_Id;
12432      Obj_Typ : Entity_Id;
12433      Pack_Id : Entity_Id;
12434      Typ     : Entity_Id;
12435
12436   begin
12437      if No (L) or else Is_Empty_List (L) then
12438         return False;
12439      end if;
12440
12441      Decl := First (L);
12442      while Present (Decl) loop
12443
12444         --  Library-level tagged types
12445
12446         if Nkind (Decl) = N_Full_Type_Declaration then
12447            Typ := Defining_Identifier (Decl);
12448
12449            --  Ignored Ghost types do not need any cleanup actions because
12450            --  they will not appear in the final tree.
12451
12452            if Is_Ignored_Ghost_Entity (Typ) then
12453               null;
12454
12455            elsif Is_Tagged_Type (Typ)
12456              and then Is_Library_Level_Entity (Typ)
12457              and then Convention (Typ) = Convention_Ada
12458              and then Present (Access_Disp_Table (Typ))
12459              and then RTE_Available (RE_Unregister_Tag)
12460              and then not Is_Abstract_Type (Typ)
12461              and then not No_Run_Time_Mode
12462            then
12463               return True;
12464            end if;
12465
12466         --  Regular object declarations
12467
12468         elsif Nkind (Decl) = N_Object_Declaration then
12469            Obj_Id  := Defining_Identifier (Decl);
12470            Obj_Typ := Base_Type (Etype (Obj_Id));
12471            Expr    := Expression (Decl);
12472
12473            --  Bypass any form of processing for objects which have their
12474            --  finalization disabled. This applies only to objects at the
12475            --  library level.
12476
12477            if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
12478               null;
12479
12480            --  Finalization of transient objects are treated separately in
12481            --  order to handle sensitive cases. These include:
12482
12483            --    * Aggregate expansion
12484            --    * If, case, and expression with actions expansion
12485            --    * Transient scopes
12486
12487            --  If one of those contexts has marked the transient object as
12488            --  ignored, do not generate finalization actions for it.
12489
12490            elsif Is_Finalized_Transient (Obj_Id)
12491              or else Is_Ignored_Transient (Obj_Id)
12492            then
12493               null;
12494
12495            --  Ignored Ghost objects do not need any cleanup actions because
12496            --  they will not appear in the final tree.
12497
12498            elsif Is_Ignored_Ghost_Entity (Obj_Id) then
12499               null;
12500
12501            --  The object is of the form:
12502            --    Obj : [constant] Typ [:= Expr];
12503            --
12504            --  Do not process tag-to-class-wide conversions because they do
12505            --  not yield an object. Do not process the incomplete view of a
12506            --  deferred constant. Note that an object initialized by means
12507            --  of a build-in-place function call may appear as a deferred
12508            --  constant after expansion activities. These kinds of objects
12509            --  must be finalized.
12510
12511            elsif not Is_Imported (Obj_Id)
12512              and then Needs_Finalization (Obj_Typ)
12513              and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
12514              and then not (Ekind (Obj_Id) = E_Constant
12515                             and then not Has_Completion (Obj_Id)
12516                             and then No (BIP_Initialization_Call (Obj_Id)))
12517            then
12518               return True;
12519
12520            --  The object is of the form:
12521            --    Obj : Access_Typ := Non_BIP_Function_Call'reference;
12522            --
12523            --    Obj : Access_Typ :=
12524            --            BIP_Function_Call (BIPalloc => 2, ...)'reference;
12525
12526            elsif Is_Access_Type (Obj_Typ)
12527              and then Needs_Finalization
12528                         (Available_View (Designated_Type (Obj_Typ)))
12529              and then Present (Expr)
12530              and then
12531                (Is_Secondary_Stack_BIP_Func_Call (Expr)
12532                  or else
12533                    (Is_Non_BIP_Func_Call (Expr)
12534                      and then not Is_Related_To_Func_Return (Obj_Id)))
12535            then
12536               return True;
12537
12538            --  Processing for "hook" objects generated for transient objects
12539            --  declared inside an Expression_With_Actions.
12540
12541            elsif Is_Access_Type (Obj_Typ)
12542              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12543              and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
12544                                                        N_Object_Declaration
12545            then
12546               return True;
12547
12548            --  Processing for intermediate results of if expressions where
12549            --  one of the alternatives uses a controlled function call.
12550
12551            elsif Is_Access_Type (Obj_Typ)
12552              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12553              and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
12554                                                        N_Defining_Identifier
12555              and then Present (Expr)
12556              and then Nkind (Expr) = N_Null
12557            then
12558               return True;
12559
12560            --  Simple protected objects which use type System.Tasking.
12561            --  Protected_Objects.Protection to manage their locks should be
12562            --  treated as controlled since they require manual cleanup.
12563
12564            elsif Ekind (Obj_Id) = E_Variable
12565              and then (Is_Simple_Protected_Type (Obj_Typ)
12566                         or else Has_Simple_Protected_Object (Obj_Typ))
12567            then
12568               return True;
12569            end if;
12570
12571         --  Specific cases of object renamings
12572
12573         elsif Nkind (Decl) = N_Object_Renaming_Declaration then
12574            Obj_Id  := Defining_Identifier (Decl);
12575            Obj_Typ := Base_Type (Etype (Obj_Id));
12576
12577            --  Bypass any form of processing for objects which have their
12578            --  finalization disabled. This applies only to objects at the
12579            --  library level.
12580
12581            if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
12582               null;
12583
12584            --  Ignored Ghost object renamings do not need any cleanup actions
12585            --  because they will not appear in the final tree.
12586
12587            elsif Is_Ignored_Ghost_Entity (Obj_Id) then
12588               null;
12589
12590            --  Return object of a build-in-place function. This case is
12591            --  recognized and marked by the expansion of an extended return
12592            --  statement (see Expand_N_Extended_Return_Statement).
12593
12594            elsif Needs_Finalization (Obj_Typ)
12595              and then Is_Return_Object (Obj_Id)
12596              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12597            then
12598               return True;
12599
12600            --  Detect a case where a source object has been initialized by
12601            --  a controlled function call or another object which was later
12602            --  rewritten as a class-wide conversion of Ada.Tags.Displace.
12603
12604            --     Obj1 : CW_Type := Src_Obj;
12605            --     Obj2 : CW_Type := Function_Call (...);
12606
12607            --     Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
12608            --     Tmp  : ... := Function_Call (...)'reference;
12609            --     Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
12610
12611            elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
12612               return True;
12613            end if;
12614
12615         --  Inspect the freeze node of an access-to-controlled type and look
12616         --  for a delayed finalization master. This case arises when the
12617         --  freeze actions are inserted at a later time than the expansion of
12618         --  the context. Since Build_Finalizer is never called on a single
12619         --  construct twice, the master will be ultimately left out and never
12620         --  finalized. This is also needed for freeze actions of designated
12621         --  types themselves, since in some cases the finalization master is
12622         --  associated with a designated type's freeze node rather than that
12623         --  of the access type (see handling for freeze actions in
12624         --  Build_Finalization_Master).
12625
12626         elsif Nkind (Decl) = N_Freeze_Entity
12627           and then Present (Actions (Decl))
12628         then
12629            Typ := Entity (Decl);
12630
12631            --  Freeze nodes for ignored Ghost types do not need cleanup
12632            --  actions because they will never appear in the final tree.
12633
12634            if Is_Ignored_Ghost_Entity (Typ) then
12635               null;
12636
12637            elsif ((Is_Access_Object_Type (Typ)
12638                      and then Needs_Finalization
12639                                 (Available_View (Designated_Type (Typ))))
12640                    or else (Is_Type (Typ) and then Needs_Finalization (Typ)))
12641              and then Requires_Cleanup_Actions
12642                         (Actions (Decl), Lib_Level, Nested_Constructs)
12643            then
12644               return True;
12645            end if;
12646
12647         --  Nested package declarations
12648
12649         elsif Nested_Constructs
12650           and then Nkind (Decl) = N_Package_Declaration
12651         then
12652            Pack_Id := Defining_Entity (Decl);
12653
12654            --  Do not inspect an ignored Ghost package because all code found
12655            --  within will not appear in the final tree.
12656
12657            if Is_Ignored_Ghost_Entity (Pack_Id) then
12658               null;
12659
12660            elsif Ekind (Pack_Id) /= E_Generic_Package
12661              and then Requires_Cleanup_Actions
12662                         (Specification (Decl), Lib_Level)
12663            then
12664               return True;
12665            end if;
12666
12667         --  Nested package bodies
12668
12669         elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then
12670
12671            --  Do not inspect an ignored Ghost package body because all code
12672            --  found within will not appear in the final tree.
12673
12674            if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then
12675               null;
12676
12677            elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package
12678              and then Requires_Cleanup_Actions (Decl, Lib_Level)
12679            then
12680               return True;
12681            end if;
12682
12683         elsif Nkind (Decl) = N_Block_Statement
12684           and then
12685
12686           --  Handle a rare case caused by a controlled transient object
12687           --  created as part of a record init proc. The variable is wrapped
12688           --  in a block, but the block is not associated with a transient
12689           --  scope.
12690
12691           (Inside_Init_Proc
12692
12693           --  Handle the case where the original context has been wrapped in
12694           --  a block to avoid interference between exception handlers and
12695           --  At_End handlers. Treat the block as transparent and process its
12696           --  contents.
12697
12698             or else Is_Finalization_Wrapper (Decl))
12699         then
12700            if Requires_Cleanup_Actions (Decl, Lib_Level) then
12701               return True;
12702            end if;
12703         end if;
12704
12705         Next (Decl);
12706      end loop;
12707
12708      return False;
12709   end Requires_Cleanup_Actions;
12710
12711   ------------------------------------
12712   -- Safe_Unchecked_Type_Conversion --
12713   ------------------------------------
12714
12715   --  Note: this function knows quite a bit about the exact requirements of
12716   --  Gigi with respect to unchecked type conversions, and its code must be
12717   --  coordinated with any changes in Gigi in this area.
12718
12719   --  The above requirements should be documented in Sinfo ???
12720
12721   function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
12722      Otyp   : Entity_Id;
12723      Ityp   : Entity_Id;
12724      Oalign : Uint;
12725      Ialign : Uint;
12726      Pexp   : constant Node_Id := Parent (Exp);
12727
12728   begin
12729      --  If the expression is the RHS of an assignment or object declaration
12730      --  we are always OK because there will always be a target.
12731
12732      --  Object renaming declarations, (generated for view conversions of
12733      --  actuals in inlined calls), like object declarations, provide an
12734      --  explicit type, and are safe as well.
12735
12736      if (Nkind (Pexp) = N_Assignment_Statement
12737           and then Expression (Pexp) = Exp)
12738        or else Nkind (Pexp)
12739                  in N_Object_Declaration | N_Object_Renaming_Declaration
12740      then
12741         return True;
12742
12743      --  If the expression is the prefix of an N_Selected_Component we should
12744      --  also be OK because GCC knows to look inside the conversion except if
12745      --  the type is discriminated. We assume that we are OK anyway if the
12746      --  type is not set yet or if it is controlled since we can't afford to
12747      --  introduce a temporary in this case.
12748
12749      elsif Nkind (Pexp) = N_Selected_Component
12750        and then Prefix (Pexp) = Exp
12751      then
12752         return No (Etype (Pexp))
12753           or else not Is_Type (Etype (Pexp))
12754           or else not Has_Discriminants (Etype (Pexp))
12755           or else Is_Constrained (Etype (Pexp));
12756      end if;
12757
12758      --  Set the output type, this comes from Etype if it is set, otherwise we
12759      --  take it from the subtype mark, which we assume was already fully
12760      --  analyzed.
12761
12762      if Present (Etype (Exp)) then
12763         Otyp := Etype (Exp);
12764      else
12765         Otyp := Entity (Subtype_Mark (Exp));
12766      end if;
12767
12768      --  The input type always comes from the expression, and we assume this
12769      --  is indeed always analyzed, so we can simply get the Etype.
12770
12771      Ityp := Etype (Expression (Exp));
12772
12773      --  Initialize alignments to unknown so far
12774
12775      Oalign := No_Uint;
12776      Ialign := No_Uint;
12777
12778      --  Replace a concurrent type by its corresponding record type and each
12779      --  type by its underlying type and do the tests on those. The original
12780      --  type may be a private type whose completion is a concurrent type, so
12781      --  find the underlying type first.
12782
12783      if Present (Underlying_Type (Otyp)) then
12784         Otyp := Underlying_Type (Otyp);
12785      end if;
12786
12787      if Present (Underlying_Type (Ityp)) then
12788         Ityp := Underlying_Type (Ityp);
12789      end if;
12790
12791      if Is_Concurrent_Type (Otyp) then
12792         Otyp := Corresponding_Record_Type (Otyp);
12793      end if;
12794
12795      if Is_Concurrent_Type (Ityp) then
12796         Ityp := Corresponding_Record_Type (Ityp);
12797      end if;
12798
12799      --  If the base types are the same, we know there is no problem since
12800      --  this conversion will be a noop.
12801
12802      if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
12803         return True;
12804
12805      --  Same if this is an upwards conversion of an untagged type, and there
12806      --  are no constraints involved (could be more general???)
12807
12808      elsif Etype (Ityp) = Otyp
12809        and then not Is_Tagged_Type (Ityp)
12810        and then not Has_Discriminants (Ityp)
12811        and then No (First_Rep_Item (Base_Type (Ityp)))
12812      then
12813         return True;
12814
12815      --  If the expression has an access type (object or subprogram) we assume
12816      --  that the conversion is safe, because the size of the target is safe,
12817      --  even if it is a record (which might be treated as having unknown size
12818      --  at this point).
12819
12820      elsif Is_Access_Type (Ityp) then
12821         return True;
12822
12823      --  If the size of output type is known at compile time, there is never
12824      --  a problem. Note that unconstrained records are considered to be of
12825      --  known size, but we can't consider them that way here, because we are
12826      --  talking about the actual size of the object.
12827
12828      --  We also make sure that in addition to the size being known, we do not
12829      --  have a case which might generate an embarrassingly large temp in
12830      --  stack checking mode.
12831
12832      elsif Size_Known_At_Compile_Time (Otyp)
12833        and then
12834          (not Stack_Checking_Enabled
12835            or else not May_Generate_Large_Temp (Otyp))
12836        and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
12837      then
12838         return True;
12839
12840      --  If either type is tagged, then we know the alignment is OK so Gigi
12841      --  will be able to use pointer punning.
12842
12843      elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
12844         return True;
12845
12846      --  If either type is a limited record type, we cannot do a copy, so say
12847      --  safe since there's nothing else we can do.
12848
12849      elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
12850         return True;
12851
12852      --  Conversions to and from packed array types are always ignored and
12853      --  hence are safe.
12854
12855      elsif Is_Packed_Array_Impl_Type (Otyp)
12856        or else Is_Packed_Array_Impl_Type (Ityp)
12857      then
12858         return True;
12859      end if;
12860
12861      --  The only other cases known to be safe is if the input type's
12862      --  alignment is known to be at least the maximum alignment for the
12863      --  target or if both alignments are known and the output type's
12864      --  alignment is no stricter than the input's. We can use the component
12865      --  type alignment for an array if a type is an unpacked array type.
12866
12867      if Present (Alignment_Clause (Otyp)) then
12868         Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
12869
12870      elsif Is_Array_Type (Otyp)
12871        and then Present (Alignment_Clause (Component_Type (Otyp)))
12872      then
12873         Oalign := Expr_Value (Expression (Alignment_Clause
12874                                           (Component_Type (Otyp))));
12875      end if;
12876
12877      if Present (Alignment_Clause (Ityp)) then
12878         Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
12879
12880      elsif Is_Array_Type (Ityp)
12881        and then Present (Alignment_Clause (Component_Type (Ityp)))
12882      then
12883         Ialign := Expr_Value (Expression (Alignment_Clause
12884                                           (Component_Type (Ityp))));
12885      end if;
12886
12887      if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
12888         return True;
12889
12890      elsif Ialign /= No_Uint
12891        and then Oalign /= No_Uint
12892        and then Ialign <= Oalign
12893      then
12894         return True;
12895
12896      --   Otherwise, Gigi cannot handle this and we must make a temporary
12897
12898      else
12899         return False;
12900      end if;
12901   end Safe_Unchecked_Type_Conversion;
12902
12903   ---------------------------------
12904   -- Set_Current_Value_Condition --
12905   ---------------------------------
12906
12907   --  Note: the implementation of this procedure is very closely tied to the
12908   --  implementation of Get_Current_Value_Condition. Here we set required
12909   --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
12910   --  them, so they must have a consistent view.
12911
12912   procedure Set_Current_Value_Condition (Cnode : Node_Id) is
12913
12914      procedure Set_Entity_Current_Value (N : Node_Id);
12915      --  If N is an entity reference, where the entity is of an appropriate
12916      --  kind, then set the current value of this entity to Cnode, unless
12917      --  there is already a definite value set there.
12918
12919      procedure Set_Expression_Current_Value (N : Node_Id);
12920      --  If N is of an appropriate form, sets an appropriate entry in current
12921      --  value fields of relevant entities. Multiple entities can be affected
12922      --  in the case of an AND or AND THEN.
12923
12924      ------------------------------
12925      -- Set_Entity_Current_Value --
12926      ------------------------------
12927
12928      procedure Set_Entity_Current_Value (N : Node_Id) is
12929      begin
12930         if Is_Entity_Name (N) then
12931            declare
12932               Ent : constant Entity_Id := Entity (N);
12933
12934            begin
12935               --  Don't capture if not safe to do so
12936
12937               if not Safe_To_Capture_Value (N, Ent, Cond => True) then
12938                  return;
12939               end if;
12940
12941               --  Here we have a case where the Current_Value field may need
12942               --  to be set. We set it if it is not already set to a compile
12943               --  time expression value.
12944
12945               --  Note that this represents a decision that one condition
12946               --  blots out another previous one. That's certainly right if
12947               --  they occur at the same level. If the second one is nested,
12948               --  then the decision is neither right nor wrong (it would be
12949               --  equally OK to leave the outer one in place, or take the new
12950               --  inner one). Really we should record both, but our data
12951               --  structures are not that elaborate.
12952
12953               if Nkind (Current_Value (Ent)) not in N_Subexpr then
12954                  Set_Current_Value (Ent, Cnode);
12955               end if;
12956            end;
12957         end if;
12958      end Set_Entity_Current_Value;
12959
12960      ----------------------------------
12961      -- Set_Expression_Current_Value --
12962      ----------------------------------
12963
12964      procedure Set_Expression_Current_Value (N : Node_Id) is
12965         Cond : Node_Id;
12966
12967      begin
12968         Cond := N;
12969
12970         --  Loop to deal with (ignore for now) any NOT operators present. The
12971         --  presence of NOT operators will be handled properly when we call
12972         --  Get_Current_Value_Condition.
12973
12974         while Nkind (Cond) = N_Op_Not loop
12975            Cond := Right_Opnd (Cond);
12976         end loop;
12977
12978         --  For an AND or AND THEN, recursively process operands
12979
12980         if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
12981            Set_Expression_Current_Value (Left_Opnd (Cond));
12982            Set_Expression_Current_Value (Right_Opnd (Cond));
12983            return;
12984         end if;
12985
12986         --  Check possible relational operator
12987
12988         if Nkind (Cond) in N_Op_Compare then
12989            if Compile_Time_Known_Value (Right_Opnd (Cond)) then
12990               Set_Entity_Current_Value (Left_Opnd (Cond));
12991            elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
12992               Set_Entity_Current_Value (Right_Opnd (Cond));
12993            end if;
12994
12995         elsif Nkind (Cond) in N_Type_Conversion
12996                             | N_Qualified_Expression
12997                             | N_Expression_With_Actions
12998         then
12999            Set_Expression_Current_Value (Expression (Cond));
13000
13001         --  Check possible boolean variable reference
13002
13003         else
13004            Set_Entity_Current_Value (Cond);
13005         end if;
13006      end Set_Expression_Current_Value;
13007
13008   --  Start of processing for Set_Current_Value_Condition
13009
13010   begin
13011      Set_Expression_Current_Value (Condition (Cnode));
13012   end Set_Current_Value_Condition;
13013
13014   --------------------------
13015   -- Set_Elaboration_Flag --
13016   --------------------------
13017
13018   procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
13019      Loc : constant Source_Ptr := Sloc (N);
13020      Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
13021      Asn : Node_Id;
13022
13023   begin
13024      if Present (Ent) then
13025
13026         --  Nothing to do if at the compilation unit level, because in this
13027         --  case the flag is set by the binder generated elaboration routine.
13028
13029         if Nkind (Parent (N)) = N_Compilation_Unit then
13030            null;
13031
13032         --  Here we do need to generate an assignment statement
13033
13034         else
13035            Check_Restriction (No_Elaboration_Code, N);
13036
13037            Asn :=
13038              Make_Assignment_Statement (Loc,
13039                Name       => New_Occurrence_Of (Ent, Loc),
13040                Expression => Make_Integer_Literal (Loc, Uint_1));
13041
13042            --  Mark the assignment statement as elaboration code. This allows
13043            --  the early call region mechanism (see Sem_Elab) to properly
13044            --  ignore such assignments even though they are nonpreelaborable
13045            --  code.
13046
13047            Set_Is_Elaboration_Code (Asn);
13048
13049            if Nkind (Parent (N)) = N_Subunit then
13050               Insert_After (Corresponding_Stub (Parent (N)), Asn);
13051            else
13052               Insert_After (N, Asn);
13053            end if;
13054
13055            Analyze (Asn);
13056
13057            --  Kill current value indication. This is necessary because the
13058            --  tests of this flag are inserted out of sequence and must not
13059            --  pick up bogus indications of the wrong constant value.
13060
13061            Set_Current_Value (Ent, Empty);
13062
13063            --  If the subprogram is in the current declarative part and
13064            --  'access has been applied to it, generate an elaboration
13065            --  check at the beginning of the declarations of the body.
13066
13067            if Nkind (N) = N_Subprogram_Body
13068              and then Address_Taken (Spec_Id)
13069              and then
13070                Ekind (Scope (Spec_Id)) in E_Block | E_Procedure | E_Function
13071            then
13072               declare
13073                  Loc   : constant Source_Ptr := Sloc (N);
13074                  Decls : constant List_Id    := Declarations (N);
13075                  Chk   : Node_Id;
13076
13077               begin
13078                  --  No need to generate this check if first entry in the
13079                  --  declaration list is a raise of Program_Error now.
13080
13081                  if Present (Decls)
13082                    and then Nkind (First (Decls)) = N_Raise_Program_Error
13083                  then
13084                     return;
13085                  end if;
13086
13087                  --  Otherwise generate the check
13088
13089                  Chk :=
13090                    Make_Raise_Program_Error (Loc,
13091                      Condition =>
13092                        Make_Op_Eq (Loc,
13093                          Left_Opnd  => New_Occurrence_Of (Ent, Loc),
13094                          Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
13095                      Reason    => PE_Access_Before_Elaboration);
13096
13097                  if No (Decls) then
13098                     Set_Declarations (N, New_List (Chk));
13099                  else
13100                     Prepend (Chk, Decls);
13101                  end if;
13102
13103                  Analyze (Chk);
13104               end;
13105            end if;
13106         end if;
13107      end if;
13108   end Set_Elaboration_Flag;
13109
13110   ----------------------------
13111   -- Set_Renamed_Subprogram --
13112   ----------------------------
13113
13114   procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
13115   begin
13116      --  If input node is an identifier, we can just reset it
13117
13118      if Nkind (N) = N_Identifier then
13119         Set_Chars  (N, Chars (E));
13120         Set_Entity (N, E);
13121
13122         --  Otherwise we have to do a rewrite, preserving Comes_From_Source
13123
13124      else
13125         declare
13126            CS : constant Boolean := Comes_From_Source (N);
13127         begin
13128            Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
13129            Set_Entity (N, E);
13130            Set_Comes_From_Source (N, CS);
13131            Set_Analyzed (N, True);
13132         end;
13133      end if;
13134   end Set_Renamed_Subprogram;
13135
13136   ----------------------
13137   -- Side_Effect_Free --
13138   ----------------------
13139
13140   function Side_Effect_Free
13141     (N            : Node_Id;
13142      Name_Req     : Boolean := False;
13143      Variable_Ref : Boolean := False) return Boolean
13144   is
13145      Typ : constant Entity_Id := Etype (N);
13146      --  Result type of the expression
13147
13148      function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
13149      --  The argument N is a construct where the Prefix is dereferenced if it
13150      --  is an access type and the result is a variable. The call returns True
13151      --  if the construct is side effect free (not considering side effects in
13152      --  other than the prefix which are to be tested by the caller).
13153
13154      function Within_In_Parameter (N : Node_Id) return Boolean;
13155      --  Determines if N is a subcomponent of a composite in-parameter. If so,
13156      --  N is not side-effect free when the actual is global and modifiable
13157      --  indirectly from within a subprogram, because it may be passed by
13158      --  reference. The front-end must be conservative here and assume that
13159      --  this may happen with any array or record type. On the other hand, we
13160      --  cannot create temporaries for all expressions for which this
13161      --  condition is true, for various reasons that might require clearing up
13162      --  ??? For example, discriminant references that appear out of place, or
13163      --  spurious type errors with class-wide expressions. As a result, we
13164      --  limit the transformation to loop bounds, which is so far the only
13165      --  case that requires it.
13166
13167      -----------------------------
13168      -- Safe_Prefixed_Reference --
13169      -----------------------------
13170
13171      function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
13172      begin
13173         --  If prefix is not side effect free, definitely not safe
13174
13175         if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then
13176            return False;
13177
13178         --  If the prefix is of an access type that is not access-to-constant,
13179         --  then this construct is a variable reference, which means it is to
13180         --  be considered to have side effects if Variable_Ref is set True.
13181
13182         elsif Is_Access_Type (Etype (Prefix (N)))
13183           and then not Is_Access_Constant (Etype (Prefix (N)))
13184           and then Variable_Ref
13185         then
13186            --  Exception is a prefix that is the result of a previous removal
13187            --  of side effects.
13188
13189            return Is_Entity_Name (Prefix (N))
13190              and then not Comes_From_Source (Prefix (N))
13191              and then Ekind (Entity (Prefix (N))) = E_Constant
13192              and then Is_Internal_Name (Chars (Entity (Prefix (N))));
13193
13194         --  If the prefix is an explicit dereference then this construct is a
13195         --  variable reference, which means it is to be considered to have
13196         --  side effects if Variable_Ref is True.
13197
13198         --  We do NOT exclude dereferences of access-to-constant types because
13199         --  we handle them as constant view of variables.
13200
13201         elsif Nkind (Prefix (N)) = N_Explicit_Dereference
13202           and then Variable_Ref
13203         then
13204            return False;
13205
13206         --  Note: The following test is the simplest way of solving a complex
13207         --  problem uncovered by the following test (Side effect on loop bound
13208         --  that is a subcomponent of a global variable:
13209
13210         --    with Text_Io; use Text_Io;
13211         --    procedure Tloop is
13212         --      type X is
13213         --        record
13214         --          V : Natural := 4;
13215         --          S : String (1..5) := (others => 'a');
13216         --        end record;
13217         --      X1 : X;
13218
13219         --      procedure Modi;
13220
13221         --      generic
13222         --        with procedure Action;
13223         --      procedure Loop_G (Arg : X; Msg : String)
13224
13225         --      procedure Loop_G (Arg : X; Msg : String) is
13226         --      begin
13227         --        Put_Line ("begin loop_g " & Msg & " will loop till: "
13228         --                  & Natural'Image (Arg.V));
13229         --        for Index in 1 .. Arg.V loop
13230         --          Text_Io.Put_Line
13231         --            (Natural'Image (Index) & " " & Arg.S (Index));
13232         --          if Index > 2 then
13233         --            Modi;
13234         --          end if;
13235         --        end loop;
13236         --        Put_Line ("end loop_g " & Msg);
13237         --      end;
13238
13239         --      procedure Loop1 is new Loop_G (Modi);
13240         --      procedure Modi is
13241         --      begin
13242         --        X1.V := 1;
13243         --        Loop1 (X1, "from modi");
13244         --      end;
13245         --
13246         --    begin
13247         --      Loop1 (X1, "initial");
13248         --    end;
13249
13250         --  The output of the above program should be:
13251
13252         --    begin loop_g initial will loop till:  4
13253         --     1 a
13254         --     2 a
13255         --     3 a
13256         --    begin loop_g from modi will loop till:  1
13257         --     1 a
13258         --    end loop_g from modi
13259         --     4 a
13260         --    begin loop_g from modi will loop till:  1
13261         --     1 a
13262         --    end loop_g from modi
13263         --    end loop_g initial
13264
13265         --  If a loop bound is a subcomponent of a global variable, a
13266         --  modification of that variable within the loop may incorrectly
13267         --  affect the execution of the loop.
13268
13269         elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification
13270           and then Within_In_Parameter (Prefix (N))
13271           and then Variable_Ref
13272         then
13273            return False;
13274
13275         --  All other cases are side effect free
13276
13277         else
13278            return True;
13279         end if;
13280      end Safe_Prefixed_Reference;
13281
13282      -------------------------
13283      -- Within_In_Parameter --
13284      -------------------------
13285
13286      function Within_In_Parameter (N : Node_Id) return Boolean is
13287      begin
13288         if not Comes_From_Source (N) then
13289            return False;
13290
13291         elsif Is_Entity_Name (N) then
13292            return Ekind (Entity (N)) = E_In_Parameter;
13293
13294         elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
13295            return Within_In_Parameter (Prefix (N));
13296
13297         else
13298            return False;
13299         end if;
13300      end Within_In_Parameter;
13301
13302   --  Start of processing for Side_Effect_Free
13303
13304   begin
13305      --  If volatile reference, always consider it to have side effects
13306
13307      if Is_Volatile_Reference (N) then
13308         return False;
13309      end if;
13310
13311      --  Note on checks that could raise Constraint_Error. Strictly, if we
13312      --  take advantage of 11.6, these checks do not count as side effects.
13313      --  However, we would prefer to consider that they are side effects,
13314      --  since the back end CSE does not work very well on expressions which
13315      --  can raise Constraint_Error. On the other hand if we don't consider
13316      --  them to be side effect free, then we get some awkward expansions
13317      --  in -gnato mode, resulting in code insertions at a point where we
13318      --  do not have a clear model for performing the insertions.
13319
13320      --  Special handling for entity names
13321
13322      if Is_Entity_Name (N) then
13323
13324         --  A type reference is always side effect free
13325
13326         if Is_Type (Entity (N)) then
13327            return True;
13328
13329         --  Variables are considered to be a side effect if Variable_Ref
13330         --  is set or if we have a volatile reference and Name_Req is off.
13331         --  If Name_Req is True then we can't help returning a name which
13332         --  effectively allows multiple references in any case.
13333
13334         elsif Is_Variable (N, Use_Original_Node => False) then
13335            return not Variable_Ref
13336              and then (not Is_Volatile_Reference (N) or else Name_Req);
13337
13338         --  Any other entity (e.g. a subtype name) is definitely side
13339         --  effect free.
13340
13341         else
13342            return True;
13343         end if;
13344
13345      --  A value known at compile time is always side effect free
13346
13347      elsif Compile_Time_Known_Value (N) then
13348         return True;
13349
13350      --  A variable renaming is not side-effect free, because the renaming
13351      --  will function like a macro in the front-end in some cases, and an
13352      --  assignment can modify the component designated by N, so we need to
13353      --  create a temporary for it.
13354
13355      --  The guard testing for Entity being present is needed at least in
13356      --  the case of rewritten predicate expressions, and may well also be
13357      --  appropriate elsewhere. Obviously we can't go testing the entity
13358      --  field if it does not exist, so it's reasonable to say that this is
13359      --  not the renaming case if it does not exist.
13360
13361      elsif Is_Entity_Name (Original_Node (N))
13362        and then Present (Entity (Original_Node (N)))
13363        and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
13364        and then Ekind (Entity (Original_Node (N))) /= E_Constant
13365      then
13366         declare
13367            RO : constant Node_Id :=
13368                   Renamed_Object (Entity (Original_Node (N)));
13369
13370         begin
13371            --  If the renamed object is an indexed component, or an
13372            --  explicit dereference, then the designated object could
13373            --  be modified by an assignment.
13374
13375            if Nkind (RO) in N_Indexed_Component | N_Explicit_Dereference then
13376               return False;
13377
13378            --  A selected component must have a safe prefix
13379
13380            elsif Nkind (RO) = N_Selected_Component then
13381               return Safe_Prefixed_Reference (RO);
13382
13383            --  In all other cases, designated object cannot be changed so
13384            --  we are side effect free.
13385
13386            else
13387               return True;
13388            end if;
13389         end;
13390
13391      --  Remove_Side_Effects generates an object renaming declaration to
13392      --  capture the expression of a class-wide expression. In VM targets
13393      --  the frontend performs no expansion for dispatching calls to
13394      --  class- wide types since they are handled by the VM. Hence, we must
13395      --  locate here if this node corresponds to a previous invocation of
13396      --  Remove_Side_Effects to avoid a never ending loop in the frontend.
13397
13398      elsif not Tagged_Type_Expansion
13399        and then not Comes_From_Source (N)
13400        and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
13401        and then Is_Class_Wide_Type (Typ)
13402      then
13403         return True;
13404
13405      --  Generating C the type conversion of an access to constrained array
13406      --  type into an access to unconstrained array type involves initializing
13407      --  a fat pointer and the expression cannot be assumed to be free of side
13408      --  effects since it must referenced several times to compute its bounds.
13409
13410      elsif Modify_Tree_For_C
13411        and then Nkind (N) = N_Type_Conversion
13412        and then Is_Access_Type (Typ)
13413        and then Is_Array_Type (Designated_Type (Typ))
13414        and then not Is_Constrained (Designated_Type (Typ))
13415      then
13416         return False;
13417      end if;
13418
13419      --  For other than entity names and compile time known values,
13420      --  check the node kind for special processing.
13421
13422      case Nkind (N) is
13423
13424         --  An attribute reference is side-effect free if its expressions
13425         --  are side-effect free and its prefix is side-effect free or is
13426         --  an entity reference.
13427
13428         when N_Attribute_Reference =>
13429            return Side_Effect_Free_Attribute (Attribute_Name (N))
13430                     and then
13431                   Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
13432                     and then
13433                   (Is_Entity_Name (Prefix (N))
13434                      or else
13435                    Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref));
13436
13437         --  A binary operator is side effect free if and both operands are
13438         --  side effect free. For this purpose binary operators include
13439         --  membership tests and short circuit forms.
13440
13441         when N_Binary_Op
13442            | N_Membership_Test
13443            | N_Short_Circuit
13444         =>
13445            return Side_Effect_Free (Left_Opnd  (N), Name_Req, Variable_Ref)
13446                     and then
13447                   Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
13448
13449         --  An explicit dereference is side effect free only if it is
13450         --  a side effect free prefixed reference.
13451
13452         when N_Explicit_Dereference =>
13453            return Safe_Prefixed_Reference (N);
13454
13455         --  An expression with action is side effect free if its expression
13456         --  is side effect free and it has no actions.
13457
13458         when N_Expression_With_Actions =>
13459            return
13460              Is_Empty_List (Actions (N))
13461                and then Side_Effect_Free
13462                           (Expression (N), Name_Req, Variable_Ref);
13463
13464         --  A call to _rep_to_pos is side effect free, since we generate
13465         --  this pure function call ourselves. Moreover it is critically
13466         --  important to make this exception, since otherwise we can have
13467         --  discriminants in array components which don't look side effect
13468         --  free in the case of an array whose index type is an enumeration
13469         --  type with an enumeration rep clause.
13470
13471         --  All other function calls are not side effect free
13472
13473         when N_Function_Call =>
13474            return
13475              Nkind (Name (N)) = N_Identifier
13476                and then Is_TSS (Name (N), TSS_Rep_To_Pos)
13477                and then Side_Effect_Free
13478                           (First (Parameter_Associations (N)),
13479                            Name_Req, Variable_Ref);
13480
13481         --  An IF expression is side effect free if it's of a scalar type, and
13482         --  all its components are all side effect free (conditions and then
13483         --  actions and else actions). We restrict to scalar types, since it
13484         --  is annoying to deal with things like (if A then B else C)'First
13485         --  where the type involved is a string type.
13486
13487         when N_If_Expression =>
13488            return
13489              Is_Scalar_Type (Typ)
13490                and then Side_Effect_Free
13491                           (Expressions (N), Name_Req, Variable_Ref);
13492
13493         --  An indexed component is side effect free if it is a side
13494         --  effect free prefixed reference and all the indexing
13495         --  expressions are side effect free.
13496
13497         when N_Indexed_Component =>
13498            return
13499              Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
13500                and then Safe_Prefixed_Reference (N);
13501
13502         --  A type qualification, type conversion, or unchecked expression is
13503         --  side effect free if the expression is side effect free.
13504
13505         when N_Qualified_Expression
13506            | N_Type_Conversion
13507            | N_Unchecked_Expression
13508         =>
13509            return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
13510
13511         --  A selected component is side effect free only if it is a side
13512         --  effect free prefixed reference.
13513
13514         when N_Selected_Component =>
13515            return Safe_Prefixed_Reference (N);
13516
13517         --  A range is side effect free if the bounds are side effect free
13518
13519         when N_Range =>
13520            return Side_Effect_Free (Low_Bound (N),  Name_Req, Variable_Ref)
13521                     and then
13522                   Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref);
13523
13524         --  A slice is side effect free if it is a side effect free
13525         --  prefixed reference and the bounds are side effect free.
13526
13527         when N_Slice =>
13528            return
13529               Side_Effect_Free (Discrete_Range (N), Name_Req, Variable_Ref)
13530                 and then Safe_Prefixed_Reference (N);
13531
13532         --  A unary operator is side effect free if the operand
13533         --  is side effect free.
13534
13535         when N_Unary_Op =>
13536            return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
13537
13538         --  An unchecked type conversion is side effect free only if it
13539         --  is safe and its argument is side effect free.
13540
13541         when N_Unchecked_Type_Conversion =>
13542            return
13543              Safe_Unchecked_Type_Conversion (N)
13544                and then Side_Effect_Free
13545                           (Expression (N), Name_Req, Variable_Ref);
13546
13547         --  A literal is side effect free
13548
13549         when N_Character_Literal
13550            | N_Integer_Literal
13551            | N_Real_Literal
13552            | N_String_Literal
13553         =>
13554            return True;
13555
13556         --  An aggregate is side effect free if all its values are compile
13557         --  time known.
13558
13559         when N_Aggregate =>
13560            return Compile_Time_Known_Aggregate (N);
13561
13562         --  We consider that anything else has side effects. This is a bit
13563         --  crude, but we are pretty close for most common cases, and we
13564         --  are certainly correct (i.e. we never return True when the
13565         --  answer should be False).
13566
13567         when others =>
13568            return False;
13569      end case;
13570   end Side_Effect_Free;
13571
13572   --  A list is side effect free if all elements of the list are side
13573   --  effect free.
13574
13575   function Side_Effect_Free
13576     (L            : List_Id;
13577      Name_Req     : Boolean := False;
13578      Variable_Ref : Boolean := False) return Boolean
13579   is
13580      N : Node_Id;
13581
13582   begin
13583      if L = No_List or else L = Error_List then
13584         return True;
13585
13586      else
13587         N := First (L);
13588         while Present (N) loop
13589            if not Side_Effect_Free (N, Name_Req, Variable_Ref) then
13590               return False;
13591            else
13592               Next (N);
13593            end if;
13594         end loop;
13595
13596         return True;
13597      end if;
13598   end Side_Effect_Free;
13599
13600   --------------------------------
13601   -- Side_Effect_Free_Attribute --
13602   --------------------------------
13603
13604   function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean is
13605   begin
13606      case Name is
13607         when Name_Input =>
13608            return False;
13609
13610         when Name_Image
13611            | Name_Img
13612            | Name_Wide_Image
13613            | Name_Wide_Wide_Image
13614         =>
13615            --  CodePeer doesn't want to see replicated copies of 'Image calls
13616
13617            return not CodePeer_Mode;
13618
13619         when others =>
13620            return True;
13621      end case;
13622   end Side_Effect_Free_Attribute;
13623
13624   ----------------------------------
13625   -- Silly_Boolean_Array_Not_Test --
13626   ----------------------------------
13627
13628   --  This procedure implements an odd and silly test. We explicitly check
13629   --  for the case where the 'First of the component type is equal to the
13630   --  'Last of this component type, and if this is the case, we make sure
13631   --  that constraint error is raised. The reason is that the NOT is bound
13632   --  to cause CE in this case, and we will not otherwise catch it.
13633
13634   --  No such check is required for AND and OR, since for both these cases
13635   --  False op False = False, and True op True = True. For the XOR case,
13636   --  see Silly_Boolean_Array_Xor_Test.
13637
13638   --  Believe it or not, this was reported as a bug. Note that nearly always,
13639   --  the test will evaluate statically to False, so the code will be
13640   --  statically removed, and no extra overhead caused.
13641
13642   procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
13643      Loc : constant Source_Ptr := Sloc (N);
13644      CT  : constant Entity_Id  := Component_Type (T);
13645
13646   begin
13647      --  The check we install is
13648
13649      --    constraint_error when
13650      --      component_type'first = component_type'last
13651      --        and then array_type'Length /= 0)
13652
13653      --  We need the last guard because we don't want to raise CE for empty
13654      --  arrays since no out of range values result. (Empty arrays with a
13655      --  component type of True .. True -- very useful -- even the ACATS
13656      --  does not test that marginal case).
13657
13658      Insert_Action (N,
13659        Make_Raise_Constraint_Error (Loc,
13660          Condition =>
13661            Make_And_Then (Loc,
13662              Left_Opnd =>
13663                Make_Op_Eq (Loc,
13664                  Left_Opnd =>
13665                    Make_Attribute_Reference (Loc,
13666                      Prefix         => New_Occurrence_Of (CT, Loc),
13667                      Attribute_Name => Name_First),
13668
13669                  Right_Opnd =>
13670                    Make_Attribute_Reference (Loc,
13671                      Prefix         => New_Occurrence_Of (CT, Loc),
13672                      Attribute_Name => Name_Last)),
13673
13674              Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
13675          Reason => CE_Range_Check_Failed));
13676   end Silly_Boolean_Array_Not_Test;
13677
13678   ----------------------------------
13679   -- Silly_Boolean_Array_Xor_Test --
13680   ----------------------------------
13681
13682   --  This procedure implements an odd and silly test. We explicitly check
13683   --  for the XOR case where the component type is True .. True, since this
13684   --  will raise constraint error. A special check is required since CE
13685   --  will not be generated otherwise (cf Expand_Packed_Not).
13686
13687   --  No such check is required for AND and OR, since for both these cases
13688   --  False op False = False, and True op True = True, and no check is
13689   --  required for the case of False .. False, since False xor False = False.
13690   --  See also Silly_Boolean_Array_Not_Test
13691
13692   procedure Silly_Boolean_Array_Xor_Test
13693     (N : Node_Id;
13694      R : Node_Id;
13695      T : Entity_Id)
13696   is
13697      Loc : constant Source_Ptr := Sloc (N);
13698      CT  : constant Entity_Id  := Component_Type (T);
13699
13700   begin
13701      --  The check we install is
13702
13703      --    constraint_error when
13704      --      Boolean (component_type'First)
13705      --        and then Boolean (component_type'Last)
13706      --        and then array_type'Length /= 0)
13707
13708      --  We need the last guard because we don't want to raise CE for empty
13709      --  arrays since no out of range values result (Empty arrays with a
13710      --  component type of True .. True -- very useful -- even the ACATS
13711      --  does not test that marginal case).
13712
13713      Insert_Action (N,
13714        Make_Raise_Constraint_Error (Loc,
13715          Condition =>
13716            Make_And_Then (Loc,
13717              Left_Opnd  =>
13718                Make_And_Then (Loc,
13719                  Left_Opnd  =>
13720                    Convert_To (Standard_Boolean,
13721                      Make_Attribute_Reference (Loc,
13722                        Prefix         => New_Occurrence_Of (CT, Loc),
13723                        Attribute_Name => Name_First)),
13724
13725                  Right_Opnd =>
13726                    Convert_To (Standard_Boolean,
13727                      Make_Attribute_Reference (Loc,
13728                        Prefix         => New_Occurrence_Of (CT, Loc),
13729                        Attribute_Name => Name_Last))),
13730
13731              Right_Opnd => Make_Non_Empty_Check (Loc, R)),
13732          Reason    => CE_Range_Check_Failed));
13733   end Silly_Boolean_Array_Xor_Test;
13734
13735   ----------------------------
13736   -- Small_Integer_Type_For --
13737   ----------------------------
13738
13739   function Small_Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id
13740   is
13741   begin
13742      pragma Assert (S <= System_Max_Integer_Size);
13743
13744      if S <= Standard_Short_Short_Integer_Size then
13745         if Uns then
13746            return Standard_Short_Short_Unsigned;
13747         else
13748            return Standard_Short_Short_Integer;
13749         end if;
13750
13751      elsif S <= Standard_Short_Integer_Size then
13752         if Uns then
13753            return Standard_Short_Unsigned;
13754         else
13755            return Standard_Short_Integer;
13756         end if;
13757
13758      elsif S <= Standard_Integer_Size then
13759         if Uns then
13760            return Standard_Unsigned;
13761         else
13762            return Standard_Integer;
13763         end if;
13764
13765      elsif S <= Standard_Long_Integer_Size then
13766         if Uns then
13767            return Standard_Long_Unsigned;
13768         else
13769            return Standard_Long_Integer;
13770         end if;
13771
13772      elsif S <= Standard_Long_Long_Integer_Size then
13773         if Uns then
13774            return Standard_Long_Long_Unsigned;
13775         else
13776            return Standard_Long_Long_Integer;
13777         end if;
13778
13779      elsif S <= Standard_Long_Long_Long_Integer_Size then
13780         if Uns then
13781            return Standard_Long_Long_Long_Unsigned;
13782         else
13783            return Standard_Long_Long_Long_Integer;
13784         end if;
13785
13786      else
13787         raise Program_Error;
13788      end if;
13789   end Small_Integer_Type_For;
13790
13791   -------------------
13792   -- Type_Map_Hash --
13793   -------------------
13794
13795   function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header is
13796   begin
13797      return Type_Map_Header (Id mod Type_Map_Size);
13798   end Type_Map_Hash;
13799
13800   ------------------------------------------
13801   -- Type_May_Have_Bit_Aligned_Components --
13802   ------------------------------------------
13803
13804   function Type_May_Have_Bit_Aligned_Components
13805     (Typ : Entity_Id) return Boolean
13806   is
13807   begin
13808      --  Array type, check component type
13809
13810      if Is_Array_Type (Typ) then
13811         return
13812           Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
13813
13814      --  Record type, check components
13815
13816      elsif Is_Record_Type (Typ) then
13817         declare
13818            E : Entity_Id;
13819
13820         begin
13821            E := First_Component_Or_Discriminant (Typ);
13822            while Present (E) loop
13823               --  This is the crucial test: if the component itself causes
13824               --  trouble, then we can stop and return True.
13825
13826               if Component_May_Be_Bit_Aligned (E) then
13827                  return True;
13828               end if;
13829
13830               --  Otherwise, we need to test its type, to see if it may
13831               --  itself contain a troublesome component.
13832
13833               if Type_May_Have_Bit_Aligned_Components (Etype (E)) then
13834                  return True;
13835               end if;
13836
13837               Next_Component_Or_Discriminant (E);
13838            end loop;
13839
13840            return False;
13841         end;
13842
13843      --  Type other than array or record is always OK
13844
13845      else
13846         return False;
13847      end if;
13848   end Type_May_Have_Bit_Aligned_Components;
13849
13850   -------------------------------
13851   -- Update_Primitives_Mapping --
13852   -------------------------------
13853
13854   procedure Update_Primitives_Mapping
13855     (Inher_Id : Entity_Id;
13856      Subp_Id  : Entity_Id)
13857   is
13858   begin
13859      Map_Types
13860        (Parent_Type  => Find_Dispatching_Type (Inher_Id),
13861         Derived_Type => Find_Dispatching_Type (Subp_Id));
13862   end Update_Primitives_Mapping;
13863
13864   ----------------------------------
13865   -- Within_Case_Or_If_Expression --
13866   ----------------------------------
13867
13868   function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is
13869      Par : Node_Id;
13870
13871   begin
13872      --  Locate an enclosing case or if expression. Note that these constructs
13873      --  can be expanded into Expression_With_Actions, hence the test of the
13874      --  original node.
13875
13876      Par := Parent (N);
13877      while Present (Par) loop
13878         if Nkind (Original_Node (Par)) in N_Case_Expression | N_If_Expression
13879         then
13880            return True;
13881
13882         --  Prevent the search from going too far
13883
13884         elsif Is_Body_Or_Package_Declaration (Par) then
13885            return False;
13886         end if;
13887
13888         Par := Parent (Par);
13889      end loop;
13890
13891      return False;
13892   end Within_Case_Or_If_Expression;
13893
13894   ------------------------------
13895   -- Predicate_Check_In_Scope --
13896   ------------------------------
13897
13898   function Predicate_Check_In_Scope (N : Node_Id) return Boolean is
13899      S : Entity_Id;
13900
13901   begin
13902      S := Current_Scope;
13903      while Present (S) and then not Is_Subprogram (S) loop
13904         S := Scope (S);
13905      end loop;
13906
13907      if Present (S) then
13908
13909         --  Predicate checks should only be enabled in init procs for
13910         --  expressions coming from source.
13911
13912         if Is_Init_Proc (S) then
13913            return Comes_From_Source (N);
13914
13915         elsif Get_TSS_Name (S) /= TSS_Null
13916           and then not Is_Predicate_Function (S)
13917           and then not Is_Predicate_Function_M (S)
13918         then
13919            return False;
13920         end if;
13921      end if;
13922
13923      return True;
13924   end Predicate_Check_In_Scope;
13925
13926end Exp_Util;
13927