File : exp_util.adb


   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-2016, 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 
  26 with Aspects;  use Aspects;
  27 with Atree;    use Atree;
  28 with Casing;   use Casing;
  29 with Checks;   use Checks;
  30 with Debug;    use Debug;
  31 with Einfo;    use Einfo;
  32 with Elists;   use Elists;
  33 with Errout;   use Errout;
  34 with Exp_Aggr; use Exp_Aggr;
  35 with Exp_Ch6;  use Exp_Ch6;
  36 with Exp_Ch7;  use Exp_Ch7;
  37 with Ghost;    use Ghost;
  38 with Inline;   use Inline;
  39 with Itypes;   use Itypes;
  40 with Lib;      use Lib;
  41 with Nlists;   use Nlists;
  42 with Nmake;    use Nmake;
  43 with Opt;      use Opt;
  44 with Restrict; use Restrict;
  45 with Rident;   use Rident;
  46 with Sem;      use Sem;
  47 with Sem_Aux;  use Sem_Aux;
  48 with Sem_Ch8;  use Sem_Ch8;
  49 with Sem_Ch13; use Sem_Ch13;
  50 with Sem_Eval; use Sem_Eval;
  51 with Sem_Res;  use Sem_Res;
  52 with Sem_Type; use Sem_Type;
  53 with Sem_Util; use Sem_Util;
  54 with Snames;   use Snames;
  55 with Stand;    use Stand;
  56 with Stringt;  use Stringt;
  57 with Targparm; use Targparm;
  58 with Tbuild;   use Tbuild;
  59 with Ttypes;   use Ttypes;
  60 with Urealp;   use Urealp;
  61 with Validsw;  use Validsw;
  62 
  63 package body Exp_Util is
  64 
  65    -----------------------
  66    -- Local Subprograms --
  67    -----------------------
  68 
  69    function Build_Task_Array_Image
  70      (Loc    : Source_Ptr;
  71       Id_Ref : Node_Id;
  72       A_Type : Entity_Id;
  73       Dyn    : Boolean := False) return Node_Id;
  74    --  Build function to generate the image string for a task that is an array
  75    --  component, concatenating the images of each index. To avoid storage
  76    --  leaks, the string is built with successive slice assignments. The flag
  77    --  Dyn indicates whether this is called for the initialization procedure of
  78    --  an array of tasks, or for the name of a dynamically created task that is
  79    --  assigned to an indexed component.
  80 
  81    function Build_Task_Image_Function
  82      (Loc   : Source_Ptr;
  83       Decls : List_Id;
  84       Stats : List_Id;
  85       Res   : Entity_Id) return Node_Id;
  86    --  Common processing for Task_Array_Image and Task_Record_Image. Build
  87    --  function body that computes image.
  88 
  89    procedure Build_Task_Image_Prefix
  90       (Loc    : Source_Ptr;
  91        Len    : out Entity_Id;
  92        Res    : out Entity_Id;
  93        Pos    : out Entity_Id;
  94        Prefix : Entity_Id;
  95        Sum    : Node_Id;
  96        Decls  : List_Id;
  97        Stats  : List_Id);
  98    --  Common processing for Task_Array_Image and Task_Record_Image. Create
  99    --  local variables and assign prefix of name to result string.
 100 
 101    function Build_Task_Record_Image
 102      (Loc    : Source_Ptr;
 103       Id_Ref : Node_Id;
 104       Dyn    : Boolean := False) return Node_Id;
 105    --  Build function to generate the image string for a task that is a record
 106    --  component. Concatenate name of variable with that of selector. The flag
 107    --  Dyn indicates whether this is called for the initialization procedure of
 108    --  record with task components, or for a dynamically created task that is
 109    --  assigned to a selected component.
 110 
 111    procedure Evaluate_Slice_Bounds (Slice : Node_Id);
 112    --  Force evaluation of bounds of a slice, which may be given by a range
 113    --  or by a subtype indication with or without a constraint.
 114 
 115    function Make_CW_Equivalent_Type
 116      (T : Entity_Id;
 117       E : Node_Id) return Entity_Id;
 118    --  T is a class-wide type entity, E is the initial expression node that
 119    --  constrains T in case such as: " X: T := E" or "new T'(E)". This function
 120    --  returns the entity of the Equivalent type and inserts on the fly the
 121    --  necessary declaration such as:
 122    --
 123    --    type anon is record
 124    --       _parent : Root_Type (T); constrained with E discriminants (if any)
 125    --       Extension : String (1 .. expr to match size of E);
 126    --    end record;
 127    --
 128    --  This record is compatible with any object of the class of T thanks to
 129    --  the first field and has the same size as E thanks to the second.
 130 
 131    function Make_Literal_Range
 132      (Loc         : Source_Ptr;
 133       Literal_Typ : Entity_Id) return Node_Id;
 134    --  Produce a Range node whose bounds are:
 135    --    Low_Bound (Literal_Type) ..
 136    --        Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
 137    --  this is used for expanding declarations like X : String := "sdfgdfg";
 138    --
 139    --  If the index type of the target array is not integer, we generate:
 140    --     Low_Bound (Literal_Type) ..
 141    --        Literal_Type'Val
 142    --          (Literal_Type'Pos (Low_Bound (Literal_Type))
 143    --             + (Length (Literal_Typ) -1))
 144 
 145    function Make_Non_Empty_Check
 146      (Loc : Source_Ptr;
 147       N   : Node_Id) return Node_Id;
 148    --  Produce a boolean expression checking that the unidimensional array
 149    --  node N is not empty.
 150 
 151    function New_Class_Wide_Subtype
 152      (CW_Typ : Entity_Id;
 153       N      : Node_Id) return Entity_Id;
 154    --  Create an implicit subtype of CW_Typ attached to node N
 155 
 156    function Requires_Cleanup_Actions
 157      (L                 : List_Id;
 158       Lib_Level         : Boolean;
 159       Nested_Constructs : Boolean) return Boolean;
 160    --  Given a list L, determine whether it contains one of the following:
 161    --
 162    --    1) controlled objects
 163    --    2) library-level tagged types
 164    --
 165    --  Lib_Level is True when the list comes from a construct at the library
 166    --  level, and False otherwise. Nested_Constructs is True when any nested
 167    --  packages declared in L must be processed, and False otherwise.
 168 
 169    -------------------------------------
 170    -- Activate_Atomic_Synchronization --
 171    -------------------------------------
 172 
 173    procedure Activate_Atomic_Synchronization (N : Node_Id) is
 174       Msg_Node : Node_Id;
 175 
 176    begin
 177       case Nkind (Parent (N)) is
 178 
 179          --  Check for cases of appearing in the prefix of a construct where
 180          --  we don't need atomic synchronization for this kind of usage.
 181 
 182          when
 183               --  Nothing to do if we are the prefix of an attribute, since we
 184               --  do not want an atomic sync operation for things like 'Size.
 185 
 186               N_Attribute_Reference |
 187 
 188               --  The N_Reference node is like an attribute
 189 
 190               N_Reference           |
 191 
 192               --  Nothing to do for a reference to a component (or components)
 193               --  of a composite object. Only reads and updates of the object
 194               --  as a whole require atomic synchronization (RM C.6 (15)).
 195 
 196               N_Indexed_Component   |
 197               N_Selected_Component  |
 198               N_Slice               =>
 199 
 200             --  For all the above cases, nothing to do if we are the prefix
 201 
 202             if Prefix (Parent (N)) = N then
 203                return;
 204             end if;
 205 
 206          when others => null;
 207       end case;
 208 
 209       --  Nothing to do for the identifier in an object renaming declaration,
 210       --  the renaming itself does not need atomic synchronization.
 211 
 212       if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
 213          return;
 214       end if;
 215 
 216       --  Go ahead and set the flag
 217 
 218       Set_Atomic_Sync_Required (N);
 219 
 220       --  Generate info message if requested
 221 
 222       if Warn_On_Atomic_Synchronization then
 223          case Nkind (N) is
 224             when N_Identifier =>
 225                Msg_Node := N;
 226 
 227             when N_Selected_Component | N_Expanded_Name =>
 228                Msg_Node := Selector_Name (N);
 229 
 230             when N_Explicit_Dereference | N_Indexed_Component =>
 231                Msg_Node := Empty;
 232 
 233             when others =>
 234                pragma Assert (False);
 235                return;
 236          end case;
 237 
 238          if Present (Msg_Node) then
 239             Error_Msg_N
 240               ("info: atomic synchronization set for &?N?", Msg_Node);
 241          else
 242             Error_Msg_N
 243               ("info: atomic synchronization set?N?", N);
 244          end if;
 245       end if;
 246    end Activate_Atomic_Synchronization;
 247 
 248    ----------------------
 249    -- Adjust_Condition --
 250    ----------------------
 251 
 252    procedure Adjust_Condition (N : Node_Id) is
 253    begin
 254       if No (N) then
 255          return;
 256       end if;
 257 
 258       declare
 259          Loc : constant Source_Ptr := Sloc (N);
 260          T   : constant Entity_Id  := Etype (N);
 261          Ti  : Entity_Id;
 262 
 263       begin
 264          --  Defend against a call where the argument has no type, or has a
 265          --  type that is not Boolean. This can occur because of prior errors.
 266 
 267          if No (T) or else not Is_Boolean_Type (T) then
 268             return;
 269          end if;
 270 
 271          --  Apply validity checking if needed
 272 
 273          if Validity_Checks_On and Validity_Check_Tests then
 274             Ensure_Valid (N);
 275          end if;
 276 
 277          --  Immediate return if standard boolean, the most common case,
 278          --  where nothing needs to be done.
 279 
 280          if Base_Type (T) = Standard_Boolean then
 281             return;
 282          end if;
 283 
 284          --  Case of zero/non-zero semantics or non-standard enumeration
 285          --  representation. In each case, we rewrite the node as:
 286 
 287          --      ityp!(N) /= False'Enum_Rep
 288 
 289          --  where ityp is an integer type with large enough size to hold any
 290          --  value of type T.
 291 
 292          if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
 293             if Esize (T) <= Esize (Standard_Integer) then
 294                Ti := Standard_Integer;
 295             else
 296                Ti := Standard_Long_Long_Integer;
 297             end if;
 298 
 299             Rewrite (N,
 300               Make_Op_Ne (Loc,
 301                 Left_Opnd  => Unchecked_Convert_To (Ti, N),
 302                 Right_Opnd =>
 303                   Make_Attribute_Reference (Loc,
 304                     Attribute_Name => Name_Enum_Rep,
 305                     Prefix         =>
 306                       New_Occurrence_Of (First_Literal (T), Loc))));
 307             Analyze_And_Resolve (N, Standard_Boolean);
 308 
 309          else
 310             Rewrite (N, Convert_To (Standard_Boolean, N));
 311             Analyze_And_Resolve (N, Standard_Boolean);
 312          end if;
 313       end;
 314    end Adjust_Condition;
 315 
 316    ------------------------
 317    -- Adjust_Result_Type --
 318    ------------------------
 319 
 320    procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
 321    begin
 322       --  Ignore call if current type is not Standard.Boolean
 323 
 324       if Etype (N) /= Standard_Boolean then
 325          return;
 326       end if;
 327 
 328       --  If result is already of correct type, nothing to do. Note that
 329       --  this will get the most common case where everything has a type
 330       --  of Standard.Boolean.
 331 
 332       if Base_Type (T) = Standard_Boolean then
 333          return;
 334 
 335       else
 336          declare
 337             KP : constant Node_Kind := Nkind (Parent (N));
 338 
 339          begin
 340             --  If result is to be used as a Condition in the syntax, no need
 341             --  to convert it back, since if it was changed to Standard.Boolean
 342             --  using Adjust_Condition, that is just fine for this usage.
 343 
 344             if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
 345                return;
 346 
 347             --  If result is an operand of another logical operation, no need
 348             --  to reset its type, since Standard.Boolean is just fine, and
 349             --  such operations always do Adjust_Condition on their operands.
 350 
 351             elsif     KP in N_Op_Boolean
 352               or else KP in N_Short_Circuit
 353               or else KP = N_Op_Not
 354             then
 355                return;
 356 
 357             --  Otherwise we perform a conversion from the current type, which
 358             --  must be Standard.Boolean, to the desired type. Use the base
 359             --  type to prevent spurious constraint checks that are extraneous
 360             --  to the transformation. The type and its base have the same
 361             --  representation, standard or otherwise.
 362 
 363             else
 364                Set_Analyzed (N);
 365                Rewrite (N, Convert_To (Base_Type (T), N));
 366                Analyze_And_Resolve (N, Base_Type (T));
 367             end if;
 368          end;
 369       end if;
 370    end Adjust_Result_Type;
 371 
 372    --------------------------
 373    -- Append_Freeze_Action --
 374    --------------------------
 375 
 376    procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
 377       Fnode : Node_Id;
 378 
 379    begin
 380       Ensure_Freeze_Node (T);
 381       Fnode := Freeze_Node (T);
 382 
 383       if No (Actions (Fnode)) then
 384          Set_Actions (Fnode, New_List (N));
 385       else
 386          Append (N, Actions (Fnode));
 387       end if;
 388 
 389    end Append_Freeze_Action;
 390 
 391    ---------------------------
 392    -- Append_Freeze_Actions --
 393    ---------------------------
 394 
 395    procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
 396       Fnode : Node_Id;
 397 
 398    begin
 399       if No (L) then
 400          return;
 401       end if;
 402 
 403       Ensure_Freeze_Node (T);
 404       Fnode := Freeze_Node (T);
 405 
 406       if No (Actions (Fnode)) then
 407          Set_Actions (Fnode, L);
 408       else
 409          Append_List (L, Actions (Fnode));
 410       end if;
 411    end Append_Freeze_Actions;
 412 
 413    ------------------------------------
 414    -- Build_Allocate_Deallocate_Proc --
 415    ------------------------------------
 416 
 417    procedure Build_Allocate_Deallocate_Proc
 418      (N           : Node_Id;
 419       Is_Allocate : Boolean)
 420    is
 421       Desig_Typ    : Entity_Id;
 422       Expr         : Node_Id;
 423       Pool_Id      : Entity_Id;
 424       Proc_To_Call : Node_Id := Empty;
 425       Ptr_Typ      : Entity_Id;
 426 
 427       function Find_Object (E : Node_Id) return Node_Id;
 428       --  Given an arbitrary expression of an allocator, try to find an object
 429       --  reference in it, otherwise return the original expression.
 430 
 431       function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
 432       --  Determine whether subprogram Subp denotes a custom allocate or
 433       --  deallocate.
 434 
 435       -----------------
 436       -- Find_Object --
 437       -----------------
 438 
 439       function Find_Object (E : Node_Id) return Node_Id is
 440          Expr : Node_Id;
 441 
 442       begin
 443          pragma Assert (Is_Allocate);
 444 
 445          Expr := E;
 446          loop
 447             if Nkind (Expr) = N_Explicit_Dereference then
 448                Expr := Prefix (Expr);
 449 
 450             elsif Nkind (Expr) = N_Qualified_Expression then
 451                Expr := Expression (Expr);
 452 
 453             elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
 454 
 455                --  When interface class-wide types are involved in allocation,
 456                --  the expander introduces several levels of address arithmetic
 457                --  to perform dispatch table displacement. In this scenario the
 458                --  object appears as:
 459 
 460                --    Tag_Ptr (Base_Address (<object>'Address))
 461 
 462                --  Detect this case and utilize the whole expression as the
 463                --  "object" since it now points to the proper dispatch table.
 464 
 465                if Is_RTE (Etype (Expr), RE_Tag_Ptr) then
 466                   exit;
 467 
 468                --  Continue to strip the object
 469 
 470                else
 471                   Expr := Expression (Expr);
 472                end if;
 473 
 474             else
 475                exit;
 476             end if;
 477          end loop;
 478 
 479          return Expr;
 480       end Find_Object;
 481 
 482       ---------------------------------
 483       -- Is_Allocate_Deallocate_Proc --
 484       ---------------------------------
 485 
 486       function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
 487       begin
 488          --  Look for a subprogram body with only one statement which is a
 489          --  call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
 490 
 491          if Ekind (Subp) = E_Procedure
 492            and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
 493          then
 494             declare
 495                HSS  : constant Node_Id :=
 496                         Handled_Statement_Sequence (Parent (Parent (Subp)));
 497                Proc : Entity_Id;
 498 
 499             begin
 500                if Present (Statements (HSS))
 501                  and then Nkind (First (Statements (HSS))) =
 502                             N_Procedure_Call_Statement
 503                then
 504                   Proc := Entity (Name (First (Statements (HSS))));
 505 
 506                   return
 507                     Is_RTE (Proc, RE_Allocate_Any_Controlled)
 508                       or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
 509                end if;
 510             end;
 511          end if;
 512 
 513          return False;
 514       end Is_Allocate_Deallocate_Proc;
 515 
 516    --  Start of processing for Build_Allocate_Deallocate_Proc
 517 
 518    begin
 519       --  Obtain the attributes of the allocation / deallocation
 520 
 521       if Nkind (N) = N_Free_Statement then
 522          Expr := Expression (N);
 523          Ptr_Typ := Base_Type (Etype (Expr));
 524          Proc_To_Call := Procedure_To_Call (N);
 525 
 526       else
 527          if Nkind (N) = N_Object_Declaration then
 528             Expr := Expression (N);
 529          else
 530             Expr := N;
 531          end if;
 532 
 533          --  In certain cases an allocator with a qualified expression may
 534          --  be relocated and used as the initialization expression of a
 535          --  temporary:
 536 
 537          --    before:
 538          --       Obj : Ptr_Typ := new Desig_Typ'(...);
 539 
 540          --    after:
 541          --       Tmp : Ptr_Typ := new Desig_Typ'(...);
 542          --       Obj : Ptr_Typ := Tmp;
 543 
 544          --  Since the allocator is always marked as analyzed to avoid infinite
 545          --  expansion, it will never be processed by this routine given that
 546          --  the designated type needs finalization actions. Detect this case
 547          --  and complete the expansion of the allocator.
 548 
 549          if Nkind (Expr) = N_Identifier
 550            and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
 551            and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
 552          then
 553             Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
 554             return;
 555          end if;
 556 
 557          --  The allocator may have been rewritten into something else in which
 558          --  case the expansion performed by this routine does not apply.
 559 
 560          if Nkind (Expr) /= N_Allocator then
 561             return;
 562          end if;
 563 
 564          Ptr_Typ := Base_Type (Etype (Expr));
 565          Proc_To_Call := Procedure_To_Call (Expr);
 566       end if;
 567 
 568       Pool_Id := Associated_Storage_Pool (Ptr_Typ);
 569       Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
 570 
 571       --  Handle concurrent types
 572 
 573       if Is_Concurrent_Type (Desig_Typ)
 574         and then Present (Corresponding_Record_Type (Desig_Typ))
 575       then
 576          Desig_Typ := Corresponding_Record_Type (Desig_Typ);
 577       end if;
 578 
 579       --  Do not process allocations / deallocations without a pool
 580 
 581       if No (Pool_Id) then
 582          return;
 583 
 584       --  Do not process allocations on / deallocations from the secondary
 585       --  stack.
 586 
 587       elsif Is_RTE (Pool_Id, RE_SS_Pool) then
 588          return;
 589 
 590       --  Optimize the case where we are using the default Global_Pool_Object,
 591       --  and we don't need the heavy finalization machinery.
 592 
 593       elsif Pool_Id = RTE (RE_Global_Pool_Object)
 594         and then not Needs_Finalization (Desig_Typ)
 595       then
 596          return;
 597 
 598       --  Do not replicate the machinery if the allocator / free has already
 599       --  been expanded and has a custom Allocate / Deallocate.
 600 
 601       elsif Present (Proc_To_Call)
 602         and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
 603       then
 604          return;
 605       end if;
 606 
 607       if Needs_Finalization (Desig_Typ) then
 608 
 609          --  Certain run-time configurations and targets do not provide support
 610          --  for controlled types.
 611 
 612          if Restriction_Active (No_Finalization) then
 613             return;
 614 
 615          --  Do nothing if the access type may never allocate / deallocate
 616          --  objects.
 617 
 618          elsif No_Pool_Assigned (Ptr_Typ) then
 619             return;
 620          end if;
 621 
 622          --  The allocation / deallocation of a controlled object must be
 623          --  chained on / detached from a finalization master.
 624 
 625          pragma Assert (Present (Finalization_Master (Ptr_Typ)));
 626 
 627       --  The only other kind of allocation / deallocation supported by this
 628       --  routine is on / from a subpool.
 629 
 630       elsif Nkind (Expr) = N_Allocator
 631         and then No (Subpool_Handle_Name (Expr))
 632       then
 633          return;
 634       end if;
 635 
 636       declare
 637          Loc     : constant Source_Ptr := Sloc (N);
 638          Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
 639          Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
 640          Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
 641          Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
 642 
 643          Actuals      : List_Id;
 644          Fin_Addr_Id  : Entity_Id;
 645          Fin_Mas_Act  : Node_Id;
 646          Fin_Mas_Id   : Entity_Id;
 647          Proc_To_Call : Entity_Id;
 648          Subpool      : Node_Id := Empty;
 649 
 650       begin
 651          --  Step 1: Construct all the actuals for the call to library routine
 652          --  Allocate_Any_Controlled / Deallocate_Any_Controlled.
 653 
 654          --  a) Storage pool
 655 
 656          Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc));
 657 
 658          if Is_Allocate then
 659 
 660             --  b) Subpool
 661 
 662             if Nkind (Expr) = N_Allocator then
 663                Subpool := Subpool_Handle_Name (Expr);
 664             end if;
 665 
 666             --  If a subpool is present it can be an arbitrary name, so make
 667             --  the actual by copying the tree.
 668 
 669             if Present (Subpool) then
 670                Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
 671             else
 672                Append_To (Actuals, Make_Null (Loc));
 673             end if;
 674 
 675             --  c) Finalization master
 676 
 677             if Needs_Finalization (Desig_Typ) then
 678                Fin_Mas_Id  := Finalization_Master (Ptr_Typ);
 679                Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc);
 680 
 681                --  Handle the case where the master is actually a pointer to a
 682                --  master. This case arises in build-in-place functions.
 683 
 684                if Is_Access_Type (Etype (Fin_Mas_Id)) then
 685                   Append_To (Actuals, Fin_Mas_Act);
 686                else
 687                   Append_To (Actuals,
 688                     Make_Attribute_Reference (Loc,
 689                       Prefix         => Fin_Mas_Act,
 690                       Attribute_Name => Name_Unrestricted_Access));
 691                end if;
 692             else
 693                Append_To (Actuals, Make_Null (Loc));
 694             end if;
 695 
 696             --  d) Finalize_Address
 697 
 698             --  Primitive Finalize_Address is never generated in CodePeer mode
 699             --  since it contains an Unchecked_Conversion.
 700 
 701             if Needs_Finalization (Desig_Typ) and then not CodePeer_Mode then
 702                Fin_Addr_Id := Finalize_Address (Desig_Typ);
 703                pragma Assert (Present (Fin_Addr_Id));
 704 
 705                Append_To (Actuals,
 706                  Make_Attribute_Reference (Loc,
 707                    Prefix         => New_Occurrence_Of (Fin_Addr_Id, Loc),
 708                    Attribute_Name => Name_Unrestricted_Access));
 709             else
 710                Append_To (Actuals, Make_Null (Loc));
 711             end if;
 712          end if;
 713 
 714          --  e) Address
 715          --  f) Storage_Size
 716          --  g) Alignment
 717 
 718          Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc));
 719          Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc));
 720 
 721          if Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ) then
 722             Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc));
 723 
 724          --  For deallocation of class-wide types we obtain the value of
 725          --  alignment from the Type Specific Record of the deallocated object.
 726          --  This is needed because the frontend expansion of class-wide types
 727          --  into equivalent types confuses the backend.
 728 
 729          else
 730             --  Generate:
 731             --     Obj.all'Alignment
 732 
 733             --  ... because 'Alignment applied to class-wide types is expanded
 734             --  into the code that reads the value of alignment from the TSD
 735             --  (see Expand_N_Attribute_Reference)
 736 
 737             Append_To (Actuals,
 738               Unchecked_Convert_To (RTE (RE_Storage_Offset),
 739                 Make_Attribute_Reference (Loc,
 740                   Prefix         =>
 741                     Make_Explicit_Dereference (Loc, Relocate_Node (Expr)),
 742                   Attribute_Name => Name_Alignment)));
 743          end if;
 744 
 745          --  h) Is_Controlled
 746 
 747          if Needs_Finalization (Desig_Typ) then
 748             declare
 749                Flag_Id   : constant Entity_Id := Make_Temporary (Loc, 'F');
 750                Flag_Expr : Node_Id;
 751                Param     : Node_Id;
 752                Temp      : Node_Id;
 753 
 754             begin
 755                if Is_Allocate then
 756                   Temp := Find_Object (Expression (Expr));
 757                else
 758                   Temp := Expr;
 759                end if;
 760 
 761                --  Processing for allocations where the expression is a subtype
 762                --  indication.
 763 
 764                if Is_Allocate
 765                  and then Is_Entity_Name (Temp)
 766                  and then Is_Type (Entity (Temp))
 767                then
 768                   Flag_Expr :=
 769                     New_Occurrence_Of
 770                       (Boolean_Literals
 771                          (Needs_Finalization (Entity (Temp))), Loc);
 772 
 773                --  The allocation / deallocation of a class-wide object relies
 774                --  on a runtime check to determine whether the object is truly
 775                --  controlled or not. Depending on this check, the finalization
 776                --  machinery will request or reclaim extra storage reserved for
 777                --  a list header.
 778 
 779                elsif Is_Class_Wide_Type (Desig_Typ) then
 780 
 781                   --  Detect a special case where interface class-wide types
 782                   --  are involved as the object appears as:
 783 
 784                   --    Tag_Ptr (Base_Address (<object>'Address))
 785 
 786                   --  The expression already yields the proper tag, generate:
 787 
 788                   --    Temp.all
 789 
 790                   if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
 791                      Param :=
 792                        Make_Explicit_Dereference (Loc,
 793                          Prefix => Relocate_Node (Temp));
 794 
 795                   --  In the default case, obtain the tag of the object about
 796                   --  to be allocated / deallocated. Generate:
 797 
 798                   --    Temp'Tag
 799 
 800                   else
 801                      Param :=
 802                        Make_Attribute_Reference (Loc,
 803                          Prefix         => Relocate_Node (Temp),
 804                          Attribute_Name => Name_Tag);
 805                   end if;
 806 
 807                   --  Generate:
 808                   --    Needs_Finalization (<Param>)
 809 
 810                   Flag_Expr :=
 811                     Make_Function_Call (Loc,
 812                       Name                   =>
 813                         New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
 814                       Parameter_Associations => New_List (Param));
 815 
 816                --  Processing for generic actuals
 817 
 818                elsif Is_Generic_Actual_Type (Desig_Typ) then
 819                   Flag_Expr :=
 820                     New_Occurrence_Of (Boolean_Literals
 821                       (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
 822 
 823                --  The object does not require any specialized checks, it is
 824                --  known to be controlled.
 825 
 826                else
 827                   Flag_Expr := New_Occurrence_Of (Standard_True, Loc);
 828                end if;
 829 
 830                --  Create the temporary which represents the finalization state
 831                --  of the expression. Generate:
 832                --
 833                --    F : constant Boolean := <Flag_Expr>;
 834 
 835                Insert_Action (N,
 836                  Make_Object_Declaration (Loc,
 837                    Defining_Identifier => Flag_Id,
 838                    Constant_Present    => True,
 839                    Object_Definition   =>
 840                      New_Occurrence_Of (Standard_Boolean, Loc),
 841                     Expression          => Flag_Expr));
 842 
 843                Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc));
 844             end;
 845 
 846          --  The object is not controlled
 847 
 848          else
 849             Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc));
 850          end if;
 851 
 852          --  i) On_Subpool
 853 
 854          if Is_Allocate then
 855             Append_To (Actuals,
 856               New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc));
 857          end if;
 858 
 859          --  Step 2: Build a wrapper Allocate / Deallocate which internally
 860          --  calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
 861 
 862          --  Select the proper routine to call
 863 
 864          if Is_Allocate then
 865             Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
 866          else
 867             Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
 868          end if;
 869 
 870          --  Create a custom Allocate / Deallocate routine which has identical
 871          --  profile to that of System.Storage_Pools.
 872 
 873          Insert_Action (N,
 874            Make_Subprogram_Body (Loc,
 875              Specification =>
 876 
 877                --  procedure Pnn
 878 
 879                Make_Procedure_Specification (Loc,
 880                  Defining_Unit_Name => Proc_Id,
 881                  Parameter_Specifications => New_List (
 882 
 883                   --  P : Root_Storage_Pool
 884 
 885                    Make_Parameter_Specification (Loc,
 886                      Defining_Identifier => Make_Temporary (Loc, 'P'),
 887                      Parameter_Type =>
 888                        New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc)),
 889 
 890                   --  A : [out] Address
 891 
 892                    Make_Parameter_Specification (Loc,
 893                      Defining_Identifier => Addr_Id,
 894                      Out_Present         => Is_Allocate,
 895                      Parameter_Type      =>
 896                        New_Occurrence_Of (RTE (RE_Address), Loc)),
 897 
 898                   --  S : Storage_Count
 899 
 900                    Make_Parameter_Specification (Loc,
 901                      Defining_Identifier => Size_Id,
 902                      Parameter_Type      =>
 903                        New_Occurrence_Of (RTE (RE_Storage_Count), Loc)),
 904 
 905                   --  L : Storage_Count
 906 
 907                    Make_Parameter_Specification (Loc,
 908                      Defining_Identifier => Alig_Id,
 909                      Parameter_Type      =>
 910                        New_Occurrence_Of (RTE (RE_Storage_Count), Loc)))),
 911 
 912              Declarations => No_List,
 913 
 914              Handled_Statement_Sequence =>
 915                Make_Handled_Sequence_Of_Statements (Loc,
 916                  Statements => New_List (
 917                    Make_Procedure_Call_Statement (Loc,
 918                      Name => New_Occurrence_Of (Proc_To_Call, Loc),
 919                      Parameter_Associations => Actuals)))));
 920 
 921          --  The newly generated Allocate / Deallocate becomes the default
 922          --  procedure to call when the back end processes the allocation /
 923          --  deallocation.
 924 
 925          if Is_Allocate then
 926             Set_Procedure_To_Call (Expr, Proc_Id);
 927          else
 928             Set_Procedure_To_Call (N, Proc_Id);
 929          end if;
 930       end;
 931    end Build_Allocate_Deallocate_Proc;
 932 
 933    --------------------------
 934    -- Build_Procedure_Form --
 935    --------------------------
 936 
 937    procedure Build_Procedure_Form (N : Node_Id) is
 938       Loc  : constant Source_Ptr := Sloc (N);
 939       Subp : constant Entity_Id := Defining_Entity (N);
 940 
 941       Func_Formal  : Entity_Id;
 942       Proc_Formals : List_Id;
 943       Proc_Decl    : Node_Id;
 944 
 945    begin
 946       --  No action needed if this transformation was already done, or in case
 947       --  of subprogram renaming declarations.
 948 
 949       if Nkind (Specification (N)) = N_Procedure_Specification
 950         or else Nkind (N) = N_Subprogram_Renaming_Declaration
 951       then
 952          return;
 953       end if;
 954 
 955       --  Ditto when dealing with an expression function, where both the
 956       --  original expression and the generated declaration end up being
 957       --  expanded here.
 958 
 959       if Rewritten_For_C (Subp) then
 960          return;
 961       end if;
 962 
 963       Proc_Formals := New_List;
 964 
 965       --  Create a list of formal parameters with the same types as the
 966       --  function.
 967 
 968       Func_Formal := First_Formal (Subp);
 969       while Present (Func_Formal) loop
 970          Append_To (Proc_Formals,
 971            Make_Parameter_Specification (Loc,
 972              Defining_Identifier =>
 973                Make_Defining_Identifier (Loc, Chars (Func_Formal)),
 974              Parameter_Type      =>
 975                New_Occurrence_Of (Etype (Func_Formal), Loc)));
 976 
 977          Next_Formal (Func_Formal);
 978       end loop;
 979 
 980       --  Add an extra out parameter to carry the function result
 981 
 982       Name_Len := 6;
 983       Name_Buffer (1 .. Name_Len) := "RESULT";
 984       Append_To (Proc_Formals,
 985         Make_Parameter_Specification (Loc,
 986           Defining_Identifier =>
 987             Make_Defining_Identifier (Loc, Chars => Name_Find),
 988           Out_Present         => True,
 989           Parameter_Type      => New_Occurrence_Of (Etype (Subp), Loc)));
 990 
 991       --  The new procedure declaration is inserted immediately after the
 992       --  function declaration. The processing in Build_Procedure_Body_Form
 993       --  relies on this order.
 994 
 995       Proc_Decl :=
 996         Make_Subprogram_Declaration (Loc,
 997           Specification =>
 998             Make_Procedure_Specification (Loc,
 999               Defining_Unit_Name       =>
1000                 Make_Defining_Identifier (Loc, Chars (Subp)),
1001               Parameter_Specifications => Proc_Formals));
1002 
1003       Insert_After_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
1004 
1005       --  Entity of procedure must remain invisible so that it does not
1006       --  overload subsequent references to the original function.
1007 
1008       Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False);
1009 
1010       --  Mark the function as having a procedure form and link the function
1011       --  and its internally built procedure.
1012 
1013       Set_Rewritten_For_C (Subp);
1014       Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl));
1015       Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp);
1016    end Build_Procedure_Form;
1017 
1018    ------------------------
1019    -- Build_Runtime_Call --
1020    ------------------------
1021 
1022    function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
1023    begin
1024       --  If entity is not available, we can skip making the call (this avoids
1025       --  junk duplicated error messages in a number of cases).
1026 
1027       if not RTE_Available (RE) then
1028          return Make_Null_Statement (Loc);
1029       else
1030          return
1031            Make_Procedure_Call_Statement (Loc,
1032              Name => New_Occurrence_Of (RTE (RE), Loc));
1033       end if;
1034    end Build_Runtime_Call;
1035 
1036    ------------------------
1037    -- Build_SS_Mark_Call --
1038    ------------------------
1039 
1040    function Build_SS_Mark_Call
1041      (Loc  : Source_Ptr;
1042       Mark : Entity_Id) return Node_Id
1043    is
1044    begin
1045       --  Generate:
1046       --    Mark : constant Mark_Id := SS_Mark;
1047 
1048       return
1049         Make_Object_Declaration (Loc,
1050           Defining_Identifier => Mark,
1051           Constant_Present    => True,
1052           Object_Definition   =>
1053             New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
1054           Expression          =>
1055             Make_Function_Call (Loc,
1056               Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc)));
1057    end Build_SS_Mark_Call;
1058 
1059    ---------------------------
1060    -- Build_SS_Release_Call --
1061    ---------------------------
1062 
1063    function Build_SS_Release_Call
1064      (Loc  : Source_Ptr;
1065       Mark : Entity_Id) return Node_Id
1066    is
1067    begin
1068       --  Generate:
1069       --    SS_Release (Mark);
1070 
1071       return
1072         Make_Procedure_Call_Statement (Loc,
1073           Name                   =>
1074             New_Occurrence_Of (RTE (RE_SS_Release), Loc),
1075           Parameter_Associations => New_List (
1076             New_Occurrence_Of (Mark, Loc)));
1077    end Build_SS_Release_Call;
1078 
1079    ----------------------------
1080    -- Build_Task_Array_Image --
1081    ----------------------------
1082 
1083    --  This function generates the body for a function that constructs the
1084    --  image string for a task that is an array component. The function is
1085    --  local to the init proc for the array type, and is called for each one
1086    --  of the components. The constructed image has the form of an indexed
1087    --  component, whose prefix is the outer variable of the array type.
1088    --  The n-dimensional array type has known indexes Index, Index2...
1089 
1090    --  Id_Ref is an indexed component form created by the enclosing init proc.
1091    --  Its successive indexes are Val1, Val2, ... which are the loop variables
1092    --  in the loops that call the individual task init proc on each component.
1093 
1094    --  The generated function has the following structure:
1095 
1096    --  function F return String is
1097    --     Pref : string renames Task_Name;
1098    --     T1   : String := Index1'Image (Val1);
1099    --     ...
1100    --     Tn   : String := indexn'image (Valn);
1101    --     Len  : Integer := T1'Length + ... + Tn'Length + n + 1;
1102    --     --  Len includes commas and the end parentheses.
1103    --     Res  : String (1..Len);
1104    --     Pos  : Integer := Pref'Length;
1105    --
1106    --  begin
1107    --     Res (1 .. Pos) := Pref;
1108    --     Pos := Pos + 1;
1109    --     Res (Pos)    := '(';
1110    --     Pos := Pos + 1;
1111    --     Res (Pos .. Pos + T1'Length - 1) := T1;
1112    --     Pos := Pos + T1'Length;
1113    --     Res (Pos) := '.';
1114    --     Pos := Pos + 1;
1115    --     ...
1116    --     Res (Pos .. Pos + Tn'Length - 1) := Tn;
1117    --     Res (Len) := ')';
1118    --
1119    --     return Res;
1120    --  end F;
1121    --
1122    --  Needless to say, multidimensional arrays of tasks are rare enough that
1123    --  the bulkiness of this code is not really a concern.
1124 
1125    function Build_Task_Array_Image
1126      (Loc    : Source_Ptr;
1127       Id_Ref : Node_Id;
1128       A_Type : Entity_Id;
1129       Dyn    : Boolean := False) return Node_Id
1130    is
1131       Dims : constant Nat := Number_Dimensions (A_Type);
1132       --  Number of dimensions for array of tasks
1133 
1134       Temps : array (1 .. Dims) of Entity_Id;
1135       --  Array of temporaries to hold string for each index
1136 
1137       Indx : Node_Id;
1138       --  Index expression
1139 
1140       Len : Entity_Id;
1141       --  Total length of generated name
1142 
1143       Pos : Entity_Id;
1144       --  Running index for substring assignments
1145 
1146       Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1147       --  Name of enclosing variable, prefix of resulting name
1148 
1149       Res : Entity_Id;
1150       --  String to hold result
1151 
1152       Val : Node_Id;
1153       --  Value of successive indexes
1154 
1155       Sum : Node_Id;
1156       --  Expression to compute total size of string
1157 
1158       T : Entity_Id;
1159       --  Entity for name at one index position
1160 
1161       Decls : constant List_Id := New_List;
1162       Stats : constant List_Id := New_List;
1163 
1164    begin
1165       --  For a dynamic task, the name comes from the target variable. For a
1166       --  static one it is a formal of the enclosing init proc.
1167 
1168       if Dyn then
1169          Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1170          Append_To (Decls,
1171            Make_Object_Declaration (Loc,
1172              Defining_Identifier => Pref,
1173              Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1174              Expression =>
1175                Make_String_Literal (Loc,
1176                  Strval => String_From_Name_Buffer)));
1177 
1178       else
1179          Append_To (Decls,
1180            Make_Object_Renaming_Declaration (Loc,
1181              Defining_Identifier => Pref,
1182              Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
1183              Name                => Make_Identifier (Loc, Name_uTask_Name)));
1184       end if;
1185 
1186       Indx := First_Index (A_Type);
1187       Val  := First (Expressions (Id_Ref));
1188 
1189       for J in 1 .. Dims loop
1190          T := Make_Temporary (Loc, 'T');
1191          Temps (J) := T;
1192 
1193          Append_To (Decls,
1194            Make_Object_Declaration (Loc,
1195              Defining_Identifier => T,
1196              Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1197              Expression          =>
1198                Make_Attribute_Reference (Loc,
1199                  Attribute_Name => Name_Image,
1200                  Prefix         => New_Occurrence_Of (Etype (Indx), Loc),
1201                  Expressions    => New_List (New_Copy_Tree (Val)))));
1202 
1203          Next_Index (Indx);
1204          Next (Val);
1205       end loop;
1206 
1207       Sum := Make_Integer_Literal (Loc, Dims + 1);
1208 
1209       Sum :=
1210         Make_Op_Add (Loc,
1211           Left_Opnd => Sum,
1212           Right_Opnd =>
1213             Make_Attribute_Reference (Loc,
1214               Attribute_Name => Name_Length,
1215               Prefix         => New_Occurrence_Of (Pref, Loc),
1216               Expressions    => New_List (Make_Integer_Literal (Loc, 1))));
1217 
1218       for J in 1 .. Dims loop
1219          Sum :=
1220            Make_Op_Add (Loc,
1221              Left_Opnd  => Sum,
1222              Right_Opnd =>
1223                Make_Attribute_Reference (Loc,
1224                  Attribute_Name => Name_Length,
1225                  Prefix         =>
1226                   New_Occurrence_Of (Temps (J), Loc),
1227                 Expressions     => New_List (Make_Integer_Literal (Loc, 1))));
1228       end loop;
1229 
1230       Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1231 
1232       Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
1233 
1234       Append_To (Stats,
1235         Make_Assignment_Statement (Loc,
1236           Name       =>
1237             Make_Indexed_Component (Loc,
1238               Prefix      => New_Occurrence_Of (Res, Loc),
1239               Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1240           Expression =>
1241             Make_Character_Literal (Loc,
1242               Chars              => Name_Find,
1243               Char_Literal_Value => UI_From_Int (Character'Pos ('(')))));
1244 
1245       Append_To (Stats,
1246         Make_Assignment_Statement (Loc,
1247           Name       => New_Occurrence_Of (Pos, Loc),
1248           Expression =>
1249             Make_Op_Add (Loc,
1250               Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1251               Right_Opnd => Make_Integer_Literal (Loc, 1))));
1252 
1253       for J in 1 .. Dims loop
1254 
1255          Append_To (Stats,
1256            Make_Assignment_Statement (Loc,
1257              Name =>
1258                Make_Slice (Loc,
1259                  Prefix          => New_Occurrence_Of (Res, Loc),
1260                  Discrete_Range  =>
1261                    Make_Range (Loc,
1262                      Low_Bound  => New_Occurrence_Of  (Pos, Loc),
1263                      High_Bound =>
1264                        Make_Op_Subtract (Loc,
1265                          Left_Opnd  =>
1266                            Make_Op_Add (Loc,
1267                              Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1268                              Right_Opnd =>
1269                                Make_Attribute_Reference (Loc,
1270                                  Attribute_Name => Name_Length,
1271                                  Prefix         =>
1272                                    New_Occurrence_Of (Temps (J), Loc),
1273                                  Expressions    =>
1274                                    New_List (Make_Integer_Literal (Loc, 1)))),
1275                          Right_Opnd => Make_Integer_Literal (Loc, 1)))),
1276 
1277               Expression => New_Occurrence_Of (Temps (J), Loc)));
1278 
1279          if J < Dims then
1280             Append_To (Stats,
1281                Make_Assignment_Statement (Loc,
1282                   Name       => New_Occurrence_Of (Pos, Loc),
1283                   Expression =>
1284                     Make_Op_Add (Loc,
1285                       Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1286                       Right_Opnd =>
1287                         Make_Attribute_Reference (Loc,
1288                           Attribute_Name => Name_Length,
1289                           Prefix         => New_Occurrence_Of (Temps (J), Loc),
1290                           Expressions    =>
1291                             New_List (Make_Integer_Literal (Loc, 1))))));
1292 
1293             Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
1294 
1295             Append_To (Stats,
1296               Make_Assignment_Statement (Loc,
1297                 Name => Make_Indexed_Component (Loc,
1298                    Prefix => New_Occurrence_Of (Res, Loc),
1299                    Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1300                 Expression =>
1301                   Make_Character_Literal (Loc,
1302                     Chars              => Name_Find,
1303                     Char_Literal_Value => UI_From_Int (Character'Pos (',')))));
1304 
1305             Append_To (Stats,
1306               Make_Assignment_Statement (Loc,
1307                 Name         => New_Occurrence_Of (Pos, Loc),
1308                   Expression =>
1309                     Make_Op_Add (Loc,
1310                       Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1311                       Right_Opnd => Make_Integer_Literal (Loc, 1))));
1312          end if;
1313       end loop;
1314 
1315       Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
1316 
1317       Append_To (Stats,
1318         Make_Assignment_Statement (Loc,
1319           Name        =>
1320             Make_Indexed_Component (Loc,
1321               Prefix      => New_Occurrence_Of (Res, Loc),
1322               Expressions => New_List (New_Occurrence_Of (Len, Loc))),
1323            Expression =>
1324              Make_Character_Literal (Loc,
1325                Chars              => Name_Find,
1326                Char_Literal_Value => UI_From_Int (Character'Pos (')')))));
1327       return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1328    end Build_Task_Array_Image;
1329 
1330    ----------------------------
1331    -- Build_Task_Image_Decls --
1332    ----------------------------
1333 
1334    function Build_Task_Image_Decls
1335      (Loc          : Source_Ptr;
1336       Id_Ref       : Node_Id;
1337       A_Type       : Entity_Id;
1338       In_Init_Proc : Boolean := False) return List_Id
1339    is
1340       Decls  : constant List_Id   := New_List;
1341       T_Id   : Entity_Id := Empty;
1342       Decl   : Node_Id;
1343       Expr   : Node_Id   := Empty;
1344       Fun    : Node_Id   := Empty;
1345       Is_Dyn : constant Boolean :=
1346                  Nkind (Parent (Id_Ref)) = N_Assignment_Statement
1347                    and then
1348                  Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
1349 
1350    begin
1351       --  If Discard_Names or No_Implicit_Heap_Allocations are in effect,
1352       --  generate a dummy declaration only.
1353 
1354       if Restriction_Active (No_Implicit_Heap_Allocations)
1355         or else Global_Discard_Names
1356       then
1357          T_Id := Make_Temporary (Loc, 'J');
1358          Name_Len := 0;
1359 
1360          return
1361            New_List (
1362              Make_Object_Declaration (Loc,
1363                Defining_Identifier => T_Id,
1364                Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1365                Expression =>
1366                  Make_String_Literal (Loc,
1367                    Strval => String_From_Name_Buffer)));
1368 
1369       else
1370          if Nkind (Id_Ref) = N_Identifier
1371            or else Nkind (Id_Ref) = N_Defining_Identifier
1372          then
1373             --  For a simple variable, the image of the task is built from
1374             --  the name of the variable. To avoid possible conflict with the
1375             --  anonymous type created for a single protected object, add a
1376             --  numeric suffix.
1377 
1378             T_Id :=
1379               Make_Defining_Identifier (Loc,
1380                 New_External_Name (Chars (Id_Ref), 'T', 1));
1381 
1382             Get_Name_String (Chars (Id_Ref));
1383 
1384             Expr :=
1385               Make_String_Literal (Loc,
1386                 Strval => String_From_Name_Buffer);
1387 
1388          elsif Nkind (Id_Ref) = N_Selected_Component then
1389             T_Id :=
1390               Make_Defining_Identifier (Loc,
1391                 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
1392             Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
1393 
1394          elsif Nkind (Id_Ref) = N_Indexed_Component then
1395             T_Id :=
1396               Make_Defining_Identifier (Loc,
1397                 New_External_Name (Chars (A_Type), 'N'));
1398 
1399             Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
1400          end if;
1401       end if;
1402 
1403       if Present (Fun) then
1404          Append (Fun, Decls);
1405          Expr := Make_Function_Call (Loc,
1406            Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
1407 
1408          if not In_Init_Proc then
1409             Set_Uses_Sec_Stack (Defining_Entity (Fun));
1410          end if;
1411       end if;
1412 
1413       Decl := Make_Object_Declaration (Loc,
1414         Defining_Identifier => T_Id,
1415         Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1416         Constant_Present    => True,
1417         Expression          => Expr);
1418 
1419       Append (Decl, Decls);
1420       return Decls;
1421    end Build_Task_Image_Decls;
1422 
1423    -------------------------------
1424    -- Build_Task_Image_Function --
1425    -------------------------------
1426 
1427    function Build_Task_Image_Function
1428      (Loc   : Source_Ptr;
1429       Decls : List_Id;
1430       Stats : List_Id;
1431       Res   : Entity_Id) return Node_Id
1432    is
1433       Spec : Node_Id;
1434 
1435    begin
1436       Append_To (Stats,
1437         Make_Simple_Return_Statement (Loc,
1438           Expression => New_Occurrence_Of (Res, Loc)));
1439 
1440       Spec := Make_Function_Specification (Loc,
1441         Defining_Unit_Name => Make_Temporary (Loc, 'F'),
1442         Result_Definition  => New_Occurrence_Of (Standard_String, Loc));
1443 
1444       --  Calls to 'Image use the secondary stack, which must be cleaned up
1445       --  after the task name is built.
1446 
1447       return Make_Subprogram_Body (Loc,
1448          Specification => Spec,
1449          Declarations => Decls,
1450          Handled_Statement_Sequence =>
1451            Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
1452    end Build_Task_Image_Function;
1453 
1454    -----------------------------
1455    -- Build_Task_Image_Prefix --
1456    -----------------------------
1457 
1458    procedure Build_Task_Image_Prefix
1459       (Loc    : Source_Ptr;
1460        Len    : out Entity_Id;
1461        Res    : out Entity_Id;
1462        Pos    : out Entity_Id;
1463        Prefix : Entity_Id;
1464        Sum    : Node_Id;
1465        Decls  : List_Id;
1466        Stats  : List_Id)
1467    is
1468    begin
1469       Len := Make_Temporary (Loc, 'L', Sum);
1470 
1471       Append_To (Decls,
1472         Make_Object_Declaration (Loc,
1473           Defining_Identifier => Len,
1474           Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc),
1475           Expression          => Sum));
1476 
1477       Res := Make_Temporary (Loc, 'R');
1478 
1479       Append_To (Decls,
1480          Make_Object_Declaration (Loc,
1481             Defining_Identifier => Res,
1482             Object_Definition =>
1483                Make_Subtype_Indication (Loc,
1484                   Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
1485                Constraint =>
1486                  Make_Index_Or_Discriminant_Constraint (Loc,
1487                    Constraints =>
1488                      New_List (
1489                        Make_Range (Loc,
1490                          Low_Bound => Make_Integer_Literal (Loc, 1),
1491                          High_Bound => New_Occurrence_Of (Len, Loc)))))));
1492 
1493       --  Indicate that the result is an internal temporary, so it does not
1494       --  receive a bogus initialization when declaration is expanded. This
1495       --  is both efficient, and prevents anomalies in the handling of
1496       --  dynamic objects on the secondary stack.
1497 
1498       Set_Is_Internal (Res);
1499       Pos := Make_Temporary (Loc, 'P');
1500 
1501       Append_To (Decls,
1502          Make_Object_Declaration (Loc,
1503             Defining_Identifier => Pos,
1504             Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc)));
1505 
1506       --  Pos := Prefix'Length;
1507 
1508       Append_To (Stats,
1509          Make_Assignment_Statement (Loc,
1510             Name => New_Occurrence_Of (Pos, Loc),
1511             Expression =>
1512               Make_Attribute_Reference (Loc,
1513                 Attribute_Name => Name_Length,
1514                 Prefix         => New_Occurrence_Of (Prefix, Loc),
1515                 Expressions    => New_List (Make_Integer_Literal (Loc, 1)))));
1516 
1517       --  Res (1 .. Pos) := Prefix;
1518 
1519       Append_To (Stats,
1520         Make_Assignment_Statement (Loc,
1521           Name =>
1522             Make_Slice (Loc,
1523               Prefix          => New_Occurrence_Of (Res, Loc),
1524               Discrete_Range  =>
1525                 Make_Range (Loc,
1526                    Low_Bound  => Make_Integer_Literal (Loc, 1),
1527                    High_Bound => New_Occurrence_Of (Pos, Loc))),
1528 
1529           Expression => New_Occurrence_Of (Prefix, Loc)));
1530 
1531       Append_To (Stats,
1532          Make_Assignment_Statement (Loc,
1533             Name       => New_Occurrence_Of (Pos, Loc),
1534             Expression =>
1535               Make_Op_Add (Loc,
1536                 Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1537                 Right_Opnd => Make_Integer_Literal (Loc, 1))));
1538    end Build_Task_Image_Prefix;
1539 
1540    -----------------------------
1541    -- Build_Task_Record_Image --
1542    -----------------------------
1543 
1544    function Build_Task_Record_Image
1545      (Loc    : Source_Ptr;
1546       Id_Ref : Node_Id;
1547       Dyn    : Boolean := False) return Node_Id
1548    is
1549       Len : Entity_Id;
1550       --  Total length of generated name
1551 
1552       Pos : Entity_Id;
1553       --  Index into result
1554 
1555       Res : Entity_Id;
1556       --  String to hold result
1557 
1558       Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1559       --  Name of enclosing variable, prefix of resulting name
1560 
1561       Sum : Node_Id;
1562       --  Expression to compute total size of string
1563 
1564       Sel : Entity_Id;
1565       --  Entity for selector name
1566 
1567       Decls : constant List_Id := New_List;
1568       Stats : constant List_Id := New_List;
1569 
1570    begin
1571       --  For a dynamic task, the name comes from the target variable. For a
1572       --  static one it is a formal of the enclosing init proc.
1573 
1574       if Dyn then
1575          Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1576          Append_To (Decls,
1577            Make_Object_Declaration (Loc,
1578              Defining_Identifier => Pref,
1579              Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1580              Expression =>
1581                Make_String_Literal (Loc,
1582                  Strval => String_From_Name_Buffer)));
1583 
1584       else
1585          Append_To (Decls,
1586            Make_Object_Renaming_Declaration (Loc,
1587              Defining_Identifier => Pref,
1588              Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
1589              Name                => Make_Identifier (Loc, Name_uTask_Name)));
1590       end if;
1591 
1592       Sel := Make_Temporary (Loc, 'S');
1593 
1594       Get_Name_String (Chars (Selector_Name (Id_Ref)));
1595 
1596       Append_To (Decls,
1597          Make_Object_Declaration (Loc,
1598            Defining_Identifier => Sel,
1599            Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1600            Expression          =>
1601              Make_String_Literal (Loc,
1602                Strval => String_From_Name_Buffer)));
1603 
1604       Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
1605 
1606       Sum :=
1607         Make_Op_Add (Loc,
1608           Left_Opnd => Sum,
1609           Right_Opnd =>
1610            Make_Attribute_Reference (Loc,
1611              Attribute_Name => Name_Length,
1612              Prefix =>
1613                New_Occurrence_Of (Pref, Loc),
1614              Expressions => New_List (Make_Integer_Literal (Loc, 1))));
1615 
1616       Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1617 
1618       Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
1619 
1620       --  Res (Pos) := '.';
1621 
1622       Append_To (Stats,
1623          Make_Assignment_Statement (Loc,
1624            Name => Make_Indexed_Component (Loc,
1625               Prefix => New_Occurrence_Of (Res, Loc),
1626               Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1627            Expression =>
1628              Make_Character_Literal (Loc,
1629                Chars => Name_Find,
1630                Char_Literal_Value =>
1631                  UI_From_Int (Character'Pos ('.')))));
1632 
1633       Append_To (Stats,
1634         Make_Assignment_Statement (Loc,
1635           Name => New_Occurrence_Of (Pos, Loc),
1636           Expression =>
1637             Make_Op_Add (Loc,
1638               Left_Opnd => New_Occurrence_Of (Pos, Loc),
1639               Right_Opnd => Make_Integer_Literal (Loc, 1))));
1640 
1641       --  Res (Pos .. Len) := Selector;
1642 
1643       Append_To (Stats,
1644         Make_Assignment_Statement (Loc,
1645           Name => Make_Slice (Loc,
1646              Prefix => New_Occurrence_Of (Res, Loc),
1647              Discrete_Range  =>
1648                Make_Range (Loc,
1649                  Low_Bound  => New_Occurrence_Of (Pos, Loc),
1650                  High_Bound => New_Occurrence_Of (Len, Loc))),
1651           Expression => New_Occurrence_Of (Sel, Loc)));
1652 
1653       return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1654    end Build_Task_Record_Image;
1655 
1656    -----------------------------
1657    -- Check_Float_Op_Overflow --
1658    -----------------------------
1659 
1660    procedure Check_Float_Op_Overflow (N : Node_Id) is
1661    begin
1662       --  Return if no check needed
1663 
1664       if not Is_Floating_Point_Type (Etype (N))
1665         or else not (Do_Overflow_Check (N) and then Check_Float_Overflow)
1666 
1667         --  In CodePeer_Mode, rely on the overflow check flag being set instead
1668         --  and do not expand the code for float overflow checking.
1669 
1670         or else CodePeer_Mode
1671       then
1672          return;
1673       end if;
1674 
1675       --  Otherwise we replace the expression by
1676 
1677       --  do Tnn : constant ftype := expression;
1678       --     constraint_error when not Tnn'Valid;
1679       --  in Tnn;
1680 
1681       declare
1682          Loc : constant Source_Ptr := Sloc (N);
1683          Tnn : constant Entity_Id  := Make_Temporary (Loc, 'T', N);
1684          Typ : constant Entity_Id  := Etype (N);
1685 
1686       begin
1687          --  Turn off the Do_Overflow_Check flag, since we are doing that work
1688          --  right here. We also set the node as analyzed to prevent infinite
1689          --  recursion from repeating the operation in the expansion.
1690 
1691          Set_Do_Overflow_Check (N, False);
1692          Set_Analyzed (N, True);
1693 
1694          --  Do the rewrite to include the check
1695 
1696          Rewrite (N,
1697            Make_Expression_With_Actions (Loc,
1698              Actions    => New_List (
1699                Make_Object_Declaration (Loc,
1700                  Defining_Identifier => Tnn,
1701                  Object_Definition   => New_Occurrence_Of (Typ, Loc),
1702                  Constant_Present    => True,
1703                  Expression          => Relocate_Node (N)),
1704                Make_Raise_Constraint_Error (Loc,
1705                  Condition =>
1706                    Make_Op_Not (Loc,
1707                      Right_Opnd =>
1708                        Make_Attribute_Reference (Loc,
1709                          Prefix         => New_Occurrence_Of (Tnn, Loc),
1710                          Attribute_Name => Name_Valid)),
1711                  Reason    => CE_Overflow_Check_Failed)),
1712              Expression => New_Occurrence_Of (Tnn, Loc)));
1713 
1714          Analyze_And_Resolve (N, Typ);
1715       end;
1716    end Check_Float_Op_Overflow;
1717 
1718    ----------------------------------
1719    -- Component_May_Be_Bit_Aligned --
1720    ----------------------------------
1721 
1722    function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
1723       UT : Entity_Id;
1724 
1725    begin
1726       --  If no component clause, then everything is fine, since the back end
1727       --  never bit-misaligns by default, even if there is a pragma Packed for
1728       --  the record.
1729 
1730       if No (Comp) or else No (Component_Clause (Comp)) then
1731          return False;
1732       end if;
1733 
1734       UT := Underlying_Type (Etype (Comp));
1735 
1736       --  It is only array and record types that cause trouble
1737 
1738       if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then
1739          return False;
1740 
1741       --  If we know that we have a small (64 bits or less) record or small
1742       --  bit-packed array, then everything is fine, since the back end can
1743       --  handle these cases correctly.
1744 
1745       elsif Esize (Comp) <= 64
1746         and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
1747       then
1748          return False;
1749 
1750       --  Otherwise if the component is not byte aligned, we know we have the
1751       --  nasty unaligned case.
1752 
1753       elsif Normalized_First_Bit (Comp) /= Uint_0
1754         or else Esize (Comp) mod System_Storage_Unit /= Uint_0
1755       then
1756          return True;
1757 
1758       --  If we are large and byte aligned, then OK at this level
1759 
1760       else
1761          return False;
1762       end if;
1763    end Component_May_Be_Bit_Aligned;
1764 
1765    ----------------------------------------
1766    -- Containing_Package_With_Ext_Axioms --
1767    ----------------------------------------
1768 
1769    function Containing_Package_With_Ext_Axioms
1770      (E : Entity_Id) return Entity_Id
1771    is
1772    begin
1773       --  E is the package or generic package which is externally axiomatized
1774 
1775       if Ekind_In (E, E_Generic_Package, E_Package)
1776         and then Has_Annotate_Pragma_For_External_Axiomatization (E)
1777       then
1778          return E;
1779       end if;
1780 
1781       --  If E's scope is axiomatized, E is axiomatized
1782 
1783       if Present (Scope (E)) then
1784          declare
1785             First_Ax_Parent_Scope : constant Entity_Id :=
1786               Containing_Package_With_Ext_Axioms (Scope (E));
1787          begin
1788             if Present (First_Ax_Parent_Scope) then
1789                return First_Ax_Parent_Scope;
1790             end if;
1791          end;
1792       end if;
1793 
1794       --  Otherwise, if E is a package instance, it is axiomatized if the
1795       --  corresponding generic package is axiomatized.
1796 
1797       if Ekind (E) = E_Package then
1798          declare
1799             Par  : constant Node_Id := Parent (E);
1800             Decl : Node_Id;
1801 
1802          begin
1803             if Nkind (Par) = N_Defining_Program_Unit_Name then
1804                Decl := Parent (Par);
1805             else
1806                Decl := Par;
1807             end if;
1808 
1809             if Present (Generic_Parent (Decl)) then
1810                return
1811                  Containing_Package_With_Ext_Axioms (Generic_Parent (Decl));
1812             end if;
1813          end;
1814       end if;
1815 
1816       return Empty;
1817    end Containing_Package_With_Ext_Axioms;
1818 
1819    -------------------------------
1820    -- Convert_To_Actual_Subtype --
1821    -------------------------------
1822 
1823    procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
1824       Act_ST : Entity_Id;
1825 
1826    begin
1827       Act_ST := Get_Actual_Subtype (Exp);
1828 
1829       if Act_ST = Etype (Exp) then
1830          return;
1831       else
1832          Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
1833          Analyze_And_Resolve (Exp, Act_ST);
1834       end if;
1835    end Convert_To_Actual_Subtype;
1836 
1837    -----------------------------------
1838    -- Corresponding_Runtime_Package --
1839    -----------------------------------
1840 
1841    function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
1842       Pkg_Id : RTU_Id := RTU_Null;
1843 
1844    begin
1845       pragma Assert (Is_Concurrent_Type (Typ));
1846 
1847       if Ekind (Typ) in Protected_Kind then
1848          if Has_Entries (Typ)
1849 
1850             --  A protected type without entries that covers an interface and
1851             --  overrides the abstract routines with protected procedures is
1852             --  considered equivalent to a protected type with entries in the
1853             --  context of dispatching select statements. It is sufficient to
1854             --  check for the presence of an interface list in the declaration
1855             --  node to recognize this case.
1856 
1857            or else Present (Interface_List (Parent (Typ)))
1858 
1859             --  Protected types with interrupt handlers (when not using a
1860             --  restricted profile) are also considered equivalent to
1861             --  protected types with entries. The types which are used
1862             --  (Static_Interrupt_Protection and Dynamic_Interrupt_Protection)
1863             --  are derived from Protection_Entries.
1864 
1865            or else (Has_Attach_Handler (Typ) and then not Restricted_Profile)
1866            or else Has_Interrupt_Handler (Typ)
1867          then
1868             if Abort_Allowed
1869               or else Restriction_Active (No_Entry_Queue) = False
1870               or else Restriction_Active (No_Select_Statements) = False
1871               or else Number_Entries (Typ) > 1
1872               or else (Has_Attach_Handler (Typ)
1873                         and then not Restricted_Profile)
1874             then
1875                Pkg_Id := System_Tasking_Protected_Objects_Entries;
1876             else
1877                Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
1878             end if;
1879 
1880          else
1881             Pkg_Id := System_Tasking_Protected_Objects;
1882          end if;
1883       end if;
1884 
1885       return Pkg_Id;
1886    end Corresponding_Runtime_Package;
1887 
1888    -----------------------------------
1889    -- Current_Sem_Unit_Declarations --
1890    -----------------------------------
1891 
1892    function Current_Sem_Unit_Declarations return List_Id is
1893       U     : Node_Id := Unit (Cunit (Current_Sem_Unit));
1894       Decls : List_Id;
1895 
1896    begin
1897       --  If the current unit is a package body, locate the visible
1898       --  declarations of the package spec.
1899 
1900       if Nkind (U) = N_Package_Body then
1901          U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
1902       end if;
1903 
1904       if Nkind (U) = N_Package_Declaration then
1905          U := Specification (U);
1906          Decls := Visible_Declarations (U);
1907 
1908          if No (Decls) then
1909             Decls := New_List;
1910             Set_Visible_Declarations (U, Decls);
1911          end if;
1912 
1913       else
1914          Decls := Declarations (U);
1915 
1916          if No (Decls) then
1917             Decls := New_List;
1918             Set_Declarations (U, Decls);
1919          end if;
1920       end if;
1921 
1922       return Decls;
1923    end Current_Sem_Unit_Declarations;
1924 
1925    -----------------------
1926    -- Duplicate_Subexpr --
1927    -----------------------
1928 
1929    function Duplicate_Subexpr
1930      (Exp          : Node_Id;
1931       Name_Req     : Boolean := False;
1932       Renaming_Req : Boolean := False) return Node_Id
1933    is
1934    begin
1935       Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
1936       return New_Copy_Tree (Exp);
1937    end Duplicate_Subexpr;
1938 
1939    ---------------------------------
1940    -- Duplicate_Subexpr_No_Checks --
1941    ---------------------------------
1942 
1943    function Duplicate_Subexpr_No_Checks
1944      (Exp           : Node_Id;
1945       Name_Req      : Boolean   := False;
1946       Renaming_Req  : Boolean   := False;
1947       Related_Id    : Entity_Id := Empty;
1948       Is_Low_Bound  : Boolean   := False;
1949       Is_High_Bound : Boolean   := False) return Node_Id
1950    is
1951       New_Exp : Node_Id;
1952 
1953    begin
1954       Remove_Side_Effects
1955         (Exp           => Exp,
1956          Name_Req      => Name_Req,
1957          Renaming_Req  => Renaming_Req,
1958          Related_Id    => Related_Id,
1959          Is_Low_Bound  => Is_Low_Bound,
1960          Is_High_Bound => Is_High_Bound);
1961 
1962       New_Exp := New_Copy_Tree (Exp);
1963       Remove_Checks (New_Exp);
1964       return New_Exp;
1965    end Duplicate_Subexpr_No_Checks;
1966 
1967    -----------------------------------
1968    -- Duplicate_Subexpr_Move_Checks --
1969    -----------------------------------
1970 
1971    function Duplicate_Subexpr_Move_Checks
1972      (Exp          : Node_Id;
1973       Name_Req     : Boolean := False;
1974       Renaming_Req : Boolean := False) return Node_Id
1975    is
1976       New_Exp : Node_Id;
1977 
1978    begin
1979       Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
1980       New_Exp := New_Copy_Tree (Exp);
1981       Remove_Checks (Exp);
1982       return New_Exp;
1983    end Duplicate_Subexpr_Move_Checks;
1984 
1985    --------------------
1986    -- Ensure_Defined --
1987    --------------------
1988 
1989    procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
1990       IR : Node_Id;
1991 
1992    begin
1993       --  An itype reference must only be created if this is a local itype, so
1994       --  that gigi can elaborate it on the proper objstack.
1995 
1996       if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then
1997          IR := Make_Itype_Reference (Sloc (N));
1998          Set_Itype (IR, Typ);
1999          Insert_Action (N, IR);
2000       end if;
2001    end Ensure_Defined;
2002 
2003    --------------------
2004    -- Entry_Names_OK --
2005    --------------------
2006 
2007    function Entry_Names_OK return Boolean is
2008    begin
2009       return
2010         not Restricted_Profile
2011           and then not Global_Discard_Names
2012           and then not Restriction_Active (No_Implicit_Heap_Allocations)
2013           and then not Restriction_Active (No_Local_Allocators);
2014    end Entry_Names_OK;
2015 
2016    -------------------
2017    -- Evaluate_Name --
2018    -------------------
2019 
2020    procedure Evaluate_Name (Nam : Node_Id) is
2021       K : constant Node_Kind := Nkind (Nam);
2022 
2023    begin
2024       --  For an explicit dereference, we simply force the evaluation of the
2025       --  name expression. The dereference provides a value that is the address
2026       --  for the renamed object, and it is precisely this value that we want
2027       --  to preserve.
2028 
2029       if K = N_Explicit_Dereference then
2030          Force_Evaluation (Prefix (Nam));
2031 
2032       --  For a selected component, we simply evaluate the prefix
2033 
2034       elsif K = N_Selected_Component then
2035          Evaluate_Name (Prefix (Nam));
2036 
2037       --  For an indexed component, or an attribute reference, we evaluate the
2038       --  prefix, which is itself a name, recursively, and then force the
2039       --  evaluation of all the subscripts (or attribute expressions).
2040 
2041       elsif Nkind_In (K, N_Indexed_Component, N_Attribute_Reference) then
2042          Evaluate_Name (Prefix (Nam));
2043 
2044          declare
2045             E : Node_Id;
2046 
2047          begin
2048             E := First (Expressions (Nam));
2049             while Present (E) loop
2050                Force_Evaluation (E);
2051 
2052                if Original_Node (E) /= E then
2053                   Set_Do_Range_Check (E, Do_Range_Check (Original_Node (E)));
2054                end if;
2055 
2056                Next (E);
2057             end loop;
2058          end;
2059 
2060       --  For a slice, we evaluate the prefix, as for the indexed component
2061       --  case and then, if there is a range present, either directly or as the
2062       --  constraint of a discrete subtype indication, we evaluate the two
2063       --  bounds of this range.
2064 
2065       elsif K = N_Slice then
2066          Evaluate_Name (Prefix (Nam));
2067          Evaluate_Slice_Bounds (Nam);
2068 
2069       --  For a type conversion, the expression of the conversion must be the
2070       --  name of an object, and we simply need to evaluate this name.
2071 
2072       elsif K = N_Type_Conversion then
2073          Evaluate_Name (Expression (Nam));
2074 
2075       --  For a function call, we evaluate the call
2076 
2077       elsif K = N_Function_Call then
2078          Force_Evaluation (Nam);
2079 
2080       --  The remaining cases are direct name, operator symbol and character
2081       --  literal. In all these cases, we do nothing, since we want to
2082       --  reevaluate each time the renamed object is used.
2083 
2084       else
2085          return;
2086       end if;
2087    end Evaluate_Name;
2088 
2089    ---------------------------
2090    -- Evaluate_Slice_Bounds --
2091    ---------------------------
2092 
2093    procedure Evaluate_Slice_Bounds (Slice : Node_Id) is
2094       DR     : constant Node_Id := Discrete_Range (Slice);
2095       Constr : Node_Id;
2096       Rexpr  : Node_Id;
2097 
2098    begin
2099       if Nkind (DR) = N_Range then
2100          Force_Evaluation (Low_Bound (DR));
2101          Force_Evaluation (High_Bound (DR));
2102 
2103       elsif Nkind (DR) = N_Subtype_Indication then
2104          Constr := Constraint (DR);
2105 
2106          if Nkind (Constr) = N_Range_Constraint then
2107             Rexpr := Range_Expression (Constr);
2108 
2109             Force_Evaluation (Low_Bound (Rexpr));
2110             Force_Evaluation (High_Bound (Rexpr));
2111          end if;
2112       end if;
2113    end Evaluate_Slice_Bounds;
2114 
2115    ---------------------
2116    -- Evolve_And_Then --
2117    ---------------------
2118 
2119    procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
2120    begin
2121       if No (Cond) then
2122          Cond := Cond1;
2123       else
2124          Cond :=
2125            Make_And_Then (Sloc (Cond1),
2126              Left_Opnd  => Cond,
2127              Right_Opnd => Cond1);
2128       end if;
2129    end Evolve_And_Then;
2130 
2131    --------------------
2132    -- Evolve_Or_Else --
2133    --------------------
2134 
2135    procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
2136    begin
2137       if No (Cond) then
2138          Cond := Cond1;
2139       else
2140          Cond :=
2141            Make_Or_Else (Sloc (Cond1),
2142              Left_Opnd  => Cond,
2143              Right_Opnd => Cond1);
2144       end if;
2145    end Evolve_Or_Else;
2146 
2147    -----------------------------------------
2148    -- Expand_Static_Predicates_In_Choices --
2149    -----------------------------------------
2150 
2151    procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is
2152       pragma Assert (Nkind_In (N, N_Case_Statement_Alternative, N_Variant));
2153 
2154       Choices : constant List_Id := Discrete_Choices (N);
2155 
2156       Choice : Node_Id;
2157       Next_C : Node_Id;
2158       P      : Node_Id;
2159       C      : Node_Id;
2160 
2161    begin
2162       Choice := First (Choices);
2163       while Present (Choice) loop
2164          Next_C := Next (Choice);
2165 
2166          --  Check for name of subtype with static predicate
2167 
2168          if Is_Entity_Name (Choice)
2169            and then Is_Type (Entity (Choice))
2170            and then Has_Predicates (Entity (Choice))
2171          then
2172             --  Loop through entries in predicate list, converting to choices
2173             --  and inserting in the list before the current choice. Note that
2174             --  if the list is empty, corresponding to a False predicate, then
2175             --  no choices are inserted.
2176 
2177             P := First (Static_Discrete_Predicate (Entity (Choice)));
2178             while Present (P) loop
2179 
2180                --  If low bound and high bounds are equal, copy simple choice
2181 
2182                if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then
2183                   C := New_Copy (Low_Bound (P));
2184 
2185                --  Otherwise copy a range
2186 
2187                else
2188                   C := New_Copy (P);
2189                end if;
2190 
2191                --  Change Sloc to referencing choice (rather than the Sloc of
2192                --  the predicate declaration element itself).
2193 
2194                Set_Sloc (C, Sloc (Choice));
2195                Insert_Before (Choice, C);
2196                Next (P);
2197             end loop;
2198 
2199             --  Delete the predicated entry
2200 
2201             Remove (Choice);
2202          end if;
2203 
2204          --  Move to next choice to check
2205 
2206          Choice := Next_C;
2207       end loop;
2208    end Expand_Static_Predicates_In_Choices;
2209 
2210    ------------------------------
2211    -- Expand_Subtype_From_Expr --
2212    ------------------------------
2213 
2214    --  This function is applicable for both static and dynamic allocation of
2215    --  objects which are constrained by an initial expression. Basically it
2216    --  transforms an unconstrained subtype indication into a constrained one.
2217 
2218    --  The expression may also be transformed in certain cases in order to
2219    --  avoid multiple evaluation. In the static allocation case, the general
2220    --  scheme is:
2221 
2222    --     Val : T := Expr;
2223 
2224    --        is transformed into
2225 
2226    --     Val : Constrained_Subtype_of_T := Maybe_Modified_Expr;
2227    --
2228    --  Here are the main cases :
2229    --
2230    --  <if Expr is a Slice>
2231    --    Val : T ([Index_Subtype (Expr)]) := Expr;
2232    --
2233    --  <elsif Expr is a String Literal>
2234    --    Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
2235    --
2236    --  <elsif Expr is Constrained>
2237    --    subtype T is Type_Of_Expr
2238    --    Val : T := Expr;
2239    --
2240    --  <elsif Expr is an entity_name>
2241    --    Val : T (constraints taken from Expr) := Expr;
2242    --
2243    --  <else>
2244    --    type Axxx is access all T;
2245    --    Rval : Axxx := Expr'ref;
2246    --    Val  : T (constraints taken from Rval) := Rval.all;
2247 
2248    --    ??? note: when the Expression is allocated in the secondary stack
2249    --              we could use it directly instead of copying it by declaring
2250    --              Val : T (...) renames Rval.all
2251 
2252    procedure Expand_Subtype_From_Expr
2253      (N             : Node_Id;
2254       Unc_Type      : Entity_Id;
2255       Subtype_Indic : Node_Id;
2256       Exp           : Node_Id;
2257       Related_Id    : Entity_Id := Empty)
2258    is
2259       Loc     : constant Source_Ptr := Sloc (N);
2260       Exp_Typ : constant Entity_Id  := Etype (Exp);
2261       T       : Entity_Id;
2262 
2263    begin
2264       --  In general we cannot build the subtype if expansion is disabled,
2265       --  because internal entities may not have been defined. However, to
2266       --  avoid some cascaded errors, we try to continue when the expression is
2267       --  an array (or string), because it is safe to compute the bounds. It is
2268       --  in fact required to do so even in a generic context, because there
2269       --  may be constants that depend on the bounds of a string literal, both
2270       --  standard string types and more generally arrays of characters.
2271 
2272       --  In GNATprove mode, these extra subtypes are not needed
2273 
2274       if GNATprove_Mode then
2275          return;
2276       end if;
2277 
2278       if not Expander_Active
2279         and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp)))
2280       then
2281          return;
2282       end if;
2283 
2284       if Nkind (Exp) = N_Slice then
2285          declare
2286             Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
2287 
2288          begin
2289             Rewrite (Subtype_Indic,
2290               Make_Subtype_Indication (Loc,
2291                 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
2292                 Constraint =>
2293                   Make_Index_Or_Discriminant_Constraint (Loc,
2294                     Constraints => New_List
2295                       (New_Occurrence_Of (Slice_Type, Loc)))));
2296 
2297             --  This subtype indication may be used later for constraint checks
2298             --  we better make sure that if a variable was used as a bound of
2299             --  of the original slice, its value is frozen.
2300 
2301             Evaluate_Slice_Bounds (Exp);
2302          end;
2303 
2304       elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
2305          Rewrite (Subtype_Indic,
2306            Make_Subtype_Indication (Loc,
2307              Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
2308              Constraint =>
2309                Make_Index_Or_Discriminant_Constraint (Loc,
2310                  Constraints => New_List (
2311                    Make_Literal_Range (Loc,
2312                      Literal_Typ => Exp_Typ)))));
2313 
2314       --  If the type of the expression is an internally generated type it
2315       --  may not be necessary to create a new subtype. However there are two
2316       --  exceptions: references to the current instances, and aliased array
2317       --  object declarations for which the backend needs to create a template.
2318 
2319       elsif Is_Constrained (Exp_Typ)
2320         and then not Is_Class_Wide_Type (Unc_Type)
2321         and then
2322           (Nkind (N) /= N_Object_Declaration
2323             or else not Is_Entity_Name (Expression (N))
2324             or else not Comes_From_Source (Entity (Expression (N)))
2325             or else not Is_Array_Type (Exp_Typ)
2326             or else not Aliased_Present (N))
2327       then
2328          if Is_Itype (Exp_Typ) then
2329 
2330             --  Within an initialization procedure, a selected component
2331             --  denotes a component of the enclosing record, and it appears as
2332             --  an actual in a call to its own initialization procedure. If
2333             --  this component depends on the outer discriminant, we must
2334             --  generate the proper actual subtype for it.
2335 
2336             if Nkind (Exp) = N_Selected_Component
2337               and then Within_Init_Proc
2338             then
2339                declare
2340                   Decl : constant Node_Id :=
2341                            Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
2342                begin
2343                   if Present (Decl) then
2344                      Insert_Action (N, Decl);
2345                      T := Defining_Identifier (Decl);
2346                   else
2347                      T := Exp_Typ;
2348                   end if;
2349                end;
2350 
2351             --  No need to generate a new subtype
2352 
2353             else
2354                T := Exp_Typ;
2355             end if;
2356 
2357          else
2358             T := Make_Temporary (Loc, 'T');
2359 
2360             Insert_Action (N,
2361               Make_Subtype_Declaration (Loc,
2362                 Defining_Identifier => T,
2363                 Subtype_Indication  => New_Occurrence_Of (Exp_Typ, Loc)));
2364 
2365             --  This type is marked as an itype even though it has an explicit
2366             --  declaration since otherwise Is_Generic_Actual_Type can get
2367             --  set, resulting in the generation of spurious errors. (See
2368             --  sem_ch8.Analyze_Package_Renaming and sem_type.covers)
2369 
2370             Set_Is_Itype (T);
2371             Set_Associated_Node_For_Itype (T, Exp);
2372          end if;
2373 
2374          Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc));
2375 
2376       --  Nothing needs to be done for private types with unknown discriminants
2377       --  if the underlying type is not an unconstrained composite type or it
2378       --  is an unchecked union.
2379 
2380       elsif Is_Private_Type (Unc_Type)
2381         and then Has_Unknown_Discriminants (Unc_Type)
2382         and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
2383                    or else Is_Constrained (Underlying_Type (Unc_Type))
2384                    or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
2385       then
2386          null;
2387 
2388       --  Case of derived type with unknown discriminants where the parent type
2389       --  also has unknown discriminants.
2390 
2391       elsif Is_Record_Type (Unc_Type)
2392         and then not Is_Class_Wide_Type (Unc_Type)
2393         and then Has_Unknown_Discriminants (Unc_Type)
2394         and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
2395       then
2396          --  Nothing to be done if no underlying record view available
2397 
2398          if No (Underlying_Record_View (Unc_Type)) then
2399             null;
2400 
2401          --  Otherwise use the Underlying_Record_View to create the proper
2402          --  constrained subtype for an object of a derived type with unknown
2403          --  discriminants.
2404 
2405          else
2406             Remove_Side_Effects (Exp);
2407             Rewrite (Subtype_Indic,
2408               Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
2409          end if;
2410 
2411       --  Renamings of class-wide interface types require no equivalent
2412       --  constrained type declarations because we only need to reference
2413       --  the tag component associated with the interface. The same is
2414       --  presumably true for class-wide types in general, so this test
2415       --  is broadened to include all class-wide renamings, which also
2416       --  avoids cases of unbounded recursion in Remove_Side_Effects.
2417       --  (Is this really correct, or are there some cases of class-wide
2418       --  renamings that require action in this procedure???)
2419 
2420       elsif Present (N)
2421         and then Nkind (N) = N_Object_Renaming_Declaration
2422         and then Is_Class_Wide_Type (Unc_Type)
2423       then
2424          null;
2425 
2426       --  In Ada 95 nothing to be done if the type of the expression is limited
2427       --  because in this case the expression cannot be copied, and its use can
2428       --  only be by reference.
2429 
2430       --  In Ada 2005 the context can be an object declaration whose expression
2431       --  is a function that returns in place. If the nominal subtype has
2432       --  unknown discriminants, the call still provides constraints on the
2433       --  object, and we have to create an actual subtype from it.
2434 
2435       --  If the type is class-wide, the expression is dynamically tagged and
2436       --  we do not create an actual subtype either. Ditto for an interface.
2437       --  For now this applies only if the type is immutably limited, and the
2438       --  function being called is build-in-place. This will have to be revised
2439       --  when build-in-place functions are generalized to other types.
2440 
2441       elsif Is_Limited_View (Exp_Typ)
2442         and then
2443          (Is_Class_Wide_Type (Exp_Typ)
2444            or else Is_Interface (Exp_Typ)
2445            or else not Has_Unknown_Discriminants (Exp_Typ)
2446            or else not Is_Composite_Type (Unc_Type))
2447       then
2448          null;
2449 
2450       --  For limited objects initialized with build in place function calls,
2451       --  nothing to be done; otherwise we prematurely introduce an N_Reference
2452       --  node in the expression initializing the object, which breaks the
2453       --  circuitry that detects and adds the additional arguments to the
2454       --  called function.
2455 
2456       elsif Is_Build_In_Place_Function_Call (Exp) then
2457          null;
2458 
2459       else
2460          Remove_Side_Effects (Exp);
2461          Rewrite (Subtype_Indic,
2462            Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id));
2463       end if;
2464    end Expand_Subtype_From_Expr;
2465 
2466    ----------------------
2467    -- Finalize_Address --
2468    ----------------------
2469 
2470    function Finalize_Address (Typ : Entity_Id) return Entity_Id is
2471       Utyp : Entity_Id := Typ;
2472 
2473    begin
2474       --  Handle protected class-wide or task class-wide types
2475 
2476       if Is_Class_Wide_Type (Utyp) then
2477          if Is_Concurrent_Type (Root_Type (Utyp)) then
2478             Utyp := Root_Type (Utyp);
2479 
2480          elsif Is_Private_Type (Root_Type (Utyp))
2481            and then Present (Full_View (Root_Type (Utyp)))
2482            and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
2483          then
2484             Utyp := Full_View (Root_Type (Utyp));
2485          end if;
2486       end if;
2487 
2488       --  Handle private types
2489 
2490       if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then
2491          Utyp := Full_View (Utyp);
2492       end if;
2493 
2494       --  Handle protected and task types
2495 
2496       if Is_Concurrent_Type (Utyp)
2497         and then Present (Corresponding_Record_Type (Utyp))
2498       then
2499          Utyp := Corresponding_Record_Type (Utyp);
2500       end if;
2501 
2502       Utyp := Underlying_Type (Base_Type (Utyp));
2503 
2504       --  Deal with untagged derivation of private views. If the parent is
2505       --  now known to be protected, the finalization routine is the one
2506       --  defined on the corresponding record of the ancestor (corresponding
2507       --  records do not automatically inherit operations, but maybe they
2508       --  should???)
2509 
2510       if Is_Untagged_Derivation (Typ) then
2511          if Is_Protected_Type (Typ) then
2512             Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ)));
2513 
2514          else
2515             Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
2516 
2517             if Is_Protected_Type (Utyp) then
2518                Utyp := Corresponding_Record_Type (Utyp);
2519             end if;
2520          end if;
2521       end if;
2522 
2523       --  If the underlying_type is a subtype, we are dealing with the
2524       --  completion of a private type. We need to access the base type and
2525       --  generate a conversion to it.
2526 
2527       if Utyp /= Base_Type (Utyp) then
2528          pragma Assert (Is_Private_Type (Typ));
2529 
2530          Utyp := Base_Type (Utyp);
2531       end if;
2532 
2533       --  When dealing with an internally built full view for a type with
2534       --  unknown discriminants, use the original record type.
2535 
2536       if Is_Underlying_Record_View (Utyp) then
2537          Utyp := Etype (Utyp);
2538       end if;
2539 
2540       return TSS (Utyp, TSS_Finalize_Address);
2541    end Finalize_Address;
2542 
2543    ------------------------
2544    -- Find_Interface_ADT --
2545    ------------------------
2546 
2547    function Find_Interface_ADT
2548      (T     : Entity_Id;
2549       Iface : Entity_Id) return Elmt_Id
2550    is
2551       ADT : Elmt_Id;
2552       Typ : Entity_Id := T;
2553 
2554    begin
2555       pragma Assert (Is_Interface (Iface));
2556 
2557       --  Handle private types
2558 
2559       if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
2560          Typ := Full_View (Typ);
2561       end if;
2562 
2563       --  Handle access types
2564 
2565       if Is_Access_Type (Typ) then
2566          Typ := Designated_Type (Typ);
2567       end if;
2568 
2569       --  Handle task and protected types implementing interfaces
2570 
2571       if Is_Concurrent_Type (Typ) then
2572          Typ := Corresponding_Record_Type (Typ);
2573       end if;
2574 
2575       pragma Assert
2576         (not Is_Class_Wide_Type (Typ)
2577           and then Ekind (Typ) /= E_Incomplete_Type);
2578 
2579       if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
2580          return First_Elmt (Access_Disp_Table (Typ));
2581 
2582       else
2583          ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
2584          while Present (ADT)
2585            and then Present (Related_Type (Node (ADT)))
2586            and then Related_Type (Node (ADT)) /= Iface
2587            and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
2588                                      Use_Full_View => True)
2589          loop
2590             Next_Elmt (ADT);
2591          end loop;
2592 
2593          pragma Assert (Present (Related_Type (Node (ADT))));
2594          return ADT;
2595       end if;
2596    end Find_Interface_ADT;
2597 
2598    ------------------------
2599    -- Find_Interface_Tag --
2600    ------------------------
2601 
2602    function Find_Interface_Tag
2603      (T     : Entity_Id;
2604       Iface : Entity_Id) return Entity_Id
2605    is
2606       AI_Tag : Entity_Id;
2607       Found  : Boolean   := False;
2608       Typ    : Entity_Id := T;
2609 
2610       procedure Find_Tag (Typ : Entity_Id);
2611       --  Internal subprogram used to recursively climb to the ancestors
2612 
2613       --------------
2614       -- Find_Tag --
2615       --------------
2616 
2617       procedure Find_Tag (Typ : Entity_Id) is
2618          AI_Elmt : Elmt_Id;
2619          AI      : Node_Id;
2620 
2621       begin
2622          --  This routine does not handle the case in which the interface is an
2623          --  ancestor of Typ. That case is handled by the enclosing subprogram.
2624 
2625          pragma Assert (Typ /= Iface);
2626 
2627          --  Climb to the root type handling private types
2628 
2629          if Present (Full_View (Etype (Typ))) then
2630             if Full_View (Etype (Typ)) /= Typ then
2631                Find_Tag (Full_View (Etype (Typ)));
2632             end if;
2633 
2634          elsif Etype (Typ) /= Typ then
2635             Find_Tag (Etype (Typ));
2636          end if;
2637 
2638          --  Traverse the list of interfaces implemented by the type
2639 
2640          if not Found
2641            and then Present (Interfaces (Typ))
2642            and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
2643          then
2644             --  Skip the tag associated with the primary table
2645 
2646             pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
2647             AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
2648             pragma Assert (Present (AI_Tag));
2649 
2650             AI_Elmt := First_Elmt (Interfaces (Typ));
2651             while Present (AI_Elmt) loop
2652                AI := Node (AI_Elmt);
2653 
2654                if AI = Iface
2655                  or else Is_Ancestor (Iface, AI, Use_Full_View => True)
2656                then
2657                   Found := True;
2658                   return;
2659                end if;
2660 
2661                AI_Tag := Next_Tag_Component (AI_Tag);
2662                Next_Elmt (AI_Elmt);
2663             end loop;
2664          end if;
2665       end Find_Tag;
2666 
2667    --  Start of processing for Find_Interface_Tag
2668 
2669    begin
2670       pragma Assert (Is_Interface (Iface));
2671 
2672       --  Handle access types
2673 
2674       if Is_Access_Type (Typ) then
2675          Typ := Designated_Type (Typ);
2676       end if;
2677 
2678       --  Handle class-wide types
2679 
2680       if Is_Class_Wide_Type (Typ) then
2681          Typ := Root_Type (Typ);
2682       end if;
2683 
2684       --  Handle private types
2685 
2686       if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
2687          Typ := Full_View (Typ);
2688       end if;
2689 
2690       --  Handle entities from the limited view
2691 
2692       if Ekind (Typ) = E_Incomplete_Type then
2693          pragma Assert (Present (Non_Limited_View (Typ)));
2694          Typ := Non_Limited_View (Typ);
2695       end if;
2696 
2697       --  Handle task and protected types implementing interfaces
2698 
2699       if Is_Concurrent_Type (Typ) then
2700          Typ := Corresponding_Record_Type (Typ);
2701       end if;
2702 
2703       --  If the interface is an ancestor of the type, then it shared the
2704       --  primary dispatch table.
2705 
2706       if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
2707          pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
2708          return First_Tag_Component (Typ);
2709 
2710       --  Otherwise we need to search for its associated tag component
2711 
2712       else
2713          Find_Tag (Typ);
2714          pragma Assert (Found);
2715          return AI_Tag;
2716       end if;
2717    end Find_Interface_Tag;
2718 
2719    ---------------------------
2720    -- Find_Optional_Prim_Op --
2721    ---------------------------
2722 
2723    function Find_Optional_Prim_Op
2724      (T : Entity_Id; Name : Name_Id) return Entity_Id
2725    is
2726       Prim : Elmt_Id;
2727       Typ  : Entity_Id := T;
2728       Op   : Entity_Id;
2729 
2730    begin
2731       if Is_Class_Wide_Type (Typ) then
2732          Typ := Root_Type (Typ);
2733       end if;
2734 
2735       Typ := Underlying_Type (Typ);
2736 
2737       --  Loop through primitive operations
2738 
2739       Prim := First_Elmt (Primitive_Operations (Typ));
2740       while Present (Prim) loop
2741          Op := Node (Prim);
2742 
2743          --  We can retrieve primitive operations by name if it is an internal
2744          --  name. For equality we must check that both of its operands have
2745          --  the same type, to avoid confusion with user-defined equalities
2746          --  than may have a non-symmetric signature.
2747 
2748          exit when Chars (Op) = Name
2749            and then
2750              (Name /= Name_Op_Eq
2751                or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
2752 
2753          Next_Elmt (Prim);
2754       end loop;
2755 
2756       return Node (Prim); -- Empty if not found
2757    end Find_Optional_Prim_Op;
2758 
2759    ---------------------------
2760    -- Find_Optional_Prim_Op --
2761    ---------------------------
2762 
2763    function Find_Optional_Prim_Op
2764      (T    : Entity_Id;
2765       Name : TSS_Name_Type) return Entity_Id
2766    is
2767       Inher_Op  : Entity_Id := Empty;
2768       Own_Op    : Entity_Id := Empty;
2769       Prim_Elmt : Elmt_Id;
2770       Prim_Id   : Entity_Id;
2771       Typ       : Entity_Id := T;
2772 
2773    begin
2774       if Is_Class_Wide_Type (Typ) then
2775          Typ := Root_Type (Typ);
2776       end if;
2777 
2778       Typ := Underlying_Type (Typ);
2779 
2780       --  This search is based on the assertion that the dispatching version
2781       --  of the TSS routine always precedes the real primitive.
2782 
2783       Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2784       while Present (Prim_Elmt) loop
2785          Prim_Id := Node (Prim_Elmt);
2786 
2787          if Is_TSS (Prim_Id, Name) then
2788             if Present (Alias (Prim_Id)) then
2789                Inher_Op := Prim_Id;
2790             else
2791                Own_Op := Prim_Id;
2792             end if;
2793          end if;
2794 
2795          Next_Elmt (Prim_Elmt);
2796       end loop;
2797 
2798       if Present (Own_Op) then
2799          return Own_Op;
2800       elsif Present (Inher_Op) then
2801          return Inher_Op;
2802       else
2803          return Empty;
2804       end if;
2805    end Find_Optional_Prim_Op;
2806 
2807    ------------------
2808    -- Find_Prim_Op --
2809    ------------------
2810 
2811    function Find_Prim_Op
2812      (T : Entity_Id; Name : Name_Id) return Entity_Id
2813    is
2814       Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
2815    begin
2816       if No (Result) then
2817          raise Program_Error;
2818       end if;
2819 
2820       return Result;
2821    end Find_Prim_Op;
2822 
2823    ------------------
2824    -- Find_Prim_Op --
2825    ------------------
2826 
2827    function Find_Prim_Op
2828      (T    : Entity_Id;
2829       Name : TSS_Name_Type) return Entity_Id
2830    is
2831       Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
2832    begin
2833       if No (Result) then
2834          raise Program_Error;
2835       end if;
2836 
2837       return Result;
2838    end Find_Prim_Op;
2839 
2840    ----------------------------
2841    -- Find_Protection_Object --
2842    ----------------------------
2843 
2844    function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
2845       S : Entity_Id;
2846 
2847    begin
2848       S := Scop;
2849       while Present (S) loop
2850          if Ekind_In (S, E_Entry, E_Entry_Family, E_Function, E_Procedure)
2851            and then Present (Protection_Object (S))
2852          then
2853             return Protection_Object (S);
2854          end if;
2855 
2856          S := Scope (S);
2857       end loop;
2858 
2859       --  If we do not find a Protection object in the scope chain, then
2860       --  something has gone wrong, most likely the object was never created.
2861 
2862       raise Program_Error;
2863    end Find_Protection_Object;
2864 
2865    --------------------------
2866    -- Find_Protection_Type --
2867    --------------------------
2868 
2869    function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
2870       Comp : Entity_Id;
2871       Typ  : Entity_Id := Conc_Typ;
2872 
2873    begin
2874       if Is_Concurrent_Type (Typ) then
2875          Typ := Corresponding_Record_Type (Typ);
2876       end if;
2877 
2878       --  Since restriction violations are not considered serious errors, the
2879       --  expander remains active, but may leave the corresponding record type
2880       --  malformed. In such cases, component _object is not available so do
2881       --  not look for it.
2882 
2883       if not Analyzed (Typ) then
2884          return Empty;
2885       end if;
2886 
2887       Comp := First_Component (Typ);
2888       while Present (Comp) loop
2889          if Chars (Comp) = Name_uObject then
2890             return Base_Type (Etype (Comp));
2891          end if;
2892 
2893          Next_Component (Comp);
2894       end loop;
2895 
2896       --  The corresponding record of a protected type should always have an
2897       --  _object field.
2898 
2899       raise Program_Error;
2900    end Find_Protection_Type;
2901 
2902    -----------------------
2903    -- Find_Hook_Context --
2904    -----------------------
2905 
2906    function Find_Hook_Context (N : Node_Id) return Node_Id is
2907       Par : Node_Id;
2908       Top : Node_Id;
2909 
2910       Wrapped_Node : Node_Id;
2911       --  Note: if we are in a transient scope, we want to reuse it as
2912       --  the context for actions insertion, if possible. But if N is itself
2913       --  part of the stored actions for the current transient scope,
2914       --  then we need to insert at the appropriate (inner) location in
2915       --  the not as an action on Node_To_Be_Wrapped.
2916 
2917       In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N);
2918 
2919    begin
2920       --  When the node is inside a case/if expression, the lifetime of any
2921       --  temporary controlled object is extended. Find a suitable insertion
2922       --  node by locating the topmost case or if expressions.
2923 
2924       if In_Cond_Expr then
2925          Par := N;
2926          Top := N;
2927          while Present (Par) loop
2928             if Nkind_In (Original_Node (Par), N_Case_Expression,
2929                                               N_If_Expression)
2930             then
2931                Top := Par;
2932 
2933             --  Prevent the search from going too far
2934 
2935             elsif Is_Body_Or_Package_Declaration (Par) then
2936                exit;
2937             end if;
2938 
2939             Par := Parent (Par);
2940          end loop;
2941 
2942          --  The topmost case or if expression is now recovered, but it may
2943          --  still not be the correct place to add generated code. Climb to
2944          --  find a parent that is part of a declarative or statement list,
2945          --  and is not a list of actuals in a call.
2946 
2947          Par := Top;
2948          while Present (Par) loop
2949             if Is_List_Member (Par)
2950               and then not Nkind_In (Par, N_Component_Association,
2951                                           N_Discriminant_Association,
2952                                           N_Parameter_Association,
2953                                           N_Pragma_Argument_Association)
2954               and then not Nkind_In (Parent (Par), N_Function_Call,
2955                                                    N_Procedure_Call_Statement,
2956                                                    N_Entry_Call_Statement)
2957 
2958             then
2959                return Par;
2960 
2961             --  Prevent the search from going too far
2962 
2963             elsif Is_Body_Or_Package_Declaration (Par) then
2964                exit;
2965             end if;
2966 
2967             Par := Parent (Par);
2968          end loop;
2969 
2970          return Par;
2971 
2972       else
2973          Par := N;
2974          while Present (Par) loop
2975 
2976             --  Keep climbing past various operators
2977 
2978             if Nkind (Parent (Par)) in N_Op
2979               or else Nkind_In (Parent (Par), N_And_Then, N_Or_Else)
2980             then
2981                Par := Parent (Par);
2982             else
2983                exit;
2984             end if;
2985          end loop;
2986 
2987          Top := Par;
2988 
2989          --  The node may be located in a pragma in which case return the
2990          --  pragma itself:
2991 
2992          --    pragma Precondition (... and then Ctrl_Func_Call ...);
2993 
2994          --  Similar case occurs when the node is related to an object
2995          --  declaration or assignment:
2996 
2997          --    Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...;
2998 
2999          --  Another case to consider is when the node is part of a return
3000          --  statement:
3001 
3002          --    return ... and then Ctrl_Func_Call ...;
3003 
3004          --  Another case is when the node acts as a formal in a procedure
3005          --  call statement:
3006 
3007          --    Proc (... and then Ctrl_Func_Call ...);
3008 
3009          if Scope_Is_Transient then
3010             Wrapped_Node := Node_To_Be_Wrapped;
3011          else
3012             Wrapped_Node := Empty;
3013          end if;
3014 
3015          while Present (Par) loop
3016             if Par = Wrapped_Node
3017               or else Nkind_In (Par, N_Assignment_Statement,
3018                                      N_Object_Declaration,
3019                                      N_Pragma,
3020                                      N_Procedure_Call_Statement,
3021                                      N_Simple_Return_Statement)
3022             then
3023                return Par;
3024 
3025             --  Prevent the search from going too far
3026 
3027             elsif Is_Body_Or_Package_Declaration (Par) then
3028                exit;
3029             end if;
3030 
3031             Par := Parent (Par);
3032          end loop;
3033 
3034          --  Return the topmost short circuit operator
3035 
3036          return Top;
3037       end if;
3038    end Find_Hook_Context;
3039 
3040    ------------------------------
3041    -- Following_Address_Clause --
3042    ------------------------------
3043 
3044    function Following_Address_Clause (D : Node_Id) return Node_Id is
3045       Id     : constant Entity_Id := Defining_Identifier (D);
3046       Result : Node_Id;
3047       Par    : Node_Id;
3048 
3049       function Check_Decls (D : Node_Id) return Node_Id;
3050       --  This internal function differs from the main function in that it
3051       --  gets called to deal with a following package private part, and
3052       --  it checks declarations starting with D (the main function checks
3053       --  declarations following D). If D is Empty, then Empty is returned.
3054 
3055       -----------------
3056       -- Check_Decls --
3057       -----------------
3058 
3059       function Check_Decls (D : Node_Id) return Node_Id is
3060          Decl : Node_Id;
3061 
3062       begin
3063          Decl := D;
3064          while Present (Decl) loop
3065             if Nkind (Decl) = N_At_Clause
3066               and then Chars (Identifier (Decl)) = Chars (Id)
3067             then
3068                return Decl;
3069 
3070             elsif Nkind (Decl) = N_Attribute_Definition_Clause
3071               and then Chars (Decl) = Name_Address
3072               and then Chars (Name (Decl)) = Chars (Id)
3073             then
3074                return Decl;
3075             end if;
3076 
3077             Next (Decl);
3078          end loop;
3079 
3080          --  Otherwise not found, return Empty
3081 
3082          return Empty;
3083       end Check_Decls;
3084 
3085       --  Start of processing for Following_Address_Clause
3086 
3087    begin
3088       --  If parser detected no address clause for the identifier in question,
3089       --  then the answer is a quick NO, without the need for a search.
3090 
3091       if not Get_Name_Table_Boolean1 (Chars (Id)) then
3092          return Empty;
3093       end if;
3094 
3095       --  Otherwise search current declarative unit
3096 
3097       Result := Check_Decls (Next (D));
3098 
3099       if Present (Result) then
3100          return Result;
3101       end if;
3102 
3103       --  Check for possible package private part following
3104 
3105       Par := Parent (D);
3106 
3107       if Nkind (Par) = N_Package_Specification
3108         and then Visible_Declarations (Par) = List_Containing (D)
3109         and then Present (Private_Declarations (Par))
3110       then
3111          --  Private part present, check declarations there
3112 
3113          return Check_Decls (First (Private_Declarations (Par)));
3114 
3115       else
3116          --  No private part, clause not found, return Empty
3117 
3118          return Empty;
3119       end if;
3120    end Following_Address_Clause;
3121 
3122    ----------------------
3123    -- Force_Evaluation --
3124    ----------------------
3125 
3126    procedure Force_Evaluation
3127      (Exp           : Node_Id;
3128       Name_Req      : Boolean   := False;
3129       Related_Id    : Entity_Id := Empty;
3130       Is_Low_Bound  : Boolean   := False;
3131       Is_High_Bound : Boolean   := False;
3132       Mode          : Force_Evaluation_Mode := Relaxed)
3133    is
3134    begin
3135       Remove_Side_Effects
3136         (Exp                => Exp,
3137          Name_Req           => Name_Req,
3138          Variable_Ref       => True,
3139          Renaming_Req       => False,
3140          Related_Id         => Related_Id,
3141          Is_Low_Bound       => Is_Low_Bound,
3142          Is_High_Bound      => Is_High_Bound,
3143          Check_Side_Effects =>
3144            Is_Static_Expression (Exp)
3145              or else Mode = Relaxed);
3146    end Force_Evaluation;
3147 
3148    ---------------------------------
3149    -- Fully_Qualified_Name_String --
3150    ---------------------------------
3151 
3152    function Fully_Qualified_Name_String
3153      (E          : Entity_Id;
3154       Append_NUL : Boolean := True) return String_Id
3155    is
3156       procedure Internal_Full_Qualified_Name (E : Entity_Id);
3157       --  Compute recursively the qualified name without NUL at the end, adding
3158       --  it to the currently started string being generated
3159 
3160       ----------------------------------
3161       -- Internal_Full_Qualified_Name --
3162       ----------------------------------
3163 
3164       procedure Internal_Full_Qualified_Name (E : Entity_Id) is
3165          Ent : Entity_Id;
3166 
3167       begin
3168          --  Deal properly with child units
3169 
3170          if Nkind (E) = N_Defining_Program_Unit_Name then
3171             Ent := Defining_Identifier (E);
3172          else
3173             Ent := E;
3174          end if;
3175 
3176          --  Compute qualification recursively (only "Standard" has no scope)
3177 
3178          if Present (Scope (Scope (Ent))) then
3179             Internal_Full_Qualified_Name (Scope (Ent));
3180             Store_String_Char (Get_Char_Code ('.'));
3181          end if;
3182 
3183          --  Every entity should have a name except some expanded blocks
3184          --  don't bother about those.
3185 
3186          if Chars (Ent) = No_Name then
3187             return;
3188          end if;
3189 
3190          --  Generates the entity name in upper case
3191 
3192          Get_Decoded_Name_String (Chars (Ent));
3193          Set_All_Upper_Case;
3194          Store_String_Chars (Name_Buffer (1 .. Name_Len));
3195          return;
3196       end Internal_Full_Qualified_Name;
3197 
3198    --  Start of processing for Full_Qualified_Name
3199 
3200    begin
3201       Start_String;
3202       Internal_Full_Qualified_Name (E);
3203 
3204       if Append_NUL then
3205          Store_String_Char (Get_Char_Code (ASCII.NUL));
3206       end if;
3207 
3208       return End_String;
3209    end Fully_Qualified_Name_String;
3210 
3211    ------------------------
3212    -- Generate_Poll_Call --
3213    ------------------------
3214 
3215    procedure Generate_Poll_Call (N : Node_Id) is
3216    begin
3217       --  No poll call if polling not active
3218 
3219       if not Polling_Required then
3220          return;
3221 
3222       --  Otherwise generate require poll call
3223 
3224       else
3225          Insert_Before_And_Analyze (N,
3226            Make_Procedure_Call_Statement (Sloc (N),
3227              Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
3228       end if;
3229    end Generate_Poll_Call;
3230 
3231    ---------------------------------
3232    -- Get_Current_Value_Condition --
3233    ---------------------------------
3234 
3235    --  Note: the implementation of this procedure is very closely tied to the
3236    --  implementation of Set_Current_Value_Condition. In the Get procedure, we
3237    --  interpret Current_Value fields set by the Set procedure, so the two
3238    --  procedures need to be closely coordinated.
3239 
3240    procedure Get_Current_Value_Condition
3241      (Var : Node_Id;
3242       Op  : out Node_Kind;
3243       Val : out Node_Id)
3244    is
3245       Loc : constant Source_Ptr := Sloc (Var);
3246       Ent : constant Entity_Id  := Entity (Var);
3247 
3248       procedure Process_Current_Value_Condition
3249         (N : Node_Id;
3250          S : Boolean);
3251       --  N is an expression which holds either True (S = True) or False (S =
3252       --  False) in the condition. This procedure digs out the expression and
3253       --  if it refers to Ent, sets Op and Val appropriately.
3254 
3255       -------------------------------------
3256       -- Process_Current_Value_Condition --
3257       -------------------------------------
3258 
3259       procedure Process_Current_Value_Condition
3260         (N : Node_Id;
3261          S : Boolean)
3262       is
3263          Cond      : Node_Id;
3264          Prev_Cond : Node_Id;
3265          Sens      : Boolean;
3266 
3267       begin
3268          Cond := N;
3269          Sens := S;
3270 
3271          loop
3272             Prev_Cond := Cond;
3273 
3274             --  Deal with NOT operators, inverting sense
3275 
3276             while Nkind (Cond) = N_Op_Not loop
3277                Cond := Right_Opnd (Cond);
3278                Sens := not Sens;
3279             end loop;
3280 
3281             --  Deal with conversions, qualifications, and expressions with
3282             --  actions.
3283 
3284             while Nkind_In (Cond,
3285                     N_Type_Conversion,
3286                     N_Qualified_Expression,
3287                     N_Expression_With_Actions)
3288             loop
3289                Cond := Expression (Cond);
3290             end loop;
3291 
3292             exit when Cond = Prev_Cond;
3293          end loop;
3294 
3295          --  Deal with AND THEN and AND cases
3296 
3297          if Nkind_In (Cond, N_And_Then, N_Op_And) then
3298 
3299             --  Don't ever try to invert a condition that is of the form of an
3300             --  AND or AND THEN (since we are not doing sufficiently general
3301             --  processing to allow this).
3302 
3303             if Sens = False then
3304                Op  := N_Empty;
3305                Val := Empty;
3306                return;
3307             end if;
3308 
3309             --  Recursively process AND and AND THEN branches
3310 
3311             Process_Current_Value_Condition (Left_Opnd (Cond), True);
3312 
3313             if Op /= N_Empty then
3314                return;
3315             end if;
3316 
3317             Process_Current_Value_Condition (Right_Opnd (Cond), True);
3318             return;
3319 
3320          --  Case of relational operator
3321 
3322          elsif Nkind (Cond) in N_Op_Compare then
3323             Op := Nkind (Cond);
3324 
3325             --  Invert sense of test if inverted test
3326 
3327             if Sens = False then
3328                case Op is
3329                   when N_Op_Eq => Op := N_Op_Ne;
3330                   when N_Op_Ne => Op := N_Op_Eq;
3331                   when N_Op_Lt => Op := N_Op_Ge;
3332                   when N_Op_Gt => Op := N_Op_Le;
3333                   when N_Op_Le => Op := N_Op_Gt;
3334                   when N_Op_Ge => Op := N_Op_Lt;
3335                   when others  => raise Program_Error;
3336                end case;
3337             end if;
3338 
3339             --  Case of entity op value
3340 
3341             if Is_Entity_Name (Left_Opnd (Cond))
3342               and then Ent = Entity (Left_Opnd (Cond))
3343               and then Compile_Time_Known_Value (Right_Opnd (Cond))
3344             then
3345                Val := Right_Opnd (Cond);
3346 
3347             --  Case of value op entity
3348 
3349             elsif Is_Entity_Name (Right_Opnd (Cond))
3350               and then Ent = Entity (Right_Opnd (Cond))
3351               and then Compile_Time_Known_Value (Left_Opnd (Cond))
3352             then
3353                Val := Left_Opnd (Cond);
3354 
3355                --  We are effectively swapping operands
3356 
3357                case Op is
3358                   when N_Op_Eq => null;
3359                   when N_Op_Ne => null;
3360                   when N_Op_Lt => Op := N_Op_Gt;
3361                   when N_Op_Gt => Op := N_Op_Lt;
3362                   when N_Op_Le => Op := N_Op_Ge;
3363                   when N_Op_Ge => Op := N_Op_Le;
3364                   when others  => raise Program_Error;
3365                end case;
3366 
3367             else
3368                Op := N_Empty;
3369             end if;
3370 
3371             return;
3372 
3373          elsif Nkind_In (Cond,
3374                  N_Type_Conversion,
3375                  N_Qualified_Expression,
3376                  N_Expression_With_Actions)
3377          then
3378             Cond := Expression (Cond);
3379 
3380          --  Case of Boolean variable reference, return as though the
3381          --  reference had said var = True.
3382 
3383          else
3384             if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then
3385                Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
3386 
3387                if Sens = False then
3388                   Op := N_Op_Ne;
3389                else
3390                   Op := N_Op_Eq;
3391                end if;
3392             end if;
3393          end if;
3394       end Process_Current_Value_Condition;
3395 
3396    --  Start of processing for Get_Current_Value_Condition
3397 
3398    begin
3399       Op  := N_Empty;
3400       Val := Empty;
3401 
3402       --  Immediate return, nothing doing, if this is not an object
3403 
3404       if Ekind (Ent) not in Object_Kind then
3405          return;
3406       end if;
3407 
3408       --  Otherwise examine current value
3409 
3410       declare
3411          CV   : constant Node_Id := Current_Value (Ent);
3412          Sens : Boolean;
3413          Stm  : Node_Id;
3414 
3415       begin
3416          --  If statement. Condition is known true in THEN section, known False
3417          --  in any ELSIF or ELSE part, and unknown outside the IF statement.
3418 
3419          if Nkind (CV) = N_If_Statement then
3420 
3421             --  Before start of IF statement
3422 
3423             if Loc < Sloc (CV) then
3424                return;
3425 
3426                --  After end of IF statement
3427 
3428             elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
3429                return;
3430             end if;
3431 
3432             --  At this stage we know that we are within the IF statement, but
3433             --  unfortunately, the tree does not record the SLOC of the ELSE so
3434             --  we cannot use a simple SLOC comparison to distinguish between
3435             --  the then/else statements, so we have to climb the tree.
3436 
3437             declare
3438                N : Node_Id;
3439 
3440             begin
3441                N := Parent (Var);
3442                while Parent (N) /= CV loop
3443                   N := Parent (N);
3444 
3445                   --  If we fall off the top of the tree, then that's odd, but
3446                   --  perhaps it could occur in some error situation, and the
3447                   --  safest response is simply to assume that the outcome of
3448                   --  the condition is unknown. No point in bombing during an
3449                   --  attempt to optimize things.
3450 
3451                   if No (N) then
3452                      return;
3453                   end if;
3454                end loop;
3455 
3456                --  Now we have N pointing to a node whose parent is the IF
3457                --  statement in question, so now we can tell if we are within
3458                --  the THEN statements.
3459 
3460                if Is_List_Member (N)
3461                  and then List_Containing (N) = Then_Statements (CV)
3462                then
3463                   Sens := True;
3464 
3465                --  If the variable reference does not come from source, we
3466                --  cannot reliably tell whether it appears in the else part.
3467                --  In particular, if it appears in generated code for a node
3468                --  that requires finalization, it may be attached to a list
3469                --  that has not been yet inserted into the code. For now,
3470                --  treat it as unknown.
3471 
3472                elsif not Comes_From_Source (N) then
3473                   return;
3474 
3475                --  Otherwise we must be in ELSIF or ELSE part
3476 
3477                else
3478                   Sens := False;
3479                end if;
3480             end;
3481 
3482             --  ELSIF part. Condition is known true within the referenced
3483             --  ELSIF, known False in any subsequent ELSIF or ELSE part,
3484             --  and unknown before the ELSE part or after the IF statement.
3485 
3486          elsif Nkind (CV) = N_Elsif_Part then
3487 
3488             --  if the Elsif_Part had condition_actions, the elsif has been
3489             --  rewritten as a nested if, and the original elsif_part is
3490             --  detached from the tree, so there is no way to obtain useful
3491             --  information on the current value of the variable.
3492             --  Can this be improved ???
3493 
3494             if No (Parent (CV)) then
3495                return;
3496             end if;
3497 
3498             Stm := Parent (CV);
3499 
3500             --  If the tree has been otherwise rewritten there is nothing
3501             --  else to be done either.
3502 
3503             if Nkind (Stm) /= N_If_Statement then
3504                return;
3505             end if;
3506 
3507             --  Before start of ELSIF part
3508 
3509             if Loc < Sloc (CV) then
3510                return;
3511 
3512                --  After end of IF statement
3513 
3514             elsif Loc >= Sloc (Stm) +
3515               Text_Ptr (UI_To_Int (End_Span (Stm)))
3516             then
3517                return;
3518             end if;
3519 
3520             --  Again we lack the SLOC of the ELSE, so we need to climb the
3521             --  tree to see if we are within the ELSIF part in question.
3522 
3523             declare
3524                N : Node_Id;
3525 
3526             begin
3527                N := Parent (Var);
3528                while Parent (N) /= Stm loop
3529                   N := Parent (N);
3530 
3531                   --  If we fall off the top of the tree, then that's odd, but
3532                   --  perhaps it could occur in some error situation, and the
3533                   --  safest response is simply to assume that the outcome of
3534                   --  the condition is unknown. No point in bombing during an
3535                   --  attempt to optimize things.
3536 
3537                   if No (N) then
3538                      return;
3539                   end if;
3540                end loop;
3541 
3542                --  Now we have N pointing to a node whose parent is the IF
3543                --  statement in question, so see if is the ELSIF part we want.
3544                --  the THEN statements.
3545 
3546                if N = CV then
3547                   Sens := True;
3548 
3549                   --  Otherwise we must be in subsequent ELSIF or ELSE part
3550 
3551                else
3552                   Sens := False;
3553                end if;
3554             end;
3555 
3556          --  Iteration scheme of while loop. The condition is known to be
3557          --  true within the body of the loop.
3558 
3559          elsif Nkind (CV) = N_Iteration_Scheme then
3560             declare
3561                Loop_Stmt : constant Node_Id := Parent (CV);
3562 
3563             begin
3564                --  Before start of body of loop
3565 
3566                if Loc < Sloc (Loop_Stmt) then
3567                   return;
3568 
3569                --  After end of LOOP statement
3570 
3571                elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
3572                   return;
3573 
3574                --  We are within the body of the loop
3575 
3576                else
3577                   Sens := True;
3578                end if;
3579             end;
3580 
3581          --  All other cases of Current_Value settings
3582 
3583          else
3584             return;
3585          end if;
3586 
3587          --  If we fall through here, then we have a reportable condition, Sens
3588          --  is True if the condition is true and False if it needs inverting.
3589 
3590          Process_Current_Value_Condition (Condition (CV), Sens);
3591       end;
3592    end Get_Current_Value_Condition;
3593 
3594    ---------------------
3595    -- Get_Stream_Size --
3596    ---------------------
3597 
3598    function Get_Stream_Size (E : Entity_Id) return Uint is
3599    begin
3600       --  If we have a Stream_Size clause for this type use it
3601 
3602       if Has_Stream_Size_Clause (E) then
3603          return Static_Integer (Expression (Stream_Size_Clause (E)));
3604 
3605       --  Otherwise the Stream_Size if the size of the type
3606 
3607       else
3608          return Esize (E);
3609       end if;
3610    end Get_Stream_Size;
3611 
3612    ---------------------------
3613    -- Has_Access_Constraint --
3614    ---------------------------
3615 
3616    function Has_Access_Constraint (E : Entity_Id) return Boolean is
3617       Disc : Entity_Id;
3618       T    : constant Entity_Id := Etype (E);
3619 
3620    begin
3621       if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then
3622          Disc := First_Discriminant (T);
3623          while Present (Disc) loop
3624             if Is_Access_Type (Etype (Disc)) then
3625                return True;
3626             end if;
3627 
3628             Next_Discriminant (Disc);
3629          end loop;
3630 
3631          return False;
3632       else
3633          return False;
3634       end if;
3635    end Has_Access_Constraint;
3636 
3637    -----------------------------------------------------
3638    -- Has_Annotate_Pragma_For_External_Axiomatization --
3639    -----------------------------------------------------
3640 
3641    function Has_Annotate_Pragma_For_External_Axiomatization
3642      (E : Entity_Id) return Boolean
3643    is
3644       function Is_Annotate_Pragma_For_External_Axiomatization
3645         (N : Node_Id) return Boolean;
3646       --  Returns whether N is
3647       --    pragma Annotate (GNATprove, External_Axiomatization);
3648 
3649       ----------------------------------------------------
3650       -- Is_Annotate_Pragma_For_External_Axiomatization --
3651       ----------------------------------------------------
3652 
3653       --  The general form of pragma Annotate is
3654 
3655       --    pragma Annotate (IDENTIFIER [, IDENTIFIER {, ARG}]);
3656       --    ARG ::= NAME | EXPRESSION
3657 
3658       --  The first two arguments are by convention intended to refer to an
3659       --  external tool and a tool-specific function. These arguments are
3660       --  not analyzed.
3661 
3662       --  The following is used to annotate a package specification which
3663       --  GNATprove should treat specially, because the axiomatization of
3664       --  this unit is given by the user instead of being automatically
3665       --  generated.
3666 
3667       --    pragma Annotate (GNATprove, External_Axiomatization);
3668 
3669       function Is_Annotate_Pragma_For_External_Axiomatization
3670         (N : Node_Id) return Boolean
3671       is
3672          Name_GNATprove               : constant String :=
3673                                           "gnatprove";
3674          Name_External_Axiomatization : constant String :=
3675                                           "external_axiomatization";
3676          --  Special names
3677 
3678       begin
3679          if Nkind (N) = N_Pragma
3680            and then Get_Pragma_Id (Pragma_Name (N)) = Pragma_Annotate
3681            and then List_Length (Pragma_Argument_Associations (N)) = 2
3682          then
3683             declare
3684                Arg1 : constant Node_Id :=
3685                         First (Pragma_Argument_Associations (N));
3686                Arg2 : constant Node_Id := Next (Arg1);
3687                Nam1 : Name_Id;
3688                Nam2 : Name_Id;
3689 
3690             begin
3691                --  Fill in Name_Buffer with Name_GNATprove first, and then with
3692                --  Name_External_Axiomatization so that Name_Find returns the
3693                --  corresponding name. This takes care of all possible casings.
3694 
3695                Name_Len := 0;
3696                Add_Str_To_Name_Buffer (Name_GNATprove);
3697                Nam1 := Name_Find;
3698 
3699                Name_Len := 0;
3700                Add_Str_To_Name_Buffer (Name_External_Axiomatization);
3701                Nam2 := Name_Find;
3702 
3703                return Chars (Get_Pragma_Arg (Arg1)) = Nam1
3704                          and then
3705                       Chars (Get_Pragma_Arg (Arg2)) = Nam2;
3706             end;
3707 
3708          else
3709             return False;
3710          end if;
3711       end Is_Annotate_Pragma_For_External_Axiomatization;
3712 
3713       --  Local variables
3714 
3715       Decl      : Node_Id;
3716       Vis_Decls : List_Id;
3717       N         : Node_Id;
3718 
3719    --  Start of processing for Has_Annotate_Pragma_For_External_Axiomatization
3720 
3721    begin
3722       if Nkind (Parent (E)) = N_Defining_Program_Unit_Name then
3723          Decl := Parent (Parent (E));
3724       else
3725          Decl := Parent (E);
3726       end if;
3727 
3728       Vis_Decls := Visible_Declarations (Decl);
3729 
3730       N := First (Vis_Decls);
3731       while Present (N) loop
3732 
3733          --  Skip declarations generated by the frontend. Skip all pragmas
3734          --  that are not the desired Annotate pragma. Stop the search on
3735          --  the first non-pragma source declaration.
3736 
3737          if Comes_From_Source (N) then
3738             if Nkind (N) = N_Pragma then
3739                if Is_Annotate_Pragma_For_External_Axiomatization (N) then
3740                   return True;
3741                end if;
3742             else
3743                return False;
3744             end if;
3745          end if;
3746 
3747          Next (N);
3748       end loop;
3749 
3750       return False;
3751    end Has_Annotate_Pragma_For_External_Axiomatization;
3752 
3753    --------------------
3754    -- Homonym_Number --
3755    --------------------
3756 
3757    function Homonym_Number (Subp : Entity_Id) return Nat is
3758       Count : Nat;
3759       Hom   : Entity_Id;
3760 
3761    begin
3762       Count := 1;
3763       Hom := Homonym (Subp);
3764       while Present (Hom) loop
3765          if Scope (Hom) = Scope (Subp) then
3766             Count := Count + 1;
3767          end if;
3768 
3769          Hom := Homonym (Hom);
3770       end loop;
3771 
3772       return Count;
3773    end Homonym_Number;
3774 
3775    -----------------------------------
3776    -- In_Library_Level_Package_Body --
3777    -----------------------------------
3778 
3779    function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
3780    begin
3781       --  First determine whether the entity appears at the library level, then
3782       --  look at the containing unit.
3783 
3784       if Is_Library_Level_Entity (Id) then
3785          declare
3786             Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
3787 
3788          begin
3789             return Nkind (Unit (Container)) = N_Package_Body;
3790          end;
3791       end if;
3792 
3793       return False;
3794    end In_Library_Level_Package_Body;
3795 
3796    ------------------------------
3797    -- In_Unconditional_Context --
3798    ------------------------------
3799 
3800    function In_Unconditional_Context (Node : Node_Id) return Boolean is
3801       P : Node_Id;
3802 
3803    begin
3804       P := Node;
3805       while Present (P) loop
3806          case Nkind (P) is
3807             when N_Subprogram_Body =>
3808                return True;
3809 
3810             when N_If_Statement =>
3811                return False;
3812 
3813             when N_Loop_Statement =>
3814                return False;
3815 
3816             when N_Case_Statement =>
3817                return False;
3818 
3819             when others =>
3820                P := Parent (P);
3821          end case;
3822       end loop;
3823 
3824       return False;
3825    end In_Unconditional_Context;
3826 
3827    -------------------
3828    -- Insert_Action --
3829    -------------------
3830 
3831    procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
3832    begin
3833       if Present (Ins_Action) then
3834          Insert_Actions (Assoc_Node, New_List (Ins_Action));
3835       end if;
3836    end Insert_Action;
3837 
3838    --  Version with check(s) suppressed
3839 
3840    procedure Insert_Action
3841      (Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
3842    is
3843    begin
3844       Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
3845    end Insert_Action;
3846 
3847    -------------------------
3848    -- Insert_Action_After --
3849    -------------------------
3850 
3851    procedure Insert_Action_After
3852      (Assoc_Node : Node_Id;
3853       Ins_Action : Node_Id)
3854    is
3855    begin
3856       Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
3857    end Insert_Action_After;
3858 
3859    --------------------
3860    -- Insert_Actions --
3861    --------------------
3862 
3863    procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
3864       N : Node_Id;
3865       P : Node_Id;
3866 
3867       Wrapped_Node : Node_Id := Empty;
3868 
3869    begin
3870       if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
3871          return;
3872       end if;
3873 
3874       --  Ignore insert of actions from inside default expression (or other
3875       --  similar "spec expression") in the special spec-expression analyze
3876       --  mode. Any insertions at this point have no relevance, since we are
3877       --  only doing the analyze to freeze the types of any static expressions.
3878       --  See section "Handling of Default Expressions" in the spec of package
3879       --  Sem for further details.
3880 
3881       if In_Spec_Expression then
3882          return;
3883       end if;
3884 
3885       --  If the action derives from stuff inside a record, then the actions
3886       --  are attached to the current scope, to be inserted and analyzed on
3887       --  exit from the scope. The reason for this is that we may also be
3888       --  generating freeze actions at the same time, and they must eventually
3889       --  be elaborated in the correct order.
3890 
3891       if Is_Record_Type (Current_Scope)
3892         and then not Is_Frozen (Current_Scope)
3893       then
3894          if No (Scope_Stack.Table
3895                   (Scope_Stack.Last).Pending_Freeze_Actions)
3896          then
3897             Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
3898               Ins_Actions;
3899          else
3900             Append_List
3901               (Ins_Actions,
3902                Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
3903          end if;
3904 
3905          return;
3906       end if;
3907 
3908       --  We now intend to climb up the tree to find the right point to
3909       --  insert the actions. We start at Assoc_Node, unless this node is a
3910       --  subexpression in which case we start with its parent. We do this for
3911       --  two reasons. First it speeds things up. Second, if Assoc_Node is
3912       --  itself one of the special nodes like N_And_Then, then we assume that
3913       --  an initial request to insert actions for such a node does not expect
3914       --  the actions to get deposited in the node for later handling when the
3915       --  node is expanded, since clearly the node is being dealt with by the
3916       --  caller. Note that in the subexpression case, N is always the child we
3917       --  came from.
3918 
3919       --  N_Raise_xxx_Error is an annoying special case, it is a statement
3920       --  if it has type Standard_Void_Type, and a subexpression otherwise.
3921       --  Procedure calls, and similarly procedure attribute references, are
3922       --  also statements.
3923 
3924       if Nkind (Assoc_Node) in N_Subexpr
3925         and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
3926                    or else Etype (Assoc_Node) /= Standard_Void_Type)
3927         and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
3928         and then (Nkind (Assoc_Node) /= N_Attribute_Reference
3929                    or else not Is_Procedure_Attribute_Name
3930                                  (Attribute_Name (Assoc_Node)))
3931       then
3932          N := Assoc_Node;
3933          P := Parent (Assoc_Node);
3934 
3935       --  Non-subexpression case. Note that N is initially Empty in this case
3936       --  (N is only guaranteed Non-Empty in the subexpr case).
3937 
3938       else
3939          N := Empty;
3940          P := Assoc_Node;
3941       end if;
3942 
3943       --  Capture root of the transient scope
3944 
3945       if Scope_Is_Transient then
3946          Wrapped_Node := Node_To_Be_Wrapped;
3947       end if;
3948 
3949       loop
3950          pragma Assert (Present (P));
3951 
3952          --  Make sure that inserted actions stay in the transient scope
3953 
3954          if Present (Wrapped_Node) and then N = Wrapped_Node then
3955             Store_Before_Actions_In_Scope (Ins_Actions);
3956             return;
3957          end if;
3958 
3959          case Nkind (P) is
3960 
3961             --  Case of right operand of AND THEN or OR ELSE. Put the actions
3962             --  in the Actions field of the right operand. They will be moved
3963             --  out further when the AND THEN or OR ELSE operator is expanded.
3964             --  Nothing special needs to be done for the left operand since
3965             --  in that case the actions are executed unconditionally.
3966 
3967             when N_Short_Circuit =>
3968                if N = Right_Opnd (P) then
3969 
3970                   --  We are now going to either append the actions to the
3971                   --  actions field of the short-circuit operation. We will
3972                   --  also analyze the actions now.
3973 
3974                   --  This analysis is really too early, the proper thing would
3975                   --  be to just park them there now, and only analyze them if
3976                   --  we find we really need them, and to it at the proper
3977                   --  final insertion point. However attempting to this proved
3978                   --  tricky, so for now we just kill current values before and
3979                   --  after the analyze call to make sure we avoid peculiar
3980                   --  optimizations from this out of order insertion.
3981 
3982                   Kill_Current_Values;
3983 
3984                   --  If P has already been expanded, we can't park new actions
3985                   --  on it, so we need to expand them immediately, introducing
3986                   --  an Expression_With_Actions. N can't be an expression
3987                   --  with actions, or else then the actions would have been
3988                   --  inserted at an inner level.
3989 
3990                   if Analyzed (P) then
3991                      pragma Assert (Nkind (N) /= N_Expression_With_Actions);
3992                      Rewrite (N,
3993                        Make_Expression_With_Actions (Sloc (N),
3994                          Actions    => Ins_Actions,
3995                          Expression => Relocate_Node (N)));
3996                      Analyze_And_Resolve (N);
3997 
3998                   elsif Present (Actions (P)) then
3999                      Insert_List_After_And_Analyze
4000                        (Last (Actions (P)), Ins_Actions);
4001                   else
4002                      Set_Actions (P, Ins_Actions);
4003                      Analyze_List (Actions (P));
4004                   end if;
4005 
4006                   Kill_Current_Values;
4007 
4008                   return;
4009                end if;
4010 
4011             --  Then or Else dependent expression of an if expression. Add
4012             --  actions to Then_Actions or Else_Actions field as appropriate.
4013             --  The actions will be moved further out when the if is expanded.
4014 
4015             when N_If_Expression =>
4016                declare
4017                   ThenX : constant Node_Id := Next (First (Expressions (P)));
4018                   ElseX : constant Node_Id := Next (ThenX);
4019 
4020                begin
4021                   --  If the enclosing expression is already analyzed, as
4022                   --  is the case for nested elaboration checks, insert the
4023                   --  conditional further out.
4024 
4025                   if Analyzed (P) then
4026                      null;
4027 
4028                   --  Actions belong to the then expression, temporarily place
4029                   --  them as Then_Actions of the if expression. They will be
4030                   --  moved to the proper place later when the if expression
4031                   --  is expanded.
4032 
4033                   elsif N = ThenX then
4034                      if Present (Then_Actions (P)) then
4035                         Insert_List_After_And_Analyze
4036                           (Last (Then_Actions (P)), Ins_Actions);
4037                      else
4038                         Set_Then_Actions (P, Ins_Actions);
4039                         Analyze_List (Then_Actions (P));
4040                      end if;
4041 
4042                      return;
4043 
4044                   --  Actions belong to the else expression, temporarily place
4045                   --  them as Else_Actions of the if expression. They will be
4046                   --  moved to the proper place later when the if expression
4047                   --  is expanded.
4048 
4049                   elsif N = ElseX then
4050                      if Present (Else_Actions (P)) then
4051                         Insert_List_After_And_Analyze
4052                           (Last (Else_Actions (P)), Ins_Actions);
4053                      else
4054                         Set_Else_Actions (P, Ins_Actions);
4055                         Analyze_List (Else_Actions (P));
4056                      end if;
4057 
4058                      return;
4059 
4060                   --  Actions belong to the condition. In this case they are
4061                   --  unconditionally executed, and so we can continue the
4062                   --  search for the proper insert point.
4063 
4064                   else
4065                      null;
4066                   end if;
4067                end;
4068 
4069             --  Alternative of case expression, we place the action in the
4070             --  Actions field of the case expression alternative, this will
4071             --  be handled when the case expression is expanded.
4072 
4073             when N_Case_Expression_Alternative =>
4074                if Present (Actions (P)) then
4075                   Insert_List_After_And_Analyze
4076                     (Last (Actions (P)), Ins_Actions);
4077                else
4078                   Set_Actions (P, Ins_Actions);
4079                   Analyze_List (Actions (P));
4080                end if;
4081 
4082                return;
4083 
4084             --  Case of appearing within an Expressions_With_Actions node. When
4085             --  the new actions come from the expression of the expression with
4086             --  actions, they must be added to the existing actions. The other
4087             --  alternative is when the new actions are related to one of the
4088             --  existing actions of the expression with actions, and should
4089             --  never reach here: if actions are inserted on a statement
4090             --  within the Actions of an expression with actions, or on some
4091             --  sub-expression of such a statement, then the outermost proper
4092             --  insertion point is right before the statement, and we should
4093             --  never climb up as far as the N_Expression_With_Actions itself.
4094 
4095             when N_Expression_With_Actions =>
4096                if N = Expression (P) then
4097                   if Is_Empty_List (Actions (P)) then
4098                      Append_List_To (Actions (P), Ins_Actions);
4099                      Analyze_List (Actions (P));
4100                   else
4101                      Insert_List_After_And_Analyze
4102                        (Last (Actions (P)), Ins_Actions);
4103                   end if;
4104 
4105                   return;
4106 
4107                else
4108                   raise Program_Error;
4109                end if;
4110 
4111             --  Case of appearing in the condition of a while expression or
4112             --  elsif. We insert the actions into the Condition_Actions field.
4113             --  They will be moved further out when the while loop or elsif
4114             --  is analyzed.
4115 
4116             when N_Iteration_Scheme |
4117                  N_Elsif_Part
4118             =>
4119                if N = Condition (P) then
4120                   if Present (Condition_Actions (P)) then
4121                      Insert_List_After_And_Analyze
4122                        (Last (Condition_Actions (P)), Ins_Actions);
4123                   else
4124                      Set_Condition_Actions (P, Ins_Actions);
4125 
4126                      --  Set the parent of the insert actions explicitly. This
4127                      --  is not a syntactic field, but we need the parent field
4128                      --  set, in particular so that freeze can understand that
4129                      --  it is dealing with condition actions, and properly
4130                      --  insert the freezing actions.
4131 
4132                      Set_Parent (Ins_Actions, P);
4133                      Analyze_List (Condition_Actions (P));
4134                   end if;
4135 
4136                   return;
4137                end if;
4138 
4139             --  Statements, declarations, pragmas, representation clauses
4140 
4141             when
4142                --  Statements
4143 
4144                N_Procedure_Call_Statement               |
4145                N_Statement_Other_Than_Procedure_Call    |
4146 
4147                --  Pragmas
4148 
4149                N_Pragma                                 |
4150 
4151                --  Representation_Clause
4152 
4153                N_At_Clause                              |
4154                N_Attribute_Definition_Clause            |
4155                N_Enumeration_Representation_Clause      |
4156                N_Record_Representation_Clause           |
4157 
4158                --  Declarations
4159 
4160                N_Abstract_Subprogram_Declaration        |
4161                N_Entry_Body                             |
4162                N_Exception_Declaration                  |
4163                N_Exception_Renaming_Declaration         |
4164                N_Expression_Function                    |
4165                N_Formal_Abstract_Subprogram_Declaration |
4166                N_Formal_Concrete_Subprogram_Declaration |
4167                N_Formal_Object_Declaration              |
4168                N_Formal_Type_Declaration                |
4169                N_Full_Type_Declaration                  |
4170                N_Function_Instantiation                 |
4171                N_Generic_Function_Renaming_Declaration  |
4172                N_Generic_Package_Declaration            |
4173                N_Generic_Package_Renaming_Declaration   |
4174                N_Generic_Procedure_Renaming_Declaration |
4175                N_Generic_Subprogram_Declaration         |
4176                N_Implicit_Label_Declaration             |
4177                N_Incomplete_Type_Declaration            |
4178                N_Number_Declaration                     |
4179                N_Object_Declaration                     |
4180                N_Object_Renaming_Declaration            |
4181                N_Package_Body                           |
4182                N_Package_Body_Stub                      |
4183                N_Package_Declaration                    |
4184                N_Package_Instantiation                  |
4185                N_Package_Renaming_Declaration           |
4186                N_Private_Extension_Declaration          |
4187                N_Private_Type_Declaration               |
4188                N_Procedure_Instantiation                |
4189                N_Protected_Body                         |
4190                N_Protected_Body_Stub                    |
4191                N_Protected_Type_Declaration             |
4192                N_Single_Task_Declaration                |
4193                N_Subprogram_Body                        |
4194                N_Subprogram_Body_Stub                   |
4195                N_Subprogram_Declaration                 |
4196                N_Subprogram_Renaming_Declaration        |
4197                N_Subtype_Declaration                    |
4198                N_Task_Body                              |
4199                N_Task_Body_Stub                         |
4200                N_Task_Type_Declaration                  |
4201 
4202                --  Use clauses can appear in lists of declarations
4203 
4204                N_Use_Package_Clause                     |
4205                N_Use_Type_Clause                        |
4206 
4207                --  Freeze entity behaves like a declaration or statement
4208 
4209                N_Freeze_Entity                          |
4210                N_Freeze_Generic_Entity
4211             =>
4212                --  Do not insert here if the item is not a list member (this
4213                --  happens for example with a triggering statement, and the
4214                --  proper approach is to insert before the entire select).
4215 
4216                if not Is_List_Member (P) then
4217                   null;
4218 
4219                --  Do not insert if parent of P is an N_Component_Association
4220                --  node (i.e. we are in the context of an N_Aggregate or
4221                --  N_Extension_Aggregate node. In this case we want to insert
4222                --  before the entire aggregate.
4223 
4224                elsif Nkind (Parent (P)) = N_Component_Association then
4225                   null;
4226 
4227                --  Do not insert if the parent of P is either an N_Variant node
4228                --  or an N_Record_Definition node, meaning in either case that
4229                --  P is a member of a component list, and that therefore the
4230                --  actions should be inserted outside the complete record
4231                --  declaration.
4232 
4233                elsif Nkind_In (Parent (P), N_Variant, N_Record_Definition) then
4234                   null;
4235 
4236                --  Do not insert freeze nodes within the loop generated for
4237                --  an aggregate, because they may be elaborated too late for
4238                --  subsequent use in the back end: within a package spec the
4239                --  loop is part of the elaboration procedure and is only
4240                --  elaborated during the second pass.
4241 
4242                --  If the loop comes from source, or the entity is local to the
4243                --  loop itself it must remain within.
4244 
4245                elsif Nkind (Parent (P)) = N_Loop_Statement
4246                  and then not Comes_From_Source (Parent (P))
4247                  and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
4248                  and then
4249                    Scope (Entity (First (Ins_Actions))) /= Current_Scope
4250                then
4251                   null;
4252 
4253                --  Otherwise we can go ahead and do the insertion
4254 
4255                elsif P = Wrapped_Node then
4256                   Store_Before_Actions_In_Scope (Ins_Actions);
4257                   return;
4258 
4259                else
4260                   Insert_List_Before_And_Analyze (P, Ins_Actions);
4261                   return;
4262                end if;
4263 
4264             --  A special case, N_Raise_xxx_Error can act either as a statement
4265             --  or a subexpression. We tell the difference by looking at the
4266             --  Etype. It is set to Standard_Void_Type in the statement case.
4267 
4268             when
4269                N_Raise_xxx_Error =>
4270                   if Etype (P) = Standard_Void_Type then
4271                      if P = Wrapped_Node then
4272                         Store_Before_Actions_In_Scope (Ins_Actions);
4273                      else
4274                         Insert_List_Before_And_Analyze (P, Ins_Actions);
4275                      end if;
4276 
4277                      return;
4278 
4279                   --  In the subexpression case, keep climbing
4280 
4281                   else
4282                      null;
4283                   end if;
4284 
4285             --  If a component association appears within a loop created for
4286             --  an array aggregate, attach the actions to the association so
4287             --  they can be subsequently inserted within the loop. For other
4288             --  component associations insert outside of the aggregate. For
4289             --  an association that will generate a loop, its Loop_Actions
4290             --  attribute is already initialized (see exp_aggr.adb).
4291 
4292             --  The list of loop_actions can in turn generate additional ones,
4293             --  that are inserted before the associated node. If the associated
4294             --  node is outside the aggregate, the new actions are collected
4295             --  at the end of the loop actions, to respect the order in which
4296             --  they are to be elaborated.
4297 
4298             when
4299                N_Component_Association =>
4300                   if Nkind (Parent (P)) = N_Aggregate
4301                     and then Present (Loop_Actions (P))
4302                   then
4303                      if Is_Empty_List (Loop_Actions (P)) then
4304                         Set_Loop_Actions (P, Ins_Actions);
4305                         Analyze_List (Ins_Actions);
4306 
4307                      else
4308                         declare
4309                            Decl : Node_Id;
4310 
4311                         begin
4312                            --  Check whether these actions were generated by a
4313                            --  declaration that is part of the loop_ actions
4314                            --  for the component_association.
4315 
4316                            Decl := Assoc_Node;
4317                            while Present (Decl) loop
4318                               exit when Parent (Decl) = P
4319                                 and then Is_List_Member (Decl)
4320                                 and then
4321                                   List_Containing (Decl) = Loop_Actions (P);
4322                               Decl := Parent (Decl);
4323                            end loop;
4324 
4325                            if Present (Decl) then
4326                               Insert_List_Before_And_Analyze
4327                                 (Decl, Ins_Actions);
4328                            else
4329                               Insert_List_After_And_Analyze
4330                                 (Last (Loop_Actions (P)), Ins_Actions);
4331                            end if;
4332                         end;
4333                      end if;
4334 
4335                      return;
4336 
4337                   else
4338                      null;
4339                   end if;
4340 
4341             --  Another special case, an attribute denoting a procedure call
4342 
4343             when
4344                N_Attribute_Reference =>
4345                   if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
4346                      if P = Wrapped_Node then
4347                         Store_Before_Actions_In_Scope (Ins_Actions);
4348                      else
4349                         Insert_List_Before_And_Analyze (P, Ins_Actions);
4350                      end if;
4351 
4352                      return;
4353 
4354                   --  In the subexpression case, keep climbing
4355 
4356                   else
4357                      null;
4358                   end if;
4359 
4360             --  A contract node should not belong to the tree
4361 
4362             when N_Contract =>
4363                raise Program_Error;
4364 
4365             --  For all other node types, keep climbing tree
4366 
4367             when
4368                N_Abortable_Part                         |
4369                N_Accept_Alternative                     |
4370                N_Access_Definition                      |
4371                N_Access_Function_Definition             |
4372                N_Access_Procedure_Definition            |
4373                N_Access_To_Object_Definition            |
4374                N_Aggregate                              |
4375                N_Allocator                              |
4376                N_Aspect_Specification                   |
4377                N_Case_Expression                        |
4378                N_Case_Statement_Alternative             |
4379                N_Character_Literal                      |
4380                N_Compilation_Unit                       |
4381                N_Compilation_Unit_Aux                   |
4382                N_Component_Clause                       |
4383                N_Component_Declaration                  |
4384                N_Component_Definition                   |
4385                N_Component_List                         |
4386                N_Constrained_Array_Definition           |
4387                N_Decimal_Fixed_Point_Definition         |
4388                N_Defining_Character_Literal             |
4389                N_Defining_Identifier                    |
4390                N_Defining_Operator_Symbol               |
4391                N_Defining_Program_Unit_Name             |
4392                N_Delay_Alternative                      |
4393                N_Delta_Constraint                       |
4394                N_Derived_Type_Definition                |
4395                N_Designator                             |
4396                N_Digits_Constraint                      |
4397                N_Discriminant_Association               |
4398                N_Discriminant_Specification             |
4399                N_Empty                                  |
4400                N_Entry_Body_Formal_Part                 |
4401                N_Entry_Call_Alternative                 |
4402                N_Entry_Declaration                      |
4403                N_Entry_Index_Specification              |
4404                N_Enumeration_Type_Definition            |
4405                N_Error                                  |
4406                N_Exception_Handler                      |
4407                N_Expanded_Name                          |
4408                N_Explicit_Dereference                   |
4409                N_Extension_Aggregate                    |
4410                N_Floating_Point_Definition              |
4411                N_Formal_Decimal_Fixed_Point_Definition  |
4412                N_Formal_Derived_Type_Definition         |
4413                N_Formal_Discrete_Type_Definition        |
4414                N_Formal_Floating_Point_Definition       |
4415                N_Formal_Modular_Type_Definition         |
4416                N_Formal_Ordinary_Fixed_Point_Definition |
4417                N_Formal_Package_Declaration             |
4418                N_Formal_Private_Type_Definition         |
4419                N_Formal_Incomplete_Type_Definition      |
4420                N_Formal_Signed_Integer_Type_Definition  |
4421                N_Function_Call                          |
4422                N_Function_Specification                 |
4423                N_Generic_Association                    |
4424                N_Handled_Sequence_Of_Statements         |
4425                N_Identifier                             |
4426                N_In                                     |
4427                N_Index_Or_Discriminant_Constraint       |
4428                N_Indexed_Component                      |
4429                N_Integer_Literal                        |
4430                N_Iterator_Specification                 |
4431                N_Itype_Reference                        |
4432                N_Label                                  |
4433                N_Loop_Parameter_Specification           |
4434                N_Mod_Clause                             |
4435                N_Modular_Type_Definition                |
4436                N_Not_In                                 |
4437                N_Null                                   |
4438                N_Op_Abs                                 |
4439                N_Op_Add                                 |
4440                N_Op_And                                 |
4441                N_Op_Concat                              |
4442                N_Op_Divide                              |
4443                N_Op_Eq                                  |
4444                N_Op_Expon                               |
4445                N_Op_Ge                                  |
4446                N_Op_Gt                                  |
4447                N_Op_Le                                  |
4448                N_Op_Lt                                  |
4449                N_Op_Minus                               |
4450                N_Op_Mod                                 |
4451                N_Op_Multiply                            |
4452                N_Op_Ne                                  |
4453                N_Op_Not                                 |
4454                N_Op_Or                                  |
4455                N_Op_Plus                                |
4456                N_Op_Rem                                 |
4457                N_Op_Rotate_Left                         |
4458                N_Op_Rotate_Right                        |
4459                N_Op_Shift_Left                          |
4460                N_Op_Shift_Right                         |
4461                N_Op_Shift_Right_Arithmetic              |
4462                N_Op_Subtract                            |
4463                N_Op_Xor                                 |
4464                N_Operator_Symbol                        |
4465                N_Ordinary_Fixed_Point_Definition        |
4466                N_Others_Choice                          |
4467                N_Package_Specification                  |
4468                N_Parameter_Association                  |
4469                N_Parameter_Specification                |
4470                N_Pop_Constraint_Error_Label             |
4471                N_Pop_Program_Error_Label                |
4472                N_Pop_Storage_Error_Label                |
4473                N_Pragma_Argument_Association            |
4474                N_Procedure_Specification                |
4475                N_Protected_Definition                   |
4476                N_Push_Constraint_Error_Label            |
4477                N_Push_Program_Error_Label               |
4478                N_Push_Storage_Error_Label               |
4479                N_Qualified_Expression                   |
4480                N_Quantified_Expression                  |
4481                N_Raise_Expression                       |
4482                N_Range                                  |
4483                N_Range_Constraint                       |
4484                N_Real_Literal                           |
4485                N_Real_Range_Specification               |
4486                N_Record_Definition                      |
4487                N_Reference                              |
4488                N_SCIL_Dispatch_Table_Tag_Init           |
4489                N_SCIL_Dispatching_Call                  |
4490                N_SCIL_Membership_Test                   |
4491                N_Selected_Component                     |
4492                N_Signed_Integer_Type_Definition         |
4493                N_Single_Protected_Declaration           |
4494                N_Slice                                  |
4495                N_String_Literal                         |
4496                N_Subtype_Indication                     |
4497                N_Subunit                                |
4498                N_Task_Definition                        |
4499                N_Terminate_Alternative                  |
4500                N_Triggering_Alternative                 |
4501                N_Type_Conversion                        |
4502                N_Unchecked_Expression                   |
4503                N_Unchecked_Type_Conversion              |
4504                N_Unconstrained_Array_Definition         |
4505                N_Unused_At_End                          |
4506                N_Unused_At_Start                        |
4507                N_Variant                                |
4508                N_Variant_Part                           |
4509                N_Validate_Unchecked_Conversion          |
4510                N_With_Clause
4511             =>
4512                null;
4513 
4514          end case;
4515 
4516          --  If we fall through above tests, keep climbing tree
4517 
4518          N := P;
4519 
4520          if Nkind (Parent (N)) = N_Subunit then
4521 
4522             --  This is the proper body corresponding to a stub. Insertion must
4523             --  be done at the point of the stub, which is in the declarative
4524             --  part of the parent unit.
4525 
4526             P := Corresponding_Stub (Parent (N));
4527 
4528          else
4529             P := Parent (N);
4530          end if;
4531       end loop;
4532    end Insert_Actions;
4533 
4534    --  Version with check(s) suppressed
4535 
4536    procedure Insert_Actions
4537      (Assoc_Node  : Node_Id;
4538       Ins_Actions : List_Id;
4539       Suppress    : Check_Id)
4540    is
4541    begin
4542       if Suppress = All_Checks then
4543          declare
4544             Sva : constant Suppress_Array := Scope_Suppress.Suppress;
4545          begin
4546             Scope_Suppress.Suppress := (others => True);
4547             Insert_Actions (Assoc_Node, Ins_Actions);
4548             Scope_Suppress.Suppress := Sva;
4549          end;
4550 
4551       else
4552          declare
4553             Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
4554          begin
4555             Scope_Suppress.Suppress (Suppress) := True;
4556             Insert_Actions (Assoc_Node, Ins_Actions);
4557             Scope_Suppress.Suppress (Suppress) := Svg;
4558          end;
4559       end if;
4560    end Insert_Actions;
4561 
4562    --------------------------
4563    -- Insert_Actions_After --
4564    --------------------------
4565 
4566    procedure Insert_Actions_After
4567      (Assoc_Node  : Node_Id;
4568       Ins_Actions : List_Id)
4569    is
4570    begin
4571       if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then
4572          Store_After_Actions_In_Scope (Ins_Actions);
4573       else
4574          Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
4575       end if;
4576    end Insert_Actions_After;
4577 
4578    ------------------------
4579    -- Insert_Declaration --
4580    ------------------------
4581 
4582    procedure Insert_Declaration (N : Node_Id; Decl : Node_Id) is
4583       P : Node_Id;
4584 
4585    begin
4586       pragma Assert (Nkind (N) in N_Subexpr);
4587 
4588       --  Climb until we find a procedure or a package
4589 
4590       P := N;
4591       loop
4592          pragma Assert (Present (Parent (P)));
4593          P := Parent (P);
4594 
4595          if Is_List_Member (P) then
4596             exit when Nkind_In (Parent (P), N_Package_Specification,
4597                                             N_Subprogram_Body);
4598 
4599             --  Special handling for handled sequence of statements, we must
4600             --  insert in the statements not the exception handlers!
4601 
4602             if Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements then
4603                P := First (Statements (Parent (P)));
4604                exit;
4605             end if;
4606          end if;
4607       end loop;
4608 
4609       --  Now do the insertion
4610 
4611       Insert_Before (P, Decl);
4612       Analyze (Decl);
4613    end Insert_Declaration;
4614 
4615    ---------------------------------
4616    -- Insert_Library_Level_Action --
4617    ---------------------------------
4618 
4619    procedure Insert_Library_Level_Action (N : Node_Id) is
4620       Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
4621 
4622    begin
4623       Push_Scope (Cunit_Entity (Main_Unit));
4624       --  ??? should this be Current_Sem_Unit instead of Main_Unit?
4625 
4626       if No (Actions (Aux)) then
4627          Set_Actions (Aux, New_List (N));
4628       else
4629          Append (N, Actions (Aux));
4630       end if;
4631 
4632       Analyze (N);
4633       Pop_Scope;
4634    end Insert_Library_Level_Action;
4635 
4636    ----------------------------------
4637    -- Insert_Library_Level_Actions --
4638    ----------------------------------
4639 
4640    procedure Insert_Library_Level_Actions (L : List_Id) is
4641       Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
4642 
4643    begin
4644       if Is_Non_Empty_List (L) then
4645          Push_Scope (Cunit_Entity (Main_Unit));
4646          --  ??? should this be Current_Sem_Unit instead of Main_Unit?
4647 
4648          if No (Actions (Aux)) then
4649             Set_Actions (Aux, L);
4650             Analyze_List (L);
4651          else
4652             Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
4653          end if;
4654 
4655          Pop_Scope;
4656       end if;
4657    end Insert_Library_Level_Actions;
4658 
4659    ----------------------
4660    -- Inside_Init_Proc --
4661    ----------------------
4662 
4663    function Inside_Init_Proc return Boolean is
4664       S : Entity_Id;
4665 
4666    begin
4667       S := Current_Scope;
4668       while Present (S) and then S /= Standard_Standard loop
4669          if Is_Init_Proc (S) then
4670             return True;
4671          else
4672             S := Scope (S);
4673          end if;
4674       end loop;
4675 
4676       return False;
4677    end Inside_Init_Proc;
4678 
4679    ----------------------------
4680    -- Is_All_Null_Statements --
4681    ----------------------------
4682 
4683    function Is_All_Null_Statements (L : List_Id) return Boolean is
4684       Stm : Node_Id;
4685 
4686    begin
4687       Stm := First (L);
4688       while Present (Stm) loop
4689          if Nkind (Stm) /= N_Null_Statement then
4690             return False;
4691          end if;
4692 
4693          Next (Stm);
4694       end loop;
4695 
4696       return True;
4697    end Is_All_Null_Statements;
4698 
4699    --------------------------------------------------
4700    -- Is_Displacement_Of_Object_Or_Function_Result --
4701    --------------------------------------------------
4702 
4703    function Is_Displacement_Of_Object_Or_Function_Result
4704      (Obj_Id : Entity_Id) return Boolean
4705    is
4706       function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
4707       --  Determine if particular node denotes a controlled function call. The
4708       --  call may have been heavily expanded.
4709 
4710       function Is_Displace_Call (N : Node_Id) return Boolean;
4711       --  Determine whether a particular node is a call to Ada.Tags.Displace.
4712       --  The call might be nested within other actions such as conversions.
4713 
4714       function Is_Source_Object (N : Node_Id) return Boolean;
4715       --  Determine whether a particular node denotes a source object
4716 
4717       ---------------------------------
4718       -- Is_Controlled_Function_Call --
4719       ---------------------------------
4720 
4721       function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
4722          Expr : Node_Id := Original_Node (N);
4723 
4724       begin
4725          --  When a function call appears in Object.Operation format, the
4726          --  original representation has several possible forms depending on
4727          --  the availability and form of actual parameters:
4728 
4729          --    Obj.Func                    N_Selected_Component
4730          --    Obj.Func (Actual)           N_Indexed_Component
4731          --    Obj.Func (Formal => Actual) N_Function_Call, whose Name is an
4732          --                                N_Selected_Component
4733 
4734          case Nkind (Expr) is
4735             when N_Function_Call =>
4736                Expr := Name (Expr);
4737 
4738                --  Check for "Obj.Func (Formal => Actual)" case
4739 
4740                if Nkind (Expr) = N_Selected_Component then
4741                   Expr := Selector_Name (Expr);
4742                end if;
4743 
4744             --  "Obj.Func (Actual)" case
4745 
4746             when N_Indexed_Component =>
4747                Expr := Prefix (Expr);
4748 
4749                if Nkind (Expr) = N_Selected_Component then
4750                   Expr := Selector_Name (Expr);
4751                end if;
4752 
4753             --  "Obj.Func" case
4754 
4755             when N_Selected_Component =>
4756                Expr := Selector_Name (Expr);
4757 
4758             when others => null;
4759          end case;
4760 
4761          return
4762            Nkind_In (Expr, N_Expanded_Name, N_Identifier)
4763              and then Ekind (Entity (Expr)) = E_Function
4764              and then Needs_Finalization (Etype (Entity (Expr)));
4765       end Is_Controlled_Function_Call;
4766 
4767       ----------------------
4768       -- Is_Displace_Call --
4769       ----------------------
4770 
4771       function Is_Displace_Call (N : Node_Id) return Boolean is
4772          Call : Node_Id := N;
4773 
4774       begin
4775          --  Strip various actions which may precede a call to Displace
4776 
4777          loop
4778             if Nkind (Call) = N_Explicit_Dereference then
4779                Call := Prefix (Call);
4780 
4781             elsif Nkind_In (Call, N_Type_Conversion,
4782                                   N_Unchecked_Type_Conversion)
4783             then
4784                Call := Expression (Call);
4785 
4786             else
4787                exit;
4788             end if;
4789          end loop;
4790 
4791          return
4792            Present (Call)
4793              and then Nkind (Call) = N_Function_Call
4794              and then Is_RTE (Entity (Name (Call)), RE_Displace);
4795       end Is_Displace_Call;
4796 
4797       ----------------------
4798       -- Is_Source_Object --
4799       ----------------------
4800 
4801       function Is_Source_Object (N : Node_Id) return Boolean is
4802       begin
4803          return
4804            Present (N)
4805              and then Nkind (N) in N_Has_Entity
4806              and then Is_Object (Entity (N))
4807              and then Comes_From_Source (N);
4808       end Is_Source_Object;
4809 
4810       --  Local variables
4811 
4812       Decl      : constant Node_Id   := Parent (Obj_Id);
4813       Obj_Typ   : constant Entity_Id := Base_Type (Etype (Obj_Id));
4814       Orig_Decl : constant Node_Id   := Original_Node (Decl);
4815 
4816    --  Start of processing for Is_Displacement_Of_Object_Or_Function_Result
4817 
4818    begin
4819       --  Case 1:
4820 
4821       --     Obj : CW_Type := Function_Call (...);
4822 
4823       --  rewritten into:
4824 
4825       --     Tmp : ... := Function_Call (...)'reference;
4826       --     Obj : CW_Type renames (... Ada.Tags.Displace (Tmp));
4827 
4828       --  where the return type of the function and the class-wide type require
4829       --  dispatch table pointer displacement.
4830 
4831       --  Case 2:
4832 
4833       --     Obj : CW_Type := Src_Obj;
4834 
4835       --  rewritten into:
4836 
4837       --     Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
4838 
4839       --  where the type of the source object and the class-wide type require
4840       --  dispatch table pointer displacement.
4841 
4842       return
4843         Nkind (Decl) = N_Object_Renaming_Declaration
4844           and then Nkind (Orig_Decl) = N_Object_Declaration
4845           and then Comes_From_Source (Orig_Decl)
4846           and then Is_Class_Wide_Type (Obj_Typ)
4847           and then Is_Displace_Call (Renamed_Object (Obj_Id))
4848           and then
4849             (Is_Controlled_Function_Call (Expression (Orig_Decl))
4850               or else Is_Source_Object (Expression (Orig_Decl)));
4851    end Is_Displacement_Of_Object_Or_Function_Result;
4852 
4853    ------------------------------
4854    -- Is_Finalizable_Transient --
4855    ------------------------------
4856 
4857    function Is_Finalizable_Transient
4858      (Decl     : Node_Id;
4859       Rel_Node : Node_Id) return Boolean
4860    is
4861       Obj_Id  : constant Entity_Id := Defining_Identifier (Decl);
4862       Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
4863 
4864       function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
4865       --  Determine whether transient object Trans_Id is initialized either
4866       --  by a function call which returns an access type or simply renames
4867       --  another pointer.
4868 
4869       function Initialized_By_Aliased_BIP_Func_Call
4870         (Trans_Id : Entity_Id) return Boolean;
4871       --  Determine whether transient object Trans_Id is initialized by a
4872       --  build-in-place function call where the BIPalloc parameter is of
4873       --  value 1 and BIPaccess is not null. This case creates an aliasing
4874       --  between the returned value and the value denoted by BIPaccess.
4875 
4876       function Is_Aliased
4877         (Trans_Id   : Entity_Id;
4878          First_Stmt : Node_Id) return Boolean;
4879       --  Determine whether transient object Trans_Id has been renamed or
4880       --  aliased through 'reference in the statement list starting from
4881       --  First_Stmt.
4882 
4883       function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
4884       --  Determine whether transient object Trans_Id is allocated on the heap
4885 
4886       function Is_Iterated_Container
4887         (Trans_Id   : Entity_Id;
4888          First_Stmt : Node_Id) return Boolean;
4889       --  Determine whether transient object Trans_Id denotes a container which
4890       --  is in the process of being iterated in the statement list starting
4891       --  from First_Stmt.
4892 
4893       ---------------------------
4894       -- Initialized_By_Access --
4895       ---------------------------
4896 
4897       function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
4898          Expr : constant Node_Id := Expression (Parent (Trans_Id));
4899 
4900       begin
4901          return
4902            Present (Expr)
4903              and then Nkind (Expr) /= N_Reference
4904              and then Is_Access_Type (Etype (Expr));
4905       end Initialized_By_Access;
4906 
4907       ------------------------------------------
4908       -- Initialized_By_Aliased_BIP_Func_Call --
4909       ------------------------------------------
4910 
4911       function Initialized_By_Aliased_BIP_Func_Call
4912         (Trans_Id : Entity_Id) return Boolean
4913       is
4914          Call : Node_Id := Expression (Parent (Trans_Id));
4915 
4916       begin
4917          --  Build-in-place calls usually appear in 'reference format
4918 
4919          if Nkind (Call) = N_Reference then
4920             Call := Prefix (Call);
4921          end if;
4922 
4923          if Is_Build_In_Place_Function_Call (Call) then
4924             declare
4925                Access_Nam : Name_Id := No_Name;
4926                Access_OK  : Boolean := False;
4927                Actual     : Node_Id;
4928                Alloc_Nam  : Name_Id := No_Name;
4929                Alloc_OK   : Boolean := False;
4930                Formal     : Node_Id;
4931                Func_Id    : Entity_Id;
4932                Param      : Node_Id;
4933 
4934             begin
4935                --  Examine all parameter associations of the function call
4936 
4937                Param := First (Parameter_Associations (Call));
4938                while Present (Param) loop
4939                   if Nkind (Param) = N_Parameter_Association
4940                     and then Nkind (Selector_Name (Param)) = N_Identifier
4941                   then
4942                      Actual := Explicit_Actual_Parameter (Param);
4943                      Formal := Selector_Name (Param);
4944 
4945                      --  Construct the names of formals BIPaccess and BIPalloc
4946                      --  using the function name retrieved from an arbitrary
4947                      --  formal.
4948 
4949                      if Access_Nam = No_Name
4950                        and then Alloc_Nam = No_Name
4951                        and then Present (Entity (Formal))
4952                      then
4953                         Func_Id := Scope (Entity (Formal));
4954 
4955                         Access_Nam :=
4956                           New_External_Name (Chars (Func_Id),
4957                             BIP_Formal_Suffix (BIP_Object_Access));
4958 
4959                         Alloc_Nam :=
4960                           New_External_Name (Chars (Func_Id),
4961                             BIP_Formal_Suffix (BIP_Alloc_Form));
4962                      end if;
4963 
4964                      --  A match for BIPaccess => Temp has been found
4965 
4966                      if Chars (Formal) = Access_Nam
4967                        and then Nkind (Actual) /= N_Null
4968                      then
4969                         Access_OK := True;
4970                      end if;
4971 
4972                      --  A match for BIPalloc => 1 has been found
4973 
4974                      if Chars (Formal) = Alloc_Nam
4975                        and then Nkind (Actual) = N_Integer_Literal
4976                        and then Intval (Actual) = Uint_1
4977                      then
4978                         Alloc_OK := True;
4979                      end if;
4980                   end if;
4981 
4982                   Next (Param);
4983                end loop;
4984 
4985                return Access_OK and Alloc_OK;
4986             end;
4987          end if;
4988 
4989          return False;
4990       end Initialized_By_Aliased_BIP_Func_Call;
4991 
4992       ----------------
4993       -- Is_Aliased --
4994       ----------------
4995 
4996       function Is_Aliased
4997         (Trans_Id   : Entity_Id;
4998          First_Stmt : Node_Id) return Boolean
4999       is
5000          function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
5001          --  Given an object renaming declaration, retrieve the entity of the
5002          --  renamed name. Return Empty if the renamed name is anything other
5003          --  than a variable or a constant.
5004 
5005          -------------------------
5006          -- Find_Renamed_Object --
5007          -------------------------
5008 
5009          function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
5010             Ren_Obj : Node_Id := Empty;
5011 
5012             function Find_Object (N : Node_Id) return Traverse_Result;
5013             --  Try to detect an object which is either a constant or a
5014             --  variable.
5015 
5016             -----------------
5017             -- Find_Object --
5018             -----------------
5019 
5020             function Find_Object (N : Node_Id) return Traverse_Result is
5021             begin
5022                --  Stop the search once a constant or a variable has been
5023                --  detected.
5024 
5025                if Nkind (N) = N_Identifier
5026                  and then Present (Entity (N))
5027                  and then Ekind_In (Entity (N), E_Constant, E_Variable)
5028                then
5029                   Ren_Obj := Entity (N);
5030                   return Abandon;
5031                end if;
5032 
5033                return OK;
5034             end Find_Object;
5035 
5036             procedure Search is new Traverse_Proc (Find_Object);
5037 
5038             --  Local variables
5039 
5040             Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
5041 
5042          --  Start of processing for Find_Renamed_Object
5043 
5044          begin
5045             --  Actions related to dispatching calls may appear as renamings of
5046             --  tags. Do not process this type of renaming because it does not
5047             --  use the actual value of the object.
5048 
5049             if not Is_RTE (Typ, RE_Tag_Ptr) then
5050                Search (Name (Ren_Decl));
5051             end if;
5052 
5053             return Ren_Obj;
5054          end Find_Renamed_Object;
5055 
5056          --  Local variables
5057 
5058          Expr    : Node_Id;
5059          Ren_Obj : Entity_Id;
5060          Stmt    : Node_Id;
5061 
5062       --  Start of processing for Is_Aliased
5063 
5064       begin
5065          --  A controlled transient object is not considered aliased when it
5066          --  appears inside an expression_with_actions node even when there are
5067          --  explicit aliases of it:
5068 
5069          --    do
5070          --       Trans_Id : Ctrl_Typ ...;  --  controlled transient object
5071          --       Alias : ... := Trans_Id;  --  object is aliased
5072          --       Val : constant Boolean :=
5073          --               ... Alias ...;    --  aliasing ends
5074          --       <finalize Trans_Id>       --  object safe to finalize
5075          --    in Val end;
5076 
5077          --  Expansion ensures that all aliases are encapsulated in the actions
5078          --  list and do not leak to the expression by forcing the evaluation
5079          --  of the expression.
5080 
5081          if Nkind (Rel_Node) = N_Expression_With_Actions then
5082             return False;
5083 
5084          --  Otherwise examine the statements after the controlled transient
5085          --  object and look for various forms of aliasing.
5086 
5087          else
5088             Stmt := First_Stmt;
5089             while Present (Stmt) loop
5090                if Nkind (Stmt) = N_Object_Declaration then
5091                   Expr := Expression (Stmt);
5092 
5093                   --  Aliasing of the form:
5094                   --    Obj : ... := Trans_Id'reference;
5095 
5096                   if Present (Expr)
5097                     and then Nkind (Expr) = N_Reference
5098                     and then Nkind (Prefix (Expr)) = N_Identifier
5099                     and then Entity (Prefix (Expr)) = Trans_Id
5100                   then
5101                      return True;
5102                   end if;
5103 
5104                elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
5105                   Ren_Obj := Find_Renamed_Object (Stmt);
5106 
5107                   --  Aliasing of the form:
5108                   --    Obj : ... renames ... Trans_Id ...;
5109 
5110                   if Present (Ren_Obj) and then Ren_Obj = Trans_Id then
5111                      return True;
5112                   end if;
5113                end if;
5114 
5115                Next (Stmt);
5116             end loop;
5117 
5118             return False;
5119          end if;
5120       end Is_Aliased;
5121 
5122       ------------------
5123       -- Is_Allocated --
5124       ------------------
5125 
5126       function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
5127          Expr : constant Node_Id := Expression (Parent (Trans_Id));
5128       begin
5129          return
5130            Is_Access_Type (Etype (Trans_Id))
5131              and then Present (Expr)
5132              and then Nkind (Expr) = N_Allocator;
5133       end Is_Allocated;
5134 
5135       ---------------------------
5136       -- Is_Iterated_Container --
5137       ---------------------------
5138 
5139       function Is_Iterated_Container
5140         (Trans_Id   : Entity_Id;
5141          First_Stmt : Node_Id) return Boolean
5142       is
5143          Aspect : Node_Id;
5144          Call   : Node_Id;
5145          Iter   : Entity_Id;
5146          Param  : Node_Id;
5147          Stmt   : Node_Id;
5148          Typ    : Entity_Id;
5149 
5150       begin
5151          --  It is not possible to iterate over containers in non-Ada 2012 code
5152 
5153          if Ada_Version < Ada_2012 then
5154             return False;
5155          end if;
5156 
5157          Typ := Etype (Trans_Id);
5158 
5159          --  Handle access type created for secondary stack use
5160 
5161          if Is_Access_Type (Typ) then
5162             Typ := Designated_Type (Typ);
5163          end if;
5164 
5165          --  Look for aspect Default_Iterator. It may be part of a type
5166          --  declaration for a container, or inherited from a base type
5167          --  or parent type.
5168 
5169          Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator);
5170 
5171          if Present (Aspect) then
5172             Iter := Entity (Aspect);
5173 
5174             --  Examine the statements following the container object and
5175             --  look for a call to the default iterate routine where the
5176             --  first parameter is the transient. Such a call appears as:
5177 
5178             --     It : Access_To_CW_Iterator :=
5179             --            Iterate (Tran_Id.all, ...)'reference;
5180 
5181             Stmt := First_Stmt;
5182             while Present (Stmt) loop
5183 
5184                --  Detect an object declaration which is initialized by a
5185                --  secondary stack function call.
5186 
5187                if Nkind (Stmt) = N_Object_Declaration
5188                  and then Present (Expression (Stmt))
5189                  and then Nkind (Expression (Stmt)) = N_Reference
5190                  and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call
5191                then
5192                   Call := Prefix (Expression (Stmt));
5193 
5194                   --  The call must invoke the default iterate routine of
5195                   --  the container and the transient object must appear as
5196                   --  the first actual parameter. Skip any calls whose names
5197                   --  are not entities.
5198 
5199                   if Is_Entity_Name (Name (Call))
5200                     and then Entity (Name (Call)) = Iter
5201                     and then Present (Parameter_Associations (Call))
5202                   then
5203                      Param := First (Parameter_Associations (Call));
5204 
5205                      if Nkind (Param) = N_Explicit_Dereference
5206                        and then Entity (Prefix (Param)) = Trans_Id
5207                      then
5208                         return True;
5209                      end if;
5210                   end if;
5211                end if;
5212 
5213                Next (Stmt);
5214             end loop;
5215          end if;
5216 
5217          return False;
5218       end Is_Iterated_Container;
5219 
5220       --  Local variables
5221 
5222       Desig : Entity_Id := Obj_Typ;
5223 
5224    --  Start of processing for Is_Finalizable_Transient
5225 
5226    begin
5227       --  Handle access types
5228 
5229       if Is_Access_Type (Desig) then
5230          Desig := Available_View (Designated_Type (Desig));
5231       end if;
5232 
5233       return
5234         Ekind_In (Obj_Id, E_Constant, E_Variable)
5235           and then Needs_Finalization (Desig)
5236           and then Requires_Transient_Scope (Desig)
5237           and then Nkind (Rel_Node) /= N_Simple_Return_Statement
5238 
5239           --  Do not consider renamed or 'reference-d transient objects because
5240           --  the act of renaming extends the object's lifetime.
5241 
5242           and then not Is_Aliased (Obj_Id, Decl)
5243 
5244           --  Do not consider transient objects allocated on the heap since
5245           --  they are attached to a finalization master.
5246 
5247           and then not Is_Allocated (Obj_Id)
5248 
5249           --  If the transient object is a pointer, check that it is not
5250           --  initialized by a function that returns a pointer or acts as a
5251           --  renaming of another pointer.
5252 
5253           and then
5254             (not Is_Access_Type (Obj_Typ)
5255                or else not Initialized_By_Access (Obj_Id))
5256 
5257           --  Do not consider transient objects which act as indirect aliases
5258           --  of build-in-place function results.
5259 
5260           and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
5261 
5262           --  Do not consider conversions of tags to class-wide types
5263 
5264           and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
5265 
5266           --  Do not consider iterators because those are treated as normal
5267           --  controlled objects and are processed by the usual finalization
5268           --  machinery. This avoids the double finalization of an iterator.
5269 
5270           and then not Is_Iterator (Desig)
5271 
5272           --  Do not consider containers in the context of iterator loops. Such
5273           --  transient objects must exist for as long as the loop is around,
5274           --  otherwise any operation carried out by the iterator will fail.
5275 
5276           and then not Is_Iterated_Container (Obj_Id, Decl);
5277    end Is_Finalizable_Transient;
5278 
5279    ---------------------------------
5280    -- Is_Fully_Repped_Tagged_Type --
5281    ---------------------------------
5282 
5283    function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
5284       U    : constant Entity_Id := Underlying_Type (T);
5285       Comp : Entity_Id;
5286 
5287    begin
5288       if No (U) or else not Is_Tagged_Type (U) then
5289          return False;
5290       elsif Has_Discriminants (U) then
5291          return False;
5292       elsif not Has_Specified_Layout (U) then
5293          return False;
5294       end if;
5295 
5296       --  Here we have a tagged type, see if it has any unlayed out fields
5297       --  other than a possible tag and parent fields. If so, we return False.
5298 
5299       Comp := First_Component (U);
5300       while Present (Comp) loop
5301          if not Is_Tag (Comp)
5302            and then Chars (Comp) /= Name_uParent
5303            and then No (Component_Clause (Comp))
5304          then
5305             return False;
5306          else
5307             Next_Component (Comp);
5308          end if;
5309       end loop;
5310 
5311       --  All components are layed out
5312 
5313       return True;
5314    end Is_Fully_Repped_Tagged_Type;
5315 
5316    ----------------------------------
5317    -- Is_Library_Level_Tagged_Type --
5318    ----------------------------------
5319 
5320    function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
5321    begin
5322       return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ);
5323    end Is_Library_Level_Tagged_Type;
5324 
5325    --------------------------
5326    -- Is_Non_BIP_Func_Call --
5327    --------------------------
5328 
5329    function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
5330    begin
5331       --  The expected call is of the format
5332       --
5333       --    Func_Call'reference
5334 
5335       return
5336         Nkind (Expr) = N_Reference
5337           and then Nkind (Prefix (Expr)) = N_Function_Call
5338           and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
5339    end Is_Non_BIP_Func_Call;
5340 
5341    ------------------------------------
5342    -- Is_Object_Access_BIP_Func_Call --
5343    ------------------------------------
5344 
5345    function Is_Object_Access_BIP_Func_Call
5346       (Expr   : Node_Id;
5347        Obj_Id : Entity_Id) return Boolean
5348    is
5349       Access_Nam : Name_Id := No_Name;
5350       Actual     : Node_Id;
5351       Call       : Node_Id;
5352       Formal     : Node_Id;
5353       Param      : Node_Id;
5354 
5355    begin
5356       --  Build-in-place calls usually appear in 'reference format. Note that
5357       --  the accessibility check machinery may add an extra 'reference due to
5358       --  side effect removal.
5359 
5360       Call := Expr;
5361       while Nkind (Call) = N_Reference loop
5362          Call := Prefix (Call);
5363       end loop;
5364 
5365       if Nkind_In (Call, N_Qualified_Expression,
5366                          N_Unchecked_Type_Conversion)
5367       then
5368          Call := Expression (Call);
5369       end if;
5370 
5371       if Is_Build_In_Place_Function_Call (Call) then
5372 
5373          --  Examine all parameter associations of the function call
5374 
5375          Param := First (Parameter_Associations (Call));
5376          while Present (Param) loop
5377             if Nkind (Param) = N_Parameter_Association
5378               and then Nkind (Selector_Name (Param)) = N_Identifier
5379             then
5380                Formal := Selector_Name (Param);
5381                Actual := Explicit_Actual_Parameter (Param);
5382 
5383                --  Construct the name of formal BIPaccess. It is much easier to
5384                --  extract the name of the function using an arbitrary formal's
5385                --  scope rather than the Name field of Call.
5386 
5387                if Access_Nam = No_Name and then Present (Entity (Formal)) then
5388                   Access_Nam :=
5389                     New_External_Name
5390                       (Chars (Scope (Entity (Formal))),
5391                        BIP_Formal_Suffix (BIP_Object_Access));
5392                end if;
5393 
5394                --  A match for BIPaccess => Obj_Id'Unrestricted_Access has been
5395                --  found.
5396 
5397                if Chars (Formal) = Access_Nam
5398                  and then Nkind (Actual) = N_Attribute_Reference
5399                  and then Attribute_Name (Actual) = Name_Unrestricted_Access
5400                  and then Nkind (Prefix (Actual)) = N_Identifier
5401                  and then Entity (Prefix (Actual)) = Obj_Id
5402                then
5403                   return True;
5404                end if;
5405             end if;
5406 
5407             Next (Param);
5408          end loop;
5409       end if;
5410 
5411       return False;
5412    end Is_Object_Access_BIP_Func_Call;
5413 
5414    ----------------------------------
5415    -- Is_Possibly_Unaligned_Object --
5416    ----------------------------------
5417 
5418    function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
5419       T  : constant Entity_Id := Etype (N);
5420 
5421    begin
5422       --  If renamed object, apply test to underlying object
5423 
5424       if Is_Entity_Name (N)
5425         and then Is_Object (Entity (N))
5426         and then Present (Renamed_Object (Entity (N)))
5427       then
5428          return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
5429       end if;
5430 
5431       --  Tagged and controlled types and aliased types are always aligned, as
5432       --  are concurrent types.
5433 
5434       if Is_Aliased (T)
5435         or else Has_Controlled_Component (T)
5436         or else Is_Concurrent_Type (T)
5437         or else Is_Tagged_Type (T)
5438         or else Is_Controlled (T)
5439       then
5440          return False;
5441       end if;
5442 
5443       --  If this is an element of a packed array, may be unaligned
5444 
5445       if Is_Ref_To_Bit_Packed_Array (N) then
5446          return True;
5447       end if;
5448 
5449       --  Case of indexed component reference: test whether prefix is unaligned
5450 
5451       if Nkind (N) = N_Indexed_Component then
5452          return Is_Possibly_Unaligned_Object (Prefix (N));
5453 
5454       --  Case of selected component reference
5455 
5456       elsif Nkind (N) = N_Selected_Component then
5457          declare
5458             P : constant Node_Id   := Prefix (N);
5459             C : constant Entity_Id := Entity (Selector_Name (N));
5460             M : Nat;
5461             S : Nat;
5462 
5463          begin
5464             --  If component reference is for an array with non-static bounds,
5465             --  then it is always aligned: we can only process unaligned arrays
5466             --  with static bounds (more precisely compile time known bounds).
5467 
5468             if Is_Array_Type (T)
5469               and then not Compile_Time_Known_Bounds (T)
5470             then
5471                return False;
5472             end if;
5473 
5474             --  If component is aliased, it is definitely properly aligned
5475 
5476             if Is_Aliased (C) then
5477                return False;
5478             end if;
5479 
5480             --  If component is for a type implemented as a scalar, and the
5481             --  record is packed, and the component is other than the first
5482             --  component of the record, then the component may be unaligned.
5483 
5484             if Is_Packed (Etype (P))
5485               and then Represented_As_Scalar (Etype (C))
5486               and then First_Entity (Scope (C)) /= C
5487             then
5488                return True;
5489             end if;
5490 
5491             --  Compute maximum possible alignment for T
5492 
5493             --  If alignment is known, then that settles things
5494 
5495             if Known_Alignment (T) then
5496                M := UI_To_Int (Alignment (T));
5497 
5498             --  If alignment is not known, tentatively set max alignment
5499 
5500             else
5501                M := Ttypes.Maximum_Alignment;
5502 
5503                --  We can reduce this if the Esize is known since the default
5504                --  alignment will never be more than the smallest power of 2
5505                --  that does not exceed this Esize value.
5506 
5507                if Known_Esize (T) then
5508                   S := UI_To_Int (Esize (T));
5509 
5510                   while (M / 2) >= S loop
5511                      M := M / 2;
5512                   end loop;
5513                end if;
5514             end if;
5515 
5516             --  The following code is historical, it used to be present but it
5517             --  is too cautious, because the front-end does not know the proper
5518             --  default alignments for the target. Also, if the alignment is
5519             --  not known, the front end can't know in any case. If a copy is
5520             --  needed, the back-end will take care of it. This whole section
5521             --  including this comment can be removed later ???
5522 
5523             --  If the component reference is for a record that has a specified
5524             --  alignment, and we either know it is too small, or cannot tell,
5525             --  then the component may be unaligned.
5526 
5527             --  What is the following commented out code ???
5528 
5529             --  if Known_Alignment (Etype (P))
5530             --    and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
5531             --    and then M > Alignment (Etype (P))
5532             --  then
5533             --     return True;
5534             --  end if;
5535 
5536             --  Case of component clause present which may specify an
5537             --  unaligned position.
5538 
5539             if Present (Component_Clause (C)) then
5540 
5541                --  Otherwise we can do a test to make sure that the actual
5542                --  start position in the record, and the length, are both
5543                --  consistent with the required alignment. If not, we know
5544                --  that we are unaligned.
5545 
5546                declare
5547                   Align_In_Bits : constant Nat := M * System_Storage_Unit;
5548                begin
5549                   if Component_Bit_Offset (C) mod Align_In_Bits /= 0
5550                     or else Esize (C) mod Align_In_Bits /= 0
5551                   then
5552                      return True;
5553                   end if;
5554                end;
5555             end if;
5556 
5557             --  Otherwise, for a component reference, test prefix
5558 
5559             return Is_Possibly_Unaligned_Object (P);
5560          end;
5561 
5562       --  If not a component reference, must be aligned
5563 
5564       else
5565          return False;
5566       end if;
5567    end Is_Possibly_Unaligned_Object;
5568 
5569    ---------------------------------
5570    -- Is_Possibly_Unaligned_Slice --
5571    ---------------------------------
5572 
5573    function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
5574    begin
5575       --  Go to renamed object
5576 
5577       if Is_Entity_Name (N)
5578         and then Is_Object (Entity (N))
5579         and then Present (Renamed_Object (Entity (N)))
5580       then
5581          return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
5582       end if;
5583 
5584       --  The reference must be a slice
5585 
5586       if Nkind (N) /= N_Slice then
5587          return False;
5588       end if;
5589 
5590       --  We only need to worry if the target has strict alignment
5591 
5592       if not Target_Strict_Alignment then
5593          return False;
5594       end if;
5595 
5596       --  If it is a slice, then look at the array type being sliced
5597 
5598       declare
5599          Sarr : constant Node_Id := Prefix (N);
5600          --  Prefix of the slice, i.e. the array being sliced
5601 
5602          Styp : constant Entity_Id := Etype (Prefix (N));
5603          --  Type of the array being sliced
5604 
5605          Pref : Node_Id;
5606          Ptyp : Entity_Id;
5607 
5608       begin
5609          --  The problems arise if the array object that is being sliced
5610          --  is a component of a record or array, and we cannot guarantee
5611          --  the alignment of the array within its containing object.
5612 
5613          --  To investigate this, we look at successive prefixes to see
5614          --  if we have a worrisome indexed or selected component.
5615 
5616          Pref := Sarr;
5617          loop
5618             --  Case of array is part of an indexed component reference
5619 
5620             if Nkind (Pref) = N_Indexed_Component then
5621                Ptyp := Etype (Prefix (Pref));
5622 
5623                --  The only problematic case is when the array is packed, in
5624                --  which case we really know nothing about the alignment of
5625                --  individual components.
5626 
5627                if Is_Bit_Packed_Array (Ptyp) then
5628                   return True;
5629                end if;
5630 
5631             --  Case of array is part of a selected component reference
5632 
5633             elsif Nkind (Pref) = N_Selected_Component then
5634                Ptyp := Etype (Prefix (Pref));
5635 
5636                --  We are definitely in trouble if the record in question
5637                --  has an alignment, and either we know this alignment is
5638                --  inconsistent with the alignment of the slice, or we don't
5639                --  know what the alignment of the slice should be.
5640 
5641                if Known_Alignment (Ptyp)
5642                  and then (Unknown_Alignment (Styp)
5643                             or else Alignment (Styp) > Alignment (Ptyp))
5644                then
5645                   return True;
5646                end if;
5647 
5648                --  We are in potential trouble if the record type is packed.
5649                --  We could special case when we know that the array is the
5650                --  first component, but that's not such a simple case ???
5651 
5652                if Is_Packed (Ptyp) then
5653                   return True;
5654                end if;
5655 
5656                --  We are in trouble if there is a component clause, and
5657                --  either we do not know the alignment of the slice, or
5658                --  the alignment of the slice is inconsistent with the
5659                --  bit position specified by the component clause.
5660 
5661                declare
5662                   Field : constant Entity_Id := Entity (Selector_Name (Pref));
5663                begin
5664                   if Present (Component_Clause (Field))
5665                     and then
5666                       (Unknown_Alignment (Styp)
5667                         or else
5668                          (Component_Bit_Offset (Field) mod
5669                            (System_Storage_Unit * Alignment (Styp))) /= 0)
5670                   then
5671                      return True;
5672                   end if;
5673                end;
5674 
5675             --  For cases other than selected or indexed components we know we
5676             --  are OK, since no issues arise over alignment.
5677 
5678             else
5679                return False;
5680             end if;
5681 
5682             --  We processed an indexed component or selected component
5683             --  reference that looked safe, so keep checking prefixes.
5684 
5685             Pref := Prefix (Pref);
5686          end loop;
5687       end;
5688    end Is_Possibly_Unaligned_Slice;
5689 
5690    -------------------------------
5691    -- Is_Related_To_Func_Return --
5692    -------------------------------
5693 
5694    function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
5695       Expr : constant Node_Id := Related_Expression (Id);
5696    begin
5697       return
5698         Present (Expr)
5699           and then Nkind (Expr) = N_Explicit_Dereference
5700           and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
5701    end Is_Related_To_Func_Return;
5702 
5703    --------------------------------
5704    -- Is_Ref_To_Bit_Packed_Array --
5705    --------------------------------
5706 
5707    function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
5708       Result : Boolean;
5709       Expr   : Node_Id;
5710 
5711    begin
5712       if Is_Entity_Name (N)
5713         and then Is_Object (Entity (N))
5714         and then Present (Renamed_Object (Entity (N)))
5715       then
5716          return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
5717       end if;
5718 
5719       if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
5720          if Is_Bit_Packed_Array (Etype (Prefix (N))) then
5721             Result := True;
5722          else
5723             Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
5724          end if;
5725 
5726          if Result and then Nkind (N) = N_Indexed_Component then
5727             Expr := First (Expressions (N));
5728             while Present (Expr) loop
5729                Force_Evaluation (Expr);
5730                Next (Expr);
5731             end loop;
5732          end if;
5733 
5734          return Result;
5735 
5736       else
5737          return False;
5738       end if;
5739    end Is_Ref_To_Bit_Packed_Array;
5740 
5741    --------------------------------
5742    -- Is_Ref_To_Bit_Packed_Slice --
5743    --------------------------------
5744 
5745    function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
5746    begin
5747       if Nkind (N) = N_Type_Conversion then
5748          return Is_Ref_To_Bit_Packed_Slice (Expression (N));
5749 
5750       elsif Is_Entity_Name (N)
5751         and then Is_Object (Entity (N))
5752         and then Present (Renamed_Object (Entity (N)))
5753       then
5754          return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
5755 
5756       elsif Nkind (N) = N_Slice
5757         and then Is_Bit_Packed_Array (Etype (Prefix (N)))
5758       then
5759          return True;
5760 
5761       elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
5762          return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
5763 
5764       else
5765          return False;
5766       end if;
5767    end Is_Ref_To_Bit_Packed_Slice;
5768 
5769    -----------------------
5770    -- Is_Renamed_Object --
5771    -----------------------
5772 
5773    function Is_Renamed_Object (N : Node_Id) return Boolean is
5774       Pnod : constant Node_Id   := Parent (N);
5775       Kind : constant Node_Kind := Nkind (Pnod);
5776    begin
5777       if Kind = N_Object_Renaming_Declaration then
5778          return True;
5779       elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then
5780          return Is_Renamed_Object (Pnod);
5781       else
5782          return False;
5783       end if;
5784    end Is_Renamed_Object;
5785 
5786    --------------------------------------
5787    -- Is_Secondary_Stack_BIP_Func_Call --
5788    --------------------------------------
5789 
5790    function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
5791       Alloc_Nam : Name_Id := No_Name;
5792       Actual    : Node_Id;
5793       Call      : Node_Id := Expr;
5794       Formal    : Node_Id;
5795       Param     : Node_Id;
5796 
5797    begin
5798       --  Build-in-place calls usually appear in 'reference format. Note that
5799       --  the accessibility check machinery may add an extra 'reference due to
5800       --  side effect removal.
5801 
5802       while Nkind (Call) = N_Reference loop
5803          Call := Prefix (Call);
5804       end loop;
5805 
5806       if Nkind_In (Call, N_Qualified_Expression,
5807                          N_Unchecked_Type_Conversion)
5808       then
5809          Call := Expression (Call);
5810       end if;
5811 
5812       if Is_Build_In_Place_Function_Call (Call) then
5813 
5814          --  Examine all parameter associations of the function call
5815 
5816          Param := First (Parameter_Associations (Call));
5817          while Present (Param) loop
5818             if Nkind (Param) = N_Parameter_Association
5819               and then Nkind (Selector_Name (Param)) = N_Identifier
5820             then
5821                Formal := Selector_Name (Param);
5822                Actual := Explicit_Actual_Parameter (Param);
5823 
5824                --  Construct the name of formal BIPalloc. It is much easier to
5825                --  extract the name of the function using an arbitrary formal's
5826                --  scope rather than the Name field of Call.
5827 
5828                if Alloc_Nam = No_Name and then Present (Entity (Formal)) then
5829                   Alloc_Nam :=
5830                     New_External_Name
5831                       (Chars (Scope (Entity (Formal))),
5832                        BIP_Formal_Suffix (BIP_Alloc_Form));
5833                end if;
5834 
5835                --  A match for BIPalloc => 2 has been found
5836 
5837                if Chars (Formal) = Alloc_Nam
5838                  and then Nkind (Actual) = N_Integer_Literal
5839                  and then Intval (Actual) = Uint_2
5840                then
5841                   return True;
5842                end if;
5843             end if;
5844 
5845             Next (Param);
5846          end loop;
5847       end if;
5848 
5849       return False;
5850    end Is_Secondary_Stack_BIP_Func_Call;
5851 
5852    -------------------------------------
5853    -- Is_Tag_To_Class_Wide_Conversion --
5854    -------------------------------------
5855 
5856    function Is_Tag_To_Class_Wide_Conversion
5857      (Obj_Id : Entity_Id) return Boolean
5858    is
5859       Expr : constant Node_Id := Expression (Parent (Obj_Id));
5860 
5861    begin
5862       return
5863         Is_Class_Wide_Type (Etype (Obj_Id))
5864           and then Present (Expr)
5865           and then Nkind (Expr) = N_Unchecked_Type_Conversion
5866           and then Etype (Expression (Expr)) = RTE (RE_Tag);
5867    end Is_Tag_To_Class_Wide_Conversion;
5868 
5869    ----------------------------
5870    -- Is_Untagged_Derivation --
5871    ----------------------------
5872 
5873    function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
5874    begin
5875       return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
5876                or else
5877                  (Is_Private_Type (T) and then Present (Full_View (T))
5878                    and then not Is_Tagged_Type (Full_View (T))
5879                    and then Is_Derived_Type (Full_View (T))
5880                    and then Etype (Full_View (T)) /= T);
5881    end Is_Untagged_Derivation;
5882 
5883    ---------------------------
5884    -- Is_Volatile_Reference --
5885    ---------------------------
5886 
5887    function Is_Volatile_Reference (N : Node_Id) return Boolean is
5888    begin
5889       --  Only source references are to be treated as volatile, internally
5890       --  generated stuff cannot have volatile external effects.
5891 
5892       if not Comes_From_Source (N) then
5893          return False;
5894 
5895       --  Never true for reference to a type
5896 
5897       elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
5898          return False;
5899 
5900       --  Never true for a compile time known constant
5901 
5902       elsif Compile_Time_Known_Value (N) then
5903          return False;
5904 
5905       --  True if object reference with volatile type
5906 
5907       elsif Is_Volatile_Object (N) then
5908          return True;
5909 
5910       --  True if reference to volatile entity
5911 
5912       elsif Is_Entity_Name (N) then
5913          return Treat_As_Volatile (Entity (N));
5914 
5915       --  True for slice of volatile array
5916 
5917       elsif Nkind (N) = N_Slice then
5918          return Is_Volatile_Reference (Prefix (N));
5919 
5920       --  True if volatile component
5921 
5922       elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
5923          if (Is_Entity_Name (Prefix (N))
5924               and then Has_Volatile_Components (Entity (Prefix (N))))
5925            or else (Present (Etype (Prefix (N)))
5926                      and then Has_Volatile_Components (Etype (Prefix (N))))
5927          then
5928             return True;
5929          else
5930             return Is_Volatile_Reference (Prefix (N));
5931          end if;
5932 
5933       --  Otherwise false
5934 
5935       else
5936          return False;
5937       end if;
5938    end Is_Volatile_Reference;
5939 
5940    --------------------
5941    -- Kill_Dead_Code --
5942    --------------------
5943 
5944    procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
5945       W : Boolean := Warn;
5946       --  Set False if warnings suppressed
5947 
5948    begin
5949       if Present (N) then
5950          Remove_Warning_Messages (N);
5951 
5952          --  Generate warning if appropriate
5953 
5954          if W then
5955 
5956             --  We suppress the warning if this code is under control of an
5957             --  if statement, whose condition is a simple identifier, and
5958             --  either we are in an instance, or warnings off is set for this
5959             --  identifier. The reason for killing it in the instance case is
5960             --  that it is common and reasonable for code to be deleted in
5961             --  instances for various reasons.
5962 
5963             --  Could we use Is_Statically_Unevaluated here???
5964 
5965             if Nkind (Parent (N)) = N_If_Statement then
5966                declare
5967                   C : constant Node_Id := Condition (Parent (N));
5968                begin
5969                   if Nkind (C) = N_Identifier
5970                     and then
5971                       (In_Instance
5972                         or else (Present (Entity (C))
5973                                   and then Has_Warnings_Off (Entity (C))))
5974                   then
5975                      W := False;
5976                   end if;
5977                end;
5978             end if;
5979 
5980             --  Generate warning if not suppressed
5981 
5982             if W then
5983                Error_Msg_F
5984                  ("?t?this code can never be executed and has been deleted!",
5985                   N);
5986             end if;
5987          end if;
5988 
5989          --  Recurse into block statements and bodies to process declarations
5990          --  and statements.
5991 
5992          if Nkind (N) = N_Block_Statement
5993            or else Nkind (N) = N_Subprogram_Body
5994            or else Nkind (N) = N_Package_Body
5995          then
5996             Kill_Dead_Code (Declarations (N), False);
5997             Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
5998 
5999             if Nkind (N) = N_Subprogram_Body then
6000                Set_Is_Eliminated (Defining_Entity (N));
6001             end if;
6002 
6003          elsif Nkind (N) = N_Package_Declaration then
6004             Kill_Dead_Code (Visible_Declarations (Specification (N)));
6005             Kill_Dead_Code (Private_Declarations (Specification (N)));
6006 
6007             --  ??? After this point, Delete_Tree has been called on all
6008             --  declarations in Specification (N), so references to entities
6009             --  therein look suspicious.
6010 
6011             declare
6012                E : Entity_Id := First_Entity (Defining_Entity (N));
6013 
6014             begin
6015                while Present (E) loop
6016                   if Ekind (E) = E_Operator then
6017                      Set_Is_Eliminated (E);
6018                   end if;
6019 
6020                   Next_Entity (E);
6021                end loop;
6022             end;
6023 
6024          --  Recurse into composite statement to kill individual statements in
6025          --  particular instantiations.
6026 
6027          elsif Nkind (N) = N_If_Statement then
6028             Kill_Dead_Code (Then_Statements (N));
6029             Kill_Dead_Code (Elsif_Parts     (N));
6030             Kill_Dead_Code (Else_Statements (N));
6031 
6032          elsif Nkind (N) = N_Loop_Statement then
6033             Kill_Dead_Code (Statements (N));
6034 
6035          elsif Nkind (N) = N_Case_Statement then
6036             declare
6037                Alt : Node_Id;
6038             begin
6039                Alt := First (Alternatives (N));
6040                while Present (Alt) loop
6041                   Kill_Dead_Code (Statements (Alt));
6042                   Next (Alt);
6043                end loop;
6044             end;
6045 
6046          elsif Nkind (N) = N_Case_Statement_Alternative then
6047             Kill_Dead_Code (Statements (N));
6048 
6049          --  Deal with dead instances caused by deleting instantiations
6050 
6051          elsif Nkind (N) in N_Generic_Instantiation then
6052             Remove_Dead_Instance (N);
6053          end if;
6054       end if;
6055    end Kill_Dead_Code;
6056 
6057    --  Case where argument is a list of nodes to be killed
6058 
6059    procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
6060       N : Node_Id;
6061       W : Boolean;
6062 
6063    begin
6064       W := Warn;
6065 
6066       if Is_Non_Empty_List (L) then
6067          N := First (L);
6068          while Present (N) loop
6069             Kill_Dead_Code (N, W);
6070             W := False;
6071             Next (N);
6072          end loop;
6073       end if;
6074    end Kill_Dead_Code;
6075 
6076    ------------------------
6077    -- Known_Non_Negative --
6078    ------------------------
6079 
6080    function Known_Non_Negative (Opnd : Node_Id) return Boolean is
6081    begin
6082       if Is_OK_Static_Expression (Opnd) and then Expr_Value (Opnd) >= 0 then
6083          return True;
6084 
6085       else
6086          declare
6087             Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
6088          begin
6089             return
6090               Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
6091          end;
6092       end if;
6093    end Known_Non_Negative;
6094 
6095    --------------------
6096    -- Known_Non_Null --
6097    --------------------
6098 
6099    function Known_Non_Null (N : Node_Id) return Boolean is
6100    begin
6101       --  Checks for case where N is an entity reference
6102 
6103       if Is_Entity_Name (N) and then Present (Entity (N)) then
6104          declare
6105             E   : constant Entity_Id := Entity (N);
6106             Op  : Node_Kind;
6107             Val : Node_Id;
6108 
6109          begin
6110             --  First check if we are in decisive conditional
6111 
6112             Get_Current_Value_Condition (N, Op, Val);
6113 
6114             if Known_Null (Val) then
6115                if Op = N_Op_Eq then
6116                   return False;
6117                elsif Op = N_Op_Ne then
6118                   return True;
6119                end if;
6120             end if;
6121 
6122             --  If OK to do replacement, test Is_Known_Non_Null flag
6123 
6124             if OK_To_Do_Constant_Replacement (E) then
6125                return Is_Known_Non_Null (E);
6126 
6127             --  Otherwise if not safe to do replacement, then say so
6128 
6129             else
6130                return False;
6131             end if;
6132          end;
6133 
6134       --  True if access attribute
6135 
6136       elsif Nkind (N) = N_Attribute_Reference
6137         and then Nam_In (Attribute_Name (N), Name_Access,
6138                                              Name_Unchecked_Access,
6139                                              Name_Unrestricted_Access)
6140       then
6141          return True;
6142 
6143       --  True if allocator
6144 
6145       elsif Nkind (N) = N_Allocator then
6146          return True;
6147 
6148       --  For a conversion, true if expression is known non-null
6149 
6150       elsif Nkind (N) = N_Type_Conversion then
6151          return Known_Non_Null (Expression (N));
6152 
6153       --  Above are all cases where the value could be determined to be
6154       --  non-null. In all other cases, we don't know, so return False.
6155 
6156       else
6157          return False;
6158       end if;
6159    end Known_Non_Null;
6160 
6161    ----------------
6162    -- Known_Null --
6163    ----------------
6164 
6165    function Known_Null (N : Node_Id) return Boolean is
6166    begin
6167       --  Checks for case where N is an entity reference
6168 
6169       if Is_Entity_Name (N) and then Present (Entity (N)) then
6170          declare
6171             E   : constant Entity_Id := Entity (N);
6172             Op  : Node_Kind;
6173             Val : Node_Id;
6174 
6175          begin
6176             --  Constant null value is for sure null
6177 
6178             if Ekind (E) = E_Constant
6179               and then Known_Null (Constant_Value (E))
6180             then
6181                return True;
6182             end if;
6183 
6184             --  First check if we are in decisive conditional
6185 
6186             Get_Current_Value_Condition (N, Op, Val);
6187 
6188             if Known_Null (Val) then
6189                if Op = N_Op_Eq then
6190                   return True;
6191                elsif Op = N_Op_Ne then
6192                   return False;
6193                end if;
6194             end if;
6195 
6196             --  If OK to do replacement, test Is_Known_Null flag
6197 
6198             if OK_To_Do_Constant_Replacement (E) then
6199                return Is_Known_Null (E);
6200 
6201             --  Otherwise if not safe to do replacement, then say so
6202 
6203             else
6204                return False;
6205             end if;
6206          end;
6207 
6208       --  True if explicit reference to null
6209 
6210       elsif Nkind (N) = N_Null then
6211          return True;
6212 
6213       --  For a conversion, true if expression is known null
6214 
6215       elsif Nkind (N) = N_Type_Conversion then
6216          return Known_Null (Expression (N));
6217 
6218       --  Above are all cases where the value could be determined to be null.
6219       --  In all other cases, we don't know, so return False.
6220 
6221       else
6222          return False;
6223       end if;
6224    end Known_Null;
6225 
6226    -----------------------------
6227    -- Make_CW_Equivalent_Type --
6228    -----------------------------
6229 
6230    --  Create a record type used as an equivalent of any member of the class
6231    --  which takes its size from exp.
6232 
6233    --  Generate the following code:
6234 
6235    --   type Equiv_T is record
6236    --     _parent :  T (List of discriminant constraints taken from Exp);
6237    --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
6238    --   end Equiv_T;
6239    --
6240    --   ??? Note that this type does not guarantee same alignment as all
6241    --   derived types
6242 
6243    function Make_CW_Equivalent_Type
6244      (T : Entity_Id;
6245       E : Node_Id) return Entity_Id
6246    is
6247       Loc         : constant Source_Ptr := Sloc (E);
6248       Root_Typ    : constant Entity_Id  := Root_Type (T);
6249       List_Def    : constant List_Id    := Empty_List;
6250       Comp_List   : constant List_Id    := New_List;
6251       Equiv_Type  : Entity_Id;
6252       Range_Type  : Entity_Id;
6253       Str_Type    : Entity_Id;
6254       Constr_Root : Entity_Id;
6255       Sizexpr     : Node_Id;
6256 
6257    begin
6258       --  If the root type is already constrained, there are no discriminants
6259       --  in the expression.
6260 
6261       if not Has_Discriminants (Root_Typ)
6262         or else Is_Constrained (Root_Typ)
6263       then
6264          Constr_Root := Root_Typ;
6265 
6266          --  At this point in the expansion, non-limited view of the type
6267          --  must be available, otherwise the error will be reported later.
6268 
6269          if From_Limited_With (Constr_Root)
6270            and then Present (Non_Limited_View (Constr_Root))
6271          then
6272             Constr_Root := Non_Limited_View (Constr_Root);
6273          end if;
6274 
6275       else
6276          Constr_Root := Make_Temporary (Loc, 'R');
6277 
6278          --  subtype cstr__n is T (List of discr constraints taken from Exp)
6279 
6280          Append_To (List_Def,
6281            Make_Subtype_Declaration (Loc,
6282              Defining_Identifier => Constr_Root,
6283              Subtype_Indication  => Make_Subtype_From_Expr (E, Root_Typ)));
6284       end if;
6285 
6286       --  Generate the range subtype declaration
6287 
6288       Range_Type := Make_Temporary (Loc, 'G');
6289 
6290       if not Is_Interface (Root_Typ) then
6291 
6292          --  subtype rg__xx is
6293          --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
6294 
6295          Sizexpr :=
6296            Make_Op_Subtract (Loc,
6297              Left_Opnd =>
6298                Make_Attribute_Reference (Loc,
6299                  Prefix =>
6300                    OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
6301                  Attribute_Name => Name_Size),
6302              Right_Opnd =>
6303                Make_Attribute_Reference (Loc,
6304                  Prefix => New_Occurrence_Of (Constr_Root, Loc),
6305                  Attribute_Name => Name_Object_Size));
6306       else
6307          --  subtype rg__xx is
6308          --    Storage_Offset range 1 .. Expr'size / Storage_Unit
6309 
6310          Sizexpr :=
6311            Make_Attribute_Reference (Loc,
6312              Prefix =>
6313                OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
6314              Attribute_Name => Name_Size);
6315       end if;
6316 
6317       Set_Paren_Count (Sizexpr, 1);
6318 
6319       Append_To (List_Def,
6320         Make_Subtype_Declaration (Loc,
6321           Defining_Identifier => Range_Type,
6322           Subtype_Indication =>
6323             Make_Subtype_Indication (Loc,
6324               Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
6325               Constraint => Make_Range_Constraint (Loc,
6326                 Range_Expression =>
6327                   Make_Range (Loc,
6328                     Low_Bound => Make_Integer_Literal (Loc, 1),
6329                     High_Bound =>
6330                       Make_Op_Divide (Loc,
6331                         Left_Opnd => Sizexpr,
6332                         Right_Opnd => Make_Integer_Literal (Loc,
6333                             Intval => System_Storage_Unit)))))));
6334 
6335       --  subtype str__nn is Storage_Array (rg__x);
6336 
6337       Str_Type := Make_Temporary (Loc, 'S');
6338       Append_To (List_Def,
6339         Make_Subtype_Declaration (Loc,
6340           Defining_Identifier => Str_Type,
6341           Subtype_Indication =>
6342             Make_Subtype_Indication (Loc,
6343               Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc),
6344               Constraint =>
6345                 Make_Index_Or_Discriminant_Constraint (Loc,
6346                   Constraints =>
6347                     New_List (New_Occurrence_Of (Range_Type, Loc))))));
6348 
6349       --  type Equiv_T is record
6350       --    [ _parent : Tnn; ]
6351       --    E : Str_Type;
6352       --  end Equiv_T;
6353 
6354       Equiv_Type := Make_Temporary (Loc, 'T');
6355       Set_Ekind (Equiv_Type, E_Record_Type);
6356       Set_Parent_Subtype (Equiv_Type, Constr_Root);
6357 
6358       --  Set Is_Class_Wide_Equivalent_Type very early to trigger the special
6359       --  treatment for this type. In particular, even though _parent's type
6360       --  is a controlled type or contains controlled components, we do not
6361       --  want to set Has_Controlled_Component on it to avoid making it gain
6362       --  an unwanted _controller component.
6363 
6364       Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
6365 
6366       --  A class-wide equivalent type does not require initialization
6367 
6368       Set_Suppress_Initialization (Equiv_Type);
6369 
6370       if not Is_Interface (Root_Typ) then
6371          Append_To (Comp_List,
6372            Make_Component_Declaration (Loc,
6373              Defining_Identifier  =>
6374                Make_Defining_Identifier (Loc, Name_uParent),
6375              Component_Definition =>
6376                Make_Component_Definition (Loc,
6377                  Aliased_Present    => False,
6378                  Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc))));
6379       end if;
6380 
6381       Append_To (Comp_List,
6382         Make_Component_Declaration (Loc,
6383           Defining_Identifier  => Make_Temporary (Loc, 'C'),
6384           Component_Definition =>
6385             Make_Component_Definition (Loc,
6386               Aliased_Present    => False,
6387               Subtype_Indication => New_Occurrence_Of (Str_Type, Loc))));
6388 
6389       Append_To (List_Def,
6390         Make_Full_Type_Declaration (Loc,
6391           Defining_Identifier => Equiv_Type,
6392           Type_Definition     =>
6393             Make_Record_Definition (Loc,
6394               Component_List  =>
6395                 Make_Component_List (Loc,
6396                   Component_Items => Comp_List,
6397                   Variant_Part    => Empty))));
6398 
6399       --  Suppress all checks during the analysis of the expanded code to avoid
6400       --  the generation of spurious warnings under ZFP run-time.
6401 
6402       Insert_Actions (E, List_Def, Suppress => All_Checks);
6403       return Equiv_Type;
6404    end Make_CW_Equivalent_Type;
6405 
6406    -------------------------
6407    -- Make_Invariant_Call --
6408    -------------------------
6409 
6410    function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
6411       Loc     : constant Source_Ptr := Sloc (Expr);
6412       Typ     : constant Entity_Id  := Base_Type (Etype (Expr));
6413       Proc_Id : Entity_Id;
6414 
6415    begin
6416       pragma Assert (Has_Invariants (Typ));
6417 
6418       Proc_Id := Invariant_Procedure (Typ);
6419       pragma Assert (Present (Proc_Id));
6420 
6421       return
6422         Make_Procedure_Call_Statement (Loc,
6423           Name                   => New_Occurrence_Of (Proc_Id, Loc),
6424           Parameter_Associations => New_List (Relocate_Node (Expr)));
6425    end Make_Invariant_Call;
6426 
6427    ------------------------
6428    -- Make_Literal_Range --
6429    ------------------------
6430 
6431    function Make_Literal_Range
6432      (Loc         : Source_Ptr;
6433       Literal_Typ : Entity_Id) return Node_Id
6434    is
6435       Lo          : constant Node_Id :=
6436                       New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
6437       Index       : constant Entity_Id := Etype (Lo);
6438 
6439       Hi          : Node_Id;
6440       Length_Expr : constant Node_Id :=
6441                       Make_Op_Subtract (Loc,
6442                         Left_Opnd =>
6443                           Make_Integer_Literal (Loc,
6444                             Intval => String_Literal_Length (Literal_Typ)),
6445                         Right_Opnd =>
6446                           Make_Integer_Literal (Loc, 1));
6447 
6448    begin
6449       Set_Analyzed (Lo, False);
6450 
6451          if Is_Integer_Type (Index) then
6452             Hi :=
6453               Make_Op_Add (Loc,
6454                 Left_Opnd  => New_Copy_Tree (Lo),
6455                 Right_Opnd => Length_Expr);
6456          else
6457             Hi :=
6458               Make_Attribute_Reference (Loc,
6459                 Attribute_Name => Name_Val,
6460                 Prefix => New_Occurrence_Of (Index, Loc),
6461                 Expressions => New_List (
6462                  Make_Op_Add (Loc,
6463                    Left_Opnd =>
6464                      Make_Attribute_Reference (Loc,
6465                        Attribute_Name => Name_Pos,
6466                        Prefix => New_Occurrence_Of (Index, Loc),
6467                        Expressions => New_List (New_Copy_Tree (Lo))),
6468                   Right_Opnd => Length_Expr)));
6469          end if;
6470 
6471          return
6472            Make_Range (Loc,
6473              Low_Bound  => Lo,
6474              High_Bound => Hi);
6475    end Make_Literal_Range;
6476 
6477    --------------------------
6478    -- Make_Non_Empty_Check --
6479    --------------------------
6480 
6481    function Make_Non_Empty_Check
6482      (Loc : Source_Ptr;
6483       N   : Node_Id) return Node_Id
6484    is
6485    begin
6486       return
6487         Make_Op_Ne (Loc,
6488           Left_Opnd =>
6489             Make_Attribute_Reference (Loc,
6490               Attribute_Name => Name_Length,
6491               Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
6492           Right_Opnd =>
6493             Make_Integer_Literal (Loc, 0));
6494    end Make_Non_Empty_Check;
6495 
6496    -------------------------
6497    -- Make_Predicate_Call --
6498    -------------------------
6499 
6500    function Make_Predicate_Call
6501      (Typ  : Entity_Id;
6502       Expr : Node_Id;
6503       Mem  : Boolean := False) return Node_Id
6504    is
6505       Loc  : constant Source_Ptr := Sloc (Expr);
6506       Call : Node_Id;
6507       PFM  : Entity_Id;
6508 
6509       Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;
6510 
6511    begin
6512       pragma Assert (Present (Predicate_Function (Typ)));
6513 
6514       --  The related type may be subject to pragma Ghost. Set the mode now to
6515       --  ensure that the call is properly marked as Ghost.
6516 
6517       Set_Ghost_Mode_From_Entity (Typ);
6518 
6519       --  Call special membership version if requested and available
6520 
6521       if Mem then
6522          PFM := Predicate_Function_M (Typ);
6523 
6524          if Present (PFM) then
6525             Call :=
6526               Make_Function_Call (Loc,
6527                 Name                   => New_Occurrence_Of (PFM, Loc),
6528                 Parameter_Associations => New_List (Relocate_Node (Expr)));
6529 
6530             Ghost_Mode := Save_Ghost_Mode;
6531             return Call;
6532          end if;
6533       end if;
6534 
6535       --  Case of calling normal predicate function
6536 
6537       Call :=
6538         Make_Function_Call (Loc,
6539           Name                   =>
6540             New_Occurrence_Of (Predicate_Function (Typ), Loc),
6541           Parameter_Associations => New_List (Relocate_Node (Expr)));
6542 
6543       Ghost_Mode := Save_Ghost_Mode;
6544       return Call;
6545    end Make_Predicate_Call;
6546 
6547    --------------------------
6548    -- Make_Predicate_Check --
6549    --------------------------
6550 
6551    function Make_Predicate_Check
6552      (Typ  : Entity_Id;
6553       Expr : Node_Id) return Node_Id
6554    is
6555       procedure Replace_Subtype_Reference (N : Node_Id);
6556       --  Replace current occurrences of the subtype to which a dynamic
6557       --  predicate applies, by the expression that triggers a predicate
6558       --  check. This is needed for aspect Predicate_Failure, for which
6559       --  we do not generate a wrapper procedure, but simply modify the
6560       --  expression for the pragma of the predicate check.
6561 
6562       --------------------------------
6563       --  Replace_Subtype_Reference --
6564       --------------------------------
6565 
6566       procedure Replace_Subtype_Reference (N : Node_Id) is
6567       begin
6568          Rewrite (N, New_Copy_Tree (Expr));
6569 
6570          --  We want to treat the node as if it comes from source, so
6571          --  that ASIS will not ignore it.
6572 
6573          Set_Comes_From_Source (N, True);
6574       end Replace_Subtype_Reference;
6575 
6576       procedure Replace_Subtype_References is
6577         new Replace_Type_References_Generic (Replace_Subtype_Reference);
6578 
6579       --  Local variables
6580 
6581       Loc       : constant Source_Ptr := Sloc (Expr);
6582       Arg_List  : List_Id;
6583       Fail_Expr : Node_Id;
6584       Nam       : Name_Id;
6585 
6586    --  Start of processing for Make_Predicate_Check
6587 
6588    begin
6589       --  If predicate checks are suppressed, then return a null statement. For
6590       --  this call, we check only the scope setting. If the caller wants to
6591       --  check a specific entity's setting, they must do it manually.
6592 
6593       if Predicate_Checks_Suppressed (Empty) then
6594          return Make_Null_Statement (Loc);
6595       end if;
6596 
6597       --  Do not generate a check within an internal subprogram (stream
6598       --  functions and the like, including including predicate functions).
6599 
6600       if Within_Internal_Subprogram then
6601          return Make_Null_Statement (Loc);
6602       end if;
6603 
6604       --  Compute proper name to use, we need to get this right so that the
6605       --  right set of check policies apply to the Check pragma we are making.
6606 
6607       if Has_Dynamic_Predicate_Aspect (Typ) then
6608          Nam := Name_Dynamic_Predicate;
6609       elsif Has_Static_Predicate_Aspect (Typ) then
6610          Nam := Name_Static_Predicate;
6611       else
6612          Nam := Name_Predicate;
6613       end if;
6614 
6615       Arg_List := New_List (
6616         Make_Pragma_Argument_Association (Loc,
6617           Expression => Make_Identifier (Loc, Nam)),
6618         Make_Pragma_Argument_Association (Loc,
6619           Expression => Make_Predicate_Call (Typ, Expr)));
6620 
6621       --  If subtype has Predicate_Failure defined, add the correponding
6622       --  expression as an additional pragma parameter, after replacing
6623       --  current instances with the expression being checked.
6624 
6625       if Has_Aspect (Typ, Aspect_Predicate_Failure) then
6626          Fail_Expr :=
6627            New_Copy_Tree
6628              (Expression (Find_Aspect (Typ, Aspect_Predicate_Failure)));
6629          Replace_Subtype_References (Fail_Expr, Typ);
6630 
6631          Append_To (Arg_List,
6632            Make_Pragma_Argument_Association (Loc,
6633              Expression => Fail_Expr));
6634       end if;
6635 
6636       return
6637         Make_Pragma (Loc,
6638           Pragma_Identifier            => Make_Identifier (Loc, Name_Check),
6639           Pragma_Argument_Associations => Arg_List);
6640    end Make_Predicate_Check;
6641 
6642    ----------------------------
6643    -- Make_Subtype_From_Expr --
6644    ----------------------------
6645 
6646    --  1. If Expr is an unconstrained array expression, creates
6647    --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
6648 
6649    --  2. If Expr is a unconstrained discriminated type expression, creates
6650    --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
6651 
6652    --  3. If Expr is class-wide, creates an implicit class-wide subtype
6653 
6654    function Make_Subtype_From_Expr
6655      (E          : Node_Id;
6656       Unc_Typ    : Entity_Id;
6657       Related_Id : Entity_Id := Empty) return Node_Id
6658    is
6659       List_Constr : constant List_Id    := New_List;
6660       Loc         : constant Source_Ptr := Sloc (E);
6661       D           : Entity_Id;
6662       Full_Exp    : Node_Id;
6663       Full_Subtyp : Entity_Id;
6664       High_Bound  : Entity_Id;
6665       Index_Typ   : Entity_Id;
6666       Low_Bound   : Entity_Id;
6667       Priv_Subtyp : Entity_Id;
6668       Utyp        : Entity_Id;
6669 
6670    begin
6671       if Is_Private_Type (Unc_Typ)
6672         and then Has_Unknown_Discriminants (Unc_Typ)
6673       then
6674          --  The caller requests a unique external name for both the private
6675          --  and the full subtype.
6676 
6677          if Present (Related_Id) then
6678             Full_Subtyp :=
6679               Make_Defining_Identifier (Loc,
6680                 Chars => New_External_Name (Chars (Related_Id), 'C'));
6681             Priv_Subtyp :=
6682               Make_Defining_Identifier (Loc,
6683                 Chars => New_External_Name (Chars (Related_Id), 'P'));
6684 
6685          else
6686             Full_Subtyp := Make_Temporary (Loc, 'C');
6687             Priv_Subtyp := Make_Temporary (Loc, 'P');
6688          end if;
6689 
6690          --  Prepare the subtype completion. Use the base type to find the
6691          --  underlying type because the type may be a generic actual or an
6692          --  explicit subtype.
6693 
6694          Utyp := Underlying_Type (Base_Type (Unc_Typ));
6695 
6696          Full_Exp :=
6697            Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
6698          Set_Parent (Full_Exp, Parent (E));
6699 
6700          Insert_Action (E,
6701            Make_Subtype_Declaration (Loc,
6702              Defining_Identifier => Full_Subtyp,
6703              Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
6704 
6705          --  Define the dummy private subtype
6706 
6707          Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
6708          Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
6709          Set_Scope          (Priv_Subtyp, Full_Subtyp);
6710          Set_Is_Constrained (Priv_Subtyp);
6711          Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
6712          Set_Is_Itype       (Priv_Subtyp);
6713          Set_Associated_Node_For_Itype (Priv_Subtyp, E);
6714 
6715          if Is_Tagged_Type  (Priv_Subtyp) then
6716             Set_Class_Wide_Type
6717               (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
6718             Set_Direct_Primitive_Operations (Priv_Subtyp,
6719               Direct_Primitive_Operations (Unc_Typ));
6720          end if;
6721 
6722          Set_Full_View (Priv_Subtyp, Full_Subtyp);
6723 
6724          return New_Occurrence_Of (Priv_Subtyp, Loc);
6725 
6726       elsif Is_Array_Type (Unc_Typ) then
6727          Index_Typ := First_Index (Unc_Typ);
6728          for J in 1 .. Number_Dimensions (Unc_Typ) loop
6729 
6730             --  Capture the bounds of each index constraint in case the context
6731             --  is an object declaration of an unconstrained type initialized
6732             --  by a function call:
6733 
6734             --    Obj : Unconstr_Typ := Func_Call;
6735 
6736             --  This scenario requires secondary scope management and the index
6737             --  constraint cannot depend on the temporary used to capture the
6738             --  result of the function call.
6739 
6740             --    SS_Mark;
6741             --    Temp : Unconstr_Typ_Ptr := Func_Call'reference;
6742             --    subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last);
6743             --    Obj : S := Temp.all;
6744             --    SS_Release;  --  Temp is gone at this point, bounds of S are
6745             --                 --  non existent.
6746 
6747             --  Generate:
6748             --    Low_Bound : constant Base_Type (Index_Typ) := E'First (J);
6749 
6750             Low_Bound := Make_Temporary (Loc, 'B');
6751             Insert_Action (E,
6752               Make_Object_Declaration (Loc,
6753                 Defining_Identifier => Low_Bound,
6754                 Object_Definition   =>
6755                   New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
6756                 Constant_Present    => True,
6757                 Expression          =>
6758                   Make_Attribute_Reference (Loc,
6759                     Prefix         => Duplicate_Subexpr_No_Checks (E),
6760                     Attribute_Name => Name_First,
6761                     Expressions    => New_List (
6762                       Make_Integer_Literal (Loc, J)))));
6763 
6764             --  Generate:
6765             --    High_Bound : constant Base_Type (Index_Typ) := E'Last (J);
6766 
6767             High_Bound := Make_Temporary (Loc, 'B');
6768             Insert_Action (E,
6769               Make_Object_Declaration (Loc,
6770                 Defining_Identifier => High_Bound,
6771                 Object_Definition   =>
6772                   New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
6773                 Constant_Present    => True,
6774                 Expression          =>
6775                   Make_Attribute_Reference (Loc,
6776                     Prefix         => Duplicate_Subexpr_No_Checks (E),
6777                     Attribute_Name => Name_Last,
6778                     Expressions    => New_List (
6779                       Make_Integer_Literal (Loc, J)))));
6780 
6781             Append_To (List_Constr,
6782               Make_Range (Loc,
6783                 Low_Bound  => New_Occurrence_Of (Low_Bound,  Loc),
6784                 High_Bound => New_Occurrence_Of (High_Bound, Loc)));
6785 
6786             Index_Typ := Next_Index (Index_Typ);
6787          end loop;
6788 
6789       elsif Is_Class_Wide_Type (Unc_Typ) then
6790          declare
6791             CW_Subtype : Entity_Id;
6792             EQ_Typ     : Entity_Id := Empty;
6793 
6794          begin
6795             --  A class-wide equivalent type is not needed on VM targets
6796             --  because the VM back-ends handle the class-wide object
6797             --  initialization itself (and doesn't need or want the
6798             --  additional intermediate type to handle the assignment).
6799 
6800             if Expander_Active and then Tagged_Type_Expansion then
6801 
6802                --  If this is the class-wide type of a completion that is a
6803                --  record subtype, set the type of the class-wide type to be
6804                --  the full base type, for use in the expanded code for the
6805                --  equivalent type. Should this be done earlier when the
6806                --  completion is analyzed ???
6807 
6808                if Is_Private_Type (Etype (Unc_Typ))
6809                  and then
6810                    Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
6811                then
6812                   Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
6813                end if;
6814 
6815                EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
6816             end if;
6817 
6818             CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
6819             Set_Equivalent_Type (CW_Subtype, EQ_Typ);
6820             Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
6821 
6822             return New_Occurrence_Of (CW_Subtype, Loc);
6823          end;
6824 
6825       --  Indefinite record type with discriminants
6826 
6827       else
6828          D := First_Discriminant (Unc_Typ);
6829          while Present (D) loop
6830             Append_To (List_Constr,
6831               Make_Selected_Component (Loc,
6832                 Prefix        => Duplicate_Subexpr_No_Checks (E),
6833                 Selector_Name => New_Occurrence_Of (D, Loc)));
6834 
6835             Next_Discriminant (D);
6836          end loop;
6837       end if;
6838 
6839       return
6840         Make_Subtype_Indication (Loc,
6841           Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc),
6842           Constraint   =>
6843             Make_Index_Or_Discriminant_Constraint (Loc,
6844               Constraints => List_Constr));
6845    end Make_Subtype_From_Expr;
6846 
6847    ----------------------------
6848    -- Matching_Standard_Type --
6849    ----------------------------
6850 
6851    function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is
6852       pragma Assert (Is_Scalar_Type (Typ));
6853       Siz : constant Uint := Esize (Typ);
6854 
6855    begin
6856       --  Floating-point cases
6857 
6858       if Is_Floating_Point_Type (Typ) then
6859          if Siz <= Esize (Standard_Short_Float) then
6860             return Standard_Short_Float;
6861          elsif Siz <= Esize (Standard_Float) then
6862             return Standard_Float;
6863          elsif Siz <= Esize (Standard_Long_Float) then
6864             return Standard_Long_Float;
6865          elsif Siz <= Esize (Standard_Long_Long_Float) then
6866             return Standard_Long_Long_Float;
6867          else
6868             raise Program_Error;
6869          end if;
6870 
6871       --  Integer cases (includes fixed-point types)
6872 
6873       --  Unsigned integer cases (includes normal enumeration types)
6874 
6875       elsif Is_Unsigned_Type (Typ) then
6876          if Siz <= Esize (Standard_Short_Short_Unsigned) then
6877             return Standard_Short_Short_Unsigned;
6878          elsif Siz <= Esize (Standard_Short_Unsigned) then
6879             return Standard_Short_Unsigned;
6880          elsif Siz <= Esize (Standard_Unsigned) then
6881             return Standard_Unsigned;
6882          elsif Siz <= Esize (Standard_Long_Unsigned) then
6883             return Standard_Long_Unsigned;
6884          elsif Siz <= Esize (Standard_Long_Long_Unsigned) then
6885             return Standard_Long_Long_Unsigned;
6886          else
6887             raise Program_Error;
6888          end if;
6889 
6890       --  Signed integer cases
6891 
6892       else
6893          if Siz <= Esize (Standard_Short_Short_Integer) then
6894             return Standard_Short_Short_Integer;
6895          elsif Siz <= Esize (Standard_Short_Integer) then
6896             return Standard_Short_Integer;
6897          elsif Siz <= Esize (Standard_Integer) then
6898             return Standard_Integer;
6899          elsif Siz <= Esize (Standard_Long_Integer) then
6900             return Standard_Long_Integer;
6901          elsif Siz <= Esize (Standard_Long_Long_Integer) then
6902             return Standard_Long_Long_Integer;
6903          else
6904             raise Program_Error;
6905          end if;
6906       end if;
6907    end Matching_Standard_Type;
6908 
6909    -----------------------------
6910    -- May_Generate_Large_Temp --
6911    -----------------------------
6912 
6913    --  At the current time, the only types that we return False for (i.e. where
6914    --  we decide we know they cannot generate large temps) are ones where we
6915    --  know the size is 256 bits or less at compile time, and we are still not
6916    --  doing a thorough job on arrays and records ???
6917 
6918    function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
6919    begin
6920       if not Size_Known_At_Compile_Time (Typ) then
6921          return False;
6922 
6923       elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
6924          return False;
6925 
6926       elsif Is_Array_Type (Typ)
6927         and then Present (Packed_Array_Impl_Type (Typ))
6928       then
6929          return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ));
6930 
6931       --  We could do more here to find other small types ???
6932 
6933       else
6934          return True;
6935       end if;
6936    end May_Generate_Large_Temp;
6937 
6938    ------------------------
6939    -- Needs_Finalization --
6940    ------------------------
6941 
6942    function Needs_Finalization (T : Entity_Id) return Boolean is
6943       function Has_Some_Controlled_Component (Rec : Entity_Id) return Boolean;
6944       --  If type is not frozen yet, check explicitly among its components,
6945       --  because the Has_Controlled_Component flag is not necessarily set.
6946 
6947       -----------------------------------
6948       -- Has_Some_Controlled_Component --
6949       -----------------------------------
6950 
6951       function Has_Some_Controlled_Component
6952         (Rec : Entity_Id) return Boolean
6953       is
6954          Comp : Entity_Id;
6955 
6956       begin
6957          if Has_Controlled_Component (Rec) then
6958             return True;
6959 
6960          elsif not Is_Frozen (Rec) then
6961             if Is_Record_Type (Rec) then
6962                Comp := First_Entity (Rec);
6963 
6964                while Present (Comp) loop
6965                   if not Is_Type (Comp)
6966                     and then Needs_Finalization (Etype (Comp))
6967                   then
6968                      return True;
6969                   end if;
6970 
6971                   Next_Entity (Comp);
6972                end loop;
6973 
6974                return False;
6975 
6976             else
6977                return
6978                  Is_Array_Type (Rec)
6979                    and then Needs_Finalization (Component_Type (Rec));
6980             end if;
6981          else
6982             return False;
6983          end if;
6984       end Has_Some_Controlled_Component;
6985 
6986    --  Start of processing for Needs_Finalization
6987 
6988    begin
6989       --  Certain run-time configurations and targets do not provide support
6990       --  for controlled types.
6991 
6992       if Restriction_Active (No_Finalization) then
6993          return False;
6994 
6995       --  C++ types are not considered controlled. It is assumed that the
6996       --  non-Ada side will handle their clean up.
6997 
6998       elsif Convention (T) = Convention_CPP then
6999          return False;
7000 
7001       --  Never needs finalization if Disable_Controlled set
7002 
7003       elsif Disable_Controlled (T) then
7004          return False;
7005 
7006       elsif Is_Class_Wide_Type (T) and then Disable_Controlled (Etype (T)) then
7007          return False;
7008 
7009       else
7010          --  Class-wide types are treated as controlled because derivations
7011          --  from the root type can introduce controlled components.
7012 
7013          return Is_Class_Wide_Type (T)
7014              or else Is_Controlled (T)
7015              or else Has_Some_Controlled_Component (T)
7016              or else
7017                (Is_Concurrent_Type (T)
7018                  and then Present (Corresponding_Record_Type (T))
7019                  and then Needs_Finalization (Corresponding_Record_Type (T)));
7020       end if;
7021    end Needs_Finalization;
7022 
7023    ----------------------------
7024    -- Needs_Constant_Address --
7025    ----------------------------
7026 
7027    function Needs_Constant_Address
7028      (Decl : Node_Id;
7029       Typ  : Entity_Id) return Boolean
7030    is
7031    begin
7032 
7033       --  If we have no initialization of any kind, then we don't need to place
7034       --  any restrictions on the address clause, because the object will be
7035       --  elaborated after the address clause is evaluated. This happens if the
7036       --  declaration has no initial expression, or the type has no implicit
7037       --  initialization, or the object is imported.
7038 
7039       --  The same holds for all initialized scalar types and all access types.
7040       --  Packed bit arrays of size up to 64 are represented using a modular
7041       --  type with an initialization (to zero) and can be processed like other
7042       --  initialized scalar types.
7043 
7044       --  If the type is controlled, code to attach the object to a
7045       --  finalization chain is generated at the point of declaration, and
7046       --  therefore the elaboration of the object cannot be delayed: the
7047       --  address expression must be a constant.
7048 
7049       if No (Expression (Decl))
7050         and then not Needs_Finalization (Typ)
7051         and then
7052           (not Has_Non_Null_Base_Init_Proc (Typ)
7053             or else Is_Imported (Defining_Identifier (Decl)))
7054       then
7055          return False;
7056 
7057       elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
7058         or else Is_Access_Type (Typ)
7059         or else
7060           (Is_Bit_Packed_Array (Typ)
7061             and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)))
7062       then
7063          return False;
7064 
7065       else
7066 
7067          --  Otherwise, we require the address clause to be constant because
7068          --  the call to the initialization procedure (or the attach code) has
7069          --  to happen at the point of the declaration.
7070 
7071          --  Actually the IP call has been moved to the freeze actions anyway,
7072          --  so maybe we can relax this restriction???
7073 
7074          return True;
7075       end if;
7076    end Needs_Constant_Address;
7077 
7078    ----------------------------
7079    -- New_Class_Wide_Subtype --
7080    ----------------------------
7081 
7082    function New_Class_Wide_Subtype
7083      (CW_Typ : Entity_Id;
7084       N      : Node_Id) return Entity_Id
7085    is
7086       Res       : constant Entity_Id := Create_Itype (E_Void, N);
7087       Res_Name  : constant Name_Id   := Chars (Res);
7088       Res_Scope : constant Entity_Id := Scope (Res);
7089 
7090    begin
7091       Copy_Node (CW_Typ, Res);
7092       Set_Comes_From_Source (Res, False);
7093       Set_Sloc (Res, Sloc (N));
7094       Set_Is_Itype (Res);
7095       Set_Associated_Node_For_Itype (Res, N);
7096       Set_Is_Public (Res, False);   --  By default, may be changed below.
7097       Set_Public_Status (Res);
7098       Set_Chars (Res, Res_Name);
7099       Set_Scope (Res, Res_Scope);
7100       Set_Ekind (Res, E_Class_Wide_Subtype);
7101       Set_Next_Entity (Res, Empty);
7102       Set_Etype (Res, Base_Type (CW_Typ));
7103       Set_Is_Frozen (Res, False);
7104       Set_Freeze_Node (Res, Empty);
7105       return (Res);
7106    end New_Class_Wide_Subtype;
7107 
7108    --------------------------------
7109    -- Non_Limited_Designated_Type --
7110    ---------------------------------
7111 
7112    function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
7113       Desig : constant Entity_Id := Designated_Type (T);
7114    begin
7115       if Has_Non_Limited_View (Desig) then
7116          return Non_Limited_View (Desig);
7117       else
7118          return Desig;
7119       end if;
7120    end Non_Limited_Designated_Type;
7121 
7122    -----------------------------------
7123    -- OK_To_Do_Constant_Replacement --
7124    -----------------------------------
7125 
7126    function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
7127       ES : constant Entity_Id := Scope (E);
7128       CS : Entity_Id;
7129 
7130    begin
7131       --  Do not replace statically allocated objects, because they may be
7132       --  modified outside the current scope.
7133 
7134       if Is_Statically_Allocated (E) then
7135          return False;
7136 
7137       --  Do not replace aliased or volatile objects, since we don't know what
7138       --  else might change the value.
7139 
7140       elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
7141          return False;
7142 
7143       --  Debug flag -gnatdM disconnects this optimization
7144 
7145       elsif Debug_Flag_MM then
7146          return False;
7147 
7148       --  Otherwise check scopes
7149 
7150       else
7151          CS := Current_Scope;
7152 
7153          loop
7154             --  If we are in right scope, replacement is safe
7155 
7156             if CS = ES then
7157                return True;
7158 
7159             --  Packages do not affect the determination of safety
7160 
7161             elsif Ekind (CS) = E_Package then
7162                exit when CS = Standard_Standard;
7163                CS := Scope (CS);
7164 
7165             --  Blocks do not affect the determination of safety
7166 
7167             elsif Ekind (CS) = E_Block then
7168                CS := Scope (CS);
7169 
7170             --  Loops do not affect the determination of safety. Note that we
7171             --  kill all current values on entry to a loop, so we are just
7172             --  talking about processing within a loop here.
7173 
7174             elsif Ekind (CS) = E_Loop then
7175                CS := Scope (CS);
7176 
7177             --  Otherwise, the reference is dubious, and we cannot be sure that
7178             --  it is safe to do the replacement.
7179 
7180             else
7181                exit;
7182             end if;
7183          end loop;
7184 
7185          return False;
7186       end if;
7187    end OK_To_Do_Constant_Replacement;
7188 
7189    ------------------------------------
7190    -- Possible_Bit_Aligned_Component --
7191    ------------------------------------
7192 
7193    function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
7194    begin
7195       --  Do not process an unanalyzed node because it is not yet decorated and
7196       --  most checks performed below will fail.
7197 
7198       if not Analyzed (N) then
7199          return False;
7200       end if;
7201 
7202       case Nkind (N) is
7203 
7204          --  Case of indexed component
7205 
7206          when N_Indexed_Component =>
7207             declare
7208                P    : constant Node_Id   := Prefix (N);
7209                Ptyp : constant Entity_Id := Etype (P);
7210 
7211             begin
7212                --  If we know the component size and it is less than 64, then
7213                --  we are definitely OK. The back end always does assignment of
7214                --  misaligned small objects correctly.
7215 
7216                if Known_Static_Component_Size (Ptyp)
7217                  and then Component_Size (Ptyp) <= 64
7218                then
7219                   return False;
7220 
7221                --  Otherwise, we need to test the prefix, to see if we are
7222                --  indexing from a possibly unaligned component.
7223 
7224                else
7225                   return Possible_Bit_Aligned_Component (P);
7226                end if;
7227             end;
7228 
7229          --  Case of selected component
7230 
7231          when N_Selected_Component =>
7232             declare
7233                P    : constant Node_Id   := Prefix (N);
7234                Comp : constant Entity_Id := Entity (Selector_Name (N));
7235 
7236             begin
7237                --  If there is no component clause, then we are in the clear
7238                --  since the back end will never misalign a large component
7239                --  unless it is forced to do so. In the clear means we need
7240                --  only the recursive test on the prefix.
7241 
7242                if Component_May_Be_Bit_Aligned (Comp) then
7243                   return True;
7244                else
7245                   return Possible_Bit_Aligned_Component (P);
7246                end if;
7247             end;
7248 
7249          --  For a slice, test the prefix, if that is possibly misaligned,
7250          --  then for sure the slice is.
7251 
7252          when N_Slice =>
7253             return Possible_Bit_Aligned_Component (Prefix (N));
7254 
7255          --  For an unchecked conversion, check whether the expression may
7256          --  be bit-aligned.
7257 
7258          when N_Unchecked_Type_Conversion =>
7259             return Possible_Bit_Aligned_Component (Expression (N));
7260 
7261          --  If we have none of the above, it means that we have fallen off the
7262          --  top testing prefixes recursively, and we now have a stand alone
7263          --  object, where we don't have a problem, unless this is a renaming,
7264          --  in which case we need to look into the renamed object.
7265 
7266          when others =>
7267             if Is_Entity_Name (N)
7268               and then Present (Renamed_Object (Entity (N)))
7269             then
7270                return
7271                  Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
7272             else
7273                return False;
7274             end if;
7275 
7276       end case;
7277    end Possible_Bit_Aligned_Component;
7278 
7279    -----------------------------------------------
7280    -- Process_Statements_For_Controlled_Objects --
7281    -----------------------------------------------
7282 
7283    procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
7284       Loc : constant Source_Ptr := Sloc (N);
7285 
7286       function Are_Wrapped (L : List_Id) return Boolean;
7287       --  Determine whether list L contains only one statement which is a block
7288 
7289       function Wrap_Statements_In_Block
7290         (L    : List_Id;
7291          Scop : Entity_Id := Current_Scope) return Node_Id;
7292       --  Given a list of statements L, wrap it in a block statement and return
7293       --  the generated node. Scop is either the current scope or the scope of
7294       --  the context (if applicable).
7295 
7296       -----------------
7297       -- Are_Wrapped --
7298       -----------------
7299 
7300       function Are_Wrapped (L : List_Id) return Boolean is
7301          Stmt : constant Node_Id := First (L);
7302       begin
7303          return
7304            Present (Stmt)
7305              and then No (Next (Stmt))
7306              and then Nkind (Stmt) = N_Block_Statement;
7307       end Are_Wrapped;
7308 
7309       ------------------------------
7310       -- Wrap_Statements_In_Block --
7311       ------------------------------
7312 
7313       function Wrap_Statements_In_Block
7314         (L    : List_Id;
7315          Scop : Entity_Id := Current_Scope) return Node_Id
7316       is
7317          Block_Id  : Entity_Id;
7318          Block_Nod : Node_Id;
7319          Iter_Loop : Entity_Id;
7320 
7321       begin
7322          Block_Nod :=
7323            Make_Block_Statement (Loc,
7324              Declarations               => No_List,
7325              Handled_Statement_Sequence =>
7326                Make_Handled_Sequence_Of_Statements (Loc,
7327                  Statements => L));
7328 
7329          --  Create a label for the block in case the block needs to manage the
7330          --  secondary stack. A label allows for flag Uses_Sec_Stack to be set.
7331 
7332          Add_Block_Identifier (Block_Nod, Block_Id);
7333 
7334          --  When wrapping the statements of an iterator loop, check whether
7335          --  the loop requires secondary stack management and if so, propagate
7336          --  the appropriate flags to the block. This ensures that the cursor
7337          --  is properly cleaned up at each iteration of the loop.
7338 
7339          Iter_Loop := Find_Enclosing_Iterator_Loop (Scop);
7340 
7341          if Present (Iter_Loop) then
7342             Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop));
7343 
7344             --  Secondary stack reclamation is suppressed when the associated
7345             --  iterator loop contains a return statement which uses the stack.
7346 
7347             Set_Sec_Stack_Needed_For_Return
7348               (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop));
7349          end if;
7350 
7351          return Block_Nod;
7352       end Wrap_Statements_In_Block;
7353 
7354       --  Local variables
7355 
7356       Block : Node_Id;
7357 
7358    --  Start of processing for Process_Statements_For_Controlled_Objects
7359 
7360    begin
7361       --  Whenever a non-handled statement list is wrapped in a block, the
7362       --  block must be explicitly analyzed to redecorate all entities in the
7363       --  list and ensure that a finalizer is properly built.
7364 
7365       case Nkind (N) is
7366          when N_Elsif_Part             |
7367               N_If_Statement           |
7368               N_Conditional_Entry_Call |
7369               N_Selective_Accept       =>
7370 
7371             --  Check the "then statements" for elsif parts and if statements
7372 
7373             if Nkind_In (N, N_Elsif_Part, N_If_Statement)
7374               and then not Is_Empty_List (Then_Statements (N))
7375               and then not Are_Wrapped (Then_Statements (N))
7376               and then Requires_Cleanup_Actions
7377                          (Then_Statements (N), False, False)
7378             then
7379                Block := Wrap_Statements_In_Block (Then_Statements (N));
7380                Set_Then_Statements (N, New_List (Block));
7381 
7382                Analyze (Block);
7383             end if;
7384 
7385             --  Check the "else statements" for conditional entry calls, if
7386             --  statements and selective accepts.
7387 
7388             if Nkind_In (N, N_Conditional_Entry_Call,
7389                             N_If_Statement,
7390                             N_Selective_Accept)
7391               and then not Is_Empty_List (Else_Statements (N))
7392               and then not Are_Wrapped (Else_Statements (N))
7393               and then Requires_Cleanup_Actions
7394                          (Else_Statements (N), False, False)
7395             then
7396                Block := Wrap_Statements_In_Block (Else_Statements (N));
7397                Set_Else_Statements (N, New_List (Block));
7398 
7399                Analyze (Block);
7400             end if;
7401 
7402          when N_Abortable_Part             |
7403               N_Accept_Alternative         |
7404               N_Case_Statement_Alternative |
7405               N_Delay_Alternative          |
7406               N_Entry_Call_Alternative     |
7407               N_Exception_Handler          |
7408               N_Loop_Statement             |
7409               N_Triggering_Alternative     =>
7410 
7411             if not Is_Empty_List (Statements (N))
7412               and then not Are_Wrapped (Statements (N))
7413               and then Requires_Cleanup_Actions (Statements (N), False, False)
7414             then
7415                if Nkind (N) = N_Loop_Statement
7416                  and then Present (Identifier (N))
7417                then
7418                   Block :=
7419                     Wrap_Statements_In_Block
7420                       (L    => Statements (N),
7421                        Scop => Entity (Identifier (N)));
7422                else
7423                   Block := Wrap_Statements_In_Block (Statements (N));
7424                end if;
7425 
7426                Set_Statements (N, New_List (Block));
7427                Analyze (Block);
7428             end if;
7429 
7430          when others =>
7431             null;
7432       end case;
7433    end Process_Statements_For_Controlled_Objects;
7434 
7435    ------------------
7436    -- Power_Of_Two --
7437    ------------------
7438 
7439    function Power_Of_Two (N : Node_Id) return Nat is
7440       Typ : constant Entity_Id := Etype (N);
7441       pragma Assert (Is_Integer_Type (Typ));
7442 
7443       Siz : constant Nat := UI_To_Int (Esize (Typ));
7444       Val : Uint;
7445 
7446    begin
7447       if not Compile_Time_Known_Value (N) then
7448          return 0;
7449 
7450       else
7451          Val := Expr_Value (N);
7452          for J in 1 .. Siz - 1 loop
7453             if Val = Uint_2 ** J then
7454                return J;
7455             end if;
7456          end loop;
7457 
7458          return 0;
7459       end if;
7460    end Power_Of_Two;
7461 
7462    ----------------------
7463    -- Remove_Init_Call --
7464    ----------------------
7465 
7466    function Remove_Init_Call
7467      (Var        : Entity_Id;
7468       Rep_Clause : Node_Id) return Node_Id
7469    is
7470       Par : constant Node_Id   := Parent (Var);
7471       Typ : constant Entity_Id := Etype (Var);
7472 
7473       Init_Proc : Entity_Id;
7474       --  Initialization procedure for Typ
7475 
7476       function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
7477       --  Look for init call for Var starting at From and scanning the
7478       --  enclosing list until Rep_Clause or the end of the list is reached.
7479 
7480       ----------------------------
7481       -- Find_Init_Call_In_List --
7482       ----------------------------
7483 
7484       function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
7485          Init_Call : Node_Id;
7486 
7487       begin
7488          Init_Call := From;
7489          while Present (Init_Call) and then Init_Call /= Rep_Clause loop
7490             if Nkind (Init_Call) = N_Procedure_Call_Statement
7491               and then Is_Entity_Name (Name (Init_Call))
7492               and then Entity (Name (Init_Call)) = Init_Proc
7493             then
7494                return Init_Call;
7495             end if;
7496 
7497             Next (Init_Call);
7498          end loop;
7499 
7500          return Empty;
7501       end Find_Init_Call_In_List;
7502 
7503       Init_Call : Node_Id;
7504 
7505    --  Start of processing for Find_Init_Call
7506 
7507    begin
7508       if Present (Initialization_Statements (Var)) then
7509          Init_Call := Initialization_Statements (Var);
7510          Set_Initialization_Statements (Var, Empty);
7511 
7512       elsif not Has_Non_Null_Base_Init_Proc (Typ) then
7513 
7514          --  No init proc for the type, so obviously no call to be found
7515 
7516          return Empty;
7517 
7518       else
7519          --  We might be able to handle other cases below by just properly
7520          --  setting Initialization_Statements at the point where the init proc
7521          --  call is generated???
7522 
7523          Init_Proc := Base_Init_Proc (Typ);
7524 
7525          --  First scan the list containing the declaration of Var
7526 
7527          Init_Call := Find_Init_Call_In_List (From => Next (Par));
7528 
7529          --  If not found, also look on Var's freeze actions list, if any,
7530          --  since the init call may have been moved there (case of an address
7531          --  clause applying to Var).
7532 
7533          if No (Init_Call) and then Present (Freeze_Node (Var)) then
7534             Init_Call :=
7535               Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
7536          end if;
7537 
7538          --  If the initialization call has actuals that use the secondary
7539          --  stack, the call may have been wrapped into a temporary block, in
7540          --  which case the block itself has to be removed.
7541 
7542          if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
7543             declare
7544                Blk : constant Node_Id := Next (Par);
7545             begin
7546                if Present
7547                     (Find_Init_Call_In_List
7548                       (First (Statements (Handled_Statement_Sequence (Blk)))))
7549                then
7550                   Init_Call := Blk;
7551                end if;
7552             end;
7553          end if;
7554       end if;
7555 
7556       if Present (Init_Call) then
7557          Remove (Init_Call);
7558       end if;
7559       return Init_Call;
7560    end Remove_Init_Call;
7561 
7562    -------------------------
7563    -- Remove_Side_Effects --
7564    -------------------------
7565 
7566    procedure Remove_Side_Effects
7567      (Exp                : Node_Id;
7568       Name_Req           : Boolean   := False;
7569       Renaming_Req       : Boolean   := False;
7570       Variable_Ref       : Boolean   := False;
7571       Related_Id         : Entity_Id := Empty;
7572       Is_Low_Bound       : Boolean   := False;
7573       Is_High_Bound      : Boolean   := False;
7574       Check_Side_Effects : Boolean   := True)
7575    is
7576       function Build_Temporary
7577         (Loc         : Source_Ptr;
7578          Id          : Character;
7579          Related_Nod : Node_Id := Empty) return Entity_Id;
7580       --  Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod
7581       --  is present (xxx is taken from the Chars field of Related_Nod),
7582       --  otherwise it generates an internal temporary.
7583 
7584       function Is_Name_Reference (N : Node_Id) return Boolean;
7585       --  Determine if the tree referenced by N represents a name. This is
7586       --  similar to Is_Object_Reference but returns true only if N can be
7587       --  renamed without the need for a temporary, the typical example of
7588       --  an object not in this category being a function call.
7589 
7590       ---------------------
7591       -- Build_Temporary --
7592       ---------------------
7593 
7594       function Build_Temporary
7595         (Loc         : Source_Ptr;
7596          Id          : Character;
7597          Related_Nod : Node_Id := Empty) return Entity_Id
7598       is
7599          Temp_Nam : Name_Id;
7600 
7601       begin
7602          --  The context requires an external symbol
7603 
7604          if Present (Related_Id) then
7605             if Is_Low_Bound then
7606                Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST");
7607             else pragma Assert (Is_High_Bound);
7608                Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST");
7609             end if;
7610 
7611             return Make_Defining_Identifier (Loc, Temp_Nam);
7612 
7613          --  Otherwise generate an internal temporary
7614 
7615          else
7616             return Make_Temporary (Loc, Id, Related_Nod);
7617          end if;
7618       end Build_Temporary;
7619 
7620       -----------------------
7621       -- Is_Name_Reference --
7622       -----------------------
7623 
7624       function Is_Name_Reference (N : Node_Id) return Boolean is
7625       begin
7626          if Is_Entity_Name (N) then
7627             return Present (Entity (N)) and then Is_Object (Entity (N));
7628          end if;
7629 
7630          case Nkind (N) is
7631             when N_Indexed_Component | N_Slice =>
7632                return
7633                  Is_Name_Reference (Prefix (N))
7634                    or else Is_Access_Type (Etype (Prefix (N)));
7635 
7636             --  Attributes 'Input, 'Old and 'Result produce objects
7637 
7638             when N_Attribute_Reference =>
7639                return
7640                  Nam_In
7641                    (Attribute_Name (N), Name_Input, Name_Old, Name_Result);
7642 
7643             when N_Selected_Component =>
7644                return
7645                  Is_Name_Reference (Selector_Name (N))
7646                    and then
7647                      (Is_Name_Reference (Prefix (N))
7648                        or else Is_Access_Type (Etype (Prefix (N))));
7649 
7650             when N_Explicit_Dereference =>
7651                return True;
7652 
7653             --  A view conversion of a tagged name is a name reference
7654 
7655             when N_Type_Conversion =>
7656                return Is_Tagged_Type (Etype (Subtype_Mark (N)))
7657                  and then Is_Tagged_Type (Etype (Expression (N)))
7658                  and then Is_Name_Reference (Expression (N));
7659 
7660             --  An unchecked type conversion is considered to be a name if
7661             --  the operand is a name (this construction arises only as a
7662             --  result of expansion activities).
7663 
7664             when N_Unchecked_Type_Conversion =>
7665                return Is_Name_Reference (Expression (N));
7666 
7667             when others =>
7668                return False;
7669          end case;
7670       end Is_Name_Reference;
7671 
7672       --  Local variables
7673 
7674       Loc          : constant Source_Ptr      := Sloc (Exp);
7675       Exp_Type     : constant Entity_Id       := Etype (Exp);
7676       Svg_Suppress : constant Suppress_Record := Scope_Suppress;
7677       Def_Id       : Entity_Id;
7678       E            : Node_Id;
7679       New_Exp      : Node_Id;
7680       Ptr_Typ_Decl : Node_Id;
7681       Ref_Type     : Entity_Id;
7682       Res          : Node_Id;
7683 
7684    --  Start of processing for Remove_Side_Effects
7685 
7686    begin
7687       --  Handle cases in which there is nothing to do. In GNATprove mode,
7688       --  removal of side effects is useful for the light expansion of
7689       --  renamings. This removal should only occur when not inside a
7690       --  generic and not doing a pre-analysis.
7691 
7692       if not Expander_Active
7693         and (Inside_A_Generic or not Full_Analysis or not GNATprove_Mode)
7694       then
7695          return;
7696 
7697       --  Cannot generate temporaries if the invocation to remove side effects
7698       --  was issued too early and the type of the expression is not resolved
7699       --  (this happens because routines Duplicate_Subexpr_XX implicitly invoke
7700       --  Remove_Side_Effects).
7701 
7702       elsif No (Exp_Type)
7703         or else Ekind (Exp_Type) = E_Access_Attribute_Type
7704       then
7705          return;
7706 
7707       --  Nothing to do if prior expansion determined that a function call does
7708       --  not require side effect removal.
7709 
7710       elsif Nkind (Exp) = N_Function_Call
7711         and then No_Side_Effect_Removal (Exp)
7712       then
7713          return;
7714 
7715       --  No action needed for side-effect free expressions
7716 
7717       elsif Check_Side_Effects
7718         and then Side_Effect_Free (Exp, Name_Req, Variable_Ref)
7719       then
7720          return;
7721       end if;
7722 
7723       --  The remaining processing is done with all checks suppressed
7724 
7725       --  Note: from now on, don't use return statements, instead do a goto
7726       --  Leave, to ensure that we properly restore Scope_Suppress.Suppress.
7727 
7728       Scope_Suppress.Suppress := (others => True);
7729 
7730       --  If this is an elementary or a small not-by-reference record type, and
7731       --  we need to capture the value, just make a constant; this is cheap and
7732       --  objects of both kinds of types can be bit aligned, so it might not be
7733       --  possible to generate a reference to them. Likewise if this is not a
7734       --  name reference, except for a type conversion, because we would enter
7735       --  an infinite recursion with Checks.Apply_Predicate_Check if the target
7736       --  type has predicates (and type conversions need a specific treatment
7737       --  anyway, see below). Also do it if we have a volatile reference and
7738       --  Name_Req is not set (see comments for Side_Effect_Free).
7739 
7740       if (Is_Elementary_Type (Exp_Type)
7741            or else (Is_Record_Type (Exp_Type)
7742                      and then Known_Static_RM_Size (Exp_Type)
7743                      and then RM_Size (Exp_Type) <= 64
7744                      and then not Has_Discriminants (Exp_Type)
7745                      and then not Is_By_Reference_Type (Exp_Type)))
7746         and then (Variable_Ref
7747                    or else (not Is_Name_Reference (Exp)
7748                              and then Nkind (Exp) /= N_Type_Conversion)
7749                    or else (not Name_Req
7750                              and then Is_Volatile_Reference (Exp)))
7751       then
7752          Def_Id := Build_Temporary (Loc, 'R', Exp);
7753          Set_Etype (Def_Id, Exp_Type);
7754          Res := New_Occurrence_Of (Def_Id, Loc);
7755 
7756          --  If the expression is a packed reference, it must be reanalyzed and
7757          --  expanded, depending on context. This is the case for actuals where
7758          --  a constraint check may capture the actual before expansion of the
7759          --  call is complete.
7760 
7761          if Nkind (Exp) = N_Indexed_Component
7762            and then Is_Packed (Etype (Prefix (Exp)))
7763          then
7764             Set_Analyzed (Exp, False);
7765             Set_Analyzed (Prefix (Exp), False);
7766          end if;
7767 
7768          --  Generate:
7769          --    Rnn : Exp_Type renames Expr;
7770 
7771          if Renaming_Req then
7772             E :=
7773               Make_Object_Renaming_Declaration (Loc,
7774                 Defining_Identifier => Def_Id,
7775                 Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
7776                 Name                => Relocate_Node (Exp));
7777 
7778          --  Generate:
7779          --    Rnn : constant Exp_Type := Expr;
7780 
7781          else
7782             E :=
7783               Make_Object_Declaration (Loc,
7784                 Defining_Identifier => Def_Id,
7785                 Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
7786                 Constant_Present    => True,
7787                 Expression          => Relocate_Node (Exp));
7788 
7789             Set_Assignment_OK (E);
7790          end if;
7791 
7792          Insert_Action (Exp, E);
7793 
7794       --  If the expression has the form v.all then we can just capture the
7795       --  pointer, and then do an explicit dereference on the result, but
7796       --  this is not right if this is a volatile reference.
7797 
7798       elsif Nkind (Exp) = N_Explicit_Dereference
7799         and then not Is_Volatile_Reference (Exp)
7800       then
7801          Def_Id := Build_Temporary (Loc, 'R', Exp);
7802          Res :=
7803            Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc));
7804 
7805          Insert_Action (Exp,
7806            Make_Object_Declaration (Loc,
7807              Defining_Identifier => Def_Id,
7808              Object_Definition   =>
7809                New_Occurrence_Of (Etype (Prefix (Exp)), Loc),
7810              Constant_Present    => True,
7811              Expression          => Relocate_Node (Prefix (Exp))));
7812 
7813       --  Similar processing for an unchecked conversion of an expression of
7814       --  the form v.all, where we want the same kind of treatment.
7815 
7816       elsif Nkind (Exp) = N_Unchecked_Type_Conversion
7817         and then Nkind (Expression (Exp)) = N_Explicit_Dereference
7818       then
7819          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
7820          goto Leave;
7821 
7822       --  If this is a type conversion, leave the type conversion and remove
7823       --  the side effects in the expression. This is important in several
7824       --  circumstances: for change of representations, and also when this is a
7825       --  view conversion to a smaller object, where gigi can end up creating
7826       --  its own temporary of the wrong size.
7827 
7828       elsif Nkind (Exp) = N_Type_Conversion then
7829          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
7830 
7831          --  Generating C code the type conversion of an access to constrained
7832          --  array type into an access to unconstrained array type involves
7833          --  initializing a fat pointer and the expression must be free of
7834          --  side effects to safely compute its bounds.
7835 
7836          if Generate_C_Code
7837            and then Is_Access_Type (Etype (Exp))
7838            and then Is_Array_Type (Designated_Type (Etype (Exp)))
7839            and then not Is_Constrained (Designated_Type (Etype (Exp)))
7840          then
7841             Def_Id := Build_Temporary (Loc, 'R', Exp);
7842             Set_Etype (Def_Id, Exp_Type);
7843             Res := New_Occurrence_Of (Def_Id, Loc);
7844 
7845             Insert_Action (Exp,
7846               Make_Object_Declaration (Loc,
7847                 Defining_Identifier => Def_Id,
7848                 Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
7849                 Constant_Present    => True,
7850                 Expression          => Relocate_Node (Exp)));
7851          else
7852             goto Leave;
7853          end if;
7854 
7855       --  If this is an unchecked conversion that Gigi can't handle, make
7856       --  a copy or a use a renaming to capture the value.
7857 
7858       elsif Nkind (Exp) = N_Unchecked_Type_Conversion
7859         and then not Safe_Unchecked_Type_Conversion (Exp)
7860       then
7861          if CW_Or_Has_Controlled_Part (Exp_Type) then
7862 
7863             --  Use a renaming to capture the expression, rather than create
7864             --  a controlled temporary.
7865 
7866             Def_Id := Build_Temporary (Loc, 'R', Exp);
7867             Res    := New_Occurrence_Of (Def_Id, Loc);
7868 
7869             Insert_Action (Exp,
7870               Make_Object_Renaming_Declaration (Loc,
7871                 Defining_Identifier => Def_Id,
7872                 Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
7873                 Name                => Relocate_Node (Exp)));
7874 
7875          else
7876             Def_Id := Build_Temporary (Loc, 'R', Exp);
7877             Set_Etype (Def_Id, Exp_Type);
7878             Res    := New_Occurrence_Of (Def_Id, Loc);
7879 
7880             E :=
7881               Make_Object_Declaration (Loc,
7882                 Defining_Identifier => Def_Id,
7883                 Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
7884                 Constant_Present    => not Is_Variable (Exp),
7885                 Expression          => Relocate_Node (Exp));
7886 
7887             Set_Assignment_OK (E);
7888             Insert_Action (Exp, E);
7889          end if;
7890 
7891       --  For expressions that denote names, we can use a renaming scheme.
7892       --  This is needed for correctness in the case of a volatile object of
7893       --  a non-volatile type because the Make_Reference call of the "default"
7894       --  approach would generate an illegal access value (an access value
7895       --  cannot designate such an object - see Analyze_Reference).
7896 
7897       elsif Is_Name_Reference (Exp)
7898 
7899         --  We skip using this scheme if we have an object of a volatile
7900         --  type and we do not have Name_Req set true (see comments for
7901         --  Side_Effect_Free).
7902 
7903         and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
7904       then
7905          Def_Id := Build_Temporary (Loc, 'R', Exp);
7906          Res := New_Occurrence_Of (Def_Id, Loc);
7907 
7908          Insert_Action (Exp,
7909            Make_Object_Renaming_Declaration (Loc,
7910              Defining_Identifier => Def_Id,
7911              Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
7912              Name                => Relocate_Node (Exp)));
7913 
7914          --  If this is a packed reference, or a selected component with
7915          --  a non-standard representation, a reference to the temporary
7916          --  will be replaced by a copy of the original expression (see
7917          --  Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
7918          --  elaborated by gigi, and is of course not to be replaced in-line
7919          --  by the expression it renames, which would defeat the purpose of
7920          --  removing the side-effect.
7921 
7922          if Nkind_In (Exp, N_Selected_Component, N_Indexed_Component)
7923            and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
7924          then
7925             null;
7926          else
7927             Set_Is_Renaming_Of_Object (Def_Id, False);
7928          end if;
7929 
7930       --  Avoid generating a variable-sized temporary, by generating the
7931       --  reference just for the function call. The transformation could be
7932       --  refined to apply only when the array component is constrained by a
7933       --  discriminant???
7934 
7935       elsif Nkind (Exp) = N_Selected_Component
7936         and then Nkind (Prefix (Exp)) = N_Function_Call
7937         and then Is_Array_Type (Exp_Type)
7938       then
7939          Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
7940          goto Leave;
7941 
7942       --  Otherwise we generate a reference to the expression
7943 
7944       else
7945          --  An expression which is in SPARK mode is considered side effect
7946          --  free if the resulting value is captured by a variable or a
7947          --  constant.
7948 
7949          if GNATprove_Mode
7950            and then Nkind (Parent (Exp)) = N_Object_Declaration
7951          then
7952             goto Leave;
7953 
7954          --  When generating C code we cannot consider side effect free object
7955          --  declarations that have discriminants and are initialized by means
7956          --  of a function call since on this target there is no secondary
7957          --  stack to store the return value and the expander may generate an
7958          --  extra call to the function to compute the discriminant value. In
7959          --  addition, for targets that have secondary stack, the expansion of
7960          --  functions with side effects involves the generation of an access
7961          --  type to capture the return value stored in the secondary stack;
7962          --  by contrast when generating C code such expansion generates an
7963          --  internal object declaration (no access type involved) which must
7964          --  be identified here to avoid entering into a never-ending loop
7965          --  generating internal object declarations.
7966 
7967          elsif Generate_C_Code
7968            and then Nkind (Parent (Exp)) = N_Object_Declaration
7969            and then
7970              (Nkind (Exp) /= N_Function_Call
7971                 or else not Has_Discriminants (Exp_Type)
7972                 or else Is_Internal_Name
7973                           (Chars (Defining_Identifier (Parent (Exp)))))
7974          then
7975             goto Leave;
7976          end if;
7977 
7978          --  Special processing for function calls that return a limited type.
7979          --  We need to build a declaration that will enable build-in-place
7980          --  expansion of the call. This is not done if the context is already
7981          --  an object declaration, to prevent infinite recursion.
7982 
7983          --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
7984          --  to accommodate functions returning limited objects by reference.
7985 
7986          if Ada_Version >= Ada_2005
7987            and then Nkind (Exp) = N_Function_Call
7988            and then Is_Limited_View (Etype (Exp))
7989            and then Nkind (Parent (Exp)) /= N_Object_Declaration
7990          then
7991             declare
7992                Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
7993                Decl : Node_Id;
7994 
7995             begin
7996                Decl :=
7997                  Make_Object_Declaration (Loc,
7998                    Defining_Identifier => Obj,
7999                    Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
8000                    Expression          => Relocate_Node (Exp));
8001 
8002                Insert_Action (Exp, Decl);
8003                Set_Etype (Obj, Exp_Type);
8004                Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
8005                goto Leave;
8006             end;
8007          end if;
8008 
8009          Def_Id := Build_Temporary (Loc, 'R', Exp);
8010 
8011          --  The regular expansion of functions with side effects involves the
8012          --  generation of an access type to capture the return value found on
8013          --  the secondary stack. Since SPARK (and why) cannot process access
8014          --  types, use a different approach which ignores the secondary stack
8015          --  and "copies" the returned object.
8016          --  When generating C code, no need for a 'reference since the
8017          --  secondary stack is not supported.
8018 
8019          if GNATprove_Mode or Generate_C_Code then
8020             Res := New_Occurrence_Of (Def_Id, Loc);
8021             Ref_Type := Exp_Type;
8022 
8023          --  Regular expansion utilizing an access type and 'reference
8024 
8025          else
8026             Res :=
8027               Make_Explicit_Dereference (Loc,
8028                 Prefix => New_Occurrence_Of (Def_Id, Loc));
8029 
8030             --  Generate:
8031             --    type Ann is access all <Exp_Type>;
8032 
8033             Ref_Type := Make_Temporary (Loc, 'A');
8034 
8035             Ptr_Typ_Decl :=
8036               Make_Full_Type_Declaration (Loc,
8037                 Defining_Identifier => Ref_Type,
8038                 Type_Definition     =>
8039                   Make_Access_To_Object_Definition (Loc,
8040                     All_Present        => True,
8041                     Subtype_Indication =>
8042                       New_Occurrence_Of (Exp_Type, Loc)));
8043 
8044             Insert_Action (Exp, Ptr_Typ_Decl);
8045          end if;
8046 
8047          E := Exp;
8048          if Nkind (E) = N_Explicit_Dereference then
8049             New_Exp := Relocate_Node (Prefix (E));
8050 
8051          else
8052             E := Relocate_Node (E);
8053 
8054             --  Do not generate a 'reference in SPARK mode or C generation
8055             --  since the access type is not created in the first place.
8056 
8057             if GNATprove_Mode or Generate_C_Code then
8058                New_Exp := E;
8059 
8060             --  Otherwise generate reference, marking the value as non-null
8061             --  since we know it cannot be null and we don't want a check.
8062 
8063             else
8064                New_Exp := Make_Reference (Loc, E);
8065                Set_Is_Known_Non_Null (Def_Id);
8066             end if;
8067          end if;
8068 
8069          if Is_Delayed_Aggregate (E) then
8070 
8071             --  The expansion of nested aggregates is delayed until the
8072             --  enclosing aggregate is expanded. As aggregates are often
8073             --  qualified, the predicate applies to qualified expressions as
8074             --  well, indicating that the enclosing aggregate has not been
8075             --  expanded yet. At this point the aggregate is part of a
8076             --  stand-alone declaration, and must be fully expanded.
8077 
8078             if Nkind (E) = N_Qualified_Expression then
8079                Set_Expansion_Delayed (Expression (E), False);
8080                Set_Analyzed (Expression (E), False);
8081             else
8082                Set_Expansion_Delayed (E, False);
8083             end if;
8084 
8085             Set_Analyzed (E, False);
8086          end if;
8087 
8088          --  Generating C code of object declarations that have discriminants
8089          --  and are initialized by means of a function call we propagate the
8090          --  discriminants of the parent type to the internally built object.
8091          --  This is needed to avoid generating an extra call to the called
8092          --  function.
8093 
8094          --  For example, if we generate here the following declaration, it
8095          --  will be expanded later adding an extra call to evaluate the value
8096          --  of the discriminant (needed to compute the size of the object).
8097          --
8098          --     type Rec (D : Integer) is ...
8099          --     Obj : constant Rec := SomeFunc;
8100 
8101          if Generate_C_Code
8102            and then Nkind (Parent (Exp)) = N_Object_Declaration
8103            and then Has_Discriminants (Exp_Type)
8104            and then Nkind (Exp) = N_Function_Call
8105          then
8106             Insert_Action (Exp,
8107               Make_Object_Declaration (Loc,
8108                 Defining_Identifier => Def_Id,
8109                 Object_Definition   => New_Copy_Tree
8110                                          (Object_Definition (Parent (Exp))),
8111                 Constant_Present    => True,
8112                 Expression          => New_Exp));
8113          else
8114             Insert_Action (Exp,
8115               Make_Object_Declaration (Loc,
8116                 Defining_Identifier => Def_Id,
8117                 Object_Definition   => New_Occurrence_Of (Ref_Type, Loc),
8118                 Constant_Present    => True,
8119                 Expression          => New_Exp));
8120          end if;
8121       end if;
8122 
8123       --  Preserve the Assignment_OK flag in all copies, since at least one
8124       --  copy may be used in a context where this flag must be set (otherwise
8125       --  why would the flag be set in the first place).
8126 
8127       Set_Assignment_OK (Res, Assignment_OK (Exp));
8128 
8129       --  Finally rewrite the original expression and we are done
8130 
8131       Rewrite (Exp, Res);
8132       Analyze_And_Resolve (Exp, Exp_Type);
8133 
8134    <<Leave>>
8135       Scope_Suppress := Svg_Suppress;
8136    end Remove_Side_Effects;
8137 
8138    ---------------------------
8139    -- Represented_As_Scalar --
8140    ---------------------------
8141 
8142    function Represented_As_Scalar (T : Entity_Id) return Boolean is
8143       UT : constant Entity_Id := Underlying_Type (T);
8144    begin
8145       return Is_Scalar_Type (UT)
8146         or else (Is_Bit_Packed_Array (UT)
8147                   and then Is_Scalar_Type (Packed_Array_Impl_Type (UT)));
8148    end Represented_As_Scalar;
8149 
8150    ------------------------------
8151    -- Requires_Cleanup_Actions --
8152    ------------------------------
8153 
8154    function Requires_Cleanup_Actions
8155      (N         : Node_Id;
8156       Lib_Level : Boolean) return Boolean
8157    is
8158       At_Lib_Level : constant Boolean :=
8159                        Lib_Level
8160                          and then Nkind_In (N, N_Package_Body,
8161                                                N_Package_Specification);
8162       --  N is at the library level if the top-most context is a package and
8163       --  the path taken to reach N does not inlcude non-package constructs.
8164 
8165    begin
8166       case Nkind (N) is
8167          when N_Accept_Statement      |
8168               N_Block_Statement       |
8169               N_Entry_Body            |
8170               N_Package_Body          |
8171               N_Protected_Body        |
8172               N_Subprogram_Body       |
8173               N_Task_Body             =>
8174             return
8175               Requires_Cleanup_Actions (Declarations (N), At_Lib_Level, True)
8176                 or else
8177                   (Present (Handled_Statement_Sequence (N))
8178                     and then
8179                       Requires_Cleanup_Actions
8180                         (Statements (Handled_Statement_Sequence (N)),
8181                          At_Lib_Level, True));
8182 
8183          when N_Package_Specification =>
8184             return
8185               Requires_Cleanup_Actions
8186                 (Visible_Declarations (N), At_Lib_Level, True)
8187                   or else
8188               Requires_Cleanup_Actions
8189                 (Private_Declarations (N), At_Lib_Level, True);
8190 
8191          when others                  =>
8192             return False;
8193       end case;
8194    end Requires_Cleanup_Actions;
8195 
8196    ------------------------------
8197    -- Requires_Cleanup_Actions --
8198    ------------------------------
8199 
8200    function Requires_Cleanup_Actions
8201      (L                 : List_Id;
8202       Lib_Level         : Boolean;
8203       Nested_Constructs : Boolean) return Boolean
8204    is
8205       Decl    : Node_Id;
8206       Expr    : Node_Id;
8207       Obj_Id  : Entity_Id;
8208       Obj_Typ : Entity_Id;
8209       Pack_Id : Entity_Id;
8210       Typ     : Entity_Id;
8211 
8212    begin
8213       if No (L)
8214         or else Is_Empty_List (L)
8215       then
8216          return False;
8217       end if;
8218 
8219       Decl := First (L);
8220       while Present (Decl) loop
8221 
8222          --  Library-level tagged types
8223 
8224          if Nkind (Decl) = N_Full_Type_Declaration then
8225             Typ := Defining_Identifier (Decl);
8226 
8227             --  Ignored Ghost types do not need any cleanup actions because
8228             --  they will not appear in the final tree.
8229 
8230             if Is_Ignored_Ghost_Entity (Typ) then
8231                null;
8232 
8233             elsif Is_Tagged_Type (Typ)
8234               and then Is_Library_Level_Entity (Typ)
8235               and then Convention (Typ) = Convention_Ada
8236               and then Present (Access_Disp_Table (Typ))
8237               and then RTE_Available (RE_Unregister_Tag)
8238               and then not Is_Abstract_Type (Typ)
8239               and then not No_Run_Time_Mode
8240             then
8241                return True;
8242             end if;
8243 
8244          --  Regular object declarations
8245 
8246          elsif Nkind (Decl) = N_Object_Declaration then
8247             Obj_Id  := Defining_Identifier (Decl);
8248             Obj_Typ := Base_Type (Etype (Obj_Id));
8249             Expr    := Expression (Decl);
8250 
8251             --  Bypass any form of processing for objects which have their
8252             --  finalization disabled. This applies only to objects at the
8253             --  library level.
8254 
8255             if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
8256                null;
8257 
8258             --  Transient variables are treated separately in order to minimize
8259             --  the size of the generated code. See Exp_Ch7.Process_Transient_
8260             --  Objects.
8261 
8262             elsif Is_Processed_Transient (Obj_Id) then
8263                null;
8264 
8265             --  Ignored Ghost objects do not need any cleanup actions because
8266             --  they will not appear in the final tree.
8267 
8268             elsif Is_Ignored_Ghost_Entity (Obj_Id) then
8269                null;
8270 
8271             --  The expansion of iterator loops generates an object declaration
8272             --  where the Ekind is explicitly set to loop parameter. This is to
8273             --  ensure that the loop parameter behaves as a constant from user
8274             --  code point of view. Such object are never controlled and do not
8275             --  require cleanup actions. An iterator loop over a container of
8276             --  controlled objects does not produce such object declarations.
8277 
8278             elsif Ekind (Obj_Id) = E_Loop_Parameter then
8279                return False;
8280 
8281             --  The object is of the form:
8282             --    Obj : [constant] Typ [:= Expr];
8283             --
8284             --  Do not process tag-to-class-wide conversions because they do
8285             --  not yield an object. Do not process the incomplete view of a
8286             --  deferred constant. Note that an object initialized by means
8287             --  of a build-in-place function call may appear as a deferred
8288             --  constant after expansion activities. These kinds of objects
8289             --  must be finalized.
8290 
8291             elsif not Is_Imported (Obj_Id)
8292               and then Needs_Finalization (Obj_Typ)
8293               and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
8294               and then not (Ekind (Obj_Id) = E_Constant
8295                              and then not Has_Completion (Obj_Id)
8296                              and then No (BIP_Initialization_Call (Obj_Id)))
8297             then
8298                return True;
8299 
8300             --  The object is of the form:
8301             --    Obj : Access_Typ := Non_BIP_Function_Call'reference;
8302             --
8303             --    Obj : Access_Typ :=
8304             --            BIP_Function_Call (BIPalloc => 2, ...)'reference;
8305 
8306             elsif Is_Access_Type (Obj_Typ)
8307               and then Needs_Finalization
8308                          (Available_View (Designated_Type (Obj_Typ)))
8309               and then Present (Expr)
8310               and then
8311                 (Is_Secondary_Stack_BIP_Func_Call (Expr)
8312                   or else
8313                     (Is_Non_BIP_Func_Call (Expr)
8314                       and then not Is_Related_To_Func_Return (Obj_Id)))
8315             then
8316                return True;
8317 
8318             --  Processing for "hook" objects generated for controlled
8319             --  transients declared inside an Expression_With_Actions.
8320 
8321             elsif Is_Access_Type (Obj_Typ)
8322               and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
8323               and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
8324                                                         N_Object_Declaration
8325             then
8326                return True;
8327 
8328             --  Processing for intermediate results of if expressions where
8329             --  one of the alternatives uses a controlled function call.
8330 
8331             elsif Is_Access_Type (Obj_Typ)
8332               and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
8333               and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
8334                                                         N_Defining_Identifier
8335               and then Present (Expr)
8336               and then Nkind (Expr) = N_Null
8337             then
8338                return True;
8339 
8340             --  Simple protected objects which use type System.Tasking.
8341             --  Protected_Objects.Protection to manage their locks should be
8342             --  treated as controlled since they require manual cleanup.
8343 
8344             elsif Ekind (Obj_Id) = E_Variable
8345               and then (Is_Simple_Protected_Type (Obj_Typ)
8346                          or else Has_Simple_Protected_Object (Obj_Typ))
8347             then
8348                return True;
8349             end if;
8350 
8351          --  Specific cases of object renamings
8352 
8353          elsif Nkind (Decl) = N_Object_Renaming_Declaration then
8354             Obj_Id  := Defining_Identifier (Decl);
8355             Obj_Typ := Base_Type (Etype (Obj_Id));
8356 
8357             --  Bypass any form of processing for objects which have their
8358             --  finalization disabled. This applies only to objects at the
8359             --  library level.
8360 
8361             if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
8362                null;
8363 
8364             --  Ignored Ghost object renamings do not need any cleanup actions
8365             --  because they will not appear in the final tree.
8366 
8367             elsif Is_Ignored_Ghost_Entity (Obj_Id) then
8368                null;
8369 
8370             --  Return object of a build-in-place function. This case is
8371             --  recognized and marked by the expansion of an extended return
8372             --  statement (see Expand_N_Extended_Return_Statement).
8373 
8374             elsif Needs_Finalization (Obj_Typ)
8375               and then Is_Return_Object (Obj_Id)
8376               and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
8377             then
8378                return True;
8379 
8380             --  Detect a case where a source object has been initialized by
8381             --  a controlled function call or another object which was later
8382             --  rewritten as a class-wide conversion of Ada.Tags.Displace.
8383 
8384             --     Obj1 : CW_Type := Src_Obj;
8385             --     Obj2 : CW_Type := Function_Call (...);
8386 
8387             --     Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
8388             --     Tmp  : ... := Function_Call (...)'reference;
8389             --     Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
8390 
8391             elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
8392                return True;
8393             end if;
8394 
8395          --  Inspect the freeze node of an access-to-controlled type and look
8396          --  for a delayed finalization master. This case arises when the
8397          --  freeze actions are inserted at a later time than the expansion of
8398          --  the context. Since Build_Finalizer is never called on a single
8399          --  construct twice, the master will be ultimately left out and never
8400          --  finalized. This is also needed for freeze actions of designated
8401          --  types themselves, since in some cases the finalization master is
8402          --  associated with a designated type's freeze node rather than that
8403          --  of the access type (see handling for freeze actions in
8404          --  Build_Finalization_Master).
8405 
8406          elsif Nkind (Decl) = N_Freeze_Entity
8407            and then Present (Actions (Decl))
8408          then
8409             Typ := Entity (Decl);
8410 
8411             --  Freeze nodes for ignored Ghost types do not need cleanup
8412             --  actions because they will never appear in the final tree.
8413 
8414             if Is_Ignored_Ghost_Entity (Typ) then
8415                null;
8416 
8417             elsif ((Is_Access_Type (Typ)
8418                       and then not Is_Access_Subprogram_Type (Typ)
8419                       and then Needs_Finalization
8420                                  (Available_View (Designated_Type (Typ))))
8421                     or else (Is_Type (Typ) and then Needs_Finalization (Typ)))
8422               and then Requires_Cleanup_Actions
8423                          (Actions (Decl), Lib_Level, Nested_Constructs)
8424             then
8425                return True;
8426             end if;
8427 
8428          --  Nested package declarations
8429 
8430          elsif Nested_Constructs
8431            and then Nkind (Decl) = N_Package_Declaration
8432          then
8433             Pack_Id := Defining_Entity (Decl);
8434 
8435             --  Do not inspect an ignored Ghost package because all code found
8436             --  within will not appear in the final tree.
8437 
8438             if Is_Ignored_Ghost_Entity (Pack_Id) then
8439                null;
8440 
8441             elsif Ekind (Pack_Id) /= E_Generic_Package
8442               and then Requires_Cleanup_Actions
8443                          (Specification (Decl), Lib_Level)
8444             then
8445                return True;
8446             end if;
8447 
8448          --  Nested package bodies
8449 
8450          elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then
8451 
8452             --  Do not inspect an ignored Ghost package body because all code
8453             --  found within will not appear in the final tree.
8454 
8455             if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then
8456                null;
8457 
8458             elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package
8459               and then Requires_Cleanup_Actions (Decl, Lib_Level)
8460             then
8461                return True;
8462             end if;
8463 
8464          elsif Nkind (Decl) = N_Block_Statement
8465            and then
8466 
8467            --  Handle a rare case caused by a controlled transient variable
8468            --  created as part of a record init proc. The variable is wrapped
8469            --  in a block, but the block is not associated with a transient
8470            --  scope.
8471 
8472            (Inside_Init_Proc
8473 
8474            --  Handle the case where the original context has been wrapped in
8475            --  a block to avoid interference between exception handlers and
8476            --  At_End handlers. Treat the block as transparent and process its
8477            --  contents.
8478 
8479              or else Is_Finalization_Wrapper (Decl))
8480          then
8481             if Requires_Cleanup_Actions (Decl, Lib_Level) then
8482                return True;
8483             end if;
8484          end if;
8485 
8486          Next (Decl);
8487       end loop;
8488 
8489       return False;
8490    end Requires_Cleanup_Actions;
8491 
8492    ------------------------------------
8493    -- Safe_Unchecked_Type_Conversion --
8494    ------------------------------------
8495 
8496    --  Note: this function knows quite a bit about the exact requirements of
8497    --  Gigi with respect to unchecked type conversions, and its code must be
8498    --  coordinated with any changes in Gigi in this area.
8499 
8500    --  The above requirements should be documented in Sinfo ???
8501 
8502    function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
8503       Otyp   : Entity_Id;
8504       Ityp   : Entity_Id;
8505       Oalign : Uint;
8506       Ialign : Uint;
8507       Pexp   : constant Node_Id := Parent (Exp);
8508 
8509    begin
8510       --  If the expression is the RHS of an assignment or object declaration
8511       --  we are always OK because there will always be a target.
8512 
8513       --  Object renaming declarations, (generated for view conversions of
8514       --  actuals in inlined calls), like object declarations, provide an
8515       --  explicit type, and are safe as well.
8516 
8517       if (Nkind (Pexp) = N_Assignment_Statement
8518            and then Expression (Pexp) = Exp)
8519         or else Nkind_In (Pexp, N_Object_Declaration,
8520                                 N_Object_Renaming_Declaration)
8521       then
8522          return True;
8523 
8524       --  If the expression is the prefix of an N_Selected_Component we should
8525       --  also be OK because GCC knows to look inside the conversion except if
8526       --  the type is discriminated. We assume that we are OK anyway if the
8527       --  type is not set yet or if it is controlled since we can't afford to
8528       --  introduce a temporary in this case.
8529 
8530       elsif Nkind (Pexp) = N_Selected_Component
8531         and then Prefix (Pexp) = Exp
8532       then
8533          if No (Etype (Pexp)) then
8534             return True;
8535          else
8536             return
8537               not Has_Discriminants (Etype (Pexp))
8538                 or else Is_Constrained (Etype (Pexp));
8539          end if;
8540       end if;
8541 
8542       --  Set the output type, this comes from Etype if it is set, otherwise we
8543       --  take it from the subtype mark, which we assume was already fully
8544       --  analyzed.
8545 
8546       if Present (Etype (Exp)) then
8547          Otyp := Etype (Exp);
8548       else
8549          Otyp := Entity (Subtype_Mark (Exp));
8550       end if;
8551 
8552       --  The input type always comes from the expression, and we assume this
8553       --  is indeed always analyzed, so we can simply get the Etype.
8554 
8555       Ityp := Etype (Expression (Exp));
8556 
8557       --  Initialize alignments to unknown so far
8558 
8559       Oalign := No_Uint;
8560       Ialign := No_Uint;
8561 
8562       --  Replace a concurrent type by its corresponding record type and each
8563       --  type by its underlying type and do the tests on those. The original
8564       --  type may be a private type whose completion is a concurrent type, so
8565       --  find the underlying type first.
8566 
8567       if Present (Underlying_Type (Otyp)) then
8568          Otyp := Underlying_Type (Otyp);
8569       end if;
8570 
8571       if Present (Underlying_Type (Ityp)) then
8572          Ityp := Underlying_Type (Ityp);
8573       end if;
8574 
8575       if Is_Concurrent_Type (Otyp) then
8576          Otyp := Corresponding_Record_Type (Otyp);
8577       end if;
8578 
8579       if Is_Concurrent_Type (Ityp) then
8580          Ityp := Corresponding_Record_Type (Ityp);
8581       end if;
8582 
8583       --  If the base types are the same, we know there is no problem since
8584       --  this conversion will be a noop.
8585 
8586       if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
8587          return True;
8588 
8589       --  Same if this is an upwards conversion of an untagged type, and there
8590       --  are no constraints involved (could be more general???)
8591 
8592       elsif Etype (Ityp) = Otyp
8593         and then not Is_Tagged_Type (Ityp)
8594         and then not Has_Discriminants (Ityp)
8595         and then No (First_Rep_Item (Base_Type (Ityp)))
8596       then
8597          return True;
8598 
8599       --  If the expression has an access type (object or subprogram) we assume
8600       --  that the conversion is safe, because the size of the target is safe,
8601       --  even if it is a record (which might be treated as having unknown size
8602       --  at this point).
8603 
8604       elsif Is_Access_Type (Ityp) then
8605          return True;
8606 
8607       --  If the size of output type is known at compile time, there is never
8608       --  a problem. Note that unconstrained records are considered to be of
8609       --  known size, but we can't consider them that way here, because we are
8610       --  talking about the actual size of the object.
8611 
8612       --  We also make sure that in addition to the size being known, we do not
8613       --  have a case which might generate an embarrassingly large temp in
8614       --  stack checking mode.
8615 
8616       elsif Size_Known_At_Compile_Time (Otyp)
8617         and then
8618           (not Stack_Checking_Enabled
8619             or else not May_Generate_Large_Temp (Otyp))
8620         and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
8621       then
8622          return True;
8623 
8624       --  If either type is tagged, then we know the alignment is OK so Gigi
8625       --  will be able to use pointer punning.
8626 
8627       elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
8628          return True;
8629 
8630       --  If either type is a limited record type, we cannot do a copy, so say
8631       --  safe since there's nothing else we can do.
8632 
8633       elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
8634          return True;
8635 
8636       --  Conversions to and from packed array types are always ignored and
8637       --  hence are safe.
8638 
8639       elsif Is_Packed_Array_Impl_Type (Otyp)
8640         or else Is_Packed_Array_Impl_Type (Ityp)
8641       then
8642          return True;
8643       end if;
8644 
8645       --  The only other cases known to be safe is if the input type's
8646       --  alignment is known to be at least the maximum alignment for the
8647       --  target or if both alignments are known and the output type's
8648       --  alignment is no stricter than the input's. We can use the component
8649       --  type alignement for an array if a type is an unpacked array type.
8650 
8651       if Present (Alignment_Clause (Otyp)) then
8652          Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
8653 
8654       elsif Is_Array_Type (Otyp)
8655         and then Present (Alignment_Clause (Component_Type (Otyp)))
8656       then
8657          Oalign := Expr_Value (Expression (Alignment_Clause
8658                                            (Component_Type (Otyp))));
8659       end if;
8660 
8661       if Present (Alignment_Clause (Ityp)) then
8662          Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
8663 
8664       elsif Is_Array_Type (Ityp)
8665         and then Present (Alignment_Clause (Component_Type (Ityp)))
8666       then
8667          Ialign := Expr_Value (Expression (Alignment_Clause
8668                                            (Component_Type (Ityp))));
8669       end if;
8670 
8671       if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
8672          return True;
8673 
8674       elsif Ialign /= No_Uint
8675         and then Oalign /= No_Uint
8676         and then Ialign <= Oalign
8677       then
8678          return True;
8679 
8680       --   Otherwise, Gigi cannot handle this and we must make a temporary
8681 
8682       else
8683          return False;
8684       end if;
8685    end Safe_Unchecked_Type_Conversion;
8686 
8687    ---------------------------------
8688    -- Set_Current_Value_Condition --
8689    ---------------------------------
8690 
8691    --  Note: the implementation of this procedure is very closely tied to the
8692    --  implementation of Get_Current_Value_Condition. Here we set required
8693    --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
8694    --  them, so they must have a consistent view.
8695 
8696    procedure Set_Current_Value_Condition (Cnode : Node_Id) is
8697 
8698       procedure Set_Entity_Current_Value (N : Node_Id);
8699       --  If N is an entity reference, where the entity is of an appropriate
8700       --  kind, then set the current value of this entity to Cnode, unless
8701       --  there is already a definite value set there.
8702 
8703       procedure Set_Expression_Current_Value (N : Node_Id);
8704       --  If N is of an appropriate form, sets an appropriate entry in current
8705       --  value fields of relevant entities. Multiple entities can be affected
8706       --  in the case of an AND or AND THEN.
8707 
8708       ------------------------------
8709       -- Set_Entity_Current_Value --
8710       ------------------------------
8711 
8712       procedure Set_Entity_Current_Value (N : Node_Id) is
8713       begin
8714          if Is_Entity_Name (N) then
8715             declare
8716                Ent : constant Entity_Id := Entity (N);
8717 
8718             begin
8719                --  Don't capture if not safe to do so
8720 
8721                if not Safe_To_Capture_Value (N, Ent, Cond => True) then
8722                   return;
8723                end if;
8724 
8725                --  Here we have a case where the Current_Value field may need
8726                --  to be set. We set it if it is not already set to a compile
8727                --  time expression value.
8728 
8729                --  Note that this represents a decision that one condition
8730                --  blots out another previous one. That's certainly right if
8731                --  they occur at the same level. If the second one is nested,
8732                --  then the decision is neither right nor wrong (it would be
8733                --  equally OK to leave the outer one in place, or take the new
8734                --  inner one. Really we should record both, but our data
8735                --  structures are not that elaborate.
8736 
8737                if Nkind (Current_Value (Ent)) not in N_Subexpr then
8738                   Set_Current_Value (Ent, Cnode);
8739                end if;
8740             end;
8741          end if;
8742       end Set_Entity_Current_Value;
8743 
8744       ----------------------------------
8745       -- Set_Expression_Current_Value --
8746       ----------------------------------
8747 
8748       procedure Set_Expression_Current_Value (N : Node_Id) is
8749          Cond : Node_Id;
8750 
8751       begin
8752          Cond := N;
8753 
8754          --  Loop to deal with (ignore for now) any NOT operators present. The
8755          --  presence of NOT operators will be handled properly when we call
8756          --  Get_Current_Value_Condition.
8757 
8758          while Nkind (Cond) = N_Op_Not loop
8759             Cond := Right_Opnd (Cond);
8760          end loop;
8761 
8762          --  For an AND or AND THEN, recursively process operands
8763 
8764          if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
8765             Set_Expression_Current_Value (Left_Opnd (Cond));
8766             Set_Expression_Current_Value (Right_Opnd (Cond));
8767             return;
8768          end if;
8769 
8770          --  Check possible relational operator
8771 
8772          if Nkind (Cond) in N_Op_Compare then
8773             if Compile_Time_Known_Value (Right_Opnd (Cond)) then
8774                Set_Entity_Current_Value (Left_Opnd (Cond));
8775             elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
8776                Set_Entity_Current_Value (Right_Opnd (Cond));
8777             end if;
8778 
8779          elsif Nkind_In (Cond,
8780                  N_Type_Conversion,
8781                  N_Qualified_Expression,
8782                  N_Expression_With_Actions)
8783          then
8784             Set_Expression_Current_Value (Expression (Cond));
8785 
8786          --  Check possible boolean variable reference
8787 
8788          else
8789             Set_Entity_Current_Value (Cond);
8790          end if;
8791       end Set_Expression_Current_Value;
8792 
8793    --  Start of processing for Set_Current_Value_Condition
8794 
8795    begin
8796       Set_Expression_Current_Value (Condition (Cnode));
8797    end Set_Current_Value_Condition;
8798 
8799    --------------------------
8800    -- Set_Elaboration_Flag --
8801    --------------------------
8802 
8803    procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
8804       Loc : constant Source_Ptr := Sloc (N);
8805       Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
8806       Asn : Node_Id;
8807 
8808    begin
8809       if Present (Ent) then
8810 
8811          --  Nothing to do if at the compilation unit level, because in this
8812          --  case the flag is set by the binder generated elaboration routine.
8813 
8814          if Nkind (Parent (N)) = N_Compilation_Unit then
8815             null;
8816 
8817          --  Here we do need to generate an assignment statement
8818 
8819          else
8820             Check_Restriction (No_Elaboration_Code, N);
8821             Asn :=
8822               Make_Assignment_Statement (Loc,
8823                 Name       => New_Occurrence_Of (Ent, Loc),
8824                 Expression => Make_Integer_Literal (Loc, Uint_1));
8825 
8826             if Nkind (Parent (N)) = N_Subunit then
8827                Insert_After (Corresponding_Stub (Parent (N)), Asn);
8828             else
8829                Insert_After (N, Asn);
8830             end if;
8831 
8832             Analyze (Asn);
8833 
8834             --  Kill current value indication. This is necessary because the
8835             --  tests of this flag are inserted out of sequence and must not
8836             --  pick up bogus indications of the wrong constant value.
8837 
8838             Set_Current_Value (Ent, Empty);
8839 
8840             --  If the subprogram is in the current declarative part and
8841             --  'access has been applied to it, generate an elaboration
8842             --  check at the beginning of the declarations of the body.
8843 
8844             if Nkind (N) = N_Subprogram_Body
8845               and then Address_Taken (Spec_Id)
8846               and then
8847                 Ekind_In (Scope (Spec_Id), E_Block, E_Procedure, E_Function)
8848             then
8849                declare
8850                   Loc   : constant Source_Ptr := Sloc (N);
8851                   Decls : constant List_Id    := Declarations (N);
8852                   Chk   : Node_Id;
8853 
8854                begin
8855                   --  No need to generate this check if first entry in the
8856                   --  declaration list is a raise of Program_Error now.
8857 
8858                   if Present (Decls)
8859                     and then Nkind (First (Decls)) = N_Raise_Program_Error
8860                   then
8861                      return;
8862                   end if;
8863 
8864                   --  Otherwise generate the check
8865 
8866                   Chk :=
8867                     Make_Raise_Program_Error (Loc,
8868                       Condition =>
8869                         Make_Op_Eq (Loc,
8870                           Left_Opnd  => New_Occurrence_Of (Ent, Loc),
8871                           Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
8872                       Reason    => PE_Access_Before_Elaboration);
8873 
8874                   if No (Decls) then
8875                      Set_Declarations (N, New_List (Chk));
8876                   else
8877                      Prepend (Chk, Decls);
8878                   end if;
8879 
8880                   Analyze (Chk);
8881                end;
8882             end if;
8883          end if;
8884       end if;
8885    end Set_Elaboration_Flag;
8886 
8887    ----------------------------
8888    -- Set_Renamed_Subprogram --
8889    ----------------------------
8890 
8891    procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
8892    begin
8893       --  If input node is an identifier, we can just reset it
8894 
8895       if Nkind (N) = N_Identifier then
8896          Set_Chars  (N, Chars (E));
8897          Set_Entity (N, E);
8898 
8899          --  Otherwise we have to do a rewrite, preserving Comes_From_Source
8900 
8901       else
8902          declare
8903             CS : constant Boolean := Comes_From_Source (N);
8904          begin
8905             Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
8906             Set_Entity (N, E);
8907             Set_Comes_From_Source (N, CS);
8908             Set_Analyzed (N, True);
8909          end;
8910       end if;
8911    end Set_Renamed_Subprogram;
8912 
8913    ----------------------
8914    -- Side_Effect_Free --
8915    ----------------------
8916 
8917    function Side_Effect_Free
8918      (N            : Node_Id;
8919       Name_Req     : Boolean := False;
8920       Variable_Ref : Boolean := False) return Boolean
8921    is
8922       Typ : constant Entity_Id := Etype (N);
8923       --  Result type of the expression
8924 
8925       function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
8926       --  The argument N is a construct where the Prefix is dereferenced if it
8927       --  is an access type and the result is a variable. The call returns True
8928       --  if the construct is side effect free (not considering side effects in
8929       --  other than the prefix which are to be tested by the caller).
8930 
8931       function Within_In_Parameter (N : Node_Id) return Boolean;
8932       --  Determines if N is a subcomponent of a composite in-parameter. If so,
8933       --  N is not side-effect free when the actual is global and modifiable
8934       --  indirectly from within a subprogram, because it may be passed by
8935       --  reference. The front-end must be conservative here and assume that
8936       --  this may happen with any array or record type. On the other hand, we
8937       --  cannot create temporaries for all expressions for which this
8938       --  condition is true, for various reasons that might require clearing up
8939       --  ??? For example, discriminant references that appear out of place, or
8940       --  spurious type errors with class-wide expressions. As a result, we
8941       --  limit the transformation to loop bounds, which is so far the only
8942       --  case that requires it.
8943 
8944       -----------------------------
8945       -- Safe_Prefixed_Reference --
8946       -----------------------------
8947 
8948       function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
8949       begin
8950          --  If prefix is not side effect free, definitely not safe
8951 
8952          if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then
8953             return False;
8954 
8955          --  If the prefix is of an access type that is not access-to-constant,
8956          --  then this construct is a variable reference, which means it is to
8957          --  be considered to have side effects if Variable_Ref is set True.
8958 
8959          elsif Is_Access_Type (Etype (Prefix (N)))
8960            and then not Is_Access_Constant (Etype (Prefix (N)))
8961            and then Variable_Ref
8962          then
8963             --  Exception is a prefix that is the result of a previous removal
8964             --  of side-effects.
8965 
8966             return Is_Entity_Name (Prefix (N))
8967               and then not Comes_From_Source (Prefix (N))
8968               and then Ekind (Entity (Prefix (N))) = E_Constant
8969               and then Is_Internal_Name (Chars (Entity (Prefix (N))));
8970 
8971          --  If the prefix is an explicit dereference then this construct is a
8972          --  variable reference, which means it is to be considered to have
8973          --  side effects if Variable_Ref is True.
8974 
8975          --  We do NOT exclude dereferences of access-to-constant types because
8976          --  we handle them as constant view of variables.
8977 
8978          elsif Nkind (Prefix (N)) = N_Explicit_Dereference
8979            and then Variable_Ref
8980          then
8981             return False;
8982 
8983          --  Note: The following test is the simplest way of solving a complex
8984          --  problem uncovered by the following test (Side effect on loop bound
8985          --  that is a subcomponent of a global variable:
8986 
8987          --    with Text_Io; use Text_Io;
8988          --    procedure Tloop is
8989          --      type X is
8990          --        record
8991          --          V : Natural := 4;
8992          --          S : String (1..5) := (others => 'a');
8993          --        end record;
8994          --      X1 : X;
8995 
8996          --      procedure Modi;
8997 
8998          --      generic
8999          --        with procedure Action;
9000          --      procedure Loop_G (Arg : X; Msg : String)
9001 
9002          --      procedure Loop_G (Arg : X; Msg : String) is
9003          --      begin
9004          --        Put_Line ("begin loop_g " & Msg & " will loop till: "
9005          --                  & Natural'Image (Arg.V));
9006          --        for Index in 1 .. Arg.V loop
9007          --          Text_Io.Put_Line
9008          --            (Natural'Image (Index) & " " & Arg.S (Index));
9009          --          if Index > 2 then
9010          --            Modi;
9011          --          end if;
9012          --        end loop;
9013          --        Put_Line ("end loop_g " & Msg);
9014          --      end;
9015 
9016          --      procedure Loop1 is new Loop_G (Modi);
9017          --      procedure Modi is
9018          --      begin
9019          --        X1.V := 1;
9020          --        Loop1 (X1, "from modi");
9021          --      end;
9022          --
9023          --    begin
9024          --      Loop1 (X1, "initial");
9025          --    end;
9026 
9027          --  The output of the above program should be:
9028 
9029          --    begin loop_g initial will loop till:  4
9030          --     1 a
9031          --     2 a
9032          --     3 a
9033          --    begin loop_g from modi will loop till:  1
9034          --     1 a
9035          --    end loop_g from modi
9036          --     4 a
9037          --    begin loop_g from modi will loop till:  1
9038          --     1 a
9039          --    end loop_g from modi
9040          --    end loop_g initial
9041 
9042          --  If a loop bound is a subcomponent of a global variable, a
9043          --  modification of that variable within the loop may incorrectly
9044          --  affect the execution of the loop.
9045 
9046          elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification
9047            and then Within_In_Parameter (Prefix (N))
9048            and then Variable_Ref
9049          then
9050             return False;
9051 
9052          --  All other cases are side effect free
9053 
9054          else
9055             return True;
9056          end if;
9057       end Safe_Prefixed_Reference;
9058 
9059       -------------------------
9060       -- Within_In_Parameter --
9061       -------------------------
9062 
9063       function Within_In_Parameter (N : Node_Id) return Boolean is
9064       begin
9065          if not Comes_From_Source (N) then
9066             return False;
9067 
9068          elsif Is_Entity_Name (N) then
9069             return Ekind (Entity (N)) = E_In_Parameter;
9070 
9071          elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
9072             return Within_In_Parameter (Prefix (N));
9073 
9074          else
9075             return False;
9076          end if;
9077       end Within_In_Parameter;
9078 
9079    --  Start of processing for Side_Effect_Free
9080 
9081    begin
9082       --  If volatile reference, always consider it to have side effects
9083 
9084       if Is_Volatile_Reference (N) then
9085          return False;
9086       end if;
9087 
9088       --  Note on checks that could raise Constraint_Error. Strictly, if we
9089       --  take advantage of 11.6, these checks do not count as side effects.
9090       --  However, we would prefer to consider that they are side effects,
9091       --  since the backend CSE does not work very well on expressions which
9092       --  can raise Constraint_Error. On the other hand if we don't consider
9093       --  them to be side effect free, then we get some awkward expansions
9094       --  in -gnato mode, resulting in code insertions at a point where we
9095       --  do not have a clear model for performing the insertions.
9096 
9097       --  Special handling for entity names
9098 
9099       if Is_Entity_Name (N) then
9100 
9101          --  A type reference is always side effect free
9102 
9103          if Is_Type (Entity (N)) then
9104             return True;
9105 
9106          --  Variables are considered to be a side effect if Variable_Ref
9107          --  is set or if we have a volatile reference and Name_Req is off.
9108          --  If Name_Req is True then we can't help returning a name which
9109          --  effectively allows multiple references in any case.
9110 
9111          elsif Is_Variable (N, Use_Original_Node => False) then
9112             return not Variable_Ref
9113               and then (not Is_Volatile_Reference (N) or else Name_Req);
9114 
9115          --  Any other entity (e.g. a subtype name) is definitely side
9116          --  effect free.
9117 
9118          else
9119             return True;
9120          end if;
9121 
9122       --  A value known at compile time is always side effect free
9123 
9124       elsif Compile_Time_Known_Value (N) then
9125          return True;
9126 
9127       --  A variable renaming is not side-effect free, because the renaming
9128       --  will function like a macro in the front-end in some cases, and an
9129       --  assignment can modify the component designated by N, so we need to
9130       --  create a temporary for it.
9131 
9132       --  The guard testing for Entity being present is needed at least in
9133       --  the case of rewritten predicate expressions, and may well also be
9134       --  appropriate elsewhere. Obviously we can't go testing the entity
9135       --  field if it does not exist, so it's reasonable to say that this is
9136       --  not the renaming case if it does not exist.
9137 
9138       elsif Is_Entity_Name (Original_Node (N))
9139         and then Present (Entity (Original_Node (N)))
9140         and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
9141         and then Ekind (Entity (Original_Node (N))) /= E_Constant
9142       then
9143          declare
9144             RO : constant Node_Id :=
9145                    Renamed_Object (Entity (Original_Node (N)));
9146 
9147          begin
9148             --  If the renamed object is an indexed component, or an
9149             --  explicit dereference, then the designated object could
9150             --  be modified by an assignment.
9151 
9152             if Nkind_In (RO, N_Indexed_Component,
9153                              N_Explicit_Dereference)
9154             then
9155                return False;
9156 
9157             --  A selected component must have a safe prefix
9158 
9159             elsif Nkind (RO) = N_Selected_Component then
9160                return Safe_Prefixed_Reference (RO);
9161 
9162             --  In all other cases, designated object cannot be changed so
9163             --  we are side effect free.
9164 
9165             else
9166                return True;
9167             end if;
9168          end;
9169 
9170       --  Remove_Side_Effects generates an object renaming declaration to
9171       --  capture the expression of a class-wide expression. In VM targets
9172       --  the frontend performs no expansion for dispatching calls to
9173       --  class- wide types since they are handled by the VM. Hence, we must
9174       --  locate here if this node corresponds to a previous invocation of
9175       --  Remove_Side_Effects to avoid a never ending loop in the frontend.
9176 
9177       elsif not Tagged_Type_Expansion
9178         and then not Comes_From_Source (N)
9179         and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
9180         and then Is_Class_Wide_Type (Typ)
9181       then
9182          return True;
9183 
9184       --  Generating C the type conversion of an access to constrained array
9185       --  type into an access to unconstrained array type involves initializing
9186       --  a fat pointer and the expression cannot be assumed to be free of side
9187       --  effects since it must referenced several times to compute its bounds.
9188 
9189       elsif Generate_C_Code
9190         and then Nkind (N) = N_Type_Conversion
9191         and then Is_Access_Type (Typ)
9192         and then Is_Array_Type (Designated_Type (Typ))
9193         and then not Is_Constrained (Designated_Type (Typ))
9194       then
9195          return False;
9196       end if;
9197 
9198       --  For other than entity names and compile time known values,
9199       --  check the node kind for special processing.
9200 
9201       case Nkind (N) is
9202 
9203          --  An attribute reference is side effect free if its expressions
9204          --  are side effect free and its prefix is side effect free or
9205          --  is an entity reference.
9206 
9207          --  Is this right? what about x'first where x is a variable???
9208 
9209          when N_Attribute_Reference =>
9210             return Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
9211               and then Attribute_Name (N) /= Name_Input
9212               and then (Is_Entity_Name (Prefix (N))
9213                          or else Side_Effect_Free
9214                                    (Prefix (N), Name_Req, Variable_Ref));
9215 
9216          --  A binary operator is side effect free if and both operands are
9217          --  side effect free. For this purpose binary operators include
9218          --  membership tests and short circuit forms.
9219 
9220          when N_Binary_Op | N_Membership_Test | N_Short_Circuit =>
9221             return Side_Effect_Free (Left_Opnd  (N), Name_Req, Variable_Ref)
9222                      and then
9223                    Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
9224 
9225          --  An explicit dereference is side effect free only if it is
9226          --  a side effect free prefixed reference.
9227 
9228          when N_Explicit_Dereference =>
9229             return Safe_Prefixed_Reference (N);
9230 
9231          --  An expression with action is side effect free if its expression
9232          --  is side effect free and it has no actions.
9233 
9234          when N_Expression_With_Actions =>
9235             return Is_Empty_List (Actions (N))
9236               and then
9237                 Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
9238 
9239          --  A call to _rep_to_pos is side effect free, since we generate
9240          --  this pure function call ourselves. Moreover it is critically
9241          --  important to make this exception, since otherwise we can have
9242          --  discriminants in array components which don't look side effect
9243          --  free in the case of an array whose index type is an enumeration
9244          --  type with an enumeration rep clause.
9245 
9246          --  All other function calls are not side effect free
9247 
9248          when N_Function_Call =>
9249             return Nkind (Name (N)) = N_Identifier
9250               and then Is_TSS (Name (N), TSS_Rep_To_Pos)
9251               and then
9252                 Side_Effect_Free
9253                   (First (Parameter_Associations (N)), Name_Req, Variable_Ref);
9254 
9255          --  An IF expression is side effect free if it's of a scalar type, and
9256          --  all its components are all side effect free (conditions and then
9257          --  actions and else actions). We restrict to scalar types, since it
9258          --  is annoying to deal with things like (if A then B else C)'First
9259          --  where the type involved is a string type.
9260 
9261          when N_If_Expression =>
9262             return Is_Scalar_Type (Typ)
9263               and then
9264                 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref);
9265 
9266          --  An indexed component is side effect free if it is a side
9267          --  effect free prefixed reference and all the indexing
9268          --  expressions are side effect free.
9269 
9270          when N_Indexed_Component =>
9271             return Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
9272               and then Safe_Prefixed_Reference (N);
9273 
9274          --  A type qualification is side effect free if the expression
9275          --  is side effect free.
9276 
9277          when N_Qualified_Expression =>
9278             return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
9279 
9280          --  A selected component is side effect free only if it is a side
9281          --  effect free prefixed reference.
9282 
9283          when N_Selected_Component =>
9284             return Safe_Prefixed_Reference (N);
9285 
9286          --  A range is side effect free if the bounds are side effect free
9287 
9288          when N_Range =>
9289             return Side_Effect_Free (Low_Bound (N),  Name_Req, Variable_Ref)
9290                      and then
9291                    Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref);
9292 
9293          --  A slice is side effect free if it is a side effect free
9294          --  prefixed reference and the bounds are side effect free.
9295 
9296          when N_Slice =>
9297             return Side_Effect_Free
9298                      (Discrete_Range (N), Name_Req, Variable_Ref)
9299               and then Safe_Prefixed_Reference (N);
9300 
9301          --  A type conversion is side effect free if the expression to be
9302          --  converted is side effect free.
9303 
9304          when N_Type_Conversion =>
9305             return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
9306 
9307          --  A unary operator is side effect free if the operand
9308          --  is side effect free.
9309 
9310          when N_Unary_Op =>
9311             return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
9312 
9313          --  An unchecked type conversion is side effect free only if it
9314          --  is safe and its argument is side effect free.
9315 
9316          when N_Unchecked_Type_Conversion =>
9317             return Safe_Unchecked_Type_Conversion (N)
9318               and then
9319                 Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
9320 
9321          --  An unchecked expression is side effect free if its expression
9322          --  is side effect free.
9323 
9324          when N_Unchecked_Expression =>
9325             return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
9326 
9327          --  A literal is side effect free
9328 
9329          when N_Character_Literal    |
9330               N_Integer_Literal      |
9331               N_Real_Literal         |
9332               N_String_Literal       =>
9333             return True;
9334 
9335          --  We consider that anything else has side effects. This is a bit
9336          --  crude, but we are pretty close for most common cases, and we
9337          --  are certainly correct (i.e. we never return True when the
9338          --  answer should be False).
9339 
9340          when others =>
9341             return False;
9342       end case;
9343    end Side_Effect_Free;
9344 
9345    --  A list is side effect free if all elements of the list are side
9346    --  effect free.
9347 
9348    function Side_Effect_Free
9349      (L            : List_Id;
9350       Name_Req     : Boolean := False;
9351       Variable_Ref : Boolean := False) return Boolean
9352    is
9353       N : Node_Id;
9354 
9355    begin
9356       if L = No_List or else L = Error_List then
9357          return True;
9358 
9359       else
9360          N := First (L);
9361          while Present (N) loop
9362             if not Side_Effect_Free (N, Name_Req, Variable_Ref) then
9363                return False;
9364             else
9365                Next (N);
9366             end if;
9367          end loop;
9368 
9369          return True;
9370       end if;
9371    end Side_Effect_Free;
9372 
9373    ----------------------------------
9374    -- Silly_Boolean_Array_Not_Test --
9375    ----------------------------------
9376 
9377    --  This procedure implements an odd and silly test. We explicitly check
9378    --  for the case where the 'First of the component type is equal to the
9379    --  'Last of this component type, and if this is the case, we make sure
9380    --  that constraint error is raised. The reason is that the NOT is bound
9381    --  to cause CE in this case, and we will not otherwise catch it.
9382 
9383    --  No such check is required for AND and OR, since for both these cases
9384    --  False op False = False, and True op True = True. For the XOR case,
9385    --  see Silly_Boolean_Array_Xor_Test.
9386 
9387    --  Believe it or not, this was reported as a bug. Note that nearly always,
9388    --  the test will evaluate statically to False, so the code will be
9389    --  statically removed, and no extra overhead caused.
9390 
9391    procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
9392       Loc : constant Source_Ptr := Sloc (N);
9393       CT  : constant Entity_Id  := Component_Type (T);
9394 
9395    begin
9396       --  The check we install is
9397 
9398       --    constraint_error when
9399       --      component_type'first = component_type'last
9400       --        and then array_type'Length /= 0)
9401 
9402       --  We need the last guard because we don't want to raise CE for empty
9403       --  arrays since no out of range values result. (Empty arrays with a
9404       --  component type of True .. True -- very useful -- even the ACATS
9405       --  does not test that marginal case).
9406 
9407       Insert_Action (N,
9408         Make_Raise_Constraint_Error (Loc,
9409           Condition =>
9410             Make_And_Then (Loc,
9411               Left_Opnd =>
9412                 Make_Op_Eq (Loc,
9413                   Left_Opnd =>
9414                     Make_Attribute_Reference (Loc,
9415                       Prefix         => New_Occurrence_Of (CT, Loc),
9416                       Attribute_Name => Name_First),
9417 
9418                   Right_Opnd =>
9419                     Make_Attribute_Reference (Loc,
9420                       Prefix         => New_Occurrence_Of (CT, Loc),
9421                       Attribute_Name => Name_Last)),
9422 
9423               Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
9424           Reason => CE_Range_Check_Failed));
9425    end Silly_Boolean_Array_Not_Test;
9426 
9427    ----------------------------------
9428    -- Silly_Boolean_Array_Xor_Test --
9429    ----------------------------------
9430 
9431    --  This procedure implements an odd and silly test. We explicitly check
9432    --  for the XOR case where the component type is True .. True, since this
9433    --  will raise constraint error. A special check is required since CE
9434    --  will not be generated otherwise (cf Expand_Packed_Not).
9435 
9436    --  No such check is required for AND and OR, since for both these cases
9437    --  False op False = False, and True op True = True, and no check is
9438    --  required for the case of False .. False, since False xor False = False.
9439    --  See also Silly_Boolean_Array_Not_Test
9440 
9441    procedure Silly_Boolean_Array_Xor_Test (N : Node_Id; T : Entity_Id) is
9442       Loc : constant Source_Ptr := Sloc (N);
9443       CT  : constant Entity_Id  := Component_Type (T);
9444 
9445    begin
9446       --  The check we install is
9447 
9448       --    constraint_error when
9449       --      Boolean (component_type'First)
9450       --        and then Boolean (component_type'Last)
9451       --        and then array_type'Length /= 0)
9452 
9453       --  We need the last guard because we don't want to raise CE for empty
9454       --  arrays since no out of range values result (Empty arrays with a
9455       --  component type of True .. True -- very useful -- even the ACATS
9456       --  does not test that marginal case).
9457 
9458       Insert_Action (N,
9459         Make_Raise_Constraint_Error (Loc,
9460           Condition =>
9461             Make_And_Then (Loc,
9462               Left_Opnd =>
9463                 Make_And_Then (Loc,
9464                   Left_Opnd =>
9465                     Convert_To (Standard_Boolean,
9466                       Make_Attribute_Reference (Loc,
9467                         Prefix         => New_Occurrence_Of (CT, Loc),
9468                         Attribute_Name => Name_First)),
9469 
9470                   Right_Opnd =>
9471                     Convert_To (Standard_Boolean,
9472                       Make_Attribute_Reference (Loc,
9473                         Prefix         => New_Occurrence_Of (CT, Loc),
9474                         Attribute_Name => Name_Last))),
9475 
9476               Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
9477           Reason => CE_Range_Check_Failed));
9478    end Silly_Boolean_Array_Xor_Test;
9479 
9480    --------------------------
9481    -- Target_Has_Fixed_Ops --
9482    --------------------------
9483 
9484    Integer_Sized_Small : Ureal;
9485    --  Set to 2.0 ** -(Integer'Size - 1) the first time that this function is
9486    --  called (we don't want to compute it more than once).
9487 
9488    Long_Integer_Sized_Small : Ureal;
9489    --  Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this function
9490    --  is called (we don't want to compute it more than once)
9491 
9492    First_Time_For_THFO : Boolean := True;
9493    --  Set to False after first call (if Fractional_Fixed_Ops_On_Target)
9494 
9495    function Target_Has_Fixed_Ops
9496      (Left_Typ   : Entity_Id;
9497       Right_Typ  : Entity_Id;
9498       Result_Typ : Entity_Id) return Boolean
9499    is
9500       function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
9501       --  Return True if the given type is a fixed-point type with a small
9502       --  value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
9503       --  an absolute value less than 1.0. This is currently limited to
9504       --  fixed-point types that map to Integer or Long_Integer.
9505 
9506       ------------------------
9507       -- Is_Fractional_Type --
9508       ------------------------
9509 
9510       function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
9511       begin
9512          if Esize (Typ) = Standard_Integer_Size then
9513             return Small_Value (Typ) = Integer_Sized_Small;
9514 
9515          elsif Esize (Typ) = Standard_Long_Integer_Size then
9516             return Small_Value (Typ) = Long_Integer_Sized_Small;
9517 
9518          else
9519             return False;
9520          end if;
9521       end Is_Fractional_Type;
9522 
9523    --  Start of processing for Target_Has_Fixed_Ops
9524 
9525    begin
9526       --  Return False if Fractional_Fixed_Ops_On_Target is false
9527 
9528       if not Fractional_Fixed_Ops_On_Target then
9529          return False;
9530       end if;
9531 
9532       --  Here the target has Fractional_Fixed_Ops, if first time, compute
9533       --  standard constants used by Is_Fractional_Type.
9534 
9535       if First_Time_For_THFO then
9536          First_Time_For_THFO := False;
9537 
9538          Integer_Sized_Small :=
9539            UR_From_Components
9540              (Num   => Uint_1,
9541               Den   => UI_From_Int (Standard_Integer_Size - 1),
9542               Rbase => 2);
9543 
9544          Long_Integer_Sized_Small :=
9545            UR_From_Components
9546              (Num   => Uint_1,
9547               Den   => UI_From_Int (Standard_Long_Integer_Size - 1),
9548               Rbase => 2);
9549       end if;
9550 
9551       --  Return True if target supports fixed-by-fixed multiply/divide for
9552       --  fractional fixed-point types (see Is_Fractional_Type) and the operand
9553       --  and result types are equivalent fractional types.
9554 
9555       return Is_Fractional_Type (Base_Type (Left_Typ))
9556         and then Is_Fractional_Type (Base_Type (Right_Typ))
9557         and then Is_Fractional_Type (Base_Type (Result_Typ))
9558         and then Esize (Left_Typ) = Esize (Right_Typ)
9559         and then Esize (Left_Typ) = Esize (Result_Typ);
9560    end Target_Has_Fixed_Ops;
9561 
9562    ------------------------------------------
9563    -- Type_May_Have_Bit_Aligned_Components --
9564    ------------------------------------------
9565 
9566    function Type_May_Have_Bit_Aligned_Components
9567      (Typ : Entity_Id) return Boolean
9568    is
9569    begin
9570       --  Array type, check component type
9571 
9572       if Is_Array_Type (Typ) then
9573          return
9574            Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
9575 
9576       --  Record type, check components
9577 
9578       elsif Is_Record_Type (Typ) then
9579          declare
9580             E : Entity_Id;
9581 
9582          begin
9583             E := First_Component_Or_Discriminant (Typ);
9584             while Present (E) loop
9585                if Component_May_Be_Bit_Aligned (E)
9586                  or else Type_May_Have_Bit_Aligned_Components (Etype (E))
9587                then
9588                   return True;
9589                end if;
9590 
9591                Next_Component_Or_Discriminant (E);
9592             end loop;
9593 
9594             return False;
9595          end;
9596 
9597       --  Type other than array or record is always OK
9598 
9599       else
9600          return False;
9601       end if;
9602    end Type_May_Have_Bit_Aligned_Components;
9603 
9604    ----------------------------------
9605    -- Within_Case_Or_If_Expression --
9606    ----------------------------------
9607 
9608    function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is
9609       Par : Node_Id;
9610 
9611    begin
9612       --  Locate an enclosing case or if expression. Note that these constructs
9613       --  can be expanded into Expression_With_Actions, hence the test of the
9614       --  original node.
9615 
9616       Par := Parent (N);
9617       while Present (Par) loop
9618          if Nkind_In (Original_Node (Par), N_Case_Expression,
9619                                            N_If_Expression)
9620          then
9621             return True;
9622 
9623          --  Prevent the search from going too far
9624 
9625          elsif Is_Body_Or_Package_Declaration (Par) then
9626             return False;
9627          end if;
9628 
9629          Par := Parent (Par);
9630       end loop;
9631 
9632       return False;
9633    end Within_Case_Or_If_Expression;
9634 
9635    --------------------------------
9636    -- Within_Internal_Subprogram --
9637    --------------------------------
9638 
9639    function Within_Internal_Subprogram return Boolean is
9640       S : Entity_Id;
9641 
9642    begin
9643       S := Current_Scope;
9644       while Present (S) and then not Is_Subprogram (S) loop
9645          S := Scope (S);
9646       end loop;
9647 
9648       return Present (S)
9649         and then Get_TSS_Name (S) /= TSS_Null
9650         and then not Is_Predicate_Function (S)
9651         and then not Is_Predicate_Function_M (S);
9652    end Within_Internal_Subprogram;
9653 
9654 end Exp_Util;