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