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