------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ U T I L                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2023, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Accessibility;  use Accessibility;
with Casing;         use Casing;
with Checks;         use Checks;
with Debug;          use Debug;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Erroutc;        use Erroutc;
with Exp_Ch6;        use Exp_Ch6;
with Exp_Ch11;       use Exp_Ch11;
with Exp_Util;       use Exp_Util;
with Fname;          use Fname;
with Freeze;         use Freeze;
with Itypes;         use Itypes;
with Lib;            use Lib;
with Lib.Xref;       use Lib.Xref;
with Namet.Sp;       use Namet.Sp;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Output;         use Output;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Attr;       use Sem_Attr;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch13;       use Sem_Ch13;
with Sem_Disp;       use Sem_Disp;
with Sem_Elab;       use Sem_Elab;
with Sem_Eval;       use Sem_Eval;
with Sem_Prag;       use Sem_Prag;
with Sem_Res;        use Sem_Res;
with Sem_Warn;       use Sem_Warn;
with Sem_Type;       use Sem_Type;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Stand;          use Stand;
with Style;
with Stringt;        use Stringt;
with Targparm;       use Targparm;
with Tbuild;         use Tbuild;
with Ttypes;         use Ttypes;
with Uname;          use Uname;
with Warnsw;         use Warnsw;

with GNAT.Heap_Sort_G;
with GNAT.HTable;    use GNAT.HTable;

package body Sem_Util is

   ---------------------------
   -- Local Data Structures --
   ---------------------------

   Invalid_Binder_Values : array (Scalar_Id) of Entity_Id := (others => Empty);
   --  A collection to hold the entities of the variables declared in package
   --  System.Scalar_Values which describe the invalid values of scalar types.

   Invalid_Binder_Values_Set : Boolean := False;
   --  This flag prevents multiple attempts to initialize Invalid_Binder_Values

   Invalid_Floats : array (Float_Scalar_Id) of Ureal := (others => No_Ureal);
   --  A collection to hold the invalid values of float types as specified by
   --  pragma Initialize_Scalars.

   Invalid_Integers : array (Integer_Scalar_Id) of Uint := (others => No_Uint);
   --  A collection to hold the invalid values of integer types as specified
   --  by pragma Initialize_Scalars.

   -----------------------
   -- Local Subprograms --
   -----------------------

   function Build_Component_Subtype
     (C   : List_Id;
      Loc : Source_Ptr;
      T   : Entity_Id) return Node_Id;
   --  This function builds the subtype for Build_Actual_Subtype_Of_Component
   --  and Build_Discriminal_Subtype_Of_Component. C is a list of constraints,
   --  Loc is the source location, T is the original subtype.

   procedure Examine_Array_Bounds
     (Typ        : Entity_Id;
      All_Static : out Boolean;
      Has_Empty  : out Boolean);
   --  Inspect the index constraints of array type Typ. Flag All_Static is set
   --  when all ranges are static. Flag Has_Empty is set only when All_Static
   --  is set and indicates that at least one range is empty.

   function Has_Enabled_Property
     (Item_Id  : Entity_Id;
      Property : Name_Id) return Boolean;
   --  Subsidiary to routines Async_xxx_Enabled and Effective_xxx_Enabled.
   --  Determine whether the state abstraction, object, or type denoted by
   --  entity Item_Id has enabled property Property.

   function Has_Null_Extension (T : Entity_Id) return Boolean;
   --  T is a derived tagged type. Check whether the type extension is null.
   --  If the parent type is fully initialized, T can be treated as such.

   function Is_Atomic_Object_Entity (Id : Entity_Id) return Boolean;
   --  Determine whether arbitrary entity Id denotes an atomic object as per
   --  RM C.6(7).

   generic
      with function Is_Effectively_Volatile_Entity
        (Id : Entity_Id) return Boolean;
      --  Function to use on object and type entities
   function Is_Effectively_Volatile_Object_Shared
     (N : Node_Id) return Boolean;
   --  Shared function used to detect effectively volatile objects and
   --  effectively volatile objects for reading.

   function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean;
   --  Subsidiary to Is_Fully_Initialized_Type. For an unconstrained type
   --  with discriminants whose default values are static, examine only the
   --  components in the selected variant to determine whether all of them
   --  have a default.

   function Is_Preelaborable_Function (Id : Entity_Id) return Boolean;
   --  Ada 2022: Determine whether the specified function is suitable as the
   --  name of a call in a preelaborable construct (RM 10.2.1(7/5)).

   type Null_Status_Kind is
     (Is_Null,
      --  This value indicates that a subexpression is known to have a null
      --  value at compile time.

      Is_Non_Null,
      --  This value indicates that a subexpression is known to have a non-null
      --  value at compile time.

      Unknown);
      --  This value indicates that it cannot be determined at compile time
      --  whether a subexpression yields a null or non-null value.

   function Null_Status (N : Node_Id) return Null_Status_Kind;
   --  Determine whether subexpression N of an access type yields a null value,
   --  a non-null value, or the value cannot be determined at compile time. The
   --  routine does not take simple flow diagnostics into account, it relies on
   --  static facts such as the presence of null exclusions.

   function Subprogram_Name (N : Node_Id) return String;
   --  Return the fully qualified name of the enclosing subprogram for the
   --  given node N, with file:line:col information appended, e.g.
   --  "subp:file:line:col", corresponding to the source location of the
   --  body of the subprogram.

   -----------------------------
   -- Abstract_Interface_List --
   -----------------------------

   function Abstract_Interface_List (Typ : Entity_Id) return List_Id is
      Nod : Node_Id;

   begin
      if Is_Concurrent_Type (Typ) then

         --  If we are dealing with a synchronized subtype, go to the base
         --  type, whose declaration has the interface list.

         Nod := Declaration_Node (Base_Type (Typ));

         if Nkind (Nod) in N_Full_Type_Declaration | N_Private_Type_Declaration
         then
            return Empty_List;
         end if;

      elsif Ekind (Typ) = E_Record_Type_With_Private then
         if Nkind (Parent (Typ)) = N_Full_Type_Declaration then
            Nod := Type_Definition (Parent (Typ));

         elsif Nkind (Parent (Typ)) = N_Private_Type_Declaration then
            if Present (Full_View (Typ))
              and then
                Nkind (Parent (Full_View (Typ))) = N_Full_Type_Declaration
            then
               Nod := Type_Definition (Parent (Full_View (Typ)));

            --  If the full-view is not available we cannot do anything else
            --  here (the source has errors).

            else
               return Empty_List;
            end if;

         --  Support for generic formals with interfaces is still missing ???

         elsif Nkind (Parent (Typ)) = N_Formal_Type_Declaration then
            return Empty_List;

         else
            pragma Assert
              (Nkind (Parent (Typ)) = N_Private_Extension_Declaration);
            Nod := Parent (Typ);
         end if;

      elsif Ekind (Typ) = E_Record_Subtype then
         Nod := Type_Definition (Parent (Etype (Typ)));

      elsif Ekind (Typ) = E_Record_Subtype_With_Private then

         --  Recurse, because parent may still be a private extension. Also
         --  note that the full view of the subtype or the full view of its
         --  base type may (both) be unavailable.

         return Abstract_Interface_List (Etype (Typ));

      elsif Ekind (Typ) = E_Record_Type then
         if Nkind (Parent (Typ)) = N_Formal_Type_Declaration then
            Nod := Formal_Type_Definition (Parent (Typ));
         else
            Nod := Type_Definition (Parent (Typ));
         end if;

      --  Otherwise the type is of a kind which does not implement interfaces

      else
         return Empty_List;
      end if;

      return Interface_List (Nod);
   end Abstract_Interface_List;

   ----------------------------------
   -- Acquire_Warning_Match_String --
   ----------------------------------

   function Acquire_Warning_Match_String (Str_Lit : Node_Id) return String is
      S : constant String := To_String (Strval (Str_Lit));
   begin
      if S = "" then
         return "";
      else
         --  Put "*" before or after or both, if it's not already there

         declare
            F : constant Boolean := S (S'First) = '*';
            L : constant Boolean := S (S'Last) = '*';
         begin
            if F then
               if L then
                  return S;
               else
                  return S & "*";
               end if;
            else
               if L then
                  return "*" & S;
               else
                  return "*" & S & "*";
               end if;
            end if;
         end;
      end if;
   end Acquire_Warning_Match_String;

   --------------------------------
   -- Add_Access_Type_To_Process --
   --------------------------------

   procedure Add_Access_Type_To_Process (E : Entity_Id; A : Entity_Id) is
      L : Elist_Id;

   begin
      Ensure_Freeze_Node (E);
      L := Access_Types_To_Process (Freeze_Node (E));

      if No (L) then
         L := New_Elmt_List;
         Set_Access_Types_To_Process (Freeze_Node (E), L);
      end if;

      Append_Elmt (A, L);
   end Add_Access_Type_To_Process;

   --------------------------
   -- Add_Block_Identifier --
   --------------------------

   procedure Add_Block_Identifier
     (N     : Node_Id;
      Id    : out Entity_Id;
      Scope : Entity_Id := Current_Scope)
   is
      Loc : constant Source_Ptr := Sloc (N);

   begin
      pragma Assert (Nkind (N) = N_Block_Statement);

      --  The block already has a label, return its entity

      if Present (Identifier (N)) then
         Id := Entity (Identifier (N));

      --  Create a new block label and set its attributes

      else
         Id := New_Internal_Entity (E_Block, Scope, Loc, 'B');
         Set_Etype  (Id, Standard_Void_Type);
         Set_Parent (Id, N);
         Set_Identifier (N, New_Occurrence_Of (Id, Loc));
         Set_Block_Node (Id, Identifier (N));
      end if;
   end Add_Block_Identifier;

   ----------------------------
   -- Add_Global_Declaration --
   ----------------------------

   procedure Add_Global_Declaration (N : Node_Id) is
      Aux_Node : constant Node_Id := Aux_Decls_Node (Cunit (Current_Sem_Unit));

   begin
      if No (Declarations (Aux_Node)) then
         Set_Declarations (Aux_Node, New_List);
      end if;

      Append_To (Declarations (Aux_Node), N);
      Analyze (N);
   end Add_Global_Declaration;

   --------------------------------
   -- Address_Integer_Convert_OK --
   --------------------------------

   function Address_Integer_Convert_OK (T1, T2 : Entity_Id) return Boolean is
   begin
      if Allow_Integer_Address
        and then ((Is_Descendant_Of_Address  (T1)
                    and then Is_Private_Type (T1)
                    and then Is_Integer_Type (T2))
                            or else
                  (Is_Descendant_Of_Address  (T2)
                    and then Is_Private_Type (T2)
                    and then Is_Integer_Type (T1)))
      then
         return True;
      else
         return False;
      end if;
   end Address_Integer_Convert_OK;

   -------------------
   -- Address_Value --
   -------------------

   function Address_Value (N : Node_Id) return Node_Id is
      Expr : Node_Id := N;

   begin
      loop
         --  For constant, get constant expression

         if Is_Entity_Name (Expr)
           and then Ekind (Entity (Expr)) = E_Constant
         then
            Expr := Constant_Value (Entity (Expr));

         --  For unchecked conversion, get result to convert

         elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
            Expr := Expression (Expr);

         --  For (common case) of To_Address call, get argument

         elsif Nkind (Expr) = N_Function_Call
           and then Is_Entity_Name (Name (Expr))
           and then Is_RTE (Entity (Name (Expr)), RE_To_Address)
         then
            Expr := First_Actual (Expr);

         --  We finally have the real expression

         else
            exit;
         end if;
      end loop;

      return Expr;
   end Address_Value;

   -----------------
   -- Addressable --
   -----------------

   function Addressable (V : Uint) return Boolean is
   begin
      if No (V) then
         return False;
      end if;

      return V = Uint_8  or else
             V = Uint_16 or else
             V = Uint_32 or else
             V = Uint_64 or else
             (V = Uint_128 and then System_Max_Integer_Size = 128);
   end Addressable;

   function Addressable (V : Int) return Boolean is
   begin
      return V = 8  or else
             V = 16 or else
             V = 32 or else
             V = 64 or else
             V = System_Max_Integer_Size;
   end Addressable;

   ---------------------------------
   -- Aggregate_Constraint_Checks --
   ---------------------------------

   procedure Aggregate_Constraint_Checks
     (Exp       : Node_Id;
      Check_Typ : Entity_Id)
   is
      Exp_Typ : constant Entity_Id := Etype (Exp);

   begin
      if Raises_Constraint_Error (Exp) then
         return;
      end if;

      --  Ada 2005 (AI-230): Generate a conversion to an anonymous access
      --  component's type to force the appropriate accessibility checks.

      --  Ada 2005 (AI-231): Generate conversion to the null-excluding type to
      --  force the corresponding run-time check

      if Is_Access_Type (Check_Typ)
        and then Is_Local_Anonymous_Access (Check_Typ)
      then
         Rewrite (Exp, Convert_To (Check_Typ, Relocate_Node (Exp)));
         Analyze_And_Resolve (Exp, Check_Typ);
         Check_Unset_Reference (Exp);
      end if;

      --  What follows is really expansion activity, so check that expansion
      --  is on and is allowed. In GNATprove mode, we also want check flags to
      --  be added in the tree, so that the formal verification can rely on
      --  those to be present. In GNATprove mode for formal verification, some
      --  treatment typically only done during expansion needs to be performed
      --  on the tree, but it should not be applied inside generics. Otherwise,
      --  this breaks the name resolution mechanism for generic instances.

      if not Expander_Active
        and not (GNATprove_Mode and not Inside_A_Generic)
      then
         return;
      end if;

      if Is_Access_Type (Check_Typ)
        and then Can_Never_Be_Null (Check_Typ)
        and then not Can_Never_Be_Null (Exp_Typ)
      then
         Install_Null_Excluding_Check (Exp);
      end if;

      --  First check if we have to insert discriminant checks

      if Has_Discriminants (Exp_Typ) then
         Apply_Discriminant_Check (Exp, Check_Typ);

      --  Next emit length checks for array aggregates

      elsif Is_Array_Type (Exp_Typ) then
         Apply_Length_Check (Exp, Check_Typ);

      --  Finally emit scalar and string checks. If we are dealing with a
      --  scalar literal we need to check by hand because the Etype of
      --  literals is not necessarily correct.

      elsif Is_Scalar_Type (Exp_Typ)
        and then Compile_Time_Known_Value (Exp)
      then
         if Is_Out_Of_Range (Exp, Base_Type (Check_Typ)) then
            Apply_Compile_Time_Constraint_Error
              (Exp, "value not in range of}??", CE_Range_Check_Failed,
               Ent => Base_Type (Check_Typ),
               Typ => Base_Type (Check_Typ));

         elsif Is_Out_Of_Range (Exp, Check_Typ) then
            Apply_Compile_Time_Constraint_Error
              (Exp, "value not in range of}??", CE_Range_Check_Failed,
               Ent => Check_Typ,
               Typ => Check_Typ);

         elsif not Range_Checks_Suppressed (Check_Typ) then
            Apply_Scalar_Range_Check (Exp, Check_Typ);
         end if;

      --  Verify that target type is also scalar, to prevent view anomalies
      --  in instantiations.

      elsif (Is_Scalar_Type (Exp_Typ)
              or else Nkind (Exp) = N_String_Literal)
        and then Is_Scalar_Type (Check_Typ)
        and then Exp_Typ /= Check_Typ
      then
         --  If expression is a constant, it is worthwhile checking whether it
         --  is a bound of the type.

         if Is_Entity_Name (Exp)
           and then Ekind (Entity (Exp)) = E_Constant
         then
            if (Is_Entity_Name (Type_Low_Bound (Check_Typ))
                 and then Entity (Exp) = Entity (Type_Low_Bound (Check_Typ)))
              or else
               (Is_Entity_Name (Type_High_Bound (Check_Typ))
                 and then Entity (Exp) = Entity (Type_High_Bound (Check_Typ)))
            then
               return;
            end if;
         end if;

         --  Change Exp into Check_Typ'(Exp) to ensure that range checks are
         --  performed at run time.

         Rewrite (Exp, Convert_To (Check_Typ, Relocate_Node (Exp)));
         Analyze_And_Resolve (Exp, Check_Typ);
         Check_Unset_Reference (Exp);

      end if;
   end Aggregate_Constraint_Checks;

   -----------------------
   -- Alignment_In_Bits --
   -----------------------

   function Alignment_In_Bits (E : Entity_Id) return Uint is
   begin
      return Alignment (E) * System_Storage_Unit;
   end Alignment_In_Bits;

   --------------------------------------
   -- All_Composite_Constraints_Static --
   --------------------------------------

   function All_Composite_Constraints_Static
     (Constr : Node_Id) return Boolean
   is
   begin
      if No (Constr) or else Error_Posted (Constr) then
         return True;
      end if;

      case Nkind (Constr) is
         when N_Subexpr =>
            if Nkind (Constr) in N_Has_Entity
              and then Present (Entity (Constr))
            then
               if Is_Type (Entity (Constr)) then
                  return
                    not Is_Discrete_Type (Entity (Constr))
                      or else Is_OK_Static_Subtype (Entity (Constr));
               end if;

            elsif Nkind (Constr) = N_Range then
               return
                 Is_OK_Static_Expression (Low_Bound (Constr))
                   and then
                 Is_OK_Static_Expression (High_Bound (Constr));

            elsif Nkind (Constr) = N_Attribute_Reference
              and then Attribute_Name (Constr) = Name_Range
            then
               return
                 Is_OK_Static_Expression
                   (Type_Low_Bound (Etype (Prefix (Constr))))
                     and then
                 Is_OK_Static_Expression
                   (Type_High_Bound (Etype (Prefix (Constr))));
            end if;

            return
              No (Etype (Constr)) -- previous error
                or else not Is_Discrete_Type (Etype (Constr))
                or else Is_OK_Static_Expression (Constr);

         when N_Discriminant_Association =>
            return All_Composite_Constraints_Static (Expression (Constr));

         when N_Range_Constraint =>
            return
              All_Composite_Constraints_Static (Range_Expression (Constr));

         when N_Index_Or_Discriminant_Constraint =>
            declare
               One_Cstr : Entity_Id;
            begin
               One_Cstr := First (Constraints (Constr));
               while Present (One_Cstr) loop
                  if not All_Composite_Constraints_Static (One_Cstr) then
                     return False;
                  end if;

                  Next (One_Cstr);
               end loop;
            end;

            return True;

         when N_Subtype_Indication =>
            return
              All_Composite_Constraints_Static (Subtype_Mark (Constr))
                and then
              All_Composite_Constraints_Static (Constraint (Constr));

         when others =>
            raise Program_Error;
      end case;
   end All_Composite_Constraints_Static;

   ------------------------
   -- Append_Entity_Name --
   ------------------------

   procedure Append_Entity_Name (Buf : in out Bounded_String; E : Entity_Id) is
      Temp : Bounded_String;

      procedure Inner (E : Entity_Id);
      --  Inner recursive routine, keep outer routine nonrecursive to ease
      --  debugging when we get strange results from this routine.

      -----------
      -- Inner --
      -----------

      procedure Inner (E : Entity_Id) is
         Scop : Node_Id;

      begin
         --  If entity has an internal name, skip by it, and print its scope.
         --  Note that we strip a final R from the name before the test; this
         --  is needed for some cases of instantiations.

         declare
            E_Name : Bounded_String;

         begin
            Append (E_Name, Chars (E));

            if E_Name.Chars (E_Name.Length) = 'R' then
               E_Name.Length := E_Name.Length - 1;
            end if;

            if Is_Internal_Name (E_Name) then
               Inner (Scope (E));
               return;
            end if;
         end;

         Scop := Scope (E);

         --  Just print entity name if its scope is at the outer level

         if Scop = Standard_Standard then
            null;

         --  If scope comes from source, write scope and entity

         elsif Comes_From_Source (Scop) then
            Append_Entity_Name (Temp, Scop);
            Append (Temp, '.');

         --  If in wrapper package skip past it

         elsif Present (Scop) and then Is_Wrapper_Package (Scop) then
            Append_Entity_Name (Temp, Scope (Scop));
            Append (Temp, '.');

         --  Otherwise nothing to output (happens in unnamed block statements)

         else
            null;
         end if;

         --  Output the name

         declare
            E_Name : Bounded_String;

         begin
            Append_Unqualified_Decoded (E_Name, Chars (E));

            --  Remove trailing upper-case letters from the name (useful for
            --  dealing with some cases of internal names generated in the case
            --  of references from within a generic).

            while E_Name.Length > 1
              and then E_Name.Chars (E_Name.Length) in 'A' .. 'Z'
            loop
               E_Name.Length := E_Name.Length - 1;
            end loop;

            --  Adjust casing appropriately (gets name from source if possible)

            Adjust_Name_Case (E_Name, Sloc (E));
            Append (Temp, E_Name);
         end;
      end Inner;

   --  Start of processing for Append_Entity_Name

   begin
      Inner (E);
      Append (Buf, Temp);
   end Append_Entity_Name;

   ---------------------------------
   -- Append_Inherited_Subprogram --
   ---------------------------------

   procedure Append_Inherited_Subprogram (S : Entity_Id) is
      Par : constant Entity_Id := Alias (S);
      --  The parent subprogram

      Scop : constant Entity_Id := Scope (Par);
      --  The scope of definition of the parent subprogram

      Typ : constant Entity_Id := Defining_Entity (Parent (S));
      --  The derived type of which S is a primitive operation

      Decl   : Node_Id;
      Next_E : Entity_Id;

   begin
      if Ekind (Current_Scope) = E_Package
        and then In_Private_Part (Current_Scope)
        and then Has_Private_Declaration (Typ)
        and then Is_Tagged_Type (Typ)
        and then Scop = Current_Scope
      then
         --  The inherited operation is available at the earliest place after
         --  the derived type declaration (RM 7.3.1 (6/1)). This is only
         --  relevant for type extensions. If the parent operation appears
         --  after the type extension, the operation is not visible.

         Decl := First
                   (Visible_Declarations
                     (Package_Specification (Current_Scope)));
         while Present (Decl) loop
            if Nkind (Decl) = N_Private_Extension_Declaration
              and then Defining_Entity (Decl) = Typ
            then
               if Sloc (Decl) > Sloc (Par) then
                  Next_E := Next_Entity (Par);
                  Link_Entities (Par, S);
                  Link_Entities (S, Next_E);
                  return;

               else
                  exit;
               end if;
            end if;

            Next (Decl);
         end loop;
      end if;

      --  If partial view is not a type extension, or it appears before the
      --  subprogram declaration, insert normally at end of entity list.

      Append_Entity (S, Current_Scope);
   end Append_Inherited_Subprogram;

   -----------------------------------------
   -- Apply_Compile_Time_Constraint_Error --
   -----------------------------------------

   procedure Apply_Compile_Time_Constraint_Error
     (N            : Node_Id;
      Msg          : String;
      Reason       : RT_Exception_Code;
      Ent          : Entity_Id  := Empty;
      Typ          : Entity_Id  := Empty;
      Loc          : Source_Ptr := No_Location;
      Warn         : Boolean    := False;
      Emit_Message : Boolean    := True)
   is
      Stat   : constant Boolean := Is_Static_Expression (N);
      R_Stat : constant Node_Id :=
                 Make_Raise_Constraint_Error (Sloc (N), Reason => Reason);
      Rtyp   : Entity_Id;

   begin
      if No (Typ) then
         Rtyp := Etype (N);
      else
         Rtyp := Typ;
      end if;

      if Emit_Message then
         Discard_Node
           (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn));
      end if;

      --  Now we replace the node by an N_Raise_Constraint_Error node
      --  This does not need reanalyzing, so set it as analyzed now.

      Rewrite (N, R_Stat);
      Set_Analyzed (N, True);

      Set_Etype (N, Rtyp);
      Set_Raises_Constraint_Error (N);

      --  Now deal with possible local raise handling

      Possible_Local_Raise (N, Standard_Constraint_Error);

      --  If the original expression was marked as static, the result is
      --  still marked as static, but the Raises_Constraint_Error flag is
      --  always set so that further static evaluation is not attempted.

      if Stat then
         Set_Is_Static_Expression (N);
      end if;
   end Apply_Compile_Time_Constraint_Error;

   ---------------------------
   -- Async_Readers_Enabled --
   ---------------------------

   function Async_Readers_Enabled (Id : Entity_Id) return Boolean is
   begin
      return Has_Enabled_Property (Id, Name_Async_Readers);
   end Async_Readers_Enabled;

   ---------------------------
   -- Async_Writers_Enabled --
   ---------------------------

   function Async_Writers_Enabled (Id : Entity_Id) return Boolean is
   begin
      return Has_Enabled_Property (Id, Name_Async_Writers);
   end Async_Writers_Enabled;

   --------------------------------------
   -- Available_Full_View_Of_Component --
   --------------------------------------

   function Available_Full_View_Of_Component (T : Entity_Id) return Boolean is
      ST  : constant Entity_Id := Scope (T);
      SCT : constant Entity_Id := Scope (Component_Type (T));
   begin
      return In_Open_Scopes (ST)
        and then In_Open_Scopes (SCT)
        and then Scope_Depth (ST) >= Scope_Depth (SCT);
   end Available_Full_View_Of_Component;

   ----------------
   -- Bad_Aspect --
   ----------------

   procedure Bad_Aspect
     (N    : Node_Id;
      Nam  : Name_Id;
      Warn : Boolean := False)
   is
   begin
      Error_Msg_Warn := Warn;
      Error_Msg_N ("<<& is not a valid aspect identifier", N);

      --  Check bad spelling
      Error_Msg_Name_1 := Aspect_Spell_Check (Nam);
      if Error_Msg_Name_1 /= No_Name then
         Error_Msg_N -- CODEFIX
            ("\<<possible misspelling of %", N);
      end if;
   end Bad_Aspect;

   -------------------
   -- Bad_Attribute --
   -------------------

   procedure Bad_Attribute
     (N    : Node_Id;
      Nam  : Name_Id;
      Warn : Boolean := False)
   is
   begin
      Error_Msg_Warn := Warn;
      Error_Msg_N ("<<unrecognized attribute&", N);

      --  Check for possible misspelling

      Error_Msg_Name_1 := Attribute_Spell_Check (Nam);
      if Error_Msg_Name_1 /= No_Name then
         Error_Msg_N -- CODEFIX
            ("\<<possible misspelling of %", N);
      end if;
   end Bad_Attribute;

   --------------------------------
   -- Bad_Predicated_Subtype_Use --
   --------------------------------

   procedure Bad_Predicated_Subtype_Use
     (Msg            : String;
      N              : Node_Id;
      Typ            : Entity_Id;
      Suggest_Static : Boolean := False)
   is
      Gen : Entity_Id;

   begin
      --  Avoid cascaded errors

      if Error_Posted (N) then
         return;
      end if;

      if Inside_A_Generic then
         Gen := Current_Scope;
         while Present (Gen) and then Ekind (Gen) /= E_Generic_Package loop
            Gen := Scope (Gen);
         end loop;

         if No (Gen) then
            return;
         end if;

         if Is_Generic_Formal (Typ) and then Is_Discrete_Type (Typ) then
            Set_No_Predicate_On_Actual (Typ);
         end if;

      elsif Has_Predicates (Typ) then
         if Is_Generic_Actual_Type (Typ) then

            --  The restriction on loop parameters is only that the type
            --  should only have static predicates.

            if Nkind (Parent (N)) = N_Loop_Parameter_Specification
              and then not Has_Dynamic_Predicate_Aspect (Typ)
              and then not Has_Ghost_Predicate_Aspect (Typ)
              and then Is_OK_Static_Subtype (Typ)
            then
               return;
            end if;

            Gen := Current_Scope;
            while not Is_Generic_Instance (Gen) loop
               Gen := Scope (Gen);
            end loop;

            pragma Assert (Present (Gen));

            if Ekind (Gen) = E_Package and then In_Package_Body (Gen) then
               Error_Msg_Warn := SPARK_Mode /= On;
               Error_Msg_FE (Msg & "<<", N, Typ);
               Error_Msg_F ("\Program_Error [<<", N);

               Insert_Action (N,
                 Make_Raise_Program_Error (Sloc (N),
                   Reason => PE_Bad_Predicated_Generic_Type));

            else
               Error_Msg_FE (Msg, N, Typ);
            end if;

         else
            Error_Msg_FE (Msg, N, Typ);
         end if;

         --  Suggest to use First_Valid/Last_Valid instead of First/Last/Range
         --  if the predicate is static.

         if not Has_Dynamic_Predicate_Aspect (Typ)
           and then not Has_Ghost_Predicate_Aspect (Typ)
           and then Has_Static_Predicate (Typ)
           and then Nkind (N) = N_Attribute_Reference
         then
            declare
               Aname   : constant Name_Id := Attribute_Name (N);
               Attr_Id : constant Attribute_Id := Get_Attribute_Id (Aname);
            begin
               case Attr_Id is
                  when Attribute_First =>
                     Error_Msg_F ("\use attribute First_Valid instead", N);
                  when Attribute_Last =>
                     Error_Msg_F ("\use attribute Last_Valid instead", N);
                  when Attribute_Range =>
                     Error_Msg_F ("\use attributes First_Valid and "
                                  & "Last_Valid instead", N);
                  when others =>
                     null;
               end case;
            end;
         end if;

         --  Emit an optional suggestion on how to remedy the error if the
         --  context warrants it.

         if Suggest_Static and then Has_Static_Predicate (Typ) then
            Error_Msg_FE ("\predicate of & should be marked static", N, Typ);
         end if;
      end if;
   end Bad_Predicated_Subtype_Use;

   -----------------------------------------
   -- Bad_Unordered_Enumeration_Reference --
   -----------------------------------------

   function Bad_Unordered_Enumeration_Reference
     (N : Node_Id;
      T : Entity_Id) return Boolean
   is
   begin
      return Is_Enumeration_Type (T)
        and then Warn_On_Unordered_Enumeration_Type
        and then not Is_Generic_Type (T)
        and then Comes_From_Source (N)
        and then not Has_Pragma_Ordered (T)
        and then not In_Same_Extended_Unit (N, T);
   end Bad_Unordered_Enumeration_Reference;

   ----------------------------
   -- Begin_Keyword_Location --
   ----------------------------

   function Begin_Keyword_Location (N : Node_Id) return Source_Ptr is
      HSS : Node_Id;

   begin
      pragma Assert
        (Nkind (N) in
           N_Block_Statement |
           N_Entry_Body      |
           N_Package_Body    |
           N_Subprogram_Body |
           N_Task_Body);

      HSS := Handled_Statement_Sequence (N);

      --  When the handled sequence of statements comes from source, the
      --  location of the "begin" keyword is that of the sequence itself.
      --  Note that an internal construct may inherit a source sequence.

      if Comes_From_Source (HSS) then
         return Sloc (HSS);

      --  The parser generates an internal handled sequence of statements to
      --  capture the location of the "begin" keyword if present in the source.
      --  Since there are no source statements, the location of the "begin"
      --  keyword is effectively that of the "end" keyword.

      elsif Comes_From_Source (N) then
         return Sloc (HSS);

      --  Otherwise the construct is internal and should carry the location of
      --  the original construct which prompted its creation.

      else
         return Sloc (N);
      end if;
   end Begin_Keyword_Location;

   --------------------------
   -- Build_Actual_Subtype --
   --------------------------

   function Build_Actual_Subtype
     (T : Entity_Id;
      N : Node_Or_Entity_Id) return Node_Id
   is
      Loc : Source_Ptr;
      --  Normally Sloc (N), but may point to corresponding body in some cases

      Constraints : List_Id;
      Decl        : Node_Id;
      Discr       : Entity_Id;
      Hi          : Node_Id;
      Lo          : Node_Id;
      Subt        : Entity_Id;
      Disc_Type   : Entity_Id;
      Obj         : Node_Id;
      Index       : Node_Id;

   begin
      Loc := Sloc (N);

      if Nkind (N) = N_Defining_Identifier then
         Obj := New_Occurrence_Of (N, Loc);

         --  If this is a formal parameter of a subprogram declaration, and
         --  we are compiling the body, we want the declaration for the
         --  actual subtype to carry the source position of the body, to
         --  prevent anomalies in gdb when stepping through the code.

         if Is_Formal (N) then
            declare
               Decl : constant Node_Id := Unit_Declaration_Node (Scope (N));
            begin
               if Nkind (Decl) = N_Subprogram_Declaration
                 and then Present (Corresponding_Body (Decl))
               then
                  Loc := Sloc (Corresponding_Body (Decl));
               end if;
            end;
         end if;

      else
         Obj := N;
      end if;

      if Is_Array_Type (T) then
         Constraints := New_List;
         Index := First_Index (T);

         for J in 1 .. Number_Dimensions (T) loop

            --  Build an array subtype declaration with the nominal subtype and
            --  the bounds of the actual. Add the declaration in front of the
            --  local declarations for the subprogram, for analysis before any
            --  reference to the formal in the body.

            --  If this is for an index with a fixed lower bound, then use
            --  the fixed lower bound as the lower bound of the actual
            --  subtype's corresponding index.

            if not Is_Constrained (T)
              and then Is_Fixed_Lower_Bound_Index_Subtype (Etype (Index))
            then
               Lo := New_Copy_Tree (Type_Low_Bound (Etype (Index)));

            else
               Lo :=
                 Make_Attribute_Reference (Loc,
                   Prefix         =>
                     Duplicate_Subexpr_No_Checks (Obj, Name_Req => True),
                   Attribute_Name => Name_First,
                   Expressions    => New_List (
                     Make_Integer_Literal (Loc, J)));
            end if;

            Hi :=
              Make_Attribute_Reference (Loc,
                Prefix         =>
                  Duplicate_Subexpr_No_Checks (Obj, Name_Req => True),
                Attribute_Name => Name_Last,
                Expressions    => New_List (
                  Make_Integer_Literal (Loc, J)));

            Append (Make_Range (Loc, Lo, Hi), Constraints);

            Next_Index (Index);
         end loop;

      --  If the type has unknown discriminants there is no constrained
      --  subtype to build. This is never called for a formal or for a
      --  lhs, so returning the type is ok ???

      elsif Has_Unknown_Discriminants (T) then
         return T;

      else
         Constraints := New_List;

         --  Type T is a generic derived type, inherit the discriminants from
         --  the parent type.

         if Is_Private_Type (T)
           and then No (Full_View (T))

            --  T was flagged as an error if it was declared as a formal
            --  derived type with known discriminants. In this case there
            --  is no need to look at the parent type since T already carries
            --  its own discriminants.

           and then not Error_Posted (T)
         then
            Disc_Type := Etype (Base_Type (T));
         else
            Disc_Type := T;
         end if;

         Discr := First_Discriminant (Disc_Type);
         while Present (Discr) loop
            Append_To (Constraints,
              Make_Selected_Component (Loc,
                Prefix =>
                  Duplicate_Subexpr_No_Checks (Obj),
                Selector_Name => New_Occurrence_Of (Discr, Loc)));
            Next_Discriminant (Discr);
         end loop;
      end if;

      Subt := Make_Temporary (Loc, 'S', Related_Node => N);
      Set_Is_Internal (Subt);

      Decl :=
        Make_Subtype_Declaration (Loc,
          Defining_Identifier => Subt,
          Subtype_Indication =>
            Make_Subtype_Indication (Loc,
              Subtype_Mark => New_Occurrence_Of (T,  Loc),
              Constraint  =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints => Constraints)));

      Mark_Rewrite_Insertion (Decl);
      return Decl;
   end Build_Actual_Subtype;

   ---------------------------------------
   -- Build_Actual_Subtype_Of_Component --
   ---------------------------------------

   function Build_Actual_Subtype_Of_Component
     (T : Entity_Id;
      N : Node_Id) return Node_Id
   is
      Loc       : constant Source_Ptr := Sloc (N);
      P         : constant Node_Id    := Prefix (N);

      D         : Elmt_Id;
      Id        : Node_Id;
      Index_Typ : Entity_Id;
      Sel       : Entity_Id  := Empty;

      Desig_Typ : Entity_Id;
      --  This is either a copy of T, or if T is an access type, then it is
      --  the directly designated type of this access type.

      function Build_Access_Record_Constraint (C : List_Id) return List_Id;
      --  If the record component is a constrained access to the current
      --  record, the subtype has not been constructed during analysis of
      --  the enclosing record type (see Analyze_Access). In that case, build
      --  a constrained access subtype after replacing references to the
      --  enclosing discriminants with the corresponding discriminant values
      --  of the prefix.

      function Build_Actual_Array_Constraint return List_Id;
      --  If one or more of the bounds of the component depends on
      --  discriminants, build  actual constraint using the discriminants
      --  of the prefix, as above.

      function Build_Actual_Record_Constraint return List_Id;
      --  Similar to previous one, for discriminated components constrained
      --  by the discriminant of the enclosing object.

      function Build_Discriminant_Reference
        (Discrim_Name : Node_Id; Obj : Node_Id := P) return Node_Id;
      --  Build a reference to the discriminant denoted by Discrim_Name.
      --  The prefix of the result is usually Obj, but it could be
      --  a prefix of Obj in some corner cases.

      function Copy_And_Maybe_Dereference (N : Node_Id) return Node_Id;
      --  Copy the subtree rooted at N and insert an explicit dereference if it
      --  is of an access type.

      -----------------------------------
      -- Build_Actual_Array_Constraint --
      -----------------------------------

      function Build_Actual_Array_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         Indx        : Node_Id;
         Hi          : Node_Id;
         Lo          : Node_Id;
         Old_Hi      : Node_Id;
         Old_Lo      : Node_Id;

      begin
         Indx := First_Index (Desig_Typ);
         while Present (Indx) loop
            Old_Lo := Type_Low_Bound  (Etype (Indx));
            Old_Hi := Type_High_Bound (Etype (Indx));

            if Denotes_Discriminant (Old_Lo) then
               Lo := Build_Discriminant_Reference (Old_Lo);
            else
               Lo := New_Copy_Tree (Old_Lo);

               --  The new bound will be reanalyzed in the enclosing
               --  declaration. For literal bounds that come from a type
               --  declaration, the type of the context must be imposed, so
               --  insure that analysis will take place. For non-universal
               --  types this is not strictly necessary.

               Set_Analyzed (Lo, False);
            end if;

            if Denotes_Discriminant (Old_Hi) then
               Hi := Build_Discriminant_Reference (Old_Hi);
            else
               Hi := New_Copy_Tree (Old_Hi);
               Set_Analyzed (Hi, False);
            end if;

            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Next_Index (Indx);
         end loop;

         return Constraints;
      end Build_Actual_Array_Constraint;

      ------------------------------------
      -- Build_Actual_Record_Constraint --
      ------------------------------------

      function Build_Actual_Record_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         D           : Elmt_Id;
         D_Val       : Node_Id;

      begin
         D := First_Elmt (Discriminant_Constraint (Desig_Typ));
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
               D_Val := Build_Discriminant_Reference (Node (D));
            else
               D_Val := New_Copy_Tree (Node (D));
            end if;

            Append (D_Val, Constraints);
            Next_Elmt (D);
         end loop;

         return Constraints;
      end Build_Actual_Record_Constraint;

      ----------------------------------
      -- Build_Discriminant_Reference --
      ----------------------------------

      function Build_Discriminant_Reference
        (Discrim_Name : Node_Id; Obj : Node_Id := P) return Node_Id
      is
         Discrim : constant Entity_Id := Entity (Discrim_Name);

         function Obj_Is_Good_Prefix return Boolean;
         --  Returns True if Obj.Discrim makes sense; that is, if
         --  Obj has Discrim as one of its discriminants (or is an
         --  access value that designates such an object).

         ------------------------
         -- Obj_Is_Good_Prefix --
         ------------------------

         function Obj_Is_Good_Prefix return Boolean is
            Obj_Type           : Entity_Id :=
              Implementation_Base_Type (Etype (Obj));

            Discriminated_Type : constant Entity_Id :=
              Implementation_Base_Type
                (Scope (Original_Record_Component (Discrim)));
         begin
            --  The order of the following two tests matters in the
            --  access-to-class-wide case.

            if Is_Access_Type (Obj_Type) then
               Obj_Type := Implementation_Base_Type
                             (Designated_Type (Obj_Type));
            end if;

            if Is_Class_Wide_Type (Obj_Type) then
               Obj_Type := Implementation_Base_Type
                             (Find_Specific_Type (Obj_Type));
            end if;

            --  If a type T1 defines a discriminant D1, then Obj.D1 is ok (for
            --  our purposes here) if T1 is an ancestor of the type of Obj.
            --  So that's what we would like to test for here.
            --  The bad news: Is_Ancestor is only defined in the tagged case.
            --  The good news: in the untagged case, Implementation_Base_Type
            --  looks through derived types so we can use a simpler test.

            if Is_Tagged_Type (Discriminated_Type) then
               return Is_Ancestor (Discriminated_Type, Obj_Type);
            else
               return Discriminated_Type = Obj_Type;
            end if;
         end Obj_Is_Good_Prefix;

      --  Start of processing for Build_Discriminant_Reference

      begin
         if not Obj_Is_Good_Prefix then
            --  If the given discriminant is not a component of the given
            --  object, then try the enclosing object.

            if Nkind (Obj) = N_Selected_Component then
               return Build_Discriminant_Reference
                        (Discrim_Name => Discrim_Name,
                         Obj          => Prefix (Obj));
            elsif Nkind (Obj) in N_Has_Entity
              and then Nkind (Parent (Entity (Obj))) =
                       N_Object_Renaming_Declaration
            then
               --  Look through a renaming (a corner case of a corner case).
               return Build_Discriminant_Reference
                        (Discrim_Name => Discrim_Name,
                         Obj          => Name (Parent (Entity (Obj))));
            else
               --  We are in some unexpected case here, so revert to the
               --  old behavior (by falling through to it).
               null;
            end if;
         end if;

         return Make_Selected_Component (Loc,
                  Prefix => Copy_And_Maybe_Dereference (Obj),
                  Selector_Name => New_Occurrence_Of (Discrim, Loc));
      end Build_Discriminant_Reference;

      ------------------------------------
      -- Build_Access_Record_Constraint --
      ------------------------------------

      function Build_Access_Record_Constraint (C : List_Id) return List_Id is
         Constraints : constant List_Id := New_List;
         D           : Node_Id;
         D_Val       : Node_Id;

      begin
         --  Retrieve the constraint from the component declaration, because
         --  the component subtype has not been constructed and the component
         --  type is an unconstrained access.

         D := First (C);
         while Present (D) loop
            if Nkind (D) = N_Discriminant_Association
              and then Denotes_Discriminant (Expression (D))
            then
               D_Val := New_Copy_Tree (D);
               Set_Expression (D_Val,
                 Make_Selected_Component (Loc,
                   Prefix => Copy_And_Maybe_Dereference (P),
                   Selector_Name =>
                     New_Occurrence_Of (Entity (Expression (D)), Loc)));

            elsif Denotes_Discriminant (D) then
               D_Val := Make_Selected_Component (Loc,
                 Prefix => Copy_And_Maybe_Dereference (P),
                 Selector_Name => New_Occurrence_Of (Entity (D), Loc));

            else
               D_Val := New_Copy_Tree (D);
            end if;

            Append (D_Val, Constraints);
            Next (D);
         end loop;

         return Constraints;
      end Build_Access_Record_Constraint;

      --------------------------------
      -- Copy_And_Maybe_Dereference --
      --------------------------------

      function Copy_And_Maybe_Dereference (N : Node_Id) return Node_Id is
         New_N : constant Node_Id := New_Copy_Tree (N);

      begin
         if Is_Access_Type (Etype (N)) then
            return Make_Explicit_Dereference (Sloc (Parent (N)), New_N);

         else
            return New_N;
         end if;
      end Copy_And_Maybe_Dereference;

   --  Start of processing for Build_Actual_Subtype_Of_Component

   begin
      --  The subtype does not need to be created for a selected component
      --  in a Spec_Expression.

      if In_Spec_Expression then
         return Empty;

      --  More comments for the rest of this body would be good ???

      elsif Nkind (N) = N_Explicit_Dereference then
         if Is_Composite_Type (T)
           and then not Is_Constrained (T)
           and then not (Is_Class_Wide_Type (T)
                          and then Is_Constrained (Root_Type (T)))
           and then not Has_Unknown_Discriminants (T)
         then
            --  If the type of the dereference is already constrained, it is an
            --  actual subtype.

            if Is_Array_Type (Etype (N))
              and then Is_Constrained (Etype (N))
            then
               return Empty;
            else
               Remove_Side_Effects (P);
               return Build_Actual_Subtype (T, N);
            end if;

         else
            return Empty;
         end if;

      elsif Nkind (N) = N_Selected_Component then
         --  The entity of the selected component allows us to retrieve
         --  the original constraint from its component declaration.

         Sel := Entity (Selector_Name (N));
         if Parent_Kind (Sel) /= N_Component_Declaration then
            return Empty;
         end if;
      end if;

      if Is_Access_Type (T) then
         Desig_Typ := Designated_Type (T);

      else
         Desig_Typ := T;
      end if;

      if Ekind (Desig_Typ) = E_Array_Subtype then
         Id := First_Index (Desig_Typ);

         --  Check whether an index bound is constrained by a discriminant

         while Present (Id) loop
            Index_Typ := Underlying_Type (Etype (Id));

            if Denotes_Discriminant (Type_Low_Bound  (Index_Typ))
                 or else
               Denotes_Discriminant (Type_High_Bound (Index_Typ))
            then
               Remove_Side_Effects (P);
               return
                 Build_Component_Subtype
                   (Build_Actual_Array_Constraint, Loc, Base_Type (T));
            end if;

            Next_Index (Id);
         end loop;

      elsif Is_Composite_Type (Desig_Typ)
        and then Has_Discriminants (Desig_Typ)
        and then not Is_Empty_Elmt_List (Discriminant_Constraint (Desig_Typ))
        and then not Has_Unknown_Discriminants (Desig_Typ)
      then
         if Is_Private_Type (Desig_Typ)
           and then No (Discriminant_Constraint (Desig_Typ))
         then
            Desig_Typ := Full_View (Desig_Typ);
         end if;

         D := First_Elmt (Discriminant_Constraint (Desig_Typ));
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
               Remove_Side_Effects (P);
               return
                 Build_Component_Subtype (
                   Build_Actual_Record_Constraint, Loc, Base_Type (T));
            end if;

            Next_Elmt (D);
         end loop;

      --  Special processing for an access record component that is
      --  the target of an assignment. If the designated type is an
      --  unconstrained discriminated record we create its actual
      --  subtype now.

      elsif Ekind (T) = E_Access_Type
        and then Present (Sel)
        and then Has_Per_Object_Constraint (Sel)
        and then Nkind (Parent (N)) = N_Assignment_Statement
        and then N = Name (Parent (N))
        --  and then not Inside_Init_Proc
        --  and then Has_Discriminants (Desig_Typ)
        --  and then not Is_Constrained (Desig_Typ)
      then
         declare
            S_Indic : constant Node_Id :=
              (Subtype_Indication
                    (Component_Definition (Parent (Sel))));
            Discs : List_Id;
         begin
            if Nkind (S_Indic) = N_Subtype_Indication then
               Discs := Constraints (Constraint (S_Indic));

               Remove_Side_Effects (P);
               return Build_Component_Subtype
                  (Build_Access_Record_Constraint (Discs), Loc, T);
            else
               return Empty;
            end if;
         end;
      end if;

      --  If none of the above, the actual and nominal subtypes are the same

      return Empty;
   end Build_Actual_Subtype_Of_Component;

   -----------------------------
   -- Build_Component_Subtype --
   -----------------------------

   function Build_Component_Subtype
     (C   : List_Id;
      Loc : Source_Ptr;
      T   : Entity_Id) return Node_Id
   is
      Subt : Entity_Id;
      Decl : Node_Id;

   begin
      --  Unchecked_Union components do not require component subtypes

      if Is_Unchecked_Union (T) then
         return Empty;
      end if;

      Subt := Make_Temporary (Loc, 'S');
      Set_Is_Internal (Subt);

      Decl :=
        Make_Subtype_Declaration (Loc,
          Defining_Identifier => Subt,
          Subtype_Indication =>
            Make_Subtype_Indication (Loc,
              Subtype_Mark => New_Occurrence_Of (Base_Type (T),  Loc),
              Constraint  =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints => C)));

      Mark_Rewrite_Insertion (Decl);
      return Decl;
   end Build_Component_Subtype;

   -----------------------------
   -- Build_Constrained_Itype --
   -----------------------------

   procedure Build_Constrained_Itype
     (N              : Node_Id;
      Typ            : Entity_Id;
      New_Assoc_List : List_Id)
   is
      Constrs     : constant List_Id    := New_List;
      Loc         : constant Source_Ptr := Sloc (N);
      Def_Id      : Entity_Id;
      Indic       : Node_Id;
      New_Assoc   : Node_Id;
      Subtyp_Decl : Node_Id;

   begin
      New_Assoc := First (New_Assoc_List);
      while Present (New_Assoc) loop

         --  There is exactly one choice in the component association (and
         --  it is either a discriminant, a component or the others clause).
         pragma Assert (List_Length (Choices (New_Assoc)) = 1);

         --  Duplicate expression for the discriminant and put it on the
         --  list of constraints for the itype declaration.

         if Is_Entity_Name (First (Choices (New_Assoc)))
           and then
             Ekind (Entity (First (Choices (New_Assoc)))) = E_Discriminant
         then
            Append_To (Constrs, Duplicate_Subexpr (Expression (New_Assoc)));
         end if;

         Next (New_Assoc);
      end loop;

      if Has_Unknown_Discriminants (Typ)
        and then Present (Underlying_Record_View (Typ))
      then
         Indic :=
           Make_Subtype_Indication (Loc,
             Subtype_Mark =>
               New_Occurrence_Of (Underlying_Record_View (Typ), Loc),
             Constraint   =>
               Make_Index_Or_Discriminant_Constraint (Loc,
                 Constraints => Constrs));
      else
         Indic :=
           Make_Subtype_Indication (Loc,
             Subtype_Mark =>
               New_Occurrence_Of (Base_Type (Typ), Loc),
             Constraint   =>
               Make_Index_Or_Discriminant_Constraint (Loc,
                 Constraints => Constrs));
      end if;

      Def_Id := Create_Itype (Ekind (Typ), N);

      Subtyp_Decl :=
        Make_Subtype_Declaration (Loc,
          Defining_Identifier => Def_Id,
          Subtype_Indication  => Indic);
      Set_Parent (Subtyp_Decl, Parent (N));

      --  Itypes must be analyzed with checks off (see itypes.ads)

      Analyze (Subtyp_Decl, Suppress => All_Checks);

      Set_Etype (N, Def_Id);
   end Build_Constrained_Itype;

   ---------------------------
   -- Build_Default_Subtype --
   ---------------------------

   function Build_Default_Subtype
     (T : Entity_Id;
      N : Node_Id) return Entity_Id
   is
      Loc  : constant Source_Ptr := Sloc (N);
      Disc : Entity_Id;

      Bas : Entity_Id;
      --  The base type that is to be constrained by the defaults

   begin
      if not Has_Discriminants (T) or else Is_Constrained (T) then
         return T;
      end if;

      Bas := Base_Type (T);

      --  If T is non-private but its base type is private, this is the
      --  completion of a subtype declaration whose parent type is private
      --  (see Complete_Private_Subtype in Sem_Ch3). The proper discriminants
      --  are to be found in the full view of the base. Check that the private
      --  status of T and its base differ.

      if Is_Private_Type (Bas)
        and then not Is_Private_Type (T)
        and then Present (Full_View (Bas))
      then
         Bas := Full_View (Bas);
      end if;

      Disc := First_Discriminant (T);

      if No (Discriminant_Default_Value (Disc)) then
         return T;
      end if;

      declare
         Act         : constant Entity_Id := Make_Temporary (Loc, 'S');
         Constraints : constant List_Id := New_List;
         Decl        : Node_Id;

      begin
         while Present (Disc) loop
            Append_To (Constraints,
              New_Copy_Tree (Discriminant_Default_Value (Disc)));
            Next_Discriminant (Disc);
         end loop;

         Decl :=
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => Act,
             Subtype_Indication  =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark => New_Occurrence_Of (Bas, Loc),
                 Constraint   =>
                   Make_Index_Or_Discriminant_Constraint (Loc,
                     Constraints => Constraints)));

         Insert_Action (N, Decl);

         --  If the context is a component declaration the subtype declaration
         --  will be analyzed when the enclosing type is frozen, otherwise do
         --  it now.

         if Ekind (Current_Scope) /= E_Record_Type then
            Analyze (Decl);
         end if;

         return Act;
      end;
   end Build_Default_Subtype;

   ------------------------------
   -- Build_Default_Subtype_OK --
   ------------------------------

   function Build_Default_Subtype_OK (T : Entity_Id) return Boolean is

      function Default_Discriminant_Values_Known_At_Compile_Time
         (T : Entity_Id) return Boolean;
         --  For an unconstrained type T, return False if the given type has a
         --  discriminant with default value not known at compile time. Return
         --  True otherwise.

      ---------------------------------------------------------
      -- Default_Discriminant_Values_Known_At_Compile_Time --
      ---------------------------------------------------------

      function Default_Discriminant_Values_Known_At_Compile_Time
         (T : Entity_Id) return Boolean
      is
         Discr : Entity_Id;
         DDV : Node_Id;

      begin

         --  If the type has no discriminant, we know them all at compile time

         if not Has_Discriminants (T) then
            return True;
         end if;

         --  The type has discriminants, check that none of them has a default
         --  value not known at compile time.

         Discr := First_Discriminant (T);

         while Present (Discr) loop
            DDV := Discriminant_Default_Value (Discr);

            if Present (DDV) and then not Compile_Time_Known_Value (DDV) then
               return False;
            end if;

            Next_Discriminant (Discr);
         end loop;

         return True;
      end Default_Discriminant_Values_Known_At_Compile_Time;

   --  Start of processing for Build_Default_Subtype_OK

   begin

      if Is_Constrained (T) then

         --  We won't build a new subtype if T is constrained

         return False;
      end if;

      if not Default_Discriminant_Values_Known_At_Compile_Time (T) then

         --  This is a special case of definite subtypes. To allocate a
         --  specific size to the subtype, we need to know the value at compile
         --  time. This might not be the case if the default value is the
         --  result of a function. In that case, the object might be definite
         --  and limited but the needed size might not be statically known or
         --  too tricky to obtain. In that case, we will not build the subtype.

         return False;
      end if;

      return Is_Definite_Subtype (T) and then Is_Limited_View (T);
   end Build_Default_Subtype_OK;

   --------------------------------------------
   -- Build_Discriminal_Subtype_Of_Component --
   --------------------------------------------

   function Build_Discriminal_Subtype_Of_Component
     (T : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (T);
      D   : Elmt_Id;
      Id  : Node_Id;

      function Build_Discriminal_Array_Constraint return List_Id;
      --  If one or more of the bounds of the component depends on
      --  discriminants, build actual constraint using the discriminants
      --  of the prefix.

      function Build_Discriminal_Record_Constraint return List_Id;
      --  Similar to previous one, for discriminated components constrained by
      --  the discriminant of the enclosing object.

      ----------------------------------------
      -- Build_Discriminal_Array_Constraint --
      ----------------------------------------

      function Build_Discriminal_Array_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         Indx        : Node_Id;
         Hi          : Node_Id;
         Lo          : Node_Id;
         Old_Hi      : Node_Id;
         Old_Lo      : Node_Id;

      begin
         Indx := First_Index (T);
         while Present (Indx) loop
            Old_Lo := Type_Low_Bound  (Etype (Indx));
            Old_Hi := Type_High_Bound (Etype (Indx));

            if Denotes_Discriminant (Old_Lo) then
               Lo := New_Occurrence_Of (Discriminal (Entity (Old_Lo)), Loc);

            else
               Lo := New_Copy_Tree (Old_Lo);
            end if;

            if Denotes_Discriminant (Old_Hi) then
               Hi := New_Occurrence_Of (Discriminal (Entity (Old_Hi)), Loc);

            else
               Hi := New_Copy_Tree (Old_Hi);
            end if;

            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Next_Index (Indx);
         end loop;

         return Constraints;
      end Build_Discriminal_Array_Constraint;

      -----------------------------------------
      -- Build_Discriminal_Record_Constraint --
      -----------------------------------------

      function Build_Discriminal_Record_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         D           : Elmt_Id;
         D_Val       : Node_Id;

      begin
         D := First_Elmt (Discriminant_Constraint (T));
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
               D_Val :=
                 New_Occurrence_Of (Discriminal (Entity (Node (D))), Loc);
            else
               D_Val := New_Copy_Tree (Node (D));
            end if;

            Append (D_Val, Constraints);
            Next_Elmt (D);
         end loop;

         return Constraints;
      end Build_Discriminal_Record_Constraint;

   --  Start of processing for Build_Discriminal_Subtype_Of_Component

   begin
      if Ekind (T) = E_Array_Subtype then
         Id := First_Index (T);
         while Present (Id) loop
            if Denotes_Discriminant (Type_Low_Bound  (Etype (Id)))
                 or else
               Denotes_Discriminant (Type_High_Bound (Etype (Id)))
            then
               return Build_Component_Subtype
                 (Build_Discriminal_Array_Constraint, Loc, T);
            end if;

            Next_Index (Id);
         end loop;

      elsif Ekind (T) = E_Record_Subtype
        and then Has_Discriminants (T)
        and then not Has_Unknown_Discriminants (T)
      then
         D := First_Elmt (Discriminant_Constraint (T));
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
               return Build_Component_Subtype
                 (Build_Discriminal_Record_Constraint, Loc, T);
            end if;

            Next_Elmt (D);
         end loop;
      end if;

      --  If none of the above, the actual and nominal subtypes are the same

      return Empty;
   end Build_Discriminal_Subtype_Of_Component;

   ------------------------------
   -- Build_Elaboration_Entity --
   ------------------------------

   procedure Build_Elaboration_Entity (N : Node_Id; Spec_Id : Entity_Id) is
      Loc      : constant Source_Ptr := Sloc (N);
      Decl     : Node_Id;
      Elab_Ent : Entity_Id;

      procedure Set_Package_Name (Ent : Entity_Id);
      --  Given an entity, sets the fully qualified name of the entity in
      --  Name_Buffer, with components separated by double underscores. This
      --  is a recursive routine that climbs the scope chain to Standard.

      ----------------------
      -- Set_Package_Name --
      ----------------------

      procedure Set_Package_Name (Ent : Entity_Id) is
      begin
         if Scope (Ent) /= Standard_Standard then
            Set_Package_Name (Scope (Ent));

            declare
               Nam : constant String := Get_Name_String (Chars (Ent));
            begin
               Name_Buffer (Name_Len + 1) := '_';
               Name_Buffer (Name_Len + 2) := '_';
               Name_Buffer (Name_Len + 3 .. Name_Len + Nam'Length + 2) := Nam;
               Name_Len := Name_Len + Nam'Length + 2;
            end;

         else
            Get_Name_String (Chars (Ent));
         end if;
      end Set_Package_Name;

   --  Start of processing for Build_Elaboration_Entity

   begin
      --  Ignore call if already constructed

      if Present (Elaboration_Entity (Spec_Id)) then
         return;

      --  Do not generate an elaboration entity in GNATprove move because the
      --  elaboration counter is a form of expansion.

      elsif GNATprove_Mode then
         return;

      --  See if we need elaboration entity

      --  We always need an elaboration entity when preserving control flow, as
      --  we want to remain explicit about the unit's elaboration order.

      elsif Opt.Suppress_Control_Flow_Optimizations then
         null;

      --  We always need an elaboration entity for the dynamic elaboration
      --  model, since it is needed to properly generate the PE exception for
      --  access before elaboration.

      elsif Dynamic_Elaboration_Checks then
         null;

      --  For the static model, we don't need the elaboration counter if this
      --  unit is sure to have no elaboration code, since that means there
      --  is no elaboration unit to be called. Note that we can't just decide
      --  after the fact by looking to see whether there was elaboration code,
      --  because that's too late to make this decision.

      elsif Restriction_Active (No_Elaboration_Code) then
         return;

      --  Similarly, for the static model, we can skip the elaboration counter
      --  if we have the No_Multiple_Elaboration restriction, since for the
      --  static model, that's the only purpose of the counter (to avoid
      --  multiple elaboration).

      elsif Restriction_Active (No_Multiple_Elaboration) then
         return;
      end if;

      --  Here we need the elaboration entity

      --  Construct name of elaboration entity as xxx_E, where xxx is the unit
      --  name with dots replaced by double underscore. We have to manually
      --  construct this name, since it will be elaborated in the outer scope,
      --  and thus will not have the unit name automatically prepended.

      Set_Package_Name (Spec_Id);
      Add_Str_To_Name_Buffer ("_E");

      --  Create elaboration counter

      Elab_Ent := Make_Defining_Identifier (Loc, Chars => Name_Find);
      Set_Elaboration_Entity (Spec_Id, Elab_Ent);

      Decl :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Elab_Ent,
          Object_Definition   =>
            New_Occurrence_Of (Standard_Short_Integer, Loc),
          Expression          => Make_Integer_Literal (Loc, Uint_0));

      Push_Scope (Standard_Standard);
      Add_Global_Declaration (Decl);
      Pop_Scope;

      --  Reset True_Constant indication, since we will indeed assign a value
      --  to the variable in the binder main. We also kill the Current_Value
      --  and Last_Assignment fields for the same reason.

      Set_Is_True_Constant (Elab_Ent, False);
      Set_Current_Value    (Elab_Ent, Empty);
      Set_Last_Assignment  (Elab_Ent, Empty);

      --  We do not want any further qualification of the name (if we did not
      --  do this, we would pick up the name of the generic package in the case
      --  of a library level generic instantiation).

      Set_Has_Qualified_Name       (Elab_Ent);
      Set_Has_Fully_Qualified_Name (Elab_Ent);
   end Build_Elaboration_Entity;

   --------------------------------
   -- Build_Explicit_Dereference --
   --------------------------------

   procedure Build_Explicit_Dereference
     (Expr : Node_Id;
      Disc : Entity_Id)
   is
      Loc : constant Source_Ptr := Sloc (Expr);
      I   : Interp_Index;
      It  : Interp;

   begin
      --  An entity of a type with a reference aspect is overloaded with
      --  both interpretations: with and without the dereference. Now that
      --  the dereference is made explicit, set the type of the node properly,
      --  to prevent anomalies in the backend. Same if the expression is an
      --  overloaded function call whose return type has a reference aspect.

      if Is_Entity_Name (Expr) then
         Set_Etype (Expr, Etype (Entity (Expr)));

         --  The designated entity will not be examined again when resolving
         --  the dereference, so generate a reference to it now.

         Generate_Reference (Entity (Expr), Expr);

      elsif Nkind (Expr) = N_Function_Call then

         --  If the name of the indexing function is overloaded, locate the one
         --  whose return type has an implicit dereference on the desired
         --  discriminant, and set entity and type of function call.

         if Is_Overloaded (Name (Expr)) then
            Get_First_Interp (Name (Expr), I, It);

            while Present (It.Nam) loop
               if Ekind ((It.Typ)) = E_Record_Type
                 and then First_Entity ((It.Typ)) = Disc
               then
                  Set_Entity (Name (Expr), It.Nam);
                  Set_Etype (Name (Expr), Etype (It.Nam));
                  exit;
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end if;

         --  Set type of call from resolved function name.

         Set_Etype (Expr, Etype (Name (Expr)));
      end if;

      Set_Is_Overloaded (Expr, False);

      --  The expression will often be a generalized indexing that yields a
      --  container element that is then dereferenced, in which case the
      --  generalized indexing call is also non-overloaded.

      if Nkind (Expr) = N_Indexed_Component
        and then Present (Generalized_Indexing (Expr))
      then
         Set_Is_Overloaded (Generalized_Indexing (Expr), False);
      end if;

      Rewrite (Expr,
        Make_Explicit_Dereference (Loc,
          Prefix =>
            Make_Selected_Component (Loc,
              Prefix        => Relocate_Node (Expr),
              Selector_Name => New_Occurrence_Of (Disc, Loc))));
      Set_Etype (Prefix (Expr), Etype (Disc));
      Set_Etype (Expr, Designated_Type (Etype (Disc)));
   end Build_Explicit_Dereference;

   ---------------------------
   -- Build_Overriding_Spec --
   ---------------------------

   function Build_Overriding_Spec
     (Op  : Entity_Id;
      Typ : Entity_Id) return Node_Id
   is
      Loc     : constant Source_Ptr := Sloc (Typ);
      Par_Typ : constant Entity_Id := Find_Dispatching_Type (Op);
      Spec    : constant Node_Id := Specification (Unit_Declaration_Node (Op));

      Formal_Spec : Node_Id;
      Formal_Type : Node_Id;
      New_Spec    : Node_Id;

   begin
      New_Spec := Copy_Subprogram_Spec (Spec);

      Formal_Spec := First (Parameter_Specifications (New_Spec));
      while Present (Formal_Spec) loop
         Formal_Type := Parameter_Type (Formal_Spec);

         if Is_Entity_Name (Formal_Type)
           and then Entity (Formal_Type) = Par_Typ
         then
            Rewrite (Formal_Type, New_Occurrence_Of (Typ, Loc));

         elsif Nkind (Formal_Type) = N_Access_Definition
           and then Entity (Subtype_Mark (Formal_Type)) = Par_Typ
         then
            Rewrite (Subtype_Mark (Formal_Type), New_Occurrence_Of (Typ, Loc));
         end if;

         Next (Formal_Spec);
      end loop;

      return New_Spec;
   end Build_Overriding_Spec;

   -------------------
   -- Build_Subtype --
   -------------------

   function Build_Subtype
     (Related_Node : Node_Id;
      Loc          : Source_Ptr;
      Typ          : Entity_Id;
      Constraints  : List_Id)
      return Entity_Id
   is
      Indic       : Node_Id;
      Subtyp_Decl : Node_Id;
      Def_Id      : Entity_Id;
      Btyp        : Entity_Id := Base_Type (Typ);

   begin
      --  The Related_Node better be here or else we won't be able to
      --  attach new itypes to a node in the tree.

      pragma Assert (Present (Related_Node));

      --  If the view of the component's type is incomplete or private
      --  with unknown discriminants, then the constraint must be applied
      --  to the full type.

      if Has_Unknown_Discriminants (Btyp)
        and then Present (Underlying_Type (Btyp))
      then
         Btyp := Underlying_Type (Btyp);
      end if;

      Indic :=
        Make_Subtype_Indication (Loc,
          Subtype_Mark => New_Occurrence_Of (Btyp, Loc),
          Constraint   =>
            Make_Index_Or_Discriminant_Constraint (Loc, Constraints));

      Def_Id := Create_Itype (Ekind (Typ), Related_Node);

      Subtyp_Decl :=
        Make_Subtype_Declaration (Loc,
          Defining_Identifier => Def_Id,
          Subtype_Indication  => Indic);

      Set_Parent (Subtyp_Decl, Parent (Related_Node));

      --  Itypes must be analyzed with checks off (see package Itypes)

      Analyze (Subtyp_Decl, Suppress => All_Checks);

      if Is_Itype (Def_Id) and then Has_Predicates (Typ) then
         Inherit_Predicate_Flags (Def_Id, Typ);

         --  Indicate where the predicate function may be found

         if Is_Itype (Typ) then
            if Present (Predicate_Function (Def_Id)) then
               null;

            elsif Present (Predicate_Function (Typ)) then
               Set_Predicate_Function (Def_Id, Predicate_Function (Typ));

            else
               Set_Predicated_Parent (Def_Id, Predicated_Parent (Typ));
            end if;

         elsif No (Predicate_Function (Def_Id)) then
            Set_Predicated_Parent (Def_Id, Typ);
         end if;
      end if;

      return Def_Id;
   end Build_Subtype;

   -----------------------------------
   -- Cannot_Raise_Constraint_Error --
   -----------------------------------

   function Cannot_Raise_Constraint_Error (Expr : Node_Id) return Boolean is

      function List_Cannot_Raise_CE (L : List_Id) return Boolean;
      --  Returns True if none of the list members cannot possibly raise
      --  Constraint_Error.

      --------------------------
      -- List_Cannot_Raise_CE --
      --------------------------

      function List_Cannot_Raise_CE (L : List_Id) return Boolean is
         N : Node_Id;
      begin
         N := First (L);
         while Present (N) loop
            if Cannot_Raise_Constraint_Error (N) then
               Next (N);
            else
               return False;
            end if;
         end loop;

         return True;
      end List_Cannot_Raise_CE;

   --  Start of processing for Cannot_Raise_Constraint_Error

   begin
      if Compile_Time_Known_Value (Expr) then
         return True;

      elsif Do_Range_Check (Expr) then
         return False;

      elsif Raises_Constraint_Error (Expr) then
         return False;

      else
         case Nkind (Expr) is
            when N_Identifier =>
               return True;

            when N_Expanded_Name =>
               return True;

            when N_Indexed_Component =>
               return not Do_Range_Check (Expr)
                 and then Cannot_Raise_Constraint_Error (Prefix (Expr))
                 and then List_Cannot_Raise_CE (Expressions (Expr));

            when N_Selected_Component =>
               return not Do_Discriminant_Check (Expr)
                 and then Cannot_Raise_Constraint_Error (Prefix (Expr));

            when N_Attribute_Reference =>
               if Do_Overflow_Check (Expr) then
                  return False;

               elsif No (Expressions (Expr)) then
                  return True;

               else
                  return List_Cannot_Raise_CE (Expressions (Expr));
               end if;

            when N_Type_Conversion =>
               if Do_Overflow_Check (Expr)
                 or else Do_Length_Check (Expr)
               then
                  return False;
               else
                  return Cannot_Raise_Constraint_Error (Expression (Expr));
               end if;

            when N_Unchecked_Type_Conversion =>
               return Cannot_Raise_Constraint_Error (Expression (Expr));

            when N_Unary_Op =>
               if Do_Overflow_Check (Expr) then
                  return False;
               else
                  return Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
               end if;

            when N_Op_Divide
               | N_Op_Mod
               | N_Op_Rem
            =>
               if Do_Division_Check (Expr)
                    or else
                  Do_Overflow_Check (Expr)
               then
                  return False;
               else
                  return
                    Cannot_Raise_Constraint_Error (Left_Opnd  (Expr))
                      and then
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
               end if;

            when N_Op_Add
               | N_Op_And
               | N_Op_Concat
               | N_Op_Eq
               | N_Op_Expon
               | N_Op_Ge
               | N_Op_Gt
               | N_Op_Le
               | N_Op_Lt
               | N_Op_Multiply
               | N_Op_Ne
               | N_Op_Or
               | N_Op_Rotate_Left
               | N_Op_Rotate_Right
               | N_Op_Shift_Left
               | N_Op_Shift_Right
               | N_Op_Shift_Right_Arithmetic
               | N_Op_Subtract
               | N_Op_Xor
            =>
               if Do_Overflow_Check (Expr) then
                  return False;
               else
                  return
                    Cannot_Raise_Constraint_Error (Left_Opnd  (Expr))
                      and then
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
               end if;

            when others =>
               return False;
         end case;
      end if;
   end Cannot_Raise_Constraint_Error;

   -------------------------------
   -- Check_Ambiguous_Aggregate --
   -------------------------------

   procedure Check_Ambiguous_Aggregate (Call : Node_Id) is
      Actual : Node_Id;

   begin
      if All_Extensions_Allowed then
         Actual := First_Actual (Call);
         while Present (Actual) loop
            if Nkind (Actual) = N_Aggregate then
               Error_Msg_N
                 ("\add type qualification to aggregate actual", Actual);
               exit;
            end if;
            Next_Actual (Actual);
         end loop;
      end if;
   end Check_Ambiguous_Aggregate;

   -----------------------------------------
   -- Check_Dynamically_Tagged_Expression --
   -----------------------------------------

   procedure Check_Dynamically_Tagged_Expression
     (Expr        : Node_Id;
      Typ         : Entity_Id;
      Related_Nod : Node_Id)
   is
   begin
      pragma Assert (Is_Tagged_Type (Typ));

      --  In order to avoid spurious errors when analyzing the expanded code,
      --  this check is done only for nodes that come from source and for
      --  actuals of generic instantiations.

      if (Comes_From_Source (Related_Nod)
           or else In_Generic_Actual (Expr))
        and then (Is_Class_Wide_Type (Etype (Expr))
                   or else Is_Dynamically_Tagged (Expr))
        and then not Is_Class_Wide_Type (Typ)
      then
         Error_Msg_N ("dynamically tagged expression not allowed!", Expr);
      end if;
   end Check_Dynamically_Tagged_Expression;

   --------------------------
   -- Check_Fully_Declared --
   --------------------------

   procedure Check_Fully_Declared (T : Entity_Id; N : Node_Id) is
   begin
      if Ekind (T) = E_Incomplete_Type then

         --  Ada 2005 (AI-50217): If the type is available through a limited
         --  with_clause, verify that its full view has been analyzed.

         if From_Limited_With (T)
           and then Present (Non_Limited_View (T))
           and then Ekind (Non_Limited_View (T)) /= E_Incomplete_Type
         then
            --  The non-limited view is fully declared

            null;

         else
            Error_Msg_NE
              ("premature usage of incomplete}", N, First_Subtype (T));
         end if;

      --  Need comments for these tests ???

      elsif Has_Private_Component (T)
        and then not Is_Generic_Type (Root_Type (T))
        and then not In_Spec_Expression
      then
         --  Special case: if T is the anonymous type created for a single
         --  task or protected object, use the name of the source object.

         if Is_Concurrent_Type (T)
           and then not Comes_From_Source (T)
           and then Nkind (N) = N_Object_Declaration
         then
            Error_Msg_NE
              ("type of& has incomplete component",
               N, Defining_Identifier (N));
         else
            Error_Msg_NE
              ("premature usage of incomplete}",
               N, First_Subtype (T));
         end if;
      end if;
   end Check_Fully_Declared;

   -------------------------------------------
   -- Check_Function_With_Address_Parameter --
   -------------------------------------------

   procedure Check_Function_With_Address_Parameter (Subp_Id : Entity_Id) is
      F : Entity_Id;
      T : Entity_Id;

   begin
      F := First_Formal (Subp_Id);
      while Present (F) loop
         T := Etype (F);

         if Is_Private_Type (T) and then Present (Full_View (T)) then
            T := Full_View (T);
         end if;

         if Is_Descendant_Of_Address (T) or else Is_Limited_Type (T) then
            Set_Is_Pure (Subp_Id, False);
            exit;
         end if;

         Next_Formal (F);
      end loop;
   end Check_Function_With_Address_Parameter;

   -------------------------------------
   -- Check_Function_Writable_Actuals --
   -------------------------------------

   procedure Check_Function_Writable_Actuals (N : Node_Id) is
      Writable_Actuals_List : Elist_Id := No_Elist;
      Identifiers_List      : Elist_Id := No_Elist;
      Aggr_Error_Node       : Node_Id  := Empty;
      Error_Node            : Node_Id  := Empty;

      procedure Collect_Identifiers (N : Node_Id);
      --  In a single traversal of subtree N collect in Writable_Actuals_List
      --  all the actuals of functions with writable actuals, and in the list
      --  Identifiers_List collect all the identifiers that are not actuals of
      --  functions with writable actuals. If a writable actual is referenced
      --  twice as writable actual then Error_Node is set to reference its
      --  second occurrence, the error is reported, and the tree traversal
      --  is abandoned.

      -------------------------
      -- Collect_Identifiers --
      -------------------------

      procedure Collect_Identifiers (N : Node_Id) is

         function Check_Node (N : Node_Id) return Traverse_Result;
         --  Process a single node during the tree traversal to collect the
         --  writable actuals of functions and all the identifiers which are
         --  not writable actuals of functions.

         function Contains (List : Elist_Id; N : Node_Id) return Boolean;
         --  Returns True if List has a node whose Entity is Entity (N)

         ----------------
         -- Check_Node --
         ----------------

         function Check_Node (N : Node_Id) return Traverse_Result is
            Is_Writable_Actual : Boolean := False;
            Id                 : Entity_Id := Empty;
            --  Default init of Id for CodePeer

         begin
            if Nkind (N) = N_Identifier then

               --  No analysis possible if the entity is not decorated

               if No (Entity (N)) then
                  return Skip;

               --  Don't collect identifiers of packages, called functions, etc

               elsif Ekind (Entity (N)) in
                       E_Package | E_Function | E_Procedure | E_Entry
               then
                  return Skip;

               --  For rewritten nodes, continue the traversal in the original
               --  subtree. Needed to handle aggregates in original expressions
               --  extracted from the tree by Remove_Side_Effects.

               elsif Is_Rewrite_Substitution (N) then
                  Collect_Identifiers (Original_Node (N));
                  return Skip;

               --  For now we skip aggregate discriminants, since they require
               --  performing the analysis in two phases to identify conflicts:
               --  first one analyzing discriminants and second one analyzing
               --  the rest of components (since at run time, discriminants are
               --  evaluated prior to components): too much computation cost
               --  to identify a corner case???

               elsif Nkind (Parent (N)) = N_Component_Association
                  and then Nkind (Parent (Parent (N))) in
                             N_Aggregate | N_Extension_Aggregate
               then
                  declare
                     Choice : constant Node_Id := First (Choices (Parent (N)));

                  begin
                     if Ekind (Entity (N)) = E_Discriminant then
                        return Skip;

                     elsif Expression (Parent (N)) = N
                       and then Nkind (Choice) = N_Identifier
                       and then Ekind (Entity (Choice)) = E_Discriminant
                     then
                        return Skip;
                     end if;
                  end;

               --  Analyze if N is a writable actual of a function

               elsif Nkind (Parent (N)) = N_Function_Call then
                  declare
                     Call   : constant Node_Id := Parent (N);
                     Actual : Node_Id;
                     Formal : Node_Id;

                  begin
                     Id := Get_Called_Entity (Call);

                     --  In case of previous error, no check is possible

                     if No (Id) then
                        return Abandon;
                     end if;

                     if Ekind (Id) in E_Function | E_Generic_Function
                       and then Has_Out_Or_In_Out_Parameter (Id)
                     then
                        Formal := First_Formal (Id);
                        Actual := First_Actual (Call);
                        while Present (Actual) and then Present (Formal) loop
                           if Actual = N then
                              if Ekind (Formal) in E_Out_Parameter
                                                 | E_In_Out_Parameter
                              then
                                 Is_Writable_Actual := True;
                              end if;

                              exit;
                           end if;

                           Next_Formal (Formal);
                           Next_Actual (Actual);
                        end loop;
                     end if;
                  end;
               end if;

               if Is_Writable_Actual then

                  --  Skip checking the error in non-elementary types since
                  --  RM 6.4.1(6.15/3) is restricted to elementary types, but
                  --  store this actual in Writable_Actuals_List since it is
                  --  needed to perform checks on other constructs that have
                  --  arbitrary order of evaluation (for example, aggregates).

                  if not Is_Elementary_Type (Etype (N)) then
                     if not Contains (Writable_Actuals_List, N) then
                        Append_New_Elmt (N, To => Writable_Actuals_List);
                     end if;

                  --  Second occurrence of an elementary type writable actual

                  elsif Contains (Writable_Actuals_List, N) then

                     --  Report the error on the second occurrence of the
                     --  identifier. We cannot assume that N is the second
                     --  occurrence (according to their location in the
                     --  sources), since Traverse_Func walks through Field2
                     --  last (see comment in the body of Traverse_Func).

                     declare
                        Elmt : Elmt_Id;

                     begin
                        Elmt := First_Elmt (Writable_Actuals_List);
                        while Present (Elmt)
                           and then Entity (Node (Elmt)) /= Entity (N)
                        loop
                           Next_Elmt (Elmt);
                        end loop;

                        if Sloc (N) > Sloc (Node (Elmt)) then
                           Error_Node := N;
                        else
                           Error_Node := Node (Elmt);
                        end if;

                        Error_Msg_NE
                          ("value may be affected by call to & "
                           & "because order of evaluation is arbitrary",
                           Error_Node, Id);
                        return Abandon;
                     end;

                  --  First occurrence of a elementary type writable actual

                  else
                     Append_New_Elmt (N, To => Writable_Actuals_List);
                  end if;

               else
                  if No (Identifiers_List) then
                     Identifiers_List := New_Elmt_List;
                  end if;

                  Append_Unique_Elmt (N, Identifiers_List);
               end if;
            end if;

            return OK;
         end Check_Node;

         --------------
         -- Contains --
         --------------

         function Contains
           (List : Elist_Id;
            N    : Node_Id) return Boolean
         is
            pragma Assert (Nkind (N) in N_Has_Entity);

            Elmt : Elmt_Id;

         begin
            if No (List) then
               return False;
            end if;

            Elmt := First_Elmt (List);
            while Present (Elmt) loop
               if Entity (Node (Elmt)) = Entity (N) then
                  return True;
               else
                  Next_Elmt (Elmt);
               end if;
            end loop;

            return False;
         end Contains;

         ------------------
         -- Do_Traversal --
         ------------------

         procedure Do_Traversal is new Traverse_Proc (Check_Node);
         --  The traversal procedure

      --  Start of processing for Collect_Identifiers

      begin
         if Present (Error_Node) then
            return;
         end if;

         if Nkind (N) in N_Subexpr and then Is_OK_Static_Expression (N) then
            return;
         end if;

         Do_Traversal (N);
      end Collect_Identifiers;

   --  Start of processing for Check_Function_Writable_Actuals

   begin
      --  The check only applies to Ada 2012 code on which Check_Actuals has
      --  been set, and only to constructs that have multiple constituents
      --  whose order of evaluation is not specified by the language.

      if Ada_Version < Ada_2012
        or else not Check_Actuals (N)
        or else Nkind (N) not in N_Op
                               | N_Membership_Test
                               | N_Range
                               | N_Aggregate
                               | N_Extension_Aggregate
                               | N_Full_Type_Declaration
                               | N_Function_Call
                               | N_Procedure_Call_Statement
                               | N_Entry_Call_Statement
        or else (Nkind (N) = N_Full_Type_Declaration
                  and then not Is_Record_Type (Defining_Identifier (N)))

        --  In addition, this check only applies to source code, not to code
        --  generated by constraint checks.

        or else not Comes_From_Source (N)
      then
         return;
      end if;

      --  If a construct C has two or more direct constituents that are names
      --  or expressions whose evaluation may occur in an arbitrary order, at
      --  least one of which contains a function call with an in out or out
      --  parameter, then the construct is legal only if: for each name N that
      --  is passed as a parameter of mode in out or out to some inner function
      --  call C2 (not including the construct C itself), there is no other
      --  name anywhere within a direct constituent of the construct C other
      --  than the one containing C2, that is known to refer to the same
      --  object (RM 6.4.1(6.17/3)).

      case Nkind (N) is
         when N_Range =>
            Collect_Identifiers (Low_Bound (N));
            Collect_Identifiers (High_Bound (N));

         when N_Membership_Test
            | N_Op
         =>
            declare
               Expr : Node_Id;

            begin
               Collect_Identifiers (Left_Opnd (N));

               if Present (Right_Opnd (N)) then
                  Collect_Identifiers (Right_Opnd (N));
               end if;

               if Nkind (N) in N_Membership_Test then
                  Expr := First (Alternatives (N));
                  while Present (Expr) loop
                     Collect_Identifiers (Expr);

                     Next (Expr);
                  end loop;
               end if;
            end;

         when N_Full_Type_Declaration =>
            declare
               function Get_Record_Part (N : Node_Id) return Node_Id;
               --  Return the record part of this record type definition

               ---------------------
               -- Get_Record_Part --
               ---------------------

               function Get_Record_Part (N : Node_Id) return Node_Id is
                  Type_Def : constant Node_Id := Type_Definition (N);
               begin
                  if Nkind (Type_Def) = N_Derived_Type_Definition then
                     return Record_Extension_Part (Type_Def);
                  else
                     return Type_Def;
                  end if;
               end Get_Record_Part;

               Comp   : Node_Id;
               Def_Id : Entity_Id := Defining_Identifier (N);
               Rec    : Node_Id   := Get_Record_Part (N);

            begin
               --  No need to perform any analysis if the record has no
               --  components

               if No (Rec) or else No (Component_List (Rec)) then
                  return;
               end if;

               --  Collect the identifiers starting from the deepest
               --  derivation. Done to report the error in the deepest
               --  derivation.

               loop
                  if Present (Component_List (Rec)) then
                     Comp := First (Component_Items (Component_List (Rec)));
                     while Present (Comp) loop
                        if Nkind (Comp) = N_Component_Declaration
                          and then Present (Expression (Comp))
                        then
                           Collect_Identifiers (Expression (Comp));
                        end if;

                        Next (Comp);
                     end loop;
                  end if;

                  exit when No (Underlying_Type (Etype (Def_Id)))
                    or else Base_Type (Underlying_Type (Etype (Def_Id)))
                              = Def_Id;

                  Def_Id := Base_Type (Underlying_Type (Etype (Def_Id)));
                  Rec := Get_Record_Part (Parent (Def_Id));
               end loop;
            end;

         when N_Entry_Call_Statement
            | N_Subprogram_Call
         =>
            declare
               Id     : constant Entity_Id := Get_Called_Entity (N);
               Formal : Node_Id;
               Actual : Node_Id;

            begin
               Formal := First_Formal (Id);
               Actual := First_Actual (N);
               while Present (Actual) and then Present (Formal) loop
                  if Ekind (Formal) in E_Out_Parameter | E_In_Out_Parameter
                  then
                     Collect_Identifiers (Actual);
                  end if;

                  Next_Formal (Formal);
                  Next_Actual (Actual);
               end loop;
            end;

         when N_Aggregate
            | N_Extension_Aggregate
         =>
            declare
               Assoc     : Node_Id;
               Choice    : Node_Id;
               Comp_Expr : Node_Id;

            begin
               --  Handle the N_Others_Choice of array aggregates with static
               --  bounds. There is no need to perform this analysis in
               --  aggregates without static bounds since we cannot evaluate
               --  if the N_Others_Choice covers several elements. There is
               --  no need to handle the N_Others choice of record aggregates
               --  since at this stage it has been already expanded by
               --  Resolve_Record_Aggregate.

               if Is_Array_Type (Etype (N))
                 and then Nkind (N) = N_Aggregate
                 and then Present (Aggregate_Bounds (N))
                 and then Compile_Time_Known_Bounds (Etype (N))
                 and then Expr_Value (High_Bound (Aggregate_Bounds (N)))
                            >
                          Expr_Value (Low_Bound (Aggregate_Bounds (N)))
               then
                  declare
                     Count_Components   : Uint := Uint_0;
                     Num_Components     : Uint;
                     Others_Assoc       : Node_Id := Empty;
                     Others_Choice      : Node_Id := Empty;
                     Others_Box_Present : Boolean := False;

                  begin
                     --  Count positional associations

                     if Present (Expressions (N)) then
                        Comp_Expr := First (Expressions (N));
                        while Present (Comp_Expr) loop
                           Count_Components := Count_Components + 1;
                           Next (Comp_Expr);
                        end loop;
                     end if;

                     --  Count the rest of elements and locate the N_Others
                     --  choice (if any)

                     Assoc := First (Component_Associations (N));
                     while Present (Assoc) loop
                        Choice := First (Choices (Assoc));
                        while Present (Choice) loop
                           if Nkind (Choice) = N_Others_Choice then
                              Others_Assoc       := Assoc;
                              Others_Choice      := Choice;
                              Others_Box_Present := Box_Present (Assoc);

                           --  Count several components

                           elsif Nkind (Choice) in
                                   N_Range | N_Subtype_Indication
                             or else (Is_Entity_Name (Choice)
                                       and then Is_Type (Entity (Choice)))
                           then
                              declare
                                 L, H : Node_Id;
                              begin
                                 Get_Index_Bounds (Choice, L, H);
                                 pragma Assert
                                   (Compile_Time_Known_Value (L)
                                     and then Compile_Time_Known_Value (H));
                                 Count_Components :=
                                   Count_Components
                                     + Expr_Value (H) - Expr_Value (L) + 1;
                              end;

                           --  Count single component. No other case available
                           --  since we are handling an aggregate with static
                           --  bounds.

                           else
                              pragma Assert (Is_OK_Static_Expression (Choice)
                                or else Nkind (Choice) = N_Identifier
                                or else Nkind (Choice) = N_Integer_Literal);

                              Count_Components := Count_Components + 1;
                           end if;

                           Next (Choice);
                        end loop;

                        Next (Assoc);
                     end loop;

                     Num_Components :=
                       Expr_Value (High_Bound (Aggregate_Bounds (N))) -
                         Expr_Value (Low_Bound (Aggregate_Bounds (N))) + 1;

                     pragma Assert (Count_Components <= Num_Components);

                     --  Handle the N_Others choice if it covers several
                     --  components

                     if Present (Others_Choice)
                       and then (Num_Components - Count_Components) > 1
                     then
                        if not Others_Box_Present then

                           --  At this stage, if expansion is active, the
                           --  expression of the others choice has not been
                           --  analyzed. Hence we generate a duplicate and
                           --  we analyze it silently to have available the
                           --  minimum decoration required to collect the
                           --  identifiers.

                           pragma Assert (Present (Others_Assoc));

                           if not Expander_Active then
                              Comp_Expr := Expression (Others_Assoc);
                           else
                              Comp_Expr :=
                                New_Copy_Tree (Expression (Others_Assoc));
                              Preanalyze_Without_Errors (Comp_Expr);
                           end if;

                           Collect_Identifiers (Comp_Expr);

                           if Present (Writable_Actuals_List) then

                              --  As suggested by Robert, at current stage we
                              --  report occurrences of this case as warnings.

                              Error_Msg_N
                                ("writable function parameter may affect "
                                 & "value in other component because order "
                                 & "of evaluation is unspecified??",
                                 Node (First_Elmt (Writable_Actuals_List)));
                           end if;
                        end if;
                     end if;
                  end;

               --  For an array aggregate, a discrete_choice_list that has
               --  a nonstatic range is considered as two or more separate
               --  occurrences of the expression (RM 6.4.1(20/3)).

               elsif Is_Array_Type (Etype (N))
                 and then Nkind (N) = N_Aggregate
                 and then Present (Aggregate_Bounds (N))
                 and then not Compile_Time_Known_Bounds (Etype (N))
               then
                  --  Collect identifiers found in the dynamic bounds

                  declare
                     Count_Components : Natural := 0;
                     Low, High        : Node_Id;

                  begin
                     Assoc := First (Component_Associations (N));
                     while Present (Assoc) loop
                        Choice := First (Choices (Assoc));
                        while Present (Choice) loop
                           if Nkind (Choice) in
                                N_Range | N_Subtype_Indication
                             or else (Is_Entity_Name (Choice)
                                       and then Is_Type (Entity (Choice)))
                           then
                              Get_Index_Bounds (Choice, Low, High);

                              if not Compile_Time_Known_Value (Low) then
                                 Collect_Identifiers (Low);

                                 if No (Aggr_Error_Node) then
                                    Aggr_Error_Node := Low;
                                 end if;
                              end if;

                              if not Compile_Time_Known_Value (High) then
                                 Collect_Identifiers (High);

                                 if No (Aggr_Error_Node) then
                                    Aggr_Error_Node := High;
                                 end if;
                              end if;

                           --  The RM rule is violated if there is more than
                           --  a single choice in a component association.

                           else
                              Count_Components := Count_Components + 1;

                              if No (Aggr_Error_Node)
                                and then Count_Components > 1
                              then
                                 Aggr_Error_Node := Choice;
                              end if;

                              if not Compile_Time_Known_Value (Choice) then
                                 Collect_Identifiers (Choice);
                              end if;
                           end if;

                           Next (Choice);
                        end loop;

                        Next (Assoc);
                     end loop;
                  end;
               end if;

               --  Handle ancestor part of extension aggregates

               if Nkind (N) = N_Extension_Aggregate then
                  Collect_Identifiers (Ancestor_Part (N));
               end if;

               --  Handle positional associations

               if Present (Expressions (N)) then
                  Comp_Expr := First (Expressions (N));
                  while Present (Comp_Expr) loop
                     if not Is_OK_Static_Expression (Comp_Expr) then
                        Collect_Identifiers (Comp_Expr);
                     end if;

                     Next (Comp_Expr);
                  end loop;
               end if;

               --  Handle discrete associations

               if Present (Component_Associations (N)) then
                  Assoc := First (Component_Associations (N));
                  while Present (Assoc) loop

                     if not Box_Present (Assoc) then
                        Choice := First (Choices (Assoc));
                        while Present (Choice) loop

                           --  For now we skip discriminants since it requires
                           --  performing the analysis in two phases: first one
                           --  analyzing discriminants and second one analyzing
                           --  the rest of components since discriminants are
                           --  evaluated prior to components: too much extra
                           --  work to detect a corner case???

                           if Nkind (Choice) in N_Has_Entity
                             and then Present (Entity (Choice))
                             and then Ekind (Entity (Choice)) = E_Discriminant
                           then
                              null;

                           elsif Box_Present (Assoc) then
                              null;

                           else
                              if not Analyzed (Expression (Assoc)) then
                                 Comp_Expr :=
                                   New_Copy_Tree (Expression (Assoc));
                                 Set_Parent (Comp_Expr, Parent (N));
                                 Preanalyze_Without_Errors (Comp_Expr);
                              else
                                 Comp_Expr := Expression (Assoc);
                              end if;

                              Collect_Identifiers (Comp_Expr);
                           end if;

                           Next (Choice);
                        end loop;
                     end if;

                     Next (Assoc);
                  end loop;
               end if;
            end;

         when others =>
            return;
      end case;

      --  No further action needed if we already reported an error

      if Present (Error_Node) then
         return;
      end if;

      --  Check violation of RM 6.20/3 in aggregates

      if Present (Aggr_Error_Node)
        and then Present (Writable_Actuals_List)
      then
         Error_Msg_N
           ("value may be affected by call in other component because they "
            & "are evaluated in unspecified order",
            Node (First_Elmt (Writable_Actuals_List)));
         return;
      end if;

      --  Check if some writable argument of a function is referenced

      if Present (Writable_Actuals_List)
        and then Present (Identifiers_List)
      then
         declare
            Elmt_1 : Elmt_Id;
            Elmt_2 : Elmt_Id;

         begin
            Elmt_1 := First_Elmt (Writable_Actuals_List);
            while Present (Elmt_1) loop
               Elmt_2 := First_Elmt (Identifiers_List);
               while Present (Elmt_2) loop
                  if Entity (Node (Elmt_1)) = Entity (Node (Elmt_2)) then
                     case Nkind (Parent (Node (Elmt_2))) is
                        when N_Aggregate
                           | N_Component_Association
                           | N_Component_Declaration
                        =>
                           Error_Msg_N
                             ("value may be affected by call in other "
                              & "component because they are evaluated "
                              & "in unspecified order",
                              Node (Elmt_2));

                        when N_Membership_Test =>
                           Error_Msg_N
                             ("value may be affected by call in other "
                              & "alternative because they are evaluated "
                              & "in unspecified order",
                              Node (Elmt_2));

                        when others =>
                           Error_Msg_N
                             ("value of actual may be affected by call in "
                              & "other actual because they are evaluated "
                              & "in unspecified order",
                              Node (Elmt_2));
                     end case;
                  end if;

                  Next_Elmt (Elmt_2);
               end loop;

               Next_Elmt (Elmt_1);
            end loop;
         end;
      end if;
   end Check_Function_Writable_Actuals;

   --------------------------------
   -- Check_Implicit_Dereference --
   --------------------------------

   procedure Check_Implicit_Dereference (N : Node_Id;  Typ : Entity_Id) is
      Disc  : Entity_Id;
      Desig : Entity_Id;
      Nam   : Node_Id;

   begin
      if Nkind (N) = N_Indexed_Component
        and then Present (Generalized_Indexing (N))
      then
         Nam := Generalized_Indexing (N);
      else
         Nam := N;
      end if;

      if Ada_Version < Ada_2012
        or else not Has_Implicit_Dereference (Base_Type (Typ))
      then
         return;

      elsif not Comes_From_Source (N)
        and then Nkind (N) /= N_Indexed_Component
      then
         return;

      elsif Is_Entity_Name (Nam) and then Is_Type (Entity (Nam)) then
         null;

      else
         Disc := First_Discriminant (Typ);
         while Present (Disc) loop
            if Has_Implicit_Dereference (Disc) then
               Desig := Designated_Type (Etype (Disc));
               Add_One_Interp (Nam, Disc, Desig);

               --  If the node is a generalized indexing, add interpretation
               --  to that node as well, for subsequent resolution.

               if Nkind (N) = N_Indexed_Component then
                  Add_One_Interp (N, Disc, Desig);
               end if;

               --  If the operation comes from a generic unit and the context
               --  is a selected component, the selector name may be global
               --  and set in the instance already. Remove the entity to
               --  force resolution of the selected component, and the
               --  generation of an explicit dereference if needed.

               if In_Instance
                 and then Nkind (Parent (Nam)) = N_Selected_Component
               then
                  Set_Entity (Selector_Name (Parent (Nam)), Empty);
               end if;

               exit;
            end if;

            Next_Discriminant (Disc);
         end loop;
      end if;
   end Check_Implicit_Dereference;

   ----------------------------------
   -- Check_Internal_Protected_Use --
   ----------------------------------

   procedure Check_Internal_Protected_Use (N : Node_Id; Nam : Entity_Id) is
      S    : Entity_Id;
      Prot : Entity_Id;

   begin
      Prot := Empty;

      S := Current_Scope;
      while Present (S) loop
         if S = Standard_Standard then
            exit;

         elsif Ekind (S) = E_Function
           and then Ekind (Scope (S)) = E_Protected_Type
         then
            Prot := Scope (S);
            exit;
         end if;

         S := Scope (S);
      end loop;

      if Present (Prot)
        and then Scope (Nam) = Prot
        and then Ekind (Nam) /= E_Function
      then
         --  An indirect function call (e.g. a callback within a protected
         --  function body) is not statically illegal. If the access type is
         --  anonymous and is the type of an access parameter, the scope of Nam
         --  will be the protected type, but it is not a protected operation.

         if Ekind (Nam) = E_Subprogram_Type
           and then Nkind (Associated_Node_For_Itype (Nam)) =
                      N_Function_Specification
         then
            null;

         elsif Nkind (N) = N_Subprogram_Renaming_Declaration then
            Error_Msg_N
              ("within protected function cannot use protected procedure in "
               & "renaming or as generic actual", N);

         elsif Nkind (N) = N_Attribute_Reference then
            Error_Msg_N
              ("within protected function cannot take access of protected "
               & "procedure", N);

         else
            Error_Msg_N
              ("within protected function, protected object is constant", N);
            Error_Msg_N
              ("\cannot call operation that may modify it", N);
         end if;
      end if;

      --  Verify that an internal call does not appear within a precondition
      --  of a protected operation. This implements AI12-0166.
      --  The precondition aspect has been rewritten as a pragma Precondition
      --  and we check whether the scope of the called subprogram is the same
      --  as that of the entity to which the aspect applies.

      if Convention (Nam) = Convention_Protected then
         declare
            P : Node_Id;

         begin
            P := Parent (N);
            while Present (P) loop
               if Nkind (P) = N_Pragma
                 and then Chars (Pragma_Identifier (P)) = Name_Precondition
                 and then From_Aspect_Specification (P)
                 and then
                   Scope (Entity (Corresponding_Aspect (P))) = Scope (Nam)
               then
                  Error_Msg_N
                    ("internal call cannot appear in precondition of "
                     & "protected operation", N);
                  return;

               elsif Nkind (P) = N_Pragma
                 and then Chars (Pragma_Identifier (P)) = Name_Contract_Cases
               then
                  --  Check whether call is in a case guard. It is legal in a
                  --  consequence.

                  P := N;
                  while Present (P) loop
                     if Nkind (Parent (P)) = N_Component_Association
                       and then P /= Expression (Parent (P))
                     then
                        Error_Msg_N
                          ("internal call cannot appear in case guard in a "
                           & "contract case", N);
                     end if;

                     P := Parent (P);
                  end loop;

                  return;

               elsif Nkind (P) = N_Parameter_Specification
                 and then Scope (Current_Scope) = Scope (Nam)
                 and then Nkind (Parent (P)) in
                            N_Entry_Declaration | N_Subprogram_Declaration
               then
                  Error_Msg_N
                    ("internal call cannot appear in default for formal of "
                     & "protected operation", N);
                  return;

               --  Prevent the search from going too far

               elsif Is_Body_Or_Package_Declaration (P) then
                  exit;
               end if;

               P := Parent (P);
            end loop;
         end;
      end if;
   end Check_Internal_Protected_Use;

   ---------------------------------------
   -- Check_Later_Vs_Basic_Declarations --
   ---------------------------------------

   procedure Check_Later_Vs_Basic_Declarations
     (Decls          : List_Id;
      During_Parsing : Boolean)
   is
      Body_Sloc : Source_Ptr;
      Decl      : Node_Id;

      function Is_Later_Declarative_Item (Decl : Node_Id) return Boolean;
      --  Return whether Decl is considered as a declarative item.
      --  When During_Parsing is True, the semantics of Ada 83 is followed.
      --  When During_Parsing is False, the semantics of SPARK is followed.

      -------------------------------
      -- Is_Later_Declarative_Item --
      -------------------------------

      function Is_Later_Declarative_Item (Decl : Node_Id) return Boolean is
      begin
         if Nkind (Decl) in N_Later_Decl_Item then
            return True;

         elsif Nkind (Decl) = N_Pragma then
            return True;

         elsif During_Parsing then
            return False;

         --  In SPARK, a package declaration is not considered as a later
         --  declarative item.

         elsif Nkind (Decl) = N_Package_Declaration then
            return False;

         --  In SPARK, a renaming is considered as a later declarative item

         elsif Nkind (Decl) in N_Renaming_Declaration then
            return True;

         else
            return False;
         end if;
      end Is_Later_Declarative_Item;

   --  Start of processing for Check_Later_Vs_Basic_Declarations

   begin
      Decl := First (Decls);

      --  Loop through sequence of basic declarative items

      Outer : while Present (Decl) loop
         if Nkind (Decl) not in
              N_Subprogram_Body | N_Package_Body | N_Task_Body
           and then Nkind (Decl) not in N_Body_Stub
         then
            Next (Decl);

            --  Once a body is encountered, we only allow later declarative
            --  items. The inner loop checks the rest of the list.

         else
            Body_Sloc := Sloc (Decl);

            Inner : while Present (Decl) loop
               if not Is_Later_Declarative_Item (Decl) then
                  if During_Parsing then
                     if Ada_Version = Ada_83 then
                        Error_Msg_Sloc := Body_Sloc;
                        Error_Msg_N
                          ("(Ada 83) decl cannot appear after body#", Decl);
                     end if;
                  end if;
               end if;

               Next (Decl);
            end loop Inner;
         end if;
      end loop Outer;
   end Check_Later_Vs_Basic_Declarations;

   ---------------------------
   -- Check_No_Hidden_State --
   ---------------------------

   procedure Check_No_Hidden_State (Id : Entity_Id) is
      Context     : Entity_Id := Empty;
      Not_Visible : Boolean   := False;
      Scop        : Entity_Id;

   begin
      pragma Assert (Ekind (Id) in E_Abstract_State | E_Variable);

      --  Nothing to do for internally-generated abstract states and variables
      --  because they do not represent the hidden state of the source unit.

      if not Comes_From_Source (Id) then
         return;
      end if;

      --  Find the proper context where the object or state appears

      Scop := Scope (Id);
      while Present (Scop) loop
         Context := Scop;

         --  Keep track of the context's visibility

         Not_Visible := Not_Visible or else In_Private_Part (Context);

         --  Prevent the search from going too far

         if Context = Standard_Standard then
            return;

         --  Objects and states that appear immediately within a subprogram or
         --  entry inside a construct nested within a subprogram do not
         --  introduce a hidden state. They behave as local variable
         --  declarations. The same is true for elaboration code inside a block
         --  or a task.

         elsif Is_Subprogram_Or_Entry (Context)
           or else Ekind (Context) in E_Block | E_Task_Type
         then
            return;
         end if;

         --  Stop the traversal when a package subject to a null abstract state
         --  has been found.

         if Is_Package_Or_Generic_Package (Context)
           and then Has_Null_Abstract_State (Context)
         then
            exit;
         end if;

         Scop := Scope (Scop);
      end loop;

      --  At this point we know that there is at least one package with a null
      --  abstract state in visibility. Emit an error message unconditionally
      --  if the entity being processed is a state because the placement of the
      --  related package is irrelevant. This is not the case for objects as
      --  the intermediate context matters.

      if Present (Context)
        and then (Ekind (Id) = E_Abstract_State or else Not_Visible)
      then
         Error_Msg_N ("cannot introduce hidden state &", Id);
         Error_Msg_NE ("\package & has null abstract state", Id, Context);
      end if;
   end Check_No_Hidden_State;

   ---------------------------------------------
   -- Check_Nonoverridable_Aspect_Consistency --
   ---------------------------------------------

   procedure Check_Inherited_Nonoverridable_Aspects
     (Inheritor      : Entity_Id;
      Interface_List : List_Id;
      Parent_Type    : Entity_Id) is

      --  array needed for iterating over subtype values
      Nonoverridable_Aspects : constant array (Positive range <>) of
        Nonoverridable_Aspect_Id :=
          (Aspect_Default_Iterator,
           Aspect_Iterator_Element,
           Aspect_Implicit_Dereference,
           Aspect_Constant_Indexing,
           Aspect_Variable_Indexing,
           Aspect_Aggregate,
           Aspect_Max_Entry_Queue_Length
           --  , Aspect_No_Controlled_Parts
          );

      --  Note that none of these 8 aspects can be specified (for a type)
      --  via a pragma. For 7 of them, the corresponding pragma does not
      --  exist. The Pragma_Id enumeration type does include
      --  Pragma_Max_Entry_Queue_Length, but that pragma is only use to
      --  specify the aspect for a protected entry or entry family, not for
      --  a type, and therefore cannot introduce the sorts of inheritance
      --  issues that we are concerned with in this procedure.

      type Entity_Array is array (Nat range <>) of Entity_Id;

      function Ancestor_Entities return Entity_Array;
      --  Returns all progenitors (including parent type, if present)

      procedure Check_Consistency_For_One_Aspect_Of_Two_Ancestors
        (Aspect        : Nonoverridable_Aspect_Id;
         Ancestor_1    : Entity_Id;
         Aspect_Spec_1 : Node_Id;
         Ancestor_2    : Entity_Id;
         Aspect_Spec_2 : Node_Id);
      --  A given aspect has been specified for each of two ancestors;
      --  check that the two aspect specifications are compatible (see
      --  RM 13.1.1(18.5) and AI12-0211).

      -----------------------
      -- Ancestor_Entities --
      -----------------------

      function Ancestor_Entities return Entity_Array is
         Ifc_Count : constant Nat := List_Length (Interface_List);
         Ifc_Ancestors : Entity_Array (1 .. Ifc_Count);
         Ifc : Node_Id := First (Interface_List);
      begin
         for Idx in Ifc_Ancestors'Range loop
            Ifc_Ancestors (Idx) := Entity (Ifc);
            pragma Assert (Present (Ifc_Ancestors (Idx)));
            Ifc := Next (Ifc);
         end loop;
         pragma Assert (No (Ifc));
         if Present (Parent_Type) then
            return Parent_Type & Ifc_Ancestors;
         else
            return Ifc_Ancestors;
         end if;
      end Ancestor_Entities;

      -------------------------------------------------------
      -- Check_Consistency_For_One_Aspect_Of_Two_Ancestors --
      -------------------------------------------------------

      procedure Check_Consistency_For_One_Aspect_Of_Two_Ancestors
        (Aspect        : Nonoverridable_Aspect_Id;
         Ancestor_1    : Entity_Id;
         Aspect_Spec_1 : Node_Id;
         Ancestor_2    : Entity_Id;
         Aspect_Spec_2 : Node_Id) is
      begin
         if not Is_Confirming (Aspect, Aspect_Spec_1, Aspect_Spec_2) then
            Error_Msg_Name_1 := Aspect_Names (Aspect);
            Error_Msg_Name_2 := Chars (Ancestor_1);
            Error_Msg_Name_3 := Chars (Ancestor_2);

            Error_Msg (
              "incompatible % aspects inherited from ancestors % and %",
              Sloc (Inheritor));
         end if;
      end Check_Consistency_For_One_Aspect_Of_Two_Ancestors;

      Ancestors : constant Entity_Array := Ancestor_Entities;

      --  start of processing for Check_Inherited_Nonoverridable_Aspects
   begin
      --  No Ada_Version check here; AI12-0211 is a binding interpretation.

      if Ancestors'Length < 2 then
         return; --  Inconsistency impossible; it takes 2 to disagree.
      elsif In_Instance_Body then
         return;  -- No legality checking in an instance body.
      end if;

      for Aspect of Nonoverridable_Aspects loop
         declare
            First_Ancestor_With_Aspect : Entity_Id := Empty;
            First_Aspect_Spec, Current_Aspect_Spec : Node_Id := Empty;
         begin
            for Ancestor of Ancestors loop
               Current_Aspect_Spec := Find_Aspect (Ancestor, Aspect);
               if Present (Current_Aspect_Spec) then
                  if Present (First_Ancestor_With_Aspect) then
                     Check_Consistency_For_One_Aspect_Of_Two_Ancestors
                       (Aspect        => Aspect,
                        Ancestor_1    => First_Ancestor_With_Aspect,
                        Aspect_Spec_1 => First_Aspect_Spec,
                        Ancestor_2    => Ancestor,
                        Aspect_Spec_2 => Current_Aspect_Spec);
                  else
                     First_Ancestor_With_Aspect := Ancestor;
                     First_Aspect_Spec := Current_Aspect_Spec;
                  end if;
               end if;
            end loop;
         end;
      end loop;
   end Check_Inherited_Nonoverridable_Aspects;

   ----------------------------------------
   -- Check_Nonvolatile_Function_Profile --
   ----------------------------------------

   procedure Check_Nonvolatile_Function_Profile (Func_Id : Entity_Id) is
      Formal : Entity_Id;

   begin
      --  Inspect all formal parameters

      Formal := First_Formal (Func_Id);
      while Present (Formal) loop
         if Is_Effectively_Volatile_For_Reading (Etype (Formal)) then
            Error_Msg_NE
              ("nonvolatile function & cannot have a volatile parameter",
               Formal, Func_Id);
         end if;

         Next_Formal (Formal);
      end loop;

      --  Inspect the return type

      if Is_Effectively_Volatile_For_Reading (Etype (Func_Id)) then
         Error_Msg_NE
           ("nonvolatile function & cannot have a volatile return type",
            Result_Definition (Parent (Func_Id)), Func_Id);
      end if;
   end Check_Nonvolatile_Function_Profile;

   -------------------
   -- Check_Parents --
   -------------------

   function Check_Parents (N : Node_Id; List : Elist_Id) return Boolean is

      function Check_Node
        (Parent_Node : Node_Id;
         N           : Node_Id) return Traverse_Result;
      --  Process a single node.

      ----------------
      -- Check_Node --
      ----------------

      function Check_Node
        (Parent_Node : Node_Id;
         N           : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Identifier
           and then Parent (N) /= Parent_Node
           and then Present (Entity (N))
           and then Contains (List, Entity (N))
         then
            return Abandon;
         end if;

         return OK;
      end Check_Node;

      function Traverse is new Traverse_Func_With_Parent (Check_Node);

   --  Start of processing for Check_Parents

   begin
      return Traverse (N) = OK;
   end Check_Parents;

   -----------------------------
   -- Check_Part_Of_Reference --
   -----------------------------

   procedure Check_Part_Of_Reference (Var_Id : Entity_Id; Ref : Node_Id) is
      function Is_Enclosing_Package_Body
        (Body_Decl : Node_Id;
         Obj_Id    : Entity_Id) return Boolean;
      pragma Inline (Is_Enclosing_Package_Body);
      --  Determine whether package body Body_Decl or its corresponding spec
      --  immediately encloses the declaration of object Obj_Id.

      function Is_Internal_Declaration_Or_Body
        (Decl : Node_Id) return Boolean;
      pragma Inline (Is_Internal_Declaration_Or_Body);
      --  Determine whether declaration or body denoted by Decl is internal

      function Is_Single_Declaration_Or_Body
        (Decl     : Node_Id;
         Conc_Typ : Entity_Id) return Boolean;
      pragma Inline (Is_Single_Declaration_Or_Body);
      --  Determine whether protected/task declaration or body denoted by Decl
      --  belongs to single concurrent type Conc_Typ.

      function Is_Single_Task_Pragma
        (Prag     : Node_Id;
         Task_Typ : Entity_Id) return Boolean;
      pragma Inline (Is_Single_Task_Pragma);
      --  Determine whether pragma Prag belongs to single task type Task_Typ

      -------------------------------
      -- Is_Enclosing_Package_Body --
      -------------------------------

      function Is_Enclosing_Package_Body
        (Body_Decl : Node_Id;
         Obj_Id    : Entity_Id) return Boolean
      is
         Obj_Context : Node_Id;

      begin
         --  Find the context of the object declaration

         Obj_Context := Parent (Declaration_Node (Obj_Id));

         if Nkind (Obj_Context) = N_Package_Specification then
            Obj_Context := Parent (Obj_Context);
         end if;

         --  The object appears immediately within the package body

         if Obj_Context = Body_Decl then
            return True;

         --  The object appears immediately within the corresponding spec

         elsif Nkind (Obj_Context) = N_Package_Declaration
           and then Unit_Declaration_Node (Corresponding_Spec (Body_Decl)) =
                      Obj_Context
         then
            return True;
         end if;

         return False;
      end Is_Enclosing_Package_Body;

      -------------------------------------
      -- Is_Internal_Declaration_Or_Body --
      -------------------------------------

      function Is_Internal_Declaration_Or_Body
        (Decl : Node_Id) return Boolean
      is
      begin
         if Comes_From_Source (Decl) then
            return False;

         --  A body generated for an expression function which has not been
         --  inserted into the tree yet (In_Spec_Expression is True) is not
         --  considered internal.

         elsif Nkind (Decl) = N_Subprogram_Body
           and then Was_Expression_Function (Decl)
           and then not In_Spec_Expression
         then
            return False;
         end if;

         return True;
      end Is_Internal_Declaration_Or_Body;

      -----------------------------------
      -- Is_Single_Declaration_Or_Body --
      -----------------------------------

      function Is_Single_Declaration_Or_Body
        (Decl     : Node_Id;
         Conc_Typ : Entity_Id) return Boolean
      is
         Spec_Id : constant Entity_Id := Unique_Defining_Entity (Decl);

      begin
         return
           Present (Anonymous_Object (Spec_Id))
             and then Anonymous_Object (Spec_Id) = Conc_Typ;
      end Is_Single_Declaration_Or_Body;

      ---------------------------
      -- Is_Single_Task_Pragma --
      ---------------------------

      function Is_Single_Task_Pragma
        (Prag     : Node_Id;
         Task_Typ : Entity_Id) return Boolean
      is
         Decl : constant Node_Id := Find_Related_Declaration_Or_Body (Prag);

      begin
         --  To qualify, the pragma must be associated with single task type
         --  Task_Typ.

         return
           Is_Single_Task_Object (Task_Typ)
             and then Nkind (Decl) = N_Object_Declaration
             and then Defining_Entity (Decl) = Task_Typ;
      end Is_Single_Task_Pragma;

      --  Local variables

      Conc_Obj : constant Entity_Id := Encapsulating_State (Var_Id);
      Par      : Node_Id;
      Prag_Nam : Name_Id;
      Prev     : Node_Id;

   --  Start of processing for Check_Part_Of_Reference

   begin
      --  Nothing to do when the variable was recorded, but did not become a
      --  constituent of a single concurrent type.

      if No (Conc_Obj) then
         return;
      end if;

      --  Traverse the parent chain looking for a suitable context for the
      --  reference to the concurrent constituent.

      Prev := Ref;
      Par  := Parent (Prev);
      while Present (Par) loop
         if Nkind (Par) = N_Pragma then
            Prag_Nam := Pragma_Name (Par);

            --  A concurrent constituent is allowed to appear in pragmas
            --  Initial_Condition and Initializes as this is part of the
            --  elaboration checks for the constituent (SPARK RM 9(3)).

            if Prag_Nam in Name_Initial_Condition | Name_Initializes then
               return;

            --  When the reference appears within pragma Depends or Global,
            --  check whether the pragma applies to a single task type. Note
            --  that the pragma may not encapsulated by the type definition,
            --  but this is still a valid context.

            elsif Prag_Nam in Name_Depends | Name_Global
              and then Is_Single_Task_Pragma (Par, Conc_Obj)
            then
               return;
            end if;

         --  The reference appears somewhere in the definition of a single
         --  concurrent type (SPARK RM 9(3)).

         elsif Nkind (Par) in
                 N_Single_Protected_Declaration | N_Single_Task_Declaration
           and then Defining_Entity (Par) = Conc_Obj
         then
            return;

         --  The reference appears within the declaration or body of a single
         --  concurrent type (SPARK RM 9(3)).

         elsif Nkind (Par) in N_Protected_Body
                            | N_Protected_Type_Declaration
                            | N_Task_Body
                            | N_Task_Type_Declaration
           and then Is_Single_Declaration_Or_Body (Par, Conc_Obj)
         then
            return;

         --  The reference appears within the statement list of the object's
         --  immediately enclosing package (SPARK RM 9(3)).

         elsif Nkind (Par) = N_Package_Body
           and then Nkind (Prev) = N_Handled_Sequence_Of_Statements
           and then Is_Enclosing_Package_Body (Par, Var_Id)
         then
            return;

         --  The reference has been relocated within an internally generated
         --  package or subprogram. Assume that the reference is legal as the
         --  real check was already performed in the original context of the
         --  reference.

         elsif Nkind (Par) in N_Package_Body
                            | N_Package_Declaration
                            | N_Subprogram_Body
                            | N_Subprogram_Declaration
           and then Is_Internal_Declaration_Or_Body (Par)
         then
            return;

         --  The reference has been relocated to an inlined body for GNATprove.
         --  Assume that the reference is legal as the real check was already
         --  performed in the original context of the reference.

         elsif GNATprove_Mode
           and then Nkind (Par) = N_Subprogram_Body
           and then Chars (Defining_Entity (Par)) = Name_uParent
         then
            return;
         end if;

         Prev := Par;
         Par  := Parent (Prev);
      end loop;

      --  At this point it is known that the reference does not appear within a
      --  legal context.

      Error_Msg_NE
        ("reference to variable & cannot appear in this context", Ref, Var_Id);
      Error_Msg_Name_1 := Chars (Var_Id);

      if Is_Single_Protected_Object (Conc_Obj) then
         Error_Msg_NE
           ("\% is constituent of single protected type &", Ref, Conc_Obj);

      else
         Error_Msg_NE
           ("\% is constituent of single task type &", Ref, Conc_Obj);
      end if;
   end Check_Part_Of_Reference;

   ------------------------------------------
   -- Check_Potentially_Blocking_Operation --
   ------------------------------------------

   procedure Check_Potentially_Blocking_Operation (N : Node_Id) is
      S : Entity_Id;

   begin
      --  N is one of the potentially blocking operations listed in 9.5.1(8).
      --  When pragma Detect_Blocking is active, the run time will raise
      --  Program_Error. Here we only issue a warning, since we generally
      --  support the use of potentially blocking operations in the absence
      --  of the pragma.

      --  Indirect blocking through a subprogram call cannot be diagnosed
      --  statically without interprocedural analysis, so we do not attempt
      --  to do it here.

      S := Scope (Current_Scope);
      while Present (S) and then S /= Standard_Standard loop
         if Is_Protected_Type (S) then
            Error_Msg_N
              ("potentially blocking operation in protected operation??", N);
            return;
         end if;

         S := Scope (S);
      end loop;
   end Check_Potentially_Blocking_Operation;

   ------------------------------------
   --  Check_Previous_Null_Procedure --
   ------------------------------------

   procedure Check_Previous_Null_Procedure
     (Decl : Node_Id;
      Prev : Entity_Id)
   is
   begin
      if Ekind (Prev) = E_Procedure
        and then Nkind (Parent (Prev)) = N_Procedure_Specification
        and then Null_Present (Parent (Prev))
      then
         Error_Msg_Sloc := Sloc (Prev);
         Error_Msg_N
           ("declaration cannot complete previous null procedure#", Decl);
      end if;
   end Check_Previous_Null_Procedure;

   ---------------------------------
   -- Check_Result_And_Post_State --
   ---------------------------------

   procedure Check_Result_And_Post_State (Subp_Id : Entity_Id) is
      procedure Check_Result_And_Post_State_In_Pragma
        (Prag        : Node_Id;
         Result_Seen : in out Boolean);
      --  Determine whether pragma Prag mentions attribute 'Result and whether
      --  the pragma contains an expression that evaluates differently in pre-
      --  and post-state. Prag is a [refined] postcondition or a contract-cases
      --  pragma. Result_Seen is set when the pragma mentions attribute 'Result

      -------------------------------------------
      -- Check_Result_And_Post_State_In_Pragma --
      -------------------------------------------

      procedure Check_Result_And_Post_State_In_Pragma
        (Prag        : Node_Id;
         Result_Seen : in out Boolean)
      is
         procedure Check_Conjunct (Expr : Node_Id);
         --  Check an individual conjunct in a conjunction of Boolean
         --  expressions, connected by "and" or "and then" operators.

         procedure Check_Conjuncts (Expr : Node_Id);
         --  Apply the post-state check to every conjunct in an expression, in
         --  case this is a conjunction of Boolean expressions. Otherwise apply
         --  it to the expression as a whole.

         procedure Check_Expression (Expr : Node_Id);
         --  Perform the 'Result and post-state checks on a given expression

         function Is_Function_Result (N : Node_Id) return Traverse_Result;
         --  Attempt to find attribute 'Result in a subtree denoted by N

         function Mentions_Post_State (N : Node_Id) return Boolean;
         --  Determine whether a subtree denoted by N mentions any construct
         --  that denotes a post-state.

         procedure Check_Function_Result is
           new Traverse_Proc (Is_Function_Result);

         --------------------
         -- Check_Conjunct --
         --------------------

         procedure Check_Conjunct (Expr : Node_Id) is
            function Adjust_Message (Msg : String) return String;
            --  Prepend a prefix to the input message Msg denoting that the
            --  message applies to a conjunct in the expression, when this
            --  is the case.

            function Applied_On_Conjunct return Boolean;
            --  Returns True if the message applies to a conjunct in the
            --  expression, instead of the whole expression.

            function Has_Global_Output (Subp : Entity_Id) return Boolean;
            --  Returns True if Subp has an output in its Global contract

            function Has_No_Output (Subp : Entity_Id) return Boolean;
            --  Returns True if Subp has no declared output: no function
            --  result, no output parameter, and no output in its Global
            --  contract.

            --------------------
            -- Adjust_Message --
            --------------------

            function Adjust_Message (Msg : String) return String is
            begin
               if Applied_On_Conjunct then
                  return "conjunct in " & Msg;
               else
                  return Msg;
               end if;
            end Adjust_Message;

            -------------------------
            -- Applied_On_Conjunct --
            -------------------------

            function Applied_On_Conjunct return Boolean is
            begin
               --  Expr is the conjunct of an enclosing "and" expression

               return Nkind (Parent (Expr)) in N_Subexpr

                 --  or Expr is a conjunct of an enclosing "and then"
                 --  expression in a postcondition aspect that was split into
                 --  multiple pragmas. The first conjunct has the "and then"
                 --  expression as Original_Node, and other conjuncts have
                 --  Split_PCC set to True.

                 or else Nkind (Original_Node (Expr)) = N_And_Then
                 or else Split_PPC (Prag);
            end Applied_On_Conjunct;

            -----------------------
            -- Has_Global_Output --
            -----------------------

            function Has_Global_Output (Subp : Entity_Id) return Boolean is
               Global : constant Node_Id := Get_Pragma (Subp, Pragma_Global);
               List   : Node_Id;
               Assoc  : Node_Id;

            begin
               if No (Global) then
                  return False;
               end if;

               List := Expression (Get_Argument (Global, Subp));

               --  Empty list (no global items) or single global item
               --  declaration (only input items).

               if Nkind (List) in N_Null
                                | N_Expanded_Name
                                | N_Identifier
                                | N_Selected_Component
               then
                  return False;

               --  Simple global list (only input items) or moded global list
               --  declaration.

               elsif Nkind (List) = N_Aggregate then
                  if Present (Expressions (List)) then
                     return False;

                  else
                     Assoc := First (Component_Associations (List));
                     while Present (Assoc) loop
                        if Chars (First (Choices (Assoc))) /= Name_Input then
                           return True;
                        end if;

                        Next (Assoc);
                     end loop;

                     return False;
                  end if;

               --  To accommodate partial decoration of disabled SPARK
               --  features, this routine may be called with illegal input.
               --  If this is the case, do not raise Program_Error.

               else
                  return False;
               end if;
            end Has_Global_Output;

            -------------------
            -- Has_No_Output --
            -------------------

            function Has_No_Output (Subp : Entity_Id) return Boolean is
               Param : Node_Id;

            begin
               --  A function has its result as output

               if Ekind (Subp) = E_Function then
                  return False;
               end if;

               --  An OUT or IN OUT parameter is an output

               Param := First_Formal (Subp);
               while Present (Param) loop
                  if Ekind (Param) in E_Out_Parameter | E_In_Out_Parameter then
                     return False;
                  end if;

                  Next_Formal (Param);
               end loop;

               --  An item of mode Output or In_Out in the Global contract is
               --  an output.

               if Has_Global_Output (Subp) then
                  return False;
               end if;

               return True;
            end Has_No_Output;

            --  Local variables

            Err_Node : Node_Id;
            --  Error node when reporting a warning on a (refined)
            --  postcondition.

         --  Start of processing for Check_Conjunct

         begin
            if Applied_On_Conjunct then
               Err_Node := Expr;
            else
               Err_Node := Prag;
            end if;

            --  Do not report missing reference to outcome in postcondition if
            --  either the postcondition is trivially True or False, or if the
            --  subprogram is ghost and has no declared output.

            if not Is_Trivial_Boolean (Expr)
              and then not Mentions_Post_State (Expr)
              and then not (Is_Ghost_Entity (Subp_Id)
                             and then Has_No_Output (Subp_Id))
              and then not Is_Wrapper (Subp_Id)
            then
               if Pragma_Name (Prag) = Name_Contract_Cases then
                  Error_Msg_NE (Adjust_Message
                    ("contract case does not check the outcome of calling "
                     & "&?.t?"), Expr, Subp_Id);

               elsif Pragma_Name (Prag) = Name_Refined_Post then
                  Error_Msg_NE (Adjust_Message
                    ("refined postcondition does not check the outcome of "
                     & "calling &?.t?"), Err_Node, Subp_Id);

               else
                  Error_Msg_NE (Adjust_Message
                    ("postcondition does not check the outcome of calling "
                     & "&?.t?"), Err_Node, Subp_Id);
               end if;
            end if;
         end Check_Conjunct;

         ---------------------
         -- Check_Conjuncts --
         ---------------------

         procedure Check_Conjuncts (Expr : Node_Id) is
         begin
            if Nkind (Expr) in N_Op_And | N_And_Then then
               Check_Conjuncts (Left_Opnd (Expr));
               Check_Conjuncts (Right_Opnd (Expr));
            else
               Check_Conjunct (Expr);
            end if;
         end Check_Conjuncts;

         ----------------------
         -- Check_Expression --
         ----------------------

         procedure Check_Expression (Expr : Node_Id) is
         begin
            if not Is_Trivial_Boolean (Expr) then
               Check_Function_Result (Expr);
               Check_Conjuncts (Expr);
            end if;
         end Check_Expression;

         ------------------------
         -- Is_Function_Result --
         ------------------------

         function Is_Function_Result (N : Node_Id) return Traverse_Result is
         begin
            if Is_Attribute_Result (N) then
               Result_Seen := True;
               return Abandon;

            --  Warn on infinite recursion if call is to current function

            elsif Nkind (N) = N_Function_Call
              and then Is_Entity_Name (Name (N))
              and then Entity (Name (N)) = Subp_Id
              and then not Is_Potentially_Unevaluated (N)
            then
               Error_Msg_NE
                 ("call to & within its postcondition will lead to infinite "
                  & "recursion?", N, Subp_Id);
               return OK;

            --  Continue the traversal

            else
               return OK;
            end if;
         end Is_Function_Result;

         -------------------------
         -- Mentions_Post_State --
         -------------------------

         function Mentions_Post_State (N : Node_Id) return Boolean is
            Post_State_Seen : Boolean := False;

            function Is_Post_State (N : Node_Id) return Traverse_Result;
            --  Attempt to find a construct that denotes a post-state. If this
            --  is the case, set flag Post_State_Seen.

            -------------------
            -- Is_Post_State --
            -------------------

            function Is_Post_State (N : Node_Id) return Traverse_Result is
               Ent : Entity_Id;

            begin
               if Nkind (N) in N_Explicit_Dereference | N_Function_Call then
                  Post_State_Seen := True;
                  return Abandon;

               elsif Nkind (N) in N_Expanded_Name | N_Identifier then
                  Ent := Entity (N);

                  --  Treat an undecorated reference as OK

                  if No (Ent)

                    --  A reference to an assignable entity is considered a
                    --  change in the post-state of a subprogram.

                    or else Ekind (Ent) in E_Generic_In_Out_Parameter
                                         | E_In_Out_Parameter
                                         | E_Out_Parameter
                                         | E_Variable

                    --  The reference may be modified through a dereference

                    or else (Is_Access_Type (Etype (Ent))
                              and then Nkind (Parent (N)) =
                                         N_Selected_Component)
                  then
                     Post_State_Seen := True;
                     return Abandon;
                  end if;

               elsif Nkind (N) = N_Attribute_Reference then
                  if Attribute_Name (N) = Name_Old then
                     return Skip;

                  elsif Attribute_Name (N) = Name_Result then
                     Post_State_Seen := True;
                     return Abandon;
                  end if;
               end if;

               return OK;
            end Is_Post_State;

            procedure Find_Post_State is new Traverse_Proc (Is_Post_State);

         --  Start of processing for Mentions_Post_State

         begin
            Find_Post_State (N);

            return Post_State_Seen;
         end Mentions_Post_State;

         --  Local variables

         Expr  : constant Node_Id :=
                   Get_Pragma_Arg
                     (First (Pragma_Argument_Associations (Prag)));
         Nam   : constant Name_Id := Pragma_Name (Prag);
         CCase : Node_Id;

      --  Start of processing for Check_Result_And_Post_State_In_Pragma

      begin
         --  Examine all consequences

         if Nam = Name_Contract_Cases then
            CCase := First (Component_Associations (Expr));
            while Present (CCase) loop
               Check_Expression (Expression (CCase));

               Next (CCase);
            end loop;

         --  Examine the expression of a postcondition

         else pragma Assert (Nam in Name_Postcondition | Name_Refined_Post);
            Check_Expression (Expr);
         end if;
      end Check_Result_And_Post_State_In_Pragma;

      --  Local variables

      Items        : constant Node_Id := Contract (Subp_Id);
      Case_Prag    : Node_Id := Empty;
      Post_Prag    : Node_Id := Empty;
      Prag         : Node_Id;
      Seen_In_Case : Boolean := False;
      Seen_In_Post : Boolean := False;
      Spec_Id      : constant Entity_Id := Unique_Entity (Subp_Id);

   --  Start of processing for Check_Result_And_Post_State

   begin
      --  The lack of attribute 'Result or a post-state is classified as a
      --  suspicious contract. Do not perform the check if the corresponding
      --  swich is not set.

      if not Warn_On_Suspicious_Contract then
         return;

      --  Nothing to do if there is no contract

      elsif No (Items) then
         return;

      --  If the subprogram has a contract Exceptional_Cases, it is often
      --  useful to refer only to the pre-state in the postcondition, to
      --  indicate when the subprogram might terminate normally.

      elsif Present (Get_Pragma (Subp_Id, Pragma_Exceptional_Cases)) then
         return;

      --  Same if the subprogram has a contract Always_Terminates => Cond,
      --  where Cond is not syntactically True.

      else
         declare
            Prag : constant Node_Id :=
              Get_Pragma (Subp_Id, Pragma_Always_Terminates);
         begin
            if Present (Prag)
              and then Present (Pragma_Argument_Associations (Prag))
            then
               declare
                  Cond : constant Node_Id :=
                    Get_Pragma_Arg
                      (First (Pragma_Argument_Associations (Prag)));
               begin
                  if not Compile_Time_Known_Value (Cond)
                    or else not Is_True (Expr_Value (Cond))
                  then
                     return;
                  end if;
               end;
            end if;
         end;
      end if;

      --  Examine all postconditions for attribute 'Result and a post-state

      Prag := Pre_Post_Conditions (Items);
      while Present (Prag) loop
         if Pragma_Name_Unmapped (Prag)
              in Name_Postcondition | Name_Refined_Post
           and then not Error_Posted (Prag)
         then
            Post_Prag := Prag;
            Check_Result_And_Post_State_In_Pragma (Prag, Seen_In_Post);
         end if;

         Prag := Next_Pragma (Prag);
      end loop;

      --  Examine the contract cases of the subprogram for attribute 'Result
      --  and a post-state.

      Prag := Contract_Test_Cases (Items);
      while Present (Prag) loop
         if Pragma_Name (Prag) = Name_Contract_Cases
           and then not Error_Posted (Prag)
         then
            Case_Prag := Prag;
            Check_Result_And_Post_State_In_Pragma (Prag, Seen_In_Case);
         end if;

         Prag := Next_Pragma (Prag);
      end loop;

      --  Do not emit any errors if the subprogram is not a function

      if Ekind (Spec_Id) not in E_Function | E_Generic_Function then
         null;

      --  Regardless of whether the function has postconditions or contract
      --  cases, or whether they mention attribute 'Result, an [IN] OUT formal
      --  parameter is always treated as a result.

      elsif Has_Out_Or_In_Out_Parameter (Spec_Id) then
         null;

      --  The function has both a postcondition and contract cases and they do
      --  not mention attribute 'Result.

      elsif Present (Case_Prag)
        and then not Seen_In_Case
        and then Present (Post_Prag)
        and then not Seen_In_Post
      then
         Error_Msg_N
           ("neither postcondition nor contract cases mention function "
            & "result?.t?", Post_Prag);

      --  The function has contract cases only and they do not mention
      --  attribute 'Result.

      elsif Present (Case_Prag) and then not Seen_In_Case then
         Error_Msg_N
           ("contract cases do not mention function result?.t?", Case_Prag);

      --  The function has non-trivial postconditions only and they do not
      --  mention attribute 'Result.

      elsif Present (Post_Prag)
        and then not Seen_In_Post
        and then not Is_Trivial_Boolean
          (Get_Pragma_Arg (First (Pragma_Argument_Associations (Post_Prag))))
      then
         Error_Msg_N
           ("postcondition does not mention function result?.t?", Post_Prag);
      end if;
   end Check_Result_And_Post_State;

   -----------------------------
   -- Check_State_Refinements --
   -----------------------------

   procedure Check_State_Refinements
     (Context      : Node_Id;
      Is_Main_Unit : Boolean := False)
   is
      procedure Check_Package (Pack : Node_Id);
      --  Verify that all abstract states of a [generic] package denoted by its
      --  declarative node Pack have proper refinement. Recursively verify the
      --  visible and private declarations of the [generic] package for other
      --  nested packages.

      procedure Check_Packages_In (Decls : List_Id);
      --  Seek out [generic] package declarations within declarative list Decls
      --  and verify the status of their abstract state refinement.

      function SPARK_Mode_Is_Off (N : Node_Id) return Boolean;
      --  Determine whether construct N is subject to pragma SPARK_Mode Off

      -------------------
      -- Check_Package --
      -------------------

      procedure Check_Package (Pack : Node_Id) is
         Body_Id : constant Entity_Id := Corresponding_Body (Pack);
         Spec    : constant Node_Id   := Specification (Pack);
         States  : constant Elist_Id  :=
                     Abstract_States (Defining_Entity (Pack));

         State_Elmt : Elmt_Id;
         State_Id   : Entity_Id;

      begin
         --  Do not verify proper state refinement when the package is subject
         --  to pragma SPARK_Mode Off because this disables the requirement for
         --  state refinement.

         if SPARK_Mode_Is_Off (Pack) then
            null;

         --  State refinement can only occur in a completing package body. Do
         --  not verify proper state refinement when the body is subject to
         --  pragma SPARK_Mode Off because this disables the requirement for
         --  state refinement.

         elsif Present (Body_Id)
           and then SPARK_Mode_Is_Off (Unit_Declaration_Node (Body_Id))
         then
            null;

         --  Do not verify proper state refinement when the package is an
         --  instance as this check was already performed in the generic.

         elsif Present (Generic_Parent (Spec)) then
            null;

         --  Otherwise examine the contents of the package

         else
            if Present (States) then
               State_Elmt := First_Elmt (States);
               while Present (State_Elmt) loop
                  State_Id := Node (State_Elmt);

                  --  Emit an error when a non-null state lacks refinement,
                  --  but has Part_Of constituents or there is a package
                  --  body (SPARK RM 7.1.4(4)). Constituents in private
                  --  child packages, which are not known at this stage,
                  --  independently require the existence of a package body.

                  if not Is_Null_State (State_Id)
                    and then No (Refinement_Constituents (State_Id))
                    and then
                      (Present (Part_Of_Constituents (State_Id))
                         or else
                       Present (Body_Id))
                  then
                     Error_Msg_N ("state & requires refinement", State_Id);
                     Error_Msg_N ("\package body should have Refined_State "
                                  & "for state & with constituents", State_Id);
                  end if;

                  Next_Elmt (State_Elmt);
               end loop;
            end if;

            Check_Packages_In (Visible_Declarations (Spec));
            Check_Packages_In (Private_Declarations (Spec));
         end if;
      end Check_Package;

      -----------------------
      -- Check_Packages_In --
      -----------------------

      procedure Check_Packages_In (Decls : List_Id) is
         Decl : Node_Id;

      begin
         if Present (Decls) then
            Decl := First (Decls);
            while Present (Decl) loop
               if Nkind (Decl) in N_Generic_Package_Declaration
                                | N_Package_Declaration
               then
                  Check_Package (Decl);
               end if;

               Next (Decl);
            end loop;
         end if;
      end Check_Packages_In;

      -----------------------
      -- SPARK_Mode_Is_Off --
      -----------------------

      function SPARK_Mode_Is_Off (N : Node_Id) return Boolean is
         Id   : constant Entity_Id := Defining_Entity (N);
         Prag : constant Node_Id   := SPARK_Pragma (Id);

      begin
         --  Default the mode to "off" when the context is an instance and all
         --  SPARK_Mode pragmas found within are to be ignored.

         if Ignore_SPARK_Mode_Pragmas (Id) then
            return True;

         else
            return
              Present (Prag)
                and then Get_SPARK_Mode_From_Annotation (Prag) = Off;
         end if;
      end SPARK_Mode_Is_Off;

   --  Start of processing for Check_State_Refinements

   begin
      --  A block may declare a nested package

      if Nkind (Context) = N_Block_Statement then
         Check_Packages_In (Declarations (Context));

      --  An entry, protected, subprogram, or task body may declare a nested
      --  package.

      elsif Nkind (Context) in N_Entry_Body
                             | N_Protected_Body
                             | N_Subprogram_Body
                             | N_Task_Body
      then
         --  Do not verify proper state refinement when the body is subject to
         --  pragma SPARK_Mode Off because this disables the requirement for
         --  state refinement.

         if not SPARK_Mode_Is_Off (Context) then
            Check_Packages_In (Declarations (Context));
         end if;

      --  A package body may declare a nested package

      elsif Nkind (Context) = N_Package_Body then
         Check_Package (Unit_Declaration_Node (Corresponding_Spec (Context)));

         --  Do not verify proper state refinement when the body is subject to
         --  pragma SPARK_Mode Off because this disables the requirement for
         --  state refinement.

         if not SPARK_Mode_Is_Off (Context) then
            Check_Packages_In (Declarations (Context));
         end if;

      --  A library level [generic] package may declare a nested package

      elsif Nkind (Context) in
              N_Generic_Package_Declaration | N_Package_Declaration
        and then Is_Main_Unit
      then
         Check_Package (Context);
      end if;
   end Check_State_Refinements;

   ------------------------------
   -- Check_Unprotected_Access --
   ------------------------------

   procedure Check_Unprotected_Access
     (Context : Node_Id;
      Expr    : Node_Id)
   is
      Cont_Encl_Typ : Entity_Id;
      Pref_Encl_Typ : Entity_Id;

      function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id;
      --  Check whether Obj is a private component of a protected object.
      --  Return the protected type where the component resides, Empty
      --  otherwise.

      function Is_Public_Operation return Boolean;
      --  Verify that the enclosing operation is callable from outside the
      --  protected object, to minimize false positives.

      ------------------------------
      -- Enclosing_Protected_Type --
      ------------------------------

      function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id is
      begin
         if Is_Entity_Name (Obj) then
            declare
               Ent : Entity_Id := Entity (Obj);

            begin
               --  The object can be a renaming of a private component, use
               --  the original record component.

               if Is_Prival (Ent) then
                  Ent := Prival_Link (Ent);
               end if;

               if Is_Protected_Type (Scope (Ent)) then
                  return Scope (Ent);
               end if;
            end;
         end if;

         --  For indexed and selected components, recursively check the prefix

         if Nkind (Obj) in N_Indexed_Component | N_Selected_Component then
            return Enclosing_Protected_Type (Prefix (Obj));

         --  The object does not denote a protected component

         else
            return Empty;
         end if;
      end Enclosing_Protected_Type;

      -------------------------
      -- Is_Public_Operation --
      -------------------------

      function Is_Public_Operation return Boolean is
         S : Entity_Id;
         E : Entity_Id;

      begin
         S := Current_Scope;
         while Present (S) and then S /= Pref_Encl_Typ loop
            if Scope (S) = Pref_Encl_Typ then
               E := First_Entity (Pref_Encl_Typ);
               while Present (E)
                 and then E /= First_Private_Entity (Pref_Encl_Typ)
               loop
                  if E = S then
                     return True;
                  end if;

                  Next_Entity (E);
               end loop;
            end if;

            S := Scope (S);
         end loop;

         return False;
      end Is_Public_Operation;

   --  Start of processing for Check_Unprotected_Access

   begin
      if Nkind (Expr) = N_Attribute_Reference
        and then Attribute_Name (Expr) = Name_Unchecked_Access
      then
         Cont_Encl_Typ := Enclosing_Protected_Type (Context);
         Pref_Encl_Typ := Enclosing_Protected_Type (Prefix (Expr));

         --  Check whether we are trying to export a protected component to a
         --  context with an equal or lower access level.

         if Present (Pref_Encl_Typ)
           and then No (Cont_Encl_Typ)
           and then Is_Public_Operation
           and then Scope_Depth (Pref_Encl_Typ)
                      >= Static_Accessibility_Level
                           (Context, Object_Decl_Level)
         then
            Error_Msg_N
              ("??possible unprotected access to protected data", Expr);
         end if;
      end if;
   end Check_Unprotected_Access;

   ------------------------------
   -- Check_Unused_Body_States --
   ------------------------------

   procedure Check_Unused_Body_States (Body_Id : Entity_Id) is
      procedure Process_Refinement_Clause
        (Clause : Node_Id;
         States : Elist_Id);
      --  Inspect all constituents of refinement clause Clause and remove any
      --  matches from body state list States.

      procedure Report_Unused_Body_States (States : Elist_Id);
      --  Emit errors for each abstract state or object found in list States

      -------------------------------
      -- Process_Refinement_Clause --
      -------------------------------

      procedure Process_Refinement_Clause
        (Clause : Node_Id;
         States : Elist_Id)
      is
         procedure Process_Constituent (Constit : Node_Id);
         --  Remove constituent Constit from body state list States

         -------------------------
         -- Process_Constituent --
         -------------------------

         procedure Process_Constituent (Constit : Node_Id) is
            Constit_Id : Entity_Id;

         begin
            --  Guard against illegal constituents. Only abstract states and
            --  objects can appear on the right hand side of a refinement.

            if Is_Entity_Name (Constit) then
               Constit_Id := Entity_Of (Constit);

               if Present (Constit_Id)
                 and then Ekind (Constit_Id) in
                            E_Abstract_State | E_Constant | E_Variable
               then
                  Remove (States, Constit_Id);
               end if;
            end if;
         end Process_Constituent;

         --  Local variables

         Constit : Node_Id;

      --  Start of processing for Process_Refinement_Clause

      begin
         if Nkind (Clause) = N_Component_Association then
            Constit := Expression (Clause);

            --  Multiple constituents appear as an aggregate

            if Nkind (Constit) = N_Aggregate then
               Constit := First (Expressions (Constit));
               while Present (Constit) loop
                  Process_Constituent (Constit);
                  Next (Constit);
               end loop;

            --  Various forms of a single constituent

            else
               Process_Constituent (Constit);
            end if;
         end if;
      end Process_Refinement_Clause;

      -------------------------------
      -- Report_Unused_Body_States --
      -------------------------------

      procedure Report_Unused_Body_States (States : Elist_Id) is
         Posted     : Boolean := False;
         State_Elmt : Elmt_Id;
         State_Id   : Entity_Id;

      begin
         if Present (States) then
            State_Elmt := First_Elmt (States);
            while Present (State_Elmt) loop
               State_Id := Node (State_Elmt);

               --  Constants are part of the hidden state of a package, but the
               --  compiler cannot determine whether they have variable input
               --  (SPARK RM 7.1.1(2)) and cannot classify them properly as a
               --  hidden state. Do not emit an error when a constant does not
               --  participate in a state refinement, even though it acts as a
               --  hidden state.

               if Ekind (State_Id) = E_Constant then
                  null;

               --  Overlays do not contribute to package state

               elsif Ekind (State_Id) = E_Variable
                 and then Present (Ultimate_Overlaid_Entity (State_Id))
               then
                  null;

               --  Generate an error message of the form:

               --    body of package ... has unused hidden states
               --      abstract state ... defined at ...
               --      variable ... defined at ...

               else
                  if not Posted then
                     Posted := True;
                     SPARK_Msg_N
                       ("body of package & has unused hidden states", Body_Id);
                  end if;

                  Error_Msg_Sloc := Sloc (State_Id);

                  if Ekind (State_Id) = E_Abstract_State then
                     SPARK_Msg_NE
                       ("\abstract state & defined #", Body_Id, State_Id);

                  else
                     SPARK_Msg_NE ("\variable & defined #", Body_Id, State_Id);
                  end if;
               end if;

                  Next_Elmt (State_Elmt);
            end loop;
         end if;
      end Report_Unused_Body_States;

      --  Local variables

      Prag    : constant Node_Id := Get_Pragma (Body_Id, Pragma_Refined_State);
      Spec_Id : constant Entity_Id := Spec_Entity (Body_Id);
      Clause  : Node_Id;
      States  : Elist_Id;

   --  Start of processing for Check_Unused_Body_States

   begin
      --  Inspect the clauses of pragma Refined_State and determine whether all
      --  visible states declared within the package body participate in the
      --  refinement.

      if Present (Prag) then
         Clause := Expression (Get_Argument (Prag, Spec_Id));
         States := Collect_Body_States (Body_Id);

         --  Multiple non-null state refinements appear as an aggregate

         if Nkind (Clause) = N_Aggregate then
            Clause := First (Component_Associations (Clause));
            while Present (Clause) loop
               Process_Refinement_Clause (Clause, States);
               Next (Clause);
            end loop;

         --  Various forms of a single state refinement

         else
            Process_Refinement_Clause (Clause, States);
         end if;

         --  Ensure that all abstract states and objects declared in the
         --  package body state space are utilized as constituents.

         Report_Unused_Body_States (States);
      end if;
   end Check_Unused_Body_States;

   ------------------------------------
   -- Check_Volatility_Compatibility --
   ------------------------------------

   procedure Check_Volatility_Compatibility
     (Id1, Id2                     : Entity_Id;
      Description_1, Description_2 : String;
      Srcpos_Bearer                : Node_Id) is

   begin
      if SPARK_Mode /= On then
         return;
      end if;

      declare
         AR1 : constant Boolean := Async_Readers_Enabled (Id1);
         AW1 : constant Boolean := Async_Writers_Enabled (Id1);
         ER1 : constant Boolean := Effective_Reads_Enabled (Id1);
         EW1 : constant Boolean := Effective_Writes_Enabled (Id1);
         AR2 : constant Boolean := Async_Readers_Enabled (Id2);
         AW2 : constant Boolean := Async_Writers_Enabled (Id2);
         ER2 : constant Boolean := Effective_Reads_Enabled (Id2);
         EW2 : constant Boolean := Effective_Writes_Enabled (Id2);

         AR_Check_Failed : constant Boolean := AR1 and not AR2;
         AW_Check_Failed : constant Boolean := AW1 and not AW2;
         ER_Check_Failed : constant Boolean := ER1 and not ER2;
         EW_Check_Failed : constant Boolean := EW1 and not EW2;

         package Failure_Description is
            procedure Note_If_Failure
              (Failed : Boolean; Aspect_Name : String);
            --  If Failed is False, do nothing.
            --  If Failed is True, add Aspect_Name to the failure description.

            function Failure_Text return String;
            --  returns accumulated list of failing aspects
         end Failure_Description;

         package body Failure_Description is
            Description_Buffer : Bounded_String;

            ---------------------
            -- Note_If_Failure --
            ---------------------

            procedure Note_If_Failure
              (Failed : Boolean; Aspect_Name : String) is
            begin
               if Failed then
                  if Description_Buffer.Length /= 0 then
                     Append (Description_Buffer, ", ");
                  end if;
                  Append (Description_Buffer, Aspect_Name);
               end if;
            end Note_If_Failure;

            ------------------
            -- Failure_Text --
            ------------------

            function Failure_Text return String is
            begin
               return +Description_Buffer;
            end Failure_Text;
         end Failure_Description;

         use Failure_Description;
      begin
         if AR_Check_Failed
           or AW_Check_Failed
           or ER_Check_Failed
           or EW_Check_Failed
         then
            Note_If_Failure (AR_Check_Failed, "Async_Readers");
            Note_If_Failure (AW_Check_Failed, "Async_Writers");
            Note_If_Failure (ER_Check_Failed, "Effective_Reads");
            Note_If_Failure (EW_Check_Failed, "Effective_Writes");

            Error_Msg_N
              (Description_1
                 & " and "
                 & Description_2
                 & " are not compatible with respect to volatility due to "
                 & Failure_Text,
               Srcpos_Bearer);
         end if;
      end;
   end Check_Volatility_Compatibility;

   -----------------
   -- Choice_List --
   -----------------

   function Choice_List (N : Node_Id) return List_Id is
   begin
      if Nkind (N) = N_Iterated_Component_Association then
         return Discrete_Choices (N);
      else
         return Choices (N);
      end if;
   end Choice_List;

   ---------------------
   -- Class_Condition --
   ---------------------

   function Class_Condition
     (Kind : Condition_Kind;
      Subp : Entity_Id) return Node_Id is

   begin
      case Kind is
         when Class_Postcondition =>
            return Class_Postconditions (Subp);

         when Class_Precondition =>
            return Class_Preconditions (Subp);

         when Ignored_Class_Postcondition =>
            return Ignored_Class_Postconditions (Subp);

         when Ignored_Class_Precondition =>
            return Ignored_Class_Preconditions (Subp);
      end case;
   end Class_Condition;

   -------------------------
   -- Collect_Body_States --
   -------------------------

   function Collect_Body_States (Body_Id : Entity_Id) return Elist_Id is
      function Is_Visible_Object (Obj_Id : Entity_Id) return Boolean;
      --  Determine whether object Obj_Id is a suitable visible state of a
      --  package body.

      procedure Collect_Visible_States
        (Pack_Id : Entity_Id;
         States  : in out Elist_Id);
      --  Gather the entities of all abstract states and objects declared in
      --  the visible state space of package Pack_Id.

      ----------------------------
      -- Collect_Visible_States --
      ----------------------------

      procedure Collect_Visible_States
        (Pack_Id : Entity_Id;
         States  : in out Elist_Id)
      is
         Item_Id : Entity_Id;

      begin
         --  Traverse the entity chain of the package and inspect all visible
         --  items.

         Item_Id := First_Entity (Pack_Id);
         while Present (Item_Id) and then not In_Private_Part (Item_Id) loop

            --  Do not consider internally generated items as those cannot be
            --  named and participate in refinement.

            if not Comes_From_Source (Item_Id) then
               null;

            elsif Ekind (Item_Id) = E_Abstract_State then
               Append_New_Elmt (Item_Id, States);

            elsif Ekind (Item_Id) in E_Constant | E_Variable
              and then Is_Visible_Object (Item_Id)
            then
               Append_New_Elmt (Item_Id, States);

            --  Recursively gather the visible states of a nested package
            --  except for nested package renamings.

            elsif Ekind (Item_Id) = E_Package
              and then No (Renamed_Entity (Item_Id))
            then
               Collect_Visible_States (Item_Id, States);
            end if;

            Next_Entity (Item_Id);
         end loop;
      end Collect_Visible_States;

      -----------------------
      -- Is_Visible_Object --
      -----------------------

      function Is_Visible_Object (Obj_Id : Entity_Id) return Boolean is
      begin
         --  Objects that map generic formals to their actuals are not visible
         --  from outside the generic instantiation.

         if Present (Corresponding_Generic_Association
                       (Declaration_Node (Obj_Id)))
         then
            return False;

         --  Constituents of a single protected/task type act as components of
         --  the type and are not visible from outside the type.

         elsif Ekind (Obj_Id) = E_Variable
           and then Present (Encapsulating_State (Obj_Id))
           and then Is_Single_Concurrent_Object (Encapsulating_State (Obj_Id))
         then
            return False;

         else
            return True;
         end if;
      end Is_Visible_Object;

      --  Local variables

      Body_Decl : constant Node_Id := Unit_Declaration_Node (Body_Id);
      Decl      : Node_Id;
      Item_Id   : Entity_Id;
      States    : Elist_Id := No_Elist;

   --  Start of processing for Collect_Body_States

   begin
      --  Inspect the declarations of the body looking for source objects,
      --  packages and package instantiations. Note that even though this
      --  processing is very similar to Collect_Visible_States, a package
      --  body does not have a First/Next_Entity list.

      Decl := First (Declarations (Body_Decl));
      while Present (Decl) loop

         --  Capture source objects as internally generated temporaries cannot
         --  be named and participate in refinement.

         if Nkind (Decl) = N_Object_Declaration then
            Item_Id := Defining_Entity (Decl);

            if Comes_From_Source (Item_Id)
              and then Is_Visible_Object (Item_Id)
            then
               Append_New_Elmt (Item_Id, States);
            end if;

         --  Capture the visible abstract states and objects of a source
         --  package [instantiation].

         elsif Nkind (Decl) = N_Package_Declaration then
            Item_Id := Defining_Entity (Decl);

            if Comes_From_Source (Item_Id) then
               Collect_Visible_States (Item_Id, States);
            end if;
         end if;

         Next (Decl);
      end loop;

      return States;
   end Collect_Body_States;

   ------------------------
   -- Collect_Interfaces --
   ------------------------

   procedure Collect_Interfaces
     (T               : Entity_Id;
      Ifaces_List     : out Elist_Id;
      Exclude_Parents : Boolean := False;
      Use_Full_View   : Boolean := True)
   is
      procedure Collect (Typ : Entity_Id);
      --  Subsidiary subprogram used to traverse the whole list
      --  of directly and indirectly implemented interfaces

      -------------
      -- Collect --
      -------------

      procedure Collect (Typ : Entity_Id) is
         Ancestor   : Entity_Id;
         Full_T     : Entity_Id;
         Id         : Node_Id;
         Iface      : Entity_Id;

      begin
         Full_T := Typ;

         --  Handle private types and subtypes

         if Use_Full_View
           and then Is_Private_Type (Typ)
           and then Present (Full_View (Typ))
         then
            Full_T := Full_View (Typ);

            if Ekind (Full_T) = E_Record_Subtype then
               Full_T := Etype (Typ);

               if Present (Full_View (Full_T)) then
                  Full_T := Full_View (Full_T);
               end if;
            end if;
         end if;

         --  Include the ancestor if we are generating the whole list of
         --  abstract interfaces.

         if Etype (Full_T) /= Typ

            --  Protect the frontend against wrong sources. For example:

            --    package P is
            --      type A is tagged null record;
            --      type B is new A with private;
            --      type C is new A with private;
            --    private
            --      type B is new C with null record;
            --      type C is new B with null record;
            --    end P;

           and then Etype (Full_T) /= T
         then
            Ancestor := Etype (Full_T);
            Collect (Ancestor);

            if Is_Interface (Ancestor) and then not Exclude_Parents then
               Append_Unique_Elmt (Ancestor, Ifaces_List);
            end if;
         end if;

         --  Traverse the graph of ancestor interfaces

         Id := First (Abstract_Interface_List (Full_T));
         while Present (Id) loop
            Iface := Etype (Id);

            --  Protect against wrong uses. For example:
            --    type I is interface;
            --    type O is tagged null record;
            --    type Wrong is new I and O with null record; -- ERROR

            if Is_Interface (Iface) then
               if Exclude_Parents
                 and then Etype (T) /= T
                 and then Interface_Present_In_Ancestor (Etype (T), Iface)
               then
                  null;
               else
                  Collect (Iface);
                  Append_Unique_Elmt (Iface, Ifaces_List);
               end if;
            end if;

            Next (Id);
         end loop;
      end Collect;

   --  Start of processing for Collect_Interfaces

   begin
      pragma Assert (Is_Tagged_Type (T) or else Is_Concurrent_Type (T));
      Ifaces_List := New_Elmt_List;
      Collect (T);
   end Collect_Interfaces;

   ----------------------------------
   -- Collect_Interface_Components --
   ----------------------------------

   procedure Collect_Interface_Components
     (Tagged_Type     : Entity_Id;
      Components_List : out Elist_Id)
   is
      procedure Collect (Typ : Entity_Id);
      --  Subsidiary subprogram used to climb to the parents

      -------------
      -- Collect --
      -------------

      procedure Collect (Typ : Entity_Id) is
         Tag_Comp   : Entity_Id;
         Parent_Typ : Entity_Id;

      begin
         --  Handle private types

         if Present (Full_View (Etype (Typ))) then
            Parent_Typ := Full_View (Etype (Typ));
         else
            Parent_Typ := Etype (Typ);
         end if;

         if Parent_Typ /= Typ

            --  Protect the frontend against wrong sources. For example:

            --    package P is
            --      type A is tagged null record;
            --      type B is new A with private;
            --      type C is new A with private;
            --    private
            --      type B is new C with null record;
            --      type C is new B with null record;
            --    end P;

           and then Parent_Typ /= Tagged_Type
         then
            Collect (Parent_Typ);
         end if;

         --  Collect the components containing tags of secondary dispatch
         --  tables.

         Tag_Comp := Next_Tag_Component (First_Tag_Component (Typ));
         while Present (Tag_Comp) loop
            pragma Assert (Present (Related_Type (Tag_Comp)));
            Append_Elmt (Tag_Comp, Components_List);

            Tag_Comp := Next_Tag_Component (Tag_Comp);
         end loop;
      end Collect;

   --  Start of processing for Collect_Interface_Components

   begin
      pragma Assert (Ekind (Tagged_Type) = E_Record_Type
        and then Is_Tagged_Type (Tagged_Type));

      Components_List := New_Elmt_List;
      Collect (Tagged_Type);
   end Collect_Interface_Components;

   -----------------------------
   -- Collect_Interfaces_Info --
   -----------------------------

   procedure Collect_Interfaces_Info
     (T               : Entity_Id;
      Ifaces_List     : out Elist_Id;
      Components_List : out Elist_Id;
      Tags_List       : out Elist_Id)
   is
      Comps_List : Elist_Id;
      Comp_Elmt  : Elmt_Id;
      Comp_Iface : Entity_Id;
      Iface_Elmt : Elmt_Id;
      Iface      : Entity_Id;

      function Search_Tag (Iface : Entity_Id) return Entity_Id;
      --  Search for the secondary tag associated with the interface type
      --  Iface that is implemented by T.

      ----------------
      -- Search_Tag --
      ----------------

      function Search_Tag (Iface : Entity_Id) return Entity_Id is
         ADT : Elmt_Id;
      begin
         if not Is_CPP_Class (T) then
            ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (T))));
         else
            ADT := Next_Elmt (First_Elmt (Access_Disp_Table (T)));
         end if;

         while Present (ADT)
           and then Is_Tag (Node (ADT))
           and then Related_Type (Node (ADT)) /= Iface
         loop
            --  Skip secondary dispatch table referencing thunks to user
            --  defined primitives covered by this interface.

            pragma Assert (Has_Suffix (Node (ADT), 'P'));
            Next_Elmt (ADT);

            --  Skip secondary dispatch tables of Ada types

            if not Is_CPP_Class (T) then

               --  Skip secondary dispatch table referencing thunks to
               --  predefined primitives.

               pragma Assert (Has_Suffix (Node (ADT), 'Y'));
               Next_Elmt (ADT);

               --  Skip secondary dispatch table referencing user-defined
               --  primitives covered by this interface.

               pragma Assert (Has_Suffix (Node (ADT), 'D'));
               Next_Elmt (ADT);

               --  Skip secondary dispatch table referencing predefined
               --  primitives.

               pragma Assert (Has_Suffix (Node (ADT), 'Z'));
               Next_Elmt (ADT);
            end if;
         end loop;

         pragma Assert (Is_Tag (Node (ADT)));
         return Node (ADT);
      end Search_Tag;

   --  Start of processing for Collect_Interfaces_Info

   begin
      Collect_Interfaces (T, Ifaces_List);
      Collect_Interface_Components (T, Comps_List);

      --  Search for the record component and tag associated with each
      --  interface type of T.

      Components_List := New_Elmt_List;
      Tags_List       := New_Elmt_List;

      Iface_Elmt := First_Elmt (Ifaces_List);
      while Present (Iface_Elmt) loop
         Iface := Node (Iface_Elmt);

         --  Associate the primary tag component and the primary dispatch table
         --  with all the interfaces that are parents of T

         if Is_Ancestor (Iface, T, Use_Full_View => True) then
            Append_Elmt (First_Tag_Component (T), Components_List);
            Append_Elmt (Node (First_Elmt (Access_Disp_Table (T))), Tags_List);

         --  Otherwise search for the tag component and secondary dispatch
         --  table of Iface

         else
            Comp_Elmt := First_Elmt (Comps_List);
            while Present (Comp_Elmt) loop
               Comp_Iface := Related_Type (Node (Comp_Elmt));

               if Comp_Iface = Iface
                 or else Is_Ancestor (Iface, Comp_Iface, Use_Full_View => True)
               then
                  Append_Elmt (Node (Comp_Elmt), Components_List);
                  Append_Elmt (Search_Tag (Comp_Iface), Tags_List);
                  exit;
               end if;

               Next_Elmt (Comp_Elmt);
            end loop;
            pragma Assert (Present (Comp_Elmt));
         end if;

         Next_Elmt (Iface_Elmt);
      end loop;
   end Collect_Interfaces_Info;

   ---------------------
   -- Collect_Parents --
   ---------------------

   procedure Collect_Parents
     (T             : Entity_Id;
      List          : out Elist_Id;
      Use_Full_View : Boolean := True)
   is
      Current_Typ : Entity_Id := T;
      Parent_Typ  : Entity_Id;

   begin
      List := New_Elmt_List;

      --  No action if the if the type has no parents

      if T = Etype (T) then
         return;
      end if;

      loop
         Parent_Typ := Etype (Current_Typ);

         if Is_Private_Type (Parent_Typ)
           and then Present (Full_View (Parent_Typ))
           and then Use_Full_View
         then
            Parent_Typ := Full_View (Base_Type (Parent_Typ));
         end if;

         Append_Elmt (Parent_Typ, List);

         exit when Parent_Typ = Current_Typ;
         Current_Typ := Parent_Typ;
      end loop;
   end Collect_Parents;

   ----------------------------------
   -- Collect_Primitive_Operations --
   ----------------------------------

   function Collect_Primitive_Operations (T : Entity_Id) return Elist_Id is
      B_Type : constant Entity_Id := Base_Type (T);

      function Match (E : Entity_Id) return Boolean;
      --  True if E's base type is B_Type, or E is of an anonymous access type
      --  and the base type of its designated type is B_Type.

      -----------
      -- Match --
      -----------

      function Match (E : Entity_Id) return Boolean is
         Etyp : Entity_Id := Etype (E);

      begin
         if Ekind (Etyp) = E_Anonymous_Access_Type then
            Etyp := Designated_Type (Etyp);
         end if;

         --  In Ada 2012 a primitive operation may have a formal of an
         --  incomplete view of the parent type.

         return Base_Type (Etyp) = B_Type
           or else
             (Ada_Version >= Ada_2012
               and then Ekind (Etyp) = E_Incomplete_Type
               and then Full_View (Etyp) = B_Type);
      end Match;

      --  Local variables

      B_Decl         : constant Node_Id := Original_Node (Parent (B_Type));
      B_Scope        : Entity_Id        := Scope (B_Type);
      Op_List        : Elist_Id;
      Eq_Prims_List  : Elist_Id := No_Elist;
      Formal         : Entity_Id;
      Is_Prim        : Boolean;
      Is_Type_In_Pkg : Boolean;
      Formal_Derived : Boolean := False;
      Id             : Entity_Id;

   --  Start of processing for Collect_Primitive_Operations

   begin
      --  For tagged types, the primitive operations are collected as they
      --  are declared, and held in an explicit list which is simply returned.

      if Is_Tagged_Type (B_Type) then
         return Primitive_Operations (B_Type);

      --  An untagged generic type that is a derived type inherits the
      --  primitive operations of its parent type. Other formal types only
      --  have predefined operators, which are not explicitly represented.

      elsif Is_Generic_Type (B_Type) then
         if Nkind (B_Decl) = N_Formal_Type_Declaration
           and then Nkind (Formal_Type_Definition (B_Decl)) =
                                           N_Formal_Derived_Type_Definition
         then
            Formal_Derived := True;
         else
            return New_Elmt_List;
         end if;
      end if;

      Op_List := New_Elmt_List;

      if B_Scope = Standard_Standard then
         if B_Type = Standard_String then
            Append_Elmt (Standard_Op_Concat, Op_List);

         elsif B_Type = Standard_Wide_String then
            Append_Elmt (Standard_Op_Concatw, Op_List);

         else
            null;
         end if;

      --  Locate the primitive subprograms of the type

      else
         --  The primitive operations appear after the base type, except if the
         --  derivation happens within the private part of B_Scope and the type
         --  is a private type, in which case both the type and some primitive
         --  operations may appear before the base type, and the list of
         --  candidates starts after the type.

         if In_Open_Scopes (B_Scope)
           and then Scope (T) = B_Scope
           and then In_Private_Part (B_Scope)
         then
            Id := Next_Entity (T);

         --  In Ada 2012, If the type has an incomplete partial view, there may
         --  be primitive operations declared before the full view, so we need
         --  to start scanning from the incomplete view, which is earlier on
         --  the entity chain.

         elsif Nkind (Parent (B_Type)) = N_Full_Type_Declaration
           and then Present (Incomplete_View (Parent (B_Type)))
         then
            Id := Incomplete_View (Parent (B_Type));

            --  If T is a derived from a type with an incomplete view declared
            --  elsewhere, that incomplete view is irrelevant, we want the
            --  operations in the scope of T.

            if Scope (Id) /= Scope (B_Type) then
               Id := Next_Entity (B_Type);
            end if;

         else
            Id := Next_Entity (B_Type);
         end if;

         --  Set flag if this is a type in a package spec

         Is_Type_In_Pkg :=
           Is_Package_Or_Generic_Package (B_Scope)
             and then
           Parent_Kind (Declaration_Node (First_Subtype (T))) /=
             N_Package_Body;

         while Present (Id) loop

            --  Test whether the result type or any of the parameter types of
            --  each subprogram following the type match that type when the
            --  type is declared in a package spec, is a derived type, or the
            --  subprogram is marked as primitive. (The Is_Primitive test is
            --  needed to find primitives of nonderived types in declarative
            --  parts that happen to override the predefined "=" operator.)

            --  Note that generic formal subprograms are not considered to be
            --  primitive operations and thus are never inherited.

            if Is_Overloadable (Id)
              and then (Is_Type_In_Pkg
                         or else Is_Derived_Type (B_Type)
                         or else Is_Primitive (Id))
              and then Parent_Kind (Parent (Id))
                                    not in N_Formal_Subprogram_Declaration
            then
               Is_Prim := False;

               if Match (Id) then
                  Is_Prim := True;

               else
                  Formal := First_Formal (Id);
                  while Present (Formal) loop
                     if Match (Formal) then
                        Is_Prim := True;
                        exit;
                     end if;

                     Next_Formal (Formal);
                  end loop;
               end if;

               --  For a formal derived type, the only primitives are the ones
               --  inherited from the parent type. Operations appearing in the
               --  package declaration are not primitive for it.

               if Is_Prim
                 and then (not Formal_Derived or else Present (Alias (Id)))
               then
                  --  In the special case of an equality operator aliased to
                  --  an overriding dispatching equality belonging to the same
                  --  type, we don't include it in the list of primitives.
                  --  This avoids inheriting multiple equality operators when
                  --  deriving from untagged private types whose full type is
                  --  tagged, which can otherwise cause ambiguities. Note that
                  --  this should only happen for this kind of untagged parent
                  --  type, since normally dispatching operations are inherited
                  --  using the type's Primitive_Operations list.

                  if Chars (Id) = Name_Op_Eq
                    and then Is_Dispatching_Operation (Id)
                    and then Present (Alias (Id))
                    and then Present (Overridden_Operation (Alias (Id)))
                    and then Base_Type (Etype (First_Entity (Id))) =
                               Base_Type (Etype (First_Entity (Alias (Id))))
                  then
                     null;

                  --  Include the subprogram in the list of primitives

                  else
                     Append_Elmt (Id, Op_List);

                     --  Save collected equality primitives for later filtering
                     --  (if we are processing a private type for which we can
                     --  collect several candidates).

                     if Inherits_From_Tagged_Full_View (T)
                       and then Chars (Id) = Name_Op_Eq
                       and then Etype (First_Formal (Id)) =
                                Etype (Next_Formal (First_Formal (Id)))
                     then
                        Append_New_Elmt (Id, Eq_Prims_List);
                     end if;
                  end if;
               end if;
            end if;

            Next_Entity (Id);

            --  For a type declared in System, some of its operations may
            --  appear in the target-specific extension to System.

            if No (Id)
              and then Is_RTU (B_Scope, System)
              and then Present_System_Aux
            then
               B_Scope := System_Aux_Id;
               Id := First_Entity (System_Aux_Id);
            end if;
         end loop;

         --  Filter collected equality primitives

         if Inherits_From_Tagged_Full_View (T)
           and then Present (Eq_Prims_List)
         then
            declare
               First  : constant Elmt_Id := First_Elmt (Eq_Prims_List);
               Second : Elmt_Id;

            begin
               pragma Assert (No (Next_Elmt (First))
                 or else No (Next_Elmt (Next_Elmt (First))));

               --  No action needed if we have collected a single equality
               --  primitive

               if Present (Next_Elmt (First)) then
                  Second := Next_Elmt (First);

                  if Is_Dispatching_Operation
                       (Ultimate_Alias (Node (First)))
                  then
                     Remove (Op_List, Node (First));

                  elsif Is_Dispatching_Operation
                          (Ultimate_Alias (Node (Second)))
                  then
                     Remove (Op_List, Node (Second));

                  else
                     raise Program_Error;
                  end if;
               end if;
            end;
         end if;
      end if;

      return Op_List;
   end Collect_Primitive_Operations;

   -----------------------------------
   -- Compile_Time_Constraint_Error --
   -----------------------------------

   function Compile_Time_Constraint_Error
     (N         : Node_Id;
      Msg       : String;
      Ent       : Entity_Id  := Empty;
      Loc       : Source_Ptr := No_Location;
      Warn      : Boolean    := False;
      Extra_Msg : String     := "") return Node_Id
   is
      Msgc : String (1 .. Msg'Length + 3);
      --  Copy of message, with room for possible ?? or << and ! at end

      Msgl : Natural;
      Wmsg : Boolean;
      Eloc : Source_Ptr;

   begin
      --  If this is a warning, convert it into an error if we are in code
      --  subject to SPARK_Mode being set On, unless Warn is True to force a
      --  warning. The rationale is that a compile-time constraint error should
      --  lead to an error instead of a warning when SPARK_Mode is On, but in
      --  a few cases we prefer to issue a warning and generate both a suitable
      --  run-time error in GNAT and a suitable check message in GNATprove.
      --  Those cases are those that likely correspond to deactivated SPARK
      --  code, so that this kind of code can be compiled and analyzed instead
      --  of being rejected.

      Error_Msg_Warn := Warn or SPARK_Mode /= On;

      --  A static constraint error in an instance body is not a fatal error.
      --  We choose to inhibit the message altogether, because there is no
      --  obvious node (for now) on which to post it. On the other hand the
      --  offending node must be replaced with a constraint_error in any case.

      --  No messages are generated if we already posted an error on this node

      if not Error_Posted (N) then
         if Loc /= No_Location then
            Eloc := Loc;
         else
            Eloc := Sloc (N);
         end if;

         --  Copy message to Msgc, converting any ? in the message into <
         --  instead, so that we have an error in GNATprove mode.

         Msgl := Msg'Length;

         for J in 1 .. Msgl loop
            if Msg (J) = '?' and then (J = 1 or else Msg (J - 1) /= ''') then
               Msgc (J) := '<';
            else
               Msgc (J) := Msg (J);
            end if;
         end loop;

         --  Message is a warning, even in Ada 95 case

         if Msg (Msg'Last) = '?' or else Msg (Msg'Last) = '<' then
            Wmsg := True;

         --  In Ada 83, all messages are warnings. In the private part and the
         --  body of an instance, constraint_checks are only warnings. We also
         --  make this a warning if the Warn parameter is set.

         elsif Warn
           or else (Ada_Version = Ada_83 and then Comes_From_Source (N))
           or else In_Instance_Not_Visible
         then
            Msgl := Msgl + 1;
            Msgc (Msgl) := '<';
            Msgl := Msgl + 1;
            Msgc (Msgl) := '<';
            Wmsg := True;

         --  Otherwise we have a real error message (Ada 95 static case) and we
         --  make this an unconditional message. Note that in the warning case
         --  we do not make the message unconditional, it seems reasonable to
         --  delete messages like this (about exceptions that will be raised)
         --  in dead code.

         else
            Wmsg := False;
            Msgl := Msgl + 1;
            Msgc (Msgl) := '!';
         end if;

         --  One more test, skip the warning if the related expression is
         --  statically unevaluated, since we don't want to warn about what
         --  will happen when something is evaluated if it never will be
         --  evaluated.

         --  Suppress error reporting when checking that the expression of a
         --  static expression function is a potentially static expression,
         --  because we don't want additional errors being reported during the
         --  preanalysis of the expression (see Analyze_Expression_Function).

         if not Is_Statically_Unevaluated (N)
           and then not Checking_Potentially_Static_Expression
         then
            if Present (Ent) then
               Error_Msg_NEL (Msgc (1 .. Msgl), N, Ent, Eloc);
            else
               Error_Msg_NEL (Msgc (1 .. Msgl), N, Etype (N), Eloc);
            end if;

            --  Emit any extra message as a continuation

            if Extra_Msg /= "" then
               Error_Msg_N ('\' & Extra_Msg, N);
            end if;

            if Wmsg then

               --  Check whether the context is an Init_Proc

               if Inside_Init_Proc then
                  declare
                     Init_Proc_Type : constant Entity_Id :=
                       Etype (First_Formal (Current_Scope_No_Loops));

                     Conc_Typ : constant Entity_Id :=
                       (if Present (Init_Proc_Type)
                          and then Ekind (Init_Proc_Type) = E_Record_Type
                        then Corresponding_Concurrent_Type (Init_Proc_Type)
                        else Empty);

                  begin
                     --  Don't complain if the corresponding concurrent type
                     --  doesn't come from source (i.e. a single task/protected
                     --  object).

                     if Present (Conc_Typ)
                       and then not Comes_From_Source (Conc_Typ)
                     then
                        Error_Msg ("\& [<<", Eloc, N);

                     else
                        if GNATprove_Mode then
                           Error_Msg
                             ("\Constraint_Error would have been raised"
                              & " for objects of this type", Eloc, N);
                        else
                           Error_Msg
                             ("\Constraint_Error will be raised"
                              & " for objects of this type??", Eloc, N);
                        end if;
                     end if;
                  end;

               else
                  Error_Msg ("\Constraint_Error [<<", Eloc, N);
               end if;

            else
               Error_Msg ("\static expression fails Constraint_Check", Eloc);
               Set_Error_Posted (N);
            end if;
         end if;
      end if;

      return N;
   end Compile_Time_Constraint_Error;

   ----------------------------
   -- Compute_Returns_By_Ref --
   ----------------------------

   procedure Compute_Returns_By_Ref (Func : Entity_Id) is
      Kind : constant Entity_Kind := Ekind (Func);
      Typ  : constant Entity_Id   := Etype (Func);

   begin
      --  Nothing to do for procedures

      if Kind in E_Procedure | E_Generic_Procedure
        or else (Kind = E_Subprogram_Type and then Typ = Standard_Void_Type)
      then
         null;

      --  The build-in-place protocols return a reference to the result

      elsif Is_Build_In_Place_Function (Func) then
         Set_Returns_By_Ref (Func);

      --  In Ada 95, limited types are returned by reference, but not if the
      --  convention is other than Ada.

      elsif Is_Limited_View (Typ)
        and then not Has_Foreign_Convention (Func)
      then
         Set_Returns_By_Ref (Func);
      end if;
   end Compute_Returns_By_Ref;

   --------------------------------
   -- Collect_Types_In_Hierarchy --
   --------------------------------

   function Collect_Types_In_Hierarchy
     (Typ                : Entity_Id;
      Examine_Components : Boolean := False) return Elist_Id
   is
      Results : Elist_Id;

      procedure Process_Type (Typ : Entity_Id);
      --  Collect type Typ if it satisfies function Predicate. Do so for its
      --  parent type, base type, progenitor types, and any component types.

      ------------------
      -- Process_Type --
      ------------------

      procedure Process_Type (Typ : Entity_Id) is
         Comp       : Entity_Id;
         Iface_Elmt : Elmt_Id;

      begin
         if not Is_Type (Typ) or else Error_Posted (Typ) then
            return;
         end if;

         --  Collect the current type if it satisfies the predicate

         if Predicate (Typ) then
            Append_Elmt (Typ, Results);
         end if;

         --  Process component types

         if Examine_Components then

            --  Examine components and discriminants

            if Is_Concurrent_Type (Typ)
              or else Is_Incomplete_Or_Private_Type (Typ)
              or else Is_Record_Type (Typ)
              or else Has_Discriminants (Typ)
            then
               Comp := First_Component_Or_Discriminant (Typ);

               while Present (Comp) loop
                  Process_Type (Etype (Comp));

                  Next_Component_Or_Discriminant (Comp);
               end loop;

            --  Examine array components

            elsif Ekind (Typ) = E_Array_Type then
               Process_Type (Component_Type (Typ));
            end if;
         end if;

         --  Examine parent type

         if Etype (Typ) /= Typ then
            --  Prevent infinite recursion, which can happen in illegal
            --  programs. Silently return if illegal. For now, just deal
            --  with the 2-type cycle case. Larger cycles will get
            --  SIGSEGV at compile time from running out of stack.

            if Etype (Etype (Typ)) = Typ then
               if Total_Errors_Detected = 0 then
                  raise Program_Error;
               else
                  return;
               end if;
            end if;

            Process_Type (Etype (Typ));
         end if;

         --  Examine base type

         if Base_Type (Typ) /= Typ then
            Process_Type (Base_Type (Typ));
         end if;

         --  Examine interfaces

         if Is_Record_Type (Typ)
           and then Present (Interfaces (Typ))
         then
            Iface_Elmt := First_Elmt (Interfaces (Typ));
            while Present (Iface_Elmt) loop
               Process_Type (Node (Iface_Elmt));

               Next_Elmt (Iface_Elmt);
            end loop;
         end if;
      end Process_Type;

   --  Start of processing for Collect_Types_In_Hierarchy

   begin
      Results := New_Elmt_List;
      Process_Type (Typ);
      return Results;
   end Collect_Types_In_Hierarchy;

   -----------------------
   -- Conditional_Delay --
   -----------------------

   procedure Conditional_Delay (New_Ent, Old_Ent : Entity_Id) is
   begin
      if Has_Delayed_Freeze (Old_Ent) and then not Is_Frozen (Old_Ent) then
         Set_Has_Delayed_Freeze (New_Ent);
      end if;
   end Conditional_Delay;

   -------------------------
   -- Copy_Component_List --
   -------------------------

   function Copy_Component_List
     (R_Typ : Entity_Id;
      Loc   : Source_Ptr) return List_Id
   is
      Comp  : Node_Id;
      Comps : constant List_Id := New_List;

   begin
      Comp := First_Component (Underlying_Type (R_Typ));
      while Present (Comp) loop
         if Comes_From_Source (Comp) then
            declare
               Comp_Decl : constant Node_Id := Declaration_Node (Comp);
            begin
               Append_To (Comps,
                 Make_Component_Declaration (Loc,
                   Defining_Identifier =>
                     Make_Defining_Identifier (Loc, Chars (Comp)),
                   Component_Definition =>
                     New_Copy_Tree
                       (Component_Definition (Comp_Decl), New_Sloc => Loc)));
            end;
         end if;

         Next_Component (Comp);
      end loop;

      return Comps;
   end Copy_Component_List;

   -----------------------
   -- Copy_Ghost_Aspect --
   -----------------------

   procedure Copy_Ghost_Aspect (From : Node_Id; To : Node_Id) is
      pragma Assert (not Has_Aspects (To));
      Asp : Node_Id;

   begin
      if Has_Aspects (From) then
         Asp := Find_Aspect (Defining_Entity (From), Aspect_Ghost);

         if Present (Asp) then
            Set_Aspect_Specifications (To, New_List (New_Copy_Tree (Asp)));
         end if;
      end if;
   end Copy_Ghost_Aspect;

   -------------------------
   -- Copy_Parameter_List --
   -------------------------

   function Copy_Parameter_List (Subp_Id : Entity_Id) return List_Id is
      Loc    : constant Source_Ptr := Sloc (Subp_Id);
      Plist  : List_Id;
      Formal : Entity_Id := First_Formal (Subp_Id);

   begin
      if Present (Formal) then
         Plist := New_List;
         while Present (Formal) loop
            Append_To (Plist,
              Make_Parameter_Specification (Loc,
                Defining_Identifier =>
                  Make_Defining_Identifier (Sloc (Formal), Chars (Formal)),
                In_Present          => In_Present (Parent (Formal)),
                Out_Present         => Out_Present (Parent (Formal)),
                Parameter_Type      =>
                  New_Occurrence_Of (Etype (Formal), Loc),
                Expression          =>
                  New_Copy_Tree (Expression (Parent (Formal)))));

            Next_Formal (Formal);
         end loop;
      else
         Plist := No_List;
      end if;

      return Plist;
   end Copy_Parameter_List;

   ----------------------------
   -- Copy_SPARK_Mode_Aspect --
   ----------------------------

   procedure Copy_SPARK_Mode_Aspect (From : Node_Id; To : Node_Id) is
      pragma Assert (not Has_Aspects (To));
      Asp : Node_Id;

   begin
      if Has_Aspects (From) then
         Asp := Find_Aspect (Defining_Entity (From), Aspect_SPARK_Mode);

         if Present (Asp) then
            Set_Aspect_Specifications (To, New_List (New_Copy_Tree (Asp)));
         end if;
      end if;
   end Copy_SPARK_Mode_Aspect;

   --------------------------
   -- Copy_Subprogram_Spec --
   --------------------------

   function Copy_Subprogram_Spec
     (Spec     : Node_Id;
      New_Sloc : Source_Ptr := No_Location) return Node_Id
   is
      Def_Id      : Node_Id;
      Formal_Spec : Node_Id;
      Result      : Node_Id;

   begin
      --  The structure of the original tree must be replicated without any
      --  alterations. Use New_Copy_Tree for this purpose.

      Result := New_Copy_Tree (Spec, New_Sloc => New_Sloc);

      --  However, the spec of a null procedure carries the corresponding null
      --  statement of the body (created by the parser), and this cannot be
      --  shared with the new subprogram spec.

      if Nkind (Result) = N_Procedure_Specification then
         Set_Null_Statement (Result, Empty);
      end if;

      --  Create a new entity for the defining unit name

      Def_Id := Defining_Unit_Name (Result);
      Set_Defining_Unit_Name (Result,
        Make_Defining_Identifier (Sloc (Def_Id), Chars (Def_Id)));

      --  Create new entities for the formal parameters

      Formal_Spec := First (Parameter_Specifications (Result));
      while Present (Formal_Spec) loop
         Def_Id := Defining_Identifier (Formal_Spec);
         Set_Defining_Identifier (Formal_Spec,
           Make_Defining_Identifier (Sloc (Def_Id), Chars (Def_Id)));

         Next (Formal_Spec);
      end loop;

      return Result;
   end Copy_Subprogram_Spec;

   --------------------------------
   -- Corresponding_Generic_Type --
   --------------------------------

   function Corresponding_Generic_Type (T : Entity_Id) return Entity_Id is
      Inst : Entity_Id;
      Gen  : Entity_Id;
      Typ  : Entity_Id;

   begin
      if not Is_Generic_Actual_Type (T) then
         return Any_Type;

      --  If the actual is the actual of an enclosing instance, resolution
      --  was correct in the generic.

      elsif Nkind (Parent (T)) = N_Subtype_Declaration
        and then Is_Entity_Name (Subtype_Indication (Parent (T)))
        and then
          Is_Generic_Actual_Type (Entity (Subtype_Indication (Parent (T))))
      then
         return Any_Type;

      else
         Inst := Scope (T);

         if Is_Wrapper_Package (Inst) then
            Inst := Related_Instance (Inst);
         end if;

         Gen  :=
           Generic_Parent
             (Specification (Unit_Declaration_Node (Inst)));

         --  Generic actual has the same name as the corresponding formal

         Typ := First_Entity (Gen);
         while Present (Typ) loop
            if Chars (Typ) = Chars (T) then
               return Typ;
            end if;

            Next_Entity (Typ);
         end loop;

         return Any_Type;
      end if;
   end Corresponding_Generic_Type;

   --------------------------------
   -- Corresponding_Primitive_Op --
   --------------------------------

   function Corresponding_Primitive_Op
     (Ancestor_Op     : Entity_Id;
      Descendant_Type : Entity_Id) return Entity_Id
   is
      function Find_Untagged_Type_Of (Prim : Entity_Id) return Entity_Id;
      --  Search for the untagged type of the primitive operation Prim.

      function Profile_Matches_Ancestor (S : Entity_Id) return Boolean;
      --  Returns True if subprogram S has the proper profile for an
      --  overriding of Ancestor_Op (that is, corresponding formals either
      --  have the same type, or are corresponding controlling formals,
      --  and similarly for result types).

      ---------------------------
      -- Find_Untagged_Type_Of --
      ---------------------------

      function Find_Untagged_Type_Of (Prim : Entity_Id) return Entity_Id is
         E : Entity_Id := First_Entity (Scope (Prim));

      begin
         while Present (E) and then E /= Prim loop
            if not Is_Tagged_Type (E)
              and then Contains (Direct_Primitive_Operations (E), Prim)
            then
               return E;
            end if;

            Next_Entity (E);
         end loop;

         pragma Assert (False);
         return Empty;
      end Find_Untagged_Type_Of;

      Typ  : constant Entity_Id :=
               (if Is_Dispatching_Operation (Ancestor_Op)
                 then Find_Dispatching_Type (Ancestor_Op)
                 else Find_Untagged_Type_Of (Ancestor_Op));

      ------------------------------
      -- Profile_Matches_Ancestor --
      ------------------------------

      function Profile_Matches_Ancestor (S : Entity_Id) return Boolean is
         F1 : Entity_Id := First_Formal (Ancestor_Op);
         F2 : Entity_Id := First_Formal (S);

      begin
         if Ekind (Ancestor_Op) /= Ekind (S) then
            return False;
         end if;

         --  ??? This should probably account for anonymous access formals,
         --  but the parent function (Corresponding_Primitive_Op) is currently
         --  only called for user-defined literal functions, which can't have
         --  such formals. But if this is ever used in a more general context
         --  it should be extended to handle such formals (and result types).

         while Present (F1) and then Present (F2) loop
            if Etype (F1) = Etype (F2)
              or else Is_Ancestor (Typ, Etype (F2))
            then
               Next_Formal (F1);
               Next_Formal (F2);
            else
               return False;
            end if;
         end loop;

         return No (F1)
           and then No (F2)
           and then (Etype (Ancestor_Op) = Etype (S)
                      or else Is_Ancestor (Typ, Etype (S)));
      end Profile_Matches_Ancestor;

      --  Local variables

      Elmt : Elmt_Id;
      Subp : Entity_Id;

   --  Start of processing for Corresponding_Primitive_Op

   begin
      pragma Assert (Is_Ancestor (Typ, Descendant_Type)
                      or else Is_Progenitor (Typ, Descendant_Type));

      Elmt := First_Elmt (Primitive_Operations (Descendant_Type));

      while Present (Elmt) loop
         Subp := Node (Elmt);

         --  For regular primitives we need to check the profile against
         --  the ancestor when the name matches the name of Ancestor_Op,
         --  but for predefined dispatching operations we cannot rely on
         --  the name of the primitive to identify a candidate since their
         --  name is internally built by adding a suffix to the name of the
         --  tagged type.

         if Chars (Subp) = Chars (Ancestor_Op)
           or else Is_Predefined_Dispatching_Operation (Subp)
         then
            --  Handle case where Ancestor_Op is a primitive of a progenitor.
            --  We rely on internal entities that map interface primitives:
            --  their attribute Interface_Alias references the interface
            --  primitive, and their Alias attribute references the primitive
            --  of Descendant_Type implementing that interface primitive.

            if Present (Interface_Alias (Subp)) then
               if Interface_Alias (Subp) = Ancestor_Op then
                  return Alias (Subp);
               end if;

            --  Otherwise, return subprogram when profile matches its ancestor

            elsif Profile_Matches_Ancestor (Subp) then
               return Subp;
            end if;
         end if;

         Next_Elmt (Elmt);
      end loop;

      pragma Assert (False);
      return Empty;
   end Corresponding_Primitive_Op;

   --------------------
   -- Current_Entity --
   --------------------

   --  The currently visible definition for a given identifier is the
   --  one most chained at the start of the visibility chain, i.e. the
   --  one that is referenced by the Node_Id value of the name of the
   --  given identifier.

   function Current_Entity (N : Node_Id) return Entity_Id is
   begin
      return Get_Name_Entity_Id (Chars (N));
   end Current_Entity;

   -----------------------------
   -- Current_Entity_In_Scope --
   -----------------------------

   function Current_Entity_In_Scope (N : Name_Id) return Entity_Id is
      CS : constant Entity_Id := Current_Scope;

      E  : Entity_Id;

   begin
      E := Get_Name_Entity_Id (N);

      if No (E) then
         null;

      elsif Scope_Is_Transient then
         while Present (E) loop
            exit when Scope (E) = CS or else Scope (E) = Scope (CS);

            E := Homonym (E);
         end loop;

      else
         while Present (E) loop
            exit when Scope (E) = CS;

            E := Homonym (E);
         end loop;
      end if;

      return E;
   end Current_Entity_In_Scope;

   -----------------------------
   -- Current_Entity_In_Scope --
   -----------------------------

   function Current_Entity_In_Scope (N : Node_Id) return Entity_Id is
   begin
      return Current_Entity_In_Scope (Chars (N));
   end Current_Entity_In_Scope;

   -------------------
   -- Current_Scope --
   -------------------

   function Current_Scope return Entity_Id is
   begin
      if Scope_Stack.Last = -1 then
         return Standard_Standard;
      else
         declare
            C : constant Entity_Id :=
                  Scope_Stack.Table (Scope_Stack.Last).Entity;
         begin
            if Present (C) then
               return C;
            else
               return Standard_Standard;
            end if;
         end;
      end if;
   end Current_Scope;

   ----------------------------
   -- Current_Scope_No_Loops --
   ----------------------------

   function Current_Scope_No_Loops return Entity_Id is
      S : Entity_Id;

   begin
      --  Examine the scope stack starting from the current scope and skip any
      --  internally generated loops.

      S := Current_Scope;
      while Present (S) and then S /= Standard_Standard loop
         if Ekind (S) = E_Loop and then not Comes_From_Source (S) then
            S := Scope (S);
         else
            exit;
         end if;
      end loop;

      return S;
   end Current_Scope_No_Loops;

   ------------------------
   -- Current_Subprogram --
   ------------------------

   function Current_Subprogram return Entity_Id is
      Scop : constant Entity_Id := Current_Scope;
   begin
      if Is_Subprogram_Or_Generic_Subprogram (Scop) then
         return Scop;
      else
         return Enclosing_Subprogram (Scop);
      end if;
   end Current_Subprogram;

   ------------------------------
   -- CW_Or_Needs_Finalization --
   ------------------------------

   function CW_Or_Needs_Finalization (Typ : Entity_Id) return Boolean is
   begin
      return Is_Class_Wide_Type (Typ) or else Needs_Finalization (Typ);
   end CW_Or_Needs_Finalization;

   ---------------------
   -- Defining_Entity --
   ---------------------

   function Defining_Entity (N : Node_Id) return Entity_Id is
      Ent : constant Entity_Id := Defining_Entity_Or_Empty (N);

   begin
      if Present (Ent) then
         return Ent;

      else
         raise Program_Error;
      end if;
   end Defining_Entity;

   ------------------------------
   -- Defining_Entity_Or_Empty --
   ------------------------------

   function Defining_Entity_Or_Empty (N : Node_Id) return Entity_Id is
   begin
      case Nkind (N) is
         when N_Abstract_Subprogram_Declaration
            | N_Expression_Function
            | N_Formal_Subprogram_Declaration
            | N_Generic_Package_Declaration
            | N_Generic_Subprogram_Declaration
            | N_Package_Declaration
            | N_Subprogram_Body
            | N_Subprogram_Body_Stub
            | N_Subprogram_Declaration
            | N_Subprogram_Renaming_Declaration
         =>
            return Defining_Entity (Specification (N));

         when N_Component_Declaration
            | N_Defining_Program_Unit_Name
            | N_Discriminant_Specification
            | N_Entry_Body
            | N_Entry_Declaration
            | N_Entry_Index_Specification
            | N_Exception_Declaration
            | N_Exception_Renaming_Declaration
            | N_Formal_Object_Declaration
            | N_Formal_Package_Declaration
            | N_Formal_Type_Declaration
            | N_Full_Type_Declaration
            | N_Implicit_Label_Declaration
            | N_Incomplete_Type_Declaration
            | N_Iterator_Specification
            | N_Loop_Parameter_Specification
            | N_Number_Declaration
            | N_Object_Declaration
            | N_Object_Renaming_Declaration
            | N_Package_Body_Stub
            | N_Parameter_Specification
            | N_Private_Extension_Declaration
            | N_Private_Type_Declaration
            | N_Protected_Body
            | N_Protected_Body_Stub
            | N_Protected_Type_Declaration
            | N_Single_Protected_Declaration
            | N_Single_Task_Declaration
            | N_Subtype_Declaration
            | N_Task_Body
            | N_Task_Body_Stub
            | N_Task_Type_Declaration
         =>
            return Defining_Identifier (N);

         when N_Compilation_Unit =>
            return Defining_Entity (Unit (N));

         when N_Subunit =>
            return Defining_Entity (Proper_Body (N));

         when N_Function_Instantiation
            | N_Function_Specification
            | N_Generic_Function_Renaming_Declaration
            | N_Generic_Package_Renaming_Declaration
            | N_Generic_Procedure_Renaming_Declaration
            | N_Package_Body
            | N_Package_Instantiation
            | N_Package_Renaming_Declaration
            | N_Package_Specification
            | N_Procedure_Instantiation
            | N_Procedure_Specification
         =>
            declare
               Nam : constant Node_Id := Defining_Unit_Name (N);
               Err : Entity_Id := Empty;

            begin
               if Nkind (Nam) in N_Entity then
                  return Nam;

               --  For Error, make up a name and attach to declaration so we
               --  can continue semantic analysis.

               elsif Nam = Error then
                  Err := Make_Temporary (Sloc (N), 'T');
                  Set_Defining_Unit_Name (N, Err);

                  return Err;

               --  If not an entity, get defining identifier

               else
                  return Defining_Identifier (Nam);
               end if;
            end;

         when N_Block_Statement
            | N_Loop_Statement
         =>
            return Entity (Identifier (N));

         when others =>
            return Empty;
      end case;
   end Defining_Entity_Or_Empty;

   --------------------------
   -- Denotes_Discriminant --
   --------------------------

   function Denotes_Discriminant
     (N                : Node_Id;
      Check_Concurrent : Boolean := False) return Boolean
   is
      E : Entity_Id;

   begin
      if not Is_Entity_Name (N) or else No (Entity (N)) then
         return False;
      else
         E := Entity (N);
      end if;

      --  If we are checking for a protected type, the discriminant may have
      --  been rewritten as the corresponding discriminal of the original type
      --  or of the corresponding concurrent record, depending on whether we
      --  are in the spec or body of the protected type.

      return Ekind (E) = E_Discriminant
        or else
          (Check_Concurrent
            and then Ekind (E) = E_In_Parameter
            and then Present (Discriminal_Link (E))
            and then
              (Is_Concurrent_Type (Scope (Discriminal_Link (E)))
                or else
                  Is_Concurrent_Record_Type (Scope (Discriminal_Link (E)))));
   end Denotes_Discriminant;

   -------------------------
   -- Denotes_Same_Object --
   -------------------------

   function Denotes_Same_Object (A1, A2 : Node_Id) return Boolean is
      function Is_Object_Renaming (N : Node_Id) return Boolean;
      --  Return true if N names an object renaming entity

      function Is_Valid_Renaming (N : Node_Id) return Boolean;
      --  For renamings, return False if the prefix of any dereference within
      --  the renamed object_name is a variable, or any expression within the
      --  renamed object_name contains references to variables or calls on
      --  nonstatic functions; otherwise return True (RM 6.4.1(6.10/3))

      ------------------------
      -- Is_Object_Renaming --
      ------------------------

      function Is_Object_Renaming (N : Node_Id) return Boolean is
      begin
         return Is_Entity_Name (N)
           and then Ekind (Entity (N)) in E_Variable | E_Constant
           and then Present (Renamed_Object (Entity (N)));
      end Is_Object_Renaming;

      -----------------------
      -- Is_Valid_Renaming --
      -----------------------

      function Is_Valid_Renaming (N : Node_Id) return Boolean is
      begin
         if Is_Object_Renaming (N)
           and then not Is_Valid_Renaming (Renamed_Object (Entity (N)))
         then
            return False;
         end if;

         --  Check if any expression within the renamed object_name contains no
         --  references to variables nor calls on nonstatic functions.

         if Nkind (N) = N_Indexed_Component then
            declare
               Indx : Node_Id;

            begin
               Indx := First (Expressions (N));
               while Present (Indx) loop
                  if not Is_OK_Static_Expression (Indx) then
                     return False;
                  end if;

                  Next (Indx);
               end loop;
            end;

         elsif Nkind (N) = N_Slice then
            declare
               Rng : constant Node_Id := Discrete_Range (N);
            begin
               --  Bounds specified as a range

               if Nkind (Rng) = N_Range then
                  if not Is_OK_Static_Range (Rng) then
                     return False;
                  end if;

               --  Bounds specified as a constrained subtype indication

               elsif Nkind (Rng) = N_Subtype_Indication then
                  if not Is_OK_Static_Range
                       (Range_Expression (Constraint (Rng)))
                  then
                     return False;
                  end if;

               --  Bounds specified as a subtype name

               elsif not Is_OK_Static_Expression (Rng) then
                  return False;
               end if;
            end;
         end if;

         if Has_Prefix (N) then
            declare
               P : constant Node_Id := Prefix (N);

            begin
               if Nkind (N) = N_Explicit_Dereference
                 and then Is_Variable (P)
               then
                  return False;

               elsif Is_Entity_Name (P)
                 and then Ekind (Entity (P)) = E_Function
               then
                  return False;

               elsif Nkind (P) = N_Function_Call then
                  return False;
               end if;

               --  Recursion to continue traversing the prefix of the
               --  renaming expression

               return Is_Valid_Renaming (P);
            end;
         end if;

         return True;
      end Is_Valid_Renaming;

   --  Start of processing for Denotes_Same_Object

   begin
      --  Both names statically denote the same stand-alone object or
      --  parameter (RM 6.4.1(6.6/3)).

      if Is_Entity_Name (A1)
        and then Is_Entity_Name (A2)
        and then Entity (A1) = Entity (A2)
      then
         return True;

      --  Both names are selected_components, their prefixes are known to
      --  denote the same object, and their selector_names denote the same
      --  component (RM 6.4.1(6.7/3)).

      elsif Nkind (A1) = N_Selected_Component
        and then Nkind (A2) = N_Selected_Component
      then
         return Denotes_Same_Object (Prefix (A1), Prefix (A2))
           and then
             Entity (Selector_Name (A1)) = Entity (Selector_Name (A2));

      --  Both names are dereferences and the dereferenced names are known to
      --  denote the same object (RM 6.4.1(6.8/3)).

      elsif Nkind (A1) = N_Explicit_Dereference
        and then Nkind (A2) = N_Explicit_Dereference
      then
         return Denotes_Same_Object (Prefix (A1), Prefix (A2));

      --  Both names are indexed_components, their prefixes are known to denote
      --  the same object, and each of the pairs of corresponding index values
      --  are either both static expressions with the same static value or both
      --  names that are known to denote the same object (RM 6.4.1(6.9/3)).

      elsif Nkind (A1) = N_Indexed_Component
        and then Nkind (A2) = N_Indexed_Component
      then
         if not Denotes_Same_Object (Prefix (A1), Prefix (A2)) then
            return False;
         else
            declare
               Indx1 : Node_Id;
               Indx2 : Node_Id;

            begin
               Indx1 := First (Expressions (A1));
               Indx2 := First (Expressions (A2));
               while Present (Indx1) loop

                  --  Indexes must denote the same static value or same object

                  if Is_OK_Static_Expression (Indx1) then
                     if not Is_OK_Static_Expression (Indx2) then
                        return False;

                     elsif Expr_Value (Indx1) /= Expr_Value (Indx2) then
                        return False;
                     end if;

                  elsif not Denotes_Same_Object (Indx1, Indx2) then
                     return False;
                  end if;

                  Next (Indx1);
                  Next (Indx2);
               end loop;

               return True;
            end;
         end if;

      --  Both names are slices, their prefixes are known to denote the same
      --  object, and the two slices have statically matching index constraints
      --  (RM 6.4.1(6.10/3)).

      elsif Nkind (A1) = N_Slice
        and then Nkind (A2) = N_Slice
      then
         if not Denotes_Same_Object (Prefix (A1), Prefix (A2)) then
            return False;
         else
            declare
               Lo1, Lo2, Hi1, Hi2 : Node_Id;

            begin
               Get_Index_Bounds (Discrete_Range (A1), Lo1, Hi1);
               Get_Index_Bounds (Discrete_Range (A2), Lo2, Hi2);

               --  Check whether bounds are statically identical. There is no
               --  attempt to detect partial overlap of slices.

               return Is_OK_Static_Expression (Lo1)
                 and then Is_OK_Static_Expression (Lo2)
                 and then Is_OK_Static_Expression (Hi1)
                 and then Is_OK_Static_Expression (Hi2)
                 and then Expr_Value (Lo1) = Expr_Value (Lo2)
                 and then Expr_Value (Hi1) = Expr_Value (Hi2);
            end;
         end if;

      --  One of the two names statically denotes a renaming declaration whose
      --  renamed object_name is known to denote the same object as the other;
      --  the prefix of any dereference within the renamed object_name is not a
      --  variable, and any expression within the renamed object_name contains
      --  no references to variables nor calls on nonstatic functions (RM
      --  6.4.1(6.11/3)).

      elsif Is_Object_Renaming (A1)
        and then Is_Valid_Renaming (A1)
      then
         return Denotes_Same_Object (Renamed_Object (Entity (A1)), A2);

      elsif Is_Object_Renaming (A2)
        and then Is_Valid_Renaming (A2)
      then
         return Denotes_Same_Object (A1, Renamed_Object (Entity (A2)));

      else
         return False;
      end if;
   end Denotes_Same_Object;

   -------------------------
   -- Denotes_Same_Prefix --
   -------------------------

   function Denotes_Same_Prefix (A1, A2 : Node_Id) return Boolean is
   begin
      if Is_Entity_Name (A1) then
         if Nkind (A2) in N_Selected_Component | N_Indexed_Component
           and then not Is_Access_Type (Etype (A1))
         then
            return Denotes_Same_Object (A1, Prefix (A2))
              or else Denotes_Same_Prefix (A1, Prefix (A2));
         else
            return False;
         end if;

      elsif Is_Entity_Name (A2) then
         return Denotes_Same_Prefix (A1 => A2, A2 => A1);

      elsif Nkind (A1) in N_Selected_Component | N_Indexed_Component | N_Slice
              and then
            Nkind (A2) in N_Selected_Component | N_Indexed_Component | N_Slice
      then
         declare
            Root1, Root2   : Node_Id;
            Depth1, Depth2 : Nat := 0;

         begin
            Root1 := Prefix (A1);
            while not Is_Entity_Name (Root1) loop
               if Nkind (Root1) not in
                    N_Selected_Component | N_Indexed_Component
               then
                  return False;
               else
                  Root1 := Prefix (Root1);
               end if;

               Depth1 := Depth1 + 1;
            end loop;

            Root2 := Prefix (A2);
            while not Is_Entity_Name (Root2) loop
               if Nkind (Root2) not in
                    N_Selected_Component | N_Indexed_Component
               then
                  return False;
               else
                  Root2 := Prefix (Root2);
               end if;

               Depth2 := Depth2 + 1;
            end loop;

            --  If both have the same depth and they do not denote the same
            --  object, they are disjoint and no warning is needed.

            if Depth1 = Depth2 then
               return False;

            elsif Depth1 > Depth2 then
               Root1 := Prefix (A1);
               for J in 1 .. Depth1 - Depth2 - 1 loop
                  Root1 := Prefix (Root1);
               end loop;

               return Denotes_Same_Object (Root1, A2);

            else
               Root2 := Prefix (A2);
               for J in 1 .. Depth2 - Depth1 - 1 loop
                  Root2 := Prefix (Root2);
               end loop;

               return Denotes_Same_Object (A1, Root2);
            end if;
         end;

      else
         return False;
      end if;
   end Denotes_Same_Prefix;

   ----------------------
   -- Denotes_Variable --
   ----------------------

   function Denotes_Variable (N : Node_Id) return Boolean is
   begin
      return Is_Variable (N) and then Paren_Count (N) = 0;
   end Denotes_Variable;

   -----------------------------
   -- Depends_On_Discriminant --
   -----------------------------

   function Depends_On_Discriminant (N : Node_Id) return Boolean is
      L : Node_Id;
      H : Node_Id;

   begin
      Get_Index_Bounds (N, L, H);
      return Denotes_Discriminant (L) or else Denotes_Discriminant (H);
   end Depends_On_Discriminant;

   -------------------------------------
   -- Derivation_Too_Early_To_Inherit --
   -------------------------------------

   function Derivation_Too_Early_To_Inherit
     (Typ : Entity_Id; Streaming_Op : TSS_Name_Type) return Boolean is

      Btyp        : constant Entity_Id := Implementation_Base_Type (Typ);
      Parent_Type : Entity_Id;

      Real_Rep : Node_Id;

   --  Start of processing for Derivation_Too_Early_To_Inherit

   begin
      if Is_Derived_Type (Btyp) then
         Parent_Type := Implementation_Base_Type (Etype (Btyp));
         pragma Assert (Parent_Type /= Btyp);

         if Has_Stream_Attribute_Definition
              (Parent_Type, Streaming_Op, Real_Rep => Real_Rep)

           and then In_Same_Extended_Unit (Btyp, Parent_Type)
           and then Instantiation (Get_Source_File_Index (Sloc (Btyp))) =
                    Instantiation (Get_Source_File_Index (Sloc (Parent_Type)))
         then
            return Earlier_In_Extended_Unit (Btyp, Real_Rep);
         end if;
      end if;

      return False;
   end Derivation_Too_Early_To_Inherit;

   -------------------------
   -- Designate_Same_Unit --
   -------------------------

   function Designate_Same_Unit
     (Name1 : Node_Id;
      Name2 : Node_Id) return Boolean
   is
      K1 : constant Node_Kind := Nkind (Name1);
      K2 : constant Node_Kind := Nkind (Name2);

      function Prefix_Node (N : Node_Id) return Node_Id;
      --  Returns the parent unit name node of a defining program unit name
      --  or the prefix if N is a selected component or an expanded name.

      function Select_Node (N : Node_Id) return Node_Id;
      --  Returns the defining identifier node of a defining program unit
      --  name or  the selector node if N is a selected component or an
      --  expanded name.

      -----------------
      -- Prefix_Node --
      -----------------

      function Prefix_Node (N : Node_Id) return Node_Id is
      begin
         if Nkind (N) = N_Defining_Program_Unit_Name then
            return Name (N);
         else
            return Prefix (N);
         end if;
      end Prefix_Node;

      -----------------
      -- Select_Node --
      -----------------

      function Select_Node (N : Node_Id) return Node_Id is
      begin
         if Nkind (N) = N_Defining_Program_Unit_Name then
            return Defining_Identifier (N);
         else
            return Selector_Name (N);
         end if;
      end Select_Node;

   --  Start of processing for Designate_Same_Unit

   begin
      if K1 in N_Identifier | N_Defining_Identifier
           and then
         K2 in N_Identifier | N_Defining_Identifier
      then
         return Chars (Name1) = Chars (Name2);

      elsif K1 in N_Expanded_Name
                | N_Selected_Component
                | N_Defining_Program_Unit_Name
        and then
            K2 in N_Expanded_Name
                | N_Selected_Component
                | N_Defining_Program_Unit_Name
      then
         return
           Chars (Select_Node (Name1)) = Chars (Select_Node (Name2))
             and then
               Designate_Same_Unit (Prefix_Node (Name1), Prefix_Node (Name2));

      else
         return False;
      end if;
   end Designate_Same_Unit;

   ---------------------------------------------
   -- Diagnose_Iterated_Component_Association --
   ---------------------------------------------

   procedure Diagnose_Iterated_Component_Association (N : Node_Id) is
      Def_Id : constant Entity_Id := Defining_Identifier (N);
      Aggr   : Node_Id;

   begin
      --  Determine whether the iterated component association appears within
      --  an aggregate. If this is the case, raise Program_Error because the
      --  iterated component association cannot be left in the tree as is and
      --  must always be processed by the related aggregate.

      Aggr := N;
      while Present (Aggr) loop
         if Nkind (Aggr) = N_Aggregate then
            raise Program_Error;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Aggr) then
            exit;
         end if;

         Aggr := Parent (Aggr);
      end loop;

      --  At this point it is known that the iterated component association is
      --  not within an aggregate. This is really a quantified expression with
      --  a missing "all" or "some" quantifier.

      Error_Msg_N ("missing quantifier", Def_Id);

      --  Rewrite the iterated component association as True to prevent any
      --  cascaded errors.

      Rewrite (N, New_Occurrence_Of (Standard_True, Sloc (N)));
      Analyze (N);
   end Diagnose_Iterated_Component_Association;

   ------------------------
   -- Discriminated_Size --
   ------------------------

   function Discriminated_Size (Comp : Entity_Id) return Boolean is
      function Non_Static_Bound (Bound : Node_Id) return Boolean;
      --  Check whether the bound of an index is non-static and does denote
      --  a discriminant, in which case any object of the type (protected or
      --  otherwise) will have a non-static size.

      ----------------------
      -- Non_Static_Bound --
      ----------------------

      function Non_Static_Bound (Bound : Node_Id) return Boolean is
      begin
         if Is_OK_Static_Expression (Bound) then
            return False;

         --  If the bound is given by a discriminant it is non-static
         --  (A static constraint replaces the reference with the value).
         --  In an protected object the discriminant has been replaced by
         --  the corresponding discriminal within the protected operation.

         elsif Is_Entity_Name (Bound)
           and then
             (Ekind (Entity (Bound)) = E_Discriminant
               or else Present (Discriminal_Link (Entity (Bound))))
         then
            return False;

         else
            return True;
         end if;
      end Non_Static_Bound;

      --  Local variables

      Typ   : constant Entity_Id := Etype (Comp);
      Index : Node_Id;

   --  Start of processing for Discriminated_Size

   begin
      if not Is_Array_Type (Typ) then
         return False;
      end if;

      if Ekind (Typ) = E_Array_Subtype then
         Index := First_Index (Typ);
         while Present (Index) loop
            if Non_Static_Bound (Low_Bound (Index))
              or else Non_Static_Bound (High_Bound (Index))
            then
               return False;
            end if;

            Next_Index (Index);
         end loop;

         return True;
      end if;

      return False;
   end Discriminated_Size;

   -----------------------------
   -- Effective_Reads_Enabled --
   -----------------------------

   function Effective_Reads_Enabled (Id : Entity_Id) return Boolean is
   begin
      return Has_Enabled_Property (Id, Name_Effective_Reads);
   end Effective_Reads_Enabled;

   ------------------------------
   -- Effective_Writes_Enabled --
   ------------------------------

   function Effective_Writes_Enabled (Id : Entity_Id) return Boolean is
   begin
      return Has_Enabled_Property (Id, Name_Effective_Writes);
   end Effective_Writes_Enabled;

   ------------------------------
   -- Enclosing_Comp_Unit_Node --
   ------------------------------

   function Enclosing_Comp_Unit_Node (N : Node_Id) return Node_Id is
      Current_Node : Node_Id;

   begin
      Current_Node := N;
      while Present (Current_Node)
        and then Nkind (Current_Node) /= N_Compilation_Unit
      loop
         Current_Node := Parent (Current_Node);
      end loop;

      return Current_Node;
   end Enclosing_Comp_Unit_Node;

   --------------------------
   -- Enclosing_CPP_Parent --
   --------------------------

   function Enclosing_CPP_Parent (Typ : Entity_Id) return Entity_Id is
      Parent_Typ : Entity_Id := Typ;

   begin
      while not Is_CPP_Class (Parent_Typ)
         and then Etype (Parent_Typ) /= Parent_Typ
      loop
         Parent_Typ := Etype (Parent_Typ);

         if Is_Private_Type (Parent_Typ) then
            Parent_Typ := Full_View (Base_Type (Parent_Typ));
         end if;
      end loop;

      pragma Assert (Is_CPP_Class (Parent_Typ));
      return Parent_Typ;
   end Enclosing_CPP_Parent;

   ---------------------------
   -- Enclosing_Declaration --
   ---------------------------

   function Enclosing_Declaration (N : Node_Id) return Node_Id is
      Decl : Node_Id := N;

   begin
      while Present (Decl)
        and then not (Nkind (Decl) in N_Declaration
                        or else
                      Nkind (Decl) in N_Later_Decl_Item
                        or else
                      Nkind (Decl) in N_Renaming_Declaration
                        or else
                      Nkind (Decl) = N_Number_Declaration)
      loop
         Decl := Parent (Decl);
      end loop;

      return Decl;
   end Enclosing_Declaration;

   ----------------------------------------
   -- Enclosing_Declaration_Or_Statement --
   ----------------------------------------

   function Enclosing_Declaration_Or_Statement
     (N : Node_Id) return Node_Id
   is
      Par : Node_Id;

   begin
      Par := N;
      while Present (Par) loop
         if Is_Declaration (Par) or else Is_Statement (Par) then
            return Par;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            exit;
         end if;

         Par := Parent (Par);
      end loop;

      return N;
   end Enclosing_Declaration_Or_Statement;

   ----------------------------
   -- Enclosing_Generic_Body --
   ----------------------------

   function Enclosing_Generic_Body (N : Node_Id) return Node_Id is
      Par     : Node_Id;
      Spec_Id : Entity_Id;

   begin
      Par := Parent (N);
      while Present (Par) loop
         if Nkind (Par) in N_Package_Body | N_Subprogram_Body then
            Spec_Id := Corresponding_Spec (Par);

            if Present (Spec_Id)
              and then Nkind (Unit_Declaration_Node (Spec_Id)) in
                         N_Generic_Declaration
            then
               return Par;
            end if;
         end if;

         Par := Parent (Par);
      end loop;

      return Empty;
   end Enclosing_Generic_Body;

   ----------------------------
   -- Enclosing_Generic_Unit --
   ----------------------------

   function Enclosing_Generic_Unit (N : Node_Id) return Node_Id is
      Par       : Node_Id;
      Spec_Decl : Node_Id;
      Spec_Id   : Entity_Id;

   begin
      Par := Parent (N);
      while Present (Par) loop
         if Nkind (Par) in N_Generic_Declaration then
            return Par;

         elsif Nkind (Par) in N_Package_Body | N_Subprogram_Body then
            Spec_Id := Corresponding_Spec (Par);

            if Present (Spec_Id) then
               Spec_Decl := Unit_Declaration_Node (Spec_Id);

               if Nkind (Spec_Decl) in N_Generic_Declaration then
                  return Spec_Decl;
               end if;
            end if;
         end if;

         Par := Parent (Par);
      end loop;

      return Empty;
   end Enclosing_Generic_Unit;

   -------------------
   -- Enclosing_HSS --
   -------------------

   function Enclosing_HSS (Stmt : Node_Id) return Node_Id is
      Par : Node_Id;
   begin
      pragma Assert (Is_Statement (Stmt));

      Par := Parent (Stmt);
      while Present (Par) loop

         if Nkind (Par) = N_Handled_Sequence_Of_Statements then
            return Par;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            return Empty;

         end if;

         Par := Parent (Par);
      end loop;

      return Par;
   end Enclosing_HSS;

   -------------------------------
   -- Enclosing_Lib_Unit_Entity --
   -------------------------------

   function Enclosing_Lib_Unit_Entity
      (E : Entity_Id := Current_Scope) return Entity_Id
   is
      Unit_Entity : Entity_Id;

   begin
      --  Look for enclosing library unit entity by following scope links.
      --  Equivalent to, but faster than indexing through the scope stack.

      Unit_Entity := E;
      while (Present (Scope (Unit_Entity))
        and then Scope (Unit_Entity) /= Standard_Standard)
        and not Is_Child_Unit (Unit_Entity)
      loop
         Unit_Entity := Scope (Unit_Entity);
      end loop;

      return Unit_Entity;
   end Enclosing_Lib_Unit_Entity;

   -----------------------------
   -- Enclosing_Lib_Unit_Node --
   -----------------------------

   function Enclosing_Lib_Unit_Node (N : Node_Id) return Node_Id is
      Encl_Unit : Node_Id;

   begin
      Encl_Unit := Enclosing_Comp_Unit_Node (N);
      while Present (Encl_Unit)
        and then Nkind (Unit (Encl_Unit)) = N_Subunit
      loop
         Encl_Unit := Library_Unit (Encl_Unit);
      end loop;

      pragma Assert (Nkind (Encl_Unit) = N_Compilation_Unit);
      return Encl_Unit;
   end Enclosing_Lib_Unit_Node;

   -----------------------
   -- Enclosing_Package --
   -----------------------

   function Enclosing_Package (N : Node_Or_Entity_Id) return Entity_Id is
      Dynamic_Scope : Entity_Id;

   begin
      --  Obtain the enclosing scope when N is a Node_Id - taking care to
      --  handle the case when the enclosing scope is already a package.

      if Nkind (N) not in N_Entity then
         declare
            Encl_Scop : constant Entity_Id := Find_Enclosing_Scope (N);
         begin
            if No (Encl_Scop) then
               return Empty;
            elsif Ekind (Encl_Scop) in
                    E_Generic_Package | E_Package | E_Package_Body
            then
               return Encl_Scop;
            end if;

            return Enclosing_Package (Encl_Scop);
         end;
      end if;

      --  When N is already an Entity_Id proceed

      Dynamic_Scope := Enclosing_Dynamic_Scope (N);
      if Dynamic_Scope = Standard_Standard then
         return Standard_Standard;

      elsif Dynamic_Scope = Empty then
         return Empty;

      elsif Ekind (Dynamic_Scope) in
              E_Generic_Package | E_Package | E_Package_Body
      then
         return Dynamic_Scope;

      else
         return Enclosing_Package (Dynamic_Scope);
      end if;
   end Enclosing_Package;

   -------------------------------------
   -- Enclosing_Package_Or_Subprogram --
   -------------------------------------

   function Enclosing_Package_Or_Subprogram (E : Entity_Id) return Entity_Id is
      S : Entity_Id;

   begin
      S := Scope (E);
      while Present (S) loop
         if Is_Package_Or_Generic_Package (S)
           or else Is_Subprogram_Or_Generic_Subprogram (S)
         then
            return S;

         else
            S := Scope (S);
         end if;
      end loop;

      return Empty;
   end Enclosing_Package_Or_Subprogram;

   --------------------------
   -- Enclosing_Subprogram --
   --------------------------

   function Enclosing_Subprogram (N : Node_Or_Entity_Id) return Entity_Id is
      Dyn_Scop  : Entity_Id;
      Encl_Scop : Entity_Id;

   begin
      --  Obtain the enclosing scope when N is a Node_Id - taking care to
      --  handle the case when the enclosing scope is already a subprogram.

      if Nkind (N) not in N_Entity then
         Encl_Scop := Find_Enclosing_Scope (N);

         if No (Encl_Scop) then
            return Empty;
         elsif Ekind (Encl_Scop) in Subprogram_Kind then
            return Encl_Scop;
         end if;

         return Enclosing_Subprogram (Encl_Scop);
      end if;

      --  When N is already an Entity_Id proceed

      Dyn_Scop := Enclosing_Dynamic_Scope (N);
      if Dyn_Scop = Standard_Standard then
         return Empty;

      elsif Dyn_Scop = Empty then
         return Empty;

      elsif Ekind (Dyn_Scop) = E_Subprogram_Body then
         return Corresponding_Spec (Parent (Parent (Dyn_Scop)));

      elsif Ekind (Dyn_Scop) in E_Block | E_Loop | E_Return_Statement then
         return Enclosing_Subprogram (Dyn_Scop);

      elsif Ekind (Dyn_Scop) in E_Entry | E_Entry_Family then

         --  For a task entry or entry family, return the enclosing subprogram
         --  of the task itself.

         if Ekind (Scope (Dyn_Scop)) = E_Task_Type then
            return Enclosing_Subprogram (Dyn_Scop);

         --  A protected entry or entry family is rewritten as a protected
         --  procedure which is the desired enclosing subprogram. This is
         --  relevant when unnesting a procedure local to an entry body.

         else
            return Protected_Body_Subprogram (Dyn_Scop);
         end if;

      elsif Ekind (Dyn_Scop) = E_Task_Type then
         return Get_Task_Body_Procedure (Dyn_Scop);

      --  The scope may appear as a private type or as a private extension
      --  whose completion is a task or protected type.

      elsif Ekind (Dyn_Scop) in
              E_Limited_Private_Type | E_Record_Type_With_Private
        and then Present (Full_View (Dyn_Scop))
        and then Ekind (Full_View (Dyn_Scop)) in E_Task_Type | E_Protected_Type
      then
         return Get_Task_Body_Procedure (Full_View (Dyn_Scop));

      --  No body is generated if the protected operation is eliminated

      elsif not Is_Eliminated (Dyn_Scop)
        and then Present (Protected_Body_Subprogram (Dyn_Scop))
      then
         return Protected_Body_Subprogram (Dyn_Scop);

      else
         return Dyn_Scop;
      end if;
   end Enclosing_Subprogram;

   --------------------------
   -- End_Keyword_Location --
   --------------------------

   function End_Keyword_Location (N : Node_Id) return Source_Ptr is
      function End_Label_Loc (Nod : Node_Id) return Source_Ptr;
      --  Return the source location of Nod's end label according to the
      --  following precedence rules:
      --
      --    1) If the end label exists, return its location
      --    2) If Nod exists, return its location
      --    3) Return the location of N

      -------------------
      -- End_Label_Loc --
      -------------------

      function End_Label_Loc (Nod : Node_Id) return Source_Ptr is
         Label : Node_Id;

      begin
         if Present (Nod) then
            Label := End_Label (Nod);

            if Present (Label) then
               return Sloc (Label);
            else
               return Sloc (Nod);
            end if;

         else
            return Sloc (N);
         end if;
      end End_Label_Loc;

      --  Local variables

      Owner : Node_Id := Empty;

   --  Start of processing for End_Keyword_Location

   begin
      if Nkind (N) in N_Block_Statement
                    | N_Entry_Body
                    | N_Package_Body
                    | N_Subprogram_Body
                    | N_Task_Body
      then
         Owner := Handled_Statement_Sequence (N);

      elsif Nkind (N) = N_Package_Declaration then
         Owner := Specification (N);

      elsif Nkind (N) = N_Protected_Body then
         Owner := N;

      elsif Nkind (N) in N_Protected_Type_Declaration
                       | N_Single_Protected_Declaration
      then
         Owner := Protected_Definition (N);

      elsif Nkind (N) in N_Single_Task_Declaration | N_Task_Type_Declaration
      then
         Owner := Task_Definition (N);

      --  This routine should not be called with other contexts

      else
         pragma Assert (False);
         null;
      end if;

      return End_Label_Loc (Owner);
   end End_Keyword_Location;

   ------------------------
   -- Ensure_Freeze_Node --
   ------------------------

   procedure Ensure_Freeze_Node (E : Entity_Id) is
      FN : Node_Id;
   begin
      if No (Freeze_Node (E)) then
         FN := Make_Freeze_Entity (Sloc (E));
         Set_Has_Delayed_Freeze (E);
         Set_Freeze_Node (E, FN);
         Set_Access_Types_To_Process (FN, No_Elist);
         Set_TSS_Elist (FN, No_Elist);
         Set_Entity (FN, E);
      end if;
   end Ensure_Freeze_Node;

   ----------------
   -- Enter_Name --
   ----------------

   procedure Enter_Name (Def_Id : Entity_Id) is
      C : constant Entity_Id := Current_Entity (Def_Id);
      E : constant Entity_Id := Current_Entity_In_Scope (Def_Id);
      S : constant Entity_Id := Current_Scope;

   begin
      Generate_Definition (Def_Id);

      --  Add new name to current scope declarations. Check for duplicate
      --  declaration, which may or may not be a genuine error.

      if Present (E) then

         --  Case of previous entity entered because of a missing declaration
         --  or else a bad subtype indication. Best is to use the new entity,
         --  and make the previous one invisible.

         if Etype (E) = Any_Type then
            Set_Is_Immediately_Visible (E, False);

         --  Case of renaming declaration constructed for package instances.
         --  if there is an explicit declaration with the same identifier,
         --  the renaming is not immediately visible any longer, but remains
         --  visible through selected component notation.

         elsif Nkind (Parent (E)) = N_Package_Renaming_Declaration
           and then not Comes_From_Source (E)
         then
            Set_Is_Immediately_Visible (E, False);

         --  The new entity may be the package renaming, which has the same
         --  same name as a generic formal which has been seen already.

         elsif Nkind (Parent (Def_Id)) = N_Package_Renaming_Declaration
           and then not Comes_From_Source (Def_Id)
         then
            Set_Is_Immediately_Visible (E, False);

         --  For a fat pointer corresponding to a remote access to subprogram,
         --  we use the same identifier as the RAS type, so that the proper
         --  name appears in the stub. This type is only retrieved through
         --  the RAS type and never by visibility, and is not added to the
         --  visibility list (see below).

         elsif Nkind (Parent (Def_Id)) = N_Full_Type_Declaration
           and then Ekind (Def_Id) = E_Record_Type
           and then Present (Corresponding_Remote_Type (Def_Id))
         then
            null;

         --  Case of an implicit operation or derived literal. The new entity
         --  hides the implicit one,  which is removed from all visibility,
         --  i.e. the entity list of its scope, and homonym chain of its name.

         elsif (Is_Overloadable (E) and then Is_Inherited_Operation (E))
           or else Is_Internal (E)
         then
            declare
               Decl     : constant Node_Id := Parent (E);
               Prev     : Entity_Id;
               Prev_Vis : Entity_Id;

            begin
               --  If E is an implicit declaration, it cannot be the first
               --  entity in the scope.

               Prev := First_Entity (Current_Scope);
               while Present (Prev) and then Next_Entity (Prev) /= E loop
                  Next_Entity (Prev);
               end loop;

               if No (Prev) then

                  --  If E is not on the entity chain of the current scope,
                  --  it is an implicit declaration in the generic formal
                  --  part of a generic subprogram. When analyzing the body,
                  --  the generic formals are visible but not on the entity
                  --  chain of the subprogram. The new entity will become
                  --  the visible one in the body.

                  pragma Assert
                    (Nkind (Parent (Decl)) = N_Generic_Subprogram_Declaration);
                  null;

               else
                  Link_Entities (Prev, Next_Entity (E));

                  if No (Next_Entity (Prev)) then
                     Set_Last_Entity (Current_Scope, Prev);
                  end if;

                  if E = Current_Entity (E) then
                     Prev_Vis := Empty;

                  else
                     Prev_Vis := Current_Entity (E);
                     while Homonym (Prev_Vis) /= E loop
                        Prev_Vis := Homonym (Prev_Vis);
                     end loop;
                  end if;

                  if Present (Prev_Vis) then

                     --  Skip E in the visibility chain

                     Set_Homonym (Prev_Vis, Homonym (E));

                  else
                     Set_Name_Entity_Id (Chars (E), Homonym (E));
                  end if;

                  --  The inherited operation cannot be retrieved
                  --  by name, even though it may remain accesssible
                  --  in some cases involving subprogram bodies without
                  --  specs appearing in with_clauses..

                  Set_Is_Immediately_Visible (E, False);
               end if;
            end;

         --  This section of code could use a comment ???

         elsif Present (Etype (E))
           and then Is_Concurrent_Type (Etype (E))
           and then E = Def_Id
         then
            return;

         --  If the homograph is a protected component renaming, it should not
         --  be hiding the current entity. Such renamings are treated as weak
         --  declarations.

         elsif Is_Prival (E) then
            Set_Is_Immediately_Visible (E, False);

         --  In this case the current entity is a protected component renaming.
         --  Perform minimal decoration by setting the scope and return since
         --  the prival should not be hiding other visible entities.

         elsif Is_Prival (Def_Id) then
            Set_Scope (Def_Id, Current_Scope);
            return;

         --  Analogous to privals, the discriminal generated for an entry index
         --  parameter acts as a weak declaration. Perform minimal decoration
         --  to avoid bogus errors.

         elsif Is_Discriminal (Def_Id)
           and then Ekind (Discriminal_Link (Def_Id)) = E_Entry_Index_Parameter
         then
            Set_Scope (Def_Id, Current_Scope);
            return;

         --  In the body or private part of an instance, a type extension may
         --  introduce a component with the same name as that of an actual. The
         --  legality rule is not enforced, but the semantics of the full type
         --  with two components of same name are not clear at this point???

         elsif In_Instance_Not_Visible then
            null;

         --  When compiling a package body, some child units may have become
         --  visible. They cannot conflict with local entities that hide them.

         elsif Is_Child_Unit (E)
           and then In_Open_Scopes (Scope (E))
           and then not Is_Immediately_Visible (E)
         then
            null;

         --  Conversely, with front-end inlining we may compile the parent body
         --  first, and a child unit subsequently. The context is now the
         --  parent spec, and body entities are not visible.

         elsif Is_Child_Unit (Def_Id)
           and then Is_Package_Body_Entity (E)
           and then not In_Package_Body (Current_Scope)
         then
            null;

         --  Case of genuine duplicate declaration

         else
            Error_Msg_Sloc := Sloc (E);

            --  If the previous declaration is an incomplete type declaration
            --  this may be an attempt to complete it with a private type. The
            --  following avoids confusing cascaded errors.

            if Nkind (Parent (E)) = N_Incomplete_Type_Declaration
              and then Nkind (Parent (Def_Id)) = N_Private_Type_Declaration
            then
               Error_Msg_N
                 ("incomplete type cannot be completed with a private " &
                  "declaration", Parent (Def_Id));
               Set_Is_Immediately_Visible (E, False);
               Set_Full_View (E, Def_Id);

            --  An inherited component of a record conflicts with a new
            --  discriminant. The discriminant is inserted first in the scope,
            --  but the error should be posted on it, not on the component.

            elsif Ekind (E) = E_Discriminant
              and then Present (Scope (Def_Id))
              and then Scope (Def_Id) /= Current_Scope
            then
               Error_Msg_Sloc := Sloc (Def_Id);
               Error_Msg_N ("& conflicts with declaration#", E);
               return;

            --  If the name of the unit appears in its own context clause, a
            --  dummy package with the name has already been created, and the
            --  error emitted. Try to continue quietly.

            elsif Error_Posted (E)
              and then Sloc (E) = No_Location
              and then Nkind (Parent (E)) = N_Package_Specification
              and then Current_Scope = Standard_Standard
            then
               Set_Scope (Def_Id, Current_Scope);
               return;

            else
               Error_Msg_N ("& conflicts with declaration#", Def_Id);

               --  Avoid cascaded messages with duplicate components in
               --  derived types.

               if Ekind (E) in E_Component | E_Discriminant then
                  return;
               end if;
            end if;

            if Nkind (Parent (Parent (Def_Id))) =
                                             N_Generic_Subprogram_Declaration
              and then Def_Id =
                Defining_Entity (Specification (Parent (Parent (Def_Id))))
            then
               Error_Msg_N ("\generic units cannot be overloaded", Def_Id);
            end if;

            --  If entity is in standard, then we are in trouble, because it
            --  means that we have a library package with a duplicated name.
            --  That's hard to recover from, so abort.

            if S = Standard_Standard then
               raise Unrecoverable_Error;

            --  Otherwise we continue with the declaration. Having two
            --  identical declarations should not cause us too much trouble.

            else
               null;
            end if;
         end if;
      end if;

      --  If we fall through, declaration is OK, at least OK enough to continue

      --  If Def_Id is a discriminant or a record component we are in the midst
      --  of inheriting components in a derived record definition. Preserve
      --  their Ekind and Etype.

      if Ekind (Def_Id) in E_Discriminant | E_Component then
         null;

      --  If a type is already set, leave it alone (happens when a type
      --  declaration is reanalyzed following a call to the optimizer).

      elsif Present (Etype (Def_Id)) then
         null;

      else
         Set_Etype (Def_Id, Any_Type); -- avoid cascaded errors
      end if;

      --  All entities except Itypes are immediately visible

      if not Is_Itype (Def_Id) then
         Set_Is_Immediately_Visible (Def_Id);
         Set_Current_Entity         (Def_Id);
      end if;

      Set_Homonym       (Def_Id, C);
      Append_Entity     (Def_Id, S);
      Set_Public_Status (Def_Id);

      --  Warn if new entity hides an old one

      if Warn_On_Hiding and then Present (C) then
         Warn_On_Hiding_Entity (Def_Id, Hidden => C, Visible => Def_Id,
                                On_Use_Clause => False);
      end if;
   end Enter_Name;

   ---------------
   -- Entity_Of --
   ---------------

   function Entity_Of (N : Node_Id) return Entity_Id is
      Id  : Entity_Id;
      Ren : Node_Id;

   begin
      --  Assume that the arbitrary node does not have an entity

      Id := Empty;

      if Is_Entity_Name (N) then
         Id := Entity (N);

         --  Follow a possible chain of renamings to reach the earliest renamed
         --  source object.

         while Present (Id)
           and then Is_Object (Id)
           and then Present (Renamed_Object (Id))
         loop
            Ren := Renamed_Object (Id);

            --  The reference renames an abstract state or a whole object

            --    Obj : ...;
            --    Ren : ... renames Obj;

            if Is_Entity_Name (Ren) then

               --  Do not follow a renaming that goes through a generic formal,
               --  because these entities are hidden and must not be referenced
               --  from outside the generic.

               if Is_Hidden (Entity (Ren)) then
                  exit;

               else
                  Id := Entity (Ren);
               end if;

            --  The reference renames a function result. Check the original
            --  node in case expansion relocates the function call.

            --    Ren : ... renames Func_Call;

            elsif Nkind (Original_Node (Ren)) = N_Function_Call then
               exit;

            --  Otherwise the reference renames something which does not yield
            --  an abstract state or a whole object. Treat the reference as not
            --  having a proper entity for SPARK legality purposes.

            else
               Id := Empty;
               exit;
            end if;
         end loop;
      end if;

      return Id;
   end Entity_Of;

   --------------------------
   -- Examine_Array_Bounds --
   --------------------------

   procedure Examine_Array_Bounds
     (Typ        : Entity_Id;
      All_Static : out Boolean;
      Has_Empty  : out Boolean)
   is
      function Is_OK_Static_Bound (Bound : Node_Id) return Boolean;
      --  Determine whether bound Bound is a suitable static bound

      ------------------------
      -- Is_OK_Static_Bound --
      ------------------------

      function Is_OK_Static_Bound (Bound : Node_Id) return Boolean is
      begin
         return
           not Error_Posted (Bound)
             and then Is_OK_Static_Expression (Bound);
      end Is_OK_Static_Bound;

      --  Local variables

      Hi_Bound : Node_Id;
      Index    : Node_Id;
      Lo_Bound : Node_Id;

   --  Start of processing for Examine_Array_Bounds

   begin
      --  An unconstrained array type does not have static bounds, and it is
      --  not known whether they are empty or not.

      if not Is_Constrained (Typ) then
         All_Static := False;
         Has_Empty  := False;

      --  A string literal has static bounds, and is not empty as long as it
      --  contains at least one character.

      elsif Ekind (Typ) = E_String_Literal_Subtype then
         All_Static := True;
         Has_Empty  := String_Literal_Length (Typ) > 0;
      end if;

      --  Assume that all bounds are static and not empty

      All_Static := True;
      Has_Empty  := False;

      --  Examine each index

      Index := First_Index (Typ);
      while Present (Index) loop
         if Is_Discrete_Type (Etype (Index)) then
            Get_Index_Bounds (Index, Lo_Bound, Hi_Bound);

            if Is_OK_Static_Bound (Lo_Bound)
                 and then
               Is_OK_Static_Bound (Hi_Bound)
            then
               --  The static bounds produce an empty range

               if Is_Null_Range (Lo_Bound, Hi_Bound) then
                  Has_Empty := True;
               end if;

            --  Otherwise at least one of the bounds is not static

            else
               All_Static := False;
            end if;

         --  Otherwise the index is non-discrete, therefore not static

         else
            All_Static := False;
         end if;

         Next_Index (Index);
      end loop;
   end Examine_Array_Bounds;

   -------------------
   -- Exceptions_OK --
   -------------------

   function Exceptions_OK return Boolean is
   begin
      return
        not (Restriction_Active (No_Exception_Handlers)    or else
             Restriction_Active (No_Exception_Propagation) or else
             Restriction_Active (No_Exceptions));
   end Exceptions_OK;

   --------------------------
   -- Explain_Limited_Type --
   --------------------------

   procedure Explain_Limited_Type (T : Entity_Id; N : Node_Id) is
      C : Entity_Id;

   begin
      --  For array, component type must be limited

      if Is_Array_Type (T) then
         Error_Msg_Node_2 := T;
         Error_Msg_NE
           ("\component type& of type& is limited", N, Component_Type (T));
         Explain_Limited_Type (Component_Type (T), N);

      elsif Is_Record_Type (T) then

         --  No need for extra messages if explicit limited record

         if Is_Limited_Record (Base_Type (T)) then
            return;
         end if;

         --  Otherwise find a limited component. Check only components that
         --  come from source, or inherited components that appear in the
         --  source of the ancestor.

         C := First_Component (T);
         while Present (C) loop
            if Is_Limited_Type (Etype (C))
              and then
                (Comes_From_Source (C)
                   or else
                     (Present (Original_Record_Component (C))
                       and then
                         Comes_From_Source (Original_Record_Component (C))))
            then
               Error_Msg_Node_2 := T;
               Error_Msg_NE ("\component& of type& has limited type", N, C);
               Explain_Limited_Type (Etype (C), N);
               return;
            end if;

            Next_Component (C);
         end loop;

         --  The type may be declared explicitly limited, even if no component
         --  of it is limited, in which case we fall out of the loop.
         return;
      end if;
   end Explain_Limited_Type;

   ---------------------------------------
   -- Expression_Of_Expression_Function --
   ---------------------------------------

   function Expression_Of_Expression_Function
     (Subp : Entity_Id) return Node_Id
   is
      Expr_Func : Node_Id := Empty;

   begin
      pragma Assert (Is_Expression_Function_Or_Completion (Subp));

      if Nkind (Original_Node (Subprogram_Spec (Subp))) =
           N_Expression_Function
      then
         Expr_Func := Original_Node (Subprogram_Spec (Subp));

      elsif Nkind (Original_Node (Subprogram_Body (Subp))) =
              N_Expression_Function
      then
         Expr_Func := Original_Node (Subprogram_Body (Subp));

      else
         pragma Assert (False);
         null;
      end if;

      return Original_Node (Expression (Expr_Func));
   end Expression_Of_Expression_Function;

   -------------------------------
   -- Extensions_Visible_Status --
   -------------------------------

   function Extensions_Visible_Status
     (Id : Entity_Id) return Extensions_Visible_Mode
   is
      Arg  : Node_Id;
      Decl : Node_Id;
      Expr : Node_Id;
      Prag : Node_Id;
      Subp : Entity_Id;

   begin
      --  When a formal parameter is subject to Extensions_Visible, the pragma
      --  is stored in the contract of related subprogram.

      if Is_Formal (Id) then
         Subp := Scope (Id);

      elsif Is_Subprogram_Or_Generic_Subprogram (Id) then
         Subp := Id;

      --  No other construct carries this pragma

      else
         return Extensions_Visible_None;
      end if;

      Prag := Get_Pragma (Subp, Pragma_Extensions_Visible);

      --  In certain cases analysis may request the Extensions_Visible status
      --  of an expression function before the pragma has been analyzed yet.
      --  Inspect the declarative items after the expression function looking
      --  for the pragma (if any).

      if No (Prag) and then Is_Expression_Function (Subp) then
         Decl := Next (Unit_Declaration_Node (Subp));
         while Present (Decl) loop
            if Nkind (Decl) = N_Pragma
              and then Pragma_Name (Decl) = Name_Extensions_Visible
            then
               Prag := Decl;
               exit;

            --  A source construct ends the region where Extensions_Visible may
            --  appear, stop the traversal. An expanded expression function is
            --  no longer a source construct, but it must still be recognized.

            elsif Comes_From_Source (Decl)
              or else
                (Nkind (Decl) in N_Subprogram_Body | N_Subprogram_Declaration
                  and then Is_Expression_Function (Defining_Entity (Decl)))
            then
               exit;
            end if;

            Next (Decl);
         end loop;
      end if;

      --  Extract the value from the Boolean expression (if any)

      if Present (Prag) then
         Arg := First (Pragma_Argument_Associations (Prag));

         if Present (Arg) then
            Expr := Get_Pragma_Arg (Arg);

            --  When the associated subprogram is an expression function, the
            --  argument of the pragma may not have been analyzed.

            if not Analyzed (Expr) then
               Preanalyze_And_Resolve (Expr, Standard_Boolean);
            end if;

            --  Guard against cascading errors when the argument of pragma
            --  Extensions_Visible is not a valid static Boolean expression.

            if Error_Posted (Expr) then
               return Extensions_Visible_None;

            elsif Is_True (Expr_Value (Expr)) then
               return Extensions_Visible_True;

            else
               return Extensions_Visible_False;
            end if;

         --  Otherwise the aspect or pragma defaults to True

         else
            return Extensions_Visible_True;
         end if;

      --  Otherwise aspect or pragma Extensions_Visible is not inherited or
      --  directly specified. In SPARK code, its value defaults to "False".

      elsif SPARK_Mode = On then
         return Extensions_Visible_False;

      --  In non-SPARK code, aspect or pragma Extensions_Visible defaults to
      --  "True".

      else
         return Extensions_Visible_True;
      end if;
   end Extensions_Visible_Status;

   -----------------
   -- Find_Actual --
   -----------------

   procedure Find_Actual
     (N        : Node_Id;
      Formal   : out Entity_Id;
      Call     : out Node_Id)
   is
      Context  : constant Node_Id := Parent (N);
      Actual   : Node_Id;
      Call_Nam : Node_Id;
      Call_Ent : Node_Id := Empty;

   begin
      if Nkind (Context) in N_Indexed_Component | N_Selected_Component
        and then N = Prefix (Context)
      then
         Find_Actual (Context, Formal, Call);
         return;

      elsif Nkind (Context) = N_Parameter_Association
        and then N = Explicit_Actual_Parameter (Context)
      then
         Call := Parent (Context);

      elsif Nkind (Context) in N_Entry_Call_Statement
                             | N_Function_Call
                             | N_Procedure_Call_Statement
      then
         Call := Context;

      else
         Formal := Empty;
         Call   := Empty;
         return;
      end if;

      --  If we have a call to a subprogram look for the parameter. Note that
      --  we exclude overloaded calls, since we don't know enough to be sure
      --  of giving the right answer in this case.

      if Nkind (Call) in N_Entry_Call_Statement
                       | N_Function_Call
                       | N_Procedure_Call_Statement
      then
         Call_Nam := Name (Call);

         --  A call to an entry family may appear as an indexed component

         if Nkind (Call_Nam) = N_Indexed_Component then
            Call_Nam := Prefix (Call_Nam);
         end if;

         --  A call to a protected or task entry appears as a selected
         --  component rather than an expanded name.

         if Nkind (Call_Nam) = N_Selected_Component then
            Call_Nam := Selector_Name (Call_Nam);
         end if;

         --  If Call_Nam is an entity name, get its entity

         if Is_Entity_Name (Call_Nam) then
            Call_Ent := Entity (Call_Nam);

         --  If it is a dereference, get the designated subprogram type

         elsif Nkind (Call_Nam) = N_Explicit_Dereference then
            declare
               Typ : Entity_Id := Etype (Prefix (Call_Nam));
            begin
               if Present (Full_View (Typ)) then
                  Typ := Full_View (Typ);
               elsif Is_Private_Type (Typ)
                 and then Present (Underlying_Full_View (Typ))
               then
                  Typ := Underlying_Full_View (Typ);
               end if;

               if Is_Access_Type (Typ) then
                  Call_Ent := Directly_Designated_Type (Typ);
               else
                  pragma Assert (Has_Implicit_Dereference (Typ));
                  Formal := Empty;
                  Call   := Empty;
                  return;
               end if;
            end;
         end if;

         if Present (Call_Ent)
           and then (Is_Generic_Subprogram (Call_Ent)
                      or else Is_Overloadable (Call_Ent)
                      or else Ekind (Call_Ent) in E_Entry_Family
                                                | E_Subprogram_Body
                                                | E_Subprogram_Type)
           and then not Is_Overloaded (Call_Nam)
         then
            --  If node is name in call it is not an actual

            if N = Call_Nam then
               Formal := Empty;
               Call   := Empty;
               return;
            end if;

            --  Fall here if we are definitely a parameter

            Actual := First_Actual (Call);
            Formal := First_Formal (Call_Ent);
            while Present (Formal) and then Present (Actual) loop
               if Actual = N then
                  return;

               --  An actual that is the prefix in a prefixed call may have
               --  been rewritten in the call. Check if sloc and kinds and
               --  names match.

               elsif Sloc (Actual) = Sloc (N)
                 and then Nkind (Actual) = N_Identifier
                 and then Nkind (Actual) = Nkind (N)
                 and then Chars (Actual) = Chars (N)
               then
                  return;

               else
                  Next_Actual (Actual);
                  Next_Formal (Formal);
               end if;
            end loop;
         end if;
      end if;

      --  Fall through here if we did not find matching actual

      Formal := Empty;
      Call   := Empty;
   end Find_Actual;

   ---------------------------
   -- Find_Body_Discriminal --
   ---------------------------

   function Find_Body_Discriminal
     (Spec_Discriminant : Entity_Id) return Entity_Id
   is
      Tsk  : Entity_Id;
      Disc : Entity_Id;

   begin
      --  If expansion is suppressed, then the scope can be the concurrent type
      --  itself rather than a corresponding concurrent record type.

      if Is_Concurrent_Type (Scope (Spec_Discriminant)) then
         Tsk := Scope (Spec_Discriminant);

      else
         pragma Assert (Is_Concurrent_Record_Type (Scope (Spec_Discriminant)));

         Tsk := Corresponding_Concurrent_Type (Scope (Spec_Discriminant));
      end if;

      --  Find discriminant of original concurrent type, and use its current
      --  discriminal, which is the renaming within the task/protected body.

      Disc := First_Discriminant (Tsk);
      while Present (Disc) loop
         if Chars (Disc) = Chars (Spec_Discriminant) then
            return Discriminal (Disc);
         end if;

         Next_Discriminant (Disc);
      end loop;

      --  That loop should always succeed in finding a matching entry and
      --  returning. Fatal error if not.

      raise Program_Error;
   end Find_Body_Discriminal;

   -------------------------------------
   -- Find_Corresponding_Discriminant --
   -------------------------------------

   function Find_Corresponding_Discriminant
     (Id  : Node_Id;
      Typ : Entity_Id) return Entity_Id
   is
      Par_Disc : Entity_Id;
      Old_Disc : Entity_Id;
      New_Disc : Entity_Id;

   begin
      Par_Disc := Original_Record_Component (Original_Discriminant (Id));

      --  The original type may currently be private, and the discriminant
      --  only appear on its full view.

      if Is_Private_Type (Scope (Par_Disc))
        and then not Has_Discriminants (Scope (Par_Disc))
        and then Present (Full_View (Scope (Par_Disc)))
      then
         Old_Disc := First_Discriminant (Full_View (Scope (Par_Disc)));
      else
         Old_Disc := First_Discriminant (Scope (Par_Disc));
      end if;

      if Is_Class_Wide_Type (Typ) then
         New_Disc := First_Discriminant (Root_Type (Typ));
      else
         New_Disc := First_Discriminant (Typ);
      end if;

      while Present (Old_Disc) and then Present (New_Disc) loop
         if Old_Disc = Par_Disc then
            return New_Disc;
         end if;

         Next_Discriminant (Old_Disc);
         Next_Discriminant (New_Disc);
      end loop;

      --  Should always find it

      raise Program_Error;
   end Find_Corresponding_Discriminant;

   -------------------
   -- Find_DIC_Type --
   -------------------

   function Find_DIC_Type (Typ : Entity_Id) return Entity_Id is
      Curr_Typ : Entity_Id;
      --  The current type being examined in the parent hierarchy traversal

      DIC_Typ : Entity_Id;
      --  The type which carries the DIC pragma. This variable denotes the
      --  partial view when private types are involved.

      Par_Typ : Entity_Id;
      --  The parent type of the current type. This variable denotes the full
      --  view when private types are involved.

   begin
      --  The input type defines its own DIC pragma, therefore it is the owner

      if Has_Own_DIC (Typ) then
         DIC_Typ := Typ;

      --  Otherwise the DIC pragma is inherited from a parent type

      else
         pragma Assert (Has_Inherited_DIC (Typ));

         --  Climb the parent chain

         Curr_Typ := Typ;
         loop
            --  Inspect the parent type. Do not consider subtypes as they
            --  inherit the DIC attributes from their base types.

            DIC_Typ := Base_Type (Etype (Curr_Typ));

            --  Look at the full view of a private type because the type may
            --  have a hidden parent introduced in the full view.

            Par_Typ := DIC_Typ;

            if Is_Private_Type (Par_Typ)
              and then Present (Full_View (Par_Typ))
            then
               Par_Typ := Full_View (Par_Typ);
            end if;

            --  Stop the climb once the nearest parent type which defines a DIC
            --  pragma of its own is encountered or when the root of the parent
            --  chain is reached.

            exit when Has_Own_DIC (DIC_Typ) or else Curr_Typ = Par_Typ;

            Curr_Typ := Par_Typ;
         end loop;
      end if;

      return DIC_Typ;
   end Find_DIC_Type;

   ----------------------------------
   -- Find_Enclosing_Iterator_Loop --
   ----------------------------------

   function Find_Enclosing_Iterator_Loop (Id : Entity_Id) return Entity_Id is
      Constr : Node_Id;
      S      : Entity_Id;

   begin
      --  Traverse the scope chain looking for an iterator loop. Such loops are
      --  usually transformed into blocks, hence the use of Original_Node.

      S := Id;
      while Present (S) and then S /= Standard_Standard loop
         if Ekind (S) = E_Loop
           and then Nkind (Parent (S)) = N_Implicit_Label_Declaration
         then
            Constr := Original_Node (Label_Construct (Parent (S)));

            if Nkind (Constr) = N_Loop_Statement
              and then Present (Iteration_Scheme (Constr))
              and then Nkind (Iterator_Specification
                                (Iteration_Scheme (Constr))) =
                                                 N_Iterator_Specification
            then
               return S;
            end if;
         end if;

         S := Scope (S);
      end loop;

      return Empty;
   end Find_Enclosing_Iterator_Loop;

   --------------------------
   -- Find_Enclosing_Scope --
   --------------------------

   function Find_Enclosing_Scope (N : Node_Id) return Entity_Id is
      Par : Node_Id;

   begin
      --  Examine the parent chain looking for a construct which defines a
      --  scope.

      Par := Parent (N);
      while Present (Par) loop
         case Nkind (Par) is

            --  The construct denotes a declaration, the proper scope is its
            --  entity.

            when N_Entry_Declaration
               | N_Expression_Function
               | N_Full_Type_Declaration
               | N_Generic_Package_Declaration
               | N_Generic_Subprogram_Declaration
               | N_Package_Declaration
               | N_Private_Extension_Declaration
               | N_Protected_Type_Declaration
               | N_Single_Protected_Declaration
               | N_Single_Task_Declaration
               | N_Subprogram_Declaration
               | N_Task_Type_Declaration
            =>
               return Defining_Entity (Par);

            --  The construct denotes a body, the proper scope is the entity of
            --  the corresponding spec or that of the body if the body does not
            --  complete a previous declaration.

            when N_Entry_Body
               | N_Package_Body
               | N_Protected_Body
               | N_Subprogram_Body
               | N_Task_Body
            =>
               return Unique_Defining_Entity (Par);

            --  Special cases

            --  Blocks carry either a source or an internally-generated scope,
            --  unless the block is a byproduct of exception handling.

            when N_Block_Statement =>
               if not Exception_Junk (Par) then
                  return Entity (Identifier (Par));
               end if;

            --  Loops carry an internally-generated scope

            when N_Loop_Statement =>
               return Entity (Identifier (Par));

            --  Extended return statements carry an internally-generated scope

            when N_Extended_Return_Statement =>
               return Return_Statement_Entity (Par);

            --  A traversal from a subunit continues via the corresponding stub

            when N_Subunit =>
               Par := Corresponding_Stub (Par);

            when others =>
               null;
         end case;

         Par := Parent (Par);
      end loop;

      return Standard_Standard;
   end Find_Enclosing_Scope;

   ------------------------------------
   -- Find_Loop_In_Conditional_Block --
   ------------------------------------

   function Find_Loop_In_Conditional_Block (N : Node_Id) return Node_Id is
      Stmt : Node_Id;

   begin
      Stmt := N;

      if Nkind (Stmt) = N_If_Statement then
         Stmt := First (Then_Statements (Stmt));
      end if;

      pragma Assert (Nkind (Stmt) = N_Block_Statement);

      --  Inspect the statements of the conditional block. In general the loop
      --  should be the first statement in the statement sequence of the block,
      --  but the finalization machinery may have introduced extra object
      --  declarations.

      Stmt := First (Statements (Handled_Statement_Sequence (Stmt)));
      while Present (Stmt) loop
         if Nkind (Stmt) = N_Loop_Statement then
            return Stmt;
         end if;

         Next (Stmt);
      end loop;

      --  The expansion of attribute 'Loop_Entry produced a malformed block

      raise Program_Error;
   end Find_Loop_In_Conditional_Block;

   --------------------------
   -- Find_Overlaid_Entity --
   --------------------------

   procedure Find_Overlaid_Entity
     (N   : Node_Id;
      Ent : out Entity_Id;
      Off : out Boolean)
   is
      pragma Assert
        (Nkind (N) = N_Attribute_Definition_Clause
         and then Chars (N) = Name_Address);

      Expr : Node_Id;

   begin
      --  We are looking for one of the two following forms:

      --    for X'Address use Y'Address

      --  or

      --    Const : constant Address := expr;
      --    ...
      --    for X'Address use Const;

      --  In the second case, the expr is either Y'Address, or recursively a
      --  constant that eventually references Y'Address.

      Ent := Empty;
      Off := False;

      Expr := Expression (N);

      --  This loop checks the form of the expression for Y'Address, using
      --  recursion to deal with intermediate constants.

      loop
         --  Check for Y'Address

         if Nkind (Expr) = N_Attribute_Reference
           and then Attribute_Name (Expr) = Name_Address
         then
            Expr := Prefix (Expr);
            exit;

         --  Check for Const where Const is a constant entity

         elsif Is_Entity_Name (Expr)
           and then Ekind (Entity (Expr)) = E_Constant
         then
            Expr := Constant_Value (Entity (Expr));

         --  Anything else does not need checking

         else
            return;
         end if;
      end loop;

      --  This loop checks the form of the prefix for an entity, using
      --  recursion to deal with intermediate components.

      loop
         --  Check for Y where Y is an entity

         if Is_Entity_Name (Expr) then
            Ent := Entity (Expr);

            --  If expansion is disabled, then we might see an entity of a
            --  protected component or of a discriminant of a concurrent unit.
            --  Ignore such entities, because further warnings for overlays
            --  expect this routine to only collect entities of entire objects.

            if Ekind (Ent) in E_Component | E_Discriminant then
               pragma Assert
                 (not Expander_Active
                  and then Is_Concurrent_Type (Scope (Ent)));
               Ent := Empty;
            end if;
            return;

         --  Check for components

         elsif Nkind (Expr) in N_Selected_Component | N_Indexed_Component then
            Expr := Prefix (Expr);
            Off  := True;

         --  Anything else does not need checking

         else
            return;
         end if;
      end loop;
   end Find_Overlaid_Entity;

   -------------------------
   -- Find_Parameter_Type --
   -------------------------

   function Find_Parameter_Type (Param : Node_Id) return Entity_Id is
   begin
      if Nkind (Param) /= N_Parameter_Specification then
         return Empty;

      --  For an access parameter, obtain the type from the formal entity
      --  itself, because access to subprogram nodes do not carry a type.
      --  Shouldn't we always use the formal entity ???

      elsif Nkind (Parameter_Type (Param)) = N_Access_Definition then
         return Etype (Defining_Identifier (Param));

      else
         return Etype (Parameter_Type (Param));
      end if;
   end Find_Parameter_Type;

   -----------------------------------
   -- Find_Placement_In_State_Space --
   -----------------------------------

   procedure Find_Placement_In_State_Space
     (Item_Id   : Entity_Id;
      Placement : out State_Space_Kind;
      Pack_Id   : out Entity_Id)
   is
      function Inside_Package_Body (Id : Entity_Id) return Boolean;
      function Inside_Private_Part (Id : Entity_Id) return Boolean;
      --  Return True if Id is declared directly within the package body
      --  and the package private parts, respectively. We cannot use
      --  In_Private_Part/In_Body_Part flags, as these are only set during the
      --  analysis of the package itself, while Find_Placement_In_State_Space
      --  can be called on an entity of another package.

      ------------------------
      -- Inside_Package_Body --
      ------------------------

      function Inside_Package_Body (Id : Entity_Id) return Boolean is
         Spec_Id   : constant Entity_Id := Scope (Id);
         Body_Decl : constant Opt_N_Package_Body_Id := Package_Body (Spec_Id);
         Decl      : constant Node_Id := Enclosing_Declaration (Id);
      begin
         if Present (Body_Decl)
           and then Is_List_Member (Decl)
           and then List_Containing (Decl) = Declarations (Body_Decl)
         then
            return True;
         else
            return False;
         end if;
      end Inside_Package_Body;

      -------------------------
      -- Inside_Private_Part --
      -------------------------

      function Inside_Private_Part (Id : Entity_Id) return Boolean is
         Spec_Id       : constant Entity_Id := Scope (Id);
         Private_Decls : constant List_Id :=
           Private_Declarations (Package_Specification (Spec_Id));
         Decl          : constant Node_Id := Enclosing_Declaration (Id);
      begin
         if Is_List_Member (Decl)
           and then List_Containing (Decl) = Private_Decls
         then
            return True;

         elsif Ekind (Id) = E_Package
           and then Is_Private_Library_Unit (Id)
         then
            return True;

         else
            return False;
         end if;
      end Inside_Private_Part;

      --  Local variables

      Context : Entity_Id;

   --  Start of processing for Find_Placement_In_State_Space

   begin
      --  Assume that the item does not appear in the state space of a package

      Placement := Not_In_Package;

      --  Climb the scope stack and examine the enclosing context

      Context := Item_Id;
      Pack_Id := Scope (Context);
      while Present (Pack_Id) and then Pack_Id /= Standard_Standard loop
         if Is_Package_Or_Generic_Package (Pack_Id) then

            --  A package body is a cut off point for the traversal as the
            --  item cannot be visible to the outside from this point on.

            if Inside_Package_Body (Context) then
               Placement := Body_State_Space;
               return;

            --  The private part of a package is a cut off point for the
            --  traversal as the item cannot be visible to the outside
            --  from this point on.

            elsif Inside_Private_Part (Context) then
               Placement := Private_State_Space;
               return;

            --  When the item appears in the visible state space of a package,
            --  continue to climb the scope stack as this may not be the final
            --  state space.

            else
               Placement := Visible_State_Space;

               --  The visible state space of a child unit acts as the proper
               --  placement of an item, unless this is a private child unit.

               if Is_Child_Unit (Pack_Id)
                 and then not Is_Private_Library_Unit (Pack_Id)
               then
                  return;
               end if;
            end if;

         --  The item or its enclosing package appear in a construct that has
         --  no state space.

         else
            Placement := Not_In_Package;
            Pack_Id := Empty;
            return;
         end if;

         Context := Scope (Context);
         Pack_Id := Scope (Context);
      end loop;
   end Find_Placement_In_State_Space;

   -----------------------
   -- Find_Primitive_Eq --
   -----------------------

   function Find_Primitive_Eq (Typ : Entity_Id) return Entity_Id is
      function Find_Eq_Prim (Prims_List : Elist_Id) return Entity_Id;
      --  Search for the equality primitive; return Empty if the primitive is
      --  not found.

      ------------------
      -- Find_Eq_Prim --
      ------------------

      function Find_Eq_Prim (Prims_List : Elist_Id) return Entity_Id is
         Prim      : Entity_Id;
         Prim_Elmt : Elmt_Id;

      begin
         Prim_Elmt := First_Elmt (Prims_List);
         while Present (Prim_Elmt) loop
            Prim := Node (Prim_Elmt);

            --  Locate primitive equality with the right signature

            if Chars (Prim) = Name_Op_Eq
              and then Etype (First_Formal (Prim)) =
                       Etype (Next_Formal (First_Formal (Prim)))
              and then Base_Type (Etype (Prim)) = Standard_Boolean
            then
               return Prim;
            end if;

            Next_Elmt (Prim_Elmt);
         end loop;

         return Empty;
      end Find_Eq_Prim;

      --  Local Variables

      Eq_Prim   : Entity_Id;
      Full_Type : Entity_Id;

   --  Start of processing for Find_Primitive_Eq

   begin
      if Is_Private_Type (Typ) then
         Full_Type := Underlying_Type (Typ);
      else
         Full_Type := Typ;
      end if;

      if No (Full_Type) then
         return Empty;
      end if;

      Full_Type := Base_Type (Full_Type);

      --  When the base type itself is private, use the full view

      if Is_Private_Type (Full_Type) then
         Full_Type := Underlying_Type (Full_Type);
      end if;

      if Is_Class_Wide_Type (Full_Type) then
         Full_Type := Root_Type (Full_Type);
      end if;

      if not Is_Tagged_Type (Full_Type) then
         Eq_Prim := Find_Eq_Prim (Collect_Primitive_Operations (Typ));

      --  If this is an untagged private type completed with a derivation of
      --  an untagged private type whose full view is a tagged type, we use
      --  the primitive operations of the private parent type (since it does
      --  not have a full view, and also because its equality primitive may
      --  have been overridden in its untagged full view). If no equality was
      --  defined for it then take its dispatching equality primitive.

      elsif Inherits_From_Tagged_Full_View (Typ) then
         Eq_Prim := Find_Eq_Prim (Collect_Primitive_Operations (Typ));

         if No (Eq_Prim) then
            Eq_Prim := Find_Eq_Prim (Primitive_Operations (Full_Type));
         end if;

      else
         Eq_Prim := Find_Eq_Prim (Primitive_Operations (Full_Type));
      end if;

      return Eq_Prim;
   end Find_Primitive_Eq;

   ------------------------
   -- Find_Specific_Type --
   ------------------------

   function Find_Specific_Type (CW : Entity_Id) return Entity_Id is
      Typ : Entity_Id := Root_Type (CW);

   begin
      if Ekind (Typ) = E_Incomplete_Type then
         if From_Limited_With (Typ) then
            Typ := Non_Limited_View (Typ);
         else
            Typ := Full_View (Typ);
         end if;
      end if;

      if Is_Private_Type (Typ)
        and then not Is_Tagged_Type (Typ)
        and then Present (Full_View (Typ))
      then
         return Full_View (Typ);
      else
         return Typ;
      end if;
   end Find_Specific_Type;

   -----------------------------
   -- Find_Static_Alternative --
   -----------------------------

   function Find_Static_Alternative (N : Node_Id) return Node_Id is
      Expr   : constant Node_Id := Expression (N);
      Val    : constant Uint    := Expr_Value (Expr);
      Alt    : Node_Id;
      Choice : Node_Id;

   begin
      Alt := First (Alternatives (N));

      Search : loop
         if Nkind (Alt) /= N_Pragma then
            Choice := First (Discrete_Choices (Alt));
            while Present (Choice) loop

               --  Others choice, always matches

               if Nkind (Choice) = N_Others_Choice then
                  exit Search;

               --  Range, check if value is in the range

               elsif Nkind (Choice) = N_Range then
                  exit Search when
                    Val >= Expr_Value (Low_Bound (Choice))
                      and then
                    Val <= Expr_Value (High_Bound (Choice));

               --  Choice is a subtype name. Note that we know it must
               --  be a static subtype, since otherwise it would have
               --  been diagnosed as illegal.

               elsif Is_Entity_Name (Choice)
                 and then Is_Type (Entity (Choice))
               then
                  exit Search when Is_In_Range (Expr, Etype (Choice),
                                                Assume_Valid => False);

               --  Choice is a subtype indication

               elsif Nkind (Choice) = N_Subtype_Indication then
                  declare
                     C : constant Node_Id := Constraint (Choice);
                     R : constant Node_Id := Range_Expression (C);

                  begin
                     exit Search when
                       Val >= Expr_Value (Low_Bound  (R))
                         and then
                       Val <= Expr_Value (High_Bound (R));
                  end;

               --  Choice is a simple expression

               else
                  exit Search when Val = Expr_Value (Choice);
               end if;

               Next (Choice);
            end loop;
         end if;

         Next (Alt);
         pragma Assert (Present (Alt));
      end loop Search;

      --  The above loop *must* terminate by finding a match, since we know the
      --  case statement is valid, and the value of the expression is known at
      --  compile time. When we fall out of the loop, Alt points to the
      --  alternative that we know will be selected at run time.

      return Alt;
   end Find_Static_Alternative;

   ------------------
   -- First_Actual --
   ------------------

   function First_Actual (Node : Node_Id) return Node_Id is
      N : Node_Id;

   begin
      if No (Parameter_Associations (Node)) then
         return Empty;
      end if;

      N := First (Parameter_Associations (Node));

      if Nkind (N) = N_Parameter_Association then
         return First_Named_Actual (Node);
      else
         return N;
      end if;
   end First_Actual;

   ------------------
   -- First_Global --
   ------------------

   function First_Global
     (Subp        : Entity_Id;
      Global_Mode : Name_Id;
      Refined     : Boolean := False) return Node_Id
   is
      function First_From_Global_List
        (List        : Node_Id;
         Global_Mode : Name_Id := Name_Input) return Entity_Id;
      --  Get the first item with suitable mode from List

      ----------------------------
      -- First_From_Global_List --
      ----------------------------

      function First_From_Global_List
        (List        : Node_Id;
         Global_Mode : Name_Id := Name_Input) return Entity_Id
      is
         Assoc : Node_Id;

      begin
         --  Empty list (no global items)

         if Nkind (List) = N_Null then
            return Empty;

         --  Single global item declaration (only input items)

         elsif Nkind (List) in N_Expanded_Name | N_Identifier then
            if Global_Mode = Name_Input then
               return List;
            else
               return Empty;
            end if;

         --  Simple global list (only input items) or moded global list
         --  declaration.

         elsif Nkind (List) = N_Aggregate then
            if Present (Expressions (List)) then
               if Global_Mode = Name_Input then
                  return First (Expressions (List));
               else
                  return Empty;
               end if;

            else
               Assoc := First (Component_Associations (List));
               while Present (Assoc) loop

                  --  When we find the desired mode in an association, call
                  --  recursively First_From_Global_List as if the mode was
                  --  Name_Input, in order to reuse the existing machinery
                  --  for the other cases.

                  if Chars (First (Choices (Assoc))) = Global_Mode then
                     return First_From_Global_List (Expression (Assoc));
                  end if;

                  Next (Assoc);
               end loop;

               return Empty;
            end if;

            --  To accommodate partial decoration of disabled SPARK features,
            --  this routine may be called with illegal input. If this is the
            --  case, do not raise Program_Error.

         else
            return Empty;
         end if;
      end First_From_Global_List;

      --  Local variables

      Global  : Node_Id := Empty;
      Body_Id : Entity_Id;

   --  Start of processing for First_Global

   begin
      pragma Assert (Global_Mode in Name_In_Out
                                  | Name_Input
                                  | Name_Output
                                  | Name_Proof_In);

      --  Retrieve the suitable pragma Global or Refined_Global. In the second
      --  case, it can only be located on the body entity.

      if Refined then
         if Is_Subprogram_Or_Generic_Subprogram (Subp) then
            Body_Id := Subprogram_Body_Entity (Subp);

         elsif Is_Entry (Subp) or else Is_Task_Type (Subp) then
            Body_Id := Corresponding_Body (Parent (Subp));

         --  ??? It should be possible to retrieve the Refined_Global on the
         --  task body associated to the task object. This is not yet possible.

         elsif Is_Single_Task_Object (Subp) then
            Body_Id := Empty;

         else
            Body_Id := Empty;
         end if;

         if Present (Body_Id) then
            Global := Get_Pragma (Body_Id, Pragma_Refined_Global);
         end if;
      else
         Global := Get_Pragma (Subp, Pragma_Global);
      end if;

      --  No corresponding global if pragma is not present

      if No (Global) then
         return Empty;

      --  Otherwise retrieve the corresponding list of items depending on the
      --  Global_Mode.

      else
         return First_From_Global_List
           (Expression (Get_Argument (Global, Subp)), Global_Mode);
      end if;
   end First_Global;

   -------------
   -- Fix_Msg --
   -------------

   function Fix_Msg (Id : Entity_Id; Msg : String) return String is
      Is_Task   : constant Boolean :=
                    Ekind (Id) in E_Task_Body | E_Task_Type
                      or else Is_Single_Task_Object (Id);
      Msg_Last  : constant Natural := Msg'Last;
      Msg_Index : Natural;
      Res       : String (Msg'Range) := (others => ' ');
      Res_Index : Natural;

   begin
      --  Copy all characters from the input message Msg to result Res with
      --  suitable replacements.

      Msg_Index := Msg'First;
      Res_Index := Res'First;
      while Msg_Index <= Msg_Last loop

         --  Replace "subprogram" with a different word

         if Msg_Index <= Msg_Last - 10
           and then Msg (Msg_Index .. Msg_Index + 9) = "subprogram"
         then
            if Is_Entry (Id) then
               Res (Res_Index .. Res_Index + 4) := "entry";
               Res_Index := Res_Index + 5;

            elsif Is_Task then
               Res (Res_Index .. Res_Index + 8) := "task type";
               Res_Index := Res_Index + 9;

            else
               Res (Res_Index .. Res_Index + 9) := "subprogram";
               Res_Index := Res_Index + 10;
            end if;

            Msg_Index := Msg_Index + 10;

         --  Replace "protected" with a different word

         elsif Msg_Index <= Msg_Last - 9
           and then Msg (Msg_Index .. Msg_Index + 8) = "protected"
           and then Is_Task
         then
            Res (Res_Index .. Res_Index + 3) := "task";
            Res_Index := Res_Index + 4;
            Msg_Index := Msg_Index + 9;

         --  Otherwise copy the character

         else
            Res (Res_Index) := Msg (Msg_Index);
            Msg_Index := Msg_Index + 1;
            Res_Index := Res_Index + 1;
         end if;
      end loop;

      return Res (Res'First .. Res_Index - 1);
   end Fix_Msg;

   -------------------------
   -- From_Nested_Package --
   -------------------------

   function From_Nested_Package (T : Entity_Id) return Boolean is
      Pack : constant Entity_Id := Scope (T);

   begin
      return
        Ekind (Pack) = E_Package
          and then not Is_Frozen (Pack)
          and then not Scope_Within_Or_Same (Current_Scope, Pack)
          and then In_Open_Scopes (Scope (Pack));
   end From_Nested_Package;

   -----------------------
   -- Gather_Components --
   -----------------------

   procedure Gather_Components
     (Typ                   : Entity_Id;
      Comp_List             : Node_Id;
      Governed_By           : List_Id;
      Into                  : Elist_Id;
      Report_Errors         : out Boolean;
      Allow_Compile_Time    : Boolean := False;
      Include_Interface_Tag : Boolean := False)
   is
      Assoc           : Node_Id;
      Variant         : Node_Id;
      Discrete_Choice : Node_Id;
      Comp_Item       : Node_Id;
      Discrim         : Entity_Id;
      Discrim_Name    : Node_Id;

      type Discriminant_Value_Status is
        (Static_Expr, Static_Subtype, Bad);
      subtype Good_Discrim_Value_Status is Discriminant_Value_Status
        range Static_Expr .. Static_Subtype; -- range excludes Bad

      Discrim_Value         : Node_Id;
      Discrim_Value_Subtype : Node_Id;
      Discrim_Value_Status  : Discriminant_Value_Status := Bad;

      function OK_Scope_For_Discrim_Value_Error_Messages return Boolean is
        (Scope (Original_Record_Component
                        (Entity (First (Choices (Assoc))))) = Typ);
      --  Used to avoid generating error messages having a source position
      --  which refers to somewhere (e.g., a discriminant value in a derived
      --  tagged type declaration) unrelated to the offending construct. This
      --  is required for correctness - clients of Gather_Components such as
      --  Sem_Ch3.Create_Constrained_Components depend on this function
      --  returning True while processing semantically correct examples;
      --  generating an error message in this case would be wrong.

   begin
      Report_Errors := False;

      if No (Comp_List) or else Null_Present (Comp_List) then
         return;
      end if;

      Comp_Item := First (Component_Items (Comp_List));
      while Present (Comp_Item) loop

         --  Skip the tag of a tagged record, as well as all items that are not
         --  user components (anonymous types, rep clauses, Parent field,
         --  controller field).

         if Nkind (Comp_Item) = N_Component_Declaration then
            declare
               Comp : constant Entity_Id := Defining_Identifier (Comp_Item);
            begin
               if not (Is_Tag (Comp)
                        and then not
                          (Include_Interface_Tag
                            and then Etype (Comp) = RTE (RE_Interface_Tag)))
                 and then Chars (Comp) /= Name_uParent
               then
                  Append_Elmt (Comp, Into);
               end if;
            end;
         end if;

         Next (Comp_Item);
      end loop;

      if No (Variant_Part (Comp_List)) then
         return;
      else
         Discrim_Name := Name (Variant_Part (Comp_List));
         Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
      end if;

      --  Look for the discriminant that governs this variant part.
      --  The discriminant *must* be in the Governed_By List

      Assoc := First (Governed_By);
      Find_Constraint : loop
         Discrim := First (Choices (Assoc));
         pragma Assert (No (Next (Discrim)));

         exit Find_Constraint when
           Chars (Discrim_Name) = Chars (Discrim)
             or else
               (Present (Corresponding_Discriminant (Entity (Discrim)))
                 and then Chars (Corresponding_Discriminant
                            (Entity (Discrim))) = Chars  (Discrim_Name))
             or else
               Chars (Original_Record_Component (Entity (Discrim))) =
                 Chars (Discrim_Name);

         if No (Next (Assoc)) then
            if not Is_Constrained (Typ) and then Is_Derived_Type (Typ) then

               --  If the type is a tagged type with inherited discriminants,
               --  use the stored constraint on the parent in order to find
               --  the values of discriminants that are otherwise hidden by an
               --  explicit constraint. Renamed discriminants are handled in
               --  the code above.

               --  If several parent discriminants are renamed by a single
               --  discriminant of the derived type, the call to obtain the
               --  Corresponding_Discriminant field only retrieves the last
               --  of them. We recover the constraint on the others from the
               --  Stored_Constraint as well.

               --  An inherited discriminant may have been constrained in a
               --  later ancestor (not the immediate parent) so we must examine
               --  the stored constraint of all of them to locate the inherited
               --  value.

               declare
                  C : Elmt_Id;
                  D : Entity_Id;
                  T : Entity_Id := Typ;

               begin
                  while Is_Derived_Type (T) loop
                     if Present (Stored_Constraint (T)) then
                        D := First_Discriminant (Etype (T));
                        C := First_Elmt (Stored_Constraint (T));
                        while Present (D) and then Present (C) loop
                           if Chars (Discrim_Name) = Chars (D) then
                              if Is_Entity_Name (Node (C))
                                and then Entity (Node (C)) = Entity (Discrim)
                              then
                                 --  D is renamed by Discrim, whose value is
                                 --  given in Assoc.

                                 null;

                              else
                                 Assoc :=
                                   Make_Component_Association (Sloc (Typ),
                                     New_List
                                       (New_Occurrence_Of (D, Sloc (Typ))),
                                     Duplicate_Subexpr_No_Checks (Node (C)));
                              end if;

                              exit Find_Constraint;
                           end if;

                           Next_Discriminant (D);
                           Next_Elmt (C);
                        end loop;
                     end if;

                     --  Discriminant may be inherited from ancestor

                     T := Etype (T);
                  end loop;
               end;
            end if;
         end if;

         Next (Assoc);

         if No (Assoc) then
            Error_Msg_NE
              ("missing value for discriminant&",
               First (Governed_By), Discrim_Name);

            Report_Errors := True;
            return;
         end if;
      end loop Find_Constraint;

      Discrim_Value := Expression (Assoc);

      if Is_OK_Static_Expression (Discrim_Value)
        or else (Allow_Compile_Time
                 and then Compile_Time_Known_Value (Discrim_Value))
      then
         Discrim_Value_Status := Static_Expr;
      else
         if Ada_Version >= Ada_2022 then
            if Is_Rewrite_Substitution (Discrim_Value)
               and then Nkind (Discrim_Value) = N_Type_Conversion
               and then Etype (Original_Node (Discrim_Value))
                      = Etype (Expression (Discrim_Value))
            then
               Discrim_Value_Subtype := Etype (Original_Node (Discrim_Value));
               --  An unhelpful (for this code) type conversion may be
               --  introduced in some cases; deal with it.
            else
               Discrim_Value_Subtype := Etype (Discrim_Value);
            end if;

            if Is_OK_Static_Subtype (Discrim_Value_Subtype) and then
               not Is_Null_Range (Type_Low_Bound (Discrim_Value_Subtype),
                                  Type_High_Bound (Discrim_Value_Subtype))
            then
               --  Is_Null_Range test doesn't account for predicates, as in
               --    subtype Null_By_Predicate is Natural
               --      with Static_Predicate => Null_By_Predicate < 0;
               --  so test for that null case separately.

               if not Has_Static_Predicate (Discrim_Value_Subtype)
                 or else Present (First (Static_Discrete_Predicate
                                           (Discrim_Value_Subtype)))
               then
                  Discrim_Value_Status := Static_Subtype;
               end if;
            end if;
         end if;

         if Discrim_Value_Status = Bad then

            --  If the variant part is governed by a discriminant of the type
            --  this is an error. If the variant part and the discriminant are
            --  inherited from an ancestor this is legal (AI05-220) unless the
            --  components are being gathered for an aggregate, in which case
            --  the caller must check Report_Errors.
            --
            --  In Ada 2022 the above rules are relaxed. A nonstatic governing
            --  discriminant is OK as long as it has a static subtype and
            --  every value of that subtype (and there must be at least one)
            --  selects the same variant.

            if OK_Scope_For_Discrim_Value_Error_Messages then
               if Ada_Version >= Ada_2022 then
                  Error_Msg_FE
                    ("value for discriminant & must be static or " &
                     "discriminant's nominal subtype must be static " &
                     "and non-null!",
                     Discrim_Value, Discrim);
               else
                  Error_Msg_FE
                    ("value for discriminant & must be static!",
                     Discrim_Value, Discrim);
               end if;
               Why_Not_Static (Discrim_Value);
            end if;

            Report_Errors := True;
            return;
         end if;
      end if;

      Search_For_Discriminant_Value : declare
         Low  : Node_Id;
         High : Node_Id;

         UI_High          : Uint;
         UI_Low           : Uint;
         UI_Discrim_Value : Uint;

      begin
         case Good_Discrim_Value_Status'(Discrim_Value_Status) is
            when Static_Expr =>
               UI_Discrim_Value := Expr_Value (Discrim_Value);
            when Static_Subtype =>
               --  Arbitrarily pick one value of the subtype and look
               --  for the variant associated with that value; we will
               --  check later that the same variant is associated with
               --  all of the other values of the subtype.
               if Has_Static_Predicate (Discrim_Value_Subtype) then
                  declare
                     Range_Or_Expr : constant Node_Id :=
                       First (Static_Discrete_Predicate
                                (Discrim_Value_Subtype));
                  begin
                     if Nkind (Range_Or_Expr) = N_Range then
                        UI_Discrim_Value :=
                          Expr_Value (Low_Bound (Range_Or_Expr));
                     else
                        UI_Discrim_Value := Expr_Value (Range_Or_Expr);
                     end if;
                  end;
               else
                  UI_Discrim_Value
                    := Expr_Value (Type_Low_Bound (Discrim_Value_Subtype));
               end if;
         end case;

         Find_Discrete_Value : while Present (Variant) loop

            --  If a choice is a subtype with a static predicate, it must
            --  be rewritten as an explicit list of non-predicated choices.

            Expand_Static_Predicates_In_Choices (Variant);

            Discrete_Choice := First (Discrete_Choices (Variant));
            while Present (Discrete_Choice) loop
               exit Find_Discrete_Value when
                 Nkind (Discrete_Choice) = N_Others_Choice;

               Get_Index_Bounds (Discrete_Choice, Low, High);

               UI_Low  := Expr_Value (Low);
               UI_High := Expr_Value (High);

               exit Find_Discrete_Value when
                 UI_Low <= UI_Discrim_Value
                   and then
                 UI_High >= UI_Discrim_Value;

               Next (Discrete_Choice);
            end loop;

            Next_Non_Pragma (Variant);
         end loop Find_Discrete_Value;
      end Search_For_Discriminant_Value;

      --  The case statement must include a variant that corresponds to the
      --  value of the discriminant, unless the discriminant type has a
      --  static predicate. In that case the absence of an others_choice that
      --  would cover this value becomes a run-time error (3.8.1 (21.1/2)).

      if No (Variant)
        and then not Has_Static_Predicate (Etype (Discrim_Name))
      then
         Error_Msg_NE
           ("value of discriminant & is out of range", Discrim_Value, Discrim);
         Report_Errors := True;
         return;
      end  if;

      --  If we have found the corresponding choice, recursively add its
      --  components to the Into list. The nested components are part of
      --  the same record type.

      if Present (Variant) then
         if Discrim_Value_Status = Static_Subtype then
            declare
               Discrim_Value_Subtype_Intervals
                 : constant Interval_Lists.Discrete_Interval_List
                 := Interval_Lists.Type_Intervals (Discrim_Value_Subtype);

               Variant_Intervals
                 : constant Interval_Lists.Discrete_Interval_List
                 := Interval_Lists.Choice_List_Intervals
                     (Discrete_Choices => Discrete_Choices (Variant));
            begin
               if not Interval_Lists.Is_Subset
                        (Subset => Discrim_Value_Subtype_Intervals,
                         Of_Set => Variant_Intervals)
               then
                  if OK_Scope_For_Discrim_Value_Error_Messages then
                     Error_Msg_NE
                       ("no single variant is associated with all values of " &
                        "the subtype of discriminant value &",
                        Discrim_Value, Discrim);
                  end if;
                  Report_Errors := True;
                  return;
               end if;
            end;
         end if;

         Gather_Components
           (Typ, Component_List (Variant), Governed_By, Into,
            Report_Errors, Allow_Compile_Time);
      end if;
   end Gather_Components;

   ------------------------
   -- Get_Actual_Subtype --
   ------------------------

   function Get_Actual_Subtype (N : Node_Id) return Entity_Id is
      Typ  : constant Entity_Id := Etype (N);
      Utyp : Entity_Id := Underlying_Type (Typ);
      Decl : Node_Id;
      Atyp : Entity_Id;

   begin
      if No (Utyp) then
         Utyp := Typ;
      end if;

      --  If what we have is an identifier that references a subprogram
      --  formal, or a variable or constant object, then we get the actual
      --  subtype from the referenced entity if one has been built.

      if Nkind (N) = N_Identifier
        and then
          (Is_Formal (Entity (N))
            or else Ekind (Entity (N)) = E_Constant
            or else Ekind (Entity (N)) = E_Variable)
        and then Present (Actual_Subtype (Entity (N)))
      then
         return Actual_Subtype (Entity (N));

      --  Similarly, if we have an explicit dereference, then we get the
      --  actual subtype from the node itself if one has been built.

      elsif Nkind (N) = N_Explicit_Dereference
        and then Present (Actual_Designated_Subtype (N))
      then
         return Actual_Designated_Subtype (N);

      --  Actual subtype of unchecked union is always itself. We never need
      --  the "real" actual subtype. If we did, we couldn't get it anyway
      --  because the discriminant is not available. The restrictions on
      --  Unchecked_Union are designed to make sure that this is OK.

      elsif Is_Unchecked_Union (Base_Type (Utyp)) then
         return Typ;

      --  Here for the unconstrained case, we must find actual subtype
      --  No actual subtype is available, so we must build it on the fly.

      --  Checking the type, not the underlying type, for constrainedness
      --  seems to be necessary. Maybe all the tests should be on the type???

      elsif not Is_Constrained (Typ)
           and then (Is_Array_Type (Utyp)
                      or else (Is_Record_Type (Utyp)
                                and then Has_Discriminants (Utyp)))
           and then not Has_Unknown_Discriminants (Utyp)
           and then not (Ekind (Utyp) = E_String_Literal_Subtype)
      then
         --  Nothing to do if in spec expression (why not???)

         if In_Spec_Expression then
            return Typ;

         elsif Is_Private_Type (Typ) and then not Has_Discriminants (Typ) then

            --  If the type has no discriminants, there is no subtype to
            --  build, even if the underlying type is discriminated.

            return Typ;

         --  Else build the actual subtype

         else
            Decl := Build_Actual_Subtype (Typ, N);

            --  The call may yield a declaration, or just return the entity

            if Decl = Typ then
               return Typ;
            end if;

            Atyp := Defining_Identifier (Decl);

            --  If Build_Actual_Subtype generated a new declaration then use it

            if Atyp /= Typ then

               --  The actual subtype is an Itype, so analyze the declaration,
               --  but do not attach it to the tree, to get the type defined.

               Set_Parent (Decl, N);
               Set_Is_Itype (Atyp);
               Analyze (Decl, Suppress => All_Checks);
               Set_Associated_Node_For_Itype (Atyp, N);
               if Expander_Active then
                  Set_Has_Delayed_Freeze (Atyp, False);

                  --  We need to freeze the actual subtype immediately. This is
                  --  needed because otherwise this Itype will not get frozen
                  --  at all; it is always safe to freeze on creation because
                  --  any associated types must be frozen at this point.

                  --  On the other hand, if we are performing preanalysis on
                  --  a conjured-up copy of a name (see calls to
                  --  Preanalyze_Range in sem_ch5.adb) then we don't want
                  --  to freeze Atyp, now or ever. In this case, the tree
                  --  we eventually pass to the back end should contain no
                  --  references to Atyp (and a freeze node would contain
                  --  such a reference). That's why Expander_Active is tested.

                  Freeze_Itype (Atyp, N);
               end if;
               return Atyp;

            --  Otherwise we did not build a declaration, so return original

            else
               return Typ;
            end if;
         end if;

      --  For all remaining cases, the actual subtype is the same as
      --  the nominal type.

      else
         return Typ;
      end if;
   end Get_Actual_Subtype;

   -------------------------------------
   -- Get_Actual_Subtype_If_Available --
   -------------------------------------

   function Get_Actual_Subtype_If_Available (N : Node_Id) return Entity_Id is
      Typ : constant Entity_Id := Etype (N);

   begin
      --  If what we have is an identifier that references a subprogram
      --  formal, or a variable or constant object, then we get the actual
      --  subtype from the referenced entity if one has been built.

      if Nkind (N) = N_Identifier
        and then
          (Is_Formal (Entity (N))
            or else Ekind (Entity (N)) = E_Constant
            or else Ekind (Entity (N)) = E_Variable)
        and then Present (Actual_Subtype (Entity (N)))
      then
         return Actual_Subtype (Entity (N));

      --  Similarly, if we have an explicit dereference, then we get the
      --  actual subtype from the node itself if one has been built.

      elsif Nkind (N) = N_Explicit_Dereference
        and then Present (Actual_Designated_Subtype (N))
      then
         return Actual_Designated_Subtype (N);

      --  Otherwise the Etype of N is returned unchanged

      else
         return Typ;
      end if;
   end Get_Actual_Subtype_If_Available;

   ------------------------
   -- Get_Body_From_Stub --
   ------------------------

   function Get_Body_From_Stub (N : Node_Id) return Node_Id is
   begin
      return Proper_Body (Unit (Library_Unit (N)));
   end Get_Body_From_Stub;

   ---------------------
   -- Get_Cursor_Type --
   ---------------------

   function Get_Cursor_Type
     (Aspect : Node_Id;
      Typ    : Entity_Id) return Entity_Id
   is
      Assoc    : Node_Id;
      Func     : Entity_Id;
      First_Op : Entity_Id;
      Cursor   : Entity_Id;

   begin
      --  If error already detected, return

      if Error_Posted (Aspect) then
         return Any_Type;
      end if;

      --  The cursor type for an Iterable aspect is the return type of a
      --  non-overloaded First primitive operation. Locate association for
      --  First.

      Assoc := First (Component_Associations (Expression (Aspect)));
      First_Op := Any_Id;
      while Present (Assoc) loop
         if Chars (First (Choices (Assoc))) = Name_First then
            First_Op := Expression (Assoc);
            exit;
         end if;

         Next (Assoc);
      end loop;

      if First_Op = Any_Id then
         Error_Msg_N ("aspect Iterable must specify First operation", Aspect);
         return Any_Type;

      elsif not Analyzed (First_Op) then
         Analyze (First_Op);
      end if;

      Cursor := Any_Type;

      --  Locate function with desired name and profile in scope of type
      --  In the rare case where the type is an integer type, a base type
      --  is created for it, check that the base type of the first formal
      --  of First matches the base type of the domain.

      Func := First_Entity (Scope (Typ));
      while Present (Func) loop
         if Chars (Func) = Chars (First_Op)
           and then Ekind (Func) = E_Function
           and then Present (First_Formal (Func))
           and then Base_Type (Etype (First_Formal (Func))) = Base_Type (Typ)
           and then No (Next_Formal (First_Formal (Func)))
         then
            if Cursor /= Any_Type then
               Error_Msg_N
                 ("operation First for iterable type must be unique", Aspect);
               return Any_Type;
            else
               Cursor := Etype (Func);
            end if;
         end if;

         Next_Entity (Func);
      end loop;

      --  If not found, no way to resolve remaining primitives

      if Cursor = Any_Type then
         Error_Msg_N
           ("primitive operation for Iterable type must appear in the same "
            & "list of declarations as the type", Aspect);
      end if;

      return Cursor;
   end Get_Cursor_Type;

   function Get_Cursor_Type (Typ : Entity_Id) return Entity_Id is
   begin
      return Etype (Get_Iterable_Type_Primitive (Typ, Name_First));
   end Get_Cursor_Type;

   -------------------------------
   -- Get_Default_External_Name --
   -------------------------------

   function Get_Default_External_Name (E : Node_Or_Entity_Id) return Node_Id is
   begin
      Get_Decoded_Name_String (Chars (E));

      if Opt.External_Name_Imp_Casing = Uppercase then
         Set_Casing (All_Upper_Case);
      else
         Set_Casing (All_Lower_Case);
      end if;

      return
        Make_String_Literal (Sloc (E),
          Strval => String_From_Name_Buffer);
   end Get_Default_External_Name;

   --------------------------
   -- Get_Enclosing_Object --
   --------------------------

   function Get_Enclosing_Object (N : Node_Id) return Entity_Id is
   begin
      if Is_Entity_Name (N) then
         return Entity (N);
      else
         case Nkind (N) is
            when N_Indexed_Component
               | N_Selected_Component
               | N_Slice
            =>
               --  If not generating code, a dereference may be left implicit.
               --  In thoses cases, return Empty.

               if Is_Access_Type (Etype (Prefix (N))) then
                  return Empty;
               else
                  return Get_Enclosing_Object (Prefix (N));
               end if;

            when N_Type_Conversion =>
               return Get_Enclosing_Object (Expression (N));

            when others =>
               return Empty;
         end case;
      end if;
   end Get_Enclosing_Object;

   -------------------------------
   -- Get_Enclosing_Deep_Object --
   -------------------------------

   function Get_Enclosing_Deep_Object (N : Node_Id) return Entity_Id is
   begin
      if Is_Entity_Name (N) then
         return Entity (N);
      else
         case Nkind (N) is
            when N_Explicit_Dereference
               | N_Indexed_Component
               | N_Selected_Component
               | N_Slice
            =>
               return Get_Enclosing_Deep_Object (Prefix (N));

            when N_Type_Conversion =>
               return Get_Enclosing_Deep_Object (Expression (N));

            when others =>
               return Empty;
         end case;
      end if;
   end Get_Enclosing_Deep_Object;

   ---------------------------
   -- Get_Enum_Lit_From_Pos --
   ---------------------------

   function Get_Enum_Lit_From_Pos
     (T   : Entity_Id;
      Pos : Uint;
      Loc : Source_Ptr) return Node_Id
   is
      Btyp : Entity_Id := Base_Type (T);
      Lit  : Node_Id;
      LLoc : Source_Ptr;

   begin
      --  In the case where the literal is of type Character, Wide_Character
      --  or Wide_Wide_Character or of a type derived from them, there needs
      --  to be some special handling since there is no explicit chain of
      --  literals to search. Instead, an N_Character_Literal node is created
      --  with the appropriate Char_Code and Chars fields.

      if Is_Standard_Character_Type (T) then
         Set_Character_Literal_Name (UI_To_CC (Pos));

         return
           Make_Character_Literal (Loc,
             Chars              => Name_Find,
             Char_Literal_Value => Pos);

      --  For all other cases, we have a complete table of literals, and
      --  we simply iterate through the chain of literal until the one
      --  with the desired position value is found.

      else
         if Is_Private_Type (Btyp) and then Present (Full_View (Btyp)) then
            Btyp := Full_View (Btyp);
         end if;

         Lit := First_Literal (Btyp);

         --  Position in the enumeration type starts at 0

         if Pos < 0 then
            raise Constraint_Error;
         end if;

         for J in 1 .. UI_To_Int (Pos) loop
            Next_Literal (Lit);

            --  If Lit is Empty, Pos is not in range, so raise Constraint_Error
            --  inside the loop to avoid calling Next_Literal on Empty.

            if No (Lit) then
               raise Constraint_Error;
            end if;
         end loop;

         --  Create a new node from Lit, with source location provided by Loc
         --  if not equal to No_Location, or by copying the source location of
         --  Lit otherwise.

         LLoc := Loc;

         if LLoc = No_Location then
            LLoc := Sloc (Lit);
         end if;

         return New_Occurrence_Of (Lit, LLoc);
      end if;
   end Get_Enum_Lit_From_Pos;

   ----------------------
   -- Get_Fullest_View --
   ----------------------

   function Get_Fullest_View
     (E           : Entity_Id;
      Include_PAT : Boolean := True;
      Recurse     : Boolean := True) return Entity_Id
   is
      New_E : Entity_Id := Empty;

   begin
      --  Prevent cascaded errors

      if No (E) then
         return E;
      end if;

      --  Look at each kind of entity to see where we may need to go deeper.

      case Ekind (E) is
         when Incomplete_Kind =>
            if From_Limited_With (E) then
               New_E := Non_Limited_View (E);
            elsif Present (Full_View (E)) then
               New_E := Full_View (E);
            elsif Ekind (E) = E_Incomplete_Subtype then
               New_E := Etype (E);
            end if;

         when Private_Kind =>
            if Present (Underlying_Full_View (E)) then
               New_E := Underlying_Full_View (E);
            elsif Present (Full_View (E)) then
               New_E := Full_View (E);
            elsif Etype (E) /= E then
               New_E := Etype (E);
            end if;

         when Array_Kind =>
            if Include_PAT and then Present (Packed_Array_Impl_Type (E)) then
               New_E := Packed_Array_Impl_Type (E);
            end if;

         when E_Record_Subtype =>
            if Present (Cloned_Subtype (E)) then
               New_E := Cloned_Subtype (E);
            end if;

         when E_Class_Wide_Type =>
            New_E := Root_Type (E);

         when E_Class_Wide_Subtype =>
            if Present (Equivalent_Type (E)) then
               New_E := Equivalent_Type (E);
            elsif Present (Cloned_Subtype (E)) then
               New_E := Cloned_Subtype (E);
            end if;

         when E_Protected_Subtype
            | E_Protected_Type
            | E_Task_Subtype
            | E_Task_Type
         =>
            if Present (Corresponding_Record_Type (E)) then
               New_E := Corresponding_Record_Type (E);
            end if;

         when E_Access_Protected_Subprogram_Type
            | E_Anonymous_Access_Protected_Subprogram_Type
         =>
            if Present (Equivalent_Type (E)) then
               New_E := Equivalent_Type (E);
            end if;

         when E_Access_Subtype =>
            New_E := Base_Type (E);

         when others =>
            null;
      end case;

      --  If we found a fuller view, either return it or recurse. Otherwise,
      --  return our input.

      return (if    No (New_E) then E
              elsif Recurse then Get_Fullest_View (New_E, Include_PAT, Recurse)
              else  New_E);
   end Get_Fullest_View;

   ------------------------
   -- Get_Generic_Entity --
   ------------------------

   function Get_Generic_Entity (N : Node_Id) return Entity_Id is
      Ent : constant Entity_Id := Entity (Name (N));
   begin
      if Present (Renamed_Entity (Ent)) then
         return Renamed_Entity (Ent);
      else
         return Ent;
      end if;
   end Get_Generic_Entity;

   -------------------------------------
   -- Get_Incomplete_View_Of_Ancestor --
   -------------------------------------

   function Get_Incomplete_View_Of_Ancestor (E : Entity_Id) return Entity_Id is
      Cur_Unit  : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
      Par_Scope : Entity_Id;
      Par_Type  : Entity_Id;

   begin
      --  The incomplete view of an ancestor is only relevant for private
      --  derived types in child units.

      if not Is_Derived_Type (E)
        or else not Is_Child_Unit (Cur_Unit)
      then
         return Empty;

      else
         Par_Scope := Scope (Cur_Unit);
         if No (Par_Scope) then
            return Empty;
         end if;

         Par_Type := Etype (Base_Type (E));

         --  Traverse list of ancestor types until we find one declared in
         --  a parent or grandparent unit (two levels seem sufficient).

         while Present (Par_Type) loop
            if Scope (Par_Type) = Par_Scope
              or else Scope (Par_Type) = Scope (Par_Scope)
            then
               return Par_Type;

            elsif not Is_Derived_Type (Par_Type) then
               return Empty;

            else
               Par_Type := Etype (Base_Type (Par_Type));
            end if;
         end loop;

         --  If none found, there is no relevant ancestor type.

         return Empty;
      end if;
   end Get_Incomplete_View_Of_Ancestor;

   ----------------------
   -- Get_Index_Bounds --
   ----------------------

   procedure Get_Index_Bounds
     (N             : Node_Id;
      L             : out Node_Id;
      H             : out Node_Id;
      Use_Full_View : Boolean := False)
   is
      function Scalar_Range_Of_Type (Typ : Entity_Id) return Node_Id;
      --  Obtain the scalar range of type Typ. If flag Use_Full_View is set and
      --  Typ qualifies, the scalar range is obtained from the full view of the
      --  type.

      --------------------------
      -- Scalar_Range_Of_Type --
      --------------------------

      function Scalar_Range_Of_Type (Typ : Entity_Id) return Node_Id is
         T : Entity_Id := Typ;

      begin
         if Use_Full_View and then Present (Full_View (T)) then
            T := Full_View (T);
         end if;

         return Scalar_Range (T);
      end Scalar_Range_Of_Type;

      --  Local variables

      Kind : constant Node_Kind := Nkind (N);
      Rng  : Node_Id;

   --  Start of processing for Get_Index_Bounds

   begin
      if Kind = N_Range then
         L := Low_Bound (N);
         H := High_Bound (N);

      elsif Kind = N_Subtype_Indication then
         Rng := Range_Expression (Constraint (N));

         if Rng = Error then
            L := Error;
            H := Error;
            return;

         else
            L := Low_Bound  (Range_Expression (Constraint (N)));
            H := High_Bound (Range_Expression (Constraint (N)));
         end if;

      elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
         Rng := Scalar_Range_Of_Type (Entity (N));

         if Error_Posted (Rng) then
            L := Error;
            H := Error;

         elsif Nkind (Rng) = N_Subtype_Indication then
            Get_Index_Bounds (Rng, L, H);

         else
            L := Low_Bound  (Rng);
            H := High_Bound (Rng);
         end if;

      else
         --  N is an expression, indicating a range with one value

         L := N;
         H := N;
      end if;
   end Get_Index_Bounds;

   function Get_Index_Bounds
     (N             : Node_Id;
      Use_Full_View : Boolean := False) return Range_Nodes is
      Result : Range_Nodes;
   begin
      Get_Index_Bounds (N, Result.First, Result.Last, Use_Full_View);
      return Result;
   end Get_Index_Bounds;

   function Get_Index_Bounds
     (N             : Node_Id;
      Use_Full_View : Boolean := False) return Range_Values is
      Nodes : constant Range_Nodes := Get_Index_Bounds (N, Use_Full_View);
   begin
      return (Expr_Value (Nodes.First), Expr_Value (Nodes.Last));
   end Get_Index_Bounds;

   -----------------------------
   -- Get_Interfacing_Aspects --
   -----------------------------

   procedure Get_Interfacing_Aspects
     (Iface_Asp : Node_Id;
      Conv_Asp  : out Node_Id;
      EN_Asp    : out Node_Id;
      Expo_Asp  : out Node_Id;
      Imp_Asp   : out Node_Id;
      LN_Asp    : out Node_Id;
      Do_Checks : Boolean := False)
   is
      procedure Save_Or_Duplication_Error
        (Asp : Node_Id;
         To  : in out Node_Id);
      --  Save the value of aspect Asp in node To. If To already has a value,
      --  then this is considered a duplicate use of aspect. Emit an error if
      --  flag Do_Checks is set.

      -------------------------------
      -- Save_Or_Duplication_Error --
      -------------------------------

      procedure Save_Or_Duplication_Error
        (Asp : Node_Id;
         To  : in out Node_Id)
      is
      begin
         --  Detect an extra aspect and issue an error

         if Present (To) then
            if Do_Checks then
               Error_Msg_Name_1 := Chars (Identifier (Asp));
               Error_Msg_Sloc   := Sloc (To);
               Error_Msg_N ("aspect % previously given #", Asp);
            end if;

         --  Otherwise capture the aspect

         else
            To := Asp;
         end if;
      end Save_Or_Duplication_Error;

      --  Local variables

      Asp    : Node_Id;
      Asp_Id : Aspect_Id;

      --  The following variables capture each individual aspect

      Conv : Node_Id := Empty;
      EN   : Node_Id := Empty;
      Expo : Node_Id := Empty;
      Imp  : Node_Id := Empty;
      LN   : Node_Id := Empty;

   --  Start of processing for Get_Interfacing_Aspects

   begin
      --  The input interfacing aspect should reside in an aspect specification
      --  list.

      pragma Assert (Is_List_Member (Iface_Asp));

      --  Examine the aspect specifications of the related entity. Find and
      --  capture all interfacing aspects. Detect duplicates and emit errors
      --  if applicable.

      Asp := First (List_Containing (Iface_Asp));
      while Present (Asp) loop
         Asp_Id := Get_Aspect_Id (Asp);

         if Asp_Id = Aspect_Convention then
            Save_Or_Duplication_Error (Asp, Conv);

         elsif Asp_Id = Aspect_External_Name then
            Save_Or_Duplication_Error (Asp, EN);

         elsif Asp_Id = Aspect_Export then
            Save_Or_Duplication_Error (Asp, Expo);

         elsif Asp_Id = Aspect_Import then
            Save_Or_Duplication_Error (Asp, Imp);

         elsif Asp_Id = Aspect_Link_Name then
            Save_Or_Duplication_Error (Asp, LN);
         end if;

         Next (Asp);
      end loop;

      Conv_Asp := Conv;
      EN_Asp   := EN;
      Expo_Asp := Expo;
      Imp_Asp  := Imp;
      LN_Asp   := LN;
   end Get_Interfacing_Aspects;

   ---------------------------------
   -- Get_Iterable_Type_Primitive --
   ---------------------------------

   function Get_Iterable_Type_Primitive
     (Typ : Entity_Id;
      Nam : Name_Id) return Entity_Id
   is
      pragma Assert
        (Is_Type (Typ)
         and then
           Nam in Name_Element
                | Name_First
                | Name_Has_Element
                | Name_Last
                | Name_Next
                | Name_Previous);

      Funcs : constant Node_Id := Find_Value_Of_Aspect (Typ, Aspect_Iterable);
      Assoc : Node_Id;

   begin
      if No (Funcs) then
         return Empty;

      else
         Assoc := First (Component_Associations (Funcs));
         while Present (Assoc) loop
            if Chars (First (Choices (Assoc))) = Nam then
               return Entity (Expression (Assoc));
            end if;

            Next (Assoc);
         end loop;

         return Empty;
      end if;
   end Get_Iterable_Type_Primitive;

   ---------------------------
   -- Get_Library_Unit_Name --
   ---------------------------

   function Get_Library_Unit_Name (Decl_Node : Node_Id) return String_Id is
      Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
      Buf : Bounded_String;
   begin
      Get_Unit_Name_String (Buf, Unit_Name_Id);

      --  Remove the last seven characters (" (spec)" or " (body)")

      Buf.Length := Buf.Length - 7;
      pragma Assert (Buf.Chars (Buf.Length + 1) = ' ');

      return String_From_Name_Buffer (Buf);
   end Get_Library_Unit_Name;

   --------------------------
   -- Get_Max_Queue_Length --
   --------------------------

   function Get_Max_Queue_Length (Id : Entity_Id) return Uint is
      pragma Assert (Is_Entry (Id));
      Prag : constant Entity_Id := Get_Pragma (Id, Pragma_Max_Queue_Length);
      Max  : Uint;

   begin
      --  A value of 0 or -1 represents no maximum specified, and entries and
      --  entry families with no Max_Queue_Length aspect or pragma default to
      --  it.

      if No (Prag) then
         return Uint_0;
      end if;

      Max := Expr_Value
        (Expression (First (Pragma_Argument_Associations (Prag))));

      --  Since -1 and 0 are equivalent, return 0 for instances of -1 for
      --  uniformity.

      if Max = -1 then
         return Uint_0;
      end if;

      return Max;
   end Get_Max_Queue_Length;

   ------------------------
   -- Get_Name_Entity_Id --
   ------------------------

   function Get_Name_Entity_Id (Id : Name_Id) return Entity_Id is
   begin
      return Entity_Id (Get_Name_Table_Int (Id));
   end Get_Name_Entity_Id;

   ------------------------------
   -- Get_Name_From_CTC_Pragma --
   ------------------------------

   function Get_Name_From_CTC_Pragma (N : Node_Id) return String_Id is
      Arg : constant Node_Id :=
              Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
   begin
      return Strval (Expr_Value_S (Arg));
   end Get_Name_From_CTC_Pragma;

   -----------------------
   -- Get_Parent_Entity --
   -----------------------

   function Get_Parent_Entity (Unit : Node_Id) return Entity_Id is
   begin
      if Nkind (Unit) = N_Package_Body
        and then Nkind (Original_Node (Unit)) = N_Package_Instantiation
      then
         return Defining_Entity
                  (Specification (Instance_Spec (Original_Node (Unit))));
      elsif Nkind (Unit) = N_Package_Instantiation then
         return Defining_Entity (Specification (Instance_Spec (Unit)));
      else
         return Defining_Entity (Unit);
      end if;
   end Get_Parent_Entity;

   -------------------
   -- Get_Pragma_Id --
   -------------------

   function Get_Pragma_Id (N : Node_Id) return Pragma_Id is
   begin
      return Get_Pragma_Id (Pragma_Name_Unmapped (N));
   end Get_Pragma_Id;

   ------------------------
   -- Get_Qualified_Name --
   ------------------------

   function Get_Qualified_Name
     (Id     : Entity_Id;
      Suffix : Entity_Id := Empty) return Name_Id
   is
      Suffix_Nam : Name_Id := No_Name;

   begin
      if Present (Suffix) then
         Suffix_Nam := Chars (Suffix);
      end if;

      return Get_Qualified_Name (Chars (Id), Suffix_Nam, Scope (Id));
   end Get_Qualified_Name;

   function Get_Qualified_Name
     (Nam    : Name_Id;
      Suffix : Name_Id   := No_Name;
      Scop   : Entity_Id := Current_Scope) return Name_Id
   is
      procedure Add_Scope (S : Entity_Id);
      --  Add the fully qualified form of scope S to the name buffer. The
      --  format is:
      --    s-1__s__

      ---------------
      -- Add_Scope --
      ---------------

      procedure Add_Scope (S : Entity_Id) is
      begin
         if S = Empty then
            null;

         elsif S = Standard_Standard then
            null;

         else
            Add_Scope (Scope (S));
            Get_Name_String_And_Append (Chars (S));
            Add_Str_To_Name_Buffer ("__");
         end if;
      end Add_Scope;

   --  Start of processing for Get_Qualified_Name

   begin
      Name_Len := 0;
      Add_Scope (Scop);

      --  Append the base name after all scopes have been chained

      Get_Name_String_And_Append (Nam);

      --  Append the suffix (if present)

      if Suffix /= No_Name then
         Add_Str_To_Name_Buffer ("__");
         Get_Name_String_And_Append (Suffix);
      end if;

      return Name_Find;
   end Get_Qualified_Name;

   -----------------------
   -- Get_Reason_String --
   -----------------------

   procedure Get_Reason_String (N : Node_Id) is
   begin
      if Nkind (N) = N_String_Literal then
         Store_String_Chars (Strval (N));

      elsif Nkind (N) = N_Op_Concat then
         Get_Reason_String (Left_Opnd (N));
         Get_Reason_String (Right_Opnd (N));

      --  If not of required form, error

      else
         Error_Msg_N
           ("Reason for pragma Warnings has wrong form", N);
         Error_Msg_N
           ("\must be string literal or concatenation of string literals", N);
         return;
      end if;
   end Get_Reason_String;

   --------------------------------
   -- Get_Reference_Discriminant --
   --------------------------------

   function Get_Reference_Discriminant (Typ : Entity_Id) return Entity_Id is
      D : Entity_Id;

   begin
      D := First_Discriminant (Typ);
      while Present (D) loop
         if Has_Implicit_Dereference (D) then
            return D;
         end if;
         Next_Discriminant (D);
      end loop;

      return Empty;
   end Get_Reference_Discriminant;

   ---------------------------
   -- Get_Referenced_Object --
   ---------------------------

   function Get_Referenced_Object (N : Node_Id) return Node_Id is
      R : Node_Id;

   begin
      R := N;
      while Is_Entity_Name (R)
        and then Is_Object (Entity (R))
        and then Present (Renamed_Object (Entity (R)))
      loop
         R := Renamed_Object (Entity (R));
      end loop;

      return R;
   end Get_Referenced_Object;

   ------------------------
   -- Get_Renamed_Entity --
   ------------------------

   function Get_Renamed_Entity (E : Entity_Id) return Entity_Id is
      R : Entity_Id := E;
   begin
      while Present (Renamed_Entity (R)) loop
         R := Renamed_Entity (R);
      end loop;

      return R;
   end Get_Renamed_Entity;

   -----------------------
   -- Get_Return_Object --
   -----------------------

   function Get_Return_Object (N : Node_Id) return Entity_Id is
      Decl : Node_Id;

   begin
      Decl := First (Return_Object_Declarations (N));
      while Present (Decl) loop
         exit when Nkind (Decl) = N_Object_Declaration
           and then Is_Return_Object (Defining_Identifier (Decl));
         Next (Decl);
      end loop;

      pragma Assert (Present (Decl));
      return Defining_Identifier (Decl);
   end Get_Return_Object;

   ---------------------------
   -- Get_Subprogram_Entity --
   ---------------------------

   function Get_Subprogram_Entity (Nod : Node_Id) return Entity_Id is
      Subp    : Node_Id;
      Subp_Id : Entity_Id;

   begin
      if Nkind (Nod) = N_Accept_Statement then
         Subp := Entry_Direct_Name (Nod);

      elsif Nkind (Nod) = N_Slice then
         Subp := Prefix (Nod);

      else
         Subp := Name (Nod);
      end if;

      --  Strip the subprogram call

      loop
         if Nkind (Subp) in N_Explicit_Dereference
                          | N_Indexed_Component
                          | N_Selected_Component
         then
            Subp := Prefix (Subp);

         elsif Nkind (Subp) in N_Type_Conversion
                             | N_Unchecked_Type_Conversion
         then
            Subp := Expression (Subp);

         else
            exit;
         end if;
      end loop;

      --  Extract the entity of the subprogram call

      if Is_Entity_Name (Subp) then
         Subp_Id := Entity (Subp);

         if Ekind (Subp_Id) = E_Access_Subprogram_Type then
            Subp_Id := Directly_Designated_Type (Subp_Id);
         end if;

         if Is_Subprogram (Subp_Id) then
            return Subp_Id;
         else
            return Empty;
         end if;

      --  The search did not find a construct that denotes a subprogram

      else
         return Empty;
      end if;
   end Get_Subprogram_Entity;

   -----------------------------
   -- Get_Task_Body_Procedure --
   -----------------------------

   function Get_Task_Body_Procedure (E : Entity_Id) return Entity_Id is
   begin
      --  Note: A task type may be the completion of a private type with
      --  discriminants. When performing elaboration checks on a task
      --  declaration, the current view of the type may be the private one,
      --  and the procedure that holds the body of the task is held in its
      --  underlying type.

      --  This is an odd function, why not have Task_Body_Procedure do
      --  the following digging???

      return Task_Body_Procedure (Underlying_Type (Root_Type (E)));
   end Get_Task_Body_Procedure;

   -------------------------------
   -- Get_User_Defined_Equality --
   -------------------------------

   function Get_User_Defined_Equality (E : Entity_Id) return Entity_Id is
      Prim : Elmt_Id;

   begin
      Prim := First_Elmt (Collect_Primitive_Operations (E));
      while Present (Prim) loop
         if Is_User_Defined_Equality (Node (Prim)) then
            return Node (Prim);
         end if;

         Next_Elmt (Prim);
      end loop;

      return Empty;
   end Get_User_Defined_Equality;

   ---------------
   -- Get_Views --
   ---------------

   procedure Get_Views
     (Typ       : Entity_Id;
      Priv_Typ  : out Entity_Id;
      Full_Typ  : out Entity_Id;
      UFull_Typ : out Entity_Id;
      CRec_Typ  : out Entity_Id)
   is
      IP_View : Entity_Id;

   begin
      --  Assume that none of the views can be recovered

      Priv_Typ  := Empty;
      Full_Typ  := Empty;
      UFull_Typ := Empty;
      CRec_Typ  := Empty;

      --  The input type is the corresponding record type of a protected or a
      --  task type.

      if Ekind (Typ) = E_Record_Type
        and then Is_Concurrent_Record_Type (Typ)
      then
         CRec_Typ := Typ;
         Full_Typ := Corresponding_Concurrent_Type (CRec_Typ);
         Priv_Typ := Incomplete_Or_Partial_View (Full_Typ);

      --  Otherwise the input type denotes an arbitrary type

      else
         IP_View := Incomplete_Or_Partial_View (Typ);

         --  The input type denotes the full view of a private type

         if Present (IP_View) then
            Priv_Typ := IP_View;
            Full_Typ := Typ;

         --  The input type is a private type

         elsif Is_Private_Type (Typ) then
            Priv_Typ := Typ;
            Full_Typ := Full_View (Priv_Typ);

         --  Otherwise the input type does not have any views

         else
            Full_Typ := Typ;
         end if;

         if Present (Full_Typ) and then Is_Private_Type (Full_Typ) then
            UFull_Typ := Underlying_Full_View (Full_Typ);

            if Present (UFull_Typ)
              and then Ekind (UFull_Typ) in E_Protected_Type | E_Task_Type
            then
               CRec_Typ := Corresponding_Record_Type (UFull_Typ);
            end if;

         else
            if Present (Full_Typ)
              and then Ekind (Full_Typ) in E_Protected_Type | E_Task_Type
            then
               CRec_Typ := Corresponding_Record_Type (Full_Typ);
            end if;
         end if;
      end if;
   end Get_Views;

   ------------------------------
   -- Has_Compatible_Alignment --
   ------------------------------

   function Has_Compatible_Alignment
     (Obj         : Entity_Id;
      Expr        : Node_Id;
      Layout_Done : Boolean) return Alignment_Result
   is
      function Has_Compatible_Alignment_Internal
        (Obj         : Entity_Id;
         Expr        : Node_Id;
         Layout_Done : Boolean;
         Default     : Alignment_Result) return Alignment_Result;
      --  This is the internal recursive function that actually does the work.
      --  There is one additional parameter, which says what the result should
      --  be if no alignment information is found, and there is no definite
      --  indication of compatible alignments. At the outer level, this is set
      --  to Unknown, but for internal recursive calls in the case where types
      --  are known to be correct, it is set to Known_Compatible.

      ---------------------------------------
      -- Has_Compatible_Alignment_Internal --
      ---------------------------------------

      function Has_Compatible_Alignment_Internal
        (Obj         : Entity_Id;
         Expr        : Node_Id;
         Layout_Done : Boolean;
         Default     : Alignment_Result) return Alignment_Result
      is
         Result : Alignment_Result := Known_Compatible;
         --  Holds the current status of the result. Note that once a value of
         --  Known_Incompatible is set, it is sticky and does not get changed
         --  to Unknown (the value in Result only gets worse as we go along,
         --  never better).

         Offs : Uint := No_Uint;
         --  Set to a factor of the offset from the base object when Expr is a
         --  selected or indexed component, based on Component_Bit_Offset and
         --  Component_Size respectively. A negative value is used to represent
         --  a value that is not known at compile time.

         procedure Check_Prefix;
         --  Checks the prefix recursively in the case where the expression
         --  is an indexed or selected component.

         procedure Set_Result (R : Alignment_Result);
         --  If R represents a worse outcome (unknown instead of known
         --  compatible, or known incompatible), then set Result to R.

         ------------------
         -- Check_Prefix --
         ------------------

         procedure Check_Prefix is
         begin
            --  The subtlety here is that in doing a recursive call to check
            --  the prefix, we have to decide what to do in the case where we
            --  don't find any specific indication of an alignment problem.

            --  At the outer level, we normally set Unknown as the result in
            --  this case, since we can only set Known_Compatible if we really
            --  know that the alignment value is OK, but for the recursive
            --  call, in the case where the types match, and we have not
            --  specified a peculiar alignment for the object, we are only
            --  concerned about suspicious rep clauses, the default case does
            --  not affect us, since the compiler will, in the absence of such
            --  rep clauses, ensure that the alignment is correct.

            if Default = Known_Compatible
              or else
                (Etype (Obj) = Etype (Expr)
                  and then (not Known_Alignment (Obj)
                             or else
                               Alignment (Obj) = Alignment (Etype (Obj))))
            then
               Set_Result
                 (Has_Compatible_Alignment_Internal
                    (Obj, Prefix (Expr), Layout_Done, Known_Compatible));

            --  In all other cases, we need a full check on the prefix

            else
               Set_Result
                 (Has_Compatible_Alignment_Internal
                    (Obj, Prefix (Expr), Layout_Done, Unknown));
            end if;
         end Check_Prefix;

         ----------------
         -- Set_Result --
         ----------------

         procedure Set_Result (R : Alignment_Result) is
         begin
            if R > Result then
               Result := R;
            end if;
         end Set_Result;

      --  Start of processing for Has_Compatible_Alignment_Internal

      begin
         --  If Expr is a selected component, we must make sure there is no
         --  potentially troublesome component clause and that the record is
         --  not packed if the layout is not done.

         if Nkind (Expr) = N_Selected_Component then

            --  Packing generates unknown alignment if layout is not done

            if Is_Packed (Etype (Prefix (Expr))) and then not Layout_Done then
               Set_Result (Unknown);
            end if;

            --  Check prefix and component offset

            Check_Prefix;
            Offs := Component_Bit_Offset (Entity (Selector_Name (Expr)));

         --  If Expr is an indexed component, we must make sure there is no
         --  potentially troublesome Component_Size clause and that the array
         --  is not bit-packed if the layout is not done.

         elsif Nkind (Expr) = N_Indexed_Component then
            declare
               Typ : constant Entity_Id := Etype (Prefix (Expr));

            begin
               --  Packing generates unknown alignment if layout is not done

               if Is_Bit_Packed_Array (Typ) and then not Layout_Done then
                  Set_Result (Unknown);
               end if;

               --  Check prefix and component offset (or at least size)

               Check_Prefix;
               Offs := Indexed_Component_Bit_Offset (Expr);
               if No (Offs) then
                  Offs := Component_Size (Typ);
               end if;
            end;
         end if;

         --  If we have a null offset, the result is entirely determined by
         --  the base object and has already been computed recursively.

         if Present (Offs) and then Offs = Uint_0 then
            null;

         --  Case where we know the alignment of the object

         elsif Known_Alignment (Obj) then
            declare
               ObjA : constant Uint := Alignment (Obj);
               ExpA : Uint          := No_Uint;
               SizA : Uint          := No_Uint;

            begin
               --  If alignment of Obj is 1, then we are always OK

               if ObjA = 1 then
                  Set_Result (Known_Compatible);

               --  Alignment of Obj is greater than 1, so we need to check

               else
                  --  If we have an offset, see if it is compatible

                  if Present (Offs) and then Offs > Uint_0 then
                     if Offs mod (System_Storage_Unit * ObjA) /= 0 then
                        Set_Result (Known_Incompatible);
                     end if;

                  --  See if Expr is an object with known alignment

                  elsif Is_Entity_Name (Expr)
                    and then Known_Alignment (Entity (Expr))
                  then
                     Offs := Uint_0;
                     ExpA := Alignment (Entity (Expr));

                  --  Otherwise, we can use the alignment of the type of Expr
                  --  given that we already checked for discombobulating rep
                  --  clauses for the cases of indexed and selected components
                  --  above.

                  elsif Known_Alignment (Etype (Expr)) then
                     ExpA := Alignment (Etype (Expr));

                  --  Otherwise the alignment is unknown

                  else
                     Set_Result (Default);
                  end if;

                  --  If we got an alignment, see if it is acceptable

                  if Present (ExpA) and then ExpA < ObjA then
                     Set_Result (Known_Incompatible);
                  end if;

                  --  If Expr is a component or an entire object with a known
                  --  alignment, then we are fine. Otherwise, if its size is
                  --  known, it must be big enough for the required alignment.

                  if Present (Offs) then
                     null;

                  --  See if Expr is an object with known size

                  elsif Is_Entity_Name (Expr)
                    and then Known_Static_Esize (Entity (Expr))
                  then
                     SizA := Esize (Entity (Expr));

                  --  Otherwise, we check the object size of the Expr type

                  elsif Known_Static_Esize (Etype (Expr)) then
                     SizA := Esize (Etype (Expr));
                  end if;

                  --  If we got a size, see if it is a multiple of the Obj
                  --  alignment; if not, then the alignment cannot be
                  --  acceptable, since the size is always a multiple of the
                  --  alignment.

                  if Present (SizA) then
                     if SizA mod (ObjA * Ttypes.System_Storage_Unit) /= 0 then
                        Set_Result (Known_Incompatible);
                     end if;
                  end if;
               end if;
            end;

         --  If we do not know required alignment, any non-zero offset is a
         --  potential problem (but certainly may be OK, so result is unknown).

         elsif Present (Offs) then
            Set_Result (Unknown);

         --  If we can't find the result by direct comparison of alignment
         --  values, then there is still one case that we can determine known
         --  result, and that is when we can determine that the types are the
         --  same, and no alignments are specified. Then we known that the
         --  alignments are compatible, even if we don't know the alignment
         --  value in the front end.

         elsif Etype (Obj) = Etype (Expr) then

            --  Types are the same, but we have to check for possible size
            --  and alignments on the Expr object that may make the alignment
            --  different, even though the types are the same.

            if Is_Entity_Name (Expr) then

               --  First check alignment of the Expr object. Any alignment less
               --  than Maximum_Alignment is worrisome since this is the case
               --  where we do not know the alignment of Obj.

               if Known_Alignment (Entity (Expr))
                 and then Alignment (Entity (Expr)) < Ttypes.Maximum_Alignment
               then
                  Set_Result (Unknown);

               --  Now check size of Expr object. Any size that is not an even
               --  multiple of Maximum_Alignment is also worrisome since it
               --  may cause the alignment of the object to be less than the
               --  alignment of the type.

               elsif Known_Static_Esize (Entity (Expr))
                 and then
                   Esize (Entity (Expr)) mod
                     (Ttypes.Maximum_Alignment * Ttypes.System_Storage_Unit)
                                                                        /= 0
               then
                  Set_Result (Unknown);

               --  Otherwise same type is decisive

               else
                  Set_Result (Known_Compatible);
               end if;
            end if;

         --  Another case to deal with is when there is an explicit size or
         --  alignment clause when the types are not the same. If so, then the
         --  result is Unknown. We don't need to do this test if the Default is
         --  Unknown, since that result will be set in any case.

         elsif Default /= Unknown
           and then (Has_Size_Clause      (Etype (Expr))
                       or else
                     Has_Alignment_Clause (Etype (Expr)))
         then
            Set_Result (Unknown);

         --  If no indication found, set default

         else
            Set_Result (Default);
         end if;

         --  Return worst result found

         return Result;
      end Has_Compatible_Alignment_Internal;

   --  Start of processing for Has_Compatible_Alignment

   begin
      --  If Obj has no specified alignment, then set alignment from the type
      --  alignment. Perhaps we should always do this, but for sure we should
      --  do it when there is an address clause since we can do more if the
      --  alignment is known.

      if not Known_Alignment (Obj) and then Known_Alignment (Etype (Obj)) then
         Set_Alignment (Obj, Alignment (Etype (Obj)));
      end if;

      --  Now do the internal call that does all the work

      return
        Has_Compatible_Alignment_Internal (Obj, Expr, Layout_Done, Unknown);
   end Has_Compatible_Alignment;

   ----------------------
   -- Has_Declarations --
   ----------------------

   function Has_Declarations (N : Node_Id) return Boolean is
   begin
      return Nkind (N) in N_Accept_Statement
                        | N_Block_Statement
                        | N_Compilation_Unit_Aux
                        | N_Entry_Body
                        | N_Package_Body
                        | N_Protected_Body
                        | N_Subprogram_Body
                        | N_Task_Body
                        | N_Package_Specification;
   end Has_Declarations;

   ---------------------------------
   -- Has_Defaulted_Discriminants --
   ---------------------------------

   function Has_Defaulted_Discriminants (Typ : Entity_Id) return Boolean is
   begin
      return Has_Discriminants (Typ)
       and then Present (Discriminant_Default_Value
                           (First_Discriminant (Typ)));
   end Has_Defaulted_Discriminants;

   -------------------
   -- Has_Denormals --
   -------------------

   function Has_Denormals (E : Entity_Id) return Boolean is
   begin
      return Is_Floating_Point_Type (E) and then Denorm_On_Target;
   end Has_Denormals;

   -------------------------------------------
   -- Has_Discriminant_Dependent_Constraint --
   -------------------------------------------

   function Has_Discriminant_Dependent_Constraint
     (Comp : Entity_Id) return Boolean
   is
      Comp_Decl  : constant Node_Id := Parent (Comp);
      Subt_Indic : Node_Id;
      Constr     : Node_Id;
      Assn       : Node_Id;

   begin
      --  Discriminants can't depend on discriminants

      if Ekind (Comp) = E_Discriminant then
         return False;

      else
         Subt_Indic := Subtype_Indication (Component_Definition (Comp_Decl));

         if Nkind (Subt_Indic) = N_Subtype_Indication then
            Constr := Constraint (Subt_Indic);

            if Nkind (Constr) = N_Index_Or_Discriminant_Constraint then
               Assn := First (Constraints (Constr));
               while Present (Assn) loop
                  case Nkind (Assn) is
                     when N_Identifier
                        | N_Range
                        | N_Subtype_Indication
                     =>
                        if Depends_On_Discriminant (Assn) then
                           return True;
                        end if;

                     when N_Discriminant_Association =>
                        if Depends_On_Discriminant (Expression (Assn)) then
                           return True;
                        end if;

                     when others =>
                        null;
                  end case;

                  Next (Assn);
               end loop;
            end if;
         end if;
      end if;

      return False;
   end Has_Discriminant_Dependent_Constraint;

   --------------------------------------
   -- Has_Effectively_Volatile_Profile --
   --------------------------------------

   function Has_Effectively_Volatile_Profile
     (Subp_Id : Entity_Id) return Boolean
   is
      Formal : Entity_Id;

   begin
      --  Inspect the formal parameters looking for an effectively volatile
      --  type for reading.

      Formal := First_Formal (Subp_Id);
      while Present (Formal) loop
         if Is_Effectively_Volatile_For_Reading (Etype (Formal)) then
            return True;
         end if;

         Next_Formal (Formal);
      end loop;

      --  Inspect the return type of functions

      if Ekind (Subp_Id) in E_Function | E_Generic_Function
        and then Is_Effectively_Volatile_For_Reading (Etype (Subp_Id))
      then
         return True;
      end if;

      return False;
   end Has_Effectively_Volatile_Profile;

   --------------------------
   -- Has_Enabled_Property --
   --------------------------

   function Has_Enabled_Property
     (Item_Id  : Entity_Id;
      Property : Name_Id) return Boolean
   is
      function Protected_Type_Or_Variable_Has_Enabled_Property return Boolean;
      --  Determine whether a protected type or variable denoted by Item_Id
      --  has the property enabled.

      function State_Has_Enabled_Property return Boolean;
      --  Determine whether a state denoted by Item_Id has the property enabled

      function Type_Or_Variable_Has_Enabled_Property
        (Item_Id : Entity_Id) return Boolean;
      --  Determine whether type or variable denoted by Item_Id has the
      --  property enabled.

      -----------------------------------------------------
      -- Protected_Type_Or_Variable_Has_Enabled_Property --
      -----------------------------------------------------

      function Protected_Type_Or_Variable_Has_Enabled_Property return Boolean
      is
      begin
         --  Protected entities always have the properties Async_Readers and
         --  Async_Writers (SPARK RM 7.1.2(16)).

         if Property = Name_Async_Readers
           or else Property = Name_Async_Writers
         then
            return True;

         --  Protected objects that have Part_Of components also inherit their
         --  properties Effective_Reads and Effective_Writes
         --  (SPARK RM 7.1.2(16)).

         elsif Is_Single_Protected_Object (Item_Id) then
            declare
               Constit_Elmt : Elmt_Id;
               Constit_Id   : Entity_Id;
               Constits     : constant Elist_Id
                 := Part_Of_Constituents (Item_Id);
            begin
               if Present (Constits) then
                  Constit_Elmt := First_Elmt (Constits);
                  while Present (Constit_Elmt) loop
                     Constit_Id := Node (Constit_Elmt);

                     if Has_Enabled_Property (Constit_Id, Property) then
                        return True;
                     end if;

                     Next_Elmt (Constit_Elmt);
                  end loop;
               end if;
            end;
         end if;

         return False;
      end Protected_Type_Or_Variable_Has_Enabled_Property;

      --------------------------------
      -- State_Has_Enabled_Property --
      --------------------------------

      function State_Has_Enabled_Property return Boolean is
         Decl : constant Node_Id := Parent (Item_Id);

         procedure Find_Simple_Properties
           (Has_External    : out Boolean;
            Has_Synchronous : out Boolean);
         --  Extract the simple properties associated with declaration Decl

         function Is_Enabled_External_Property return Boolean;
         --  Determine whether property Property appears within the external
         --  property list of declaration Decl, and return its status.

         ----------------------------
         -- Find_Simple_Properties --
         ----------------------------

         procedure Find_Simple_Properties
           (Has_External    : out Boolean;
            Has_Synchronous : out Boolean)
         is
            Opt : Node_Id;

         begin
            --  Assume that none of the properties are available

            Has_External    := False;
            Has_Synchronous := False;

            Opt := First (Expressions (Decl));
            while Present (Opt) loop
               if Nkind (Opt) = N_Identifier then
                  if Chars (Opt) = Name_External then
                     Has_External := True;

                  elsif Chars (Opt) = Name_Synchronous then
                     Has_Synchronous := True;
                  end if;
               end if;

               Next (Opt);
            end loop;
         end Find_Simple_Properties;

         ----------------------------------
         -- Is_Enabled_External_Property --
         ----------------------------------

         function Is_Enabled_External_Property return Boolean is
            Opt      : Node_Id;
            Opt_Nam  : Node_Id;
            Prop     : Node_Id;
            Prop_Nam : Node_Id;
            Props    : Node_Id;

         begin
            Opt := First (Component_Associations (Decl));
            while Present (Opt) loop
               Opt_Nam := First (Choices (Opt));

               if Nkind (Opt_Nam) = N_Identifier
                 and then Chars (Opt_Nam) = Name_External
               then
                  Props := Expression (Opt);

                  --  Multiple properties appear as an aggregate

                  if Nkind (Props) = N_Aggregate then

                     --  Simple property form

                     Prop := First (Expressions (Props));
                     while Present (Prop) loop
                        if Chars (Prop) = Property then
                           return True;
                        end if;

                        Next (Prop);
                     end loop;

                     --  Property with expression form

                     Prop := First (Component_Associations (Props));
                     while Present (Prop) loop
                        Prop_Nam := First (Choices (Prop));

                        --  The property can be represented in two ways:
                        --      others   => <value>
                        --    <property> => <value>

                        if Nkind (Prop_Nam) = N_Others_Choice
                          or else (Nkind (Prop_Nam) = N_Identifier
                                    and then Chars (Prop_Nam) = Property)
                        then
                           return Is_True (Expr_Value (Expression (Prop)));
                        end if;

                        Next (Prop);
                     end loop;

                  --  Single property

                  else
                     return Chars (Props) = Property;
                  end if;
               end if;

               Next (Opt);
            end loop;

            return False;
         end Is_Enabled_External_Property;

         --  Local variables

         Has_External    : Boolean;
         Has_Synchronous : Boolean;

      --  Start of processing for State_Has_Enabled_Property

      begin
         --  The declaration of an external abstract state appears as an
         --  extension aggregate. If this is not the case, properties can
         --  never be set.

         if Nkind (Decl) /= N_Extension_Aggregate then
            return False;
         end if;

         Find_Simple_Properties (Has_External, Has_Synchronous);

         --  Simple option External enables all properties (SPARK RM 7.1.2(2))

         if Has_External then
            return True;

         --  Option External may enable or disable specific properties

         elsif Is_Enabled_External_Property then
            return True;

         --  Simple option Synchronous
         --
         --    enables                disables
         --       Async_Readers          Effective_Reads
         --       Async_Writers          Effective_Writes
         --
         --  Note that both forms of External have higher precedence than
         --  Synchronous (SPARK RM 7.1.4(9)).

         elsif Has_Synchronous then
            return Property in Name_Async_Readers | Name_Async_Writers;
         end if;

         return False;
      end State_Has_Enabled_Property;

      -------------------------------------------
      -- Type_Or_Variable_Has_Enabled_Property --
      -------------------------------------------

      function Type_Or_Variable_Has_Enabled_Property
        (Item_Id : Entity_Id) return Boolean
      is
         AR : constant Node_Id :=
                Get_Pragma (Item_Id, Pragma_Async_Readers);
         AW : constant Node_Id :=
                Get_Pragma (Item_Id, Pragma_Async_Writers);
         ER : constant Node_Id :=
                Get_Pragma (Item_Id, Pragma_Effective_Reads);
         EW : constant Node_Id :=
                Get_Pragma (Item_Id, Pragma_Effective_Writes);

         Is_Derived_Type_With_Volatile_Parent_Type : constant Boolean :=
           Is_Derived_Type (Item_Id)
           and then Is_Effectively_Volatile (Etype (Base_Type (Item_Id)));

      begin
         --  A non-effectively volatile object can never possess external
         --  properties.

         if not Is_Effectively_Volatile (Item_Id) then
            return False;

         --  External properties related to variables come in two flavors -
         --  explicit and implicit. The explicit case is characterized by the
         --  presence of a property pragma with an optional Boolean flag. The
         --  property is enabled when the flag evaluates to True or the flag is
         --  missing altogether.

         elsif Property = Name_Async_Readers    and then Present (AR) then
            return Is_Enabled_Pragma (AR);

         elsif Property = Name_Async_Writers    and then Present (AW) then
            return Is_Enabled_Pragma (AW);

         elsif Property = Name_Effective_Reads  and then Present (ER) then
            return Is_Enabled_Pragma (ER);

         elsif Property = Name_Effective_Writes and then Present (EW) then
            return Is_Enabled_Pragma (EW);

         --  If other properties are set explicitly, then this one is set
         --  implicitly to False, except in the case of a derived type
         --  whose parent type is volatile (in that case, we will inherit
         --  from the parent type, below).

         elsif (Present (AR)
           or else Present (AW)
           or else Present (ER)
           or else Present (EW))
           and then not Is_Derived_Type_With_Volatile_Parent_Type
         then
            return False;

         --  For a private type (including subtype of a private types), look at
         --  the full view.

         elsif Is_Private_Type (Item_Id) and then Present (Full_View (Item_Id))
         then
            return Type_Or_Variable_Has_Enabled_Property (Full_View (Item_Id));

         --  For a derived type whose parent type is volatile, the
         --  property may be inherited (but ignore a non-volatile parent).

         elsif Is_Derived_Type_With_Volatile_Parent_Type then
            return Type_Or_Variable_Has_Enabled_Property
              (First_Subtype (Etype (Base_Type (Item_Id))));

         --  For a subtype, the property will be inherited from its base type.

         elsif Is_Type (Item_Id)
           and then not Is_Base_Type (Item_Id)
         then
            return Type_Or_Variable_Has_Enabled_Property (Etype (Item_Id));

         --  If not specified explicitly for an object and its type
         --  is effectively volatile, then take result from the type.

         elsif Is_Object (Item_Id)
           and then Is_Effectively_Volatile (Etype (Item_Id))
         then
            return Has_Enabled_Property (Etype (Item_Id), Property);

         --  The implicit case lacks all property pragmas

         elsif No (AR) and then No (AW) and then No (ER) and then No (EW) then
            if Is_Protected_Type (Etype (Item_Id)) then
               return Protected_Type_Or_Variable_Has_Enabled_Property;
            else
               return True;
            end if;

         else
            return False;
         end if;
      end Type_Or_Variable_Has_Enabled_Property;

   --  Start of processing for Has_Enabled_Property

   begin
      --  Abstract states and variables have a flexible scheme of specifying
      --  external properties.

      if Ekind (Item_Id) = E_Abstract_State then
         return State_Has_Enabled_Property;

      elsif Ekind (Item_Id) in E_Variable | E_Constant then
         return Type_Or_Variable_Has_Enabled_Property (Item_Id);

      --  Other objects can only inherit properties through their type. We
      --  cannot call directly Type_Or_Variable_Has_Enabled_Property on
      --  these as they don't have contracts attached, which is expected by
      --  this function.

      elsif Is_Object (Item_Id) then
         return Type_Or_Variable_Has_Enabled_Property (Etype (Item_Id));

      elsif Is_Type (Item_Id) then
         return Type_Or_Variable_Has_Enabled_Property
           (Item_Id => First_Subtype (Item_Id));

      --  Otherwise a property is enabled when the related item is effectively
      --  volatile.

      else
         return Is_Effectively_Volatile (Item_Id);
      end if;
   end Has_Enabled_Property;

   -------------------------------------
   -- Has_Full_Default_Initialization --
   -------------------------------------

   function Has_Full_Default_Initialization (Typ : Entity_Id) return Boolean is
      Comp : Entity_Id;

   begin
      --  A type subject to pragma Default_Initial_Condition may be fully
      --  default initialized depending on inheritance and the argument of
      --  the pragma. Since any type may act as the full view of a private
      --  type, this check must be performed prior to the specialized tests
      --  below.

      if Has_Fully_Default_Initializing_DIC_Pragma (Typ) then
         return True;
      end if;

      --  A scalar type is fully default initialized if it is subject to aspect
      --  Default_Value.

      if Is_Scalar_Type (Typ) then
         return Has_Default_Aspect (Typ);

      --  An access type is fully default initialized by default

      elsif Is_Access_Type (Typ) then
         return True;

      --  An array type is fully default initialized if its element type is
      --  scalar and the array type carries aspect Default_Component_Value or
      --  the element type is fully default initialized.

      elsif Is_Array_Type (Typ) then
         return
           Has_Default_Aspect (Typ)
             or else Has_Full_Default_Initialization (Component_Type (Typ));

      --  A protected type, record type, or type extension is fully default
      --  initialized if all its components either carry an initialization
      --  expression or have a type that is fully default initialized. The
      --  parent type of a type extension must be fully default initialized.

      elsif Is_Record_Type (Typ) or else Is_Protected_Type (Typ) then

         --  Inspect all entities defined in the scope of the type, looking for
         --  uninitialized components.

         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Comes_From_Source (Comp)
              and then No (Expression (Parent (Comp)))
              and then not Has_Full_Default_Initialization (Etype (Comp))
            then
               return False;
            end if;

            Next_Component (Comp);
         end loop;

         --  Ensure that the parent type of a type extension is fully default
         --  initialized.

         if Etype (Typ) /= Typ
           and then not Has_Full_Default_Initialization (Etype (Typ))
         then
            return False;
         end if;

         --  If we get here, then all components and parent portion are fully
         --  default initialized.

         return True;

      --  A task type is fully default initialized by default

      elsif Is_Task_Type (Typ) then
         return True;

      --  Otherwise the type is not fully default initialized

      else
         return False;
      end if;
   end Has_Full_Default_Initialization;

   -----------------------------------------------
   -- Has_Fully_Default_Initializing_DIC_Pragma --
   -----------------------------------------------

   function Has_Fully_Default_Initializing_DIC_Pragma
     (Typ : Entity_Id) return Boolean
   is
      Args : List_Id;
      Prag : Node_Id;

   begin
      --  A type that inherits pragma Default_Initial_Condition from a parent
      --  type is automatically fully default initialized.

      if Has_Inherited_DIC (Typ) then
         return True;

      --  Otherwise the type is fully default initialized only when the pragma
      --  appears without an argument, or the argument is non-null.

      elsif Has_Own_DIC (Typ) then
         Prag := Get_Pragma (Typ, Pragma_Default_Initial_Condition);
         pragma Assert (Present (Prag));
         Args := Pragma_Argument_Associations (Prag);

         --  The pragma appears without an argument in which case it defaults
         --  to True.

         if No (Args) then
            return True;

         --  The pragma appears with a non-null expression

         elsif Nkind (Get_Pragma_Arg (First (Args))) /= N_Null then
            return True;
         end if;
      end if;

      return False;
   end Has_Fully_Default_Initializing_DIC_Pragma;

   ---------------------------------
   -- Has_Inferable_Discriminants --
   ---------------------------------

   function Has_Inferable_Discriminants (N : Node_Id) return Boolean is

      function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
      --  Determines whether the left-most prefix of a selected component is a
      --  formal parameter in a subprogram. Assumes N is a selected component.

      --------------------------------
      -- Prefix_Is_Formal_Parameter --
      --------------------------------

      function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
         Sel_Comp : Node_Id;

      begin
         --  Move to the left-most prefix by climbing up the tree

         Sel_Comp := N;
         while Present (Parent (Sel_Comp))
           and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
         loop
            Sel_Comp := Parent (Sel_Comp);
         end loop;

         return Is_Formal (Entity (Prefix (Sel_Comp)));
      end Prefix_Is_Formal_Parameter;

   --  Start of processing for Has_Inferable_Discriminants

   begin
      --  For selected components, the subtype of the selector must be a
      --  constrained Unchecked_Union. If the component is subject to a
      --  per-object constraint, then the enclosing object must have inferable
      --  discriminants.

      if Nkind (N) = N_Selected_Component then
         if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then

            --  A small hack. If we have a per-object constrained selected
            --  component of a formal parameter, return True since we do not
            --  know the actual parameter association yet.

            if Prefix_Is_Formal_Parameter (N) then
               return True;

            --  Otherwise, check the enclosing object and the selector

            else
               return Has_Inferable_Discriminants (Prefix (N))
                 and then Has_Inferable_Discriminants (Selector_Name (N));
            end if;

         --  The call to Has_Inferable_Discriminants will determine whether
         --  the selector has a constrained Unchecked_Union nominal type.

         else
            return Has_Inferable_Discriminants (Selector_Name (N));
         end if;

      --  A qualified expression has inferable discriminants if its subtype
      --  mark is a constrained Unchecked_Union subtype.

      elsif Nkind (N) = N_Qualified_Expression then
         return Is_Unchecked_Union (Etype (Subtype_Mark (N)))
           and then Is_Constrained (Etype (Subtype_Mark (N)));

      --  For all other names, it is sufficient to have a constrained
      --  Unchecked_Union nominal subtype.

      else
         return Is_Unchecked_Union (Base_Type (Etype (N)))
           and then Is_Constrained (Etype (N));
      end if;
   end Has_Inferable_Discriminants;

   --------------------
   -- Has_Infinities --
   --------------------

   function Has_Infinities (E : Entity_Id) return Boolean is
   begin
      return
        Is_Floating_Point_Type (E)
          and then Nkind (Scalar_Range (E)) = N_Range
          and then Includes_Infinities (Scalar_Range (E));
   end Has_Infinities;

   --------------------
   -- Has_Interfaces --
   --------------------

   function Has_Interfaces
     (T             : Entity_Id;
      Use_Full_View : Boolean := True) return Boolean
   is
      Typ : Entity_Id := Base_Type (T);

   begin
      --  Handle concurrent types

      if Is_Concurrent_Type (Typ) then
         Typ := Corresponding_Record_Type (Typ);
      end if;

      if No (Typ)
        or else not Is_Record_Type (Typ)
        or else not Is_Tagged_Type (Typ)
      then
         return False;
      end if;

      --  Handle private types

      if Use_Full_View and then Present (Full_View (Typ)) then
         Typ := Full_View (Typ);
      end if;

      --  Handle concurrent record types

      if Is_Concurrent_Record_Type (Typ)
        and then Is_Non_Empty_List (Abstract_Interface_List (Typ))
      then
         return True;
      end if;

      loop
         if Is_Interface (Typ)
           or else
             (Is_Record_Type (Typ)
               and then Present (Interfaces (Typ))
               and then not Is_Empty_Elmt_List (Interfaces (Typ)))
         then
            return True;
         end if;

         exit when Etype (Typ) = Typ

            --  Handle private types

            or else (Present (Full_View (Etype (Typ)))
                      and then Full_View (Etype (Typ)) = Typ)

            --  Protect frontend against wrong sources with cyclic derivations

            or else Etype (Typ) = T;

         --  Climb to the ancestor type handling private types

         if Present (Full_View (Etype (Typ))) then
            Typ := Full_View (Etype (Typ));
         else
            Typ := Etype (Typ);
         end if;
      end loop;

      return False;
   end Has_Interfaces;

   --------------------------
   -- Has_Max_Queue_Length --
   --------------------------

   function Has_Max_Queue_Length (Id : Entity_Id) return Boolean is
   begin
      return
        Ekind (Id) = E_Entry
          and then Present (Get_Pragma (Id, Pragma_Max_Queue_Length));
   end Has_Max_Queue_Length;

   ---------------------------------
   -- Has_No_Obvious_Side_Effects --
   ---------------------------------

   function Has_No_Obvious_Side_Effects (N : Node_Id) return Boolean is
   begin
      --  For now handle literals, constants, and non-volatile variables and
      --  expressions combining these with operators or short circuit forms.

      if Nkind (N) in N_Numeric_Or_String_Literal then
         return True;

      elsif Nkind (N) = N_Character_Literal then
         return True;

      elsif Nkind (N) in N_Unary_Op then
         return Has_No_Obvious_Side_Effects (Right_Opnd (N));

      elsif Nkind (N) in N_Binary_Op or else Nkind (N) in N_Short_Circuit then
         return Has_No_Obvious_Side_Effects (Left_Opnd  (N))
                   and then
                Has_No_Obvious_Side_Effects (Right_Opnd (N));

      elsif Nkind (N) = N_Expression_With_Actions
        and then Is_Empty_List (Actions (N))
      then
         return Has_No_Obvious_Side_Effects (Expression (N));

      elsif Nkind (N) in N_Has_Entity then
         return Present (Entity (N))
           and then
             Ekind (Entity (N)) in
               E_Variable     | E_Constant      | E_Enumeration_Literal |
               E_In_Parameter | E_Out_Parameter | E_In_Out_Parameter
           and then not Is_Volatile (Entity (N));

      else
         return False;
      end if;
   end Has_No_Obvious_Side_Effects;

   -----------------------------
   -- Has_Non_Null_Refinement --
   -----------------------------

   function Has_Non_Null_Refinement (Id : Entity_Id) return Boolean is
      Constits : Elist_Id;

   begin
      pragma Assert (Ekind (Id) = E_Abstract_State);
      Constits := Refinement_Constituents (Id);

      --  For a refinement to be non-null, the first constituent must be
      --  anything other than null.

      return
        Present (Constits)
          and then Nkind (Node (First_Elmt (Constits))) /= N_Null;
   end Has_Non_Null_Refinement;

   -----------------------------
   -- Has_Non_Null_Statements --
   -----------------------------

   function Has_Non_Null_Statements (L : List_Id) return Boolean is
      Node : Node_Id;

   begin
      Node := First (L);

      while Present (Node) loop
         if Nkind (Node) not in N_Null_Statement | N_Call_Marker then
            return True;
         end if;

         Next (Node);
      end loop;

      return False;
   end Has_Non_Null_Statements;

   ----------------------------------
   -- Is_Access_Subprogram_Wrapper --
   ----------------------------------

   function Is_Access_Subprogram_Wrapper (E : Entity_Id) return Boolean is
      Formal : constant Entity_Id := Last_Formal (E);
   begin
      return Present (Formal)
        and then Ekind (Etype (Formal)) in Access_Subprogram_Kind
        and then Access_Subprogram_Wrapper
           (Directly_Designated_Type (Etype (Formal))) = E;
   end Is_Access_Subprogram_Wrapper;

   ---------------------------
   -- Is_Explicitly_Aliased --
   ---------------------------

   function Is_Explicitly_Aliased (N : Node_Id) return Boolean is
   begin
      return Is_Formal (N)
               and then Present (Parent (N))
               and then Nkind (Parent (N)) = N_Parameter_Specification
               and then Aliased_Present (Parent (N));
   end Is_Explicitly_Aliased;

   ----------------------------
   -- Is_Container_Aggregate --
   ----------------------------

   function Is_Container_Aggregate (Exp : Node_Id) return Boolean is

      function Is_Record_Aggregate return Boolean is (False);
      --  ??? Unimplemented. Given an aggregate whose type is a
      --  record type with specified Aggregate aspect, how do we
      --  determine whether it is a record aggregate or a container
      --  aggregate? If the code where the aggregate occurs can see only
      --  a partial view of the aggregate's type then the aggregate
      --  cannot be a record type; an aggregate of a private type has to
      --  be a container aggregate.

   begin
      return Nkind (Exp) = N_Aggregate
        and then Has_Aspect (Etype (Exp), Aspect_Aggregate)
        and then not Is_Record_Aggregate;
   end Is_Container_Aggregate;

   ---------------------------------
   -- Side_Effect_Free_Statements --
   ---------------------------------

   function Side_Effect_Free_Statements (L : List_Id) return Boolean is
      Node : Node_Id;

   begin
      Node := First (L);

      while Present (Node) loop
         case Nkind (Node) is
            when N_Null_Statement | N_Call_Marker | N_Raise_xxx_Error =>
               null;

            when N_Object_Declaration =>
               if Present (Expression (Node))
                 and then not Side_Effect_Free (Expression (Node))
               then
                  return False;
               end if;

            when others =>
               return False;
         end case;

         Next (Node);
      end loop;

      return True;
   end Side_Effect_Free_Statements;

   ---------------------------
   -- Side_Effect_Free_Loop --
   ---------------------------

   function Side_Effect_Free_Loop (N : Node_Id) return Boolean is
      Scheme : Node_Id;
      Spec   : Node_Id;
      Subt   : Node_Id;

   begin
      --  If this is not a loop (e.g. because the loop has been rewritten),
      --  then return false.

      if Nkind (N) /= N_Loop_Statement then
         return False;
      end if;

      --  First check the statements

      if Side_Effect_Free_Statements (Statements (N)) then

         --  Then check the loop condition/indexes

         if Present (Iteration_Scheme (N)) then
            Scheme := Iteration_Scheme (N);

            if Present (Condition (Scheme))
              or else Present (Iterator_Specification (Scheme))
            then
               return False;
            elsif Present (Loop_Parameter_Specification (Scheme)) then
               Spec := Loop_Parameter_Specification (Scheme);
               Subt := Discrete_Subtype_Definition (Spec);

               if Present (Subt) then
                  if Nkind (Subt) = N_Range then
                     return Side_Effect_Free (Low_Bound (Subt))
                       and then Side_Effect_Free (High_Bound (Subt));
                  else
                     --  subtype indication

                     return True;
                  end if;
               end if;
            end if;
         end if;
      end if;

      return False;
   end Side_Effect_Free_Loop;

   ----------------------------------
   -- Has_Non_Trivial_Precondition --
   ----------------------------------

   function Has_Non_Trivial_Precondition (Subp : Entity_Id) return Boolean is
      Pre : constant Node_Id := Find_Aspect (Subp, Aspect_Pre,
                                             Class_Present => True);
   begin
      return
        Present (Pre)
          and then not Is_Entity_Name (Expression (Pre));
   end Has_Non_Trivial_Precondition;

   -------------------
   -- Has_Null_Body --
   -------------------

   function Has_Null_Body (Proc_Id : Entity_Id) return Boolean is
      Body_Id : Entity_Id;
      Decl    : Node_Id;
      Spec    : Node_Id;
      Stmt1   : Node_Id;
      Stmt2   : Node_Id;

   begin
      Spec := Parent (Proc_Id);
      Decl := Parent (Spec);

      --  Retrieve the entity of the procedure body (e.g. invariant proc).

      if Nkind (Spec) = N_Procedure_Specification
        and then Nkind (Decl) = N_Subprogram_Declaration
      then
         Body_Id := Corresponding_Body (Decl);

      --  The body acts as a spec

      else
         Body_Id := Proc_Id;
      end if;

      --  The body will be generated later

      if No (Body_Id) then
         return False;
      end if;

      Spec := Parent (Body_Id);
      Decl := Parent (Spec);

      pragma Assert
        (Nkind (Spec) = N_Procedure_Specification
          and then Nkind (Decl) = N_Subprogram_Body);

      Stmt1 := First (Statements (Handled_Statement_Sequence (Decl)));

      --  Look for a null statement followed by an optional return
      --  statement.

      if Nkind (Stmt1) = N_Null_Statement then
         Stmt2 := Next (Stmt1);

         if Present (Stmt2) then
            return Nkind (Stmt2) = N_Simple_Return_Statement;
         else
            return True;
         end if;
      end if;

      return False;
   end Has_Null_Body;

   ------------------------
   -- Has_Null_Exclusion --
   ------------------------

   function Has_Null_Exclusion (N : Node_Id) return Boolean is
   begin
      case Nkind (N) is
         when N_Access_Definition
            | N_Access_Function_Definition
            | N_Access_Procedure_Definition
            | N_Access_To_Object_Definition
            | N_Allocator
            | N_Derived_Type_Definition
            | N_Function_Specification
            | N_Subtype_Declaration
         =>
            return Null_Exclusion_Present (N);

         when N_Component_Definition
            | N_Formal_Object_Declaration
         =>
            if Present (Subtype_Mark (N)) then
               return Null_Exclusion_Present (N);
            else pragma Assert (Present (Access_Definition (N)));
               return Null_Exclusion_Present (Access_Definition (N));
            end if;

         when N_Object_Renaming_Declaration =>
            if Present (Subtype_Mark (N)) then
               return Null_Exclusion_Present (N);
            elsif Present (Access_Definition (N)) then
               return Null_Exclusion_Present (Access_Definition (N));
            else
               return False;  -- Case of no subtype in renaming (AI12-0275)
            end if;

         when N_Discriminant_Specification =>
            if Nkind (Discriminant_Type (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Discriminant_Type (N));
            else
               return Null_Exclusion_Present (N);
            end if;

         when N_Object_Declaration =>
            if Nkind (Object_Definition (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Object_Definition (N));
            else
               return Null_Exclusion_Present (N);
            end if;

         when N_Parameter_Specification =>
            if Nkind (Parameter_Type (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Parameter_Type (N))
                 or else Null_Exclusion_Present (N);
            else
               return Null_Exclusion_Present (N);
            end if;

         when others =>
            return False;
      end case;
   end Has_Null_Exclusion;

   ------------------------
   -- Has_Null_Extension --
   ------------------------

   function Has_Null_Extension (T : Entity_Id) return Boolean is
      B     : constant Entity_Id := Base_Type (T);
      Comps : Node_Id;
      Ext   : Node_Id;

   begin
      if Nkind (Parent (B)) = N_Full_Type_Declaration
        and then Present (Record_Extension_Part (Type_Definition (Parent (B))))
      then
         Ext := Record_Extension_Part (Type_Definition (Parent (B)));

         if Present (Ext) then
            if Null_Present (Ext) then
               return True;
            else
               Comps := Component_List (Ext);

               --  The null component list is rewritten during analysis to
               --  include the parent component. Any other component indicates
               --  that the extension was not originally null.

               return Null_Present (Comps)
                 or else No (Next (First (Component_Items (Comps))));
            end if;
         else
            return False;
         end if;

      else
         return False;
      end if;
   end Has_Null_Extension;

   -------------------------
   -- Has_Null_Refinement --
   -------------------------

   function Has_Null_Refinement (Id : Entity_Id) return Boolean is
      Constits : Elist_Id;

   begin
      pragma Assert (Ekind (Id) = E_Abstract_State);
      Constits := Refinement_Constituents (Id);

      --  For a refinement to be null, the state's sole constituent must be a
      --  null.

      return
        Present (Constits)
          and then Nkind (Node (First_Elmt (Constits))) = N_Null;
   end Has_Null_Refinement;

   ------------------------------------------
   -- Has_Nonstatic_Class_Wide_Pre_Or_Post --
   ------------------------------------------

   function Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post
     (Subp : Entity_Id) return Boolean
   is
      Disp_Type  : constant Entity_Id := Find_Dispatching_Type (Subp);
      Prag       : Node_Id;
      Pragma_Arg : Node_Id;

   begin
      if Present (Disp_Type)
        and then Is_Abstract_Type (Disp_Type)
        and then Present (Contract (Subp))
      then
         Prag := Pre_Post_Conditions (Contract (Subp));

         while Present (Prag) loop
            if Pragma_Name (Prag) in Name_Precondition | Name_Postcondition
              and then Class_Present (Prag)
            then
               Pragma_Arg :=
                 Nlists.First
                   (Pragma_Argument_Associations (Prag));

               if not Is_Static_Expression (Expression (Pragma_Arg)) then
                  return True;
               end if;
            end if;

            Prag := Next_Pragma (Prag);
         end loop;
      end if;

      return False;
   end Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post;

   -------------------------------
   -- Has_Overriding_Initialize --
   -------------------------------

   function Has_Overriding_Initialize (T : Entity_Id) return Boolean is
      BT   : constant Entity_Id := Base_Type (T);
      P    : Elmt_Id;

   begin
      if Is_Controlled (BT) then
         if Is_RTU (Scope (BT), Ada_Finalization) then
            return False;

         elsif Present (Primitive_Operations (BT)) then
            P := First_Elmt (Primitive_Operations (BT));
            while Present (P) loop
               declare
                  Init : constant Entity_Id := Node (P);
                  Formal : constant Entity_Id := First_Formal (Init);
               begin
                  if Ekind (Init) = E_Procedure
                    and then Chars (Init) = Name_Initialize
                    and then Comes_From_Source (Init)
                    and then Present (Formal)
                    and then Etype (Formal) = BT
                    and then No (Next_Formal (Formal))
                    and then (Ada_Version < Ada_2012
                               or else not Null_Present (Parent (Init)))
                  then
                     return True;
                  end if;
               end;

               Next_Elmt (P);
            end loop;
         end if;

         --  Here if type itself does not have a non-null Initialize operation:
         --  check immediate ancestor.

         if Is_Derived_Type (BT)
           and then Has_Overriding_Initialize (Etype (BT))
         then
            return True;
         end if;
      end if;

      return False;
   end Has_Overriding_Initialize;

   --------------------------------------
   -- Has_Preelaborable_Initialization --
   --------------------------------------

   function Has_Preelaborable_Initialization
     (E                 : Entity_Id;
      Preelab_Init_Expr : Node_Id := Empty) return Boolean
   is
      Has_PE : Boolean;

      procedure Check_Components (E : Entity_Id);
      --  Check component/discriminant chain, sets Has_PE False if a component
      --  or discriminant does not meet the preelaborable initialization rules.

      function Type_Named_In_Preelab_Init_Expression
        (Typ  : Entity_Id;
         Expr : Node_Id) return Boolean;
      --  Returns True iff Typ'Preelaborable_Initialization occurs in Expr
      --  (where Expr may be a conjunction of one or more P_I attributes).

      ----------------------
      -- Check_Components --
      ----------------------

      procedure Check_Components (E : Entity_Id) is
         Ent : Entity_Id;
         Exp : Node_Id;

      begin
         --  Loop through components and discriminants of record or protected
         --  type.

         Ent := First_Component_Or_Discriminant (E);
         while Present (Ent) loop

            case Ekind (Ent) is
               when E_Component =>

                  --  Get default expression if any. If there is no declaration
                  --  node, it means we have an internal entity. The parent and
                  --  tag fields are examples of such entities. For such cases,
                  --  we just test the type of the entity.

                  if Present (Declaration_Node (Ent)) then
                     Exp := Expression (Declaration_Node (Ent));
                  else
                     Exp := Empty;
                  end if;

               when E_Discriminant =>

                  --  Note: for a renamed discriminant, the Declaration_Node
                  --  may point to the one from the ancestor, and have a
                  --  different expression, so use the proper attribute to
                  --  retrieve the expression from the derived constraint.

                  Exp := Discriminant_Default_Value (Ent);

               when others =>
                  raise Program_Error;
            end case;

            --  A component has PI if it has no default expression and the
            --  component type has PI.

            if No (Exp) then
               if not Has_Preelaborable_Initialization
                        (Etype (Ent), Preelab_Init_Expr)
               then
                  Has_PE := False;
                  exit;
               end if;

            --  Require the default expression to be preelaborable

            elsif not Is_Preelaborable_Construct (Exp) then
               Has_PE := False;
               exit;
            end if;

            Next_Component_Or_Discriminant (Ent);
         end loop;
      end Check_Components;

      --------------------------------------
      -- Type_Named_In_Preelab_Expression --
      --------------------------------------

      function Type_Named_In_Preelab_Init_Expression
        (Typ  : Entity_Id;
         Expr : Node_Id) return Boolean
      is
      begin
         --  Return True if Expr is a Preelaborable_Initialization attribute
         --  and the prefix is a subtype that has the same type as Typ.

         if Nkind (Expr) = N_Attribute_Reference
           and then Attribute_Name (Expr) = Name_Preelaborable_Initialization
           and then Is_Entity_Name (Prefix (Expr))
           and then Base_Type (Entity (Prefix (Expr))) = Base_Type (Typ)
         then
            return True;

         --  In the case where Expr is a conjunction, test whether either
         --  operand is a Preelaborable_Initialization attribute whose prefix
         --  has the same type as Typ, and return True if so.

         elsif Nkind (Expr) = N_Op_And
           and then
            (Type_Named_In_Preelab_Init_Expression (Typ, Left_Opnd (Expr))
              or else
             Type_Named_In_Preelab_Init_Expression (Typ, Right_Opnd (Expr)))
         then
            return True;

         --  Typ not named in a Preelaborable_Initialization attribute of Expr

         else
            return False;
         end if;
      end Type_Named_In_Preelab_Init_Expression;

   --  Start of processing for Has_Preelaborable_Initialization

   begin
      --  Immediate return if already marked as known preelaborable init. This
      --  covers types for which this function has already been called once
      --  and returned True (in which case the result is cached), and also
      --  types to which a pragma Preelaborable_Initialization applies.

      if Known_To_Have_Preelab_Init (E) then
         return True;
      end if;

      --  If the type is a subtype representing a generic actual type, then
      --  test whether its base type has preelaborable initialization since
      --  the subtype representing the actual does not inherit this attribute
      --  from the actual or formal. (but maybe it should???)

      if Is_Generic_Actual_Type (E) then
         return Has_Preelaborable_Initialization (Base_Type (E));
      end if;

      --  All elementary types have preelaborable initialization

      if Is_Elementary_Type (E) then
         Has_PE := True;

      --  Array types have PI if the component type has PI

      elsif Is_Array_Type (E) then
         Has_PE := Has_Preelaborable_Initialization
                     (Component_Type (E), Preelab_Init_Expr);

      --  A derived type has preelaborable initialization if its parent type
      --  has preelaborable initialization and (in the case of a derived record
      --  extension) if the non-inherited components all have preelaborable
      --  initialization. However, a user-defined controlled type with an
      --  overriding Initialize procedure does not have preelaborable
      --  initialization.

      elsif Is_Derived_Type (E) then

         --  When the rule of RM 10.2.1(11.8/5) applies, we presume a component
         --  of a generic formal derived type has preelaborable initialization.
         --  (See comment on spec of Has_Preelaborable_Initialization.)

         if Is_Generic_Type (E)
           and then Present (Preelab_Init_Expr)
           and then
             Type_Named_In_Preelab_Init_Expression (E, Preelab_Init_Expr)
         then
            return True;
         end if;

         --  If the derived type is a private extension then it doesn't have
         --  preelaborable initialization.

         if Ekind (Base_Type (E)) = E_Record_Type_With_Private then
            return False;
         end if;

         --  First check whether ancestor type has preelaborable initialization

         Has_PE := Has_Preelaborable_Initialization
                     (Etype (Base_Type (E)), Preelab_Init_Expr);

         --  If OK, check extension components (if any)

         if Has_PE and then Is_Record_Type (E) then
            Check_Components (E);
         end if;

         --  Check specifically for 10.2.1(11.4/2) exception: a controlled type
         --  with a user defined Initialize procedure does not have PI. If
         --  the type is untagged, the control primitives come from a component
         --  that has already been checked.

         if Has_PE
           and then Is_Controlled (E)
           and then Is_Tagged_Type (E)
           and then Has_Overriding_Initialize (E)
         then
            Has_PE := False;
         end if;

      --  Private types not derived from a type having preelaborable init and
      --  that are not marked with pragma Preelaborable_Initialization do not
      --  have preelaborable initialization.

      elsif Is_Private_Type (E) then

         --  When the rule of RM 10.2.1(11.8/5) applies, we presume a component
         --  of a generic formal private type has preelaborable initialization.
         --  (See comment on spec of Has_Preelaborable_Initialization.)

         if Is_Generic_Type (E)
           and then Present (Preelab_Init_Expr)
           and then
             Type_Named_In_Preelab_Init_Expression (E, Preelab_Init_Expr)
         then
            return True;
         else
            return False;
         end if;

      --  Record type has PI if it is non private and all components have PI

      elsif Is_Record_Type (E) then
         Has_PE := True;
         Check_Components (E);

      --  Protected types must not have entries, and components must meet
      --  same set of rules as for record components.

      elsif Is_Protected_Type (E) then
         if Has_Entries (E) then
            Has_PE := False;
         else
            Has_PE := True;
            Check_Components (E);
         end if;

      --  Type System.Address always has preelaborable initialization

      elsif Is_RTE (E, RE_Address) then
         Has_PE := True;

      --  In all other cases, type does not have preelaborable initialization

      else
         return False;
      end if;

      --  If type has preelaborable initialization, cache result

      if Has_PE then
         Set_Known_To_Have_Preelab_Init (E);
      end if;

      return Has_PE;
   end Has_Preelaborable_Initialization;

   ----------------
   -- Has_Prefix --
   ----------------

   function Has_Prefix (N : Node_Id) return Boolean is
   begin
      return Nkind (N) in
        N_Attribute_Reference | N_Expanded_Name | N_Explicit_Dereference |
        N_Indexed_Component   | N_Reference     | N_Selected_Component   |
        N_Slice;
   end Has_Prefix;

   ---------------------------
   -- Has_Private_Component --
   ---------------------------

   function Has_Private_Component (Type_Id : Entity_Id) return Boolean is
      Btype     : Entity_Id := Base_Type (Type_Id);
      Component : Entity_Id;

   begin
      if Error_Posted (Type_Id)
        or else Error_Posted (Btype)
      then
         return False;
      end if;

      if Is_Class_Wide_Type (Btype) then
         Btype := Root_Type (Btype);
      end if;

      if Is_Private_Type (Btype) then
         declare
            UT : constant Entity_Id := Underlying_Type (Btype);
         begin
            if No (UT) then
               if No (Full_View (Btype)) then
                  return not Is_Generic_Type (Btype)
                            and then
                         not Is_Generic_Type (Root_Type (Btype));
               else
                  return not Is_Generic_Type (Root_Type (Full_View (Btype)));
               end if;
            else
               return not Is_Frozen (UT) and then Has_Private_Component (UT);
            end if;
         end;

      elsif Is_Array_Type (Btype) then
         return Has_Private_Component (Component_Type (Btype));

      elsif Is_Record_Type (Btype) then
         Component := First_Component (Btype);
         while Present (Component) loop
            if Has_Private_Component (Etype (Component)) then
               return True;
            end if;

            Next_Component (Component);
         end loop;

         return False;

      elsif Is_Protected_Type (Btype)
        and then Present (Corresponding_Record_Type (Btype))
      then
         return Has_Private_Component (Corresponding_Record_Type (Btype));

      else
         return False;
      end if;
   end Has_Private_Component;

   --------------------------------
   -- Has_Relaxed_Initialization --
   --------------------------------

   function Has_Relaxed_Initialization (E : Entity_Id) return Boolean is

      function Denotes_Relaxed_Parameter
        (Expr  : Node_Id;
         Param : Entity_Id)
         return Boolean;
      --  Returns True iff expression Expr denotes a formal parameter or
      --  function Param (through its attribute Result).

      -------------------------------
      -- Denotes_Relaxed_Parameter --
      -------------------------------

      function Denotes_Relaxed_Parameter
        (Expr  : Node_Id;
         Param : Entity_Id) return Boolean is
      begin
         if Nkind (Expr) in N_Identifier | N_Expanded_Name then
            return Entity (Expr) = Param;
         else
            pragma Assert (Is_Attribute_Result (Expr));
            return Entity (Prefix (Expr)) = Param;
         end if;
      end Denotes_Relaxed_Parameter;

   --  Start of processing for Has_Relaxed_Initialization

   begin
      --  When analyzing, we checked all syntax legality rules for the aspect
      --  Relaxed_Initialization, but didn't store the property anywhere (e.g.
      --  as an Einfo flag). To query the property we look directly at the AST,
      --  but now without any syntactic checks.

      case Ekind (E) is
         --  Abstract states have option Relaxed_Initialization

         when E_Abstract_State =>
            return Is_Relaxed_Initialization_State (E);

         --  Constants have this aspect attached directly; for deferred
         --  constants, the aspect is attached to the partial view.

         when E_Constant =>
            return Has_Aspect (E, Aspect_Relaxed_Initialization);

         --  Variables have this aspect attached directly

         when E_Variable =>
            return Has_Aspect (E, Aspect_Relaxed_Initialization);

         --  Types have this aspect attached directly (though we only allow it
         --  to be specified for the first subtype). For private types, the
         --  aspect is attached to the partial view.

         when Type_Kind =>
            pragma Assert (Is_First_Subtype (E));
            return Has_Aspect (E, Aspect_Relaxed_Initialization);

         --  Formal parameters and functions have the Relaxed_Initialization
         --  aspect attached to the subprogram entity and must be listed in
         --  the aspect expression.

         when Formal_Kind
            | E_Function
         =>
            declare
               Subp_Id     : Entity_Id;
               Aspect_Expr : Node_Id;
               Param_Expr  : Node_Id;
               Assoc       : Node_Id;

            begin
               if Is_Formal (E) then
                  Subp_Id := Scope (E);
               else
                  Subp_Id := E;
               end if;

               if Has_Aspect (Subp_Id, Aspect_Relaxed_Initialization) then
                  Aspect_Expr :=
                    Find_Value_Of_Aspect
                      (Subp_Id, Aspect_Relaxed_Initialization);

                  --  Aspect expression is either an aggregate with an optional
                  --  Boolean expression (which defaults to True), e.g.:
                  --
                  --    function F (X : Integer) return Integer
                  --      with Relaxed_Initialization => (X => True, F'Result);

                  if Nkind (Aspect_Expr) = N_Aggregate then

                     if Present (Component_Associations (Aspect_Expr)) then
                        Assoc := First (Component_Associations (Aspect_Expr));

                        while Present (Assoc) loop
                           if Denotes_Relaxed_Parameter
                             (First (Choices (Assoc)), E)
                           then
                              return
                                Is_True
                                  (Static_Boolean (Expression (Assoc)));
                           end if;

                           Next (Assoc);
                        end loop;
                     end if;

                     Param_Expr := First (Expressions (Aspect_Expr));

                     while Present (Param_Expr) loop
                        if Denotes_Relaxed_Parameter (Param_Expr, E) then
                           return True;
                        end if;

                        Next (Param_Expr);
                     end loop;

                     return False;

                  --  or it is a single identifier, e.g.:
                  --
                  --    function F (X : Integer) return Integer
                  --      with Relaxed_Initialization => X;

                  else
                     return Denotes_Relaxed_Parameter (Aspect_Expr, E);
                  end if;
               else
                  return False;
               end if;
            end;

         when others =>
            raise Program_Error;
      end case;
   end Has_Relaxed_Initialization;

   ----------------------
   -- Has_Signed_Zeros --
   ----------------------

   function Has_Signed_Zeros (E : Entity_Id) return Boolean is
   begin
      return Is_Floating_Point_Type (E) and then Signed_Zeros_On_Target;
   end Has_Signed_Zeros;

   ------------------------------
   -- Has_Significant_Contract --
   ------------------------------

   function Has_Significant_Contract (Subp_Id : Entity_Id) return Boolean is
      Subp_Nam : constant Name_Id := Chars (Subp_Id);

   begin
      --  _Finalizer procedure

      if Subp_Nam = Name_uFinalizer then
         return False;

      --  _Wrapped_Statements procedure which gets generated as part of the
      --  expansion of postconditions.

      elsif Subp_Nam = Name_uWrapped_Statements then
         return False;

      --  Predicate function

      elsif Ekind (Subp_Id) = E_Function
        and then Is_Predicate_Function (Subp_Id)
      then
         return False;

      --  TSS subprogram

      elsif Get_TSS_Name (Subp_Id) /= TSS_Null then
         return False;

      else
         return True;
      end if;
   end Has_Significant_Contract;

   -----------------------------
   -- Has_Static_Array_Bounds --
   -----------------------------

   function Has_Static_Array_Bounds (Typ : Node_Id) return Boolean is
      All_Static : Boolean;
      Dummy      : Boolean;

   begin
      Examine_Array_Bounds (Typ, All_Static, Dummy);

      return All_Static;
   end Has_Static_Array_Bounds;

   ---------------------------------------
   -- Has_Static_Non_Empty_Array_Bounds --
   ---------------------------------------

   function Has_Static_Non_Empty_Array_Bounds (Typ : Node_Id) return Boolean is
      All_Static : Boolean;
      Has_Empty  : Boolean;

   begin
      Examine_Array_Bounds (Typ, All_Static, Has_Empty);

      return All_Static and not Has_Empty;
   end Has_Static_Non_Empty_Array_Bounds;

   ----------------
   -- Has_Stream --
   ----------------

   function Has_Stream (T : Entity_Id) return Boolean is
      E : Entity_Id;

   begin
      if No (T) then
         return False;

      elsif Is_RTE (Root_Type (T), RE_Root_Stream_Type) then
         return True;

      elsif Is_Array_Type (T) then
         return Has_Stream (Component_Type (T));

      elsif Is_Record_Type (T) then
         E := First_Component (T);
         while Present (E) loop
            if Has_Stream (Etype (E)) then
               return True;
            else
               Next_Component (E);
            end if;
         end loop;

         return False;

      elsif Is_Private_Type (T) then
         return Has_Stream (Underlying_Type (T));

      else
         return False;
      end if;
   end Has_Stream;

   ----------------
   -- Has_Suffix --
   ----------------

   function Has_Suffix (E : Entity_Id; Suffix : Character) return Boolean is
   begin
      Get_Name_String (Chars (E));
      return Name_Buffer (Name_Len) = Suffix;
   end Has_Suffix;

   ----------------
   -- Add_Suffix --
   ----------------

   function Add_Suffix (E : Entity_Id; Suffix : Character) return Name_Id is
   begin
      Get_Name_String (Chars (E));
      Add_Char_To_Name_Buffer (Suffix);
      return Name_Find;
   end Add_Suffix;

   -------------------
   -- Remove_Suffix --
   -------------------

   function Remove_Suffix (E : Entity_Id; Suffix : Character) return Name_Id is
   begin
      pragma Assert (Has_Suffix (E, Suffix));
      Get_Name_String (Chars (E));
      Name_Len := Name_Len - 1;
      return Name_Find;
   end Remove_Suffix;

   ----------------------------------
   -- Replace_Null_By_Null_Address --
   ----------------------------------

   procedure Replace_Null_By_Null_Address (N : Node_Id) is
      procedure Replace_Null_Operand (Op : Node_Id; Other_Op : Node_Id);
      --  Replace operand Op with a reference to Null_Address when the operand
      --  denotes a null Address. Other_Op denotes the other operand.

      --------------------------
      -- Replace_Null_Operand --
      --------------------------

      procedure Replace_Null_Operand (Op : Node_Id; Other_Op : Node_Id) is
      begin
         --  Check the type of the complementary operand since the N_Null node
         --  has not been decorated yet.

         if Nkind (Op) = N_Null
           and then Is_Descendant_Of_Address (Etype (Other_Op))
         then
            Rewrite (Op, New_Occurrence_Of (RTE (RE_Null_Address), Sloc (Op)));
         end if;
      end Replace_Null_Operand;

   --  Start of processing for Replace_Null_By_Null_Address

   begin
      pragma Assert (Relaxed_RM_Semantics);
      pragma Assert (Nkind (N) in N_Null | N_Op_Compare);

      if Nkind (N) = N_Null then
         Rewrite (N, New_Occurrence_Of (RTE (RE_Null_Address), Sloc (N)));

      else
         declare
            L : constant Node_Id := Left_Opnd  (N);
            R : constant Node_Id := Right_Opnd (N);

         begin
            Replace_Null_Operand (L, Other_Op => R);
            Replace_Null_Operand (R, Other_Op => L);
         end;
      end if;
   end Replace_Null_By_Null_Address;

   --------------------------
   -- Has_Tagged_Component --
   --------------------------

   function Has_Tagged_Component (Typ : Entity_Id) return Boolean is
      Comp : Entity_Id;

   begin
      if Is_Private_Type (Typ) and then Present (Underlying_Type (Typ)) then
         return Has_Tagged_Component (Underlying_Type (Typ));

      elsif Is_Array_Type (Typ) then
         return Has_Tagged_Component (Component_Type (Typ));

      elsif Is_Tagged_Type (Typ) then
         return True;

      elsif Is_Record_Type (Typ) then
         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Has_Tagged_Component (Etype (Comp)) then
               return True;
            end if;

            Next_Component (Comp);
         end loop;

         return False;

      else
         return False;
      end if;
   end Has_Tagged_Component;

   -----------------------------
   -- Has_Undefined_Reference --
   -----------------------------

   function Has_Undefined_Reference (Expr : Node_Id) return Boolean is
      Has_Undef_Ref : Boolean := False;
      --  Flag set when expression Expr contains at least one undefined
      --  reference.

      function Is_Undefined_Reference (N : Node_Id) return Traverse_Result;
      --  Determine whether N denotes a reference and if it does, whether it is
      --  undefined.

      ----------------------------
      -- Is_Undefined_Reference --
      ----------------------------

      function Is_Undefined_Reference (N : Node_Id) return Traverse_Result is
      begin
         if Is_Entity_Name (N)
           and then Present (Entity (N))
           and then Entity (N) = Any_Id
         then
            Has_Undef_Ref := True;
            return Abandon;
         end if;

         return OK;
      end Is_Undefined_Reference;

      procedure Find_Undefined_References is
        new Traverse_Proc (Is_Undefined_Reference);

   --  Start of processing for Has_Undefined_Reference

   begin
      Find_Undefined_References (Expr);

      return Has_Undef_Ref;
   end Has_Undefined_Reference;

   ----------------------------------------
   -- Has_Effectively_Volatile_Component --
   ----------------------------------------

   function Has_Effectively_Volatile_Component
     (Typ : Entity_Id) return Boolean
   is
      Comp : Entity_Id;

   begin
      if Has_Volatile_Components (Typ) then
         return True;

      elsif Is_Array_Type (Typ) then
         return Is_Effectively_Volatile (Component_Type (Typ));

      elsif Is_Record_Type (Typ) then
         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Is_Effectively_Volatile (Etype (Comp)) then
               return True;
            end if;

            Next_Component (Comp);
         end loop;
      end if;

      return False;
   end Has_Effectively_Volatile_Component;

   ----------------------------
   -- Has_Volatile_Component --
   ----------------------------

   function Has_Volatile_Component (Typ : Entity_Id) return Boolean is
      Comp : Entity_Id;

   begin
      if Has_Volatile_Components (Typ) then
         return True;

      elsif Is_Array_Type (Typ) then
         return Is_Volatile (Component_Type (Typ));

      elsif Is_Record_Type (Typ) then
         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Is_Volatile_Object_Ref (Comp) then
               return True;
            end if;

            Next_Component (Comp);
         end loop;
      end if;

      return False;
   end Has_Volatile_Component;

   -------------------------
   -- Implementation_Kind --
   -------------------------

   function Implementation_Kind (Subp : Entity_Id) return Name_Id is
      Impl_Prag : constant Node_Id := Get_Rep_Pragma (Subp, Name_Implemented);
      Arg       : Node_Id;
   begin
      pragma Assert (Present (Impl_Prag));
      Arg := Last (Pragma_Argument_Associations (Impl_Prag));
      return Chars (Get_Pragma_Arg (Arg));
   end Implementation_Kind;

   --------------------------
   -- Implements_Interface --
   --------------------------

   function Implements_Interface
     (Typ_Ent         : Entity_Id;
      Iface_Ent       : Entity_Id;
      Exclude_Parents : Boolean := False) return Boolean
   is
      Ifaces_List : Elist_Id;
      Elmt        : Elmt_Id;
      Iface       : Entity_Id := Base_Type (Iface_Ent);
      Typ         : Entity_Id := Base_Type (Typ_Ent);

   begin
      if Is_Class_Wide_Type (Typ) then
         Typ := Root_Type (Typ);
      end if;

      if not Has_Interfaces (Typ) then
         return False;
      end if;

      if Is_Class_Wide_Type (Iface) then
         Iface := Root_Type (Iface);
      end if;

      Collect_Interfaces (Typ, Ifaces_List);

      Elmt := First_Elmt (Ifaces_List);
      while Present (Elmt) loop
         if Is_Ancestor (Node (Elmt), Typ, Use_Full_View => True)
           and then Exclude_Parents
         then
            null;

         elsif Node (Elmt) = Iface then
            return True;
         end if;

         Next_Elmt (Elmt);
      end loop;

      return False;
   end Implements_Interface;

   --------------------------------
   -- Implicitly_Designated_Type --
   --------------------------------

   function Implicitly_Designated_Type (Typ : Entity_Id) return Entity_Id is
      Desig : constant Entity_Id := Designated_Type (Typ);

   begin
      --  An implicit dereference is a legal occurrence of an incomplete type
      --  imported through a limited_with clause, if the full view is visible.

      if Is_Incomplete_Type (Desig)
        and then From_Limited_With (Desig)
        and then not From_Limited_With (Scope (Desig))
        and then
          (Is_Immediately_Visible (Scope (Desig))
            or else
              (Is_Child_Unit (Scope (Desig))
                and then Is_Visible_Lib_Unit (Scope (Desig))))
      then
         return Available_View (Desig);
      else
         return Desig;
      end if;
   end Implicitly_Designated_Type;

   ------------------------------------
   -- In_Assertion_Expression_Pragma --
   ------------------------------------

   function In_Assertion_Expression_Pragma (N : Node_Id) return Boolean is
      Par  : Node_Id;
      Prag : Node_Id := Empty;

   begin
      --  Climb the parent chain looking for an enclosing pragma

      Par := N;
      while Present (Par) loop
         if Nkind (Par) = N_Pragma then
            Prag := Par;
            exit;

         --  Precondition-like pragmas are expanded into if statements, check
         --  the original node instead.

         elsif Nkind (Original_Node (Par)) = N_Pragma then
            Prag := Original_Node (Par);
            exit;

         --  The expansion of attribute 'Old generates a constant to capture
         --  the result of the prefix. If the parent traversal reaches
         --  one of these constants, then the node technically came from a
         --  postcondition-like pragma. Note that the Ekind is not tested here
         --  because N may be the expression of an object declaration which is
         --  currently being analyzed. Such objects carry Ekind of E_Void.

         elsif Nkind (Par) = N_Object_Declaration
           and then Constant_Present (Par)
           and then Stores_Attribute_Old_Prefix (Defining_Entity (Par))
         then
            return True;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            return False;
         end if;

         Par := Parent (Par);
      end loop;

      return
        Present (Prag)
          and then Assertion_Expression_Pragma (Get_Pragma_Id (Prag));
   end In_Assertion_Expression_Pragma;

   -------------------
   -- In_Check_Node --
   -------------------

   function In_Check_Node (N : Node_Id) return Boolean is
      Par : Node_Id := Parent (N);
   begin
      while Present (Par) loop
         if Nkind (Par) in N_Raise_xxx_Error then
            return True;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            return False;

         else
            Par := Parent (Par);
         end if;
      end loop;

      return False;
   end In_Check_Node;

   -------------------------------
   -- In_Generic_Formal_Package --
   -------------------------------

   function In_Generic_Formal_Package (E : Entity_Id) return Boolean is
      Par : Node_Id;

   begin
      Par := Parent (E);
      while Present (Par) loop
         if Nkind (Par) = N_Formal_Package_Declaration
           or else Nkind (Original_Node (Par)) = N_Formal_Package_Declaration
         then
            return True;
         end if;

         Par := Parent (Par);
      end loop;

      return False;
   end In_Generic_Formal_Package;

   ----------------------
   -- In_Generic_Scope --
   ----------------------

   function In_Generic_Scope (E : Entity_Id) return Boolean is
      S : Entity_Id;

   begin
      S := Scope (E);
      while Present (S) and then S /= Standard_Standard loop
         if Is_Generic_Unit (S) then
            return True;
         end if;

         S := Scope (S);
      end loop;

      return False;
   end In_Generic_Scope;

   -----------------
   -- In_Instance --
   -----------------

   function In_Instance return Boolean is
      Curr_Unit : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
      S         : Entity_Id;

   begin
      S := Current_Scope;
      while Present (S) and then S /= Standard_Standard loop
         if Is_Generic_Instance (S) then

            --  A child instance is always compiled in the context of a parent
            --  instance. Nevertheless, its actuals must not be analyzed in an
            --  instance context. We detect this case by examining the current
            --  compilation unit, which must be a child instance, and checking
            --  that it has not been analyzed yet.

            if Is_Child_Unit (Curr_Unit)
              and then Nkind (Unit (Cunit (Current_Sem_Unit))) =
                                                     N_Package_Instantiation
              and then Ekind (Curr_Unit) = E_Void
            then
               return False;
            else
               return True;
            end if;
         end if;

         S := Scope (S);
      end loop;

      return False;
   end In_Instance;

   ----------------------
   -- In_Instance_Body --
   ----------------------

   function In_Instance_Body return Boolean is
      S : Entity_Id;

   begin
      S := Current_Scope;
      while Present (S) and then S /= Standard_Standard loop
         if Ekind (S) in E_Function | E_Procedure
           and then Is_Generic_Instance (S)
         then
            return True;

         elsif Ekind (S) = E_Package
           and then In_Package_Body (S)
           and then Is_Generic_Instance (S)
         then
            return True;
         end if;

         S := Scope (S);
      end loop;

      return False;
   end In_Instance_Body;

   -----------------------------
   -- In_Instance_Not_Visible --
   -----------------------------

   function In_Instance_Not_Visible return Boolean is
      S : Entity_Id;

   begin
      S := Current_Scope;
      while Present (S) and then S /= Standard_Standard loop
         if Ekind (S) in E_Function | E_Procedure
           and then Is_Generic_Instance (S)
         then
            return True;

         elsif Ekind (S) = E_Package
           and then (In_Package_Body (S) or else In_Private_Part (S))
           and then Is_Generic_Instance (S)
         then
            return True;
         end if;

         S := Scope (S);
      end loop;

      return False;
   end In_Instance_Not_Visible;

   ------------------------------
   -- In_Instance_Visible_Part --
   ------------------------------

   function In_Instance_Visible_Part
     (Id : Entity_Id := Current_Scope) return Boolean
   is
      Inst : Entity_Id;

   begin
      Inst := Id;
      while Present (Inst) and then Inst /= Standard_Standard loop
         if Ekind (Inst) = E_Package
           and then Is_Generic_Instance (Inst)
           and then not In_Package_Body (Inst)
           and then not In_Private_Part (Inst)
         then
            return True;
         end if;

         Inst := Scope (Inst);
      end loop;

      return False;
   end In_Instance_Visible_Part;

   ---------------------
   -- In_Package_Body --
   ---------------------

   function In_Package_Body return Boolean is
      S : Entity_Id;

   begin
      S := Current_Scope;
      while Present (S) and then S /= Standard_Standard loop
         if Ekind (S) = E_Package and then In_Package_Body (S) then
            return True;
         else
            S := Scope (S);
         end if;
      end loop;

      return False;
   end In_Package_Body;

   --------------------------
   -- In_Pragma_Expression --
   --------------------------

   function In_Pragma_Expression (N : Node_Id; Nam : Name_Id) return Boolean is
      P : Node_Id;
   begin
      P := Parent (N);
      loop
         if No (P) then
            return False;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (P) then
            return False;

         elsif Nkind (P) = N_Pragma and then Pragma_Name (P) = Nam then
            return True;

         else
            P := Parent (P);
         end if;
      end loop;
   end In_Pragma_Expression;

   ---------------------------
   -- In_Pre_Post_Condition --
   ---------------------------

   function In_Pre_Post_Condition
     (N : Node_Id; Class_Wide_Only : Boolean := False) return Boolean
   is
      Par     : Node_Id;
      Prag    : Node_Id := Empty;
      Prag_Id : Pragma_Id;

   begin
      --  Climb the parent chain looking for an enclosing pragma

      Par := N;
      while Present (Par) loop
         if Nkind (Par) = N_Pragma then
            Prag := Par;
            exit;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            exit;
         end if;

         Par := Parent (Par);
      end loop;

      if Present (Prag) then
         Prag_Id := Get_Pragma_Id (Prag);

         if Class_Wide_Only then
            return
              Prag_Id = Pragma_Post_Class
                or else Prag_Id = Pragma_Pre_Class
                or else (Class_Present (Prag)
                          and then (Prag_Id = Pragma_Post
                                     or else Prag_Id = Pragma_Postcondition
                                     or else Prag_Id = Pragma_Pre
                                     or else Prag_Id = Pragma_Precondition));
         else
            return
              Prag_Id = Pragma_Post
                or else Prag_Id = Pragma_Post_Class
                or else Prag_Id = Pragma_Postcondition
                or else Prag_Id = Pragma_Pre
                or else Prag_Id = Pragma_Pre_Class
                or else Prag_Id = Pragma_Precondition;
         end if;

      --  Otherwise the node is not enclosed by a pre/postcondition pragma

      else
         return False;
      end if;
   end In_Pre_Post_Condition;

   ------------------------------
   -- In_Quantified_Expression --
   ------------------------------

   function In_Quantified_Expression (N : Node_Id) return Boolean is
      P : Node_Id;
   begin
      P := Parent (N);
      loop
         if No (P) then
            return False;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (P) then
            return False;

         elsif Nkind (P) = N_Quantified_Expression then
            return True;
         else
            P := Parent (P);
         end if;
      end loop;
   end In_Quantified_Expression;

   -------------------------------------
   -- In_Reverse_Storage_Order_Object --
   -------------------------------------

   function In_Reverse_Storage_Order_Object (N : Node_Id) return Boolean is
      Pref : Node_Id;
      Btyp : Entity_Id := Empty;

   begin
      --  Climb up indexed components

      Pref := N;
      loop
         case Nkind (Pref) is
            when N_Selected_Component =>
               Pref := Prefix (Pref);
               exit;

            when N_Indexed_Component =>
               Pref := Prefix (Pref);

            when others =>
               Pref := Empty;
               exit;
         end case;
      end loop;

      if Present (Pref) then
         Btyp := Base_Type (Etype (Pref));
      end if;

      return Present (Btyp)
        and then (Is_Record_Type (Btyp) or else Is_Array_Type (Btyp))
        and then Reverse_Storage_Order (Btyp);
   end In_Reverse_Storage_Order_Object;

   ------------------------------
   -- In_Same_Declarative_Part --
   ------------------------------

   function In_Same_Declarative_Part
     (Context : Node_Id;
      N       : Node_Id) return Boolean
   is
      Cont : Node_Id := Context;
      Nod  : Node_Id;

   begin
      if Nkind (Cont) = N_Compilation_Unit_Aux then
         Cont := Parent (Cont);
      end if;

      Nod := Parent (N);
      while Present (Nod) loop
         if Nod = Cont then
            return True;

         elsif Nkind (Nod) in N_Accept_Statement
                            | N_Block_Statement
                            | N_Compilation_Unit
                            | N_Entry_Body
                            | N_Package_Body
                            | N_Package_Declaration
                            | N_Protected_Body
                            | N_Subprogram_Body
                            | N_Task_Body
         then
            return False;

         elsif Nkind (Nod) = N_Subunit then
            Nod := Corresponding_Stub (Nod);

         else
            Nod := Parent (Nod);
         end if;
      end loop;

      return False;
   end In_Same_Declarative_Part;

   --------------------------------------
   -- In_Subprogram_Or_Concurrent_Unit --
   --------------------------------------

   function In_Subprogram_Or_Concurrent_Unit return Boolean is
      E : Entity_Id;
      K : Entity_Kind;

   begin
      --  Use scope chain to check successively outer scopes

      E := Current_Scope;
      loop
         K := Ekind (E);

         if K in Subprogram_Kind
           or else K in Concurrent_Kind
           or else K in Generic_Subprogram_Kind
         then
            return True;

         elsif E = Standard_Standard then
            return False;
         end if;

         E := Scope (E);
      end loop;
   end In_Subprogram_Or_Concurrent_Unit;

   ----------------
   -- In_Subtree --
   ----------------

   function In_Subtree (N : Node_Id; Root : Node_Id) return Boolean is
      Curr : Node_Id;

   begin
      Curr := N;
      while Present (Curr) loop
         if Curr = Root then
            return True;
         end if;

         Curr := Parent (Curr);
      end loop;

      return False;
   end In_Subtree;

   ----------------
   -- In_Subtree --
   ----------------

   function In_Subtree
     (N     : Node_Id;
      Root1 : Node_Id;
      Root2 : Node_Id) return Boolean
   is
      Curr : Node_Id;

   begin
      Curr := N;
      while Present (Curr) loop
         if Curr = Root1 or else Curr = Root2 then
            return True;
         end if;

         Curr := Parent (Curr);
      end loop;

      return False;
   end In_Subtree;

   ---------------------
   -- In_Return_Value --
   ---------------------

   function In_Return_Value (Expr : Node_Id) return Boolean is
      Par              : Node_Id;
      Prev_Par         : Node_Id;
      Pre              : Node_Id;
      In_Function_Call : Boolean := False;

   begin
      --  Move through parent nodes to determine if Expr contributes to the
      --  return value of the current subprogram.

      Par      := Expr;
      Prev_Par := Empty;
      while Present (Par) loop

         case Nkind (Par) is
            --  Ignore ranges and they don't contribute to the result

            when N_Range =>
               return False;

            --  An object declaration whose parent is an extended return
            --  statement is a return object.

            when N_Object_Declaration =>
               if Present (Parent (Par))
                 and then Nkind (Parent (Par)) = N_Extended_Return_Statement
               then
                  return True;
               end if;

            --  We hit a simple return statement, so we know we are in one

            when N_Simple_Return_Statement =>
               return True;

            --  Only include one nexting level of function calls

            when N_Function_Call =>
               if not In_Function_Call then
                  In_Function_Call := True;

                  --  When the function return type has implicit dereference
                  --  specified we know it cannot directly contribute to the
                  --  return value.

                  if Present (Etype (Par))
                    and then Has_Implicit_Dereference
                               (Get_Full_View (Etype (Par)))
                  then
                     return False;
                  end if;
               else
                  return False;
               end if;

            --  Check if we are on the right-hand side of an assignment
            --  statement to a return object.

            --  This is not specified in the RM ???

            when N_Assignment_Statement =>
               if Prev_Par = Name (Par) then
                  return False;
               end if;

               Pre := Name (Par);
               while Present (Pre) loop
                  if Is_Entity_Name (Pre)
                    and then Is_Return_Object (Entity (Pre))
                  then
                     return True;
                  end if;

                  exit when Nkind (Pre) not in N_Selected_Component
                                             | N_Indexed_Component
                                             | N_Slice;

                  Pre := Prefix (Pre);
               end loop;

            --  Otherwise, we hit a master which was not relevant

            when others =>
               if Is_Master (Par) then
                  return False;
               end if;
         end case;

         --  Iterate up to the next parent, keeping track of the previous one

         Prev_Par := Par;
         Par      := Parent (Par);
      end loop;

      return False;
   end In_Return_Value;

   -----------------------------------------
   -- In_Statement_Condition_With_Actions --
   -----------------------------------------

   function In_Statement_Condition_With_Actions (N : Node_Id) return Boolean is
      Prev : Node_Id := N;
      P    : Node_Id := Parent (N);
      --  P and Prev will be used for traversing the AST, while maintaining an
      --  invariant that P = Parent (Prev).
   begin
      while Present (P) loop
         if Nkind (P) = N_Iteration_Scheme
           and then Prev = Condition (P)
         then
            return True;

         elsif Nkind (P) = N_Elsif_Part
           and then Prev = Condition (P)
         then
            return True;

         --  No point in going beyond statements

         elsif Nkind (N) in N_Statement_Other_Than_Procedure_Call
                          | N_Procedure_Call_Statement
         then
            exit;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (P) then
            exit;
         end if;

         Prev := P;
         P := Parent (P);
      end loop;

      return False;
   end In_Statement_Condition_With_Actions;

   ---------------------
   -- In_Visible_Part --
   ---------------------

   function In_Visible_Part (Scope_Id : Entity_Id) return Boolean is
   begin
      return Is_Package_Or_Generic_Package (Scope_Id)
        and then In_Open_Scopes (Scope_Id)
        and then not In_Package_Body (Scope_Id)
        and then not In_Private_Part (Scope_Id);
   end In_Visible_Part;

   --------------------------------
   -- Incomplete_Or_Partial_View --
   --------------------------------

   function Incomplete_Or_Partial_View (Id : Entity_Id) return Entity_Id is
      S : constant Entity_Id := Scope (Id);

      function Inspect_Decls
        (Decls : List_Id;
         Taft  : Boolean := False) return Entity_Id;
      --  Check whether a declarative region contains the incomplete or partial
      --  view of Id.

      -------------------
      -- Inspect_Decls --
      -------------------

      function Inspect_Decls
        (Decls : List_Id;
         Taft  : Boolean := False) return Entity_Id
      is
         Decl  : Node_Id;
         Match : Node_Id;

      begin
         Decl := First (Decls);
         while Present (Decl) loop
            Match := Empty;

            --  The partial view of a Taft-amendment type is an incomplete
            --  type.

            if Taft then
               if Nkind (Decl) = N_Incomplete_Type_Declaration then
                  Match := Defining_Identifier (Decl);
               end if;

            --  Otherwise look for a private type whose full view matches the
            --  input type. Note that this checks full_type_declaration nodes
            --  to account for derivations from a private type where the type
            --  declaration hold the partial view and the full view is an
            --  itype.

            elsif Nkind (Decl) in N_Full_Type_Declaration
                                | N_Private_Extension_Declaration
                                | N_Private_Type_Declaration
            then
               Match := Defining_Identifier (Decl);
            end if;

            --  Guard against unanalyzed entities

            if Present (Match)
              and then Is_Type (Match)
              and then Present (Full_View (Match))
              and then Full_View (Match) = Id
            then
               return Match;
            end if;

            Next (Decl);
         end loop;

         return Empty;
      end Inspect_Decls;

      --  Local variables

      Prev : Entity_Id;

   --  Start of processing for Incomplete_Or_Partial_View

   begin
      --  Deferred constant or incomplete type case

      Prev := Current_Entity (Id);

      while Present (Prev) loop
         exit when Scope (Prev) = S;

         Prev := Homonym (Prev);
      end loop;

      if Present (Prev)
        and then (Is_Incomplete_Type (Prev) or else Ekind (Prev) = E_Constant)
        and then Present (Full_View (Prev))
        and then Full_View (Prev) = Id
      then
         return Prev;
      end if;

      --  Private or Taft amendment type case

      if Present (S) and then Is_Package_Or_Generic_Package (S) then
         declare
            Pkg_Decl : constant Node_Id := Package_Specification (S);

         begin
            --  It is knows that Typ has a private view, look for it in the
            --  visible declarations of the enclosing scope. A special case
            --  of this is when the two views have been exchanged - the full
            --  appears earlier than the private.

            if Has_Private_Declaration (Id) then
               Prev := Inspect_Decls (Visible_Declarations (Pkg_Decl));

               --  Exchanged view case, look in the private declarations

               if No (Prev) then
                  Prev := Inspect_Decls (Private_Declarations (Pkg_Decl));
               end if;

               return Prev;

            --  Otherwise if this is the package body, then Typ is a potential
            --  Taft amendment type. The incomplete view should be located in
            --  the private declarations of the enclosing scope.

            elsif In_Package_Body (S) then
               return Inspect_Decls (Private_Declarations (Pkg_Decl), True);
            end if;
         end;
      end if;

      --  The type has no incomplete or private view

      return Empty;
   end Incomplete_Or_Partial_View;

   ---------------------------------------
   -- Incomplete_View_From_Limited_With --
   ---------------------------------------

   function Incomplete_View_From_Limited_With
     (Typ : Entity_Id) return Entity_Id
   is
   begin
      --  It might make sense to make this an attribute in Einfo, and set it
      --  in Sem_Ch10 in Build_Shadow_Entity. However, we're running short on
      --  slots for new attributes, and it seems a bit simpler to just search
      --  the Limited_View (if it exists) for an incomplete type whose
      --  Non_Limited_View is Typ.

      if Ekind (Scope (Typ)) = E_Package
        and then Present (Limited_View (Scope (Typ)))
      then
         declare
            Ent : Entity_Id := First_Entity (Limited_View (Scope (Typ)));
         begin
            while Present (Ent) loop
               if Is_Incomplete_Type (Ent)
                 and then Non_Limited_View (Ent) = Typ
               then
                  return Ent;
               end if;

               Next_Entity (Ent);
            end loop;
         end;
      end if;

      return Typ;
   end Incomplete_View_From_Limited_With;

   ----------------------------------
   -- Indexed_Component_Bit_Offset --
   ----------------------------------

   function Indexed_Component_Bit_Offset (N : Node_Id) return Uint is
      Exp : constant Node_Id   := First (Expressions (N));
      Typ : constant Entity_Id := Etype (Prefix (N));
      Off : constant Uint      := Component_Size (Typ);
      Ind : Node_Id;

   begin
      --  Return early if the component size is not known or variable

      if No (Off) or else Off < Uint_0 then
         return No_Uint;
      end if;

      --  Deal with the degenerate case of an empty component

      if Off = Uint_0 then
         return Off;
      end if;

      --  Check that both the index value and the low bound are known

      if not Compile_Time_Known_Value (Exp) then
         return No_Uint;
      end if;

      Ind := First_Index (Typ);
      if No (Ind) then
         return No_Uint;
      end if;

      --  Do not attempt to compute offsets within multi-dimensional arrays

      if Present (Next_Index (Ind)) then
         return No_Uint;
      end if;

      if Nkind (Ind) = N_Subtype_Indication then
         Ind := Constraint (Ind);

         if Nkind (Ind) = N_Range_Constraint then
            Ind := Range_Expression (Ind);
         end if;
      end if;

      if Nkind (Ind) /= N_Range
        or else not Compile_Time_Known_Value (Low_Bound (Ind))
      then
         return No_Uint;
      end if;

      --  Return the scaled offset

      return Off * (Expr_Value (Exp) - Expr_Value (Low_Bound (Ind)));
   end Indexed_Component_Bit_Offset;

   -----------------------------
   -- Inherit_Predicate_Flags --
   -----------------------------

   procedure Inherit_Predicate_Flags
     (Subt, Par  : Entity_Id;
      Only_Flags : Boolean := False)
   is
   begin
      if Ada_Version < Ada_2012
        or else Present (Predicate_Function (Subt))
      then
         return;
      end if;

      Set_Has_Predicates (Subt, Has_Predicates (Par));
      Set_Has_Static_Predicate_Aspect
        (Subt, Has_Static_Predicate_Aspect (Par));
      Set_Has_Dynamic_Predicate_Aspect
        (Subt, Has_Dynamic_Predicate_Aspect (Par));
      Set_Has_Ghost_Predicate_Aspect
        (Subt, Has_Ghost_Predicate_Aspect (Par));

      --  A named subtype does not inherit the predicate function of its
      --  parent but an itype declared for a loop index needs the discrete
      --  predicate information of its parent to execute the loop properly.
      --  A non-discrete type may has a static predicate (for example True)
      --  but has no static_discrete_predicate.

      if not Only_Flags
        and then Is_Itype (Subt)
        and then Present (Predicate_Function (Par))
      then
         Set_Subprograms_For_Type (Subt, Subprograms_For_Type (Par));

         if Has_Static_Predicate (Par) and then Is_Discrete_Type (Par) then
            Set_Static_Discrete_Predicate
              (Subt, Static_Discrete_Predicate (Par));
         end if;
      end if;
   end Inherit_Predicate_Flags;

   ----------------------------
   -- Inherit_Rep_Item_Chain --
   ----------------------------

   procedure Inherit_Rep_Item_Chain (Typ : Entity_Id; From_Typ : Entity_Id) is
      Item      : Node_Id;
      Next_Item : Node_Id;

   begin
      --  There are several inheritance scenarios to consider depending on
      --  whether both types have rep item chains and whether the destination
      --  type already inherits part of the source type's rep item chain.

      --  1) The source type lacks a rep item chain
      --     From_Typ ---> Empty
      --
      --     Typ --------> Item (or Empty)

      --  In this case inheritance cannot take place because there are no items
      --  to inherit.

      --  2) The destination type lacks a rep item chain
      --     From_Typ ---> Item ---> ...
      --
      --     Typ --------> Empty

      --  Inheritance takes place by setting the First_Rep_Item of the
      --  destination type to the First_Rep_Item of the source type.
      --     From_Typ ---> Item ---> ...
      --                    ^
      --     Typ -----------+

      --  3.1) Both source and destination types have at least one rep item.
      --  The destination type does NOT inherit a rep item from the source
      --  type.
      --     From_Typ ---> Item ---> Item
      --
      --     Typ --------> Item ---> Item

      --  Inheritance takes place by setting the Next_Rep_Item of the last item
      --  of the destination type to the First_Rep_Item of the source type.
      --     From_Typ -------------------> Item ---> Item
      --                                    ^
      --     Typ --------> Item ---> Item --+

      --  3.2) Both source and destination types have at least one rep item.
      --  The destination type DOES inherit part of the rep item chain of the
      --  source type.
      --     From_Typ ---> Item ---> Item ---> Item
      --                              ^
      --     Typ --------> Item ------+

      --  This rare case arises when the full view of a private extension must
      --  inherit the rep item chain from the full view of its parent type and
      --  the full view of the parent type contains extra rep items. Currently
      --  only invariants may lead to such form of inheritance.

      --     type From_Typ is tagged private
      --       with Type_Invariant'Class => Item_2;

      --     type Typ is new From_Typ with private
      --       with Type_Invariant => Item_4;

      --  At this point the rep item chains contain the following items

      --     From_Typ -----------> Item_2 ---> Item_3
      --                            ^
      --     Typ --------> Item_4 --+

      --  The full views of both types may introduce extra invariants

      --     type From_Typ is tagged null record
      --       with Type_Invariant => Item_1;

      --     type Typ is new From_Typ with null record;

      --  The full view of Typ would have to inherit any new rep items added to
      --  the full view of From_Typ.

      --     From_Typ -----------> Item_1 ---> Item_2 ---> Item_3
      --                            ^
      --     Typ --------> Item_4 --+

      --  To achieve this form of inheritance, the destination type must first
      --  sever the link between its own rep chain and that of the source type,
      --  then inheritance 3.1 takes place.

      --  Case 1: The source type lacks a rep item chain

      if No (First_Rep_Item (From_Typ)) then
         return;

      --  Case 2: The destination type lacks a rep item chain

      elsif No (First_Rep_Item (Typ)) then
         Set_First_Rep_Item (Typ, First_Rep_Item (From_Typ));

      --  Case 3: Both the source and destination types have at least one rep
      --  item. Traverse the rep item chain of the destination type to find the
      --  last rep item.

      else
         Item      := Empty;
         Next_Item := First_Rep_Item (Typ);
         while Present (Next_Item) loop

            --  Detect a link between the destination type's rep chain and that
            --  of the source type. There are two possibilities:

            --    Variant 1
            --                  Next_Item
            --                      V
            --       From_Typ ---> Item_1 --->
            --                      ^
            --       Typ -----------+
            --
            --       Item is Empty

            --    Variant 2
            --                              Next_Item
            --                                  V
            --       From_Typ ---> Item_1 ---> Item_2 --->
            --                                  ^
            --       Typ --------> Item_3 ------+
            --                      ^
            --                     Item

            if Present_In_Rep_Item (From_Typ, Next_Item) then
               exit;
            end if;

            Item      := Next_Item;
            Next_Item := Next_Rep_Item (Next_Item);
         end loop;

         --  Inherit the source type's rep item chain

         if Present (Item) then
            Set_Next_Rep_Item (Item, First_Rep_Item (From_Typ));
         else
            Set_First_Rep_Item (Typ, First_Rep_Item (From_Typ));
         end if;
      end if;
   end Inherit_Rep_Item_Chain;

   ------------------------------------
   -- Inherits_From_Tagged_Full_View --
   ------------------------------------

   function Inherits_From_Tagged_Full_View (Typ : Entity_Id) return Boolean is
   begin
      return Is_Private_Type (Typ)
        and then Present (Full_View (Typ))
        and then Is_Private_Type (Full_View (Typ))
        and then not Is_Tagged_Type (Full_View (Typ))
        and then Present (Underlying_Type (Full_View (Typ)))
        and then Is_Tagged_Type (Underlying_Type (Full_View (Typ)));
   end Inherits_From_Tagged_Full_View;

   ---------------------------------
   -- Insert_Explicit_Dereference --
   ---------------------------------

   procedure Insert_Explicit_Dereference (N : Node_Id) is
      New_Prefix : constant Node_Id := Relocate_Node (N);
      Ent        : Entity_Id := Empty;
      Pref       : Node_Id := Empty;
      I          : Interp_Index;
      It         : Interp;
      T          : Entity_Id;

   begin
      Save_Interps (N, New_Prefix);

      Rewrite (N,
        Make_Explicit_Dereference (Sloc (Parent (N)),
          Prefix => New_Prefix));

      Set_Etype (N, Designated_Type (Etype (New_Prefix)));

      if Is_Overloaded (New_Prefix) then

         --  The dereference is also overloaded, and its interpretations are
         --  the designated types of the interpretations of the original node.

         Set_Etype (N, Any_Type);

         Get_First_Interp (New_Prefix, I, It);
         while Present (It.Nam) loop
            T := It.Typ;

            if Is_Access_Type (T) then
               Add_One_Interp (N, Designated_Type (T), Designated_Type (T));
            end if;

            Get_Next_Interp (I, It);
         end loop;

      else
         --  Prefix is unambiguous: mark the original prefix (which might
         --  Come_From_Source) as a reference, since the new (relocated) one
         --  won't be taken into account.

         if Is_Entity_Name (New_Prefix) then
            Ent := Entity (New_Prefix);
            Pref := New_Prefix;

         --  For a retrieval of a subcomponent of some composite object,
         --  retrieve the ultimate entity if there is one.

         elsif Nkind (New_Prefix) in N_Selected_Component | N_Indexed_Component
         then
            Pref := Prefix (New_Prefix);
            while Present (Pref)
              and then Nkind (Pref) in
                         N_Selected_Component | N_Indexed_Component
            loop
               Pref := Prefix (Pref);
            end loop;

            if Present (Pref) and then Is_Entity_Name (Pref) then
               Ent := Entity (Pref);
            end if;
         end if;

         --  Place the reference on the entity node

         if Present (Ent) then
            Generate_Reference (Ent, Pref);
         end if;
      end if;
   end Insert_Explicit_Dereference;

   ------------------------------------------
   -- Inspect_Deferred_Constant_Completion --
   ------------------------------------------

   procedure Inspect_Deferred_Constant_Completion (Decls : List_Id) is
      Decl : Node_Id;

   begin
      Decl := First (Decls);
      while Present (Decl) loop

         --  Deferred constant signature

         if Nkind (Decl) = N_Object_Declaration
           and then Constant_Present (Decl)
           and then No (Expression (Decl))

            --  No need to check internally generated constants

           and then Comes_From_Source (Decl)

            --  The constant is not completed. A full object declaration or a
            --  pragma Import complete a deferred constant.

           and then not Has_Completion (Defining_Identifier (Decl))
         then
            Error_Msg_N
              ("constant declaration requires initialization expression",
              Defining_Identifier (Decl));
         end if;

         Next (Decl);
      end loop;
   end Inspect_Deferred_Constant_Completion;

   -------------------------------
   -- Install_Elaboration_Model --
   -------------------------------

   procedure Install_Elaboration_Model (Unit_Id : Entity_Id) is
      function Find_Elaboration_Checks_Pragma (L : List_Id) return Node_Id;
      --  Try to find pragma Elaboration_Checks in arbitrary list L. Return
      --  Empty if there is no such pragma.

      ------------------------------------
      -- Find_Elaboration_Checks_Pragma --
      ------------------------------------

      function Find_Elaboration_Checks_Pragma (L : List_Id) return Node_Id is
         Item : Node_Id;

      begin
         Item := First (L);
         while Present (Item) loop
            if Nkind (Item) = N_Pragma
              and then Pragma_Name (Item) = Name_Elaboration_Checks
            then
               return Item;
            end if;

            Next (Item);
         end loop;

         return Empty;
      end Find_Elaboration_Checks_Pragma;

      --  Local variables

      Args  : List_Id;
      Model : Node_Id;
      Prag  : Node_Id;
      Unit  : Node_Id;

   --  Start of processing for Install_Elaboration_Model

   begin
      --  Nothing to do when the unit does not exist

      if No (Unit_Id) then
         return;
      end if;

      Unit := Parent (Unit_Declaration_Node (Unit_Id));

      --  Nothing to do when the unit is not a library unit

      if Nkind (Unit) /= N_Compilation_Unit then
         return;
      end if;

      Prag := Find_Elaboration_Checks_Pragma (Context_Items (Unit));

      --  The compilation unit is subject to pragma Elaboration_Checks. Set the
      --  elaboration model as specified by the pragma.

      if Present (Prag) then
         Args := Pragma_Argument_Associations (Prag);

         --  Guard against an illegal pragma. The sole argument must be an
         --  identifier which specifies either Dynamic or Static model.

         if Present (Args) then
            Model := Get_Pragma_Arg (First (Args));

            if Nkind (Model) = N_Identifier then
               Dynamic_Elaboration_Checks := Chars (Model) = Name_Dynamic;
            end if;
         end if;
      end if;
   end Install_Elaboration_Model;

   -----------------------------
   -- Install_Generic_Formals --
   -----------------------------

   procedure Install_Generic_Formals (Subp_Id : Entity_Id) is
      E : Entity_Id;

   begin
      pragma Assert (Is_Generic_Subprogram (Subp_Id));

      E := First_Entity (Subp_Id);
      while Present (E) loop
         Install_Entity (E);
         Next_Entity (E);
      end loop;
   end Install_Generic_Formals;

   ------------------------
   -- Install_SPARK_Mode --
   ------------------------

   procedure Install_SPARK_Mode (Mode : SPARK_Mode_Type; Prag : Node_Id) is
   begin
      SPARK_Mode        := Mode;
      SPARK_Mode_Pragma := Prag;
   end Install_SPARK_Mode;

   --------------------------
   -- Invalid_Scalar_Value --
   --------------------------

   function Invalid_Scalar_Value
     (Loc      : Source_Ptr;
      Scal_Typ : Scalar_Id) return Node_Id
   is
      function Invalid_Binder_Value return Node_Id;
      --  Return a reference to the corresponding invalid value for type
      --  Scal_Typ as defined in unit System.Scalar_Values.

      function Invalid_Float_Value return Node_Id;
      --  Return the invalid value of float type Scal_Typ

      function Invalid_Integer_Value return Node_Id;
      --  Return the invalid value of integer type Scal_Typ

      procedure Set_Invalid_Binder_Values;
      --  Set the contents of collection Invalid_Binder_Values

      --------------------------
      -- Invalid_Binder_Value --
      --------------------------

      function Invalid_Binder_Value return Node_Id is
         Val_Id : Entity_Id;

      begin
         --  Initialize the collection of invalid binder values the first time
         --  around.

         Set_Invalid_Binder_Values;

         --  Obtain the corresponding variable from System.Scalar_Values which
         --  holds the invalid value for this type.

         Val_Id := Invalid_Binder_Values (Scal_Typ);
         pragma Assert (Present (Val_Id));

         return New_Occurrence_Of (Val_Id, Loc);
      end Invalid_Binder_Value;

      -------------------------
      -- Invalid_Float_Value --
      -------------------------

      function Invalid_Float_Value return Node_Id is
         Value : constant Ureal := Invalid_Floats (Scal_Typ);

      begin
         --  Pragma Invalid_Scalars did not specify an invalid value for this
         --  type. Fall back to the value provided by the binder.

         if Value = No_Ureal then
            return Invalid_Binder_Value;
         else
            return Make_Real_Literal (Loc, Realval => Value);
         end if;
      end Invalid_Float_Value;

      ---------------------------
      -- Invalid_Integer_Value --
      ---------------------------

      function Invalid_Integer_Value return Node_Id is
         Value : constant Uint := Invalid_Integers (Scal_Typ);

      begin
         --  Pragma Invalid_Scalars did not specify an invalid value for this
         --  type. Fall back to the value provided by the binder.

         if No (Value) then
            return Invalid_Binder_Value;
         else
            return Make_Integer_Literal (Loc, Intval => Value);
         end if;
      end Invalid_Integer_Value;

      -------------------------------
      -- Set_Invalid_Binder_Values --
      -------------------------------

      procedure Set_Invalid_Binder_Values is
      begin
         if not Invalid_Binder_Values_Set then
            Invalid_Binder_Values_Set := True;

            --  Initialize the contents of the collection once since RTE calls
            --  are not cheap.

            Invalid_Binder_Values :=
              (Name_Short_Float     => RTE (RE_IS_Isf),
               Name_Float           => RTE (RE_IS_Ifl),
               Name_Long_Float      => RTE (RE_IS_Ilf),
               Name_Long_Long_Float => RTE (RE_IS_Ill),
               Name_Signed_8        => RTE (RE_IS_Is1),
               Name_Signed_16       => RTE (RE_IS_Is2),
               Name_Signed_32       => RTE (RE_IS_Is4),
               Name_Signed_64       => RTE (RE_IS_Is8),
               Name_Signed_128      => Empty,
               Name_Unsigned_8      => RTE (RE_IS_Iu1),
               Name_Unsigned_16     => RTE (RE_IS_Iu2),
               Name_Unsigned_32     => RTE (RE_IS_Iu4),
               Name_Unsigned_64     => RTE (RE_IS_Iu8),
               Name_Unsigned_128    => Empty);

            if System_Max_Integer_Size < 128 then
               Invalid_Binder_Values (Name_Signed_128)   := RTE (RE_IS_Is8);
               Invalid_Binder_Values (Name_Unsigned_128) := RTE (RE_IS_Iu8);
            else
               Invalid_Binder_Values (Name_Signed_128)   := RTE (RE_IS_Is16);
               Invalid_Binder_Values (Name_Unsigned_128) := RTE (RE_IS_Iu16);
            end if;
         end if;
      end Set_Invalid_Binder_Values;

   --  Start of processing for Invalid_Scalar_Value

   begin
      if Scal_Typ in Float_Scalar_Id then
         return Invalid_Float_Value;

      else pragma Assert (Scal_Typ in Integer_Scalar_Id);
         return Invalid_Integer_Value;
      end if;
   end Invalid_Scalar_Value;

   ------------------------
   -- Is_Access_Variable --
   ------------------------

   function Is_Access_Variable (E : Entity_Id) return Boolean is
   begin
      return Is_Access_Type (E)
        and then not Is_Access_Constant (E)
        and then Ekind (Directly_Designated_Type (E)) /= E_Subprogram_Type;
   end Is_Access_Variable;

   -----------------------------
   -- Is_Actual_Out_Parameter --
   -----------------------------

   function Is_Actual_Out_Parameter (N : Node_Id) return Boolean is
      Formal : Entity_Id;
      Call   : Node_Id;
   begin
      Find_Actual (N, Formal, Call);
      return Present (Formal) and then Ekind (Formal) = E_Out_Parameter;
   end Is_Actual_Out_Parameter;

   --------------------------------
   -- Is_Actual_In_Out_Parameter --
   --------------------------------

   function Is_Actual_In_Out_Parameter (N : Node_Id) return Boolean is
      Formal : Entity_Id;
      Call   : Node_Id;
   begin
      Find_Actual (N, Formal, Call);
      return Present (Formal) and then Ekind (Formal) = E_In_Out_Parameter;
   end Is_Actual_In_Out_Parameter;

   ---------------------------------------
   -- Is_Actual_Out_Or_In_Out_Parameter --
   ---------------------------------------

   function Is_Actual_Out_Or_In_Out_Parameter (N : Node_Id) return Boolean is
      Formal : Entity_Id;
      Call   : Node_Id;
   begin
      Find_Actual (N, Formal, Call);
      return Present (Formal)
        and then Ekind (Formal) in E_Out_Parameter | E_In_Out_Parameter;
   end Is_Actual_Out_Or_In_Out_Parameter;

   -------------------------
   -- Is_Actual_Parameter --
   -------------------------

   function Is_Actual_Parameter (N : Node_Id) return Boolean is
      PK : constant Node_Kind := Nkind (Parent (N));

   begin
      case PK is
         when N_Parameter_Association =>
            return N = Explicit_Actual_Parameter (Parent (N));

         when N_Entry_Call_Statement
            | N_Subprogram_Call
         =>
            return Is_List_Member (N)
              and then
                List_Containing (N) = Parameter_Associations (Parent (N));

         when others =>
            return False;
      end case;
   end Is_Actual_Parameter;

   ---------------------
   -- Is_Aliased_View --
   ---------------------

   function Is_Aliased_View (Obj : Node_Id) return Boolean is
      E : Entity_Id;

   begin
      if Is_Entity_Name (Obj) then
         E := Entity (Obj);

         return
           (Is_Object (E)
             and then
               (Is_Aliased (E)
                 or else (Present (Renamed_Object (E))
                           and then Is_Aliased_View (Renamed_Object (E)))))

           or else ((Is_Formal (E) or else Is_Formal_Object (E))
                      and then Is_Tagged_Type (Etype (E)))

           or else (Is_Concurrent_Type (E) and then In_Open_Scopes (E))

           --  Current instance of type, either directly or as rewritten
           --  reference to the current object.

           or else (Is_Entity_Name (Original_Node (Obj))
                     and then Present (Entity (Original_Node (Obj)))
                     and then Is_Type (Entity (Original_Node (Obj))))

           or else (Is_Type (E) and then E = Current_Scope)

           or else (Is_Incomplete_Or_Private_Type (E)
                     and then Full_View (E) = Current_Scope)

           --  Ada 2012 AI05-0053: the return object of an extended return
           --  statement is aliased if its type is immutably limited.

           or else (Is_Return_Object (E)
                     and then Is_Limited_View (Etype (E)))

           --  The current instance of a limited type is aliased, so
           --  we want to allow uses of T'Access in the init proc for
           --  a limited type T. However, we don't want to mark the formal
           --  parameter as being aliased since that could impact callers.

           or else (Is_Formal (E)
                     and then Chars (E) = Name_uInit
                     and then Is_Limited_View (Etype (E)));

      elsif Nkind (Obj) = N_Selected_Component then
         return Is_Aliased (Entity (Selector_Name (Obj)));

      elsif Nkind (Obj) = N_Indexed_Component then
         return Has_Aliased_Components (Etype (Prefix (Obj)))
           or else
             (Is_Access_Type (Etype (Prefix (Obj)))
               and then Has_Aliased_Components
                          (Designated_Type (Etype (Prefix (Obj)))));

      elsif Nkind (Obj) in N_Unchecked_Type_Conversion | N_Type_Conversion then
         return Is_Tagged_Type (Etype (Obj))
           and then Is_Aliased_View (Expression (Obj));

      --  Ada 2022 AI12-0228

      elsif Nkind (Obj) = N_Qualified_Expression
        and then Ada_Version >= Ada_2012
      then
         return Is_Aliased_View (Expression (Obj));

      --  The dereference of an access-to-object value denotes an aliased view,
      --  but this routine uses the rules of the language so we need to exclude
      --  rewritten constructs that introduce artificial dereferences.

      elsif Nkind (Obj) = N_Explicit_Dereference then
         return not Is_Captured_Function_Call (Obj)
           and then not
             (Nkind (Parent (Obj)) = N_Object_Renaming_Declaration
               and then Is_Return_Object (Defining_Entity (Parent (Obj))));

      else
         return False;
      end if;
   end Is_Aliased_View;

   -------------------------
   -- Is_Ancestor_Package --
   -------------------------

   function Is_Ancestor_Package
     (E1 : Entity_Id;
      E2 : Entity_Id) return Boolean
   is
      Par : Entity_Id;

   begin
      Par := E2;
      while Present (Par) and then Par /= Standard_Standard loop
         if Par = E1 then
            return True;
         end if;

         Par := Scope (Par);
      end loop;

      return False;
   end Is_Ancestor_Package;

   ----------------------
   -- Is_Atomic_Object --
   ----------------------

   function Is_Atomic_Object (N : Node_Id) return Boolean is
      function Prefix_Has_Atomic_Components (P : Node_Id) return Boolean;
      --  Determine whether prefix P has atomic components. This requires the
      --  presence of an Atomic_Components aspect/pragma.

      ---------------------------------
      -- Prefix_Has_Atomic_Components --
      ---------------------------------

      function Prefix_Has_Atomic_Components (P : Node_Id) return Boolean is
         Typ : constant Entity_Id := Etype (P);

      begin
         if Is_Access_Type (Typ) then
            return Has_Atomic_Components (Designated_Type (Typ));

         elsif Has_Atomic_Components (Typ) then
            return True;

         elsif Is_Entity_Name (P)
           and then Has_Atomic_Components (Entity (P))
         then
            return True;

         else
            return False;
         end if;
      end Prefix_Has_Atomic_Components;

   --  Start of processing for Is_Atomic_Object

   begin
      if Is_Entity_Name (N) then
         return Is_Atomic_Object_Entity (Entity (N));

      elsif Is_Atomic (Etype (N)) then
         return True;

      elsif Nkind (N) = N_Indexed_Component then
         return Prefix_Has_Atomic_Components (Prefix (N));

      elsif Nkind (N) = N_Selected_Component then
         return Is_Atomic (Entity (Selector_Name (N)));

      else
         return False;
      end if;
   end Is_Atomic_Object;

   -----------------------------
   -- Is_Atomic_Object_Entity --
   -----------------------------

   function Is_Atomic_Object_Entity (Id : Entity_Id) return Boolean is
   begin
      return
        Is_Object (Id)
          and then (Is_Atomic (Id) or else Is_Atomic (Etype (Id)));
   end Is_Atomic_Object_Entity;

   -----------------------------
   -- Is_Attribute_Loop_Entry --
   -----------------------------

   function Is_Attribute_Loop_Entry (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Loop_Entry;
   end Is_Attribute_Loop_Entry;

   ----------------------
   -- Is_Attribute_Old --
   ----------------------

   function Is_Attribute_Old (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Old;
   end Is_Attribute_Old;

   -------------------------
   -- Is_Attribute_Result --
   -------------------------

   function Is_Attribute_Result (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Result;
   end Is_Attribute_Result;

   -------------------------
   -- Is_Attribute_Update --
   -------------------------

   function Is_Attribute_Update (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Update;
   end Is_Attribute_Update;

   ------------------------------------
   -- Is_Body_Or_Package_Declaration --
   ------------------------------------

   function Is_Body_Or_Package_Declaration (N : Node_Id) return Boolean is
   begin
      return Is_Body (N) or else Nkind (N) = N_Package_Declaration;
   end Is_Body_Or_Package_Declaration;

   -----------------------
   -- Is_Bounded_String --
   -----------------------

   function Is_Bounded_String (T : Entity_Id) return Boolean is
      Under : constant Entity_Id := Underlying_Type (Root_Type (T));

   begin
      --  Check whether T is ultimately derived from Ada.Strings.Superbounded.
      --  Super_String, or one of the [Wide_]Wide_ versions. This will
      --  be True for all the Bounded_String types in instances of the
      --  Generic_Bounded_Length generics, and for types derived from those.

      return Present (Under)
        and then (Is_RTE (Root_Type (Under), RO_SU_Super_String) or else
                  Is_RTE (Root_Type (Under), RO_WI_Super_String) or else
                  Is_RTE (Root_Type (Under), RO_WW_Super_String));
   end Is_Bounded_String;

   -------------------------------
   -- Is_By_Protected_Procedure --
   -------------------------------

   function Is_By_Protected_Procedure (Id : Entity_Id) return Boolean is
   begin
      return Ekind (Id) = E_Procedure
        and then Present (Get_Rep_Pragma (Id, Name_Implemented))
        and then Implementation_Kind (Id) = Name_By_Protected_Procedure;
   end Is_By_Protected_Procedure;

   ---------------------
   -- Is_CCT_Instance --
   ---------------------

   function Is_CCT_Instance
     (Ref_Id     : Entity_Id;
      Context_Id : Entity_Id) return Boolean
   is
   begin
      pragma Assert (Ekind (Ref_Id) in E_Protected_Type | E_Task_Type);

      if Is_Single_Task_Object (Context_Id) then
         return Scope_Within_Or_Same (Etype (Context_Id), Ref_Id);

      else
         pragma Assert
           (Ekind (Context_Id) in
              E_Entry     | E_Entry_Family   | E_Function  | E_Package |
              E_Procedure | E_Protected_Type | E_Task_Type
             or else Is_Record_Type (Context_Id));
         return Scope_Within_Or_Same (Context_Id, Ref_Id);
      end if;
   end Is_CCT_Instance;

   -------------------------
   -- Is_Child_Or_Sibling --
   -------------------------

   function Is_Child_Or_Sibling
     (Pack_1 : Entity_Id;
      Pack_2 : Entity_Id) return Boolean
   is
      function Distance_From_Standard (Pack : Entity_Id) return Nat;
      --  Given an arbitrary package, return the number of "climbs" necessary
      --  to reach scope Standard_Standard.

      procedure Equalize_Depths
        (Pack           : in out Entity_Id;
         Depth          : in out Nat;
         Depth_To_Reach : Nat);
      --  Given an arbitrary package, its depth and a target depth to reach,
      --  climb the scope chain until the said depth is reached. The pointer
      --  to the package and its depth a modified during the climb.

      ----------------------------
      -- Distance_From_Standard --
      ----------------------------

      function Distance_From_Standard (Pack : Entity_Id) return Nat is
         Dist : Nat;
         Scop : Entity_Id;

      begin
         Dist := 0;
         Scop := Pack;
         while Present (Scop) and then Scop /= Standard_Standard loop
            Dist := Dist + 1;
            Scop := Scope (Scop);
         end loop;

         return Dist;
      end Distance_From_Standard;

      ---------------------
      -- Equalize_Depths --
      ---------------------

      procedure Equalize_Depths
        (Pack           : in out Entity_Id;
         Depth          : in out Nat;
         Depth_To_Reach : Nat)
      is
      begin
         --  The package must be at a greater or equal depth

         if Depth < Depth_To_Reach then
            raise Program_Error;
         end if;

         --  Climb the scope chain until the desired depth is reached

         while Present (Pack) and then Depth /= Depth_To_Reach loop
            Pack  := Scope (Pack);
            Depth := Depth - 1;
         end loop;
      end Equalize_Depths;

      --  Local variables

      P_1       : Entity_Id := Pack_1;
      P_1_Child : Boolean   := False;
      P_1_Depth : Nat       := Distance_From_Standard (P_1);
      P_2       : Entity_Id := Pack_2;
      P_2_Child : Boolean   := False;
      P_2_Depth : Nat       := Distance_From_Standard (P_2);

   --  Start of processing for Is_Child_Or_Sibling

   begin
      pragma Assert
        (Ekind (Pack_1) = E_Package and then Ekind (Pack_2) = E_Package);

      --  Both packages denote the same entity, therefore they cannot be
      --  children or siblings.

      if P_1 = P_2 then
         return False;

      --  One of the packages is at a deeper level than the other. Note that
      --  both may still come from different hierarchies.

      --        (root)           P_2
      --        /    \            :
      --       X     P_2    or    X
      --       :                  :
      --      P_1                P_1

      elsif P_1_Depth > P_2_Depth then
         Equalize_Depths
           (Pack           => P_1,
            Depth          => P_1_Depth,
            Depth_To_Reach => P_2_Depth);
         P_1_Child := True;

      --        (root)           P_1
      --        /    \            :
      --      P_1     X     or    X
      --              :           :
      --             P_2         P_2

      elsif P_2_Depth > P_1_Depth then
         Equalize_Depths
           (Pack           => P_2,
            Depth          => P_2_Depth,
            Depth_To_Reach => P_1_Depth);
         P_2_Child := True;
      end if;

      --  At this stage the package pointers have been elevated to the same
      --  depth. If the related entities are the same, then one package is a
      --  potential child of the other:

      --      P_1
      --       :
      --       X    became   P_1 P_2   or vice versa
      --       :
      --      P_2

      if P_1 = P_2 then
         if P_1_Child then
            return Is_Child_Unit (Pack_1);

         else pragma Assert (P_2_Child);
            return Is_Child_Unit (Pack_2);
         end if;

      --  The packages may come from the same package chain or from entirely
      --  different hierarchies. To determine this, climb the scope stack until
      --  a common root is found.

      --        (root)      (root 1)  (root 2)
      --        /    \         |         |
      --      P_1    P_2      P_1       P_2

      else
         while Present (P_1) and then Present (P_2) loop

            --  The two packages may be siblings

            if P_1 = P_2 then
               return Is_Child_Unit (Pack_1) and then Is_Child_Unit (Pack_2);
            end if;

            P_1 := Scope (P_1);
            P_2 := Scope (P_2);
         end loop;
      end if;

      return False;
   end Is_Child_Or_Sibling;

   -------------------
   -- Is_Confirming --
   -------------------

   function Is_Confirming (Aspect : Nonoverridable_Aspect_Id;
                           Aspect_Spec_1, Aspect_Spec_2 : Node_Id)
                          return Boolean is
      function Names_Match (Nm1, Nm2 : Node_Id) return Boolean;

      -----------------
      -- Names_Match --
      -----------------

      function Names_Match (Nm1, Nm2 : Node_Id) return Boolean is
      begin
         if Nkind (Nm1) /= Nkind (Nm2) then
            return False;
            --  This may be too restrictive given that visibility
            --  may allow an identifier in one case and an expanded
            --  name in the other.
         end if;
         case Nkind (Nm1) is
            when N_Identifier =>
               return Name_Equals (Chars (Nm1), Chars (Nm2));

            when N_Expanded_Name =>
               --  An inherited operation has the same name as its
               --  ancestor, but they may have different scopes.
               --  This may be too permissive for Iterator_Element, which
               --  is intended to be identical in parent and derived type.

               return Names_Match (Selector_Name (Nm1),
                                   Selector_Name (Nm2));

            when N_Empty =>
               return True; -- needed for Aggregate aspect checking

            when others =>
               --  e.g., 'Class attribute references
               if Is_Entity_Name (Nm1) and Is_Entity_Name (Nm2) then
                  return Entity (Nm1) = Entity (Nm2);
               end if;

               raise Program_Error;
         end case;
      end Names_Match;
   begin
      --  allow users to disable "shall be confirming" check, at least for now
      if Relaxed_RM_Semantics then
         return True;
      end if;

      --  ??? Type conversion here (along with "when others =>" below) is a
      --  workaround for a bootstrapping problem related to casing on a
      --  static-predicate-bearing subtype.

      case Aspect_Id (Aspect) is
         --  name-valued aspects; compare text of names, not resolution.
         when Aspect_Default_Iterator
            | Aspect_Iterator_Element
            | Aspect_Constant_Indexing
            | Aspect_Variable_Indexing =>
            declare
               Item_1 : constant Node_Id := Aspect_Rep_Item (Aspect_Spec_1);
               Item_2 : constant Node_Id := Aspect_Rep_Item (Aspect_Spec_2);
            begin
               if Nkind (Item_1) /= N_Attribute_Definition_Clause
                 or Nkind (Item_2) /= N_Attribute_Definition_Clause
               then
                  pragma Assert (Serious_Errors_Detected > 0);
                  return True;
               end if;

               return Names_Match (Expression (Item_1),
                                   Expression (Item_2));
            end;

         --  A confirming aspect for Implicit_Derenfence on a derived type
         --  has already been checked in Analyze_Aspect_Implicit_Dereference,
         --  including the presence of renamed discriminants.

         when Aspect_Implicit_Dereference =>
            return True;

         --  one of a kind
         when Aspect_Aggregate =>
            declare
               Empty_1,
               Add_Named_1,
               Add_Unnamed_1,
               New_Indexed_1,
               Assign_Indexed_1,
               Empty_2,
               Add_Named_2,
               Add_Unnamed_2,
               New_Indexed_2,
               Assign_Indexed_2 : Node_Id := Empty;
            begin
               Parse_Aspect_Aggregate
                 (N                   => Expression (Aspect_Spec_1),
                  Empty_Subp          => Empty_1,
                  Add_Named_Subp      => Add_Named_1,
                  Add_Unnamed_Subp    => Add_Unnamed_1,
                  New_Indexed_Subp    => New_Indexed_1,
                  Assign_Indexed_Subp => Assign_Indexed_1);
               Parse_Aspect_Aggregate
                 (N                   => Expression (Aspect_Spec_2),
                  Empty_Subp          => Empty_2,
                  Add_Named_Subp      => Add_Named_2,
                  Add_Unnamed_Subp    => Add_Unnamed_2,
                  New_Indexed_Subp    => New_Indexed_2,
                  Assign_Indexed_Subp => Assign_Indexed_2);
               return
                 Names_Match (Empty_1, Empty_2) and then
                 Names_Match (Add_Named_1, Add_Named_2) and then
                 Names_Match (Add_Unnamed_1, Add_Unnamed_2) and then
                 Names_Match (New_Indexed_1, New_Indexed_2) and then
                 Names_Match (Assign_Indexed_1, Assign_Indexed_2);
            end;

         --  Checking for this aspect is performed elsewhere during freezing
         when Aspect_No_Controlled_Parts =>
            return True;

         --  scalar-valued aspects; compare (static) values.
         when Aspect_Max_Entry_Queue_Length =>
            --  This should be unreachable. Max_Entry_Queue_Length is
            --  supported only for protected entries, not for types.
            pragma Assert (Serious_Errors_Detected /= 0);
            return True;

         when others =>
            raise Program_Error;
      end case;
   end Is_Confirming;

   -----------------------------
   -- Is_Concurrent_Interface --
   -----------------------------

   function Is_Concurrent_Interface (T : Entity_Id) return Boolean is
   begin
      return Is_Protected_Interface (T)
        or else Is_Synchronized_Interface (T)
        or else Is_Task_Interface (T);
   end Is_Concurrent_Interface;

   ------------------------------------------------------
   -- Is_Conjunction_Of_Formal_Preelab_Init_Attributes --
   ------------------------------------------------------

   function Is_Conjunction_Of_Formal_Preelab_Init_Attributes
     (Expr : Node_Id) return Boolean
   is

      function Is_Formal_Preelab_Init_Attribute
        (N : Node_Id) return Boolean;
      --  Returns True if N is a Preelaborable_Initialization attribute
      --  applied to a generic formal type, or N's Original_Node is such
      --  an attribute.

      --------------------------------------
      -- Is_Formal_Preelab_Init_Attribute --
      --------------------------------------

      function Is_Formal_Preelab_Init_Attribute
        (N : Node_Id) return Boolean
      is
         Orig_N : constant Node_Id := Original_Node (N);

      begin
         return Nkind (Orig_N) = N_Attribute_Reference
           and then Attribute_Name (Orig_N) = Name_Preelaborable_Initialization
           and then Is_Entity_Name (Prefix (Orig_N))
           and then Is_Generic_Type (Entity (Prefix (Orig_N)));
      end Is_Formal_Preelab_Init_Attribute;

   --  Start of Is_Conjunction_Of_Formal_Preelab_Init_Attributes

   begin
      return Is_Formal_Preelab_Init_Attribute (Expr)
        or else (Nkind (Expr) = N_Op_And
                  and then
                    Is_Conjunction_Of_Formal_Preelab_Init_Attributes
                      (Left_Opnd (Expr))
                  and then
                    Is_Conjunction_Of_Formal_Preelab_Init_Attributes
                      (Right_Opnd (Expr)));
   end Is_Conjunction_Of_Formal_Preelab_Init_Attributes;

   -----------------------
   -- Is_Constant_Bound --
   -----------------------

   function Is_Constant_Bound (Exp : Node_Id) return Boolean is
   begin
      if Compile_Time_Known_Value (Exp) then
         return True;

      elsif Is_Entity_Name (Exp) and then Present (Entity (Exp)) then
         return Is_Constant_Object (Entity (Exp))
           or else Ekind (Entity (Exp)) = E_Enumeration_Literal;

      elsif Nkind (Exp) in N_Binary_Op then
         return Is_Constant_Bound (Left_Opnd (Exp))
           and then Is_Constant_Bound (Right_Opnd (Exp))
           and then Scope (Entity (Exp)) = Standard_Standard;

      else
         return False;
      end if;
   end Is_Constant_Bound;

   ---------------------------
   --  Is_Container_Element --
   ---------------------------

   function Is_Container_Element (Exp : Node_Id) return Boolean is
      Loc  : constant Source_Ptr := Sloc (Exp);
      Pref : constant Node_Id   := Prefix (Exp);

      Call : Node_Id;
      --  Call to an indexing aspect

      Cont_Typ : Entity_Id;
      --  The type of the container being accessed

      Elem_Typ : Entity_Id;
      --  Its element type

      Indexing : Entity_Id;
      Is_Const : Boolean;
      --  Indicates that constant indexing is used, and the element is thus
      --  a constant.

      Ref_Typ : Entity_Id;
      --  The reference type returned by the indexing operation

   begin
      --  If C is a container, in a context that imposes the element type of
      --  that container, the indexing notation C (X) is rewritten as:

      --    Indexing (C, X).Discr.all

      --  where Indexing is one of the indexing aspects of the container.
      --  If the context does not require a reference, the construct can be
      --  rewritten as

      --    Element (C, X)

      --  First, verify that the construct has the proper form

      if not Expander_Active then
         return False;

      elsif Nkind (Pref) /= N_Selected_Component then
         return False;

      elsif Nkind (Prefix (Pref)) /= N_Function_Call then
         return False;

      else
         Call    := Prefix (Pref);
         Ref_Typ := Etype (Call);
      end if;

      if not Has_Implicit_Dereference (Ref_Typ)
        or else No (First (Parameter_Associations (Call)))
        or else not Is_Entity_Name (Name (Call))
      then
         return False;
      end if;

      --  Retrieve type of container object, and its iterator aspects

      Cont_Typ := Etype (First (Parameter_Associations (Call)));
      Indexing := Find_Value_Of_Aspect (Cont_Typ, Aspect_Constant_Indexing);
      Is_Const := False;

      if No (Indexing) then

         --  Container should have at least one indexing operation

         return False;

      elsif Entity (Name (Call)) /= Entity (Indexing) then

         --  This may be a variable indexing operation

         Indexing := Find_Value_Of_Aspect (Cont_Typ, Aspect_Variable_Indexing);

         if No (Indexing)
           or else Entity (Name (Call)) /= Entity (Indexing)
         then
            return False;
         end if;

      else
         Is_Const := True;
      end if;

      Elem_Typ := Find_Value_Of_Aspect (Cont_Typ, Aspect_Iterator_Element);

      if No (Elem_Typ) or else Entity (Elem_Typ) /= Etype (Exp) then
         return False;
      end if;

      --  Check that the expression is not the target of an assignment, in
      --  which case the rewriting is not possible.

      if not Is_Const then
         declare
            Par : Node_Id;

         begin
            Par := Exp;
            while Present (Par)
            loop
               if Nkind (Parent (Par)) = N_Assignment_Statement
                 and then Par = Name (Parent (Par))
               then
                  return False;

               --  A renaming produces a reference, and the transformation
               --  does not apply.

               elsif Nkind (Parent (Par)) = N_Object_Renaming_Declaration then
                  return False;

               elsif Nkind (Parent (Par)) in
                       N_Function_Call            |
                       N_Procedure_Call_Statement |
                       N_Entry_Call_Statement
               then
                  --  Check that the element is not part of an actual for an
                  --  in-out parameter.

                  declare
                     F : Entity_Id;
                     A : Node_Id;

                  begin
                     F := First_Formal (Entity (Name (Parent (Par))));
                     A := First (Parameter_Associations (Parent (Par)));
                     while Present (F) loop
                        if A = Par and then Ekind (F) /= E_In_Parameter then
                           return False;
                        end if;

                        Next_Formal (F);
                        Next (A);
                     end loop;
                  end;

                  --  E_In_Parameter in a call: element is not modified.

                  exit;
               end if;

               Par := Parent (Par);
            end loop;
         end;
      end if;

      --  The expression has the proper form and the context requires the
      --  element type. Retrieve the Element function of the container and
      --  rewrite the construct as a call to it.

      declare
         Op : Elmt_Id;

      begin
         Op := First_Elmt (Primitive_Operations (Cont_Typ));
         while Present (Op) loop
            exit when Chars (Node (Op)) = Name_Element;
            Next_Elmt (Op);
         end loop;

         if No (Op) then
            return False;

         else
            Rewrite (Exp,
              Make_Function_Call (Loc,
                Name                   => New_Occurrence_Of (Node (Op), Loc),
                Parameter_Associations => Parameter_Associations (Call)));
            Analyze_And_Resolve (Exp, Entity (Elem_Typ));
            return True;
         end if;
      end;
   end Is_Container_Element;

   ----------------------------
   -- Is_Contract_Annotation --
   ----------------------------

   function Is_Contract_Annotation (Item : Node_Id) return Boolean is
   begin
      return Is_Package_Contract_Annotation (Item)
               or else
             Is_Subprogram_Contract_Annotation (Item);
   end Is_Contract_Annotation;

   --------------------------------------
   -- Is_Controlling_Limited_Procedure --
   --------------------------------------

   function Is_Controlling_Limited_Procedure
     (Proc_Nam : Entity_Id) return Boolean
   is
      Param     : Node_Id;
      Param_Typ : Entity_Id := Empty;

   begin
      if Ekind (Proc_Nam) = E_Procedure
        and then Present (Parameter_Specifications (Parent (Proc_Nam)))
      then
         Param :=
           Parameter_Type
             (First (Parameter_Specifications (Parent (Proc_Nam))));

         --  The formal may be an anonymous access type

         if Nkind (Param) = N_Access_Definition then
            Param_Typ := Entity (Subtype_Mark (Param));
         else
            Param_Typ := Etype (Param);
         end if;

      --  In the case where an Itype was created for a dispatchin call, the
      --  procedure call has been rewritten. The actual may be an access to
      --  interface type in which case it is the designated type that is the
      --  controlling type.

      elsif Present (Associated_Node_For_Itype (Proc_Nam))
        and then Present (Original_Node (Associated_Node_For_Itype (Proc_Nam)))
        and then
          Present (Parameter_Associations
                     (Associated_Node_For_Itype (Proc_Nam)))
      then
         Param_Typ :=
           Etype (First (Parameter_Associations
                          (Associated_Node_For_Itype (Proc_Nam))));

         if Ekind (Param_Typ) = E_Anonymous_Access_Type then
            Param_Typ := Directly_Designated_Type (Param_Typ);
         end if;
      end if;

      if Present (Param_Typ) then
         return
           Is_Interface (Param_Typ)
             and then Is_Limited_Record (Param_Typ);
      end if;

      return False;
   end Is_Controlling_Limited_Procedure;

   -----------------------------
   -- Is_CPP_Constructor_Call --
   -----------------------------

   function Is_CPP_Constructor_Call (N : Node_Id) return Boolean is
      Ret_Typ : Entity_Id;

   begin
      if Nkind (N) /= N_Function_Call then
         return False;
      end if;

      Ret_Typ := Base_Type (Etype (N));

      if Is_Class_Wide_Type (Ret_Typ) then
         Ret_Typ := Root_Type (Ret_Typ);
      end if;

      if Is_Private_Type (Ret_Typ) then
         Ret_Typ := Underlying_Type (Ret_Typ);
      end if;

      return Present (Ret_Typ)
        and then Is_CPP_Class (Ret_Typ)
        and then Is_Constructor (Entity (Name (N)))
        and then Is_Imported (Entity (Name (N)));
   end Is_CPP_Constructor_Call;

   -------------------------
   -- Is_Current_Instance --
   -------------------------

   function Is_Current_Instance (N : Node_Id) return Boolean is
      Typ : constant Entity_Id := Entity (N);
      P   : Node_Id;

   begin
      --  Simplest case: entity is a concurrent type and we are currently
      --  inside the body. This will eventually be expanded into a call to
      --  Self (for tasks) or _object (for protected objects).

      if Is_Concurrent_Type (Typ) and then In_Open_Scopes (Typ) then
         return True;

      else
         --  Check whether the context is a (sub)type declaration for the
         --  type entity.

         P := Parent (N);
         while Present (P) loop
            if Nkind (P) in N_Full_Type_Declaration
                          | N_Private_Type_Declaration
                          | N_Subtype_Declaration
              and then Comes_From_Source (P)

              --  If the type has a previous incomplete declaration, the
              --  reference in the type definition may have the incomplete
              --  view. So, here we detect if this incomplete view is a current
              --  instance by checking if its full view is the entity of the
              --  full declaration begin analyzed.

              and then
                (Defining_Entity (P) = Typ
                  or else
                   (Ekind (Typ) = E_Incomplete_Type
                     and then Full_View (Typ) = Defining_Entity (P)))
            then
               return True;

            --  A subtype name may appear in an aspect specification for a
            --  Predicate_Failure aspect, for which we do not construct a
            --  wrapper procedure. The subtype will be replaced by the
            --  expression being tested when the corresponding predicate
            --  check is expanded. It may also appear in the pragma Predicate
            --  expression during legality checking.

            elsif Nkind (P) = N_Aspect_Specification
              and then Nkind (Parent (P)) = N_Subtype_Declaration
              and then Underlying_Type (Defining_Identifier (Parent (P))) =
                       Underlying_Type (Typ)
            then
               return True;

            elsif Nkind (P) = N_Pragma
              and then Get_Pragma_Id (P) in Pragma_Predicate
                                          | Pragma_Predicate_Failure
            then
               declare
                  Arg : constant Entity_Id :=
                    Entity (Expression (Get_Argument (P)));
               begin
                  if Underlying_Type (Arg) = Underlying_Type (Typ) then
                     return True;
                  end if;
               end;
            end if;

            P := Parent (P);
         end loop;
      end if;

      --  In any other context this is not a current occurrence

      return False;
   end Is_Current_Instance;

   --------------------------------------------------
   -- Is_Current_Instance_Reference_In_Type_Aspect --
   --------------------------------------------------

   function Is_Current_Instance_Reference_In_Type_Aspect
     (N : Node_Id) return Boolean
   is
   begin
      --  When a current_instance is referenced within an aspect_specification
      --  of a type or subtype, it will show up as a reference to the formal
      --  parameter of the aspect's associated subprogram rather than as a
      --  reference to the type or subtype itself (in fact, the original name
      --  is never even analyzed). We check for predicate, invariant, and
      --  Default_Initial_Condition subprograms (in theory there could be
      --  other cases added, in which case this function will need updating).

      if Is_Entity_Name (N) then
         return Present (Entity (N))
           and then Ekind (Entity (N)) = E_In_Parameter
           and then Ekind (Scope (Entity (N))) in E_Function | E_Procedure
           and then
             (Is_Predicate_Function (Scope (Entity (N)))
               or else Is_Invariant_Procedure (Scope (Entity (N)))
               or else Is_Partial_Invariant_Procedure (Scope (Entity (N)))
               or else Is_DIC_Procedure (Scope (Entity (N))));

      else
         case Nkind (N) is
            when N_Indexed_Component
               | N_Slice
            =>
               return
                 Is_Current_Instance_Reference_In_Type_Aspect (Prefix (N));

            when N_Selected_Component =>
               return
                 Is_Current_Instance_Reference_In_Type_Aspect (Prefix (N));

            when N_Type_Conversion =>
               return Is_Current_Instance_Reference_In_Type_Aspect
                        (Expression (N));

            when N_Qualified_Expression =>
               return Is_Current_Instance_Reference_In_Type_Aspect
                        (Expression (N));

            when others =>
               return False;
         end case;
      end if;
   end Is_Current_Instance_Reference_In_Type_Aspect;

   --------------------
   -- Is_Declaration --
   --------------------

   function Is_Declaration
     (N                : Node_Id;
      Body_OK          : Boolean := True;
      Concurrent_OK    : Boolean := True;
      Formal_OK        : Boolean := True;
      Generic_OK       : Boolean := True;
      Instantiation_OK : Boolean := True;
      Renaming_OK      : Boolean := True;
      Stub_OK          : Boolean := True;
      Subprogram_OK    : Boolean := True;
      Type_OK          : Boolean := True) return Boolean
   is
   begin
      case Nkind (N) is

         --  Body declarations

         when N_Proper_Body =>
            return Body_OK;

         --  Concurrent type declarations

         when N_Protected_Type_Declaration
            | N_Single_Protected_Declaration
            | N_Single_Task_Declaration
            | N_Task_Type_Declaration
         =>
            return Concurrent_OK or Type_OK;

         --  Formal declarations

         when N_Formal_Abstract_Subprogram_Declaration
            | N_Formal_Concrete_Subprogram_Declaration
            | N_Formal_Object_Declaration
            | N_Formal_Package_Declaration
            | N_Formal_Type_Declaration
         =>
            return Formal_OK;

         --  Generic declarations

         when N_Generic_Package_Declaration
            | N_Generic_Subprogram_Declaration
         =>
            return Generic_OK;

         --  Generic instantiations

         when N_Function_Instantiation
            | N_Package_Instantiation
            | N_Procedure_Instantiation
         =>
            return Instantiation_OK;

         --  Generic renaming declarations

         when N_Generic_Renaming_Declaration =>
            return Generic_OK or Renaming_OK;

         --  Renaming declarations

         when N_Exception_Renaming_Declaration
            | N_Object_Renaming_Declaration
            | N_Package_Renaming_Declaration
            | N_Subprogram_Renaming_Declaration
         =>
            return Renaming_OK;

         --  Stub declarations

         when N_Body_Stub =>
            return Stub_OK;

         --  Subprogram declarations

         when N_Abstract_Subprogram_Declaration
            | N_Entry_Declaration
            | N_Expression_Function
            | N_Subprogram_Declaration
         =>
            return Subprogram_OK;

         --  Type declarations

         when N_Full_Type_Declaration
            | N_Incomplete_Type_Declaration
            | N_Private_Extension_Declaration
            | N_Private_Type_Declaration
            | N_Subtype_Declaration
         =>
            return Type_OK;

         --  Miscellaneous

         when N_Component_Declaration
            | N_Exception_Declaration
            | N_Implicit_Label_Declaration
            | N_Number_Declaration
            | N_Object_Declaration
            | N_Package_Declaration
         =>
            return True;

         when others =>
            return False;
      end case;
   end Is_Declaration;

   --------------------------------
   -- Is_Declared_Within_Variant --
   --------------------------------

   function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean is
      Comp_Decl : constant Node_Id := Parent (Comp);
      Comp_List : constant Node_Id := Parent (Comp_Decl);
   begin
      return Nkind (Parent (Comp_List)) = N_Variant;
   end Is_Declared_Within_Variant;

   ----------------------------------------------
   -- Is_Dependent_Component_Of_Mutable_Object --
   ----------------------------------------------

   function Is_Dependent_Component_Of_Mutable_Object
     (Object : Node_Id) return Boolean
   is
      P           : Node_Id;
      Prefix_Type : Entity_Id;
      P_Aliased   : Boolean := False;
      Comp        : Entity_Id;

      Deref : Node_Id := Original_Node (Object);
      --  Dereference node, in something like X.all.Y(2)

   --  Start of processing for Is_Dependent_Component_Of_Mutable_Object

   begin
      --  Find the dereference node if any

      while Nkind (Deref) in
              N_Indexed_Component | N_Selected_Component | N_Slice
      loop
         Deref := Original_Node (Prefix (Deref));
      end loop;

      --  If the prefix is a qualified expression of a variable, then function
      --  Is_Variable will return False for that because a qualified expression
      --  denotes a constant view, so we need to get the name being qualified
      --  so we can test below whether that's a variable (or a dereference).

      if Nkind (Deref) = N_Qualified_Expression then
         Deref := Expression (Deref);
      end if;

      --  Ada 2005: If we have a component or slice of a dereference, something
      --  like X.all.Y (2) and the type of X is access-to-constant, Is_Variable
      --  will return False, because it is indeed a constant view. But it might
      --  be a view of a variable object, so we want the following condition to
      --  be True in that case.

      if Is_Variable (Object)
        or else Is_Variable (Deref)
        or else
          (Ada_Version >= Ada_2005
            and then (Nkind (Deref) = N_Explicit_Dereference
                       or else (Present (Etype (Deref))
                                 and then Is_Access_Type (Etype (Deref)))))
      then
         if Nkind (Object) = N_Selected_Component then

            --  If the selector is not a component, then we definitely return
            --  False (it could be a function selector in a prefix form call
            --  occurring in an iterator specification).

            if Ekind (Entity (Selector_Name (Object))) not in
                 E_Component | E_Discriminant
            then
               return False;
            end if;

            --  Get the original node of the prefix in case it has been
            --  rewritten, which can occur, for example, in qualified
            --  expression cases. Also, a discriminant check on a selected
            --  component may be expanded into a dereference when removing
            --  side effects, and the subtype of the original node may be
            --  unconstrained.

            P := Original_Node (Prefix (Object));
            Prefix_Type := Etype (P);

            --  If the prefix is a qualified expression, we want to look at its
            --  operand.

            if Nkind (P) = N_Qualified_Expression then
               P := Expression (P);
               Prefix_Type := Etype (P);
            end if;

            if Is_Entity_Name (P) then
               --  The Etype may not be set on P (which is wrong) in certain
               --  corner cases involving the deprecated front-end inlining of
               --  subprograms (via -gnatN), so use the Etype set on the
               --  the entity for these instances since we know it is present.

               if No (Prefix_Type) then
                  Prefix_Type := Etype (Entity (P));
               end if;

               if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then
                  Prefix_Type := Base_Type (Prefix_Type);
               end if;

               if Is_Aliased (Entity (P)) then
                  P_Aliased := True;
               end if;

            --  For explicit dereferences we get the access prefix so we can
            --  treat this similarly to implicit dereferences and examine the
            --  kind of the access type and its designated subtype further
            --  below.

            elsif Nkind (P) = N_Explicit_Dereference then
               P := Prefix (P);
               Prefix_Type := Etype (P);

            else
               --  Check for prefix being an aliased component???

               null;
            end if;

            --  A heap object is constrained by its initial value

            --  Ada 2005 (AI-363): Always assume the object could be mutable in
            --  the dereferenced case, since the access value might denote an
            --  unconstrained aliased object, whereas in Ada 95 the designated
            --  object is guaranteed to be constrained. A worst-case assumption
            --  has to apply in Ada 2005 because we can't tell at compile
            --  time whether the object is "constrained by its initial value",
            --  despite the fact that 3.10.2(26/2) and 8.5.1(5/2) are semantic
            --  rules (these rules are acknowledged to need fixing). We don't
            --  impose this more stringent checking for earlier Ada versions or
            --  when Relaxed_RM_Semantics applies (the latter for CodePeer's
            --  benefit, though it's unclear on why using -gnat95 would not be
            --  sufficient???).

            if Ada_Version < Ada_2005 or else Relaxed_RM_Semantics then
               if Is_Access_Type (Prefix_Type)
                 or else Nkind (P) = N_Explicit_Dereference
               then
                  return False;
               end if;

            else pragma Assert (Ada_Version >= Ada_2005);
               if Is_Access_Type (Prefix_Type) then
                  --  We need to make sure we have the base subtype, in case
                  --  this is actually an access subtype (whose Ekind will be
                  --  E_Access_Subtype).

                  Prefix_Type := Etype (Prefix_Type);

                  --  If the access type is pool-specific, and there is no
                  --  constrained partial view of the designated type, then the
                  --  designated object is known to be constrained. If it's a
                  --  formal access type and the renaming is in the generic
                  --  spec, we also treat it as pool-specific (known to be
                  --  constrained), but assume the worst if in the generic body
                  --  (see RM 3.3(23.3/3)).

                  if Ekind (Prefix_Type) = E_Access_Type
                    and then (not Is_Generic_Type (Prefix_Type)
                               or else not In_Generic_Body (Current_Scope))
                    and then not Object_Type_Has_Constrained_Partial_View
                                   (Typ  => Designated_Type (Prefix_Type),
                                    Scop => Current_Scope)
                  then
                     return False;

                  --  Otherwise (general access type, or there is a constrained
                  --  partial view of the designated type), we need to check
                  --  based on the designated type.

                  else
                     Prefix_Type := Designated_Type (Prefix_Type);
                  end if;
               end if;
            end if;

            Comp :=
              Original_Record_Component (Entity (Selector_Name (Object)));

            --  As per AI-0017, the renaming is illegal in a generic body, even
            --  if the subtype is indefinite (only applies to prefixes of an
            --  untagged formal type, see RM 3.3 (23.11/3)).

            --  Ada 2005 (AI-363): In Ada 2005 an aliased object can be mutable

            if not Is_Constrained (Prefix_Type)
              and then (Is_Definite_Subtype (Prefix_Type)
                         or else
                           (not Is_Tagged_Type (Prefix_Type)
                             and then Is_Generic_Type (Prefix_Type)
                             and then In_Generic_Body (Current_Scope)))

              and then (Is_Declared_Within_Variant (Comp)
                         or else Has_Discriminant_Dependent_Constraint (Comp))
              and then (not P_Aliased or else Ada_Version >= Ada_2005)
            then
               return True;

            --  If the prefix is of an access type at this point, then we want
            --  to return False, rather than calling this function recursively
            --  on the access object (which itself might be a discriminant-
            --  dependent component of some other object, but that isn't
            --  relevant to checking the object passed to us). This avoids
            --  issuing wrong errors when compiling with -gnatc, where there
            --  can be implicit dereferences that have not been expanded.

            elsif Is_Access_Type (Etype (Prefix (Object))) then
               return False;

            else
               return
                 Is_Dependent_Component_Of_Mutable_Object (Prefix (Object));
            end if;

         elsif Nkind (Object) = N_Indexed_Component
           or else Nkind (Object) = N_Slice
         then
            return Is_Dependent_Component_Of_Mutable_Object
                     (Original_Node (Prefix (Object)));

         --  A type conversion that Is_Variable is a view conversion:
         --  go back to the denoted object.

         elsif Nkind (Object) = N_Type_Conversion then
            return
              Is_Dependent_Component_Of_Mutable_Object
                (Original_Node (Expression (Object)));
         end if;
      end if;

      return False;
   end Is_Dependent_Component_Of_Mutable_Object;

   ---------------------
   -- Is_Dereferenced --
   ---------------------

   function Is_Dereferenced (N : Node_Id) return Boolean is
      P : constant Node_Id := Parent (N);
   begin
      return Nkind (P) in N_Selected_Component
                        | N_Explicit_Dereference
                        | N_Indexed_Component
                        | N_Slice
        and then Prefix (P) = N;
   end Is_Dereferenced;

   ----------------------
   -- Is_Descendant_Of --
   ----------------------

   function Is_Descendant_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean is
      T    : Entity_Id;
      Etyp : Entity_Id;

   begin
      pragma Assert (Nkind (T1) in N_Entity);
      pragma Assert (Nkind (T2) in N_Entity);

      T := Base_Type (T1);

      --  Immediate return if the types match

      if T = T2 then
         return True;

      --  Comment needed here ???

      elsif Ekind (T) = E_Class_Wide_Type then
         return Etype (T) = T2;

      --  All other cases

      else
         loop
            Etyp := Etype (T);

            --  Done if we found the type we are looking for

            if Etyp = T2 then
               return True;

            --  Done if no more derivations to check

            elsif T = T1
              or else T = Etyp
            then
               return False;

            --  Following test catches error cases resulting from prev errors

            elsif No (Etyp) then
               return False;

            elsif Is_Private_Type (T) and then Etyp = Full_View (T) then
               return False;

            elsif Is_Private_Type (Etyp) and then Full_View (Etyp) = T then
               return False;
            end if;

            T := Base_Type (Etyp);
         end loop;
      end if;
   end Is_Descendant_Of;

   ----------------------------------------
   -- Is_Descendant_Of_Suspension_Object --
   ----------------------------------------

   function Is_Descendant_Of_Suspension_Object
     (Typ : Entity_Id) return Boolean
   is
      Cur_Typ : Entity_Id;
      Par_Typ : Entity_Id;

   begin
      --  Climb the type derivation chain checking each parent type against
      --  Suspension_Object.

      Cur_Typ := Base_Type (Typ);
      while Present (Cur_Typ) loop
         Par_Typ := Etype (Cur_Typ);

         --  The current type is a match

         if Is_RTE (Cur_Typ, RE_Suspension_Object) then
            return True;

         --  Stop the traversal once the root of the derivation chain has been
         --  reached. In that case the current type is its own base type.

         elsif Cur_Typ = Par_Typ then
            exit;
         end if;

         Cur_Typ := Base_Type (Par_Typ);
      end loop;

      return False;
   end Is_Descendant_Of_Suspension_Object;

   ---------------------------------------------
   -- Is_Double_Precision_Floating_Point_Type --
   ---------------------------------------------

   function Is_Double_Precision_Floating_Point_Type
     (E : Entity_Id) return Boolean is
   begin
      return Is_Floating_Point_Type (E)
        and then Machine_Radix_Value (E) = Uint_2
        and then Machine_Mantissa_Value (E) = UI_From_Int (53)
        and then Machine_Emax_Value (E) = Uint_2 ** Uint_10
        and then Machine_Emin_Value (E) = Uint_3 - (Uint_2 ** Uint_10);
   end Is_Double_Precision_Floating_Point_Type;

   -----------------------------
   -- Is_Effectively_Volatile --
   -----------------------------

   function Is_Effectively_Volatile
     (Id               : Entity_Id;
      Ignore_Protected : Boolean := False) return Boolean is
   begin
      if Is_Type (Id) then

         --  An arbitrary type is effectively volatile when it is subject to
         --  pragma Atomic or Volatile, unless No_Caching is enabled.

         if Is_Volatile (Id)
           and then not No_Caching_Enabled (Id)
         then
            return True;

         --  An array type is effectively volatile when it is subject to pragma
         --  Atomic_Components or Volatile_Components or its component type is
         --  effectively volatile.

         elsif Is_Array_Type (Id) then
            if Has_Volatile_Components (Id) then
               return True;
            else
               declare
                  Anc : Entity_Id := Base_Type (Id);
               begin
                  if Is_Private_Type (Anc) then
                     Anc := Full_View (Anc);
                  end if;

                  --  Test for presence of ancestor, as the full view of a
                  --  private type may be missing in case of error.

                  return Present (Anc)
                    and then Is_Effectively_Volatile
                      (Component_Type (Anc), Ignore_Protected);
               end;
            end if;

         --  A protected type is always volatile unless Ignore_Protected is
         --  True.

         elsif Is_Protected_Type (Id) and then not Ignore_Protected then
            return True;

         --  A descendant of Ada.Synchronous_Task_Control.Suspension_Object is
         --  automatically volatile.

         elsif Is_Descendant_Of_Suspension_Object (Id) then
            return True;

         --  Otherwise the type is not effectively volatile

         else
            return False;
         end if;

      --  Otherwise Id denotes an object

      else pragma Assert (Is_Object (Id));
         --  A volatile object for which No_Caching is enabled is not
         --  effectively volatile.

         return
           (Is_Volatile (Id)
            and then not
              (Ekind (Id) = E_Variable and then No_Caching_Enabled (Id)))
             or else Has_Volatile_Components (Id)
             or else Is_Effectively_Volatile (Etype (Id), Ignore_Protected);
      end if;
   end Is_Effectively_Volatile;

   -----------------------------------------
   -- Is_Effectively_Volatile_For_Reading --
   -----------------------------------------

   function Is_Effectively_Volatile_For_Reading
     (Id               : Entity_Id;
      Ignore_Protected : Boolean := False) return Boolean
   is
   begin
      --  A concurrent type is effectively volatile for reading, except for a
      --  protected type when Ignore_Protected is True.

      if Is_Task_Type (Id)
        or else (Is_Protected_Type (Id) and then not Ignore_Protected)
      then
         return True;

      elsif Is_Effectively_Volatile (Id, Ignore_Protected) then

        --  Other volatile types and objects are effectively volatile for
        --  reading when they have property Async_Writers or Effective_Reads
        --  set to True. This includes the case of an array type whose
        --  Volatile_Components aspect is True (hence it is effectively
        --  volatile) which does not have the properties Async_Writers
        --  and Effective_Reads set to False.

         if Async_Writers_Enabled (Id)
           or else Effective_Reads_Enabled (Id)
         then
            return True;

         --  In addition, an array type is effectively volatile for reading
         --  when its component type is effectively volatile for reading.

         elsif Is_Array_Type (Id) then
            declare
               Anc : Entity_Id := Base_Type (Id);
            begin
               if Is_Private_Type (Anc) then
                  Anc := Full_View (Anc);
               end if;

               --  Test for presence of ancestor, as the full view of a
               --  private type may be missing in case of error.

               return Present (Anc)
                 and then Is_Effectively_Volatile_For_Reading
                   (Component_Type (Anc), Ignore_Protected);
            end;
         end if;
      end if;

      return False;

   end Is_Effectively_Volatile_For_Reading;

   ------------------------------------
   -- Is_Effectively_Volatile_Object --
   ------------------------------------

   function Is_Effectively_Volatile_Object (N : Node_Id) return Boolean is
      function Is_Effectively_Volatile (E : Entity_Id) return Boolean is
         (Is_Effectively_Volatile (E, Ignore_Protected => False));

      function Is_Effectively_Volatile_Object_Inst
      is new Is_Effectively_Volatile_Object_Shared (Is_Effectively_Volatile);
   begin
      return Is_Effectively_Volatile_Object_Inst (N);
   end Is_Effectively_Volatile_Object;

   ------------------------------------------------
   -- Is_Effectively_Volatile_Object_For_Reading --
   ------------------------------------------------

   function Is_Effectively_Volatile_Object_For_Reading
     (N : Node_Id) return Boolean
   is
      function Is_Effectively_Volatile_For_Reading
        (E : Entity_Id) return Boolean
      is (Is_Effectively_Volatile_For_Reading (E, Ignore_Protected => False));

      function Is_Effectively_Volatile_Object_For_Reading_Inst
      is new Is_Effectively_Volatile_Object_Shared
        (Is_Effectively_Volatile_For_Reading);
   begin
      return Is_Effectively_Volatile_Object_For_Reading_Inst (N);
   end Is_Effectively_Volatile_Object_For_Reading;

   -------------------------------------------
   -- Is_Effectively_Volatile_Object_Shared --
   -------------------------------------------

   function Is_Effectively_Volatile_Object_Shared
     (N : Node_Id) return Boolean
   is
   begin
      if Is_Entity_Name (N) then
         return Is_Object (Entity (N))
           and then Is_Effectively_Volatile_Entity (Entity (N));

      elsif Nkind (N) in N_Indexed_Component | N_Slice then
         return Is_Effectively_Volatile_Object_Shared (Prefix (N));

      elsif Nkind (N) = N_Selected_Component then
         return
           Is_Effectively_Volatile_Object_Shared (Prefix (N))
             or else
           Is_Effectively_Volatile_Object_Shared (Selector_Name (N));

      elsif Nkind (N) in N_Qualified_Expression
                       | N_Unchecked_Type_Conversion
                       | N_Type_Conversion
      then
         return Is_Effectively_Volatile_Object_Shared (Expression (N));

      else
         return False;
      end if;
   end Is_Effectively_Volatile_Object_Shared;

   ----------------------------------------
   -- Is_Entity_Of_Quantified_Expression --
   ----------------------------------------

   function Is_Entity_Of_Quantified_Expression (Id : Entity_Id) return Boolean
   is
      Par : constant Node_Id := Parent (Id);

   begin
      return (Nkind (Par) = N_Loop_Parameter_Specification
               or else Nkind (Par) = N_Iterator_Specification)
        and then Defining_Identifier (Par) = Id
        and then Nkind (Parent (Par)) = N_Quantified_Expression;
   end Is_Entity_Of_Quantified_Expression;

   -------------------
   -- Is_Entry_Body --
   -------------------

   function Is_Entry_Body (Id : Entity_Id) return Boolean is
   begin
      return
        Is_Entry (Id)
          and then Nkind (Unit_Declaration_Node (Id)) = N_Entry_Body;
   end Is_Entry_Body;

   --------------------------
   -- Is_Entry_Declaration --
   --------------------------

   function Is_Entry_Declaration (Id : Entity_Id) return Boolean is
   begin
      return
        Is_Entry (Id)
          and then Nkind (Unit_Declaration_Node (Id)) = N_Entry_Declaration;
   end Is_Entry_Declaration;

   ------------------------------------
   -- Is_Expanded_Priority_Attribute --
   ------------------------------------

   function Is_Expanded_Priority_Attribute (E : Entity_Id) return Boolean is
   begin
      return
        Nkind (E) = N_Function_Call
          and then not Configurable_Run_Time_Mode
          and then Nkind (Original_Node (E)) = N_Attribute_Reference
          and then (Is_RTE (Entity (Name (E)), RE_Get_Ceiling)
                     or else Is_RTE (Entity (Name (E)), RO_PE_Get_Ceiling));
   end Is_Expanded_Priority_Attribute;

   ----------------------------
   -- Is_Expression_Function --
   ----------------------------

   function Is_Expression_Function (Subp : Entity_Id) return Boolean is
   begin
      if Ekind (Subp) in E_Function | E_Subprogram_Body then
         return
           Nkind (Original_Node (Unit_Declaration_Node (Subp))) =
             N_Expression_Function;
      else
         return False;
      end if;
   end Is_Expression_Function;

   ------------------------------------------
   -- Is_Expression_Function_Or_Completion --
   ------------------------------------------

   function Is_Expression_Function_Or_Completion
     (Subp : Entity_Id) return Boolean
   is
      Subp_Decl : Node_Id;

   begin
      if Ekind (Subp) = E_Function then
         Subp_Decl := Unit_Declaration_Node (Subp);

         --  The function declaration is either an expression function or is
         --  completed by an expression function body.

         return
           Is_Expression_Function (Subp)
             or else (Nkind (Subp_Decl) = N_Subprogram_Declaration
                       and then Present (Corresponding_Body (Subp_Decl))
                       and then Is_Expression_Function
                                  (Corresponding_Body (Subp_Decl)));

      elsif Ekind (Subp) = E_Subprogram_Body then
         return Is_Expression_Function (Subp);

      else
         return False;
      end if;
   end Is_Expression_Function_Or_Completion;

   -----------------------------------------------
   -- Is_Extended_Precision_Floating_Point_Type --
   -----------------------------------------------

   function Is_Extended_Precision_Floating_Point_Type
     (E : Entity_Id) return Boolean is
   begin
      return Is_Floating_Point_Type (E)
        and then Machine_Radix_Value (E) = Uint_2
        and then Machine_Mantissa_Value (E) = Uint_64
        and then Machine_Emax_Value (E) = Uint_2 ** Uint_14
        and then Machine_Emin_Value (E) = Uint_3 - (Uint_2 ** Uint_14);
   end Is_Extended_Precision_Floating_Point_Type;

   -----------------------
   -- Is_EVF_Expression --
   -----------------------

   function Is_EVF_Expression (N : Node_Id) return Boolean is
      Orig_N : constant Node_Id := Original_Node (N);
      Alt    : Node_Id;
      Expr   : Node_Id;
      Id     : Entity_Id;

   begin
      --  Detect a reference to a formal parameter of a specific tagged type
      --  whose related subprogram is subject to pragma Expresions_Visible with
      --  value "False".

      if Is_Entity_Name (N) and then Present (Entity (N)) then
         Id := Entity (N);

         return
           Is_Formal (Id)
             and then Is_Specific_Tagged_Type (Etype (Id))
             and then Extensions_Visible_Status (Id) =
                      Extensions_Visible_False;

      --  A case expression is an EVF expression when it contains at least one
      --  EVF dependent_expression. Note that a case expression may have been
      --  expanded, hence the use of Original_Node.

      elsif Nkind (Orig_N) = N_Case_Expression then
         Alt := First (Alternatives (Orig_N));
         while Present (Alt) loop
            if Is_EVF_Expression (Expression (Alt)) then
               return True;
            end if;

            Next (Alt);
         end loop;

      --  An if expression is an EVF expression when it contains at least one
      --  EVF dependent_expression. Note that an if expression may have been
      --  expanded, hence the use of Original_Node.

      elsif Nkind (Orig_N) = N_If_Expression then
         Expr := Next (First (Expressions (Orig_N)));
         while Present (Expr) loop
            if Is_EVF_Expression (Expr) then
               return True;
            end if;

            Next (Expr);
         end loop;

      --  A qualified expression or a type conversion is an EVF expression when
      --  its operand is an EVF expression.

      elsif Nkind (N) in N_Qualified_Expression
                       | N_Unchecked_Type_Conversion
                       | N_Type_Conversion
      then
         return Is_EVF_Expression (Expression (N));

      --  Attributes 'Loop_Entry, 'Old, and 'Update are EVF expressions when
      --  their prefix denotes an EVF expression.

      elsif Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) in Name_Loop_Entry
                                     | Name_Old
                                     | Name_Update
      then
         return Is_EVF_Expression (Prefix (N));
      end if;

      return False;
   end Is_EVF_Expression;

   --------------
   -- Is_False --
   --------------

   function Is_False (U : Opt_Ubool) return Boolean is
   begin
      return not Is_True (U);
   end Is_False;

   ---------------------------
   -- Is_Fixed_Model_Number --
   ---------------------------

   function Is_Fixed_Model_Number (U : Ureal; T : Entity_Id) return Boolean is
      S : constant Ureal := Small_Value (T);
      M : Urealp.Save_Mark;
      R : Boolean;

   begin
      M := Urealp.Mark;
      R := (U = UR_Trunc (U / S) * S);
      Urealp.Release (M);
      return R;
   end Is_Fixed_Model_Number;

   -----------------------------
   -- Is_Full_Access_Object --
   -----------------------------

   function Is_Full_Access_Object (N : Node_Id) return Boolean is
   begin
      return Is_Atomic_Object (N)
        or else Is_Volatile_Full_Access_Object_Ref (N);
   end Is_Full_Access_Object;

   -------------------------------
   -- Is_Fully_Initialized_Type --
   -------------------------------

   function Is_Fully_Initialized_Type (Typ : Entity_Id) return Boolean is
   begin
      --  Scalar types

      if Is_Scalar_Type (Typ) then

         --  A scalar type with an aspect Default_Value is fully initialized

         --  Note: Iniitalize/Normalize_Scalars also ensure full initialization
         --  of a scalar type, but we don't take that into account here, since
         --  we don't want these to affect warnings.

         return Has_Default_Aspect (Typ);

      elsif Is_Access_Type (Typ) then
         return True;

      elsif Is_Array_Type (Typ) then
         if Is_Fully_Initialized_Type (Component_Type (Typ))
           or else (Ada_Version >= Ada_2012 and then Has_Default_Aspect (Typ))
         then
            return True;
         end if;

         --  An interesting case, if we have a constrained type one of whose
         --  bounds is known to be null, then there are no elements to be
         --  initialized, so all the elements are initialized.

         if Is_Constrained (Typ) then
            declare
               Indx     : Node_Id;
               Indx_Typ : Entity_Id;
               Lbd, Hbd : Node_Id;

            begin
               Indx := First_Index (Typ);
               while Present (Indx) loop
                  if Etype (Indx) = Any_Type then
                     return False;

                  --  If index is a range, use directly

                  elsif Nkind (Indx) = N_Range then
                     Lbd := Low_Bound  (Indx);
                     Hbd := High_Bound (Indx);

                  else
                     Indx_Typ := Etype (Indx);

                     if Is_Private_Type (Indx_Typ) then
                        Indx_Typ := Full_View (Indx_Typ);
                     end if;

                     if No (Indx_Typ) or else Etype (Indx_Typ) = Any_Type then
                        return False;
                     else
                        Lbd := Type_Low_Bound  (Indx_Typ);
                        Hbd := Type_High_Bound (Indx_Typ);
                     end if;
                  end if;

                  if Compile_Time_Known_Value (Lbd)
                       and then
                     Compile_Time_Known_Value (Hbd)
                  then
                     if Expr_Value (Hbd) < Expr_Value (Lbd) then
                        return True;
                     end if;
                  end if;

                  Next_Index (Indx);
               end loop;
            end;
         end if;

         --  If no null indexes, then type is not fully initialized

         return False;

      --  Record types

      elsif Is_Record_Type (Typ) then
         if Has_Defaulted_Discriminants (Typ)
           and then Is_Fully_Initialized_Variant (Typ)
         then
            return True;
         end if;

         --  We consider bounded string types to be fully initialized, because
         --  otherwise we get false alarms when the Data component is not
         --  default-initialized.

         if Is_Bounded_String (Typ) then
            return True;
         end if;

         --  Controlled records are considered to be fully initialized if
         --  there is a user defined Initialize routine. This may not be
         --  entirely correct, but as the spec notes, we are guessing here
         --  what is best from the point of view of issuing warnings.

         if Is_Controlled (Typ) then
            declare
               Utyp : constant Entity_Id := Underlying_Type (Typ);

            begin
               if Present (Utyp) then
                  declare
                     Init : constant Entity_Id :=
                              (Find_Optional_Prim_Op
                                 (Underlying_Type (Typ), Name_Initialize));

                  begin
                     if Present (Init)
                       and then Comes_From_Source (Init)
                       and then not In_Predefined_Unit (Init)
                     then
                        return True;

                     elsif Has_Null_Extension (Typ)
                        and then
                          Is_Fully_Initialized_Type
                            (Etype (Base_Type (Typ)))
                     then
                        return True;
                     end if;
                  end;
               end if;
            end;
         end if;

         --  Otherwise see if all record components are initialized

         declare
            Comp : Entity_Id;

         begin
            Comp := First_Component (Typ);
            while Present (Comp) loop
               if (No (Parent (Comp))
                    or else No (Expression (Parent (Comp))))
                 and then not Is_Fully_Initialized_Type (Etype (Comp))

                  --  Special VM case for tag components, which need to be
                  --  defined in this case, but are never initialized as VMs
                  --  are using other dispatching mechanisms. Ignore this
                  --  uninitialized case. Note that this applies both to the
                  --  uTag entry and the main vtable pointer (CPP_Class case).

                 and then (Tagged_Type_Expansion or else not Is_Tag (Comp))
               then
                  return False;
               end if;

               Next_Component (Comp);
            end loop;
         end;

         --  No uninitialized components, so type is fully initialized.
         --  Note that this catches the case of no components as well.

         return True;

      elsif Is_Concurrent_Type (Typ) then
         return True;

      elsif Is_Private_Type (Typ) then
         declare
            U : constant Entity_Id := Underlying_Type (Typ);

         begin
            if No (U) then
               return False;
            else
               return Is_Fully_Initialized_Type (U);
            end if;
         end;

      else
         return False;
      end if;
   end Is_Fully_Initialized_Type;

   ----------------------------------
   -- Is_Fully_Initialized_Variant --
   ----------------------------------

   function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean is
      Loc           : constant Source_Ptr := Sloc (Typ);
      Constraints   : constant List_Id    := New_List;
      Components    : constant Elist_Id   := New_Elmt_List;
      Comp_Elmt     : Elmt_Id;
      Comp_Id       : Node_Id;
      Comp_List     : Node_Id;
      Discr         : Entity_Id;
      Discr_Val     : Node_Id;

      Report_Errors : Boolean;
      pragma Warnings (Off, Report_Errors);

   begin
      if Serious_Errors_Detected > 0 then
         return False;
      end if;

      if Is_Record_Type (Typ)
        and then Nkind (Parent (Typ)) = N_Full_Type_Declaration
        and then Nkind (Type_Definition (Parent (Typ))) = N_Record_Definition
      then
         Comp_List := Component_List (Type_Definition (Parent (Typ)));

         Discr := First_Discriminant (Typ);
         while Present (Discr) loop
            if Nkind (Parent (Discr)) = N_Discriminant_Specification then
               Discr_Val := Expression (Parent (Discr));

               if Present (Discr_Val)
                 and then Is_OK_Static_Expression (Discr_Val)
               then
                  Append_To (Constraints,
                    Make_Component_Association (Loc,
                      Choices    => New_List (New_Occurrence_Of (Discr, Loc)),
                      Expression => New_Copy (Discr_Val)));
               else
                  return False;
               end if;
            else
               return False;
            end if;

            Next_Discriminant (Discr);
         end loop;

         Gather_Components
           (Typ           => Typ,
            Comp_List     => Comp_List,
            Governed_By   => Constraints,
            Into          => Components,
            Report_Errors => Report_Errors);

         --  Check that each component present is fully initialized

         Comp_Elmt := First_Elmt (Components);
         while Present (Comp_Elmt) loop
            Comp_Id := Node (Comp_Elmt);

            if Ekind (Comp_Id) = E_Component
              and then (No (Parent (Comp_Id))
                         or else No (Expression (Parent (Comp_Id))))
              and then not Is_Fully_Initialized_Type (Etype (Comp_Id))
            then
               return False;
            end if;

            Next_Elmt (Comp_Elmt);
         end loop;

         return True;

      elsif Is_Private_Type (Typ) then
         declare
            U : constant Entity_Id := Underlying_Type (Typ);

         begin
            if No (U) then
               return False;
            else
               return Is_Fully_Initialized_Variant (U);
            end if;
         end;

      else
         return False;
      end if;
   end Is_Fully_Initialized_Variant;

   ------------------------------------
   -- Is_Generic_Declaration_Or_Body --
   ------------------------------------

   function Is_Generic_Declaration_Or_Body (Decl : Node_Id) return Boolean is
      Spec_Decl : Node_Id;

   begin
      --  Package/subprogram body

      if Nkind (Decl) in N_Package_Body | N_Subprogram_Body
        and then Present (Corresponding_Spec (Decl))
      then
         Spec_Decl := Unit_Declaration_Node (Corresponding_Spec (Decl));

      --  Package/subprogram body stub

      elsif Nkind (Decl) in N_Package_Body_Stub | N_Subprogram_Body_Stub
        and then Present (Corresponding_Spec_Of_Stub (Decl))
      then
         Spec_Decl :=
           Unit_Declaration_Node (Corresponding_Spec_Of_Stub (Decl));

      --  All other cases

      else
         Spec_Decl := Decl;
      end if;

      --  Rather than inspecting the defining entity of the spec declaration,
      --  look at its Nkind. This takes care of the case where the analysis of
      --  a generic body modifies the Ekind of its spec to allow for recursive
      --  calls.

      return Nkind (Spec_Decl) in N_Generic_Declaration;
   end Is_Generic_Declaration_Or_Body;

   ---------------------------
   -- Is_Independent_Object --
   ---------------------------

   function Is_Independent_Object (N : Node_Id) return Boolean is
      function Is_Independent_Object_Entity (Id : Entity_Id) return Boolean;
      --  Determine whether arbitrary entity Id denotes an object that is
      --  Independent.

      function Prefix_Has_Independent_Components (P : Node_Id) return Boolean;
      --  Determine whether prefix P has independent components. This requires
      --  the presence of an Independent_Components aspect/pragma.

      ------------------------------------
      --  Is_Independent_Object_Entity  --
      ------------------------------------

      function Is_Independent_Object_Entity (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Object (Id)
             and then (Is_Independent (Id)
                        or else
                       Is_Independent (Etype (Id)));
      end Is_Independent_Object_Entity;

      -------------------------------------
      -- Prefix_Has_Independent_Components --
      -------------------------------------

      function Prefix_Has_Independent_Components (P : Node_Id) return Boolean
      is
         Typ : constant Entity_Id := Etype (P);

      begin
         if Is_Access_Type (Typ) then
            return Has_Independent_Components (Designated_Type (Typ));

         elsif Has_Independent_Components (Typ) then
            return True;

         elsif Is_Entity_Name (P)
           and then Has_Independent_Components (Entity (P))
         then
            return True;

         else
            return False;
         end if;
      end Prefix_Has_Independent_Components;

   --  Start of processing for Is_Independent_Object

   begin
      if Is_Entity_Name (N) then
         return Is_Independent_Object_Entity (Entity (N));

      elsif Is_Independent (Etype (N)) then
         return True;

      elsif Nkind (N) = N_Indexed_Component then
         return Prefix_Has_Independent_Components (Prefix (N));

      elsif Nkind (N) = N_Selected_Component then
         return Prefix_Has_Independent_Components (Prefix (N))
           or else Is_Independent (Entity (Selector_Name (N)));

      else
         return False;
      end if;
   end Is_Independent_Object;

   ----------------------------
   -- Is_Inherited_Operation --
   ----------------------------

   function Is_Inherited_Operation (E : Entity_Id) return Boolean is
      pragma Assert (Is_Overloadable (E));
      Kind : constant Node_Kind := Nkind (Parent (E));
   begin
      return Kind = N_Full_Type_Declaration
        or else Kind = N_Private_Extension_Declaration
        or else Kind = N_Subtype_Declaration
        or else (Ekind (E) = E_Enumeration_Literal
                  and then Is_Derived_Type (Etype (E)));
   end Is_Inherited_Operation;

   --------------------------------------
   -- Is_Inlinable_Expression_Function --
   --------------------------------------

   function Is_Inlinable_Expression_Function
     (Subp : Entity_Id) return Boolean
   is
      Return_Expr : Node_Id;

   begin
      if Is_Expression_Function_Or_Completion (Subp)
        and then Has_Pragma_Inline_Always (Subp)
        and then Needs_No_Actuals (Subp)
        and then No (Contract (Subp))
        and then not Is_Dispatching_Operation (Subp)
        and then Needs_Finalization (Etype (Subp))
        and then not Is_Class_Wide_Type (Etype (Subp))
        and then not Has_Invariants (Etype (Subp))
        and then Present (Subprogram_Body (Subp))
        and then Was_Expression_Function (Subprogram_Body (Subp))
      then
         Return_Expr := Expression_Of_Expression_Function (Subp);

         --  The returned object must not have a qualified expression and its
         --  nominal subtype must be statically compatible with the result
         --  subtype of the expression function.

         return
           Nkind (Return_Expr) = N_Identifier
             and then Etype (Return_Expr) = Etype (Subp);
      end if;

      return False;
   end Is_Inlinable_Expression_Function;

   -----------------------
   -- Is_Internal_Block --
   -----------------------

   function Is_Internal_Block (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Block_Statement
        and then Is_Internal (Entity (Identifier (N)));
   end Is_Internal_Block;

   -----------------
   -- Is_Iterator --
   -----------------

   function Is_Iterator (Typ : Entity_Id) return Boolean is
      function Denotes_Iterator (Iter_Typ : Entity_Id) return Boolean;
      --  Determine whether type Iter_Typ is a predefined forward or reversible
      --  iterator.

      ----------------------
      -- Denotes_Iterator --
      ----------------------

      function Denotes_Iterator (Iter_Typ : Entity_Id) return Boolean is
      begin
         --  Check that the name matches, and that the ultimate ancestor is in
         --  a predefined unit, i.e the one that declares iterator interfaces.

         return
           Chars (Iter_Typ) in Name_Forward_Iterator | Name_Reversible_Iterator
             and then In_Predefined_Unit (Root_Type (Iter_Typ));
      end Denotes_Iterator;

      --  Local variables

      Iface_Elmt : Elmt_Id;
      Ifaces     : Elist_Id;

   --  Start of processing for Is_Iterator

   begin
      --  The type may be a subtype of a descendant of the proper instance of
      --  the predefined interface type, so we must use the root type of the
      --  given type. The same is done for Is_Reversible_Iterator.

      if Is_Class_Wide_Type (Typ)
        and then Denotes_Iterator (Root_Type (Typ))
      then
         return True;

      elsif not Is_Tagged_Type (Typ) or else not Is_Derived_Type (Typ) then
         return False;

      elsif Present (Find_Value_Of_Aspect (Typ, Aspect_Iterable)) then
         return True;

      else
         Collect_Interfaces (Typ, Ifaces);

         Iface_Elmt := First_Elmt (Ifaces);
         while Present (Iface_Elmt) loop
            if Denotes_Iterator (Node (Iface_Elmt)) then
               return True;
            end if;

            Next_Elmt (Iface_Elmt);
         end loop;

         return False;
      end if;
   end Is_Iterator;

   ----------------------------
   -- Is_Iterator_Over_Array --
   ----------------------------

   function Is_Iterator_Over_Array (N : Node_Id) return Boolean is
      Container     : constant Node_Id   := Name (N);
      Container_Typ : constant Entity_Id := Base_Type (Etype (Container));
   begin
      return Is_Array_Type (Container_Typ);
   end Is_Iterator_Over_Array;

   --------------------------
   -- Known_To_Be_Assigned --
   --------------------------

   function Known_To_Be_Assigned
     (N        : Node_Id;
      Only_LHS : Boolean := False) return Boolean
   is
      function Known_Assn (N : Node_Id) return Boolean is
        (Known_To_Be_Assigned (N, Only_LHS));
      --  Local function to simplify the passing of parameters for recursive
      --  calls.

      P    : constant Node_Id := Parent (N);
      Form : Entity_Id := Empty;
      Call : Node_Id   := Empty;

   --  Start of processing for Known_To_Be_Assigned

   begin
      --  Check for out parameters

      Find_Actual (N, Form, Call);

      if Present (Form) then
         return Ekind (Form) /= E_In_Parameter and then not Only_LHS;
      end if;

      --  Otherwise look at the parent

      case Nkind (P) is

         --  Test left side of assignment

         when N_Assignment_Statement =>
            return N = Name (P);

         --  Test prefix of component or attribute. Note that the prefix of an
         --  explicit or implicit dereference cannot be an l-value. In the case
         --  of a 'Read attribute, the reference can be an actual in the
         --  argument list of the attribute.

         when N_Attribute_Reference =>
            return
              not Only_LHS and then
                ((N = Prefix (P)
                   and then Name_Implies_Lvalue_Prefix (Attribute_Name (P)))
                 or else
                   Attribute_Name (P) = Name_Read);

         --  For an expanded name, the name is an lvalue if the expanded name
         --  is an lvalue, but the prefix is never an lvalue, since it is just
         --  the scope where the name is found.

         when N_Expanded_Name =>
            if N = Prefix (P) then
               return Known_Assn (P);
            else
               return False;
            end if;

         --  For a selected component A.B, A is certainly an lvalue if A.B is.
         --  B is a little interesting, if we have A.B := 3, there is some
         --  discussion as to whether B is an lvalue or not, we choose to say
         --  it is. Note however that A is not an lvalue if it is of an access
         --  type since this is an implicit dereference.

         when N_Selected_Component =>
            if N = Prefix (P)
              and then Present (Etype (N))
              and then Is_Access_Type (Etype (N))
            then
               return False;
            else
               return Known_Assn (P);
            end if;

         --  For an indexed component or slice, the index or slice bounds is
         --  never an lvalue. The prefix is an lvalue if the indexed component
         --  or slice is an lvalue, except if it is an access type, where we
         --  have an implicit dereference.

         when N_Indexed_Component | N_Slice =>
            if N /= Prefix (P)
              or else (Present (Etype (N)) and then Is_Access_Type (Etype (N)))
            then
               return False;
            else
               return Known_Assn (P);
            end if;

         --  Prefix of a reference is an lvalue if the reference is an lvalue

         when N_Reference =>
            return Known_Assn (P);

         --  Prefix of explicit dereference is never an lvalue

         when N_Explicit_Dereference =>
            return False;

         --  Test for appearing in a conversion that itself appears in an
         --  lvalue context, since this should be an lvalue.

         when N_Type_Conversion =>
            return Known_Assn (P);

         --  Test for appearance in object renaming declaration

         when N_Object_Renaming_Declaration =>
            return not Only_LHS;

         --  All other references are definitely not lvalues

         when others =>
            return False;
      end case;
   end Known_To_Be_Assigned;

   -----------------------------
   -- Is_Library_Level_Entity --
   -----------------------------

   function Is_Library_Level_Entity (E : Entity_Id) return Boolean is
   begin
      --  The following is a small optimization, and it also properly handles
      --  discriminals, which in task bodies might appear in expressions before
      --  the corresponding procedure has been created, and which therefore do
      --  not have an assigned scope.

      if Is_Formal (E) then
         return False;

      --  If we somehow got an empty value for Scope, the tree must be
      --  malformed. Rather than blow up we return True in this case.

      elsif No (Scope (E)) then
         return True;

      --  Handle loops since Enclosing_Dynamic_Scope skips them; required to
      --  properly handle entities local to quantified expressions in library
      --  level specifications.

      elsif Ekind (Scope (E)) = E_Loop then
         return False;
      end if;

      --  Normal test is simply that the enclosing dynamic scope is Standard

      return Enclosing_Dynamic_Scope (E) = Standard_Standard;
   end Is_Library_Level_Entity;

   --------------------------------
   -- Is_Limited_Class_Wide_Type --
   --------------------------------

   function Is_Limited_Class_Wide_Type (Typ : Entity_Id) return Boolean is
   begin
      return
        Is_Class_Wide_Type (Typ)
          and then (Is_Limited_Type (Typ) or else From_Limited_With (Typ));
   end Is_Limited_Class_Wide_Type;

   ---------------------------------
   -- Is_Local_Variable_Reference --
   ---------------------------------

   function Is_Local_Variable_Reference (Expr : Node_Id) return Boolean is
   begin
      if not Is_Entity_Name (Expr) then
         return False;

      else
         declare
            Ent : constant Entity_Id := Entity (Expr);
            Sub : constant Entity_Id := Enclosing_Subprogram (Ent);
         begin
            if Ekind (Ent)
              not in E_Variable | E_In_Out_Parameter | E_Out_Parameter
            then
               return False;
            else
               return Present (Sub) and then Sub = Current_Subprogram;
            end if;
         end;
      end if;
   end Is_Local_Variable_Reference;

   ---------------
   -- Is_Master --
   ---------------

   function Is_Master (N : Node_Id) return Boolean is
      Disable_Subexpression_Masters : constant Boolean := True;

   begin
      if Nkind (N) in N_Subprogram_Body | N_Task_Body | N_Entry_Body
        or else Is_Statement (N)
      then
         return True;
      end if;

      --  We avoid returning True when the master is a subexpression described
      --  in RM 7.6.1(3/2) for the proposes of accessibility level calculation
      --  in Accessibility_Level_Helper.Innermost_Master_Scope_Depth ???

      if not Disable_Subexpression_Masters
        and then Nkind (N) in N_Subexpr
      then
         declare
            Par : Node_Id := N;

            subtype N_Simple_Statement_Other_Than_Simple_Return
              is Node_Kind with Static_Predicate =>
                N_Simple_Statement_Other_Than_Simple_Return
                  in N_Abort_Statement
                   | N_Assignment_Statement
                   | N_Code_Statement
                   | N_Delay_Statement
                   | N_Entry_Call_Statement
                   | N_Free_Statement
                   | N_Goto_Statement
                   | N_Null_Statement
                   | N_Raise_Statement
                   | N_Requeue_Statement
                   | N_Exit_Statement
                   | N_Procedure_Call_Statement;
         begin
            while Present (Par) loop
               Par := Parent (Par);
               if Nkind (Par) in N_Subexpr |
                 N_Simple_Statement_Other_Than_Simple_Return
               then
                  return False;
               end if;
            end loop;

            return True;
         end;
      end if;

      return False;
   end Is_Master;

   -----------------------
   -- Is_Name_Reference --
   -----------------------

   function Is_Name_Reference (N : Node_Id) return Boolean is
   begin
      if Is_Entity_Name (N) then
         return Present (Entity (N)) and then Is_Object (Entity (N));
      end if;

      case Nkind (N) is
         when N_Indexed_Component
            | N_Slice
         =>
            return
              Is_Name_Reference (Prefix (N))
                or else Is_Access_Type (Etype (Prefix (N)));

         --  Attributes 'Input, 'Old and 'Result produce objects

         when N_Attribute_Reference =>
            return Attribute_Name (N) in Name_Input | Name_Old | Name_Result;

         when N_Selected_Component =>
            return
              Is_Name_Reference (Selector_Name (N))
                and then
                  (Is_Name_Reference (Prefix (N))
                    or else Is_Access_Type (Etype (Prefix (N))));

         when N_Explicit_Dereference =>
            return True;

         --  A view conversion of a tagged name is a name reference

         when N_Type_Conversion =>
            return
              Is_Tagged_Type (Etype (Subtype_Mark (N)))
                and then Is_Tagged_Type (Etype (Expression (N)))
                and then Is_Name_Reference (Expression (N));

         --  An unchecked type conversion is considered to be a name if the
         --  operand is a name (this construction arises only as a result of
         --  expansion activities).

         when N_Unchecked_Type_Conversion =>
            return Is_Name_Reference (Expression (N));

         when others =>
            return False;
      end case;
   end Is_Name_Reference;

   --------------------------
   -- Is_Newly_Constructed --
   --------------------------

   function Is_Newly_Constructed
     (Exp : Node_Id; Context_Requires_NC : Boolean) return Boolean
   is
      Original_Exp : constant Node_Id := Original_Node (Exp);

      function Is_NC (Exp : Node_Id) return Boolean is
        (Is_Newly_Constructed (Exp, Context_Requires_NC));

      --  If the context requires that the expression shall be newly
      --  constructed, then "True" is a good result in the sense that the
      --  expression satisfies the requirements of the context (and "False"
      --  is analogously a bad result). If the context requires that the
      --  expression shall *not* be newly constructed, then things are
      --  reversed: "False" is the good value and "True" is the bad value.

      Good_Result : constant Boolean := Context_Requires_NC;
      Bad_Result  : constant Boolean := not Good_Result;
   begin
      case Nkind (Original_Exp) is
         when N_Aggregate
            | N_Extension_Aggregate
            | N_Function_Call
            | N_Op
         =>
            return True;

         when N_Identifier =>
            return Present (Entity (Original_Exp))
              and then Ekind (Entity (Original_Exp)) = E_Function;

         when N_Qualified_Expression =>
            return Is_NC (Expression (Original_Exp));

         when N_Type_Conversion
            | N_Unchecked_Type_Conversion
         =>
            if Is_View_Conversion (Original_Exp) then
               return Is_NC (Expression (Original_Exp));
            elsif not Comes_From_Source (Exp) then
               if Exp /= Original_Exp then
                  return Is_NC (Original_Exp);
               else
                  return Is_NC (Expression (Original_Exp));
               end if;
            else
               return False;
            end if;

         when N_Explicit_Dereference
            | N_Indexed_Component
            | N_Selected_Component
         =>
            return Nkind (Exp) = N_Function_Call;

         --  A use of 'Input is a function call, hence allowed. Normally the
         --  attribute will be changed to a call, but the attribute by itself
         --  can occur with -gnatc.

         when N_Attribute_Reference =>
            return Attribute_Name (Original_Exp) = Name_Input;

         --  "return raise ..." is OK

         when N_Raise_Expression =>
            return Good_Result;

         --  For a case expression, all dependent expressions must be legal

         when N_Case_Expression =>
            declare
               Alt : Node_Id;

            begin
               Alt := First (Alternatives (Original_Exp));
               while Present (Alt) loop
                  if Is_NC (Expression (Alt)) = Bad_Result then
                     return Bad_Result;
                  end if;

                  Next (Alt);
               end loop;

               return Good_Result;
            end;

         --  For an if expression, all dependent expressions must be legal

         when N_If_Expression =>
            declare
               Then_Expr : constant Node_Id :=
                             Next (First (Expressions (Original_Exp)));
               Else_Expr : constant Node_Id := Next (Then_Expr);
            begin
               if Is_NC (Then_Expr) = Bad_Result
                 or else Is_NC (Else_Expr) = Bad_Result
               then
                  return Bad_Result;
               else
                  return Good_Result;
               end if;
            end;

         when others =>
            return False;
      end case;
   end Is_Newly_Constructed;

   ------------------------------------
   -- Is_Non_Preelaborable_Construct --
   ------------------------------------

   function Is_Non_Preelaborable_Construct (N : Node_Id) return Boolean is

      --  NOTE: the routines within Is_Non_Preelaborable_Construct are
      --  intentionally unnested to avoid deep indentation of code.

      Non_Preelaborable : exception;
      --  This exception is raised when the construct violates preelaborability
      --  to terminate the recursion.

      procedure Visit (Nod : Node_Id);
      --  Semantically inspect construct Nod to determine whether it violates
      --  preelaborability. This routine raises Non_Preelaborable.

      procedure Visit_List (List : List_Id);
      pragma Inline (Visit_List);
      --  Invoke Visit on each element of list List. This routine raises
      --  Non_Preelaborable.

      procedure Visit_Pragma (Prag : Node_Id);
      pragma Inline (Visit_Pragma);
      --  Semantically inspect pragma Prag to determine whether it violates
      --  preelaborability. This routine raises Non_Preelaborable.

      procedure Visit_Subexpression (Expr : Node_Id);
      pragma Inline (Visit_Subexpression);
      --  Semantically inspect expression Expr to determine whether it violates
      --  preelaborability. This routine raises Non_Preelaborable.

      -----------
      -- Visit --
      -----------

      procedure Visit (Nod : Node_Id) is
      begin
         case Nkind (Nod) is

            --  Declarations

            when N_Component_Declaration =>

               --  Defining_Identifier is left out because it is not relevant
               --  for preelaborability.

               Visit (Component_Definition (Nod));
               Visit (Expression (Nod));

            when N_Derived_Type_Definition =>

               --  Interface_List is left out because it is not relevant for
               --  preelaborability.

               Visit (Record_Extension_Part (Nod));
               Visit (Subtype_Indication (Nod));

            when N_Entry_Declaration =>

               --  A protected type with at leat one entry is not preelaborable
               --  while task types are never preelaborable. This renders entry
               --  declarations non-preelaborable.

               raise Non_Preelaborable;

            when N_Full_Type_Declaration =>

               --  Defining_Identifier and Discriminant_Specifications are left
               --  out because they are not relevant for preelaborability.

               Visit (Type_Definition (Nod));

            when N_Function_Instantiation
               | N_Package_Instantiation
               | N_Procedure_Instantiation
            =>
               --  Defining_Unit_Name and Name are left out because they are
               --  not relevant for preelaborability.

               Visit_List (Generic_Associations (Nod));

            when N_Object_Declaration =>

               --  Defining_Identifier is left out because it is not relevant
               --  for preelaborability.

               Visit (Object_Definition (Nod));

               if Has_Init_Expression (Nod) then
                  Visit (Expression (Nod));

               elsif not Constant_Present (Nod)
                 and then not Has_Preelaborable_Initialization
                                (Etype (Defining_Entity (Nod)))
               then
                  raise Non_Preelaborable;
               end if;

            when N_Private_Extension_Declaration
               | N_Subtype_Declaration
            =>
               --  Defining_Identifier, Discriminant_Specifications, and
               --  Interface_List are left out because they are not relevant
               --  for preelaborability.

               Visit (Subtype_Indication (Nod));

            when N_Protected_Type_Declaration
               | N_Single_Protected_Declaration
            =>
               --  Defining_Identifier, Discriminant_Specifications, and
               --  Interface_List are left out because they are not relevant
               --  for preelaborability.

               Visit (Protected_Definition (Nod));

            --  A [single] task type is never preelaborable

            when N_Single_Task_Declaration
               | N_Task_Type_Declaration
            =>
               raise Non_Preelaborable;

            --  Pragmas

            when N_Pragma =>
               Visit_Pragma (Nod);

            --  Statements

            when N_Statement_Other_Than_Procedure_Call =>
               if Nkind (Nod) /= N_Null_Statement then
                  raise Non_Preelaborable;
               end if;

            --  Subexpressions

            when N_Subexpr =>
               Visit_Subexpression (Nod);

            --  Special

            when N_Access_To_Object_Definition =>
               Visit (Subtype_Indication (Nod));

            when N_Case_Expression_Alternative =>
               Visit (Expression (Nod));
               Visit_List (Discrete_Choices (Nod));

            when N_Component_Definition =>
               Visit (Access_Definition (Nod));
               Visit (Subtype_Indication (Nod));

            when N_Component_List =>
               Visit_List (Component_Items (Nod));
               Visit (Variant_Part (Nod));

            when N_Constrained_Array_Definition =>
               Visit_List (Discrete_Subtype_Definitions (Nod));
               Visit (Component_Definition (Nod));

            when N_Delta_Constraint
               | N_Digits_Constraint
            =>
               --  Delta_Expression and Digits_Expression are left out because
               --  they are not relevant for preelaborability.

               Visit (Range_Constraint (Nod));

            when N_Discriminant_Specification =>

               --  Defining_Identifier and Expression are left out because they
               --  are not relevant for preelaborability.

               Visit (Discriminant_Type (Nod));

            when N_Generic_Association =>

               --  Selector_Name is left out because it is not relevant for
               --  preelaborability.

               Visit (Explicit_Generic_Actual_Parameter (Nod));

            when N_Index_Or_Discriminant_Constraint =>
               Visit_List (Constraints (Nod));

            when N_Iterator_Specification =>

               --  Defining_Identifier is left out because it is not relevant
               --  for preelaborability.

               Visit (Name (Nod));
               Visit (Subtype_Indication (Nod));

            when N_Loop_Parameter_Specification =>

               --  Defining_Identifier is left out because it is not relevant
               --  for preelaborability.

               Visit (Discrete_Subtype_Definition (Nod));

            when N_Parameter_Association =>
               Visit (Explicit_Actual_Parameter (N));

            when N_Protected_Definition =>

               --  End_Label is left out because it is not relevant for
               --  preelaborability.

               Visit_List (Private_Declarations (Nod));
               Visit_List (Visible_Declarations (Nod));

            when N_Range_Constraint =>
               Visit (Range_Expression (Nod));

            when N_Record_Definition
               | N_Variant
            =>
               --  End_Label, Discrete_Choices, and Interface_List are left out
               --  because they are not relevant for preelaborability.

               Visit (Component_List (Nod));

            when N_Subtype_Indication =>

               --  Subtype_Mark is left out because it is not relevant for
               --  preelaborability.

               Visit (Constraint (Nod));

            when N_Unconstrained_Array_Definition =>

               --  Subtype_Marks is left out because it is not relevant for
               --  preelaborability.

               Visit (Component_Definition (Nod));

            when N_Variant_Part =>

               --  Name is left out because it is not relevant for
               --  preelaborability.

               Visit_List (Variants (Nod));

            --  Default

            when others =>
               null;
         end case;
      end Visit;

      ----------------
      -- Visit_List --
      ----------------

      procedure Visit_List (List : List_Id) is
         Nod : Node_Id;

      begin
         Nod := First (List);
         while Present (Nod) loop
            Visit (Nod);
            Next (Nod);
         end loop;
      end Visit_List;

      ------------------
      -- Visit_Pragma --
      ------------------

      procedure Visit_Pragma (Prag : Node_Id) is
      begin
         case Get_Pragma_Id (Prag) is
            when Pragma_Assert
               | Pragma_Assert_And_Cut
               | Pragma_Assume
               | Pragma_Async_Readers
               | Pragma_Async_Writers
               | Pragma_Attribute_Definition
               | Pragma_Check
               | Pragma_Constant_After_Elaboration
               | Pragma_CPU
               | Pragma_Deadline_Floor
               | Pragma_Dispatching_Domain
               | Pragma_Effective_Reads
               | Pragma_Effective_Writes
               | Pragma_Extensions_Visible
               | Pragma_Ghost
               | Pragma_Secondary_Stack_Size
               | Pragma_Task_Name
               | Pragma_Volatile_Function
            =>
               Visit_List (Pragma_Argument_Associations (Prag));

            --  Default

            when others =>
               null;
         end case;
      end Visit_Pragma;

      -------------------------
      -- Visit_Subexpression --
      -------------------------

      procedure Visit_Subexpression (Expr : Node_Id) is
         procedure Visit_Aggregate (Aggr : Node_Id);
         pragma Inline (Visit_Aggregate);
         --  Semantically inspect aggregate Aggr to determine whether it
         --  violates preelaborability.

         ---------------------
         -- Visit_Aggregate --
         ---------------------

         procedure Visit_Aggregate (Aggr : Node_Id) is
         begin
            if not Is_Preelaborable_Aggregate (Aggr) then
               raise Non_Preelaborable;
            end if;
         end Visit_Aggregate;

      --  Start of processing for Visit_Subexpression

      begin
         case Nkind (Expr) is
            when N_Allocator
               | N_Qualified_Expression
               | N_Type_Conversion
               | N_Unchecked_Expression
               | N_Unchecked_Type_Conversion
            =>
               --  Subpool_Handle_Name and Subtype_Mark are left out because
               --  they are not relevant for preelaborability.

               Visit (Expression (Expr));

            when N_Aggregate
               | N_Extension_Aggregate
            =>
               Visit_Aggregate (Expr);

            when N_Attribute_Reference
               | N_Explicit_Dereference
               | N_Reference
            =>
               --  Attribute_Name and Expressions are left out because they are
               --  not relevant for preelaborability.

               Visit (Prefix (Expr));

            when N_Case_Expression =>

               --  End_Span is left out because it is not relevant for
               --  preelaborability.

               Visit_List (Alternatives (Expr));
               Visit (Expression (Expr));

            when N_Delta_Aggregate =>
               Visit_Aggregate (Expr);
               Visit (Expression (Expr));

            when N_Expression_With_Actions =>
               Visit_List (Actions (Expr));
               Visit (Expression (Expr));

            when N_Function_Call =>

               --  Ada 2022 (AI12-0175): Calls to certain functions that are
               --  essentially unchecked conversions are preelaborable.

               if Ada_Version >= Ada_2022
                 and then Nkind (Expr) = N_Function_Call
                 and then Is_Entity_Name (Name (Expr))
                 and then Is_Preelaborable_Function (Entity (Name (Expr)))
               then
                  Visit_List (Parameter_Associations (Expr));
               else
                  raise Non_Preelaborable;
               end if;

            when N_If_Expression =>
               Visit_List (Expressions (Expr));

            when N_Quantified_Expression =>
               Visit (Condition (Expr));
               Visit (Iterator_Specification (Expr));
               Visit (Loop_Parameter_Specification (Expr));

            when N_Range =>
               Visit (High_Bound (Expr));
               Visit (Low_Bound (Expr));

            when N_Slice =>
               Visit (Discrete_Range (Expr));
               Visit (Prefix (Expr));

            --  Default

            when others =>

               --  The evaluation of an object name is not preelaborable,
               --  unless the name is a static expression (checked further
               --  below), or statically denotes a discriminant.

               if Is_Entity_Name (Expr) then
                  Object_Name : declare
                     Id : constant Entity_Id := Entity (Expr);

                  begin
                     if Is_Object (Id) then
                        if Ekind (Id) = E_Discriminant then
                           null;

                        elsif Ekind (Id) in E_Constant | E_In_Parameter
                          and then Present (Discriminal_Link (Id))
                        then
                           null;

                        else
                           raise Non_Preelaborable;
                        end if;
                     end if;
                  end Object_Name;

               --  A non-static expression is not preelaborable

               elsif not Is_OK_Static_Expression (Expr) then
                  raise Non_Preelaborable;
               end if;
         end case;
      end Visit_Subexpression;

   --  Start of processing for Is_Non_Preelaborable_Construct

   begin
      Visit (N);

      --  At this point it is known that the construct is preelaborable

      return False;

   exception

      --  The elaboration of the construct performs an action which violates
      --  preelaborability.

      when Non_Preelaborable =>
         return True;
   end Is_Non_Preelaborable_Construct;

   ---------------------------------
   -- Is_Nontrivial_DIC_Procedure --
   ---------------------------------

   function Is_Nontrivial_DIC_Procedure (Id : Entity_Id) return Boolean is
      Body_Decl : Node_Id;
      Stmt      : Node_Id;

   begin
      if Ekind (Id) = E_Procedure and then Is_DIC_Procedure (Id) then
         Body_Decl :=
           Unit_Declaration_Node
             (Corresponding_Body (Unit_Declaration_Node (Id)));

         --  The body of the Default_Initial_Condition procedure must contain
         --  at least one statement, otherwise the generation of the subprogram
         --  body failed.

         pragma Assert (Present (Handled_Statement_Sequence (Body_Decl)));

         --  To qualify as nontrivial, the first statement of the procedure
         --  must be a check in the form of an if statement. If the original
         --  Default_Initial_Condition expression was folded, then the first
         --  statement is not a check.

         Stmt := First (Statements (Handled_Statement_Sequence (Body_Decl)));

         return
           Nkind (Stmt) = N_If_Statement
             and then Nkind (Original_Node (Stmt)) = N_Pragma;
      end if;

      return False;
   end Is_Nontrivial_DIC_Procedure;

   -----------------------
   -- Is_Null_Extension --
   -----------------------

   function Is_Null_Extension
     (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean
   is
      Type_Decl : Node_Id;
      Type_Def  : Node_Id;
   begin
      pragma Assert (not Is_Class_Wide_Type (T));

      if Ignore_Privacy then
         Type_Decl := Parent (Underlying_Type (Base_Type (T)));
      else
         Type_Decl := Parent (Base_Type (T));
         if Nkind (Type_Decl) /= N_Full_Type_Declaration then
            return False;
         end if;
      end if;
      pragma Assert (Nkind (Type_Decl) = N_Full_Type_Declaration);
      Type_Def := Type_Definition (Type_Decl);
      if Present (Discriminant_Specifications (Type_Decl))
        or else Nkind (Type_Def) /= N_Derived_Type_Definition
        or else not Is_Tagged_Type (T)
        or else No (Record_Extension_Part (Type_Def))
      then
         return False;
      end if;

      return Is_Null_Record_Definition (Record_Extension_Part (Type_Def));
   end Is_Null_Extension;

   --------------------------
   -- Is_Null_Extension_Of --
   --------------------------

   function Is_Null_Extension_Of
     (Descendant, Ancestor : Entity_Id) return Boolean
   is
      Ancestor_Type : constant Entity_Id
        := Underlying_Type (Base_Type (Ancestor));
      Descendant_Type : Entity_Id := Underlying_Type (Base_Type (Descendant));
   begin
      pragma Assert (not Is_Class_Wide_Type (Descendant));
      pragma Assert (not Is_Class_Wide_Type (Ancestor));
      pragma Assert (Descendant_Type /= Ancestor_Type);

      while Descendant_Type /= Ancestor_Type loop
         if not Is_Null_Extension
                  (Descendant_Type, Ignore_Privacy => True)
         then
            return False;
         end if;
         Descendant_Type := Etype (Subtype_Indication
                              (Type_Definition (Parent (Descendant_Type))));
         Descendant_Type := Underlying_Type (Base_Type (Descendant_Type));
      end loop;
      return True;
   end Is_Null_Extension_Of;

   -------------------------------
   -- Is_Null_Record_Definition --
   -------------------------------

   function Is_Null_Record_Definition (Record_Def : Node_Id) return Boolean is
      Item : Node_Id;
   begin
      --  Testing Null_Present is just an optimization, not required.

      if Null_Present (Record_Def) then
         return True;
      elsif Present (Variant_Part (Component_List (Record_Def))) then
         return False;
      elsif No (Component_List (Record_Def)) then
         return True;
      end if;

      Item := First_Non_Pragma (Component_Items (Component_List (Record_Def)));

      while Present (Item) loop
         if Nkind (Item) = N_Component_Declaration
           and then Is_Internal_Name (Chars (Defining_Identifier (Item)))
         then
            null;
         else
            return False;
         end if;
         Next_Non_Pragma (Item);
      end loop;

      return True;
   end Is_Null_Record_Definition;

   -------------------------
   -- Is_Null_Record_Type --
   -------------------------

   function Is_Null_Record_Type
     (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean
   is
      Decl     : Node_Id;
      Type_Def : Node_Id;
   begin
      if not Is_Record_Type (T) then
         return False;
      end if;

      if Ignore_Privacy then
         Decl := Parent (Underlying_Type (Base_Type (T)));
      else
         Decl := Parent (Base_Type (T));
         if Nkind (Decl) /= N_Full_Type_Declaration then
            return False;
         end if;
      end if;
      pragma Assert (Nkind (Decl) = N_Full_Type_Declaration);
      Type_Def := Type_Definition (Decl);

      if Has_Discriminants (Defining_Identifier (Decl)) then
         return False;
      end if;

      case Nkind (Type_Def) is
         when N_Record_Definition =>
            return Is_Null_Record_Definition (Type_Def);
         when N_Derived_Type_Definition =>
            if not Is_Null_Record_Type
                     (Etype (Subtype_Indication (Type_Def)),
                      Ignore_Privacy => Ignore_Privacy)
            then
               return False;
            elsif not Is_Tagged_Type (T) then
               return True;
            else
               return Is_Null_Extension (T, Ignore_Privacy => Ignore_Privacy);
            end if;
         when others =>
            return False;
      end case;
   end Is_Null_Record_Type;

   ---------------------
   -- Is_Object_Image --
   ---------------------

   function Is_Object_Image (Prefix : Node_Id) return Boolean is
   begin
      --  Here we test for the case that the prefix is not a type and assume
      --  if it is not then it must be a named value or an object reference.
      --  This is because the parser always checks that prefixes of attributes
      --  are named.

      return not (Is_Entity_Name (Prefix)
                  and then Is_Type (Entity (Prefix))
                  and then not Is_Current_Instance (Prefix));
   end Is_Object_Image;

   -------------------------
   -- Is_Object_Reference --
   -------------------------

   function Is_Object_Reference (N : Node_Id) return Boolean is
      function Safe_Prefix (N : Node_Id) return Node_Id;
      --  Return Prefix (N) unless it has been rewritten as an
      --  N_Raise_xxx_Error node, in which case return its original node.

      -----------------
      -- Safe_Prefix --
      -----------------

      function Safe_Prefix (N : Node_Id) return Node_Id is
      begin
         if Nkind (Prefix (N)) in N_Raise_xxx_Error then
            return Original_Node (Prefix (N));
         else
            return Prefix (N);
         end if;
      end Safe_Prefix;

   begin
      --  AI12-0068: Note that a current instance reference in a type or
      --  subtype's aspect_specification is considered a value, not an object
      --  (see RM 8.6(18/5)).

      if Is_Entity_Name (N) then
         return Present (Entity (N)) and then Is_Object (Entity (N))
           and then not Is_Current_Instance_Reference_In_Type_Aspect (N);

      else
         case Nkind (N) is
            when N_Indexed_Component
               | N_Slice
            =>
               return
                 Is_Object_Reference (Safe_Prefix (N))
                   or else Is_Access_Type (Etype (Safe_Prefix (N)));

            --  In Ada 95, a function call is a constant object; a procedure
            --  call is not.

            --  Note that predefined operators are functions as well, and so
            --  are attributes that are (can be renamed as) functions.

            when N_Function_Call
               | N_Op
            =>
               return Etype (N) /= Standard_Void_Type;

            --  Attributes references 'Loop_Entry, 'Old, 'Priority and 'Result
            --  yield objects, even though they are not functions.

            when N_Attribute_Reference =>
               return
                 Attribute_Name (N) in Name_Loop_Entry
                                     | Name_Old
                                     | Name_Priority
                                     | Name_Result
                   or else Is_Function_Attribute_Name (Attribute_Name (N));

            when N_Selected_Component =>
               return
                 Is_Object_Reference (Selector_Name (N))
                   and then
                     (Is_Object_Reference (Safe_Prefix (N))
                       or else Is_Access_Type (Etype (Safe_Prefix (N))));

            --  An explicit dereference denotes an object, except that a
            --  conditional expression gets turned into an explicit dereference
            --  in some cases, and conditional expressions are not object
            --  names.

            when N_Explicit_Dereference =>
               return Nkind (Original_Node (N)) not in
                        N_Case_Expression | N_If_Expression;

            --  A view conversion of a tagged object is an object reference

            when N_Type_Conversion =>
               if Ada_Version <= Ada_2012 then
                  --  A view conversion of a tagged object is an object
                  --  reference.
                  return Is_Tagged_Type (Etype (Subtype_Mark (N)))
                    and then Is_Tagged_Type (Etype (Expression (N)))
                    and then Is_Object_Reference (Expression (N));

               else
                  --  AI12-0226: In Ada 2022 a value conversion of an object is
                  --  an object.

                  return Is_Object_Reference (Expression (N));
               end if;

            --  An unchecked type conversion is considered to be an object if
            --  the operand is an object (this construction arises only as a
            --  result of expansion activities).

            when N_Unchecked_Type_Conversion =>
               return True;

            --  AI05-0003: In Ada 2012 a qualified expression is a name.
            --  This allows disambiguation of function calls and the use
            --  of aggregates in more contexts.

            when N_Qualified_Expression =>
               return Ada_Version >= Ada_2012
                 and then Is_Object_Reference (Expression (N));

            --  In Ada 95 an aggregate is an object reference

            when N_Aggregate
               | N_Delta_Aggregate
               | N_Extension_Aggregate
            =>
               return Ada_Version >= Ada_95;

            --  A string literal is not an object reference, but it might come
            --  from rewriting of an object reference, e.g. from folding of an
            --  aggregate.

            when N_String_Literal =>
               return Is_Rewrite_Substitution (N)
                 and then Is_Object_Reference (Original_Node (N));

            --  AI12-0125: Target name represents a constant object

            when N_Target_Name =>
               return True;

            when others =>
               return False;
         end case;
      end if;
   end Is_Object_Reference;

   -----------------------------------
   -- Is_OK_Variable_For_Out_Formal --
   -----------------------------------

   function Is_OK_Variable_For_Out_Formal (AV : Node_Id) return Boolean is
   begin
      Note_Possible_Modification (AV, Sure => True);

      --  We must reject parenthesized variable names. Comes_From_Source is
      --  checked because there are currently cases where the compiler violates
      --  this rule (e.g. passing a task object to its controlled Initialize
      --  routine). This should be properly documented in sinfo???

      if Paren_Count (AV) > 0 and then Comes_From_Source (AV) then
         return False;

      --  A variable is always allowed

      elsif Is_Variable (AV) then
         return True;

      --  Generalized indexing operations are rewritten as explicit
      --  dereferences, and it is only during resolution that we can
      --  check whether the context requires an access_to_variable type.

      elsif Nkind (AV) = N_Explicit_Dereference
        and then Present (Etype (Original_Node (AV)))
        and then Has_Implicit_Dereference (Etype (Original_Node (AV)))
        and then Ada_Version >= Ada_2012
      then
         return not Is_Access_Constant (Etype (Prefix (AV)));

      --  Unchecked conversions are allowed only if they come from the
      --  generated code, which sometimes uses unchecked conversions for out
      --  parameters in cases where code generation is unaffected. We tell
      --  source unchecked conversions by seeing if they are rewrites of
      --  an original Unchecked_Conversion function call, or of an explicit
      --  conversion of a function call or an aggregate (as may happen in the
      --  expansion of a packed array aggregate).

      elsif Nkind (AV) = N_Unchecked_Type_Conversion then
         if Nkind (Original_Node (AV)) in N_Function_Call | N_Aggregate then
            return False;

         elsif Nkind (Original_Node (Expression (AV))) = N_Function_Call then
            return False;

         elsif Nkind (Original_Node (AV)) = N_Type_Conversion then
            return Is_OK_Variable_For_Out_Formal (Expression (AV));

         else
            return True;
         end if;

      --  Normal type conversions are allowed if argument is a variable

      elsif Nkind (AV) = N_Type_Conversion then
         if Is_Variable (Expression (AV))
           and then Paren_Count (Expression (AV)) = 0
         then
            Note_Possible_Modification (Expression (AV), Sure => True);
            return True;

         --  We also allow a non-parenthesized expression that raises
         --  constraint error if it rewrites what used to be a variable

         elsif Raises_Constraint_Error (Expression (AV))
            and then Paren_Count (Expression (AV)) = 0
            and then Is_Variable (Original_Node (Expression (AV)))
         then
            return True;

         --  Type conversion of something other than a variable

         else
            return False;
         end if;

      --  If this node is rewritten, then test the original form, if that is
      --  OK, then we consider the rewritten node OK (for example, if the
      --  original node is a conversion, then Is_Variable will not be true
      --  but we still want to allow the conversion if it converts a variable).

      elsif Is_Rewrite_Substitution (AV) then
         return Is_OK_Variable_For_Out_Formal (Original_Node (AV));

      --  All other non-variables are rejected

      else
         return False;
      end if;
   end Is_OK_Variable_For_Out_Formal;

   ----------------------------
   -- Is_OK_Volatile_Context --
   ----------------------------

   function Is_OK_Volatile_Context
     (Context       : Node_Id;
      Obj_Ref       : Node_Id;
      Check_Actuals : Boolean) return Boolean
   is
      function Is_Protected_Operation_Call (Nod : Node_Id) return Boolean;
      --  Determine whether an arbitrary node denotes a call to a protected
      --  entry, function, or procedure in prefixed form where the prefix is
      --  Obj_Ref.

      function Within_Check (Nod : Node_Id) return Boolean;
      --  Determine whether an arbitrary node appears in a check node

      function Within_Volatile_Function (Id : Entity_Id) return Boolean;
      --  Determine whether an arbitrary entity appears in a volatile function

      ---------------------------------
      -- Is_Protected_Operation_Call --
      ---------------------------------

      function Is_Protected_Operation_Call (Nod : Node_Id) return Boolean is
         Pref : Node_Id;
         Subp : Node_Id;

      begin
         --  A call to a protected operations retains its selected component
         --  form as opposed to other prefixed calls that are transformed in
         --  expanded names.

         if Nkind (Nod) = N_Selected_Component then
            Pref := Prefix (Nod);
            Subp := Selector_Name (Nod);

            return
              Pref = Obj_Ref
                and then Present (Etype (Pref))
                and then Is_Protected_Type (Etype (Pref))
                and then Is_Entity_Name (Subp)
                and then Present (Entity (Subp))
                and then Ekind (Entity (Subp)) in
                           E_Entry | E_Entry_Family | E_Function | E_Procedure;
         else
            return False;
         end if;
      end Is_Protected_Operation_Call;

      ------------------
      -- Within_Check --
      ------------------

      function Within_Check (Nod : Node_Id) return Boolean is
         Par : Node_Id;

      begin
         --  Climb the parent chain looking for a check node

         Par := Nod;
         while Present (Par) loop
            if Nkind (Par) in N_Raise_xxx_Error then
               return True;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);
         end loop;

         return False;
      end Within_Check;

      ------------------------------
      -- Within_Volatile_Function --
      ------------------------------

      function Within_Volatile_Function (Id : Entity_Id) return Boolean is
         pragma Assert (Ekind (Id) = E_Return_Statement);

         Func_Id : constant Entity_Id := Return_Applies_To (Id);

      begin
         pragma Assert (Ekind (Func_Id) in E_Function | E_Generic_Function);

         return Is_Volatile_Function (Func_Id);
      end Within_Volatile_Function;

      --  Local variables

      Obj_Id : Entity_Id;

   --  Start of processing for Is_OK_Volatile_Context

   begin
      --  Ignore context restriction when doing preanalysis, e.g. on a copy of
      --  an expression function, because this copy is not fully decorated and
      --  it is not possible to reliably decide the legality of the context.
      --  Any violations will be reported anyway when doing the full analysis.

      if not Full_Analysis then
         return True;
      end if;

      --  For actual parameters within explicit parameter associations switch
      --  the context to the corresponding subprogram call.

      if Nkind (Context) = N_Parameter_Association then
         return Is_OK_Volatile_Context (Context       => Parent (Context),
                                        Obj_Ref       => Obj_Ref,
                                        Check_Actuals => Check_Actuals);

      --  The volatile object appears on either side of an assignment

      elsif Nkind (Context) = N_Assignment_Statement then
         return True;

      --  The volatile object is part of the initialization expression of
      --  another object.

      elsif Nkind (Context) = N_Object_Declaration
        and then Present (Expression (Context))
        and then Expression (Context) = Obj_Ref
        and then Nkind (Parent (Context)) /= N_Expression_With_Actions
      then
         Obj_Id := Defining_Entity (Context);

         --  The volatile object acts as the initialization expression of an
         --  extended return statement. This is valid context as long as the
         --  function is volatile.

         if Is_Return_Object (Obj_Id) then
            return Within_Volatile_Function (Scope (Obj_Id));

         --  Otherwise this is a normal object initialization

         else
            return True;
         end if;

      --  The volatile object acts as the name of a renaming declaration

      elsif Nkind (Context) = N_Object_Renaming_Declaration
        and then Name (Context) = Obj_Ref
      then
         return True;

      --  The volatile object appears as an actual parameter in a call to an
      --  instance of Unchecked_Conversion whose result is renamed.

      elsif Nkind (Context) = N_Function_Call
        and then Is_Entity_Name (Name (Context))
        and then Is_Unchecked_Conversion_Instance (Entity (Name (Context)))
        and then Nkind (Parent (Context)) = N_Object_Renaming_Declaration
      then
         return True;

      --  The volatile object is actually the prefix in a protected entry,
      --  function, or procedure call.

      elsif Is_Protected_Operation_Call (Context) then
         return True;

      --  The volatile object appears as the expression of a simple return
      --  statement that applies to a volatile function.

      elsif Nkind (Context) = N_Simple_Return_Statement
        and then Expression (Context) = Obj_Ref
      then
         return
           Within_Volatile_Function (Return_Statement_Entity (Context));

      --  The volatile object appears as the prefix of a name occurring in a
      --  non-interfering context.

      elsif Nkind (Context) in
              N_Attribute_Reference  |
              N_Explicit_Dereference |
              N_Indexed_Component    |
              N_Selected_Component   |
              N_Slice
        and then Prefix (Context) = Obj_Ref
        and then Is_OK_Volatile_Context
                   (Context       => Parent (Context),
                    Obj_Ref       => Context,
                    Check_Actuals => Check_Actuals)
      then
         return True;

      --  The volatile object appears as the prefix of attributes Address,
      --  Alignment, Component_Size, First, First_Bit, Last, Last_Bit, Length,
      --  Position, Size, Storage_Size.

      elsif Nkind (Context) = N_Attribute_Reference
        and then Prefix (Context) = Obj_Ref
        and then Attribute_Name (Context) in Name_Address
                                           | Name_Alignment
                                           | Name_Component_Size
                                           | Name_First
                                           | Name_First_Bit
                                           | Name_Last
                                           | Name_Last_Bit
                                           | Name_Length
                                           | Name_Position
                                           | Name_Size
                                           | Name_Storage_Size
      then
         return True;

      --  The volatile object appears as the expression of a type conversion
      --  occurring in a non-interfering context.

      elsif Nkind (Context) in N_Qualified_Expression
                             | N_Type_Conversion
                             | N_Unchecked_Type_Conversion
        and then Expression (Context) = Obj_Ref
        and then Is_OK_Volatile_Context
                   (Context       => Parent (Context),
                    Obj_Ref       => Context,
                    Check_Actuals => Check_Actuals)
      then
         return True;

      --  The volatile object appears as the expression in a delay statement

      elsif Nkind (Context) in N_Delay_Statement then
         return True;

      --  Allow references to volatile objects in various checks. This is not a
      --  direct SPARK 2014 requirement.

      elsif Within_Check (Context) then
         return True;

      --  References to effectively volatile objects that appear as actual
      --  parameters in subprogram calls can be examined only after call itself
      --  has been resolved. Before that, assume such references to be legal.

      elsif Nkind (Context) in N_Subprogram_Call | N_Entry_Call_Statement then
         if Check_Actuals then
            declare
               Call   : Node_Id;
               Formal : Entity_Id;
               Subp   : constant Entity_Id := Get_Called_Entity (Context);
            begin
               Find_Actual (Obj_Ref, Formal, Call);
               pragma Assert (Call = Context);

               --  An effectively volatile object may act as an actual when the
               --  corresponding formal is of a non-scalar effectively volatile
               --  type (SPARK RM 7.1.3(10)).

               if not Is_Scalar_Type (Etype (Formal))
                 and then Is_Effectively_Volatile_For_Reading (Etype (Formal))
               then
                  return True;

               --  An effectively volatile object may act as an actual in a
               --  call to an instance of Unchecked_Conversion. (SPARK RM
               --  7.1.3(10)).

               elsif Is_Unchecked_Conversion_Instance (Subp) then
                  return True;

               else
                  return False;
               end if;
            end;
         else
            return True;
         end if;
      else
         return False;
      end if;
   end Is_OK_Volatile_Context;

   ------------------------------------
   -- Is_Package_Contract_Annotation --
   ------------------------------------

   function Is_Package_Contract_Annotation (Item : Node_Id) return Boolean is
      Nam : Name_Id;

   begin
      if Nkind (Item) = N_Aspect_Specification then
         Nam := Chars (Identifier (Item));

      else pragma Assert (Nkind (Item) = N_Pragma);
         Nam := Pragma_Name (Item);
      end if;

      return    Nam = Name_Abstract_State
        or else Nam = Name_Initial_Condition
        or else Nam = Name_Initializes
        or else Nam = Name_Refined_State;
   end Is_Package_Contract_Annotation;

   -----------------------------------
   -- Is_Partially_Initialized_Type --
   -----------------------------------

   function Is_Partially_Initialized_Type
     (Typ              : Entity_Id;
      Include_Implicit : Boolean := True) return Boolean
   is
   begin
      if Is_Scalar_Type (Typ) then
         return Has_Default_Aspect (Base_Type (Typ));

      elsif Is_Access_Type (Typ) then
         return Include_Implicit;

      elsif Is_Array_Type (Typ) then

         --  If component type is partially initialized, so is array type

         if Has_Default_Aspect (Base_Type (Typ))
           or else Is_Partially_Initialized_Type
                     (Component_Type (Typ), Include_Implicit)
         then
            return True;

         --  Otherwise we are only partially initialized if we are fully
         --  initialized (this is the empty array case, no point in us
         --  duplicating that code here).

         else
            return Is_Fully_Initialized_Type (Typ);
         end if;

      elsif Is_Record_Type (Typ) then

         --  A discriminated type is always partially initialized if in
         --  all mode

         if Has_Discriminants (Typ) and then Include_Implicit then
            return True;

         --  A tagged type is always partially initialized

         elsif Is_Tagged_Type (Typ) then
            return True;

         --  Case of nondiscriminated record

         else
            declare
               Comp : Entity_Id;

               Component_Present : Boolean := False;
               --  Set True if at least one component is present. If no
               --  components are present, then record type is fully
               --  initialized (another odd case, like the null array).

            begin
               --  Loop through components

               Comp := First_Component (Typ);
               while Present (Comp) loop
                  Component_Present := True;

                  --  If a component has an initialization expression then the
                  --  enclosing record type is partially initialized

                  if Present (Parent (Comp))
                    and then Present (Expression (Parent (Comp)))
                  then
                     return True;

                  --  If a component is of a type which is itself partially
                  --  initialized, then the enclosing record type is also.

                  elsif Is_Partially_Initialized_Type
                          (Etype (Comp), Include_Implicit)
                  then
                     return True;
                  end if;

                  Next_Component (Comp);
               end loop;

               --  No initialized components found. If we found any components
               --  they were all uninitialized so the result is false.

               if Component_Present then
                  return False;

               --  But if we found no components, then all the components are
               --  initialized so we consider the type to be initialized.

               else
                  return True;
               end if;
            end;
         end if;

      --  Concurrent types are always fully initialized

      elsif Is_Concurrent_Type (Typ) then
         return True;

      --  For a private type, go to underlying type. If there is no underlying
      --  type then just assume this partially initialized. Not clear if this
      --  can happen in a non-error case, but no harm in testing for this.

      elsif Is_Private_Type (Typ) then
         declare
            U : constant Entity_Id := Underlying_Type (Typ);
         begin
            if No (U) then
               return True;
            else
               return Is_Partially_Initialized_Type (U, Include_Implicit);
            end if;
         end;

      --  For any other type (are there any?) assume partially initialized

      else
         return True;
      end if;
   end Is_Partially_Initialized_Type;

   ------------------------------------
   -- Is_Potentially_Persistent_Type --
   ------------------------------------

   function Is_Potentially_Persistent_Type (T : Entity_Id) return Boolean is
      Comp : Entity_Id;
      Indx : Node_Id;

   begin
      --  For private type, test corresponding full type

      if Is_Private_Type (T) then
         return Is_Potentially_Persistent_Type (Full_View (T));

      --  Scalar types are potentially persistent

      elsif Is_Scalar_Type (T) then
         return True;

      --  Record type is potentially persistent if not tagged and the types of
      --  all it components are potentially persistent, and no component has
      --  an initialization expression.

      elsif Is_Record_Type (T)
        and then not Is_Tagged_Type (T)
        and then not Is_Partially_Initialized_Type (T)
      then
         Comp := First_Component (T);
         while Present (Comp) loop
            if not Is_Potentially_Persistent_Type (Etype (Comp)) then
               return False;
            else
               Next_Entity (Comp);
            end if;
         end loop;

         return True;

      --  Array type is potentially persistent if its component type is
      --  potentially persistent and if all its constraints are static.

      elsif Is_Array_Type (T) then
         if not Is_Potentially_Persistent_Type (Component_Type (T)) then
            return False;
         end if;

         Indx := First_Index (T);
         while Present (Indx) loop
            if not Is_OK_Static_Subtype (Etype (Indx)) then
               return False;
            else
               Next_Index (Indx);
            end if;
         end loop;

         return True;

      --  All other types are not potentially persistent

      else
         return False;
      end if;
   end Is_Potentially_Persistent_Type;

   --------------------------------
   -- Is_Potentially_Unevaluated --
   --------------------------------

   function Is_Potentially_Unevaluated (N : Node_Id) return Boolean is
      function Has_Null_Others_Choice (Aggr : Node_Id) return Boolean;
      --  Aggr is an array aggregate with static bounds and an others clause;
      --  return True if the others choice of the given array aggregate does
      --  not cover any component (i.e. is null).

      function Immediate_Context_Implies_Is_Potentially_Unevaluated
        (Expr : Node_Id) return Boolean;
      --  Return True if the *immediate* context of this expression tells us
      --  that it is potentially unevaluated; return False if the *immediate*
      --  context doesn't provide an answer to this question and we need to
      --  keep looking.

      function Non_Static_Or_Null_Range (N : Node_Id) return Boolean;
      --  Return True if the given range is nonstatic or null

      ----------------------------
      -- Has_Null_Others_Choice --
      ----------------------------

      function Has_Null_Others_Choice (Aggr : Node_Id) return Boolean is
         Idx : constant Node_Id := First_Index (Etype (Aggr));
         Hiv : constant Uint := Expr_Value (Type_High_Bound (Etype (Idx)));
         Lov : constant Uint := Expr_Value (Type_Low_Bound (Etype (Idx)));

      begin
         declare
            Intervals : constant Interval_Lists.Discrete_Interval_List :=
              Interval_Lists.Aggregate_Intervals (Aggr);

         begin
            --  The others choice is null if, after normalization, we
            --  have a single interval covering the whole aggregate.

            return Intervals'Length = 1
              and then
                Intervals (Intervals'First).Low = Lov
              and then
                Intervals (Intervals'First).High = Hiv;
         end;

      --  If the aggregate is malformed (that is, indexes are not disjoint)
      --  then no action is needed at this stage; the error will be reported
      --  later by the frontend.

      exception
         when Interval_Lists.Intervals_Error =>
            return False;
      end Has_Null_Others_Choice;

      ----------------------------------------------------------
      -- Immediate_Context_Implies_Is_Potentially_Unevaluated --
      ----------------------------------------------------------

      function Immediate_Context_Implies_Is_Potentially_Unevaluated
        (Expr : Node_Id) return Boolean
      is
         Par : constant Node_Id := Parent (Expr);

         function Aggregate_Type return Node_Id is (Etype (Parent (Par)));
      begin
         if Nkind (Par) = N_If_Expression then
            return Is_Elsif (Par) or else Expr /= First (Expressions (Par));

         elsif Nkind (Par) = N_Case_Expression then
            return Expr /= Expression (Par);

         elsif Nkind (Par) in N_And_Then | N_Or_Else then
            return Expr = Right_Opnd (Par);

         elsif Nkind (Par) in N_In | N_Not_In then

            --  If the membership includes several alternatives, only the first
            --  is definitely evaluated.

            if Present (Alternatives (Par)) then
               return Expr /= First (Alternatives (Par));

            --  If this is a range membership both bounds are evaluated

            else
               return False;
            end if;

         elsif Nkind (Par) = N_Quantified_Expression then
            return Expr = Condition (Par);

         elsif Nkind (Par) in N_Component_Association
                            | N_Iterated_Component_Association
           and then Expr = Expression (Par)
           and then Nkind (Parent (Par))
              in N_Aggregate | N_Delta_Aggregate | N_Extension_Aggregate
           and then Present (Aggregate_Type)
           and then Aggregate_Type /= Any_Composite
         then
            if Is_Array_Type (Aggregate_Type) then
               if Ada_Version >= Ada_2022 then
                  --  For Ada 2022, this predicate returns True for
                  --  any "repeatedly evaluated" expression.
                  return True;
               end if;

               declare
                  Choice           : Node_Id;
                  In_Others_Choice : Boolean := False;
                  Array_Agg        : constant Node_Id := Parent (Par);
               begin
                  --  The expression of an array_component_association is
                  --  potentially unevaluated if the associated choice is a
                  --  subtype_indication or range that defines a nonstatic or
                  --  null range.

                  Choice := First (Choices (Par));
                  while Present (Choice) loop
                     if Nkind (Choice) = N_Range
                       and then Non_Static_Or_Null_Range (Choice)
                     then
                        return True;

                     elsif Nkind (Choice) = N_Identifier
                       and then Present (Scalar_Range (Etype (Choice)))
                       and then
                         Non_Static_Or_Null_Range
                           (Scalar_Range (Etype (Choice)))
                     then
                        return True;

                     elsif Nkind (Choice) = N_Others_Choice then
                        In_Others_Choice := True;
                     end if;

                     Next (Choice);
                  end loop;

                  --  It is also potentially unevaluated if the associated
                  --  choice is an others choice and the applicable index
                  --  constraint is nonstatic or null.

                  if In_Others_Choice then
                     if not Compile_Time_Known_Bounds (Aggregate_Type) then
                        return True;
                     else
                        return Has_Null_Others_Choice (Array_Agg);
                     end if;
                  end if;
               end;

            elsif Is_Container_Aggregate (Parent (Par)) then
               --  a component of a container aggregate
               return True;
            end if;

            return False;

         else
            return False;
         end if;
      end Immediate_Context_Implies_Is_Potentially_Unevaluated;

      ------------------------------
      -- Non_Static_Or_Null_Range --
      ------------------------------

      function Non_Static_Or_Null_Range (N : Node_Id) return Boolean is
         Low, High : Node_Id;

      begin
         Get_Index_Bounds (N, Low, High);

         --  Check static bounds

         if not Compile_Time_Known_Value (Low)
           or else not Compile_Time_Known_Value (High)
         then
            return True;

         --  Check null range

         elsif Expr_Value (High) < Expr_Value (Low) then
            return True;
         end if;

         return False;
      end Non_Static_Or_Null_Range;

      --  Local variables

      Par  : Node_Id;
      Expr : Node_Id;

   --  Start of processing for Is_Potentially_Unevaluated

   begin
      Expr := N;
      Par  := N;

      --  A postcondition whose expression is a short-circuit is broken down
      --  into individual aspects for better exception reporting. The original
      --  short-circuit expression is rewritten as the second operand, and an
      --  occurrence of 'Old in that operand is potentially unevaluated.
      --  See sem_ch13.adb for details of this transformation. The reference
      --  to 'Old may appear within an expression, so we must look for the
      --  enclosing pragma argument in the tree that contains the reference.

      while Present (Par)
        and then Nkind (Par) /= N_Pragma_Argument_Association
      loop
         if Is_Rewrite_Substitution (Par)
           and then Nkind (Original_Node (Par)) = N_And_Then
         then
            return True;
         end if;

         Par := Parent (Par);
      end loop;

      --  Other cases; 'Old appears within other expression (not the top-level
      --  conjunct in a postcondition) with a potentially unevaluated operand.

      Par := Parent (Expr);

      while Present (Par)
        and then Nkind (Par) /= N_Pragma_Argument_Association
      loop
         if Comes_From_Source (Par)
           and then
             Immediate_Context_Implies_Is_Potentially_Unevaluated (Expr)
         then
            return True;

         --  For component associations continue climbing; it may be part of an
         --  array aggregate. For iterated component association we know that
         --  it belongs to an array aggreate, but only its expression is
         --  potentially unevaluated, not discrete choice list or iterator
         --  specification.

         elsif Nkind (Par) in N_Component_Association
                            | N_Iterated_Component_Association
         then
            null;

         --  If the context is not an expression, or if is the result of
         --  expansion of an enclosing construct (such as another attribute)
         --  the predicate does not apply.

         elsif Nkind (Par) = N_Case_Expression_Alternative then
            null;

         elsif Nkind (Par) not in N_Subexpr
           or else not Comes_From_Source (Par)
         then
            return False;
         end if;

         Expr := Par;
         Par  := Parent (Par);
      end loop;

      return False;
   end Is_Potentially_Unevaluated;

   -----------------------------------------
   -- Is_Predefined_Dispatching_Operation --
   -----------------------------------------

   function Is_Predefined_Dispatching_Operation
     (E : Entity_Id) return Boolean
   is
      TSS_Name : TSS_Name_Type;

   begin
      if not Is_Dispatching_Operation (E) then
         return False;
      end if;

      Get_Name_String (Chars (E));

      --  Most predefined primitives have internally generated names. Equality
      --  must be treated differently; the predefined operation is recognized
      --  as a homogeneous binary operator that returns Boolean.

      if Name_Len > TSS_Name_Type'Last then
         TSS_Name :=
           TSS_Name_Type
             (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));

         if Chars (E) in Name_uAssign | Name_uSize
           or else
             (Chars (E) = Name_Op_Eq
               and then Etype (First_Formal (E)) = Etype (Last_Formal (E)))
           or else TSS_Name = TSS_Deep_Adjust
           or else TSS_Name = TSS_Deep_Finalize
           or else TSS_Name = TSS_Stream_Input
           or else TSS_Name = TSS_Stream_Output
           or else TSS_Name = TSS_Stream_Read
           or else TSS_Name = TSS_Stream_Write
           or else TSS_Name = TSS_Put_Image
           or else Is_Predefined_Interface_Primitive (E)
         then
            return True;
         end if;
      end if;

      return False;
   end Is_Predefined_Dispatching_Operation;

   ---------------------------------------
   -- Is_Predefined_Interface_Primitive --
   ---------------------------------------

   function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
   begin
      --  In VM targets we don't restrict the functionality of this test to
      --  compiling in Ada 2005 mode since in VM targets any tagged type has
      --  these primitives.

      return (Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion)
        and then Chars (E) in Name_uDisp_Asynchronous_Select
                            | Name_uDisp_Conditional_Select
                            | Name_uDisp_Get_Prim_Op_Kind
                            | Name_uDisp_Get_Task_Id
                            | Name_uDisp_Requeue
                            | Name_uDisp_Timed_Select;
   end Is_Predefined_Interface_Primitive;

   ---------------------------------------
   -- Is_Predefined_Internal_Operation  --
   ---------------------------------------

   function Is_Predefined_Internal_Operation
     (E : Entity_Id) return Boolean
   is
      TSS_Name : TSS_Name_Type;

   begin
      if not Is_Dispatching_Operation (E) then
         return False;
      end if;

      Get_Name_String (Chars (E));

      --  Most predefined primitives have internally generated names. Equality
      --  must be treated differently; the predefined operation is recognized
      --  as a homogeneous binary operator that returns Boolean.

      if Name_Len > TSS_Name_Type'Last then
         TSS_Name :=
           TSS_Name_Type
             (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));

         if Chars (E) in Name_uSize | Name_uAssign
           or else
             (Chars (E) = Name_Op_Eq
               and then Etype (First_Formal (E)) = Etype (Last_Formal (E)))
           or else TSS_Name = TSS_Deep_Adjust
           or else TSS_Name = TSS_Deep_Finalize
           or else Is_Predefined_Interface_Primitive (E)
         then
            return True;
         end if;
      end if;

      return False;
   end Is_Predefined_Internal_Operation;

   --------------------------------
   -- Is_Preelaborable_Aggregate --
   --------------------------------

   function Is_Preelaborable_Aggregate (Aggr : Node_Id) return Boolean is
      Aggr_Typ   : constant Entity_Id := Etype (Aggr);
      Array_Aggr : constant Boolean   := Is_Array_Type (Aggr_Typ);

      Anc_Part : Node_Id;
      Assoc    : Node_Id;
      Choice   : Node_Id;
      Comp_Typ : Entity_Id := Empty; -- init to avoid warning
      Expr     : Node_Id;

   begin
      if Array_Aggr then
         Comp_Typ := Component_Type (Aggr_Typ);
      end if;

      --  Inspect the ancestor part

      if Nkind (Aggr) = N_Extension_Aggregate then
         Anc_Part := Ancestor_Part (Aggr);

         --  The ancestor denotes a subtype mark

         if Is_Entity_Name (Anc_Part)
           and then Is_Type (Entity (Anc_Part))
         then
            if not Has_Preelaborable_Initialization (Entity (Anc_Part)) then
               return False;
            end if;

         --  Otherwise the ancestor denotes an expression

         elsif not Is_Preelaborable_Construct (Anc_Part) then
            return False;
         end if;
      end if;

      --  Inspect the positional associations

      Expr := First (Expressions (Aggr));
      while Present (Expr) loop
         if not Is_Preelaborable_Construct (Expr) then
            return False;
         end if;

         Next (Expr);
      end loop;

      --  Inspect the named associations

      Assoc := First (Component_Associations (Aggr));
      while Present (Assoc) loop

         --  Inspect the choices of the current named association

         Choice := First (Choices (Assoc));
         while Present (Choice) loop
            if Array_Aggr then

               --  For a choice to be preelaborable, it must denote either a
               --  static range or a static expression.

               if Nkind (Choice) = N_Others_Choice then
                  null;

               elsif Nkind (Choice) = N_Range then
                  if not Is_OK_Static_Range (Choice) then
                     return False;
                  end if;

               elsif not Is_OK_Static_Expression (Choice) then
                  return False;
               end if;

            else
               Comp_Typ := Etype (Choice);
            end if;

            Next (Choice);
         end loop;

         --  The type of the choice must have preelaborable initialization if
         --  the association carries a <>.

         pragma Assert (Present (Comp_Typ));
         if Box_Present (Assoc) then
            if not Has_Preelaborable_Initialization (Comp_Typ) then
               return False;
            end if;

         --  The type of the expression must have preelaborable initialization

         elsif not Is_Preelaborable_Construct (Expression (Assoc)) then
            return False;
         end if;

         Next (Assoc);
      end loop;

      --  At this point the aggregate is preelaborable

      return True;
   end Is_Preelaborable_Aggregate;

   --------------------------------
   -- Is_Preelaborable_Construct --
   --------------------------------

   function Is_Preelaborable_Construct (N : Node_Id) return Boolean is
   begin
      --  Aggregates

      if Nkind (N) in N_Aggregate | N_Extension_Aggregate then
         return Is_Preelaborable_Aggregate (N);

      --  Attributes are allowed in general, even if their prefix is a formal
      --  type. It seems that certain attributes known not to be static might
      --  not be allowed, but there are no rules to prevent them.

      elsif Nkind (N) = N_Attribute_Reference then
         return True;

      --  Expressions

      elsif Nkind (N) in N_Subexpr and then Is_OK_Static_Expression (N) then
         return True;

      elsif Nkind (N) = N_Qualified_Expression then
         return Is_Preelaborable_Construct (Expression (N));

      --  Names are preelaborable when they denote a discriminant of an
      --  enclosing type. Discriminals are also considered for this check.

      elsif Is_Entity_Name (N)
        and then Present (Entity (N))
        and then
          (Ekind (Entity (N)) = E_Discriminant
            or else (Ekind (Entity (N)) in E_Constant | E_In_Parameter
                      and then Present (Discriminal_Link (Entity (N)))))
      then
         return True;

      --  Statements

      elsif Nkind (N) = N_Null then
         return True;

      --  Ada 2022 (AI12-0175): Calls to certain functions that are essentially
      --  unchecked conversions are preelaborable.

      elsif Ada_Version >= Ada_2022
        and then Nkind (N) = N_Function_Call
        and then Is_Entity_Name (Name (N))
        and then Is_Preelaborable_Function (Entity (Name (N)))
      then
         declare
            A : Node_Id;
         begin
            A := First_Actual (N);

            while Present (A) loop
               if not Is_Preelaborable_Construct (A) then
                  return False;
               end if;

               Next_Actual (A);
            end loop;
         end;

         return True;

      --  Otherwise the construct is not preelaborable

      else
         return False;
      end if;
   end Is_Preelaborable_Construct;

   -------------------------------
   -- Is_Preelaborable_Function --
   -------------------------------

   function Is_Preelaborable_Function (Id : Entity_Id) return Boolean is
      SATAC : constant Rtsfind.RTU_Id := System_Address_To_Access_Conversions;
      Scop  : constant Entity_Id := Scope (Id);

   begin
      --  Small optimization: every allowed function has convention Intrinsic
      --  (see Analyze_Subprogram_Instantiation for the subtlety in the test).

      if not Is_Intrinsic_Subprogram (Id)
        and then Convention (Id) /= Convention_Intrinsic
      then
         return False;
      end if;

      --  An instance of Unchecked_Conversion

      if Is_Unchecked_Conversion_Instance (Id) then
         return True;
      end if;

      --  A function declared in System.Storage_Elements

      if Is_RTU (Scop, System_Storage_Elements) then
         return True;
      end if;

      --  The functions To_Pointer and To_Address declared in an instance of
      --  System.Address_To_Access_Conversions (they are the only ones).

      if Ekind (Scop) = E_Package
        and then Nkind (Parent (Scop)) = N_Package_Specification
        and then Present (Generic_Parent (Parent (Scop)))
        and then Is_RTU (Generic_Parent (Parent (Scop)), SATAC)
      then
         return True;
      end if;

      return False;
   end Is_Preelaborable_Function;

   -----------------------------
   -- Is_Private_Library_Unit --
   -----------------------------

   function Is_Private_Library_Unit (Unit : Entity_Id) return Boolean is
      Comp_Unit : constant Node_Id := Parent (Unit_Declaration_Node (Unit));
   begin
      return Nkind (Comp_Unit) = N_Compilation_Unit
        and then Private_Present (Comp_Unit);
   end Is_Private_Library_Unit;

   ---------------------------------
   -- Is_Protected_Self_Reference --
   ---------------------------------

   function Is_Protected_Self_Reference (N : Node_Id) return Boolean is

      function In_Access_Definition (N : Node_Id) return Boolean;
      --  Returns true if N belongs to an access definition

      --------------------------
      -- In_Access_Definition --
      --------------------------

      function In_Access_Definition (N : Node_Id) return Boolean is
         P : Node_Id;

      begin
         P := Parent (N);
         while Present (P) loop
            if Nkind (P) = N_Access_Definition then
               return True;
            end if;

            P := Parent (P);
         end loop;

         return False;
      end In_Access_Definition;

   --  Start of processing for Is_Protected_Self_Reference

   begin
      --  Verify that prefix is analyzed and has the proper form. Note that
      --  the attributes Elab_Spec, Elab_Body, and Elab_Subp_Body, which also
      --  produce the address of an entity, do not analyze their prefix
      --  because they denote entities that are not necessarily visible.
      --  Neither of them can apply to a protected type.

      return Ada_Version >= Ada_2005
        and then Is_Entity_Name (N)
        and then Present (Entity (N))
        and then Is_Protected_Type (Entity (N))
        and then In_Open_Scopes (Entity (N))
        and then not In_Access_Definition (N);
   end Is_Protected_Self_Reference;

   -----------------------------
   -- Is_RCI_Pkg_Spec_Or_Body --
   -----------------------------

   function Is_RCI_Pkg_Spec_Or_Body (Cunit : Node_Id) return Boolean is

      function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean;
      --  Return True if the unit of Cunit is an RCI package declaration

      ---------------------------
      -- Is_RCI_Pkg_Decl_Cunit --
      ---------------------------

      function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean is
         The_Unit : constant Node_Id := Unit (Cunit);

      begin
         if Nkind (The_Unit) /= N_Package_Declaration then
            return False;
         end if;

         return Is_Remote_Call_Interface (Defining_Entity (The_Unit));
      end Is_RCI_Pkg_Decl_Cunit;

   --  Start of processing for Is_RCI_Pkg_Spec_Or_Body

   begin
      return Is_RCI_Pkg_Decl_Cunit (Cunit)
        or else
         (Nkind (Unit (Cunit)) = N_Package_Body
           and then Is_RCI_Pkg_Decl_Cunit (Library_Unit (Cunit)));
   end Is_RCI_Pkg_Spec_Or_Body;

   -----------------------------------------
   -- Is_Remote_Access_To_Class_Wide_Type --
   -----------------------------------------

   function Is_Remote_Access_To_Class_Wide_Type
     (E : Entity_Id) return Boolean
   is
   begin
      --  A remote access to class-wide type is a general access to object type
      --  declared in the visible part of a Remote_Types or Remote_Call_
      --  Interface unit.

      return Ekind (E) = E_General_Access_Type
        and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E));
   end Is_Remote_Access_To_Class_Wide_Type;

   -----------------------------------------
   -- Is_Remote_Access_To_Subprogram_Type --
   -----------------------------------------

   function Is_Remote_Access_To_Subprogram_Type
     (E : Entity_Id) return Boolean
   is
   begin
      return (Ekind (E) = E_Access_Subprogram_Type
                or else (Ekind (E) = E_Record_Type
                          and then Present (Corresponding_Remote_Type (E))))
        and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E));
   end Is_Remote_Access_To_Subprogram_Type;

   --------------------
   -- Is_Remote_Call --
   --------------------

   function Is_Remote_Call (N : Node_Id) return Boolean is
   begin
      if Nkind (N) not in N_Subprogram_Call then

         --  An entry call cannot be remote

         return False;

      elsif Nkind (Name (N)) in N_Has_Entity
        and then Is_Remote_Call_Interface (Entity (Name (N)))
      then
         --  A subprogram declared in the spec of a RCI package is remote

         return True;

      elsif Nkind (Name (N)) = N_Explicit_Dereference
        and then Is_Remote_Access_To_Subprogram_Type
                   (Etype (Prefix (Name (N))))
      then
         --  The dereference of a RAS is a remote call

         return True;

      elsif Present (Controlling_Argument (N))
        and then Is_Remote_Access_To_Class_Wide_Type
                   (Etype (Controlling_Argument (N)))
      then
         --  Any primitive operation call with a controlling argument of
         --  a RACW type is a remote call.

         return True;
      end if;

      --  All other calls are local calls

      return False;
   end Is_Remote_Call;

   ----------------------
   -- Is_Renamed_Entry --
   ----------------------

   function Is_Renamed_Entry (Proc_Nam : Entity_Id) return Boolean is
      Orig_Node : Node_Id := Empty;
      Subp_Decl : Node_Id :=
        (if No (Parent (Proc_Nam)) then Empty else Parent (Parent (Proc_Nam)));

      function Is_Entry (Nam : Node_Id) return Boolean;
      --  Determine whether Nam is an entry. Traverse selectors if there are
      --  nested selected components.

      --------------
      -- Is_Entry --
      --------------

      function Is_Entry (Nam : Node_Id) return Boolean is
      begin
         if Nkind (Nam) = N_Selected_Component then
            return Is_Entry (Selector_Name (Nam));
         end if;

         return Ekind (Entity (Nam)) = E_Entry;
      end Is_Entry;

   --  Start of processing for Is_Renamed_Entry

   begin
      if Present (Alias (Proc_Nam)) then
         Subp_Decl := Parent (Parent (Alias (Proc_Nam)));
      end if;

      --  Look for a rewritten subprogram renaming declaration

      if Nkind (Subp_Decl) = N_Subprogram_Declaration
        and then Present (Original_Node (Subp_Decl))
      then
         Orig_Node := Original_Node (Subp_Decl);
      end if;

      --  The rewritten subprogram is actually an entry

      if Present (Orig_Node)
        and then Nkind (Orig_Node) = N_Subprogram_Renaming_Declaration
        and then Is_Entry (Name (Orig_Node))
      then
         return True;
      end if;

      return False;
   end Is_Renamed_Entry;

   ----------------------------
   -- Is_Reversible_Iterator --
   ----------------------------

   function Is_Reversible_Iterator (Typ : Entity_Id) return Boolean is
      Ifaces_List : Elist_Id;
      Iface_Elmt  : Elmt_Id;
      Iface       : Entity_Id;

   begin
      if Is_Class_Wide_Type (Typ)
        and then Chars (Root_Type (Typ)) = Name_Reversible_Iterator
        and then In_Predefined_Unit (Root_Type (Typ))
      then
         return True;

      elsif not Is_Tagged_Type (Typ) or else not Is_Derived_Type (Typ) then
         return False;

      else
         Collect_Interfaces (Typ, Ifaces_List);

         Iface_Elmt := First_Elmt (Ifaces_List);
         while Present (Iface_Elmt) loop
            Iface := Node (Iface_Elmt);
            if Chars (Iface) = Name_Reversible_Iterator
              and then In_Predefined_Unit (Iface)
            then
               return True;
            end if;

            Next_Elmt (Iface_Elmt);
         end loop;
      end if;

      return False;
   end Is_Reversible_Iterator;

   ---------------------------------
   -- Is_Single_Concurrent_Object --
   ---------------------------------

   function Is_Single_Concurrent_Object (Id : Entity_Id) return Boolean is
   begin
      return
        Is_Single_Protected_Object (Id) or else Is_Single_Task_Object (Id);
   end Is_Single_Concurrent_Object;

   -------------------------------
   -- Is_Single_Concurrent_Type --
   -------------------------------

   function Is_Single_Concurrent_Type (Id : Entity_Id) return Boolean is
   begin
      return
        Ekind (Id) in E_Protected_Type | E_Task_Type
          and then Is_Single_Concurrent_Type_Declaration
                     (Declaration_Node (Id));
   end Is_Single_Concurrent_Type;

   -------------------------------------------
   -- Is_Single_Concurrent_Type_Declaration --
   -------------------------------------------

   function Is_Single_Concurrent_Type_Declaration
     (N : Node_Id) return Boolean
   is
   begin
      return Nkind (Original_Node (N)) in
               N_Single_Protected_Declaration | N_Single_Task_Declaration;
   end Is_Single_Concurrent_Type_Declaration;

   ---------------------------------------------
   -- Is_Single_Precision_Floating_Point_Type --
   ---------------------------------------------

   function Is_Single_Precision_Floating_Point_Type
     (E : Entity_Id) return Boolean is
   begin
      return Is_Floating_Point_Type (E)
        and then Machine_Radix_Value (E) = Uint_2
        and then Machine_Mantissa_Value (E) = Uint_24
        and then Machine_Emax_Value (E) = Uint_2 ** Uint_7
        and then Machine_Emin_Value (E) = Uint_3 - (Uint_2 ** Uint_7);
   end Is_Single_Precision_Floating_Point_Type;

   --------------------------------
   -- Is_Single_Protected_Object --
   --------------------------------

   function Is_Single_Protected_Object (Id : Entity_Id) return Boolean is
   begin
      return
        Ekind (Id) = E_Variable
          and then Ekind (Etype (Id)) = E_Protected_Type
          and then Is_Single_Concurrent_Type (Etype (Id));
   end Is_Single_Protected_Object;

   ---------------------------
   -- Is_Single_Task_Object --
   ---------------------------

   function Is_Single_Task_Object (Id : Entity_Id) return Boolean is
   begin
      return
        Ekind (Id) = E_Variable
          and then Ekind (Etype (Id)) = E_Task_Type
          and then Is_Single_Concurrent_Type (Etype (Id));
   end Is_Single_Task_Object;

   -----------------------------
   -- Is_Specific_Tagged_Type --
   -----------------------------

   function Is_Specific_Tagged_Type (Typ : Entity_Id) return Boolean is
      Full_Typ : Entity_Id;

   begin
      --  Handle private types

      if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
         Full_Typ := Full_View (Typ);
      else
         Full_Typ := Typ;
      end if;

      --  A specific tagged type is a non-class-wide tagged type

      return Is_Tagged_Type (Full_Typ) and not Is_Class_Wide_Type (Full_Typ);
   end Is_Specific_Tagged_Type;

   ------------------
   -- Is_Statement --
   ------------------

   function Is_Statement (N : Node_Id) return Boolean is
   begin
      return
        Nkind (N) in N_Statement_Other_Than_Procedure_Call
          or else Nkind (N) = N_Procedure_Call_Statement;
   end Is_Statement;

   --------------------------------------
   -- Is_Static_Discriminant_Component --
   --------------------------------------

   function Is_Static_Discriminant_Component (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Selected_Component
        and then not Is_In_Discriminant_Check (N)
        and then Present (Etype (Prefix (N)))
        and then Ekind (Etype (Prefix (N))) = E_Record_Subtype
        and then Has_Static_Discriminants (Etype (Prefix (N)))
        and then Present (Entity (Selector_Name (N)))
        and then Ekind (Entity (Selector_Name (N))) = E_Discriminant
        and then not In_Check_Node (N);
   end Is_Static_Discriminant_Component;

   ------------------------
   -- Is_Static_Function --
   ------------------------

   function Is_Static_Function (Subp : Entity_Id) return Boolean is
   begin
      --  Always return False for pre Ada 2022 to e.g. ignore the Static
      --  aspect in package Interfaces for Ada_Version < 2022 and also
      --  for efficiency.

      return Ada_Version >= Ada_2022
        and then Has_Aspect (Subp, Aspect_Static)
        and then
          (No (Find_Value_Of_Aspect (Subp, Aspect_Static))
            or else Is_True (Static_Boolean
                               (Find_Value_Of_Aspect (Subp, Aspect_Static))));
   end Is_Static_Function;

   -----------------------------
   -- Is_Static_Function_Call --
   -----------------------------

   function Is_Static_Function_Call (Call : Node_Id) return Boolean is
      function Has_All_Static_Actuals (Call : Node_Id) return Boolean;
      --  Return whether all actual parameters of Call are static expressions

      ----------------------------
      -- Has_All_Static_Actuals --
      ----------------------------

      function Has_All_Static_Actuals (Call : Node_Id) return Boolean is
         Actual        : Node_Id := First_Actual (Call);
         String_Result : constant Boolean :=
                           Is_String_Type (Etype (Entity (Name (Call))));

      begin
         while Present (Actual) loop
            if not Is_Static_Expression (Actual) then

               --  ??? In the string-returning case we want to avoid a call
               --  being made to Establish_Transient_Scope in Resolve_Call,
               --  but at the point where that's tested for (which now includes
               --  a call to test Is_Static_Function_Call), the actuals of the
               --  call haven't been resolved, so expressions of the actuals
               --  may not have been marked Is_Static_Expression yet, so we
               --  force them to be resolved here, so we can tell if they're
               --  static. Calling Resolve here is admittedly a kludge, and we
               --  limit this call to string-returning cases.

               if String_Result then
                  Resolve (Actual);
               end if;

               --  Test flag again in case it's now True due to above Resolve

               if not Is_Static_Expression (Actual) then
                  return False;
               end if;
            end if;

            Next_Actual (Actual);
         end loop;

         return True;
      end Has_All_Static_Actuals;

   begin
      return Nkind (Call) = N_Function_Call
        and then Is_Entity_Name (Name (Call))
        and then Is_Static_Function (Entity (Name (Call)))
        and then Has_All_Static_Actuals (Call);
   end Is_Static_Function_Call;

   -------------------------------------------
   -- Is_Subcomponent_Of_Full_Access_Object --
   -------------------------------------------

   function Is_Subcomponent_Of_Full_Access_Object (N : Node_Id) return Boolean
   is
      R : Node_Id;

   begin
      R := Get_Referenced_Object (N);

      while Nkind (R) in N_Indexed_Component | N_Selected_Component | N_Slice
      loop
         R := Get_Referenced_Object (Prefix (R));

         --  If the prefix is an access value, only the designated type matters

         if Is_Access_Type (Etype (R)) then
            if Is_Full_Access (Designated_Type (Etype (R))) then
               return True;
            end if;

         else
            if Is_Full_Access_Object (R) then
               return True;
            end if;
         end if;
      end loop;

      return False;
   end Is_Subcomponent_Of_Full_Access_Object;

   ---------------------------------------
   -- Is_Subprogram_Contract_Annotation --
   ---------------------------------------

   function Is_Subprogram_Contract_Annotation
     (Item : Node_Id) return Boolean
   is
      Nam : Name_Id;

   begin
      if Nkind (Item) = N_Aspect_Specification then
         Nam := Chars (Identifier (Item));

      else pragma Assert (Nkind (Item) = N_Pragma);
         Nam := Pragma_Name (Item);
      end if;

      return    Nam = Name_Always_Terminates
        or else Nam = Name_Contract_Cases
        or else Nam = Name_Depends
        or else Nam = Name_Exceptional_Cases
        or else Nam = Name_Extensions_Visible
        or else Nam = Name_Global
        or else Nam = Name_Post
        or else Nam = Name_Post_Class
        or else Nam = Name_Postcondition
        or else Nam = Name_Pre
        or else Nam = Name_Pre_Class
        or else Nam = Name_Precondition
        or else Nam = Name_Refined_Depends
        or else Nam = Name_Refined_Global
        or else Nam = Name_Refined_Post
        or else Nam = Name_Subprogram_Variant
        or else Nam = Name_Test_Case;
   end Is_Subprogram_Contract_Annotation;

   --------------------------------------------------
   -- Is_Subprogram_Stub_Without_Prior_Declaration --
   --------------------------------------------------

   function Is_Subprogram_Stub_Without_Prior_Declaration
     (N : Node_Id) return Boolean
   is
   begin
      pragma Assert (Nkind (N) = N_Subprogram_Body_Stub);

      case Ekind (Defining_Entity (N)) is

         --  A subprogram stub without prior declaration serves as declaration
         --  for the actual subprogram body. As such, it has an attached
         --  defining entity of E_Function or E_Procedure.

         when E_Function
            | E_Procedure
         =>
            return True;

         --  Otherwise, it is completes a [generic] subprogram declaration

         when E_Generic_Function
            | E_Generic_Procedure
            | E_Subprogram_Body
         =>
            return False;

         when others =>
            raise Program_Error;
      end case;
   end Is_Subprogram_Stub_Without_Prior_Declaration;

   ---------------------------
   -- Is_Suitable_Primitive --
   ---------------------------

   function Is_Suitable_Primitive (Subp_Id : Entity_Id) return Boolean is
   begin
      --  The Default_Initial_Condition and invariant procedures must not be
      --  treated as primitive operations even when they apply to a tagged
      --  type. These routines must not act as targets of dispatching calls
      --  because they already utilize class-wide-precondition semantics to
      --  handle inheritance and overriding.

      if Ekind (Subp_Id) = E_Procedure
        and then (Is_DIC_Procedure (Subp_Id)
                    or else
                  Is_Invariant_Procedure (Subp_Id))
      then
         return False;
      end if;

      return True;
   end Is_Suitable_Primitive;

   ----------------------------
   -- Is_Synchronized_Object --
   ----------------------------

   function Is_Synchronized_Object (Id : Entity_Id) return Boolean is
      Prag : Node_Id;

   begin
      if Is_Object (Id) then

         --  The object is synchronized if it is of a type that yields a
         --  synchronized object.

         if Yields_Synchronized_Object (Etype (Id)) then
            return True;

         --  The object is synchronized if it is atomic and Async_Writers is
         --  enabled.

         elsif Is_Atomic_Object_Entity (Id)
           and then Async_Writers_Enabled (Id)
         then
            return True;

         --  A constant is a synchronized object by default, unless its type is
         --  access-to-variable type.

         elsif Ekind (Id) = E_Constant
           and then not Is_Access_Variable (Etype (Id))
         then
            return True;

         --  A variable is a synchronized object if it is subject to pragma
         --  Constant_After_Elaboration.

         elsif Ekind (Id) = E_Variable then
            Prag := Get_Pragma (Id, Pragma_Constant_After_Elaboration);

            return Present (Prag) and then Is_Enabled_Pragma (Prag);
         end if;
      end if;

      --  Otherwise the input is not an object or it does not qualify as a
      --  synchronized object.

      return False;
   end Is_Synchronized_Object;

   ---------------------------------
   -- Is_Synchronized_Tagged_Type --
   ---------------------------------

   function Is_Synchronized_Tagged_Type (E : Entity_Id) return Boolean is
      Kind : constant Entity_Kind := Ekind (Base_Type (E));

   begin
      --  A task or protected type derived from an interface is a tagged type.
      --  Such a tagged type is called a synchronized tagged type, as are
      --  synchronized interfaces and private extensions whose declaration
      --  includes the reserved word synchronized.

      return (Is_Tagged_Type (E)
                and then (Kind = E_Task_Type
                            or else
                          Kind = E_Protected_Type))
            or else
             (Is_Interface (E)
                and then Is_Synchronized_Interface (E))
            or else
             (Ekind (E) = E_Record_Type_With_Private
                and then Nkind (Parent (E)) = N_Private_Extension_Declaration
                and then (Synchronized_Present (Parent (E))
                           or else Is_Synchronized_Interface (Etype (E))));
   end Is_Synchronized_Tagged_Type;

   -----------------
   -- Is_Transfer --
   -----------------

   function Is_Transfer (N : Node_Id) return Boolean is
      Kind : constant Node_Kind := Nkind (N);

   begin
      if Kind in N_Simple_Return_Statement
               | N_Extended_Return_Statement
               | N_Goto_Statement
               | N_Raise_Statement
               | N_Requeue_Statement
      then
         return True;

      elsif Kind in N_Exit_Statement | N_Raise_xxx_Error
        and then No (Condition (N))
      then
         return True;

      elsif Kind = N_Procedure_Call_Statement
        and then Is_Entity_Name (Name (N))
        and then Present (Entity (Name (N)))
        and then No_Return (Entity (Name (N)))
      then
         return True;

      elsif Nkind (Original_Node (N)) = N_Raise_Statement then
         return True;

      else
         return False;
      end if;
   end Is_Transfer;

   -------------
   -- Is_True --
   -------------

   function Is_True (U : Opt_Ubool) return Boolean is
   begin
      return No (U) or else U = Uint_1;
   end Is_True;

   ------------------------
   -- Is_Trivial_Boolean --
   ------------------------

   function Is_Trivial_Boolean (N : Node_Id) return Boolean is
   begin
      return Comes_From_Source (N)
        and then Nkind (N) in N_Identifier | N_Expanded_Name
        and then Entity (N) in Standard_True | Standard_False;
   end Is_Trivial_Boolean;

   --------------------------------------
   -- Is_Unchecked_Conversion_Instance --
   --------------------------------------

   function Is_Unchecked_Conversion_Instance (Id : Entity_Id) return Boolean is
      Par : Node_Id;

   begin
      --  Look for a function whose generic parent is the predefined intrinsic
      --  function Unchecked_Conversion, or for one that renames such an
      --  instance.

      if Ekind (Id) = E_Function then
         Par := Parent (Id);

         if Nkind (Par) = N_Function_Specification then
            Par := Generic_Parent (Par);

            if Present (Par) then
               return
                 Chars (Par) = Name_Unchecked_Conversion
                   and then Is_Intrinsic_Subprogram (Par)
                   and then In_Predefined_Unit (Par);
            else
               return
                 Present (Alias (Id))
                   and then Is_Unchecked_Conversion_Instance (Alias (Id));
            end if;
         end if;
      end if;

      return False;
   end Is_Unchecked_Conversion_Instance;

   -------------------------------
   -- Is_Universal_Numeric_Type --
   -------------------------------

   function Is_Universal_Numeric_Type (T : Entity_Id) return Boolean is
   begin
      return T = Universal_Integer or else T = Universal_Real;
   end Is_Universal_Numeric_Type;

   ------------------------------
   -- Is_User_Defined_Equality --
   ------------------------------

   function Is_User_Defined_Equality (Id : Entity_Id) return Boolean is
      F1, F2 : Entity_Id;

   begin
      --  An equality operator is a function that carries the name "=", returns
      --  Boolean, and has exactly two formal parameters of an identical type.

      if Ekind (Id) = E_Function
        and then Chars (Id) = Name_Op_Eq
        and then Base_Type (Etype (Id)) = Standard_Boolean
      then
         F1 := First_Formal (Id);

         if No (F1) then
            return False;
         end if;

         F2 := Next_Formal (F1);

         return Present (F2)
           and then No (Next_Formal (F2))
           and then Base_Type (Etype (F1)) = Base_Type (Etype (F2));

      else
         return False;
      end if;
   end Is_User_Defined_Equality;

   -----------------------------
   -- Is_User_Defined_Literal --
   -----------------------------

   function Is_User_Defined_Literal
     (N   : Node_Id;
      Typ : Entity_Id) return Boolean
   is
      Literal_Aspect_Map :
        constant array (N_Numeric_Or_String_Literal) of Aspect_Id :=
          (N_Integer_Literal             => Aspect_Integer_Literal,
           N_Interpolated_String_Literal => No_Aspect,
           N_Real_Literal                => Aspect_Real_Literal,
           N_String_Literal              => Aspect_String_Literal);

   begin
      --  Return True when N is either a literal or a named number and the
      --  type has the appropriate user-defined literal aspect.

      return (Nkind (N) in N_Numeric_Or_String_Literal
        and then Has_Aspect (Typ, Literal_Aspect_Map (Nkind (N))))
          or else
            (Is_Entity_Name (N)
              and then Present (Entity (N))
              and then
                ((Ekind (Entity (N)) = E_Named_Integer
                    and then Has_Aspect (Typ, Aspect_Integer_Literal))
                   or else
                     (Ekind (Entity (N)) = E_Named_Real
                        and then Has_Aspect (Typ, Aspect_Real_Literal))));
   end Is_User_Defined_Literal;

   --------------------------------------
   -- Is_Validation_Variable_Reference --
   --------------------------------------

   function Is_Validation_Variable_Reference (N : Node_Id) return Boolean is
      Var    : constant Node_Id := Unqual_Conv (N);
      Var_Id : Entity_Id;

   begin
      Var_Id := Empty;

      if Is_Entity_Name (Var) then
         Var_Id := Entity (Var);
      end if;

      return
        Present (Var_Id)
          and then Ekind (Var_Id) = E_Variable
          and then Present (Validated_Object (Var_Id));
   end Is_Validation_Variable_Reference;

   ----------------------------
   -- Is_Variable_Size_Array --
   ----------------------------

   function Is_Variable_Size_Array (E : Entity_Id) return Boolean is
      Idx : Node_Id;

   begin
      pragma Assert (Is_Array_Type (E));

      --  Check if some index is initialized with a non-constant value

      Idx := First_Index (E);
      while Present (Idx) loop
         if Nkind (Idx) = N_Range then
            if not Is_Constant_Bound (Low_Bound (Idx))
              or else not Is_Constant_Bound (High_Bound (Idx))
            then
               return True;
            end if;
         end if;

         Next_Index (Idx);
      end loop;

      return False;
   end Is_Variable_Size_Array;

   -----------------------------
   -- Is_Variable_Size_Record --
   -----------------------------

   function Is_Variable_Size_Record (E : Entity_Id) return Boolean is
      Comp     : Entity_Id;
      Comp_Typ : Entity_Id;

   begin
      pragma Assert (Is_Record_Type (E));

      Comp := First_Component (E);
      while Present (Comp) loop
         Comp_Typ := Underlying_Type (Etype (Comp));

         --  Recursive call if the record type has discriminants

         if Is_Record_Type (Comp_Typ)
           and then Has_Discriminants (Comp_Typ)
           and then Is_Variable_Size_Record (Comp_Typ)
         then
            return True;

         elsif Is_Array_Type (Comp_Typ)
           and then Is_Variable_Size_Array (Comp_Typ)
         then
            return True;
         end if;

         Next_Component (Comp);
      end loop;

      return False;
   end Is_Variable_Size_Record;

   -----------------
   -- Is_Variable --
   -----------------

   --  Should Is_Variable be refactored to better handle dereferences and
   --  technical debt ???

   function Is_Variable
     (N                 : Node_Id;
      Use_Original_Node : Boolean := True) return Boolean
   is
      Orig_Node : Node_Id;

      function In_Protected_Function (E : Entity_Id) return Boolean;
      --  Within a protected function, the private components of the enclosing
      --  protected type are constants. A function nested within a (protected)
      --  procedure is not itself protected. Within the body of a protected
      --  function the current instance of the protected type is a constant.

      function Is_Variable_Prefix (P : Node_Id) return Boolean;
      --  Prefixes can involve implicit dereferences, in which case we must
      --  test for the case of a reference of a constant access type, which can
      --  can never be a variable.

      ---------------------------
      -- In_Protected_Function --
      ---------------------------

      function In_Protected_Function (E : Entity_Id) return Boolean is
         Prot : Entity_Id;
         S    : Entity_Id;

      begin
         --  E is the current instance of a type

         if Is_Type (E) then
            Prot := E;

         --  E is an object

         else
            Prot := Scope (E);
         end if;

         if not Is_Protected_Type (Prot) then
            return False;

         else
            S := Current_Scope;
            while Present (S) and then S /= Prot loop
               if Ekind (S) = E_Function and then Scope (S) = Prot then
                  return True;
               end if;

               S := Scope (S);
            end loop;

            return False;
         end if;
      end In_Protected_Function;

      ------------------------
      -- Is_Variable_Prefix --
      ------------------------

      function Is_Variable_Prefix (P : Node_Id) return Boolean is
      begin
         if Is_Access_Type (Etype (P)) then
            return not Is_Access_Constant (Root_Type (Etype (P)));

         --  For the case of an indexed component whose prefix has a packed
         --  array type, the prefix has been rewritten into a type conversion.
         --  Determine variable-ness from the converted expression.

         elsif Nkind (P) = N_Type_Conversion
           and then not Comes_From_Source (P)
           and then Is_Packed_Array (Etype (P))
         then
            return Is_Variable (Expression (P));

         else
            return Is_Variable (P);
         end if;
      end Is_Variable_Prefix;

   --  Start of processing for Is_Variable

   begin
      --  Special check, allow x'Deref(expr) as a variable

      if Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Deref
      then
         return True;
      end if;

      --  Check if we perform the test on the original node since this may be a
      --  test of syntactic categories which must not be disturbed by whatever
      --  rewriting might have occurred. For example, an aggregate, which is
      --  certainly NOT a variable, could be turned into a variable by
      --  expansion.

      if Use_Original_Node then
         Orig_Node := Original_Node (N);
      else
         Orig_Node := N;
      end if;

      --  Definitely OK if Assignment_OK is set. Since this is something that
      --  only gets set for expanded nodes, the test is on N, not Orig_Node.

      if Nkind (N) in N_Subexpr and then Assignment_OK (N) then
         return True;

      --  Normally we go to the original node, but there is one exception where
      --  we use the rewritten node, namely when it is an explicit dereference.
      --  The generated code may rewrite a prefix which is an access type with
      --  an explicit dereference. The dereference is a variable, even though
      --  the original node may not be (since it could be a constant of the
      --  access type).

      --  In Ada 2005 we have a further case to consider: the prefix may be a
      --  function call given in prefix notation. The original node appears to
      --  be a selected component, but we need to examine the call.

      elsif Nkind (N) = N_Explicit_Dereference
        and then Nkind (Orig_Node) /= N_Explicit_Dereference
        and then Present (Etype (Orig_Node))
        and then Is_Access_Type (Etype (Orig_Node))
      then
         --  Note that if the prefix is an explicit dereference that does not
         --  come from source, we must check for a rewritten function call in
         --  prefixed notation before other forms of rewriting, to prevent a
         --  compiler crash.

         return
           (Nkind (Orig_Node) = N_Function_Call
             and then not Is_Access_Constant (Etype (Prefix (N))))
           or else
             Is_Variable_Prefix (Original_Node (Prefix (N)));

      --  Generalized indexing operations are rewritten as explicit
      --  dereferences, and it is only during resolution that we can
      --  check whether the context requires an access_to_variable type.

      elsif Nkind (N) = N_Explicit_Dereference
        and then Present (Etype (Orig_Node))
        and then Has_Implicit_Dereference (Etype (Orig_Node))
        and then Ada_Version >= Ada_2012
      then
         return not Is_Access_Constant (Etype (Prefix (N)));

      --  A function call is never a variable

      elsif Nkind (N) = N_Function_Call then
         return False;

      --  All remaining checks use the original node

      elsif Is_Entity_Name (Orig_Node)
        and then Present (Entity (Orig_Node))
      then
         declare
            E : constant Entity_Id := Entity (Orig_Node);
            K : constant Entity_Kind := Ekind (E);

         begin
            if Is_Loop_Parameter (E) then
               return False;
            end if;

            return    (K = E_Variable
                        and then Nkind (Parent (E)) /= N_Exception_Handler)
              or else (K = E_Component
                        and then not In_Protected_Function (E))
              or else (Present (Etype (E))
                        and then Is_Access_Variable (Etype (E))
                        and then Is_Dereferenced (N))
              or else K = E_Out_Parameter
              or else K = E_In_Out_Parameter
              or else K = E_Generic_In_Out_Parameter

              --  Current instance of type. If this is a protected type, check
              --  we are not within the body of one of its protected functions.

              or else (Is_Type (E)
                        and then In_Open_Scopes (E)
                        and then not In_Protected_Function (E))

              or else (Is_Incomplete_Or_Private_Type (E)
                        and then In_Open_Scopes (Full_View (E)));
         end;

      else
         case Nkind (Orig_Node) is
            when N_Indexed_Component
               | N_Slice
            =>
               return Is_Variable_Prefix (Prefix (Orig_Node));

            when N_Selected_Component =>
               return Is_Variable (Selector_Name (Orig_Node))
                       and then Is_Variable_Prefix (Prefix (Orig_Node));

            --  For an explicit dereference, the type of the prefix cannot
            --  be an access to constant or an access to subprogram.

            when N_Explicit_Dereference =>
               declare
                  Typ : constant Entity_Id := Etype (Prefix (Orig_Node));
               begin
                  return Is_Access_Type (Typ)
                    and then not Is_Access_Constant (Root_Type (Typ))
                    and then Ekind (Typ) /= E_Access_Subprogram_Type;
               end;

            --  The type conversion is the case where we do not deal with the
            --  context dependent special case of an actual parameter. Thus
            --  the type conversion is only considered a variable for the
            --  purposes of this routine if the target type is tagged. However,
            --  a type conversion is considered to be a variable if it does not
            --  come from source (this deals for example with the conversions
            --  of expressions to their actual subtypes).

            when N_Type_Conversion =>
               return Is_Variable (Expression (Orig_Node))
                 and then
                   (not Comes_From_Source (Orig_Node)
                     or else
                       (Is_Tagged_Type (Etype (Subtype_Mark (Orig_Node)))
                         and then
                        Is_Tagged_Type (Etype (Expression (Orig_Node)))));

            --  GNAT allows an unchecked type conversion as a variable. This
            --  only affects the generation of internal expanded code, since
            --  calls to instantiations of Unchecked_Conversion are never
            --  considered variables (since they are function calls).

            when N_Unchecked_Type_Conversion =>
               return Is_Variable (Expression (Orig_Node));

            when others =>
               return False;
         end case;
      end if;
   end Is_Variable;

   ------------------------
   -- Is_View_Conversion --
   ------------------------

   function Is_View_Conversion (N : Node_Id) return Boolean is
   begin
      if Nkind (N) = N_Type_Conversion
        and then Nkind (Unqual_Conv (N)) in N_Has_Etype
      then
         if Is_Tagged_Type (Etype (N))
           and then Is_Tagged_Type (Etype (Unqual_Conv (N)))
         then
            return True;

         elsif Is_Actual_Parameter (N)
           and then (Is_Actual_Out_Parameter (N)
                       or else Is_Actual_In_Out_Parameter (N))
         then
            return True;
         end if;
      end if;

      return False;
   end Is_View_Conversion;

   ---------------------------
   -- Is_Visibly_Controlled --
   ---------------------------

   function Is_Visibly_Controlled (T : Entity_Id) return Boolean is
      Root : constant Entity_Id := Root_Type (T);
   begin
      return Chars (Scope (Root)) = Name_Finalization
        and then Chars (Scope (Scope (Root))) = Name_Ada
        and then Scope (Scope (Scope (Root))) = Standard_Standard;
   end Is_Visibly_Controlled;

   ----------------------------------------
   -- Is_Volatile_Full_Access_Object_Ref --
   ----------------------------------------

   function Is_Volatile_Full_Access_Object_Ref (N : Node_Id) return Boolean is
      function Is_VFA_Object_Entity (Id : Entity_Id) return Boolean;
      --  Determine whether arbitrary entity Id denotes an object that is
      --  Volatile_Full_Access.

      ----------------------------
      --  Is_VFA_Object_Entity  --
      ----------------------------

      function Is_VFA_Object_Entity (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Object (Id)
             and then (Is_Volatile_Full_Access (Id)
                         or else
                       Is_Volatile_Full_Access (Etype (Id)));
      end Is_VFA_Object_Entity;

   --  Start of processing for Is_Volatile_Full_Access_Object_Ref

   begin
      if Is_Entity_Name (N) then
         return Is_VFA_Object_Entity (Entity (N));

      elsif Is_Volatile_Full_Access (Etype (N)) then
         return True;

      elsif Nkind (N) = N_Selected_Component then
         return Is_Volatile_Full_Access (Entity (Selector_Name (N)));

      else
         return False;
      end if;
   end Is_Volatile_Full_Access_Object_Ref;

   --------------------------
   -- Is_Volatile_Function --
   --------------------------

   function Is_Volatile_Function (Func_Id : Entity_Id) return Boolean is
   begin
      pragma Assert (Ekind (Func_Id) in E_Function | E_Generic_Function);

      --  A protected function is volatile

      if Nkind (Parent (Unit_Declaration_Node (Func_Id))) =
           N_Protected_Definition
      then
         return True;

      --  An instance of Ada.Unchecked_Conversion is a volatile function if
      --  either the source or the target are effectively volatile.

      elsif Is_Unchecked_Conversion_Instance (Func_Id)
        and then Has_Effectively_Volatile_Profile (Func_Id)
      then
         return True;

      --  Otherwise the function is treated as volatile if it is subject to
      --  enabled pragma Volatile_Function.

      else
         return
           Is_Enabled_Pragma (Get_Pragma (Func_Id, Pragma_Volatile_Function));
      end if;
   end Is_Volatile_Function;

   ----------------------------
   -- Is_Volatile_Object_Ref --
   ----------------------------

   function Is_Volatile_Object_Ref (N : Node_Id) return Boolean is
      function Is_Volatile_Object_Entity (Id : Entity_Id) return Boolean;
      --  Determine whether arbitrary entity Id denotes an object that is
      --  Volatile.

      function Prefix_Has_Volatile_Components (P : Node_Id) return Boolean;
      --  Determine whether prefix P has volatile components. This requires
      --  the presence of a Volatile_Components aspect/pragma or that P be
      --  itself a volatile object as per RM C.6(8).

      ---------------------------------
      --  Is_Volatile_Object_Entity  --
      ---------------------------------

      function Is_Volatile_Object_Entity (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Object (Id)
             and then (Is_Volatile (Id) or else Is_Volatile (Etype (Id)));
      end Is_Volatile_Object_Entity;

      ------------------------------------
      -- Prefix_Has_Volatile_Components --
      ------------------------------------

      function Prefix_Has_Volatile_Components (P : Node_Id) return Boolean is
         Typ : constant Entity_Id := Etype (P);

      begin
         if Is_Access_Type (Typ) then
            declare
               Dtyp : constant Entity_Id := Designated_Type (Typ);

            begin
               return Has_Volatile_Components (Dtyp)
                 or else Is_Volatile (Dtyp);
            end;

         elsif Has_Volatile_Components (Typ) then
            return True;

         elsif Is_Entity_Name (P)
           and then Has_Volatile_Component (Entity (P))
         then
            return True;

         elsif Is_Volatile_Object_Ref (P) then
            return True;

         else
            return False;
         end if;
      end Prefix_Has_Volatile_Components;

   --  Start of processing for Is_Volatile_Object_Ref

   begin
      if Is_Entity_Name (N) then
         return Is_Volatile_Object_Entity (Entity (N));

      elsif Is_Volatile (Etype (N)) then
         return True;

      elsif Nkind (N) = N_Indexed_Component then
         return Prefix_Has_Volatile_Components (Prefix (N));

      elsif Nkind (N) = N_Selected_Component then
         return Prefix_Has_Volatile_Components (Prefix (N))
           or else Is_Volatile (Entity (Selector_Name (N)));

      else
         return False;
      end if;
   end Is_Volatile_Object_Ref;

   -----------------------------
   -- Iterate_Call_Parameters --
   -----------------------------

   procedure Iterate_Call_Parameters (Call : Node_Id) is
      Actual : Node_Id   := First_Actual (Call);
      Formal : Entity_Id := First_Formal (Get_Called_Entity (Call));

   begin
      while Present (Formal) and then Present (Actual) loop
         Handle_Parameter (Formal, Actual);

         Next_Formal (Formal);
         Next_Actual (Actual);
      end loop;

      pragma Assert (No (Formal));
      pragma Assert (No (Actual));
   end Iterate_Call_Parameters;

   -------------------------
   -- Kill_Current_Values --
   -------------------------

   procedure Kill_Current_Values
     (Ent                  : Entity_Id;
      Last_Assignment_Only : Boolean := False)
   is
   begin
      if Is_Assignable (Ent) then
         Set_Last_Assignment (Ent, Empty);
      end if;

      if Is_Object (Ent) then
         if not Last_Assignment_Only then
            Kill_Checks (Ent);
            Set_Current_Value (Ent, Empty);

            --  Do not reset the Is_Known_[Non_]Null and Is_Known_Valid flags
            --  for a constant. Once the constant is elaborated, its value is
            --  not changed, therefore the associated flags that describe the
            --  value should not be modified either.

            if Ekind (Ent) = E_Constant then
               null;

            --  Non-constant entities

            else
               if not Can_Never_Be_Null (Ent) then
                  Set_Is_Known_Non_Null (Ent, False);
               end if;

               Set_Is_Known_Null (Ent, False);

               --  Reset the Is_Known_Valid flag unless the type is always
               --  valid. This does not apply to a loop parameter because its
               --  bounds are defined by the loop header and therefore always
               --  valid.

               if not Is_Known_Valid (Etype (Ent))
                 and then Ekind (Ent) /= E_Loop_Parameter
               then
                  Set_Is_Known_Valid (Ent, False);
               end if;
            end if;
         end if;
      end if;
   end Kill_Current_Values;

   procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False) is
      S : Entity_Id;

   begin
      --  Kill all saved checks, a special case of killing saved values

      if not Last_Assignment_Only then
         Kill_All_Checks;
      end if;

      --  Loop through relevant scopes, which includes the current scope and
      --  any parent scopes if the current scope is a block or a package.

      S := Current_Scope;
      Scope_Loop : loop

         --  Clear current values of all entities in current scope

         declare
            Ent : Entity_Id;
         begin
            Ent := First_Entity (S);
            while Present (Ent) loop
               Kill_Current_Values (Ent, Last_Assignment_Only);
               Next_Entity (Ent);
            end loop;
         end;

         --  If this is a not a subprogram, deal with parents

         if not Is_Subprogram (S) then
            S := Scope (S);
            exit Scope_Loop when S = Standard_Standard;
         else
            exit Scope_Loop;
         end if;
      end loop Scope_Loop;
   end Kill_Current_Values;

   --------------------------
   -- Kill_Size_Check_Code --
   --------------------------

   procedure Kill_Size_Check_Code (E : Entity_Id) is
   begin
      if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable)
        and then Present (Size_Check_Code (E))
      then
         Remove (Size_Check_Code (E));
         Set_Size_Check_Code (E, Empty);
      end if;
   end Kill_Size_Check_Code;

   --------------------
   -- Known_Non_Null --
   --------------------

   function Known_Non_Null (N : Node_Id) return Boolean is
      Status : constant Null_Status_Kind := Null_Status (N);

      Id  : Entity_Id;
      Op  : Node_Kind;
      Val : Node_Id;

   begin
      --  The expression yields a non-null value ignoring simple flow analysis

      if Status = Is_Non_Null then
         return True;

      --  Otherwise check whether N is a reference to an entity that appears
      --  within a conditional construct.

      elsif Is_Entity_Name (N) and then Present (Entity (N)) then

         --  First check if we are in decisive conditional

         Get_Current_Value_Condition (N, Op, Val);

         if Known_Null (Val) then
            if Op = N_Op_Eq then
               return False;
            elsif Op = N_Op_Ne then
               return True;
            end if;
         end if;

         --  If OK to do replacement, test Is_Known_Non_Null flag

         Id := Entity (N);

         if OK_To_Do_Constant_Replacement (Id) then
            return Is_Known_Non_Null (Id);
         end if;
      end if;

      --  Otherwise it is not possible to determine whether N yields a non-null
      --  value.

      return False;
   end Known_Non_Null;

   ----------------
   -- Known_Null --
   ----------------

   function Known_Null (N : Node_Id) return Boolean is
      Status : constant Null_Status_Kind := Null_Status (N);

      Id  : Entity_Id;
      Op  : Node_Kind;
      Val : Node_Id;

   begin
      --  The expression yields a null value ignoring simple flow analysis

      if Status = Is_Null then
         return True;

      --  Otherwise check whether N is a reference to an entity that appears
      --  within a conditional construct.

      elsif Is_Entity_Name (N) and then Present (Entity (N)) then

         --  First check if we are in decisive conditional

         Get_Current_Value_Condition (N, Op, Val);

         --  If Get_Current_Value_Condition were to return Val = N, then the
         --  recursion below could be infinite.

         if Val = N then
            raise Program_Error;
         end if;

         if Known_Null (Val) then
            if Op = N_Op_Eq then
               return True;
            elsif Op = N_Op_Ne then
               return False;
            end if;
         end if;

         --  If OK to do replacement, test Is_Known_Null flag

         Id := Entity (N);

         if OK_To_Do_Constant_Replacement (Id) then
            return Is_Known_Null (Id);
         end if;
      end if;

      --  Otherwise it is not possible to determine whether N yields a null
      --  value.

      return False;
   end Known_Null;

   ---------------------------
   -- Last_Source_Statement --
   ---------------------------

   function Last_Source_Statement (HSS : Node_Id) return Node_Id is
      N : Node_Id;

   begin
      N := Last (Statements (HSS));
      while Present (N) loop
         exit when Comes_From_Source (N);
         Prev (N);
      end loop;

      return N;
   end Last_Source_Statement;

   -----------------------
   -- Mark_Coextensions --
   -----------------------

   procedure Mark_Coextensions (Context_Nod : Node_Id; Root_Nod : Node_Id) is
      Is_Dynamic : Boolean;
      --  Indicates whether the context causes nested coextensions to be
      --  dynamic or static

      function Mark_Allocator (N : Node_Id) return Traverse_Result;
      --  Recognize an allocator node and label it as a dynamic coextension

      --------------------
      -- Mark_Allocator --
      --------------------

      function Mark_Allocator (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Allocator then
            if Is_Dynamic then
               Set_Is_Static_Coextension (N, False);
               Set_Is_Dynamic_Coextension (N);

            --  If the allocator expression is potentially dynamic, it may
            --  be expanded out of order and require dynamic allocation
            --  anyway, so we treat the coextension itself as dynamic.
            --  Potential optimization ???

            elsif Nkind (Expression (N)) = N_Qualified_Expression
              and then Nkind (Expression (Expression (N))) = N_Op_Concat
            then
               Set_Is_Static_Coextension (N, False);
               Set_Is_Dynamic_Coextension (N);
            else
               Set_Is_Dynamic_Coextension (N, False);
               Set_Is_Static_Coextension (N);
            end if;
         end if;

         return OK;
      end Mark_Allocator;

      procedure Mark_Allocators is new Traverse_Proc (Mark_Allocator);

   --  Start of processing for Mark_Coextensions

   begin
      --  An allocator that appears on the right-hand side of an assignment is
      --  treated as a potentially dynamic coextension when the right-hand side
      --  is an allocator or a qualified expression.

      --    Obj := new ...'(new Coextension ...);

      if Nkind (Context_Nod) = N_Assignment_Statement then
         Is_Dynamic := Nkind (Expression (Context_Nod)) in
                         N_Allocator | N_Qualified_Expression;

      --  An allocator that appears within the expression of a simple return
      --  statement is treated as a potentially dynamic coextension when the
      --  expression is either aggregate, allocator, or qualified expression.

      --    return (new Coextension ...);
      --    return new ...'(new Coextension ...);

      elsif Nkind (Context_Nod) = N_Simple_Return_Statement then
         Is_Dynamic := Nkind (Expression (Context_Nod)) in
                         N_Aggregate | N_Allocator | N_Qualified_Expression;

      --  An alloctor that appears within the initialization expression of an
      --  object declaration is considered a potentially dynamic coextension
      --  when the initialization expression is an allocator or a qualified
      --  expression.

      --    Obj : ... := new ...'(new Coextension ...);

      --  A similar case arises when the object declaration is part of an
      --  extended return statement.

      --    return Obj : ... := new ...'(new Coextension ...);
      --    return Obj : ... := (new Coextension ...);

      elsif Nkind (Context_Nod) = N_Object_Declaration then
         Is_Dynamic := Nkind (Root_Nod) in N_Allocator | N_Qualified_Expression
           or else Nkind (Parent (Context_Nod)) = N_Extended_Return_Statement;

      --  This routine should not be called with constructs that cannot contain
      --  coextensions.

      else
         raise Program_Error;
      end if;

      Mark_Allocators (Root_Nod);
   end Mark_Coextensions;

   ---------------------------------
   -- Mark_Elaboration_Attributes --
   ---------------------------------

   procedure Mark_Elaboration_Attributes
     (N_Id     : Node_Or_Entity_Id;
      Checks   : Boolean := False;
      Level    : Boolean := False;
      Modes    : Boolean := False;
      Warnings : Boolean := False)
   is
      function Elaboration_Checks_OK
        (Target_Id  : Entity_Id;
         Context_Id : Entity_Id) return Boolean;
      --  Determine whether elaboration checks are enabled for target Target_Id
      --  which resides within context Context_Id.

      procedure Mark_Elaboration_Attributes_Id (Id : Entity_Id);
      --  Preserve relevant attributes of the context in arbitrary entity Id

      procedure Mark_Elaboration_Attributes_Node (N : Node_Id);
      --  Preserve relevant attributes of the context in arbitrary node N

      ---------------------------
      -- Elaboration_Checks_OK --
      ---------------------------

      function Elaboration_Checks_OK
        (Target_Id  : Entity_Id;
         Context_Id : Entity_Id) return Boolean
      is
         Encl_Scop : Entity_Id;

      begin
         --  Elaboration checks are suppressed for the target

         if Elaboration_Checks_Suppressed (Target_Id) then
            return False;
         end if;

         --  Otherwise elaboration checks are OK for the target, but may be
         --  suppressed for the context where the target is declared.

         Encl_Scop := Context_Id;
         while Present (Encl_Scop) and then Encl_Scop /= Standard_Standard loop
            if Elaboration_Checks_Suppressed (Encl_Scop) then
               return False;
            end if;

            Encl_Scop := Scope (Encl_Scop);
         end loop;

         --  Neither the target nor its declarative context have elaboration
         --  checks suppressed.

         return True;
      end Elaboration_Checks_OK;

      ------------------------------------
      -- Mark_Elaboration_Attributes_Id --
      ------------------------------------

      procedure Mark_Elaboration_Attributes_Id (Id : Entity_Id) is
      begin
         --  Mark the status of elaboration checks in effect. Do not reset the
         --  status in case the entity is reanalyzed with checks suppressed.

         if Checks and then not Is_Elaboration_Checks_OK_Id (Id) then
            Set_Is_Elaboration_Checks_OK_Id (Id,
              Elaboration_Checks_OK
                (Target_Id  => Id,
                 Context_Id => Scope (Id)));
         end if;

         --  Mark the status of elaboration warnings in effect. Do not reset
         --  the status in case the entity is reanalyzed with warnings off.

         if Warnings and then not Is_Elaboration_Warnings_OK_Id (Id) then
            Set_Is_Elaboration_Warnings_OK_Id (Id, Elab_Warnings);
         end if;
      end Mark_Elaboration_Attributes_Id;

      --------------------------------------
      -- Mark_Elaboration_Attributes_Node --
      --------------------------------------

      procedure Mark_Elaboration_Attributes_Node (N : Node_Id) is
         function Extract_Name (N : Node_Id) return Node_Id;
         --  Obtain the Name attribute of call or instantiation N

         ------------------
         -- Extract_Name --
         ------------------

         function Extract_Name (N : Node_Id) return Node_Id is
            Nam : Node_Id;

         begin
            Nam := Name (N);

            --  A call to an entry family appears in indexed form

            if Nkind (Nam) = N_Indexed_Component then
               Nam := Prefix (Nam);
            end if;

            --  The name may also appear in qualified form

            if Nkind (Nam) = N_Selected_Component then
               Nam := Selector_Name (Nam);
            end if;

            return Nam;
         end Extract_Name;

         --  Local variables

         Context_Id : Entity_Id;
         Nam        : Node_Id;

      --  Start of processing for Mark_Elaboration_Attributes_Node

      begin
         --  Mark the status of elaboration checks in effect. Do not reset the
         --  status in case the node is reanalyzed with checks suppressed.

         if Checks and then not Is_Elaboration_Checks_OK_Node (N) then

            --  Assignments, attribute references, and variable references do
            --  not have a "declarative" context.

            Context_Id := Empty;

            --  The status of elaboration checks for calls and instantiations
            --  depends on the most recent pragma Suppress/Unsuppress, as well
            --  as the suppression status of the context where the target is
            --  defined.

            --    package Pack is
            --       function Func ...;
            --    end Pack;

            --    with Pack;
            --    procedure Main is
            --       pragma Suppress (Elaboration_Checks, Pack);
            --       X : ... := Pack.Func;
            --    ...

            --  In the example above, the call to Func has elaboration checks
            --  enabled because there is no active general purpose suppression
            --  pragma, however the elaboration checks of Pack are explicitly
            --  suppressed. As a result the elaboration checks of the call must
            --  be disabled in order to preserve this dependency.

            if Nkind (N) in N_Entry_Call_Statement
                          | N_Function_Call
                          | N_Function_Instantiation
                          | N_Package_Instantiation
                          | N_Procedure_Call_Statement
                          | N_Procedure_Instantiation
            then
               Nam := Extract_Name (N);

               if Is_Entity_Name (Nam) and then Present (Entity (Nam)) then
                  Context_Id := Scope (Entity (Nam));
               end if;
            end if;

            Set_Is_Elaboration_Checks_OK_Node (N,
              Elaboration_Checks_OK
                (Target_Id  => Empty,
                 Context_Id => Context_Id));
         end if;

         --  Mark the enclosing level of the node. Do not reset the status in
         --  case the node is relocated and reanalyzed.

         if Level and then not Is_Declaration_Level_Node (N) then
            Set_Is_Declaration_Level_Node (N,
              Find_Enclosing_Level (N) = Declaration_Level);
         end if;

         --  Mark the Ghost and SPARK mode in effect

         if Modes then
            if Ghost_Mode = Ignore then
               Set_Is_Ignored_Ghost_Node (N);
            end if;

            if SPARK_Mode = On then
               Set_Is_SPARK_Mode_On_Node (N);
            end if;
         end if;

         --  Mark the status of elaboration warnings in effect. Do not reset
         --  the status in case the node is reanalyzed with warnings off.

         if Warnings and then not Is_Elaboration_Warnings_OK_Node (N) then
            Set_Is_Elaboration_Warnings_OK_Node (N, Elab_Warnings);
         end if;
      end Mark_Elaboration_Attributes_Node;

   --  Start of processing for Mark_Elaboration_Attributes

   begin
      --  Do not capture any elaboration-related attributes when switch -gnatH
      --  (legacy elaboration checking mode enabled) is in effect because the
      --  attributes are useless to the legacy model.

      if Legacy_Elaboration_Checks then
         return;
      end if;

      if Nkind (N_Id) in N_Entity then
         Mark_Elaboration_Attributes_Id (N_Id);
      else
         Mark_Elaboration_Attributes_Node (N_Id);
      end if;
   end Mark_Elaboration_Attributes;

   ----------------------------------------
   -- Mark_Save_Invocation_Graph_Of_Body --
   ----------------------------------------

   procedure Mark_Save_Invocation_Graph_Of_Body is
      Main      : constant Node_Id := Cunit (Main_Unit);
      Main_Unit : constant Node_Id := Unit (Main);
      Aux_Id    : Entity_Id;

   begin
      Set_Save_Invocation_Graph_Of_Body (Main);

      --  Assume that the main unit does not have a complimentary unit

      Aux_Id := Empty;

      --  Obtain the complimentary unit of the main unit

      if Nkind (Main_Unit) in N_Generic_Package_Declaration
                            | N_Generic_Subprogram_Declaration
                            | N_Package_Declaration
                            | N_Subprogram_Declaration
      then
         Aux_Id := Corresponding_Body (Main_Unit);

      elsif Nkind (Main_Unit) in N_Package_Body
                               | N_Subprogram_Body
                               | N_Subprogram_Renaming_Declaration
      then
         Aux_Id := Corresponding_Spec (Main_Unit);
      end if;

      if Present (Aux_Id) then
         Set_Save_Invocation_Graph_Of_Body
           (Parent (Unit_Declaration_Node (Aux_Id)));
      end if;
   end Mark_Save_Invocation_Graph_Of_Body;

   ----------------------------------
   -- Matching_Static_Array_Bounds --
   ----------------------------------

   function Matching_Static_Array_Bounds
     (L_Typ : Node_Id;
      R_Typ : Node_Id) return Boolean
   is
      L_Ndims : constant Nat := Number_Dimensions (L_Typ);
      R_Ndims : constant Nat := Number_Dimensions (R_Typ);

      L_Index : Node_Id := Empty; -- init to ...
      R_Index : Node_Id := Empty; -- ...avoid warnings
      L_Low   : Node_Id;
      L_High  : Node_Id;
      L_Len   : Uint;
      R_Low   : Node_Id;
      R_High  : Node_Id;
      R_Len   : Uint;

   begin
      if L_Ndims /= R_Ndims then
         return False;
      end if;

      --  Unconstrained types do not have static bounds

      if not Is_Constrained (L_Typ) or else not Is_Constrained (R_Typ) then
         return False;
      end if;

      --  First treat specially the first dimension, as the lower bound and
      --  length of string literals are not stored like those of arrays.

      if Ekind (L_Typ) = E_String_Literal_Subtype then
         L_Low := String_Literal_Low_Bound (L_Typ);
         L_Len := String_Literal_Length (L_Typ);
      else
         L_Index := First_Index (L_Typ);
         Get_Index_Bounds (L_Index, L_Low, L_High);

         if Is_OK_Static_Expression (L_Low)
              and then
            Is_OK_Static_Expression (L_High)
         then
            if Expr_Value (L_High) < Expr_Value (L_Low) then
               L_Len := Uint_0;
            else
               L_Len := (Expr_Value (L_High) - Expr_Value (L_Low)) + 1;
            end if;
         else
            return False;
         end if;
      end if;

      if Ekind (R_Typ) = E_String_Literal_Subtype then
         R_Low := String_Literal_Low_Bound (R_Typ);
         R_Len := String_Literal_Length (R_Typ);
      else
         R_Index := First_Index (R_Typ);
         Get_Index_Bounds (R_Index, R_Low, R_High);

         if Is_OK_Static_Expression (R_Low)
              and then
            Is_OK_Static_Expression (R_High)
         then
            if Expr_Value (R_High) < Expr_Value (R_Low) then
               R_Len := Uint_0;
            else
               R_Len := (Expr_Value (R_High) - Expr_Value (R_Low)) + 1;
            end if;
         else
            return False;
         end if;
      end if;

      if (Is_OK_Static_Expression (L_Low)
            and then
          Is_OK_Static_Expression (R_Low))
        and then Expr_Value (L_Low) = Expr_Value (R_Low)
        and then L_Len = R_Len
      then
         null;
      else
         return False;
      end if;

      --  Then treat all other dimensions

      for Indx in 2 .. L_Ndims loop
         Next (L_Index);
         Next (R_Index);

         Get_Index_Bounds (L_Index, L_Low, L_High);
         Get_Index_Bounds (R_Index, R_Low, R_High);

         if (Is_OK_Static_Expression (L_Low)  and then
             Is_OK_Static_Expression (L_High) and then
             Is_OK_Static_Expression (R_Low)  and then
             Is_OK_Static_Expression (R_High))
           and then (Expr_Value (L_Low)  = Expr_Value (R_Low)
                       and then
                     Expr_Value (L_High) = Expr_Value (R_High))
         then
            null;
         else
            return False;
         end if;
      end loop;

      --  If we fall through the loop, all indexes matched

      return True;
   end Matching_Static_Array_Bounds;

   -----------------
   -- Might_Raise --
   -----------------

   function Might_Raise (N : Node_Id) return Boolean is
      Result : Boolean := False;

      function Process (N : Node_Id) return Traverse_Result;
      --  Set Result to True if we find something that could raise an exception

      -------------
      -- Process --
      -------------

      function Process (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) in N_Procedure_Call_Statement
                       | N_Function_Call
                       | N_Raise_Statement
                       | N_Raise_xxx_Error
                       | N_Raise_Expression
         then
            Result := True;
            return Abandon;
         else
            return OK;
         end if;
      end Process;

      procedure Set_Result is new Traverse_Proc (Process);

   --  Start of processing for Might_Raise

   begin
      --  False if exceptions can't be propagated

      if No_Exception_Handlers_Set then
         return False;
      end if;

      --  If the checks handled by the back end are not disabled, we cannot
      --  ensure that no exception will be raised.

      if not Access_Checks_Suppressed (Empty)
        or else not Discriminant_Checks_Suppressed (Empty)
        or else not Range_Checks_Suppressed (Empty)
        or else not Index_Checks_Suppressed (Empty)
        or else Opt.Stack_Checking_Enabled
      then
         return True;
      end if;

      Set_Result (N);
      return Result;
   end Might_Raise;

   ----------------------------------------
   -- Nearest_Class_Condition_Subprogram --
   ----------------------------------------

   function Nearest_Class_Condition_Subprogram
     (Kind    : Condition_Kind;
      Spec_Id : Entity_Id) return Entity_Id
   is
      Subp_Id : constant Entity_Id := Ultimate_Alias (Spec_Id);

   begin
      --  Prevent cascaded errors

      if not Is_Dispatching_Operation (Subp_Id) then
         return Empty;

      --  No need to search if this subprogram has class-wide postconditions

      elsif Present (Class_Condition (Kind, Subp_Id)) then
         return Subp_Id;
      end if;

      --  Process the contracts of inherited subprograms, looking for
      --  class-wide pre/postconditions.

      declare
         Subps   : constant Subprogram_List := Inherited_Subprograms (Subp_Id);
         Subp_Id : Entity_Id;

      begin
         for Index in Subps'Range loop
            Subp_Id := Subps (Index);

            if Present (Alias (Subp_Id)) then
               Subp_Id := Ultimate_Alias (Subp_Id);
            end if;

            --  Wrappers of class-wide pre/postconditions reference the
            --  parent primitive that has the inherited contract.

            if Is_Wrapper (Subp_Id)
              and then Present (LSP_Subprogram (Subp_Id))
            then
               Subp_Id := LSP_Subprogram (Subp_Id);
            end if;

            if Present (Class_Condition (Kind, Subp_Id)) then
               return Subp_Id;
            end if;
         end loop;
      end;

      return Empty;
   end Nearest_Class_Condition_Subprogram;

   --------------------------------
   -- Nearest_Enclosing_Instance --
   --------------------------------

   function Nearest_Enclosing_Instance (E : Entity_Id) return Entity_Id is
      Inst : Entity_Id;

   begin
      Inst := Scope (E);
      while Present (Inst) and then Inst /= Standard_Standard loop
         if Is_Generic_Instance (Inst) then
            return Inst;
         end if;

         Inst := Scope (Inst);
      end loop;

      return Empty;
   end Nearest_Enclosing_Instance;

   ------------------------
   -- Needs_Finalization --
   ------------------------

   function Needs_Finalization (Typ : Entity_Id) return Boolean is
      function Has_Some_Controlled_Component
        (Input_Typ : Entity_Id) return Boolean;
      --  Determine whether type Input_Typ has at least one controlled
      --  component.

      -----------------------------------
      -- Has_Some_Controlled_Component --
      -----------------------------------

      function Has_Some_Controlled_Component
        (Input_Typ : Entity_Id) return Boolean
      is
         Comp : Entity_Id;

      begin
         --  When a type is already frozen and has at least one controlled
         --  component, or is manually decorated, it is sufficient to inspect
         --  flag Has_Controlled_Component.

         if Has_Controlled_Component (Input_Typ) then
            return True;

         --  Otherwise inspect the internals of the type

         elsif not Is_Frozen (Input_Typ) then
            if Is_Array_Type (Input_Typ) then
               return Needs_Finalization (Component_Type (Input_Typ));

            elsif Is_Record_Type (Input_Typ) then
               Comp := First_Component (Input_Typ);
               while Present (Comp) loop
                  if Needs_Finalization (Etype (Comp)) then
                     return True;
                  end if;

                  Next_Component (Comp);
               end loop;
            end if;
         end if;

         return False;
      end Has_Some_Controlled_Component;

   --  Start of processing for Needs_Finalization

   begin
      --  Certain run-time configurations and targets do not provide support
      --  for controlled types.

      if Restriction_Active (No_Finalization) then
         return False;

      --  C++ types are not considered controlled. It is assumed that the non-
      --  Ada side will handle their clean up.

      elsif Convention (Typ) = Convention_CPP then
         return False;

      --  Class-wide types are treated as controlled because derivations from
      --  the root type may introduce controlled components.

      elsif Is_Class_Wide_Type (Typ) then
         return True;

      --  Concurrent types are controlled as long as their corresponding record
      --  is controlled.

      elsif Is_Concurrent_Type (Typ)
        and then Present (Corresponding_Record_Type (Typ))
        and then Needs_Finalization (Corresponding_Record_Type (Typ))
      then
         return True;

      --  Otherwise the type is controlled when it is either derived from type
      --  [Limited_]Controlled and not subject to aspect Disable_Controlled, or
      --  contains at least one controlled component.

      else
         return
           Is_Controlled (Typ) or else Has_Some_Controlled_Component (Typ);
      end if;
   end Needs_Finalization;

   ----------------------
   -- Needs_One_Actual --
   ----------------------

   function Needs_One_Actual (E : Entity_Id) return Boolean is
      Formal : Entity_Id;

   begin
      --  Ada 2005 or later, and formals present. The first formal must be
      --  of a type that supports prefix notation: a controlling argument,
      --  a class-wide type, or an access to such.

      if Ada_Version >= Ada_2005
        and then Present (First_Formal (E))
        and then No (Default_Value (First_Formal (E)))
        and then
          (Is_Controlling_Formal (First_Formal (E))
            or else Is_Class_Wide_Type (Etype (First_Formal (E)))
            or else Is_Anonymous_Access_Type (Etype (First_Formal (E))))
      then
         Formal := Next_Formal (First_Formal (E));
         while Present (Formal) loop
            if No (Default_Value (Formal)) then
               return False;
            end if;

            Next_Formal (Formal);
         end loop;

         return True;

      --  Ada 83/95 or no formals

      else
         return False;
      end if;
   end Needs_One_Actual;

   ----------------------------
   --  Needs_Secondary_Stack --
   ----------------------------

   function Needs_Secondary_Stack (Id : Entity_Id) return Boolean is
      pragma Assert (if Present (Id) then Ekind (Id) in E_Void | Type_Kind);

      function Caller_Known_Size_Record (Typ : Entity_Id) return Boolean;
      --  Called for untagged record and protected types. Return True if the
      --  size of function results is known in the caller for Typ.

      function Large_Max_Size_Mutable (Typ : Entity_Id) return Boolean;
      --  Returns True if Typ is a nonlimited record with defaulted
      --  discriminants whose max size makes it unsuitable for allocating on
      --  the primary stack.

      ------------------------------
      -- Caller_Known_Size_Record --
      ------------------------------

      function Caller_Known_Size_Record (Typ : Entity_Id) return Boolean is
         pragma Assert (if Present (Typ) then Typ = Underlying_Type (Typ));

         function Depends_On_Discriminant (Typ : Entity_Id) return Boolean;
         --  Called for untagged record and protected types. Return True if Typ
         --  depends on discriminants, either directly when it is unconstrained
         --  or indirectly when it is constrained by uplevel discriminants.

         -----------------------------
         -- Depends_On_Discriminant --
         -----------------------------

         function Depends_On_Discriminant (Typ : Entity_Id) return Boolean is
            Cons : Elmt_Id;

         begin
            if Has_Discriminants (Typ) then
               if not Is_Constrained (Typ) then
                  return True;

               else
                  Cons := First_Elmt (Discriminant_Constraint (Typ));
                  while Present (Cons) loop
                     if Nkind (Node (Cons)) = N_Identifier
                       and then Ekind (Entity (Node (Cons))) = E_Discriminant
                     then
                        return True;
                     end if;

                     Next_Elmt (Cons);
                  end loop;
               end if;
            end if;

            return False;
         end Depends_On_Discriminant;

      begin
         --  This is a protected type without Corresponding_Record_Type set,
         --  typically because expansion is disabled. The safe thing to do is
         --  to return True, so Needs_Secondary_Stack returns False.

         if No (Typ) then
            return True;
         end if;

         --  First see if we have a variant part and return False if it depends
         --  on discriminants.

         if Has_Variant_Part (Typ) and then Depends_On_Discriminant (Typ) then
            return False;
         end if;

         --  Then loop over components and return False if their subtype has a
         --  caller-unknown size, possibly recursively.

         --  ??? This is overly conservative, an array could be nested inside
         --  some other record that is constrained by nondiscriminants. That
         --  is, the recursive calls are too conservative.

         declare
            Comp : Entity_Id;

         begin
            Comp := First_Component (Typ);
            while Present (Comp) loop
               declare
                  Comp_Type : constant Entity_Id :=
                                Underlying_Type (Etype (Comp));

               begin
                  if Is_Record_Type (Comp_Type) then
                     if not Caller_Known_Size_Record (Comp_Type) then
                        return False;
                     end if;

                  elsif Is_Protected_Type (Comp_Type) then
                     if not Caller_Known_Size_Record
                              (Corresponding_Record_Type (Comp_Type))
                     then
                        return False;
                     end if;

                  elsif Is_Array_Type (Comp_Type) then
                     if Size_Depends_On_Discriminant (Comp_Type) then
                        return False;
                     end if;
                  end if;
               end;

               Next_Component (Comp);
            end loop;
         end;

         return True;
      end Caller_Known_Size_Record;

      ------------------------------
      -- Large_Max_Size_Mutable --
      ------------------------------

      function Large_Max_Size_Mutable (Typ : Entity_Id) return Boolean is
         pragma Assert (Typ = Underlying_Type (Typ));

         function Is_Large_Discrete_Type (T : Entity_Id) return Boolean;
         --  Returns true if the discrete type T has a large range

         ----------------------------
         -- Is_Large_Discrete_Type --
         ----------------------------

         function Is_Large_Discrete_Type (T : Entity_Id) return Boolean is
            Threshold : constant Int := 16;
            --  Arbitrary threshold above which we consider it "large". We want
            --  a fairly large threshold, because these large types really
            --  shouldn't have default discriminants in the first place, in
            --  most cases.

         begin
            return UI_To_Int (RM_Size (T)) > Threshold;
         end Is_Large_Discrete_Type;

      --  Start of processing for Large_Max_Size_Mutable

      begin
         if Is_Record_Type (Typ)
           and then not Is_Limited_View (Typ)
           and then Has_Defaulted_Discriminants (Typ)
         then
            --  Loop through the components, looking for an array whose upper
            --  bound(s) depends on discriminants, where both the subtype of
            --  the discriminant and the index subtype are too large.

            declare
               Comp : Entity_Id;

            begin
               Comp := First_Component (Typ);
               while Present (Comp) loop
                  declare
                     Comp_Type : constant Entity_Id :=
                                   Underlying_Type (Etype (Comp));

                     Hi   : Node_Id;
                     Indx : Node_Id;
                     Ityp : Entity_Id;

                  begin
                     if Is_Array_Type (Comp_Type) then
                        Indx := First_Index (Comp_Type);

                        while Present (Indx) loop
                           Ityp := Etype (Indx);
                           Hi := Type_High_Bound (Ityp);

                           if Nkind (Hi) = N_Identifier
                             and then Ekind (Entity (Hi)) = E_Discriminant
                             and then Is_Large_Discrete_Type (Ityp)
                             and then Is_Large_Discrete_Type
                                        (Etype (Entity (Hi)))
                           then
                              return True;
                           end if;

                           Next_Index (Indx);
                        end loop;
                     end if;
                  end;

                  Next_Component (Comp);
               end loop;
            end;
         end if;

         return False;
      end Large_Max_Size_Mutable;

      --  Local declarations

      Typ : constant Entity_Id := Underlying_Type (Id);

   --  Start of processing for Needs_Secondary_Stack

   begin
      --  This is a private type which is not completed yet. This can only
      --  happen in a default expression (of a formal parameter or of a
      --  record component). The safe thing to do is to return False.

      if No (Typ) then
         return False;
      end if;

      --  Do not expand transient scope for non-existent procedure return or
      --  string literal types.

      if Typ = Standard_Void_Type
        or else Ekind (Typ) = E_String_Literal_Subtype
      then
         return False;

      --  If Typ is a generic formal incomplete type, then we want to look at
      --  the actual type.

      elsif Ekind (Typ) = E_Record_Subtype
        and then Present (Cloned_Subtype (Typ))
      then
         return Needs_Secondary_Stack (Cloned_Subtype (Typ));

      --  Class-wide types obviously have an unknown size. For specific tagged
      --  types, if a call returning one of them is dispatching on result, and
      --  this type is not returned on the secondary stack, then the call goes
      --  through a thunk that only moves the result from the primary onto the
      --  secondary stack, because the computation of the size of the result is
      --  possible but complex from the outside.

      elsif Is_Class_Wide_Type (Typ) then
         return True;

      --  If the return slot of the back end cannot be accessed, then there
      --  is no way to call Adjust at the right time for the return object if
      --  the type needs finalization, so the return object must be allocated
      --  on the secondary stack.

      elsif not Back_End_Return_Slot and then Needs_Finalization (Typ) then
         return True;

      --  Definite subtypes have a known size. This includes all elementary
      --  types. Tasks have a known size even if they have discriminants, so
      --  we return False here, with one exception:
      --  For a type like:
      --    type T (Last : Natural := 0) is
      --       X : String (1 .. Last);
      --    end record;
      --  we return True. That's because for "P(F(...));", where F returns T,
      --  we don't know the size of the result at the call site, so if we
      --  allocated it on the primary stack, we would have to allocate the
      --  maximum size, which is way too big.

      elsif Is_Definite_Subtype (Typ) or else Is_Task_Type (Typ) then
         return Large_Max_Size_Mutable (Typ);

      --  Indefinite (discriminated) record type

      elsif Is_Record_Type (Typ) then
         return not Caller_Known_Size_Record (Typ);

      --  Indefinite (discriminated) protected type

      elsif Is_Protected_Type (Typ) then
         return not Caller_Known_Size_Record (Corresponding_Record_Type (Typ));

      --  Unconstrained array type

      else
         pragma Assert (Is_Array_Type (Typ) and then not Is_Constrained (Typ));
         return True;
      end if;
   end Needs_Secondary_Stack;

   ---------------------------------
   -- Needs_Simple_Initialization --
   ---------------------------------

   function Needs_Simple_Initialization
     (Typ         : Entity_Id;
      Consider_IS : Boolean := True) return Boolean
   is
      Consider_IS_NS : constant Boolean :=
        Normalize_Scalars or (Initialize_Scalars and Consider_IS);

   begin
      --  Never need initialization if it is suppressed

      if Initialization_Suppressed (Typ) then
         return False;
      end if;

      --  Check for private type, in which case test applies to the underlying
      --  type of the private type.

      if Is_Private_Type (Typ) then
         declare
            RT : constant Entity_Id := Underlying_Type (Typ);
         begin
            if Present (RT) then
               return Needs_Simple_Initialization (RT);
            else
               return False;
            end if;
         end;

      --  Scalar type with Default_Value aspect requires initialization

      elsif Is_Scalar_Type (Typ) and then Has_Default_Aspect (Typ) then
         return True;

      --  Cases needing simple initialization are access types, and, if pragma
      --  Normalize_Scalars or Initialize_Scalars is in effect, then all scalar
      --  types.

      elsif Is_Access_Type (Typ)
        or else (Consider_IS_NS and then Is_Scalar_Type (Typ))
      then
         return True;

      --  If Initialize/Normalize_Scalars is in effect, string objects also
      --  need initialization, unless they are created in the course of
      --  expanding an aggregate (since in the latter case they will be
      --  filled with appropriate initializing values before they are used).

      elsif Consider_IS_NS
        and then Is_Standard_String_Type (Typ)
        and then
          (not Is_Itype (Typ)
            or else Nkind (Associated_Node_For_Itype (Typ)) /= N_Aggregate)
      then
         return True;

      else
         return False;
      end if;
   end Needs_Simple_Initialization;

   -------------------------------------
   -- Needs_Variable_Reference_Marker --
   -------------------------------------

   function Needs_Variable_Reference_Marker
     (N        : Node_Id;
      Calls_OK : Boolean) return Boolean
   is
      function Within_Suitable_Context (Ref : Node_Id) return Boolean;
      --  Deteremine whether variable reference Ref appears within a suitable
      --  context that allows the creation of a marker.

      -----------------------------
      -- Within_Suitable_Context --
      -----------------------------

      function Within_Suitable_Context (Ref : Node_Id) return Boolean is
         Par : Node_Id;

      begin
         Par := Ref;
         while Present (Par) loop

            --  The context is not suitable when the reference appears within
            --  the formal part of an instantiation which acts as compilation
            --  unit because there is no proper list for the insertion of the
            --  marker.

            if Nkind (Par) = N_Generic_Association
              and then Nkind (Parent (Par)) in N_Generic_Instantiation
              and then Nkind (Parent (Parent (Par))) = N_Compilation_Unit
            then
               return False;

            --  The context is not suitable when the reference appears within
            --  a pragma. If the pragma has run-time semantics, the reference
            --  will be reconsidered once the pragma is expanded.

            elsif Nkind (Par) = N_Pragma then
               return False;

            --  The context is not suitable when the reference appears within a
            --  subprogram call, and the caller requests this behavior.

            elsif not Calls_OK
              and then Nkind (Par) in N_Entry_Call_Statement
                                    | N_Function_Call
                                    | N_Procedure_Call_Statement
            then
               return False;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);
         end loop;

         return True;
      end Within_Suitable_Context;

      --  Local variables

      Prag   : Node_Id;
      Var_Id : Entity_Id;

   --  Start of processing for Needs_Variable_Reference_Marker

   begin
      --  No marker needs to be created when switch -gnatH (legacy elaboration
      --  checking mode enabled) is in effect because the legacy ABE mechanism
      --  does not use markers.

      if Legacy_Elaboration_Checks then
         return False;

      --  No marker needs to be created when the reference is preanalyzed
      --  because the marker will be inserted in the wrong place.

      elsif Preanalysis_Active then
         return False;

      --  Only references warrant a marker

      elsif Nkind (N) not in N_Expanded_Name | N_Identifier then
         return False;

      --  Only source references warrant a marker

      elsif not Comes_From_Source (N) then
         return False;

      --  No marker needs to be created when the reference is erroneous, left
      --  in a bad state, or does not denote a variable.

      elsif not (Present (Entity (N))
                  and then Ekind (Entity (N)) = E_Variable
                  and then Entity (N) /= Any_Id)
      then
         return False;
      end if;

      Var_Id := Entity (N);
      Prag   := SPARK_Pragma (Var_Id);

      --  Both the variable and reference must appear in SPARK_Mode On regions
      --  because this elaboration scenario falls under the SPARK rules.

      if not (Comes_From_Source (Var_Id)
               and then Present (Prag)
               and then Get_SPARK_Mode_From_Annotation (Prag) = On
               and then Is_SPARK_Mode_On_Node (N))
      then
         return False;

      --  No marker needs to be created when the reference does not appear
      --  within a suitable context (see body for details).

      --  Performance note: parent traversal

      elsif not Within_Suitable_Context (N) then
         return False;
      end if;

      --  At this point it is known that the variable reference will play a
      --  role in ABE diagnostics and requires a marker.

      return True;
   end Needs_Variable_Reference_Marker;

   ------------------------
   -- New_Copy_List_Tree --
   ------------------------

   function New_Copy_List_Tree (List : List_Id) return List_Id is
      NL : List_Id;
      E  : Node_Id;

   begin
      if List = No_List then
         return No_List;

      else
         NL := New_List;
         E := First (List);

         while Present (E) loop
            Append (New_Copy_Tree (E), NL);
            Next (E);
         end loop;

         return NL;
      end if;
   end New_Copy_List_Tree;

   -------------------
   -- New_Copy_Tree --
   -------------------

   --  The following tables play a key role in replicating entities and Itypes.
   --  They are intentionally declared at the library level rather than within
   --  New_Copy_Tree to avoid elaborating them on each call. This performance
   --  optimization saves up to 2% of the entire compilation time spent in the
   --  front end. Care should be taken to reset the tables on each new call to
   --  New_Copy_Tree.

   NCT_Table_Max : constant := 511;

   subtype NCT_Table_Index is Nat range 0 .. NCT_Table_Max - 1;

   function NCT_Table_Hash (Key : Node_Or_Entity_Id) return NCT_Table_Index;
   --  Obtain the hash value of node or entity Key

   --------------------
   -- NCT_Table_Hash --
   --------------------

   function NCT_Table_Hash (Key : Node_Or_Entity_Id) return NCT_Table_Index is
   begin
      return NCT_Table_Index (Key mod NCT_Table_Max);
   end NCT_Table_Hash;

   ----------------------
   -- NCT_New_Entities --
   ----------------------

   --  The following table maps old entities and Itypes to their corresponding
   --  new entities and Itypes.

   --    Aaa -> Xxx

   package NCT_New_Entities is new Simple_HTable (
     Header_Num => NCT_Table_Index,
     Element    => Entity_Id,
     No_Element => Empty,
     Key        => Entity_Id,
     Hash       => NCT_Table_Hash,
     Equal      => "=");

   ------------------------
   -- NCT_Pending_Itypes --
   ------------------------

   --  The following table maps old Associated_Node_For_Itype nodes to a set of
   --  new itypes. Given a set of old Itypes Aaa, Bbb, and Ccc, where all three
   --  have the same Associated_Node_For_Itype Ppp, and their corresponding new
   --  Itypes Xxx, Yyy, Zzz, the table contains the following mapping:

   --    Ppp -> (Xxx, Yyy, Zzz)

   --  The set is expressed as an Elist

   package NCT_Pending_Itypes is new Simple_HTable (
     Header_Num => NCT_Table_Index,
     Element    => Elist_Id,
     No_Element => No_Elist,
     Key        => Node_Id,
     Hash       => NCT_Table_Hash,
     Equal      => "=");

   NCT_Tables_In_Use : Boolean := False;
   --  This flag keeps track of whether the two tables NCT_New_Entities and
   --  NCT_Pending_Itypes are in use. The flag is part of an optimization
   --  where certain operations are not performed if the tables are not in
   --  use. This saves up to 8% of the entire compilation time spent in the
   --  front end.

   -------------------
   -- New_Copy_Tree --
   -------------------

   function New_Copy_Tree
     (Source    : Node_Id;
      Map       : Elist_Id   := No_Elist;
      New_Sloc  : Source_Ptr := No_Location;
      New_Scope : Entity_Id  := Empty) return Node_Id
   is
      --  This routine performs low-level tree manipulations and needs access
      --  to the internals of the tree.

      EWA_Level : Nat := 0;
      --  This counter keeps track of how many N_Expression_With_Actions nodes
      --  are encountered during a depth-first traversal of the subtree. These
      --  nodes may define new entities in their Actions lists and thus require
      --  special processing.

      EWA_Inner_Scope_Level : Nat := 0;
      --  This counter keeps track of how many scoping constructs appear within
      --  an N_Expression_With_Actions node.

      procedure Add_New_Entity (Old_Id : Entity_Id; New_Id : Entity_Id);
      pragma Inline (Add_New_Entity);
      --  Add an entry in the NCT_New_Entities table which maps key Old_Id to
      --  value New_Id. Old_Id is an entity which appears within the Actions
      --  list of an N_Expression_With_Actions node, or within an entity map.
      --  New_Id is the corresponding new entity generated during Phase 1.

      procedure Add_Pending_Itype (Assoc_Nod : Node_Id; Itype : Entity_Id);
      pragma Inline (Add_Pending_Itype);
      --  Add an entry in the NCT_Pending_Itypes which maps key Assoc_Nod to
      --  value Itype. Assoc_Nod is the associated node of an itype. Itype is
      --  an itype.

      procedure Build_NCT_Tables (Entity_Map : Elist_Id);
      pragma Inline (Build_NCT_Tables);
      --  Populate tables NCT_New_Entities and NCT_Pending_Itypes with the
      --  information supplied in entity map Entity_Map. The format of the
      --  entity map must be as follows:
      --
      --    Old_Id1, New_Id1, Old_Id2, New_Id2, .., Old_IdN, New_IdN

      function Copy_Any_Node_With_Replacement
        (N : Node_Or_Entity_Id) return Node_Or_Entity_Id;
      pragma Inline (Copy_Any_Node_With_Replacement);
      --  Replicate entity or node N by invoking one of the following routines:
      --
      --    Copy_Node_With_Replacement
      --    Corresponding_Entity

      function Copy_Elist_With_Replacement (List : Elist_Id) return Elist_Id;
      --  Replicate the elements of entity list List

      function Copy_Field_With_Replacement
        (Field    : Union_Id;
         Old_Par  : Node_Id := Empty;
         New_Par  : Node_Id := Empty;
         Semantic : Boolean := False) return Union_Id;
      --  Replicate field Field by invoking one of the following routines:
      --
      --    Copy_Elist_With_Replacement
      --    Copy_List_With_Replacement
      --    Copy_Node_With_Replacement
      --    Corresponding_Entity
      --
      --  If the field is not an entity list, entity, itype, syntactic list,
      --  or node, then the field is returned unchanged. The routine always
      --  replicates entities, itypes, and valid syntactic fields. Old_Par is
      --  the expected parent of a syntactic field. New_Par is the new parent
      --  associated with a replicated syntactic field. Flag Semantic should
      --  be set when the input is a semantic field.

      function Copy_List_With_Replacement (List : List_Id) return List_Id;
      --  Replicate the elements of syntactic list List

      function Copy_Node_With_Replacement (N : Node_Id) return Node_Id;
      --  Replicate node N

      function Corresponding_Entity (Id : Entity_Id) return Entity_Id;
      pragma Inline (Corresponding_Entity);
      --  Return the corresponding new entity of Id generated during Phase 1.
      --  If there is no such entity, return Id.

      function In_Entity_Map
        (Id         : Entity_Id;
         Entity_Map : Elist_Id) return Boolean;
      pragma Inline (In_Entity_Map);
      --  Determine whether entity Id is one of the old ids specified in entity
      --  map Entity_Map. The format of the entity map must be as follows:
      --
      --    Old_Id1, New_Id1, Old_Id2, New_Id2, .., Old_IdN, New_IdN

      procedure Update_CFS_Sloc (N : Node_Or_Entity_Id);
      pragma Inline (Update_CFS_Sloc);
      --  Update the Comes_From_Source and Sloc attributes of node or entity N

      procedure Update_Controlling_Argument
        (Old_Call : Node_Id;
         New_Call : Node_Id);
      pragma Inline (Update_Controlling_Argument);
      --  Update Controlling_Argument of New_Call base on Old_Call to make it
      --  points to the corresponding newly copied actual parameter.

      procedure Update_Named_Associations
        (Old_Call : Node_Id;
         New_Call : Node_Id);
      pragma Inline (Update_Named_Associations);
      --  Update semantic chain First/Next_Named_Association of call New_call
      --  based on call Old_Call.

      procedure Update_New_Entities (Entity_Map : Elist_Id);
      pragma Inline (Update_New_Entities);
      --  Update the semantic attributes of all new entities generated during
      --  Phase 1 that do not appear in entity map Entity_Map. The format of
      --  the entity map must be as follows:
      --
      --    Old_Id1, New_Id1, Old_Id2, New_Id2, .., Old_IdN, New_IdN

      procedure Update_Pending_Itypes
        (Old_Assoc : Node_Id;
         New_Assoc : Node_Id);
      pragma Inline (Update_Pending_Itypes);
      --  Update semantic attribute Associated_Node_For_Itype to refer to node
      --  New_Assoc for all itypes whose associated node is Old_Assoc.

      procedure Update_Semantic_Fields (Id : Entity_Id);
      pragma Inline (Update_Semantic_Fields);
      --  Subsidiary to Update_New_Entities. Update semantic fields of entity
      --  or itype Id.

      procedure Visit_Any_Node (N : Node_Or_Entity_Id);
      pragma Inline (Visit_Any_Node);
      --  Visit entity of node N by invoking one of the following routines:
      --
      --    Visit_Entity
      --    Visit_Itype
      --    Visit_Node

      procedure Visit_Elist (List : Elist_Id);
      --  Visit the elements of entity list List

      procedure Visit_Entity (Id : Entity_Id);
      --  Visit entity Id. This action may create a new entity of Id and save
      --  it in table NCT_New_Entities.

      procedure Visit_Field
        (Field    : Union_Id;
         Par_Nod  : Node_Id := Empty;
         Semantic : Boolean := False);
      --  Visit field Field by invoking one of the following routines:
      --
      --    Visit_Elist
      --    Visit_Entity
      --    Visit_Itype
      --    Visit_List
      --    Visit_Node
      --
      --  If the field is not an entity list, entity, itype, syntactic list,
      --  or node, then the field is not visited. The routine always visits
      --  valid syntactic fields. Par_Nod is the expected parent of the
      --  syntactic field. Flag Semantic should be set when the input is a
      --  semantic field.

      procedure Visit_Itype (Itype : Entity_Id);
      --  Visit itype Itype. This action may create a new entity for Itype and
      --  save it in table NCT_New_Entities. In addition, the routine may map
      --  the associated node of Itype to the new itype in NCT_Pending_Itypes.

      procedure Visit_List (List : List_Id);
      --  Visit the elements of syntactic list List

      procedure Visit_Node (N : Node_Id);
      --  Visit node N

      procedure Visit_Semantic_Fields (Id : Entity_Id);
      pragma Inline (Visit_Semantic_Fields);
      --  Subsidiary to Visit_Entity and Visit_Itype. Visit common semantic
      --  fields of entity or itype Id.

      --------------------
      -- Add_New_Entity --
      --------------------

      procedure Add_New_Entity (Old_Id : Entity_Id; New_Id : Entity_Id) is
      begin
         pragma Assert (Present (Old_Id));
         pragma Assert (Present (New_Id));
         pragma Assert (Nkind (Old_Id) in N_Entity);
         pragma Assert (Nkind (New_Id) in N_Entity);

         NCT_Tables_In_Use := True;

         --  Sanity check the NCT_New_Entities table. No previous mapping with
         --  key Old_Id should exist.

         pragma Assert (No (NCT_New_Entities.Get (Old_Id)));

         --  Establish the mapping

         --    Old_Id -> New_Id

         NCT_New_Entities.Set (Old_Id, New_Id);
      end Add_New_Entity;

      -----------------------
      -- Add_Pending_Itype --
      -----------------------

      procedure Add_Pending_Itype (Assoc_Nod : Node_Id; Itype : Entity_Id) is
         Itypes : Elist_Id;

      begin
         pragma Assert (Present (Assoc_Nod));
         pragma Assert (Present (Itype));
         pragma Assert (Nkind (Itype) in N_Entity);
         pragma Assert (Is_Itype (Itype));

         NCT_Tables_In_Use := True;

         --  It is not possible to sanity check the NCT_Pendint_Itypes table
         --  directly because a single node may act as the associated node for
         --  multiple itypes.

         Itypes := NCT_Pending_Itypes.Get (Assoc_Nod);

         if No (Itypes) then
            Itypes := New_Elmt_List;
            NCT_Pending_Itypes.Set (Assoc_Nod, Itypes);
         end if;

         --  Establish the mapping

         --    Assoc_Nod -> (Itype, ...)

         --  Avoid inserting the same itype multiple times. This involves a
         --  linear search, however the set of itypes with the same associated
         --  node is very small.

         Append_Unique_Elmt (Itype, Itypes);
      end Add_Pending_Itype;

      ----------------------
      -- Build_NCT_Tables --
      ----------------------

      procedure Build_NCT_Tables (Entity_Map : Elist_Id) is
         Elmt   : Elmt_Id;
         Old_Id : Entity_Id;
         New_Id : Entity_Id;

      begin
         --  Nothing to do when there is no entity map

         if No (Entity_Map) then
            return;
         end if;

         Elmt := First_Elmt (Entity_Map);
         while Present (Elmt) loop

            --  Extract the (Old_Id, New_Id) pair from the entity map

            Old_Id := Node (Elmt);
            Next_Elmt (Elmt);

            New_Id := Node (Elmt);
            Next_Elmt (Elmt);

            --  Establish the following mapping within table NCT_New_Entities

            --    Old_Id -> New_Id

            Add_New_Entity (Old_Id, New_Id);

            --  Establish the following mapping within table NCT_Pending_Itypes
            --  when the new entity is an itype.

            --    Assoc_Nod -> (New_Id, ...)

            --  IMPORTANT: the associated node is that of the old itype because
            --  the node will be replicated in Phase 2.

            if Is_Itype (Old_Id) then
               Add_Pending_Itype
                 (Assoc_Nod => Associated_Node_For_Itype (Old_Id),
                  Itype     => New_Id);
            end if;
         end loop;
      end Build_NCT_Tables;

      ------------------------------------
      -- Copy_Any_Node_With_Replacement --
      ------------------------------------

      function Copy_Any_Node_With_Replacement
        (N : Node_Or_Entity_Id) return Node_Or_Entity_Id
      is
      begin
         if Nkind (N) in N_Entity then
            return Corresponding_Entity (N);
         else
            return Copy_Node_With_Replacement (N);
         end if;
      end Copy_Any_Node_With_Replacement;

      ---------------------------------
      -- Copy_Elist_With_Replacement --
      ---------------------------------

      function Copy_Elist_With_Replacement (List : Elist_Id) return Elist_Id is
         Elmt   : Elmt_Id;
         Result : Elist_Id;

      begin
         --  Copy the contents of the old list. Note that the list itself may
         --  be empty, in which case the routine returns a new empty list. This
         --  avoids sharing lists between subtrees. The element of an entity
         --  list could be an entity or a node, hence the invocation of routine
         --  Copy_Any_Node_With_Replacement.

         if Present (List) then
            Result := New_Elmt_List;

            Elmt := First_Elmt (List);
            while Present (Elmt) loop
               Append_Elmt
                 (Copy_Any_Node_With_Replacement (Node (Elmt)), Result);

               Next_Elmt (Elmt);
            end loop;

         --  Otherwise the list does not exist

         else
            Result := No_Elist;
         end if;

         return Result;
      end Copy_Elist_With_Replacement;

      ---------------------------------
      -- Copy_Field_With_Replacement --
      ---------------------------------

      function Copy_Field_With_Replacement
        (Field    : Union_Id;
         Old_Par  : Node_Id := Empty;
         New_Par  : Node_Id := Empty;
         Semantic : Boolean := False) return Union_Id
      is
      begin
         --  The field is empty

         if Field = Union_Id (Empty) then
            return Field;

         --  The field is an entity/itype/node

         elsif Field in Node_Range then
            declare
               Old_N     : constant Node_Id := Node_Id (Field);
               Syntactic : constant Boolean :=
                 Is_Syntactic_Node (Source => Old_Par, Field => Old_N);

               New_N : Node_Id;

            begin
               --  The field is an entity/itype

               if Nkind (Old_N) in N_Entity then

                  --  An entity/itype is always replicated

                  New_N := Corresponding_Entity (Old_N);

                  --  Update the parent pointer when the entity is a syntactic
                  --  field. Note that itypes do not have parent pointers.

                  if Syntactic and then New_N /= Old_N then
                     Set_Parent (New_N, New_Par);
                  end if;

               --  The field is a node

               else
                  --  A node is replicated when it is either a syntactic field
                  --  or when the caller treats it as a semantic attribute.

                  if Syntactic or else Semantic then
                     New_N := Copy_Node_With_Replacement (Old_N);

                     --  Update the parent pointer when the node is a syntactic
                     --  field.

                     if Syntactic and then New_N /= Old_N then
                        Set_Parent (New_N, New_Par);
                     end if;

                  --  Otherwise the node is returned unchanged

                  else
                     New_N := Old_N;
                  end if;
               end if;

               return Union_Id (New_N);
            end;

         --  The field is an entity list

         elsif Field in Elist_Range then
            return Union_Id (Copy_Elist_With_Replacement (Elist_Id (Field)));

         --  The field is a syntactic list

         elsif Field in List_Range then
            declare
               Old_List  : constant List_Id := List_Id (Field);
               Syntactic : constant Boolean := Parent (Old_List) = Old_Par;

               New_List : List_Id;

            begin
               --  A list is replicated when it is either a syntactic field or
               --  when the caller treats it as a semantic attribute.

               if Syntactic or else Semantic then
                  New_List := Copy_List_With_Replacement (Old_List);

                  --  Update the parent pointer when the list is a syntactic
                  --  field.

                  if Syntactic and then New_List /= Old_List then
                     Set_Parent (New_List, New_Par);
                  end if;

               --  Otherwise the list is returned unchanged

               else
                  New_List := Old_List;
               end if;

               return Union_Id (New_List);
            end;

         --  Otherwise the field denotes an attribute that does not need to be
         --  replicated (Chars, literals, etc).

         else
            return Field;
         end if;
      end Copy_Field_With_Replacement;

      --------------------------------
      -- Copy_List_With_Replacement --
      --------------------------------

      function Copy_List_With_Replacement (List : List_Id) return List_Id is
         Elmt   : Node_Id;
         Result : List_Id;

      begin
         --  Copy the contents of the old list. Note that the list itself may
         --  be empty, in which case the routine returns a new empty list. This
         --  avoids sharing lists between subtrees. The element of a syntactic
         --  list is always a node, never an entity or itype, hence the call to
         --  routine Copy_Node_With_Replacement.

         if Present (List) then
            Result := New_List;

            Elmt := First (List);
            while Present (Elmt) loop
               Append (Copy_Node_With_Replacement (Elmt), Result);

               Next (Elmt);
            end loop;

         --  Otherwise the list does not exist

         else
            Result := No_List;
         end if;

         return Result;
      end Copy_List_With_Replacement;

      --------------------------------
      -- Copy_Node_With_Replacement --
      --------------------------------

      function Copy_Node_With_Replacement (N : Node_Id) return Node_Id is
         Result : Node_Id;

         function Transform (U : Union_Id) return Union_Id;
         --  Copies one field, replacing N with Result

         ---------------
         -- Transform --
         ---------------

         function Transform (U : Union_Id) return Union_Id is
         begin
            return Copy_Field_With_Replacement
                     (Field   => U,
                      Old_Par => N,
                      New_Par => Result);
         end Transform;

         procedure Walk is new Walk_Sinfo_Fields_Pairwise (Transform);

      --  Start of processing for Copy_Node_With_Replacement

      begin
         --  Assume that the node must be returned unchanged

         Result := N;

         if N > Empty_Or_Error then
            pragma Assert (Nkind (N) not in N_Entity);

            Result := New_Copy (N);

            Walk (Result, Result);

            --  Update the Comes_From_Source and Sloc attributes of the node
            --  in case the caller has supplied new values.

            Update_CFS_Sloc (Result);

            --  Update the Associated_Node_For_Itype attribute of all itypes
            --  created during Phase 1 whose associated node is N. As a result
            --  the Associated_Node_For_Itype refers to the replicated node.
            --  No action needs to be taken when the Associated_Node_For_Itype
            --  refers to an entity because this was already handled during
            --  Phase 1, in Visit_Itype.

            Update_Pending_Itypes
              (Old_Assoc => N,
               New_Assoc => Result);

            --  Update the First/Next_Named_Association chain and the
            --  Controlling_Argument for a replicated call.

            if Nkind (N) in N_Entry_Call_Statement
                          | N_Subprogram_Call
            then
               Update_Named_Associations
                 (Old_Call => N,
                  New_Call => Result);

               if Nkind (N) in N_Subprogram_Call then
                  Update_Controlling_Argument
                    (Old_Call => N,
                     New_Call => Result);
               end if;

            --  Update the Renamed_Object attribute of a replicated object
            --  declaration.

            elsif Nkind (N) = N_Object_Renaming_Declaration then
               Set_Renamed_Object_Of_Possibly_Void
                 (Defining_Entity (Result), Name (Result));

            --  Update the Chars attribute of identifiers

            elsif Nkind (N) = N_Identifier then

               --  The Entity field of identifiers that denote aspects is used
               --  to store arbitrary expressions (and hence we must check that
               --  they reference an actual entity before copying their Chars
               --  value).

               if Present (Entity (Result))
                 and then Nkind (Entity (Result)) in N_Entity
               then
                  Set_Chars (Result, Chars (Entity (Result)));
               end if;
            end if;

            if Has_Aspects (N) then
               Set_Aspect_Specifications (Result,
                 Copy_List_With_Replacement (Aspect_Specifications (N)));
            end if;
         end if;

         return Result;
      end Copy_Node_With_Replacement;

      --------------------------
      -- Corresponding_Entity --
      --------------------------

      function Corresponding_Entity (Id : Entity_Id) return Entity_Id is
         New_Id : Entity_Id;
         Result : Entity_Id;

      begin
         --  Assume that the entity must be returned unchanged

         Result := Id;

         if Id > Empty_Or_Error then
            pragma Assert (Nkind (Id) in N_Entity);

            --  Determine whether the entity has a corresponding new entity
            --  generated during Phase 1 and if it does, use it.

            if NCT_Tables_In_Use then
               New_Id := NCT_New_Entities.Get (Id);

               if Present (New_Id) then
                  Result := New_Id;
               end if;
            end if;
         end if;

         return Result;
      end Corresponding_Entity;

      -------------------
      -- In_Entity_Map --
      -------------------

      function In_Entity_Map
        (Id         : Entity_Id;
         Entity_Map : Elist_Id) return Boolean
      is
         Elmt   : Elmt_Id;
         Old_Id : Entity_Id;

      begin
         --  The entity map contains pairs (Old_Id, New_Id). The advancement
         --  step always skips the New_Id portion of the pair.

         if Present (Entity_Map) then
            Elmt := First_Elmt (Entity_Map);
            while Present (Elmt) loop
               Old_Id := Node (Elmt);

               if Old_Id = Id then
                  return True;
               end if;

               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
            end loop;
         end if;

         return False;
      end In_Entity_Map;

      ---------------------
      -- Update_CFS_Sloc --
      ---------------------

      procedure Update_CFS_Sloc (N : Node_Or_Entity_Id) is
      begin
         --  A new source location defaults the Comes_From_Source attribute

         if New_Sloc /= No_Location then
            Set_Comes_From_Source (N, Get_Comes_From_Source_Default);
            Set_Sloc              (N, New_Sloc);
         end if;
      end Update_CFS_Sloc;

      ---------------------------------
      -- Update_Controlling_Argument --
      ---------------------------------

      procedure Update_Controlling_Argument
        (Old_Call : Node_Id;
         New_Call : Node_Id)
      is
         New_Act : Node_Id;
         Old_Act : Node_Id;

         Old_Ctrl_Arg : constant Node_Id := Controlling_Argument (Old_Call);
         --  Controlling argument of the old call node

         Replaced : Boolean := False;
         --  Flag to make sure that replacement works as expected

      begin
         if No (Old_Ctrl_Arg) then
            return;
         end if;

         --  Recreate the Controlling_Argument of a call by traversing both the
         --  old and new actual parameters in parallel.

         New_Act := First (Parameter_Associations (New_Call));
         Old_Act := First (Parameter_Associations (Old_Call));
         while Present (Old_Act) loop

            --  Actual parameter appears either in a named parameter
            --  association or directly.

            if Nkind (Old_Act) = N_Parameter_Association then
               if Explicit_Actual_Parameter (Old_Act) = Old_Ctrl_Arg then
                  Set_Controlling_Argument
                    (New_Call, Explicit_Actual_Parameter (New_Act));
                  Replaced := True;
                  exit;
               end if;

            elsif Old_Act = Old_Ctrl_Arg then
               Set_Controlling_Argument (New_Call, New_Act);
               Replaced := True;
               exit;
            end if;

            Next (New_Act);
            Next (Old_Act);
         end loop;

         pragma Assert (Replaced);
      end Update_Controlling_Argument;

      -------------------------------
      -- Update_Named_Associations --
      -------------------------------

      procedure Update_Named_Associations
        (Old_Call : Node_Id;
         New_Call : Node_Id)
      is
         New_Act  : Node_Id;
         New_Next : Node_Id;
         Old_Act  : Node_Id;
         Old_Next : Node_Id;

      begin
         if No (First_Named_Actual (Old_Call)) then
            return;
         end if;

         --  Recreate the First/Next_Named_Actual chain of a call by traversing
         --  the chains of both the old and new calls in parallel.

         New_Act := First (Parameter_Associations (New_Call));
         Old_Act := First (Parameter_Associations (Old_Call));
         while Present (Old_Act) loop
            if Nkind (Old_Act) = N_Parameter_Association
              and then Explicit_Actual_Parameter (Old_Act)
                         = First_Named_Actual (Old_Call)
            then
               Set_First_Named_Actual (New_Call,
                 Explicit_Actual_Parameter (New_Act));
            end if;

            if Nkind (Old_Act) = N_Parameter_Association
              and then Present (Next_Named_Actual (Old_Act))
            then
               --  Scan the actual parameter list to find the next suitable
               --  named actual. Note that the list may be out of order.

               New_Next := First (Parameter_Associations (New_Call));
               Old_Next := First (Parameter_Associations (Old_Call));
               while Nkind (Old_Next) /= N_Parameter_Association
                 or else Explicit_Actual_Parameter (Old_Next) /=
                           Next_Named_Actual (Old_Act)
               loop
                  Next (New_Next);
                  Next (Old_Next);
               end loop;

               Set_Next_Named_Actual (New_Act,
                 Explicit_Actual_Parameter (New_Next));
            end if;

            Next (New_Act);
            Next (Old_Act);
         end loop;
      end Update_Named_Associations;

      -------------------------
      -- Update_New_Entities --
      -------------------------

      procedure Update_New_Entities (Entity_Map : Elist_Id) is
         New_Id : Entity_Id := Empty;
         Old_Id : Entity_Id := Empty;

      begin
         if NCT_Tables_In_Use then
            NCT_New_Entities.Get_First (Old_Id, New_Id);

            --  Update the semantic fields of all new entities created during
            --  Phase 1 which were not supplied via an entity map.
            --  ??? Is there a better way of distinguishing those?

            while Present (Old_Id) and then Present (New_Id) loop
               if not In_Entity_Map (Old_Id, Entity_Map) then
                  Update_Semantic_Fields (New_Id);
               end if;

               NCT_New_Entities.Get_Next (Old_Id, New_Id);
            end loop;
         end if;
      end Update_New_Entities;

      ---------------------------
      -- Update_Pending_Itypes --
      ---------------------------

      procedure Update_Pending_Itypes
        (Old_Assoc : Node_Id;
         New_Assoc : Node_Id)
      is
         Item   : Elmt_Id;
         Itypes : Elist_Id;

      begin
         if NCT_Tables_In_Use then
            Itypes := NCT_Pending_Itypes.Get (Old_Assoc);

            --  Update the Associated_Node_For_Itype attribute for all itypes
            --  which originally refer to Old_Assoc to designate New_Assoc.

            if Present (Itypes) then
               Item := First_Elmt (Itypes);
               while Present (Item) loop
                  Set_Associated_Node_For_Itype (Node (Item), New_Assoc);

                  Next_Elmt (Item);
               end loop;
            end if;
         end if;
      end Update_Pending_Itypes;

      ----------------------------
      -- Update_Semantic_Fields --
      ----------------------------

      procedure Update_Semantic_Fields (Id : Entity_Id) is
      begin
         --  Discriminant_Constraint

         if Is_Type (Id) and then Has_Discriminants (Base_Type (Id)) then
            Set_Discriminant_Constraint (Id, Elist_Id (
              Copy_Field_With_Replacement
                (Field    => Union_Id (Discriminant_Constraint (Id)),
                 Semantic => True)));
         end if;

         --  Etype

         Set_Etype (Id, Node_Id (
           Copy_Field_With_Replacement
             (Field    => Union_Id (Etype (Id)),
              Semantic => True)));

         --  First_Index
         --  Packed_Array_Impl_Type

         if Is_Array_Type (Id) then
            if Present (First_Index (Id)) then
               Set_First_Index (Id, First (List_Id (
                 Copy_Field_With_Replacement
                   (Field    => Union_Id (List_Containing (First_Index (Id))),
                    Semantic => True))));
            end if;

            if Is_Packed (Id) then
               Set_Packed_Array_Impl_Type (Id, Node_Id (
                 Copy_Field_With_Replacement
                   (Field    => Union_Id (Packed_Array_Impl_Type (Id)),
                    Semantic => True)));
            end if;
         end if;

         --  Prev_Entity

         Set_Prev_Entity (Id, Node_Id (
           Copy_Field_With_Replacement
             (Field    => Union_Id (Prev_Entity (Id)),
              Semantic => True)));

         --  Next_Entity

         Set_Next_Entity (Id, Node_Id (
           Copy_Field_With_Replacement
             (Field    => Union_Id (Next_Entity (Id)),
              Semantic => True)));

         --  Scalar_Range

         if Is_Discrete_Type (Id) then
            Set_Scalar_Range (Id, Node_Id (
              Copy_Field_With_Replacement
                (Field    => Union_Id (Scalar_Range (Id)),
                 Semantic => True)));
         end if;

         --  Scope

         --  Update the scope when the caller specified an explicit one

         if Present (New_Scope) then
            Set_Scope (Id, New_Scope);
         else
            Set_Scope (Id, Node_Id (
              Copy_Field_With_Replacement
                (Field    => Union_Id (Scope (Id)),
                 Semantic => True)));
         end if;
      end Update_Semantic_Fields;

      --------------------
      -- Visit_Any_Node --
      --------------------

      procedure Visit_Any_Node (N : Node_Or_Entity_Id) is
      begin
         if Nkind (N) in N_Entity then
            if Is_Itype (N) then
               Visit_Itype (N);
            else
               Visit_Entity (N);
            end if;
         else
            Visit_Node (N);
         end if;
      end Visit_Any_Node;

      -----------------
      -- Visit_Elist --
      -----------------

      procedure Visit_Elist (List : Elist_Id) is
         Elmt : Elmt_Id;

      begin
         --  The element of an entity list could be an entity, itype, or a
         --  node, hence the call to Visit_Any_Node.

         if Present (List) then
            Elmt := First_Elmt (List);
            while Present (Elmt) loop
               Visit_Any_Node (Node (Elmt));

               Next_Elmt (Elmt);
            end loop;
         end if;
      end Visit_Elist;

      ------------------
      -- Visit_Entity --
      ------------------

      procedure Visit_Entity (Id : Entity_Id) is
         New_Id : Entity_Id;

      begin
         pragma Assert (Nkind (Id) in N_Entity);
         pragma Assert (not Is_Itype (Id));

         --  Nothing to do when the entity is not defined in the Actions list
         --  of an N_Expression_With_Actions node.

         if EWA_Level = 0 then
            return;

         --  Nothing to do when the entity is defined in a scoping construct
         --  within an N_Expression_With_Actions node.

         elsif EWA_Inner_Scope_Level > 0 then
            return;

         --  Nothing to do when the entity does not denote a construct that
         --  may appear within an N_Expression_With_Actions node. Relaxing
         --  this restriction leads to a performance penalty.

         --  ??? this list is flaky, and may hide dormant bugs
         --  Should functions be included???

         --  Quantified expressions contain an entity declaration that must
         --  always be replaced when the expander is active, even if it has
         --  not been analyzed yet like e.g. in predicates.

         elsif Ekind (Id) not in E_Block
                               | E_Constant
                               | E_Label
                               | E_Procedure
                               | E_Variable
           and then not Is_Entity_Of_Quantified_Expression (Id)
           and then not Is_Type (Id)
         then
            return;

         --  Nothing to do when the entity was already visited

         elsif NCT_Tables_In_Use
           and then Present (NCT_New_Entities.Get (Id))
         then
            return;

         --  Nothing to do when the declaration node of the entity is not in
         --  the subtree being replicated.

         elsif not In_Subtree
                     (N    => Declaration_Node (Id),
                      Root => Source)
         then
            return;
         end if;

         --  Create a new entity by directly copying the old entity. This
         --  action causes all attributes of the old entity to be inherited.

         New_Id := New_Copy (Id);

         --  Create a new name for the new entity because the back end needs
         --  distinct names for debugging purposes, provided that the entity
         --  has already been analyzed.

         if Ekind (Id) /= E_Void then
            Set_Chars (New_Id, New_Internal_Name ('T'));
         end if;

         --  Update the Comes_From_Source and Sloc attributes of the entity in
         --  case the caller has supplied new values.

         Update_CFS_Sloc (New_Id);

         --  Establish the following mapping within table NCT_New_Entities:

         --    Id -> New_Id

         Add_New_Entity (Id, New_Id);

         --  Deal with the semantic fields of entities. The fields are visited
         --  because they may mention entities which reside within the subtree
         --  being copied.

         Visit_Semantic_Fields (Id);
      end Visit_Entity;

      -----------------
      -- Visit_Field --
      -----------------

      procedure Visit_Field
        (Field    : Union_Id;
         Par_Nod  : Node_Id := Empty;
         Semantic : Boolean := False)
      is
      begin
         --  The field is empty

         if Field = Union_Id (Empty) then
            return;

         --  The field is an entity/itype/node

         elsif Field in Node_Range then
            declare
               N : constant Node_Id := Node_Id (Field);

            begin
               --  The field is an entity/itype

               if Nkind (N) in N_Entity then

                  --  Itypes are always visited

                  if Is_Itype (N) then
                     Visit_Itype (N);

                  --  An entity is visited when it is either a syntactic field
                  --  or when the caller treats it as a semantic attribute.

                  elsif Parent (N) = Par_Nod or else Semantic then
                     Visit_Entity (N);
                  end if;

               --  The field is a node

               else
                  --  A node is visited when it is either a syntactic field or
                  --  when the caller treats it as a semantic attribute.

                  if Parent (N) = Par_Nod or else Semantic then
                     Visit_Node (N);
                  end if;
               end if;
            end;

         --  The field is an entity list

         elsif Field in Elist_Range then
            Visit_Elist (Elist_Id (Field));

         --  The field is a syntax list

         elsif Field in List_Range then
            declare
               List : constant List_Id := List_Id (Field);

            begin
               --  A syntax list is visited when it is either a syntactic field
               --  or when the caller treats it as a semantic attribute.

               if Parent (List) = Par_Nod or else Semantic then
                  Visit_List (List);
               end if;
            end;

         --  Otherwise the field denotes information which does not need to be
         --  visited (chars, literals, etc.).

         else
            null;
         end if;
      end Visit_Field;

      -----------------
      -- Visit_Itype --
      -----------------

      procedure Visit_Itype (Itype : Entity_Id) is
         New_Assoc : Node_Id;
         New_Itype : Entity_Id;
         Old_Assoc : Node_Id;

      begin
         pragma Assert (Nkind (Itype) in N_Entity);
         pragma Assert (Is_Itype (Itype));

         --  Itypes that describe the designated type of access to subprograms
         --  have the structure of subprogram declarations, with signatures,
         --  etc. Either we duplicate the signatures completely, or choose to
         --  share such itypes, which is fine because their elaboration will
         --  have no side effects.

         if Ekind (Itype) = E_Subprogram_Type then
            return;

         --  Nothing to do if the itype was already visited

         elsif NCT_Tables_In_Use
           and then Present (NCT_New_Entities.Get (Itype))
         then
            return;

         --  Nothing to do if the associated node of the itype is not within
         --  the subtree being replicated.

         elsif not In_Subtree
                     (N    => Associated_Node_For_Itype (Itype),
                      Root => Source)
         then
            return;
         end if;

         --  Create a new itype by directly copying the old itype. This action
         --  causes all attributes of the old itype to be inherited.

         New_Itype := New_Copy (Itype);

         --  Create a new name for the new itype because the back end requires
         --  distinct names for debugging purposes.

         Set_Chars (New_Itype, New_Internal_Name ('T'));

         --  Update the Comes_From_Source and Sloc attributes of the itype in
         --  case the caller has supplied new values.

         Update_CFS_Sloc (New_Itype);

         --  Establish the following mapping within table NCT_New_Entities:

         --    Itype -> New_Itype

         Add_New_Entity (Itype, New_Itype);

         --  The new itype must be unfrozen because the resulting subtree may
         --  be inserted anywhere and cause an earlier or later freezing.

         if Present (Freeze_Node (New_Itype)) then
            Set_Freeze_Node (New_Itype, Empty);
            Set_Is_Frozen   (New_Itype, False);
         end if;

         --  If a record subtype is simply copied, the entity list will be
         --  shared, so Cloned_Subtype must be set to indicate this.

         if Ekind (Itype) in E_Class_Wide_Subtype | E_Record_Subtype then
            Set_Cloned_Subtype (New_Itype, Itype);
         end if;

         --  The associated node may denote an entity, in which case it may
         --  already have a new corresponding entity created during a prior
         --  call to Visit_Entity or Visit_Itype for the same subtree.

         --    Given
         --       Old_Assoc ---------> New_Assoc

         --    Created by Visit_Itype
         --       Itype -------------> New_Itype
         --       ANFI = Old_Assoc     ANFI = Old_Assoc  <  must be updated

         --  In the example above, Old_Assoc is an arbitrary entity that was
         --  already visited for the same subtree and has a corresponding new
         --  entity New_Assoc. Old_Assoc was inherited by New_Itype by virtue
         --  of copying entities, however it must be updated to New_Assoc.

         Old_Assoc := Associated_Node_For_Itype (Itype);

         if Nkind (Old_Assoc) in N_Entity then
            if NCT_Tables_In_Use then
               New_Assoc := NCT_New_Entities.Get (Old_Assoc);

               if Present (New_Assoc) then
                  Set_Associated_Node_For_Itype (New_Itype, New_Assoc);
               end if;
            end if;

         --  Otherwise the associated node denotes a node. Postpone the update
         --  until Phase 2 when the node is replicated. Establish the following
         --  mapping within table NCT_Pending_Itypes:

         --    Old_Assoc -> (New_Type, ...)

         else
            Add_Pending_Itype (Old_Assoc, New_Itype);
         end if;

         --  Deal with the semantic fields of itypes. The fields are visited
         --  because they may mention entities that reside within the subtree
         --  being copied.

         Visit_Semantic_Fields (Itype);
      end Visit_Itype;

      ----------------
      -- Visit_List --
      ----------------

      procedure Visit_List (List : List_Id) is
         Elmt : Node_Id;

      begin
         --  Note that the element of a syntactic list is always a node, never
         --  an entity or itype, hence the call to Visit_Node.

         Elmt := First (List);
         while Present (Elmt) loop
            Visit_Node (Elmt);

            Next (Elmt);
         end loop;
      end Visit_List;

      ----------------
      -- Visit_Node --
      ----------------

      procedure Visit_Node (N : Node_Id) is
      begin
         pragma Assert (Nkind (N) not in N_Entity);

         --  If the node is a quantified expression and expander is active,
         --  it contains an implicit declaration that may require a new entity
         --  when the condition has already been (pre)analyzed.

         if Nkind (N) = N_Expression_With_Actions
           or else
             (Nkind (N) = N_Quantified_Expression and then Expander_Active)
         then
            EWA_Level := EWA_Level + 1;

         elsif EWA_Level > 0
           and then Nkind (N) in N_Block_Statement
                               | N_Subprogram_Body
                               | N_Subprogram_Declaration
         then
            EWA_Inner_Scope_Level := EWA_Inner_Scope_Level + 1;
         end if;

         --  If the node is a block, we need to process all declarations
         --  in the block and make new entities for each.

         if Nkind (N) = N_Block_Statement then
            declare
               Decl : Node_Id := First (Declarations (N));

            begin
               while Present (Decl) loop
                  if Nkind (Decl) = N_Object_Declaration then
                     Add_New_Entity (Defining_Identifier (Decl),
                                     New_Copy (Defining_Identifier (Decl)));
                  end if;

                  Next (Decl);
               end loop;
            end;
         end if;

         declare
            procedure Action (U : Union_Id);
            procedure Action (U : Union_Id) is
            begin
               Visit_Field (Field => U, Par_Nod => N);
            end Action;

            procedure Walk is new Walk_Sinfo_Fields (Action);
         begin
            Walk (N);
         end;

         if EWA_Level > 0
           and then Nkind (N) in N_Block_Statement
                               | N_Subprogram_Body
                               | N_Subprogram_Declaration
         then
            EWA_Inner_Scope_Level := EWA_Inner_Scope_Level - 1;

         elsif Nkind (N) = N_Expression_With_Actions
           or else
             (Nkind (N) = N_Quantified_Expression and then Expander_Active)
         then
            EWA_Level := EWA_Level - 1;
         end if;
      end Visit_Node;

      ---------------------------
      -- Visit_Semantic_Fields --
      ---------------------------

      procedure Visit_Semantic_Fields (Id : Entity_Id) is
      begin
         pragma Assert (Nkind (Id) in N_Entity);

         --  Discriminant_Constraint

         if Is_Type (Id) and then Has_Discriminants (Base_Type (Id)) then
            Visit_Field
              (Field    => Union_Id (Discriminant_Constraint (Id)),
               Semantic => True);
         end if;

         --  Etype

         Visit_Field
           (Field    => Union_Id (Etype (Id)),
            Semantic => True);

         --  First_Index
         --  Packed_Array_Impl_Type

         if Is_Array_Type (Id) then
            if Present (First_Index (Id)) then
               Visit_Field
                 (Field    => Union_Id (List_Containing (First_Index (Id))),
                  Semantic => True);
            end if;

            if Is_Packed (Id) then
               Visit_Field
                 (Field    => Union_Id (Packed_Array_Impl_Type (Id)),
                  Semantic => True);
            end if;
         end if;

         --  Scalar_Range

         if Is_Discrete_Type (Id) then
            Visit_Field
              (Field    => Union_Id (Scalar_Range (Id)),
               Semantic => True);
         end if;
      end Visit_Semantic_Fields;

   --  Start of processing for New_Copy_Tree

   begin
      --  Routine New_Copy_Tree performs a deep copy of a subtree by creating
      --  shallow copies for each node within, and then updating the child and
      --  parent pointers accordingly. This process is straightforward, however
      --  the routine must deal with the following complications:

      --    * Entities defined within N_Expression_With_Actions nodes must be
      --      replicated rather than shared to avoid introducing two identical
      --      symbols within the same scope. Note that no other expression can
      --      currently define entities.

      --        do
      --           Source_Low  : ...;
      --           Source_High : ...;

      --           <reference to Source_Low>
      --           <reference to Source_High>
      --        in ... end;

      --      New_Copy_Tree handles this case by first creating new entities
      --      and then updating all existing references to point to these new
      --      entities.

      --        do
      --           New_Low  : ...;
      --           New_High : ...;

      --           <reference to New_Low>
      --           <reference to New_High>
      --        in ... end;

      --    * Itypes defined within the subtree must be replicated to avoid any
      --      dependencies on invalid or inaccessible data.

      --        subtype Source_Itype is ... range Source_Low .. Source_High;

      --      New_Copy_Tree handles this case by first creating a new itype in
      --      the same fashion as entities, and then updating various relevant
      --      constraints.

      --        subtype New_Itype is ... range New_Low .. New_High;

      --    * The Associated_Node_For_Itype field of itypes must be updated to
      --      reference the proper replicated entity or node.

      --    * Semantic fields of entities such as Etype and Scope must be
      --      updated to reference the proper replicated entities.

      --    * Some semantic fields of nodes must be updated to reference
      --      the proper replicated nodes.

      --  Finally, quantified expressions contain an implicit declaration for
      --  the bound variable. Given that quantified expressions appearing
      --  in contracts are copied to create pragmas and eventually checking
      --  procedures, a new bound variable must be created for each copy, to
      --  prevent multiple declarations of the same symbol.

      --  To meet all these demands, routine New_Copy_Tree is split into two
      --  phases.

      --  Phase 1 traverses the tree in order to locate entities and itypes
      --  defined within the subtree. New entities are generated and saved in
      --  table NCT_New_Entities. The semantic fields of all new entities and
      --  itypes are then updated accordingly.

      --  Phase 2 traverses the tree in order to replicate each node. Various
      --  semantic fields of nodes and entities are updated accordingly.

      --  Preparatory phase. Clear the contents of tables NCT_New_Entities and
      --  NCT_Pending_Itypes in case a previous call to New_Copy_Tree left some
      --  data inside.

      if NCT_Tables_In_Use then
         NCT_Tables_In_Use := False;

         NCT_New_Entities.Reset;
         NCT_Pending_Itypes.Reset;
      end if;

      --  Populate tables NCT_New_Entities and NCT_Pending_Itypes with data
      --  supplied by a linear entity map. The tables offer faster access to
      --  the same data.

      Build_NCT_Tables (Map);

      --  Execute Phase 1. Traverse the subtree and generate new entities for
      --  the following cases:

      --    * An entity defined within an N_Expression_With_Actions node

      --    * An itype referenced within the subtree where the associated node
      --      is also in the subtree.

      --  All new entities are accessible via table NCT_New_Entities, which
      --  contains mappings of the form:

      --    Old_Entity -> New_Entity
      --    Old_Itype  -> New_Itype

      --  In addition, the associated nodes of all new itypes are mapped in
      --  table NCT_Pending_Itypes:

      --    Assoc_Nod -> (New_Itype1, New_Itype2, .., New_ItypeN)

      Visit_Any_Node (Source);

      --  Update the semantic attributes of all new entities generated during
      --  Phase 1 before starting Phase 2. The updates could be performed in
      --  routine Corresponding_Entity, however this may cause the same entity
      --  to be updated multiple times, effectively generating useless nodes.
      --  Keeping the updates separates from Phase 2 ensures that only one set
      --  of attributes is generated for an entity at any one time.

      Update_New_Entities (Map);

      --  Execute Phase 2. Replicate the source subtree one node at a time.
      --  The following transformations take place:

      --    * References to entities and itypes are updated to refer to the
      --      new entities and itypes generated during Phase 1.

      --    * All Associated_Node_For_Itype attributes of itypes are updated
      --      to refer to the new replicated Associated_Node_For_Itype.

      return Copy_Node_With_Replacement (Source);
   end New_Copy_Tree;

   -------------------------
   -- New_External_Entity --
   -------------------------

   function New_External_Entity
     (Kind         : Entity_Kind;
      Scope_Id     : Entity_Id;
      Sloc_Value   : Source_Ptr;
      Related_Id   : Entity_Id;
      Suffix       : Character;
      Suffix_Index : Int := 0;
      Prefix       : Character := ' ') return Entity_Id
   is
      N : constant Entity_Id :=
            Make_Defining_Identifier (Sloc_Value,
              New_External_Name
                (Chars (Related_Id), Suffix, Suffix_Index, Prefix));

   begin
      Mutate_Ekind      (N, Kind);
      Set_Is_Internal   (N, True);
      Append_Entity     (N, Scope_Id);
      Set_Public_Status (N);

      if Kind in Type_Kind then
         Reinit_Size_Align (N);
      end if;

      return N;
   end New_External_Entity;

   -------------------------
   -- New_Internal_Entity --
   -------------------------

   function New_Internal_Entity
     (Kind       : Entity_Kind;
      Scope_Id   : Entity_Id;
      Sloc_Value : Source_Ptr;
      Id_Char    : Character) return Entity_Id
   is
      N : constant Entity_Id := Make_Temporary (Sloc_Value, Id_Char);

   begin
      Mutate_Ekind    (N, Kind);
      Set_Is_Internal (N, True);
      Append_Entity   (N, Scope_Id);

      if Kind in Type_Kind then
         Reinit_Size_Align (N);
      end if;

      return N;
   end New_Internal_Entity;

   -----------------
   -- Next_Actual --
   -----------------

   function Next_Actual (Actual_Id : Node_Id) return Node_Id is
      Par : constant Node_Id := Parent (Actual_Id);
      N   : Node_Id;

   begin
      --  If we are pointing at a positional parameter, it is a member of a
      --  node list (the list of parameters), and the next parameter is the
      --  next node on the list, unless we hit a parameter association, then
      --  we shift to using the chain whose head is the First_Named_Actual in
      --  the parent, and then is threaded using the Next_Named_Actual of the
      --  Parameter_Association. All this fiddling is because the original node
      --  list is in the textual call order, and what we need is the
      --  declaration order.

      if Is_List_Member (Actual_Id) then
         N := Next (Actual_Id);

         if Nkind (N) = N_Parameter_Association then

            --  In case of a build-in-place call, the call will no longer be a
            --  call; it will have been rewritten.

            if Nkind (Par) in N_Entry_Call_Statement
                            | N_Function_Call
                            | N_Procedure_Call_Statement
            then
               return First_Named_Actual (Par);

            --  In case of a call rewritten in GNATprove mode while "inlining
            --  for proof" go to the original call.

            elsif Nkind (Par) = N_Null_Statement then
               pragma Assert
                 (GNATprove_Mode
                    and then
                  Nkind (Original_Node (Par)) in N_Subprogram_Call);

               return First_Named_Actual (Original_Node (Par));
            else
               return Empty;
            end if;
         else
            return N;
         end if;

      else
         return Next_Named_Actual (Parent (Actual_Id));
      end if;
   end Next_Actual;

   procedure Next_Actual (Actual_Id : in out Node_Id) is
   begin
      Actual_Id := Next_Actual (Actual_Id);
   end Next_Actual;

   -----------------
   -- Next_Global --
   -----------------

   function Next_Global (Node : Node_Id) return Node_Id is
   begin
      --  The global item may either be in a list, or by itself, in which case
      --  there is no next global item with the same mode.

      if Is_List_Member (Node) then
         return Next (Node);
      else
         return Empty;
      end if;
   end Next_Global;

   procedure Next_Global (Node : in out Node_Id) is
   begin
      Node := Next_Global (Node);
   end Next_Global;

   ------------------------
   -- No_Caching_Enabled --
   ------------------------

   function No_Caching_Enabled (Id : Entity_Id) return Boolean is
      Prag : constant Node_Id := Get_Pragma (Id, Pragma_No_Caching);
      Arg1 : Node_Id;

   begin
      if Present (Prag) then
         Arg1 := First (Pragma_Argument_Associations (Prag));

         --  The pragma has an optional Boolean expression, the related
         --  property is enabled only when the expression evaluates to True.

         if Present (Arg1) then
            return Is_True (Expr_Value (Get_Pragma_Arg (Arg1)));

         --  Otherwise the lack of expression enables the property by
         --  default.

         else
            return True;
         end if;

      --  The property was never set in the first place

      else
         return False;
      end if;
   end No_Caching_Enabled;

   --------------------------
   -- No_Heap_Finalization --
   --------------------------

   function No_Heap_Finalization (Typ : Entity_Id) return Boolean is
   begin
      if Ekind (Typ) in E_Access_Type | E_General_Access_Type
        and then Is_Library_Level_Entity (Typ)
      then
         --  A global No_Heap_Finalization pragma applies to all library-level
         --  named access-to-object types.

         if Present (No_Heap_Finalization_Pragma) then
            return True;

         --  The library-level named access-to-object type itself is subject to
         --  pragma No_Heap_Finalization.

         elsif Present (Get_Pragma (Typ, Pragma_No_Heap_Finalization)) then
            return True;
         end if;
      end if;

      return False;
   end No_Heap_Finalization;

   -----------------------
   -- Normalize_Actuals --
   -----------------------

   --  Chain actuals according to formals of subprogram. If there are no named
   --  associations, the chain is simply the list of Parameter Associations,
   --  since the order is the same as the declaration order. If there are named
   --  associations, then the First_Named_Actual field in the N_Function_Call
   --  or N_Procedure_Call_Statement node points to the Parameter_Association
   --  node for the parameter that comes first in declaration order. The
   --  remaining named parameters are then chained in declaration order using
   --  Next_Named_Actual.

   --  This routine also verifies that the number of actuals is compatible with
   --  the number and default values of formals, but performs no type checking
   --  (type checking is done by the caller).

   --  If the matching succeeds, Success is set to True and the caller proceeds
   --  with type-checking. If the match is unsuccessful, then Success is set to
   --  False, and the caller attempts a different interpretation, if there is
   --  one.

   --  If the flag Report is on, the call is not overloaded, and a failure to
   --  match can be reported here, rather than in the caller.

   procedure Normalize_Actuals
     (N       : Node_Id;
      S       : Entity_Id;
      Report  : Boolean;
      Success : out Boolean)
   is
      Actuals     : constant List_Id := Parameter_Associations (N);
      Actual      : Node_Id := Empty;
      Formal      : Entity_Id;
      Last        : Node_Id := Empty;
      First_Named : Node_Id := Empty;
      Found       : Boolean;

      Formals_To_Match : Integer := 0;
      Actuals_To_Match : Integer := 0;

      procedure Chain (A : Node_Id);
      --  Add named actual at the proper place in the list, using the
      --  Next_Named_Actual link.

      function Reporting return Boolean;
      --  Determines if an error is to be reported. To report an error, we
      --  need Report to be True, and also we do not report errors caused
      --  by calls to init procs that occur within other init procs. Such
      --  errors must always be cascaded errors, since if all the types are
      --  declared correctly, the compiler will certainly build decent calls.

      -----------
      -- Chain --
      -----------

      procedure Chain (A : Node_Id) is
      begin
         if No (Last) then

            --  Call node points to first actual in list

            Set_First_Named_Actual (N, Explicit_Actual_Parameter (A));

         else
            Set_Next_Named_Actual (Last, Explicit_Actual_Parameter (A));
         end if;

         Last := A;
         Set_Next_Named_Actual (Last, Empty);
      end Chain;

      ---------------
      -- Reporting --
      ---------------

      function Reporting return Boolean is
      begin
         if not Report then
            return False;

         elsif not Within_Init_Proc then
            return True;

         elsif Is_Init_Proc (Entity (Name (N))) then
            return False;

         else
            return True;
         end if;
      end Reporting;

   --  Start of processing for Normalize_Actuals

   begin
      if Is_Access_Type (S) then

         --  The name in the call is a function call that returns an access
         --  to subprogram. The designated type has the list of formals.

         Formal := First_Formal (Designated_Type (S));
      else
         Formal := First_Formal (S);
      end if;

      while Present (Formal) loop
         Formals_To_Match := Formals_To_Match + 1;
         Next_Formal (Formal);
      end loop;

      --  Find if there is a named association, and verify that no positional
      --  associations appear after named ones.

      if Present (Actuals) then
         Actual := First (Actuals);
      end if;

      while Present (Actual)
        and then Nkind (Actual) /= N_Parameter_Association
      loop
         Actuals_To_Match := Actuals_To_Match + 1;
         Next (Actual);
      end loop;

      if No (Actual) and Actuals_To_Match = Formals_To_Match then

         --  Most common case: positional notation, no defaults

         Success := True;
         return;

      elsif Actuals_To_Match > Formals_To_Match then

         --  Too many actuals: will not work

         if Reporting then
            if Is_Entity_Name (Name (N)) then
               Error_Msg_N ("too many arguments in call to&", Name (N));
            else
               Error_Msg_N ("too many arguments in call", N);
            end if;
         end if;

         Success := False;
         return;
      end if;

      First_Named := Actual;

      while Present (Actual) loop
         if Nkind (Actual) /= N_Parameter_Association then
            Error_Msg_N
              ("positional parameters not allowed after named ones", Actual);
            Success := False;
            return;

         else
            Actuals_To_Match := Actuals_To_Match + 1;
         end if;

         Next (Actual);
      end loop;

      if Present (Actuals) then
         Actual := First (Actuals);
      end if;

      Formal := First_Formal (S);
      while Present (Formal) loop

         --  Match the formals in order. If the corresponding actual is
         --  positional, nothing to do. Else scan the list of named actuals
         --  to find the one with the right name.

         if Present (Actual)
           and then Nkind (Actual) /= N_Parameter_Association
         then
            Next (Actual);
            Actuals_To_Match := Actuals_To_Match - 1;
            Formals_To_Match := Formals_To_Match - 1;

         else
            --  For named parameters, search the list of actuals to find
            --  one that matches the next formal name.

            Actual := First_Named;
            Found  := False;
            while Present (Actual) loop
               if Chars (Selector_Name (Actual)) = Chars (Formal) then
                  Found := True;
                  Chain (Actual);
                  Actuals_To_Match := Actuals_To_Match - 1;
                  Formals_To_Match := Formals_To_Match - 1;
                  exit;
               end if;

               Next (Actual);
            end loop;

            if not Found then
               if Ekind (Formal) /= E_In_Parameter
                 or else No (Default_Value (Formal))
               then
                  if Reporting then
                     if (Comes_From_Source (S)
                          or else Sloc (S) = Standard_Location)
                       and then Is_Overloadable (S)
                     then
                        if No (Actuals)
                          and then
                            Nkind (Parent (N)) in N_Procedure_Call_Statement
                                                | N_Function_Call
                                                | N_Parameter_Association
                          and then Ekind (S) /= E_Function
                        then
                           Set_Etype (N, Etype (S));

                        else
                           Error_Msg_Name_1 := Chars (S);
                           Error_Msg_Sloc := Sloc (S);
                           Error_Msg_NE
                             ("missing argument for parameter & "
                              & "in call to % declared #", N, Formal);
                        end if;

                     elsif Is_Overloadable (S) then
                        Error_Msg_Name_1 := Chars (S);

                        --  Point to type derivation that generated the
                        --  operation.

                        Error_Msg_Sloc := Sloc (Parent (S));

                        Error_Msg_NE
                          ("missing argument for parameter & "
                           & "in call to % (inherited) #", N, Formal);

                     else
                        Error_Msg_NE
                          ("missing argument for parameter &", N, Formal);
                     end if;
                  end if;

                  Success := False;
                  return;

               else
                  Formals_To_Match := Formals_To_Match - 1;
               end if;
            end if;
         end if;

         Next_Formal (Formal);
      end loop;

      if Formals_To_Match = 0 and then Actuals_To_Match = 0 then
         Success := True;
         return;

      else
         if Reporting then

            --  Find some superfluous named actual that did not get
            --  attached to the list of associations.

            Actual := First (Actuals);
            while Present (Actual) loop
               if Nkind (Actual) = N_Parameter_Association
                 and then Actual /= Last
                 and then No (Next_Named_Actual (Actual))
               then
                  --  A validity check may introduce a copy of a call that
                  --  includes an extra actual (for example for an unrelated
                  --  accessibility check). Check that the extra actual matches
                  --  some extra formal, which must exist already because
                  --  subprogram must be frozen at this point.

                  if Present (Extra_Formals (S))
                    and then not Comes_From_Source (Actual)
                    and then Nkind (Actual) = N_Parameter_Association
                    and then Chars (Extra_Formals (S)) =
                               Chars (Selector_Name (Actual))
                  then
                     null;
                  else
                     Error_Msg_N
                       ("unmatched actual & in call", Selector_Name (Actual));
                     exit;
                  end if;
               end if;

               Next (Actual);
            end loop;
         end if;

         Success := False;
         return;
      end if;
   end Normalize_Actuals;

   --------------------------------
   -- Note_Possible_Modification --
   --------------------------------

   procedure Note_Possible_Modification (N : Node_Id; Sure : Boolean) is
      Modification_Comes_From_Source : constant Boolean :=
                                         Comes_From_Source (Parent (N));

      Ent : Entity_Id;
      Exp : Node_Id;

   begin
      --  Loop to find referenced entity, if there is one

      Exp := N;
      loop
         Ent := Empty;

         if Is_Entity_Name (Exp) then
            Ent := Entity (Exp);

            --  If the entity is missing, it is an undeclared identifier,
            --  and there is nothing to annotate.

            if No (Ent) then
               return;
            end if;

         elsif Nkind (Exp) = N_Explicit_Dereference then
            declare
               P : constant Node_Id := Prefix (Exp);

            begin
               --  In formal verification mode, keep track of all reads and
               --  writes through explicit dereferences.

               if GNATprove_Mode then
                  SPARK_Specific.Generate_Dereference (N, 'm');
               end if;

               if Nkind (P) = N_Selected_Component
                 and then Present (Entry_Formal (Entity (Selector_Name (P))))
               then
                  --  Case of a reference to an entry formal

                  Ent := Entry_Formal (Entity (Selector_Name (P)));

               elsif Nkind (P) = N_Identifier
                 and then Nkind (Parent (Entity (P))) = N_Object_Declaration
                 and then Present (Expression (Parent (Entity (P))))
                 and then Nkind (Expression (Parent (Entity (P)))) =
                                                               N_Reference
               then
                  --  Case of a reference to a value on which side effects have
                  --  been removed.

                  Exp := Prefix (Expression (Parent (Entity (P))));
                  goto Continue;

               else
                  return;
               end if;
            end;

         elsif Nkind (Exp) in N_Type_Conversion | N_Unchecked_Type_Conversion
         then
            Exp := Expression (Exp);
            goto Continue;

         elsif Nkind (Exp) in
                 N_Slice | N_Indexed_Component | N_Selected_Component
         then
            --  Special check, if the prefix is an access type, then return
            --  since we are modifying the thing pointed to, not the prefix.
            --  When we are expanding, most usually the prefix is replaced
            --  by an explicit dereference, and this test is not needed, but
            --  in some cases (notably -gnatc mode and generics) when we do
            --  not do full expansion, we need this special test.

            if Is_Access_Type (Etype (Prefix (Exp))) then
               return;

            --  Otherwise go to prefix and keep going

            else
               Exp := Prefix (Exp);
               goto Continue;
            end if;

         --  All other cases, not a modification

         else
            return;
         end if;

         --  Now look for entity being referenced

         if Present (Ent) then
            if Is_Object (Ent) then
               if Comes_From_Source (Exp)
                 or else Modification_Comes_From_Source
               then
                  --  Give warning if pragma unmodified is given and we are
                  --  sure this is a modification.

                  if Has_Pragma_Unmodified (Ent) and then Sure then

                     --  Note that the entity may be present only as a result
                     --  of pragma Unused.

                     if Has_Pragma_Unused (Ent) then
                        Error_Msg_NE
                          ("??aspect Unused specified for &!", N, Ent);
                     else
                        Error_Msg_NE
                          ("??aspect Unmodified specified for &!", N, Ent);
                     end if;
                  end if;

                  Set_Never_Set_In_Source (Ent, False);
               end if;

               Set_Is_True_Constant (Ent, False);
               Set_Current_Value    (Ent, Empty);
               Set_Is_Known_Null    (Ent, False);

               if not Can_Never_Be_Null (Ent) then
                  Set_Is_Known_Non_Null (Ent, False);
               end if;

               --  Follow renaming chain

               if Ekind (Ent) in E_Variable | E_Constant
                 and then Present (Renamed_Object (Ent))
               then
                  Exp := Renamed_Object (Ent);

                  --  If the entity is the loop variable in an iteration over
                  --  a container, retrieve container expression to indicate
                  --  possible modification.

                  if Present (Related_Expression (Ent))
                    and then Nkind (Parent (Related_Expression (Ent))) =
                                                   N_Iterator_Specification
                  then
                     Exp := Original_Node (Related_Expression (Ent));
                  end if;

                  goto Continue;

               --  The expression may be the renaming of a subcomponent of an
               --  array or container. The assignment to the subcomponent is
               --  a modification of the container.

               elsif Comes_From_Source (Original_Node (Exp))
                 and then Nkind (Original_Node (Exp)) in
                            N_Selected_Component | N_Indexed_Component
               then
                  Exp := Prefix (Original_Node (Exp));
                  goto Continue;
               end if;

               --  Generate a reference only if the assignment comes from
               --  source. This excludes, for example, calls to a dispatching
               --  assignment operation when the left-hand side is tagged. In
               --  GNATprove mode, we need those references also on generated
               --  code, as these are used to compute the local effects of
               --  subprograms.

               if Modification_Comes_From_Source or GNATprove_Mode then
                  Generate_Reference (Ent, Exp, 'm');

                  --  If the target of the assignment is the bound variable
                  --  in an iterator, indicate that the corresponding array
                  --  or container is also modified.

                  if Ada_Version >= Ada_2012
                    and then Nkind (Parent (Ent)) = N_Iterator_Specification
                  then
                     declare
                        Domain : constant Node_Id := Name (Parent (Ent));

                     begin
                        --  ??? In the full version of the construct, the
                        --  domain of iteration can be given by an expression.

                        if Is_Entity_Name (Domain) then
                           Generate_Reference      (Entity (Domain), Exp, 'm');
                           Set_Is_True_Constant    (Entity (Domain), False);
                           Set_Never_Set_In_Source (Entity (Domain), False);
                        end if;
                     end;
                  end if;
               end if;
            end if;

            Kill_Checks (Ent);

            --  If we are sure this is a modification from source, and we know
            --  this modifies a constant, then give an appropriate warning.

            if Sure
              and then Modification_Comes_From_Source
              and then Overlays_Constant (Ent)
              and then Address_Clause_Overlay_Warnings
            then
               declare
                  Addr  : constant Node_Id := Address_Clause (Ent);
                  O_Ent : Entity_Id;
                  Off   : Boolean;

               begin
                  Find_Overlaid_Entity (Addr, O_Ent, Off);

                  Error_Msg_Sloc := Sloc (Addr);
                  Error_Msg_NE
                    ("?o?constant& may be modified via address clause#",
                     N, O_Ent);
               end;
            end if;

            return;
         end if;

      <<Continue>>
         null;
      end loop;
   end Note_Possible_Modification;

   -----------------
   -- Null_Status --
   -----------------

   function Null_Status (N : Node_Id) return Null_Status_Kind is
      function Is_Null_Excluding_Def (Def : Node_Id) return Boolean;
      --  Determine whether definition Def carries a null exclusion

      function Null_Status_Of_Entity (Id : Entity_Id) return Null_Status_Kind;
      --  Determine the null status of arbitrary entity Id

      function Null_Status_Of_Type (Typ : Entity_Id) return Null_Status_Kind;
      --  Determine the null status of type Typ

      ---------------------------
      -- Is_Null_Excluding_Def --
      ---------------------------

      function Is_Null_Excluding_Def (Def : Node_Id) return Boolean is
      begin
         return Nkind (Def) in N_Access_Definition
                             | N_Access_Function_Definition
                             | N_Access_Procedure_Definition
                             | N_Access_To_Object_Definition
                             | N_Component_Definition
                             | N_Derived_Type_Definition
             and then Null_Exclusion_Present (Def);
      end Is_Null_Excluding_Def;

      ---------------------------
      -- Null_Status_Of_Entity --
      ---------------------------

      function Null_Status_Of_Entity
        (Id : Entity_Id) return Null_Status_Kind
      is
         Decl : constant Node_Id := Declaration_Node (Id);
         Def  : Node_Id;

      begin
         --  The value of an imported or exported entity may be set externally
         --  regardless of a null exclusion. As a result, the value cannot be
         --  determined statically.

         if Is_Imported (Id) or else Is_Exported (Id) then
            return Unknown;

         elsif Nkind (Decl) in N_Component_Declaration
                             | N_Discriminant_Specification
                             | N_Formal_Object_Declaration
                             | N_Object_Declaration
                             | N_Object_Renaming_Declaration
                             | N_Parameter_Specification
         then
            --  A component declaration yields a non-null value when either
            --  its component definition or access definition carries a null
            --  exclusion.

            if Nkind (Decl) = N_Component_Declaration then
               Def := Component_Definition (Decl);

               if Is_Null_Excluding_Def (Def) then
                  return Is_Non_Null;
               end if;

               Def := Access_Definition (Def);

               if Present (Def) and then Is_Null_Excluding_Def (Def) then
                  return Is_Non_Null;
               end if;

            --  A formal object declaration yields a non-null value if its
            --  access definition carries a null exclusion. If the object is
            --  default initialized, then the value depends on the expression.

            elsif Nkind (Decl) = N_Formal_Object_Declaration then
               Def := Access_Definition  (Decl);

               if Present (Def) and then Is_Null_Excluding_Def (Def) then
                  return Is_Non_Null;
               end if;

            --  A constant may yield a null or non-null value depending on its
            --  initialization expression.

            elsif Ekind (Id) = E_Constant then
               return Null_Status (Constant_Value (Id));

            --  The construct yields a non-null value when it has a null
            --  exclusion.

            elsif Null_Exclusion_Present (Decl) then
               return Is_Non_Null;

            --  An object renaming declaration yields a non-null value if its
            --  access definition carries a null exclusion. Otherwise the value
            --  depends on the renamed name.

            elsif Nkind (Decl) = N_Object_Renaming_Declaration then
               Def := Access_Definition (Decl);

               if Present (Def) and then Is_Null_Excluding_Def (Def) then
                  return Is_Non_Null;

               else
                  return Null_Status (Name (Decl));
               end if;
            end if;
         end if;

         --  At this point the declaration of the entity does not carry a null
         --  exclusion and lacks an initialization expression. Check the status
         --  of its type.

         return Null_Status_Of_Type (Etype (Id));
      end Null_Status_Of_Entity;

      -------------------------
      -- Null_Status_Of_Type --
      -------------------------

      function Null_Status_Of_Type (Typ : Entity_Id) return Null_Status_Kind is
         Curr : Entity_Id;
         Decl : Node_Id;

      begin
         --  Traverse the type chain looking for types with null exclusion

         Curr := Typ;
         while Present (Curr) and then Etype (Curr) /= Curr loop
            Decl := Parent (Curr);

            --  Guard against itypes which do not always have declarations. A
            --  type yields a non-null value if it carries a null exclusion.

            if Present (Decl) then
               if Nkind (Decl) = N_Full_Type_Declaration
                 and then Is_Null_Excluding_Def (Type_Definition (Decl))
               then
                  return Is_Non_Null;

               elsif Nkind (Decl) = N_Subtype_Declaration
                 and then Null_Exclusion_Present (Decl)
               then
                  return Is_Non_Null;
               end if;
            end if;

            Curr := Etype (Curr);
         end loop;

         --  The type chain does not contain any null excluding types

         return Unknown;
      end Null_Status_Of_Type;

   --  Start of processing for Null_Status

   begin
      --  Prevent cascaded errors or infinite loops when trying to determine
      --  the null status of an erroneous construct.

      if Error_Posted (N) then
         return Unknown;

      --  An allocator always creates a non-null value

      elsif Nkind (N) = N_Allocator then
         return Is_Non_Null;

      --  Taking the 'Access of something yields a non-null value

      elsif Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) in Name_Access
                                     | Name_Unchecked_Access
                                     | Name_Unrestricted_Access
      then
         return Is_Non_Null;

      --  "null" yields null

      elsif Nkind (N) = N_Null then
         return Is_Null;

      --  Check the status of the operand of a type conversion

      elsif Nkind (N) = N_Type_Conversion then
         return Null_Status (Expression (N));

      --  The input denotes a reference to an entity. Determine whether the
      --  entity or its type yields a null or non-null value.

      elsif Is_Entity_Name (N) and then Present (Entity (N)) then
         return Null_Status_Of_Entity (Entity (N));
      end if;

      --  Otherwise it is not possible to determine the null status of the
      --  subexpression at compile time without resorting to simple flow
      --  analysis.

      return Unknown;
   end Null_Status;

   --------------------------------------
   --  Null_To_Null_Address_Convert_OK --
   --------------------------------------

   function Null_To_Null_Address_Convert_OK
     (N   : Node_Id;
      Typ : Entity_Id := Empty) return Boolean
   is
   begin
      if not Relaxed_RM_Semantics then
         return False;
      end if;

      if Nkind (N) = N_Null then
         return Present (Typ) and then Is_Descendant_Of_Address (Typ);

      elsif Nkind (N) in N_Op_Compare then
         declare
            L : constant Node_Id := Left_Opnd (N);
            R : constant Node_Id := Right_Opnd (N);

         begin
            --  We check the Etype of the complementary operand since the
            --  N_Null node is not decorated at this stage.

            return
              ((Nkind (L) = N_Null
                 and then Is_Descendant_Of_Address (Etype (R)))
              or else
               (Nkind (R) = N_Null
                 and then Is_Descendant_Of_Address (Etype (L))));
         end;
      end if;

      return False;
   end Null_To_Null_Address_Convert_OK;

   ---------------------------------
   -- Number_Of_Elements_In_Array --
   ---------------------------------

   function Number_Of_Elements_In_Array (T : Entity_Id) return Int is
      Indx : Node_Id;
      Typ  : Entity_Id;
      Low  : Node_Id;
      High : Node_Id;
      Num  : Int := 1;

   begin
      pragma Assert (Is_Array_Type (T));

      Indx := First_Index (T);
      while Present (Indx) loop
         Typ := Underlying_Type (Etype (Indx));

         --  Never look at junk bounds of a generic type

         if Is_Generic_Type (Typ) then
            return 0;
         end if;

         --  Check the array bounds are known at compile time and return zero
         --  if they are not.

         Low  := Type_Low_Bound (Typ);
         High := Type_High_Bound (Typ);

         if not Compile_Time_Known_Value (Low) then
            return 0;
         elsif not Compile_Time_Known_Value (High) then
            return 0;
         else
            Num :=
              Num * UI_To_Int ((Expr_Value (High) - Expr_Value (Low) + 1));
         end if;

         Next_Index (Indx);
      end loop;

      return Num;
   end Number_Of_Elements_In_Array;

   ---------------------------------
   -- Original_Aspect_Pragma_Name --
   ---------------------------------

   function Original_Aspect_Pragma_Name (N : Node_Id) return Name_Id is
      Item     : Node_Id;
      Item_Nam : Name_Id;

   begin
      pragma Assert (Nkind (N) in N_Aspect_Specification | N_Pragma);

      Item := N;

      --  The pragma was generated to emulate an aspect, use the original
      --  aspect specification.

      if Nkind (Item) = N_Pragma and then From_Aspect_Specification (Item) then
         Item := Corresponding_Aspect (Item);
      end if;

      --  Retrieve the name of the aspect/pragma. As assertion pragmas from
      --  a generic instantiation might have been rewritten into pragma Check,
      --  we look at the original node for Item. Note also that Pre, Pre_Class,
      --  Post and Post_Class rewrite their pragma identifier to preserve the
      --  original name, so we look at the original node for the identifier.
      --  ??? this is kludgey

      if Nkind (Item) = N_Pragma then
         Item_Nam :=
           Chars (Original_Node (Pragma_Identifier (Original_Node (Item))));

         if Item_Nam = Name_Check then
            --  Pragma "Check" preserves the original pragma name as its first
            --  argument.
            Item_Nam :=
              Chars (Expression (First (Pragma_Argument_Associations
                (Original_Node (Item)))));
         end if;

      else
         pragma Assert (Nkind (Item) = N_Aspect_Specification);
         Item_Nam := Chars (Identifier (Item));
      end if;

      --  Deal with 'Class by converting the name to its _XXX form

      if Class_Present (Item) then
         if Item_Nam = Name_Invariant then
            Item_Nam := Name_uInvariant;

         elsif Item_Nam = Name_Post then
            Item_Nam := Name_uPost;

         elsif Item_Nam = Name_Pre then
            Item_Nam := Name_uPre;

         elsif Item_Nam in Name_Type_Invariant | Name_Type_Invariant_Class
         then
            Item_Nam := Name_uType_Invariant;

         --  Nothing to do for other cases (e.g. a Check that derived from
         --  Pre_Class and has the flag set). Also we do nothing if the name
         --  is already in special _xxx form.

         end if;
      end if;

      return Item_Nam;
   end Original_Aspect_Pragma_Name;

   --------------------------------------
   -- Original_Corresponding_Operation --
   --------------------------------------

   function Original_Corresponding_Operation (S : Entity_Id) return Entity_Id
   is
      Typ : constant Entity_Id := Find_Dispatching_Type (S);

   begin
      --  If S is an inherited primitive S2 the original corresponding
      --  operation of S is the original corresponding operation of S2

      if Present (Alias (S))
        and then Find_Dispatching_Type (Alias (S)) /= Typ
      then
         return Original_Corresponding_Operation (Alias (S));

      --  If S overrides an inherited subprogram S2 the original corresponding
      --  operation of S is the original corresponding operation of S2

      elsif Present (Overridden_Operation (S)) then
         return Original_Corresponding_Operation (Overridden_Operation (S));

      --  otherwise it is S itself

      else
         return S;
      end if;
   end Original_Corresponding_Operation;

   -----------------------------------
   -- Original_View_In_Visible_Part --
   -----------------------------------

   function Original_View_In_Visible_Part
     (Typ : Entity_Id) return Boolean
   is
      Scop : constant Entity_Id := Scope (Typ);

   begin
      --  The scope must be a package

      if not Is_Package_Or_Generic_Package (Scop) then
         return False;
      end if;

      --  A type with a private declaration has a private view declared in
      --  the visible part.

      if Has_Private_Declaration (Typ) then
         return True;
      end if;

      return List_Containing (Parent (Typ)) =
        Visible_Declarations (Package_Specification (Scop));
   end Original_View_In_Visible_Part;

   -------------------
   -- Output_Entity --
   -------------------

   procedure Output_Entity (Id : Entity_Id) is
      Scop : Entity_Id;

   begin
      Scop := Scope (Id);

      --  The entity may lack a scope when it is in the process of being
      --  analyzed. Use the current scope as an approximation.

      if No (Scop) then
         Scop := Current_Scope;
      end if;

      Output_Name (Chars (Id), Scop);
   end Output_Entity;

   -----------------
   -- Output_Name --
   -----------------

   procedure Output_Name (Nam : Name_Id; Scop : Entity_Id := Current_Scope) is
   begin
      Write_Str
        (Get_Name_String
          (Get_Qualified_Name
            (Nam    => Nam,
             Suffix => No_Name,
             Scop   => Scop)));
      Write_Eol;
   end Output_Name;

   ------------------
   -- Param_Entity --
   ------------------

   --  This would be trivial, simply a test for an identifier that was a
   --  reference to a formal, if it were not for the fact that a previous call
   --  to Expand_Entry_Parameter will have modified the reference to the
   --  identifier. A formal of a protected entity is rewritten as

   --    typ!(recobj).rec.all'Constrained

   --  where rec is a selector whose Entry_Formal link points to the formal

   --  If the type of the entry parameter has a representation clause, then an
   --  extra temp is involved (see below).

   --  For a formal of a task entity, the formal is rewritten as a local
   --  renaming.

   --  In addition, a formal that is marked volatile because it is aliased
   --  through an address clause is rewritten as dereference as well.

   function Param_Entity (N : Node_Id) return Entity_Id is
      Renamed_Obj : Node_Id;

   begin
      --  Simple reference case

      if Nkind (N) in N_Identifier | N_Expanded_Name then
         if Is_Formal (Entity (N)) then
            return Entity (N);

         --  Handle renamings of formal parameters and formals of tasks that
         --  are rewritten as renamings.

         elsif Nkind (Parent (Entity (N))) = N_Object_Renaming_Declaration then
            Renamed_Obj := Get_Referenced_Object (Renamed_Object (Entity (N)));

            if Is_Entity_Name (Renamed_Obj)
              and then Is_Formal (Entity (Renamed_Obj))
            then
               return Entity (Renamed_Obj);

            elsif
              Nkind (Parent (Parent (Entity (N)))) = N_Accept_Statement
            then
               return Entity (N);
            end if;
         end if;

      else
         if Nkind (N) = N_Explicit_Dereference then
            declare
               P    : Node_Id := Prefix (N);
               S    : Node_Id;
               E    : Entity_Id;
               Decl : Node_Id;

            begin
               --  If the type of an entry parameter has a representation
               --  clause, then the prefix is not a selected component, but
               --  instead a reference to a temp pointing at the selected
               --  component. In this case, set P to be the initial value of
               --  that temp.

               if Nkind (P) = N_Identifier then
                  E := Entity (P);

                  if Ekind (E) = E_Constant then
                     Decl := Parent (E);

                     if Nkind (Decl) = N_Object_Declaration then
                        P := Expression (Decl);
                     end if;
                  end if;
               end if;

               if Nkind (P) = N_Selected_Component then
                  S := Selector_Name (P);

                  if Present (Entry_Formal (Entity (S))) then
                     return Entry_Formal (Entity (S));
                  end if;

               elsif Nkind (Original_Node (N)) = N_Identifier then
                  return Param_Entity (Original_Node (N));
               end if;
            end;
         end if;
      end if;

      return Empty;
   end Param_Entity;

   ----------------------
   -- Policy_In_Effect --
   ----------------------

   function Policy_In_Effect (Policy : Name_Id) return Name_Id is
      function Policy_In_List (List : Node_Id) return Name_Id;
      --  Determine the mode of a policy in a N_Pragma list

      --------------------
      -- Policy_In_List --
      --------------------

      function Policy_In_List (List : Node_Id) return Name_Id is
         Arg1 : Node_Id;
         Arg2 : Node_Id;
         Prag : Node_Id;

      begin
         Prag := List;
         while Present (Prag) loop
            Arg1 := First (Pragma_Argument_Associations (Prag));
            Arg2 := Next (Arg1);

            Arg1 := Get_Pragma_Arg (Arg1);
            Arg2 := Get_Pragma_Arg (Arg2);

            --  The current Check_Policy pragma matches the requested policy or
            --  appears in the single argument form (Assertion, policy_id).

            if Chars (Arg1) in Name_Assertion | Policy then
               return Chars (Arg2);
            end if;

            Prag := Next_Pragma (Prag);
         end loop;

         return No_Name;
      end Policy_In_List;

      --  Local variables

      Kind : Name_Id;

   --  Start of processing for Policy_In_Effect

   begin
      if not Is_Valid_Assertion_Kind (Policy) then
         raise Program_Error;
      end if;

      --  Inspect all policy pragmas that appear within scopes (if any)

      Kind := Policy_In_List (Check_Policy_List);

      --  Inspect all configuration policy pragmas (if any)

      if Kind = No_Name then
         Kind := Policy_In_List (Check_Policy_List_Config);
      end if;

      --  The context lacks policy pragmas, determine the mode based on whether
      --  assertions are enabled at the configuration level. This ensures that
      --  the policy is preserved when analyzing generics.

      if Kind = No_Name then
         if Assertions_Enabled_Config then
            Kind := Name_Check;
         else
            Kind := Name_Ignore;
         end if;
      end if;

      --  In CodePeer mode and GNATprove mode, we need to consider all
      --  assertions, unless they are disabled. Force Name_Check on
      --  ignored assertions.

      if Kind in Name_Ignore | Name_Off
        and then (CodePeer_Mode or GNATprove_Mode)
      then
         Kind := Name_Check;
      end if;

      return Kind;
   end Policy_In_Effect;

   -------------------------------
   -- Preanalyze_Without_Errors --
   -------------------------------

   procedure Preanalyze_Without_Errors (N : Node_Id) is
      Status : constant Boolean := Get_Ignore_Errors;
   begin
      Set_Ignore_Errors (True);
      Preanalyze (N);
      Set_Ignore_Errors (Status);
   end Preanalyze_Without_Errors;

   -----------------------
   -- Predicate_Enabled --
   -----------------------

   function Predicate_Enabled (Typ : Entity_Id) return Boolean is
   begin
      return Present (Predicate_Function (Typ))
        and then not Predicates_Ignored (Typ)
        and then not Predicate_Checks_Suppressed (Empty);
   end Predicate_Enabled;

   ----------------------------------
   -- Predicate_Failure_Expression --
   ----------------------------------

   function Predicate_Failure_Expression
    (Typ : Entity_Id; Inherited_OK : Boolean) return Node_Id
   is
      PF_Aspect : constant Node_Id :=
        Find_Aspect (Typ, Aspect_Predicate_Failure);
   begin
      --  Check for Predicate_Failure aspect specification via an
      --  aspect_specification (as opposed to via a pragma).

      if Present (PF_Aspect) then
         if Inherited_OK or else Entity (PF_Aspect) = Typ then
            return Expression (PF_Aspect);
         else
            return Empty;
         end if;
      end if;

      --  Check for Predicate_Failure aspect specification via a pragma.

      declare
         Rep_Item : Node_Id := First_Rep_Item (Typ);
      begin
         while Present (Rep_Item) loop
            if Nkind (Rep_Item) = N_Pragma
               and then Get_Pragma_Id (Rep_Item) = Pragma_Predicate_Failure
            then
               declare
                  Arg1 : constant Node_Id :=
                    Get_Pragma_Arg
                      (First (Pragma_Argument_Associations (Rep_Item)));
                  Arg2 : constant Node_Id :=
                    Get_Pragma_Arg
                      (Next (First (Pragma_Argument_Associations (Rep_Item))));
               begin
                  if Inherited_OK or else
                     (Nkind (Arg1) in N_Has_Entity
                      and then Entity (Arg1) = Typ)
                  then
                     return Arg2;
                  end if;
               end;
            end if;

            Next_Rep_Item (Rep_Item);
         end loop;
      end;

      --  If we are interested in an inherited Predicate_Failure aspect
      --  and we have an ancestor to inherit from, then recursively check
      --  for that case.

      if Inherited_OK and then Present (Nearest_Ancestor (Typ)) then
         return Predicate_Failure_Expression (Nearest_Ancestor (Typ),
                                              Inherited_OK => True);
      end if;

      return Empty;
   end Predicate_Failure_Expression;

   ----------------------------------
   -- Predicate_Tests_On_Arguments --
   ----------------------------------

   function Predicate_Tests_On_Arguments (Subp : Entity_Id) return Boolean is
   begin
      --  Always test predicates on indirect call

      if Ekind (Subp) = E_Subprogram_Type then
         return True;

      --  Do not test predicates on call to generated default Finalize, since
      --  we are not interested in whether something we are finalizing (and
      --  typically destroying) satisfies its predicates.

      elsif Chars (Subp) = Name_Finalize
        and then not Comes_From_Source (Subp)
      then
         return False;

      --  Do not test predicates on any internally generated routines

      elsif Is_Internal_Name (Chars (Subp)) then
         return False;

      --  Do not test predicates on call to Init_Proc, since if needed the
      --  predicate test will occur at some other point.

      elsif Is_Init_Proc (Subp) then
         return False;

      --  Do not test predicates on call to predicate function, since this
      --  would cause infinite recursion.

      elsif Ekind (Subp) = E_Function
        and then Is_Predicate_Function (Subp)
      then
         return False;

      --  For now, no other exceptions

      else
         return True;
      end if;
   end Predicate_Tests_On_Arguments;

   -----------------------
   -- Private_Component --
   -----------------------

   function Private_Component (Type_Id : Entity_Id) return Entity_Id is
      Ancestor  : constant Entity_Id := Base_Type (Type_Id);

      function Trace_Components
        (T     : Entity_Id;
         Check : Boolean) return Entity_Id;
      --  Recursive function that does the work, and checks against circular
      --  definition for each subcomponent type.

      ----------------------
      -- Trace_Components --
      ----------------------

      function Trace_Components
         (T     : Entity_Id;
          Check : Boolean) return Entity_Id
       is
         Btype     : constant Entity_Id := Base_Type (T);
         Component : Entity_Id;
         P         : Entity_Id;
         Candidate : Entity_Id := Empty;

      begin
         if Check and then Btype = Ancestor then
            Error_Msg_N ("circular type definition", Type_Id);
            return Any_Type;
         end if;

         if Is_Private_Type (Btype) and then not Is_Generic_Type (Btype) then
            if Present (Full_View (Btype))
              and then Is_Record_Type (Full_View (Btype))
              and then not Is_Frozen (Btype)
            then
               --  To indicate that the ancestor depends on a private type, the
               --  current Btype is sufficient. However, to check for circular
               --  definition we must recurse on the full view.

               Candidate := Trace_Components (Full_View (Btype), True);

               if Candidate = Any_Type then
                  return Any_Type;
               else
                  return Btype;
               end if;

            else
               return Btype;
            end if;

         elsif Is_Array_Type (Btype) then
            return Trace_Components (Component_Type (Btype), True);

         elsif Is_Record_Type (Btype) then
            Component := First_Entity (Btype);
            while Present (Component)
              and then Comes_From_Source (Component)
            loop
               --  Skip anonymous types generated by constrained components

               if not Is_Type (Component) then
                  P := Trace_Components (Etype (Component), True);

                  if Present (P) then
                     if P = Any_Type then
                        return P;
                     else
                        Candidate := P;
                     end if;
                  end if;
               end if;

               Next_Entity (Component);
            end loop;

            return Candidate;

         else
            return Empty;
         end if;
      end Trace_Components;

   --  Start of processing for Private_Component

   begin
      return Trace_Components (Type_Id, False);
   end Private_Component;

   ---------------------------
   -- Primitive_Names_Match --
   ---------------------------

   function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean is
      function Non_Internal_Name (E : Entity_Id) return Name_Id;
      --  Given an internal name, returns the corresponding non-internal name

      ------------------------
      --  Non_Internal_Name --
      ------------------------

      function Non_Internal_Name (E : Entity_Id) return Name_Id is
      begin
         Get_Name_String (Chars (E));
         Name_Len := Name_Len - 1;
         return Name_Find;
      end Non_Internal_Name;

   --  Start of processing for Primitive_Names_Match

   begin
      pragma Assert (Present (E1) and then Present (E2));

      return Chars (E1) = Chars (E2)
        or else
           (not Is_Internal_Name (Chars (E1))
             and then Is_Internal_Name (Chars (E2))
             and then Non_Internal_Name (E2) = Chars (E1))
        or else
           (not Is_Internal_Name (Chars (E2))
             and then Is_Internal_Name (Chars (E1))
             and then Non_Internal_Name (E1) = Chars (E2))
        or else
           (Is_Predefined_Dispatching_Operation (E1)
             and then Is_Predefined_Dispatching_Operation (E2)
             and then Same_TSS (E1, E2))
        or else
           (Is_Init_Proc (E1) and then Is_Init_Proc (E2));
   end Primitive_Names_Match;

   -----------------------
   -- Process_End_Label --
   -----------------------

   procedure Process_End_Label
     (N   : Node_Id;
      Typ : Character;
      Ent : Entity_Id)
   is
      Loc  : Source_Ptr;
      Nam  : Node_Id;
      Scop : Entity_Id;

      Label_Ref : Boolean;
      --  Set True if reference to end label itself is required

      Endl : Node_Id;
      --  Gets set to the operator symbol or identifier that references the
      --  entity Ent. For the child unit case, this is the identifier from the
      --  designator. For other cases, this is simply Endl.

      procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id);
      --  N is an identifier node that appears as a parent unit reference in
      --  the case where Ent is a child unit. This procedure generates an
      --  appropriate cross-reference entry. E is the corresponding entity.

      -------------------------
      -- Generate_Parent_Ref --
      -------------------------

      procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id) is
      begin
         --  If names do not match, something weird, skip reference

         if Chars (E) = Chars (N) then

            --  Generate the reference. We do NOT consider this as a reference
            --  for unreferenced symbol purposes.

            Generate_Reference (E, N, 'r', Set_Ref => False, Force => True);

            if Style_Check then
               Style.Check_Identifier (N, E);
            end if;
         end if;
      end Generate_Parent_Ref;

   --  Start of processing for Process_End_Label

   begin
      --  If no node, ignore. This happens in some error situations, and
      --  also for some internally generated structures where no end label
      --  references are required in any case.

      if No (N) then
         return;
      end if;

      --  Nothing to do if no End_Label, happens for internally generated
      --  constructs where we don't want an end label reference anyway. Also
      --  nothing to do if Endl is a string literal, which means there was
      --  some prior error (bad operator symbol)

      Endl := End_Label (N);

      if No (Endl) or else Nkind (Endl) = N_String_Literal then
         return;
      end if;

      --  Reference node is not in extended main source unit

      if not In_Extended_Main_Source_Unit (N) then

         --  Generally we do not collect references except for the extended
         --  main source unit. The one exception is the 'e' entry for a
         --  package spec, where it is useful for a client to have the
         --  ending information to define scopes.

         if Typ /= 'e' then
            return;

         else
            Label_Ref := False;

            --  For this case, we can ignore any parent references, but we
            --  need the package name itself for the 'e' entry.

            if Nkind (Endl) = N_Designator then
               Endl := Identifier (Endl);
            end if;
         end if;

      --  Reference is in extended main source unit

      else
         Label_Ref := True;

         --  For designator, generate references for the parent entries

         if Nkind (Endl) = N_Designator then

            --  Generate references for the prefix if the END line comes from
            --  source (otherwise we do not need these references) We climb the
            --  scope stack to find the expected entities.

            if Comes_From_Source (Endl) then
               Nam  := Name (Endl);
               Scop := Current_Scope;
               while Nkind (Nam) = N_Selected_Component loop
                  Scop := Scope (Scop);
                  exit when No (Scop);
                  Generate_Parent_Ref (Selector_Name (Nam), Scop);
                  Nam := Prefix (Nam);
               end loop;

               if Present (Scop) then
                  Generate_Parent_Ref (Nam, Scope (Scop));
               end if;
            end if;

            Endl := Identifier (Endl);
         end if;
      end if;

      --  If the end label is not for the given entity, then either we have
      --  some previous error, or this is a generic instantiation for which
      --  we do not need to make a cross-reference in this case anyway. In
      --  either case we simply ignore the call.

      if Chars (Ent) /= Chars (Endl) then
         return;
      end if;

      --  If label was really there, then generate a normal reference and then
      --  adjust the location in the end label to point past the name (which
      --  should almost always be the semicolon).

      Loc := Sloc (Endl);

      if Comes_From_Source (Endl) then

         --  If a label reference is required, then do the style check and
         --  generate an l-type cross-reference entry for the label

         if Label_Ref then
            if Style_Check then
               Style.Check_Identifier (Endl, Ent);
            end if;

            Generate_Reference (Ent, Endl, 'l', Set_Ref => False);
         end if;

         --  Set the location to point past the label (normally this will
         --  mean the semicolon immediately following the label). This is
         --  done for the sake of the 'e' or 't' entry generated below.

         Get_Decoded_Name_String (Chars (Endl));
         Set_Sloc (Endl, Sloc (Endl) + Source_Ptr (Name_Len));
      end if;

      --  Now generate the e/t reference

      Generate_Reference (Ent, Endl, Typ, Set_Ref => False, Force => True);

      --  Restore Sloc, in case modified above, since we have an identifier
      --  and the normal Sloc should be left set in the tree.

      Set_Sloc (Endl, Loc);
   end Process_End_Label;

   --------------------------------
   -- Propagate_Concurrent_Flags --
   --------------------------------

   procedure Propagate_Concurrent_Flags
     (Typ      : Entity_Id;
      Comp_Typ : Entity_Id)
   is
   begin
      if Has_Task (Comp_Typ) then
         Set_Has_Task (Typ);
      end if;

      if Has_Protected (Comp_Typ) then
         Set_Has_Protected (Typ);
      end if;

      if Has_Timing_Event (Comp_Typ) then
         Set_Has_Timing_Event (Typ);
      end if;
   end Propagate_Concurrent_Flags;

   ------------------------------
   -- Propagate_DIC_Attributes --
   ------------------------------

   procedure Propagate_DIC_Attributes
     (Typ      : Entity_Id;
      From_Typ : Entity_Id)
   is
      DIC_Proc         : Entity_Id;
      Partial_DIC_Proc : Entity_Id;

   begin
      if Present (Typ) and then Present (From_Typ) then
         pragma Assert (Is_Type (Typ) and then Is_Type (From_Typ));

         --  Nothing to do if both the source and the destination denote the
         --  same type.

         if From_Typ = Typ then
            return;

         --  Nothing to do when the destination denotes an incomplete type
         --  because the DIC is associated with the current instance of a
         --  private type, thus it can never apply to an incomplete type.

         elsif Is_Incomplete_Type (Typ) then
            return;
         end if;

         DIC_Proc := DIC_Procedure (From_Typ);
         Partial_DIC_Proc := Partial_DIC_Procedure (From_Typ);

         --  The setting of the attributes is intentionally conservative. This
         --  prevents accidental clobbering of enabled attributes. We need to
         --  call Base_Type twice, because it is sometimes not set to an actual
         --  base type???

         if Has_Inherited_DIC (From_Typ) then
            Set_Has_Inherited_DIC (Base_Type (Base_Type (Typ)));
         end if;

         if Has_Own_DIC (From_Typ) then
            Set_Has_Own_DIC (Base_Type (Base_Type (Typ)));
         end if;

         if Present (DIC_Proc) and then No (DIC_Procedure (Typ)) then
            Set_DIC_Procedure (Typ, DIC_Proc);
         end if;

         if Present (Partial_DIC_Proc)
           and then No (Partial_DIC_Procedure (Typ))
         then
            Set_Partial_DIC_Procedure (Typ, Partial_DIC_Proc);
         end if;
      end if;
   end Propagate_DIC_Attributes;

   ------------------------------------
   -- Propagate_Invariant_Attributes --
   ------------------------------------

   procedure Propagate_Invariant_Attributes
     (Typ      : Entity_Id;
      From_Typ : Entity_Id)
   is
      Full_IP : Entity_Id;
      Part_IP : Entity_Id;

   begin
      if Present (Typ) and then Present (From_Typ) then
         pragma Assert (Is_Type (Typ) and then Is_Type (From_Typ));

         --  Nothing to do if both the source and the destination denote the
         --  same type.

         if From_Typ = Typ then
            return;
         end if;

         Full_IP := Invariant_Procedure (From_Typ);
         Part_IP := Partial_Invariant_Procedure (From_Typ);

         --  The setting of the attributes is intentionally conservative. This
         --  prevents accidental clobbering of enabled attributes. We need to
         --  call Base_Type twice, because it is sometimes not set to an actual
         --  base type???

         if Has_Inheritable_Invariants (From_Typ) then
            Set_Has_Inheritable_Invariants (Base_Type (Base_Type (Typ)));
         end if;

         if Has_Inherited_Invariants (From_Typ) then
            Set_Has_Inherited_Invariants (Base_Type (Base_Type (Typ)));
         end if;

         if Has_Own_Invariants (From_Typ) then
            Set_Has_Own_Invariants (Base_Type (Base_Type (Typ)));
         end if;

         if Present (Full_IP) and then No (Invariant_Procedure (Typ)) then
            Set_Invariant_Procedure (Typ, Full_IP);
         end if;

         if Present (Part_IP) and then No (Partial_Invariant_Procedure (Typ))
         then
            Set_Partial_Invariant_Procedure (Typ, Part_IP);
         end if;
      end if;
   end Propagate_Invariant_Attributes;

   ------------------------------------
   -- Propagate_Predicate_Attributes --
   ------------------------------------

   procedure Propagate_Predicate_Attributes
     (Typ      : Entity_Id;
      From_Typ : Entity_Id)
   is
      Pred_Func : Entity_Id;
   begin
      if Present (Typ) and then Present (From_Typ) then
         pragma Assert (Is_Type (Typ) and then Is_Type (From_Typ));

         --  Nothing to do if both the source and the destination denote the
         --  same type.

         if From_Typ = Typ then
            return;
         end if;

         Pred_Func   := Predicate_Function (From_Typ);

         --  The setting of the attributes is intentionally conservative. This
         --  prevents accidental clobbering of enabled attributes.

         if Has_Predicates (From_Typ) then
            Set_Has_Predicates (Typ);
         end if;

         if Present (Pred_Func) and then No (Predicate_Function (Typ)) then
            Set_Predicate_Function (Typ, Pred_Func);
         end if;
      end if;
   end Propagate_Predicate_Attributes;

   ---------------------------------------
   -- Record_Possible_Part_Of_Reference --
   ---------------------------------------

   procedure Record_Possible_Part_Of_Reference
     (Var_Id : Entity_Id;
      Ref    : Node_Id)
   is
      Encap : constant Entity_Id := Encapsulating_State (Var_Id);
      Refs  : Elist_Id;

   begin
      --  The variable is a constituent of a single protected/task type. Such
      --  a variable acts as a component of the type and must appear within a
      --  specific region (SPARK RM 9(3)). Instead of recording the reference,
      --  verify its legality now.

      if Present (Encap) and then Is_Single_Concurrent_Object (Encap) then
         Check_Part_Of_Reference (Var_Id, Ref);

      --  The variable is subject to pragma Part_Of and may eventually become a
      --  constituent of a single protected/task type. Record the reference to
      --  verify its placement when the contract of the variable is analyzed.

      elsif Present (Get_Pragma (Var_Id, Pragma_Part_Of)) then
         Refs := Part_Of_References (Var_Id);

         if No (Refs) then
            Refs := New_Elmt_List;
            Set_Part_Of_References (Var_Id, Refs);
         end if;

         Append_Elmt (Ref, Refs);
      end if;
   end Record_Possible_Part_Of_Reference;

   ----------------
   -- Referenced --
   ----------------

   function Referenced (Id : Entity_Id; Expr : Node_Id) return Boolean is
      Seen : Boolean := False;

      function Is_Reference (N : Node_Id) return Traverse_Result;
      --  Determine whether node N denotes a reference to Id. If this is the
      --  case, set global flag Seen to True and stop the traversal.

      ------------------
      -- Is_Reference --
      ------------------

      function Is_Reference (N : Node_Id) return Traverse_Result is
      begin
         if Is_Entity_Name (N)
           and then Present (Entity (N))
           and then Entity (N) = Id
         then
            Seen := True;
            return Abandon;
         else
            return OK;
         end if;
      end Is_Reference;

      procedure Inspect_Expression is new Traverse_Proc (Is_Reference);

   --  Start of processing for Referenced

   begin
      Inspect_Expression (Expr);
      return Seen;
   end Referenced;

   ------------------------------------
   -- References_Generic_Formal_Type --
   ------------------------------------

   function References_Generic_Formal_Type (N : Node_Id) return Boolean is

      function Process (N : Node_Id) return Traverse_Result;
      --  Process one node in search for generic formal type

      -------------
      -- Process --
      -------------

      function Process (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) in N_Has_Entity then
            declare
               E : constant Entity_Id := Entity (N);
            begin
               if Present (E) then
                  if Is_Generic_Type (E) then
                     return Abandon;
                  elsif Present (Etype (E))
                    and then Is_Generic_Type (Etype (E))
                  then
                     return Abandon;
                  end if;
               end if;
            end;
         end if;

         return Atree.OK;
      end Process;

      function Traverse is new Traverse_Func (Process);
      --  Traverse tree to look for generic type

   begin
      if Inside_A_Generic then
         return Traverse (N) = Abandon;
      else
         return False;
      end if;
   end References_Generic_Formal_Type;

   -------------------------------
   -- Remove_Entity_And_Homonym --
   -------------------------------

   procedure Remove_Entity_And_Homonym (Id : Entity_Id) is
   begin
      Remove_Entity (Id);
      Remove_Homonym (Id);
   end Remove_Entity_And_Homonym;

   --------------------
   -- Remove_Homonym --
   --------------------

   procedure Remove_Homonym (Id : Entity_Id) is
      Hom  : Entity_Id;
      Prev : Entity_Id := Empty;

   begin
      if Id = Current_Entity (Id) then
         if Present (Homonym (Id)) then
            Set_Current_Entity (Homonym (Id));
         else
            Set_Name_Entity_Id (Chars (Id), Empty);
         end if;

      else
         Hom := Current_Entity (Id);
         while Present (Hom) and then Hom /= Id loop
            Prev := Hom;
            Hom  := Homonym (Hom);
         end loop;

         --  If Id is not on the homonym chain, nothing to do

         if Present (Hom) then
            Set_Homonym (Prev, Homonym (Id));
         end if;
      end if;
   end Remove_Homonym;

   ------------------------------
   -- Remove_Overloaded_Entity --
   ------------------------------

   procedure Remove_Overloaded_Entity (Id : Entity_Id) is
      procedure Remove_Primitive_Of (Typ : Entity_Id);
      --  Remove primitive subprogram Id from the list of primitives that
      --  belong to type Typ.

      -------------------------
      -- Remove_Primitive_Of --
      -------------------------

      procedure Remove_Primitive_Of (Typ : Entity_Id) is
         Prims : Elist_Id;

      begin
         if Is_Tagged_Type (Typ) then
            Prims := Direct_Primitive_Operations (Typ);

            if Present (Prims) then
               Remove (Prims, Id);
            end if;
         end if;
      end Remove_Primitive_Of;

      --  Local variables

      Formal : Entity_Id;

   --  Start of processing for Remove_Overloaded_Entity

   begin
      Remove_Entity_And_Homonym (Id);

      --  The entity denotes a primitive subprogram. Remove it from the list of
      --  primitives of the associated controlling type.

      if Ekind (Id) in E_Function | E_Procedure and then Is_Primitive (Id) then
         Formal := First_Formal (Id);
         while Present (Formal) loop
            if Is_Controlling_Formal (Formal) then
               Remove_Primitive_Of (Etype (Formal));
               exit;
            end if;

            Next_Formal (Formal);
         end loop;

         if Ekind (Id) = E_Function and then Has_Controlling_Result (Id) then
            Remove_Primitive_Of (Etype (Id));
         end if;
      end if;
   end Remove_Overloaded_Entity;

   ---------------------
   -- Rep_To_Pos_Flag --
   ---------------------

   function Rep_To_Pos_Flag (E : Entity_Id; Loc : Source_Ptr) return Node_Id is
   begin
      return New_Occurrence_Of
               (Boolean_Literals (not Range_Checks_Suppressed (E)), Loc);
   end Rep_To_Pos_Flag;

   --------------------
   -- Require_Entity --
   --------------------

   procedure Require_Entity (N : Node_Id) is
   begin
      if Is_Entity_Name (N) and then No (Entity (N)) then
         if Total_Errors_Detected /= 0 then
            Set_Entity (N, Any_Id);
         else
            raise Program_Error;
         end if;
      end if;
   end Require_Entity;

   ------------------------------
   -- Requires_Transient_Scope --
   ------------------------------

   function Requires_Transient_Scope (Typ : Entity_Id) return Boolean is
   begin
      return Needs_Secondary_Stack (Typ) or else Needs_Finalization (Typ);
   end Requires_Transient_Scope;

   --------------------------
   -- Reset_Analyzed_Flags --
   --------------------------

   procedure Reset_Analyzed_Flags (N : Node_Id) is
      function Clear_Analyzed (N : Node_Id) return Traverse_Result;
      --  Function used to reset Analyzed flags in tree. Note that we do
      --  not reset Analyzed flags in entities, since there is no need to
      --  reanalyze entities, and indeed, it is wrong to do so, since it
      --  can result in generating auxiliary stuff more than once.

      --------------------
      -- Clear_Analyzed --
      --------------------

      function Clear_Analyzed (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) not in N_Entity then
            Set_Analyzed (N, False);
         end if;

         return OK;
      end Clear_Analyzed;

      procedure Reset_Analyzed is new Traverse_Proc (Clear_Analyzed);

   --  Start of processing for Reset_Analyzed_Flags

   begin
      Reset_Analyzed (N);
   end Reset_Analyzed_Flags;

   ------------------------
   -- Restore_SPARK_Mode --
   ------------------------

   procedure Restore_SPARK_Mode
     (Mode : SPARK_Mode_Type;
      Prag : Node_Id)
   is
   begin
      SPARK_Mode        := Mode;
      SPARK_Mode_Pragma := Prag;
   end Restore_SPARK_Mode;

   --------------------------------
   -- Returns_Unconstrained_Type --
   --------------------------------

   function Returns_Unconstrained_Type (Subp : Entity_Id) return Boolean is
   begin
      return Ekind (Subp) = E_Function
        and then not Is_Scalar_Type (Etype (Subp))
        and then not Is_Access_Type (Etype (Subp))
        and then not Is_Constrained (Etype (Subp));
   end Returns_Unconstrained_Type;

   ----------------------------
   -- Root_Type_Of_Full_View --
   ----------------------------

   function Root_Type_Of_Full_View (T : Entity_Id) return Entity_Id is
      Rtyp : constant Entity_Id := Root_Type (T);

   begin
      --  The root type of the full view may itself be a private type. Keep
      --  looking for the ultimate derivation parent.

      if Is_Private_Type (Rtyp) and then Present (Full_View (Rtyp)) then
         return Root_Type_Of_Full_View (Full_View (Rtyp));
      else
         return Rtyp;
      end if;
   end Root_Type_Of_Full_View;

   ---------------------------
   -- Safe_To_Capture_Value --
   ---------------------------

   function Safe_To_Capture_Value
     (N    : Node_Id;
      Ent  : Entity_Id;
      Cond : Boolean := False) return Boolean
   is
   begin
      --  The only entities for which we track constant values are variables
      --  that are not renamings, constants and formal parameters, so check
      --  if we have this case.

      --  Note: it may seem odd to track constant values for constants, but in
      --  fact this routine is used for other purposes than simply capturing
      --  the value. In particular, the setting of Known[_Non]_Null and
      --  Is_Known_Valid.

      if (Ekind (Ent) = E_Variable and then No (Renamed_Object (Ent)))
           or else
         Ekind (Ent) = E_Constant
           or else
         Is_Formal (Ent)
      then
         null;

      --  For conditionals, we also allow loop parameters

      elsif Cond and then Ekind (Ent) = E_Loop_Parameter then
         null;

      --  For all other cases, not just unsafe, but impossible to capture
      --  Current_Value, since the above are the only entities which have
      --  Current_Value fields.

      else
         return False;
      end if;

      --  Skip if volatile or aliased, since funny things might be going on in
      --  these cases which we cannot necessarily track. Also skip any variable
      --  for which an address clause is given, or whose address is taken. Also
      --  never capture value of library level variables (an attempt to do so
      --  can occur in the case of package elaboration code).

      if Treat_As_Volatile (Ent)
        or else Is_Aliased (Ent)
        or else Present (Address_Clause (Ent))
        or else Address_Taken (Ent)
        or else (Is_Library_Level_Entity (Ent)
                  and then Ekind (Ent) = E_Variable)
      then
         return False;
      end if;

      --  OK, all above conditions are met. We also require that the scope of
      --  the reference be the same as the scope of the entity, not counting
      --  packages and blocks and loops.

      declare
         E_Scope : constant Entity_Id := Scope (Ent);
         R_Scope : Entity_Id;

      begin
         R_Scope := Current_Scope;
         while R_Scope /= Standard_Standard loop
            exit when R_Scope = E_Scope;

            if Ekind (R_Scope) not in E_Package | E_Block | E_Loop then
               return False;
            else
               R_Scope := Scope (R_Scope);
            end if;
         end loop;
      end;

      --  We also require that the reference does not appear in a context
      --  where it is not sure to be executed (i.e. a conditional context
      --  or an exception handler). We skip this if Cond is True, since the
      --  capturing of values from conditional tests handles this ok.

      if Cond or else No (N) then
         return True;
      end if;

      declare
         Desc : Node_Id;
         P    : Node_Id;

      begin
         Desc := N;

         --  Seems dubious that case expressions are not handled here ???

         P := Parent (N);
         while Present (P) loop
            if Is_Body (P) then
               return True;

            elsif      Nkind (P) = N_If_Statement
              or else  Nkind (P) = N_Case_Statement
              or else (Nkind (P) in N_Short_Circuit
                        and then Desc = Right_Opnd (P))
              or else (Nkind (P) = N_If_Expression
                        and then Desc /= First (Expressions (P)))
              or else  Nkind (P) = N_Exception_Handler
              or else  Nkind (P) = N_Selective_Accept
              or else  Nkind (P) = N_Conditional_Entry_Call
              or else  Nkind (P) = N_Timed_Entry_Call
              or else  Nkind (P) = N_Asynchronous_Select
            then
               return False;

            else
               Desc := P;
               P := Parent (P);

               --  A special Ada 2012 case: the original node may be part
               --  of the else_actions of a conditional expression, in which
               --  case it might not have been expanded yet, and appears in
               --  a non-syntactic list of actions. In that case it is clearly
               --  not safe to save a value.

               if No (P)
                 and then Is_List_Member (Desc)
                 and then No (Parent (List_Containing (Desc)))
               then
                  return False;
               end if;
            end if;
         end loop;
      end;

      --  OK, looks safe to set value

      return True;
   end Safe_To_Capture_Value;

   ---------------
   -- Same_Name --
   ---------------

   function Same_Name (N1, N2 : Node_Id) return Boolean is
      K1 : constant Node_Kind := Nkind (N1);
      K2 : constant Node_Kind := Nkind (N2);

   begin
      if (K1 = N_Identifier or else K1 = N_Defining_Identifier)
        and then (K2 = N_Identifier or else K2 = N_Defining_Identifier)
      then
         return Chars (N1) = Chars (N2);

      elsif (K1 = N_Selected_Component or else K1 = N_Expanded_Name)
        and then (K2 = N_Selected_Component or else K2 = N_Expanded_Name)
      then
         return Same_Name (Selector_Name (N1), Selector_Name (N2))
           and then Same_Name (Prefix (N1), Prefix (N2));

      else
         return False;
      end if;
   end Same_Name;

   -----------------
   -- Same_Object --
   -----------------

   function Same_Object (Node1, Node2 : Node_Id) return Boolean is
      N1 : constant Node_Id := Original_Node (Node1);
      N2 : constant Node_Id := Original_Node (Node2);
      --  We do the tests on original nodes, since we are most interested
      --  in the original source, not any expansion that got in the way.

      K1 : constant Node_Kind := Nkind (N1);
      K2 : constant Node_Kind := Nkind (N2);

   begin
      --  First case, both are entities with same entity

      if K1 in N_Has_Entity and then K2 in N_Has_Entity then
         declare
            EN1 : constant Entity_Id := Entity (N1);
            EN2 : constant Entity_Id := Entity (N2);
         begin
            if Present (EN1) and then Present (EN2)
              and then (Ekind (EN1) in E_Variable | E_Constant
                         or else Is_Formal (EN1))
              and then EN1 = EN2
            then
               return True;
            end if;
         end;
      end if;

      --  Second case, selected component with same selector, same record

      if K1 = N_Selected_Component
        and then K2 = N_Selected_Component
        and then Chars (Selector_Name (N1)) = Chars (Selector_Name (N2))
      then
         return Same_Object (Prefix (N1), Prefix (N2));

      --  Third case, indexed component with same subscripts, same array

      elsif K1 = N_Indexed_Component
        and then K2 = N_Indexed_Component
        and then Same_Object (Prefix (N1), Prefix (N2))
      then
         declare
            E1, E2 : Node_Id;
         begin
            E1 := First (Expressions (N1));
            E2 := First (Expressions (N2));
            while Present (E1) loop
               if not Same_Value (E1, E2) then
                  return False;
               else
                  Next (E1);
                  Next (E2);
               end if;
            end loop;

            return True;
         end;

      --  Fourth case, slice of same array with same bounds

      elsif K1 = N_Slice
        and then K2 = N_Slice
        and then Nkind (Discrete_Range (N1)) = N_Range
        and then Nkind (Discrete_Range (N2)) = N_Range
        and then Same_Value (Low_Bound (Discrete_Range (N1)),
                             Low_Bound (Discrete_Range (N2)))
        and then Same_Value (High_Bound (Discrete_Range (N1)),
                             High_Bound (Discrete_Range (N2)))
      then
         return Same_Name (Prefix (N1), Prefix (N2));

      --  All other cases, not clearly the same object

      else
         return False;
      end if;
   end Same_Object;

   ---------------------------------
   -- Same_Or_Aliased_Subprograms --
   ---------------------------------

   function Same_Or_Aliased_Subprograms
     (S : Entity_Id;
      E : Entity_Id) return Boolean
   is
      Subp_Alias : constant Entity_Id := Alias (S);
      Subp       : Entity_Id := E;
   begin
      --  During expansion of subprograms with postconditions the original
      --  subprogram's declarations and statements get wrapped into a local
      --  _Wrapped_Statements subprogram.

      if Chars (Subp) = Name_uWrapped_Statements then
         Subp := Enclosing_Subprogram (Subp);
      end if;

      return S = Subp
        or else (Present (Subp_Alias) and then Subp_Alias = Subp);
   end Same_Or_Aliased_Subprograms;

   ---------------
   -- Same_Type --
   ---------------

   function Same_Type (T1, T2 : Entity_Id) return Boolean is
   begin
      if T1 = T2 then
         return True;

      elsif not Is_Constrained (T1)
        and then not Is_Constrained (T2)
        and then Base_Type (T1) = Base_Type (T2)
      then
         return True;

      --  For now don't bother with case of identical constraints, to be
      --  fiddled with later on perhaps (this is only used for optimization
      --  purposes, so it is not critical to do a best possible job)

      else
         return False;
      end if;
   end Same_Type;

   ----------------
   -- Same_Value --
   ----------------

   function Same_Value (Node1, Node2 : Node_Id) return Boolean is
   begin
      if Compile_Time_Known_Value (Node1)
        and then Compile_Time_Known_Value (Node2)
      then
         --  Handle properly compile-time expressions that are not
         --  scalar.

         if Is_String_Type (Etype (Node1)) then
            return Expr_Value_S (Node1) = Expr_Value_S (Node2);

         else
            return Expr_Value (Node1) = Expr_Value (Node2);
         end if;

      elsif Same_Object (Node1, Node2) then
         return True;
      else
         return False;
      end if;
   end Same_Value;

   --------------------
   -- Set_SPARK_Mode --
   --------------------

   procedure Set_SPARK_Mode (Context : Entity_Id) is
   begin
      --  Do not consider illegal or partially decorated constructs

      if Ekind (Context) = E_Void or else Error_Posted (Context) then
         null;

      elsif Present (SPARK_Pragma (Context)) then
         Install_SPARK_Mode
           (Mode => Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Context)),
            Prag => SPARK_Pragma (Context));
      end if;
   end Set_SPARK_Mode;

   -------------------------
   -- Scalar_Part_Present --
   -------------------------

   function Scalar_Part_Present (Typ : Entity_Id) return Boolean is
      Val_Typ : constant Entity_Id := Validated_View (Typ);
      Field   : Entity_Id;

   begin
      if Is_Scalar_Type (Val_Typ) then
         return True;

      elsif Is_Array_Type (Val_Typ) then
         return Scalar_Part_Present (Component_Type (Val_Typ));

      elsif Is_Record_Type (Val_Typ) then
         Field := First_Component_Or_Discriminant (Val_Typ);
         while Present (Field) loop
            if Scalar_Part_Present (Etype (Field)) then
               return True;
            end if;

            Next_Component_Or_Discriminant (Field);
         end loop;
      end if;

      return False;
   end Scalar_Part_Present;

   ------------------------
   -- Scope_Is_Transient --
   ------------------------

   function Scope_Is_Transient return Boolean is
   begin
      return Scope_Stack.Table (Scope_Stack.Last).Is_Transient;
   end Scope_Is_Transient;

   ------------------
   -- Scope_Within --
   ------------------

   function Scope_Within
     (Inner : Entity_Id;
      Outer : Entity_Id) return Boolean
   is
      Curr : Entity_Id;

   begin
      Curr := Inner;
      while Present (Curr) and then Curr /= Standard_Standard loop
         Curr := Scope (Curr);

         if Curr = Outer then
            return True;

         --  A selective accept body appears within a task type, but the
         --  enclosing subprogram is the procedure of the task body.

         elsif Ekind (Implementation_Base_Type (Curr)) = E_Task_Type
           and then
             Outer = Task_Body_Procedure (Implementation_Base_Type (Curr))
         then
            return True;

         --  Ditto for the body of a protected operation

         elsif Is_Subprogram (Curr)
           and then Outer = Protected_Body_Subprogram (Curr)
         then
            return True;

         --  The body of a protected operation is within the protected type

         elsif Is_Subprogram (Curr)
           and then Present (Protected_Subprogram (Curr))
           and then Is_Protected_Type (Outer)
           and then Scope (Protected_Subprogram (Curr)) = Outer
         then
            return True;

         --  Outside of its scope, a synchronized type may just be private

         elsif Is_Private_Type (Curr)
           and then Present (Full_View (Curr))
           and then Is_Concurrent_Type (Full_View (Curr))
         then
            return Scope_Within (Full_View (Curr), Outer);
         end if;
      end loop;

      return False;
   end Scope_Within;

   --------------------------
   -- Scope_Within_Or_Same --
   --------------------------

   function Scope_Within_Or_Same
     (Inner : Entity_Id;
      Outer : Entity_Id) return Boolean
   is
      Curr : Entity_Id := Inner;

   begin
      --  Similar to the above, but check for scope identity first

      while Present (Curr) and then Curr /= Standard_Standard loop
         if Curr = Outer then
            return True;

         elsif Ekind (Implementation_Base_Type (Curr)) = E_Task_Type
           and then
             Outer = Task_Body_Procedure (Implementation_Base_Type (Curr))
         then
            return True;

         elsif Is_Subprogram (Curr)
           and then Outer = Protected_Body_Subprogram (Curr)
         then
            return True;

         elsif Is_Subprogram (Curr)
           and then Present (Protected_Subprogram (Curr))
           and then Is_Protected_Type (Outer)
           and then Scope (Protected_Subprogram (Curr)) = Outer
         then
            return True;

         elsif Is_Private_Type (Curr)
           and then Present (Full_View (Curr))
         then
            if Full_View (Curr) = Outer then
               return True;
            else
               return Scope_Within (Full_View (Curr), Outer);
            end if;
         end if;

         Curr := Scope (Curr);
      end loop;

      return False;
   end Scope_Within_Or_Same;

   ------------------------
   -- Set_Current_Entity --
   ------------------------

   --  The given entity is to be set as the currently visible definition of its
   --  associated name (i.e. the Node_Id associated with its name). All we have
   --  to do is to get the name from the identifier, and then set the
   --  associated Node_Id to point to the given entity.

   procedure Set_Current_Entity (E : Entity_Id) is
   begin
      Set_Name_Entity_Id (Chars (E), E);
   end Set_Current_Entity;

   ---------------------------
   -- Set_Debug_Info_Needed --
   ---------------------------

   procedure Set_Debug_Info_Needed (T : Entity_Id) is

      procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id);
      pragma Inline (Set_Debug_Info_Needed_If_Not_Set);
      --  Used to set debug info in a related node if not set already

      --------------------------------------
      -- Set_Debug_Info_Needed_If_Not_Set --
      --------------------------------------

      procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id) is
      begin
         if Present (E) and then not Needs_Debug_Info (E) then
            Set_Debug_Info_Needed (E);

            --  For a private type, indicate that the full view also needs
            --  debug information.

            if Is_Type (E)
              and then Is_Private_Type (E)
              and then Present (Full_View (E))
            then
               Set_Debug_Info_Needed (Full_View (E));
            end if;
         end if;
      end Set_Debug_Info_Needed_If_Not_Set;

   --  Start of processing for Set_Debug_Info_Needed

   begin
      --  Nothing to do if there is no available entity

      if No (T) then
         return;

      --  Nothing to do for an entity with suppressed debug information

      elsif Debug_Info_Off (T) then
         return;

      --  Nothing to do for an ignored Ghost entity because the entity will be
      --  eliminated from the tree.

      elsif Is_Ignored_Ghost_Entity (T) then
         return;

      --  Nothing to do if entity comes from a predefined file. Library files
      --  are compiled without debug information, but inlined bodies of these
      --  routines may appear in user code, and debug information on them ends
      --  up complicating debugging the user code.

      elsif In_Inlined_Body and then In_Predefined_Unit (T) then
         Set_Needs_Debug_Info (T, False);
      end if;

      --  Set flag in entity itself. Note that we will go through the following
      --  circuitry even if the flag is already set on T. That's intentional,
      --  it makes sure that the flag will be set in subsidiary entities.

      Set_Needs_Debug_Info (T);

      --  Set flag on subsidiary entities if not set already

      if Is_Object (T) then
         Set_Debug_Info_Needed_If_Not_Set (Etype (T));

      elsif Is_Type (T) then
         Set_Debug_Info_Needed_If_Not_Set (Etype (T));

         if Is_Record_Type (T) then
            declare
               Ent : Entity_Id := First_Entity (T);
            begin
               while Present (Ent) loop
                  Set_Debug_Info_Needed_If_Not_Set (Ent);
                  Next_Entity (Ent);
               end loop;
            end;

            --  For a class wide subtype, we also need debug information
            --  for the equivalent type.

            if Ekind (T) = E_Class_Wide_Subtype then
               Set_Debug_Info_Needed_If_Not_Set (Equivalent_Type (T));
            end if;

         elsif Is_Array_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Component_Type (T));

            declare
               Indx : Node_Id := First_Index (T);
            begin
               while Present (Indx) loop
                  Set_Debug_Info_Needed_If_Not_Set (Etype (Indx));
                  Next_Index (Indx);
               end loop;
            end;

            --  For a packed array type, we also need debug information for
            --  the type used to represent the packed array. Conversely, we
            --  also need it for the former if we need it for the latter.

            if Is_Packed (T) then
               Set_Debug_Info_Needed_If_Not_Set (Packed_Array_Impl_Type (T));
            end if;

            if Is_Packed_Array_Impl_Type (T) then
               Set_Debug_Info_Needed_If_Not_Set (Original_Array_Type (T));
            end if;

         elsif Is_Access_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Directly_Designated_Type (T));

         elsif Is_Private_Type (T) then
            declare
               FV : constant Entity_Id := Full_View (T);

            begin
               Set_Debug_Info_Needed_If_Not_Set (FV);

               --  If the full view is itself a derived private type, we need
               --  debug information on its underlying type.

               if Present (FV)
                 and then Is_Private_Type (FV)
                 and then Present (Underlying_Full_View (FV))
               then
                  Set_Needs_Debug_Info (Underlying_Full_View (FV));
               end if;
            end;

         elsif Is_Protected_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Corresponding_Record_Type (T));

         elsif Is_Scalar_Type (T) then

            --  If the subrange bounds are materialized by dedicated constant
            --  objects, also include them in the debug info to make sure the
            --  debugger can properly use them.

            if Present (Scalar_Range (T))
              and then Nkind (Scalar_Range (T)) = N_Range
            then
               declare
                  Low_Bnd  : constant Node_Id := Type_Low_Bound (T);
                  High_Bnd : constant Node_Id := Type_High_Bound (T);

               begin
                  if Is_Entity_Name (Low_Bnd) then
                     Set_Debug_Info_Needed_If_Not_Set (Entity (Low_Bnd));
                  end if;

                  if Is_Entity_Name (High_Bnd) then
                     Set_Debug_Info_Needed_If_Not_Set (Entity (High_Bnd));
                  end if;
               end;
            end if;
         end if;
      end if;
   end Set_Debug_Info_Needed;

   --------------------------------
   -- Set_Debug_Info_Defining_Id --
   --------------------------------

   procedure Set_Debug_Info_Defining_Id (N : Node_Id) is
   begin
      if Comes_From_Source (Defining_Identifier (N))
        or else Debug_Generated_Code
      then
         Set_Debug_Info_Needed (Defining_Identifier (N));
      end if;
   end Set_Debug_Info_Defining_Id;

   ----------------------------
   -- Set_Entity_With_Checks --
   ----------------------------

   procedure Set_Entity_With_Checks (N : Node_Id; Val : Entity_Id) is
      Val_Actual : Entity_Id;
      Nod        : Node_Id;
      Post_Node  : Node_Id;

   begin
      --  Unconditionally set the entity

      Set_Entity (N, Val);

      --  The node to post on is the selector in the case of an expanded name,
      --  and otherwise the node itself.

      if Nkind (N) = N_Expanded_Name then
         Post_Node := Selector_Name (N);
      else
         Post_Node := N;
      end if;

      --  Check for violation of No_Fixed_IO

      if Restriction_Check_Required (No_Fixed_IO)
        and then
          ((RTU_Loaded (Ada_Text_IO)
             and then (Is_RTE (Val, RE_Decimal_IO)
                         or else
                       Is_RTE (Val, RE_Fixed_IO)))

         or else
           (RTU_Loaded (Ada_Wide_Text_IO)
             and then (Is_RTE (Val, RO_WT_Decimal_IO)
                         or else
                       Is_RTE (Val, RO_WT_Fixed_IO)))

         or else
           (RTU_Loaded (Ada_Wide_Wide_Text_IO)
             and then (Is_RTE (Val, RO_WW_Decimal_IO)
                         or else
                       Is_RTE (Val, RO_WW_Fixed_IO))))

        --  A special extra check, don't complain about a reference from within
        --  the Ada.Interrupts package itself!

        and then not In_Same_Extended_Unit (N, Val)
      then
         Check_Restriction (No_Fixed_IO, Post_Node);
      end if;

      --  Remaining checks are only done on source nodes. Note that we test
      --  for violation of No_Fixed_IO even on non-source nodes, because the
      --  cases for checking violations of this restriction are instantiations
      --  where the reference in the instance has Comes_From_Source False.

      if not Comes_From_Source (N) then
         return;
      end if;

      --  Check for violation of No_Abort_Statements, which is triggered by
      --  call to Ada.Task_Identification.Abort_Task.

      if Restriction_Check_Required (No_Abort_Statements)
        and then Is_RTE (Val, RE_Abort_Task)

        --  A special extra check, don't complain about a reference from within
        --  the Ada.Task_Identification package itself!

        and then not In_Same_Extended_Unit (N, Val)
      then
         Check_Restriction (No_Abort_Statements, Post_Node);
      end if;

      if Val = Standard_Long_Long_Integer then
         Check_Restriction (No_Long_Long_Integers, Post_Node);
      end if;

      --  Check for violation of No_Dynamic_Attachment

      if Restriction_Check_Required (No_Dynamic_Attachment)
        and then RTU_Loaded (Ada_Interrupts)
        and then (Is_RTE (Val, RE_Is_Reserved)      or else
                  Is_RTE (Val, RE_Is_Attached)      or else
                  Is_RTE (Val, RE_Current_Handler)  or else
                  Is_RTE (Val, RE_Attach_Handler)   or else
                  Is_RTE (Val, RE_Exchange_Handler) or else
                  Is_RTE (Val, RE_Detach_Handler)   or else
                  Is_RTE (Val, RE_Reference))

        --  A special extra check, don't complain about a reference from within
        --  the Ada.Interrupts package itself!

        and then not In_Same_Extended_Unit (N, Val)
      then
         Check_Restriction (No_Dynamic_Attachment, Post_Node);
      end if;

      --  Check for No_Implementation_Identifiers

      if Restriction_Check_Required (No_Implementation_Identifiers) then

         --  We have an implementation defined entity if it is marked as
         --  implementation defined, or is defined in a package marked as
         --  implementation defined. However, library packages themselves
         --  are excluded (we don't want to flag Interfaces itself, just
         --  the entities within it).

         if (Is_Implementation_Defined (Val)
              or else
                (Present (Scope (Val))
                  and then Is_Implementation_Defined (Scope (Val))))
           and then not (Is_Package_Or_Generic_Package (Val)
                          and then Is_Library_Level_Entity (Val))
         then
            Check_Restriction (No_Implementation_Identifiers, Post_Node);
         end if;
      end if;

      --  Do the style check

      if Style_Check
        and then not Suppress_Style_Checks (Val)
        and then not In_Instance
      then
         if Nkind (N) = N_Identifier then
            Nod := N;
         elsif Nkind (N) = N_Expanded_Name then
            Nod := Selector_Name (N);
         else
            return;
         end if;

         --  A special situation arises for derived operations, where we want
         --  to do the check against the parent (since the Sloc of the derived
         --  operation points to the derived type declaration itself).

         Val_Actual := Val;
         while not Comes_From_Source (Val_Actual)
           and then Nkind (Val_Actual) in N_Entity
           and then (Ekind (Val_Actual) = E_Enumeration_Literal
                      or else Is_Subprogram_Or_Generic_Subprogram (Val_Actual))
           and then Present (Alias (Val_Actual))
         loop
            Val_Actual := Alias (Val_Actual);
         end loop;

         --  Renaming declarations for generic actuals do not come from source,
         --  and have a different name from that of the entity they rename, so
         --  there is no style check to perform here.

         if Chars (Nod) = Chars (Val_Actual) then
            Style.Check_Identifier (Nod, Val_Actual);
         end if;
      end if;
   end Set_Entity_With_Checks;

   ------------------------------
   -- Set_Invalid_Scalar_Value --
   ------------------------------

   procedure Set_Invalid_Scalar_Value
     (Scal_Typ : Float_Scalar_Id;
      Value    : Ureal)
   is
      Slot : Ureal renames Invalid_Floats (Scal_Typ);

   begin
      --  Detect an attempt to set a different value for the same scalar type

      pragma Assert (Slot = No_Ureal);
      Slot := Value;
   end Set_Invalid_Scalar_Value;

   ------------------------------
   -- Set_Invalid_Scalar_Value --
   ------------------------------

   procedure Set_Invalid_Scalar_Value
     (Scal_Typ : Integer_Scalar_Id;
      Value    : Uint)
   is
      Slot : Uint renames Invalid_Integers (Scal_Typ);

   begin
      --  Detect an attempt to set a different value for the same scalar type

      pragma Assert (No (Slot));
      Slot := Value;
   end Set_Invalid_Scalar_Value;

   ------------------------
   -- Set_Name_Entity_Id --
   ------------------------

   procedure Set_Name_Entity_Id (Id : Name_Id; Val : Entity_Id) is
   begin
      Set_Name_Table_Int (Id, Int (Val));
   end Set_Name_Entity_Id;

   ---------------------
   -- Set_Next_Actual --
   ---------------------

   procedure Set_Next_Actual (Ass1_Id : Node_Id; Ass2_Id : Node_Id) is
   begin
      if Nkind (Parent (Ass1_Id)) = N_Parameter_Association then
         Set_First_Named_Actual (Parent (Ass1_Id), Ass2_Id);
      end if;
   end Set_Next_Actual;

   ----------------------------------
   -- Set_Optimize_Alignment_Flags --
   ----------------------------------

   procedure Set_Optimize_Alignment_Flags (E : Entity_Id) is
   begin
      if Optimize_Alignment = 'S' then
         Set_Optimize_Alignment_Space (E);
      elsif Optimize_Alignment = 'T' then
         Set_Optimize_Alignment_Time (E);
      end if;
   end Set_Optimize_Alignment_Flags;

   -----------------------
   -- Set_Public_Status --
   -----------------------

   procedure Set_Public_Status (Id : Entity_Id) is
      S : constant Entity_Id := Current_Scope;

      function Within_HSS_Or_If (E : Entity_Id) return Boolean;
      --  Determines if E is defined within handled statement sequence or
      --  an if statement, returns True if so, False otherwise.

      ----------------------
      -- Within_HSS_Or_If --
      ----------------------

      function Within_HSS_Or_If (E : Entity_Id) return Boolean is
         N : Node_Id;
      begin
         N := Declaration_Node (E);
         loop
            N := Parent (N);

            if No (N) then
               return False;

            elsif Nkind (N) in
                    N_Handled_Sequence_Of_Statements | N_If_Statement
            then
               return True;
            end if;
         end loop;
      end Within_HSS_Or_If;

   --  Start of processing for Set_Public_Status

   begin
      --  Everything in the scope of Standard is public

      if S = Standard_Standard then
         Set_Is_Public (Id);

      --  Entity is definitely not public if enclosing scope is not public

      elsif not Is_Public (S) then
         return;

      --  An object or function declaration that occurs in a handled sequence
      --  of statements or within an if statement is the declaration for a
      --  temporary object or local subprogram generated by the expander. It
      --  never needs to be made public and furthermore, making it public can
      --  cause back end problems.

      elsif Nkind (Parent (Id)) in
              N_Object_Declaration | N_Function_Specification
        and then Within_HSS_Or_If (Id)
      then
         return;

      --  Entities in public packages or records are public

      elsif Ekind (S) = E_Package or Is_Record_Type (S) then
         Set_Is_Public (Id);

      --  The bounds of an entry family declaration can generate object
      --  declarations that are visible to the back-end, e.g. in the
      --  the declaration of a composite type that contains tasks.

      elsif Is_Concurrent_Type (S)
        and then not Has_Completion (S)
        and then Nkind (Parent (Id)) = N_Object_Declaration
      then
         Set_Is_Public (Id);
      end if;
   end Set_Public_Status;

   -----------------------------
   -- Set_Referenced_Modified --
   -----------------------------

   procedure Set_Referenced_Modified (N : Node_Id; Out_Param : Boolean) is
      Pref : Node_Id;

   begin
      --  Deal with indexed or selected component where prefix is modified

      if Nkind (N) in N_Indexed_Component | N_Selected_Component then
         Pref := Prefix (N);

         --  If prefix is access type, then it is the designated object that is
         --  being modified, which means we have no entity to set the flag on.

         if No (Etype (Pref)) or else Is_Access_Type (Etype (Pref)) then
            return;

            --  Otherwise chase the prefix

         else
            Set_Referenced_Modified (Pref, Out_Param);
         end if;

      --  Otherwise see if we have an entity name (only other case to process)

      elsif Is_Entity_Name (N) and then Present (Entity (N)) then
         Set_Referenced_As_LHS           (Entity (N), not Out_Param);
         Set_Referenced_As_Out_Parameter (Entity (N), Out_Param);
      end if;
   end Set_Referenced_Modified;

   ------------------
   -- Set_Rep_Info --
   ------------------

   procedure Set_Rep_Info (T1 : Entity_Id; T2 : Entity_Id) is
   begin
      Set_Is_Atomic               (T1, Is_Atomic (T2));
      Set_Is_Independent          (T1, Is_Independent (T2));
      Set_Is_Volatile_Full_Access (T1, Is_Volatile_Full_Access (T2));

      if Is_Base_Type (T1) then
         Set_Is_Volatile          (T1, Is_Volatile (T2));
      end if;
   end Set_Rep_Info;

   ----------------------------
   -- Set_Scope_Is_Transient --
   ----------------------------

   procedure Set_Scope_Is_Transient (V : Boolean := True) is
   begin
      Scope_Stack.Table (Scope_Stack.Last).Is_Transient := V;
   end Set_Scope_Is_Transient;

   -------------------
   -- Set_Size_Info --
   -------------------

   procedure Set_Size_Info (T1, T2 : Entity_Id) is
   begin
      --  We copy Esize, but not RM_Size, since in general RM_Size is
      --  subtype specific and does not get inherited by all subtypes.

      Copy_Esize (To => T1, From => T2);
      Set_Has_Biased_Representation (T1, Has_Biased_Representation (T2));

      if Is_Discrete_Or_Fixed_Point_Type (T1)
           and then
         Is_Discrete_Or_Fixed_Point_Type (T2)
      then
         Set_Is_Unsigned_Type       (T1, Is_Unsigned_Type          (T2));
      end if;

      Copy_Alignment (To => T1, From => T2);
   end Set_Size_Info;

   ------------------------------
   -- Should_Ignore_Pragma_Par --
   ------------------------------

   function Should_Ignore_Pragma_Par (Prag_Name : Name_Id) return Boolean is
      pragma Assert (Compiler_State = Parsing);
      --  This one can't work during semantic analysis, because we don't have a
      --  correct Current_Source_File.

      Result : constant Boolean :=
                 Get_Name_Table_Boolean3 (Prag_Name)
                   and then not Is_Internal_File_Name
                                  (File_Name (Current_Source_File));
   begin
      return Result;
   end Should_Ignore_Pragma_Par;

   ------------------------------
   -- Should_Ignore_Pragma_Sem --
   ------------------------------

   function Should_Ignore_Pragma_Sem (N : Node_Id) return Boolean is
      pragma Assert (Compiler_State = Analyzing);
      Prag_Name : constant Name_Id := Pragma_Name (N);
      Result    : constant Boolean :=
                    Get_Name_Table_Boolean3 (Prag_Name)
                      and then not In_Internal_Unit (N);

   begin
      return Result;
   end Should_Ignore_Pragma_Sem;

   --------------------
   -- Static_Boolean --
   --------------------

   function Static_Boolean (N : Node_Id) return Opt_Ubool is
   begin
      Analyze_And_Resolve (N, Standard_Boolean);

      if N = Error
        or else Error_Posted (N)
        or else Etype (N) = Any_Type
      then
         return No_Uint;
      end if;

      if Is_OK_Static_Expression (N) then
         if not Raises_Constraint_Error (N) then
            return Expr_Value (N);
         else
            return No_Uint;
         end if;

      elsif Etype (N) = Any_Type then
         return No_Uint;

      else
         Flag_Non_Static_Expr
           ("static boolean expression required here", N);
         return No_Uint;
      end if;
   end Static_Boolean;

   --------------------
   -- Static_Integer --
   --------------------

   function Static_Integer (N : Node_Id) return Uint is
   begin
      Analyze_And_Resolve (N, Any_Integer);

      if N = Error
        or else Error_Posted (N)
        or else Etype (N) = Any_Type
      then
         return No_Uint;
      end if;

      if Is_OK_Static_Expression (N) then
         if not Raises_Constraint_Error (N) then
            return Expr_Value (N);
         else
            return No_Uint;
         end if;

      elsif Etype (N) = Any_Type then
         return No_Uint;

      else
         Flag_Non_Static_Expr
           ("static integer expression required here", N);
         return No_Uint;
      end if;
   end Static_Integer;

   -------------------------------
   -- Statically_Denotes_Entity --
   -------------------------------

   function Statically_Denotes_Entity (N : Node_Id) return Boolean is
      E : Entity_Id;
   begin
      if not Is_Entity_Name (N) then
         return False;
      else
         E := Entity (N);
      end if;

      return
        Nkind (Parent (E)) /= N_Object_Renaming_Declaration
          or else Is_Prival (E)
          or else Statically_Denotes_Entity (Renamed_Object (E));
   end Statically_Denotes_Entity;

   -------------------------------
   -- Statically_Denotes_Object --
   -------------------------------

   function Statically_Denotes_Object (N : Node_Id) return Boolean is
   begin
      return Statically_Denotes_Entity (N)
         and then Is_Object_Reference (N);
   end Statically_Denotes_Object;

   --------------------------
   -- Statically_Different --
   --------------------------

   function Statically_Different (E1, E2 : Node_Id) return Boolean is
      R1 : constant Node_Id := Get_Referenced_Object (E1);
      R2 : constant Node_Id := Get_Referenced_Object (E2);
   begin
      return     Is_Entity_Name (R1)
        and then Is_Entity_Name (R2)
        and then Entity (R1) /= Entity (R2)
        and then not Is_Formal (Entity (R1))
        and then not Is_Formal (Entity (R2));
   end Statically_Different;

   -----------------------------
   -- Statically_Names_Object --
   -----------------------------

   function Statically_Names_Object (N : Node_Id) return Boolean is
   begin
      if Statically_Denotes_Object (N) then
         return True;
      elsif Is_Entity_Name (N) then
         declare
            E : constant Entity_Id := Entity (N);
         begin
            return Nkind (Parent (E)) = N_Object_Renaming_Declaration
              and then Statically_Names_Object (Renamed_Object (E));
         end;
      end if;

      case Nkind (N) is
         when N_Indexed_Component =>
            if Is_Access_Type (Etype (Prefix (N))) then
               --  treat implicit dereference same as explicit
               return False;
            end if;

            if not Is_Constrained (Etype (Prefix (N))) then
               return False;
            end if;

            declare
               Indx : Node_Id := First_Index (Etype (Prefix (N)));
               Expr : Node_Id := First (Expressions (N));
               Index_Subtype : Node_Id;
            begin
               loop
                  Index_Subtype := Etype (Indx);

                  if not Is_Static_Subtype (Index_Subtype) then
                     return False;
                  end if;
                  if not Is_OK_Static_Expression (Expr) then
                     return False;
                  end if;

                  declare
                     Index_Value : constant Uint := Expr_Value (Expr);
                     Low_Value   : constant Uint :=
                       Expr_Value (Type_Low_Bound (Index_Subtype));
                     High_Value   : constant Uint :=
                       Expr_Value (Type_High_Bound (Index_Subtype));
                  begin
                     if Index_Value < Low_Value
                       or Index_Value > High_Value
                     then
                        return False;
                     end if;
                  end;

                  Next_Index (Indx);
                  Expr := Next (Expr);
                  pragma Assert (Present (Indx) = Present (Expr)
                    or else Serious_Errors_Detected > 0);
                  exit when not (Present (Indx) and Present (Expr));
               end loop;
            end;

         when N_Selected_Component =>
            if Is_Access_Type (Etype (Prefix (N))) then
               --  treat implicit dereference same as explicit
               return False;
            end if;

            if Ekind (Entity (Selector_Name (N))) not in
                 E_Component | E_Discriminant
            then
               return False;
            end if;

            declare
               Comp : constant Entity_Id :=
                 Original_Record_Component (Entity (Selector_Name (N)));
            begin
              --  AI12-0373 confirms that we should not call
              --  Has_Discriminant_Dependent_Constraint here which would be
              --  too strong.

               if Is_Declared_Within_Variant (Comp) then
                  return False;
               end if;
            end;

         when others => -- includes N_Slice, N_Explicit_Dereference
            return False;
      end case;

      pragma Assert (Present (Prefix (N)));

      return Statically_Names_Object (Prefix (N));
   end Statically_Names_Object;

   ---------------------------------
   -- String_From_Numeric_Literal --
   ---------------------------------

   function String_From_Numeric_Literal (N : Node_Id) return String_Id is
      Loc     : constant Source_Ptr        := Sloc (N);
      Sbuffer : constant Source_Buffer_Ptr :=
                  Source_Text (Get_Source_File_Index (Loc));
      Src_Ptr : Source_Ptr := Loc;

      C : Character := Sbuffer (Src_Ptr);
      --  Current source program character

      function Belongs_To_Numeric_Literal (C : Character) return Boolean;
      --  Return True if C belongs to the numeric literal

      --------------------------------
      -- Belongs_To_Numeric_Literal --
      --------------------------------

      function Belongs_To_Numeric_Literal (C : Character) return Boolean is
      begin
         case C is
            when '0' .. '9' | '_' | '.' | 'e' | '#' | 'A' .. 'F' =>
               return True;

            --  Make sure '+' or '-' is part of an exponent

            when '+' | '-' =>
               declare
                  Prev_C : constant Character := Sbuffer (Src_Ptr - 1);
               begin
                  return Prev_C in 'e' | 'E';
               end;

            --  Other characters cannot belong to a numeric literal

            when others =>
               return False;
         end case;
      end Belongs_To_Numeric_Literal;

   --  Start of processing for String_From_Numeric_Literal

   begin
      Start_String;
      while Belongs_To_Numeric_Literal (C) loop
         Store_String_Char (C);
         Src_Ptr := Src_Ptr + 1;
         C       := Sbuffer (Src_Ptr);
      end loop;

      return End_String;
   end String_From_Numeric_Literal;

   --------------------------------------
   -- Subject_To_Loop_Entry_Attributes --
   --------------------------------------

   function Subject_To_Loop_Entry_Attributes (N : Node_Id) return Boolean is
      Stmt : Node_Id;

   begin
      Stmt := N;

      --  The expansion mechanism transform a loop subject to at least one
      --  'Loop_Entry attribute into a conditional block. Infinite loops lack
      --  the conditional part.

      if Nkind (Stmt) in N_Block_Statement | N_If_Statement
        and then Nkind (Original_Node (N)) = N_Loop_Statement
      then
         Stmt := Original_Node (N);
      end if;

      return
        Nkind (Stmt) = N_Loop_Statement
          and then Present (Identifier (Stmt))
          and then Present (Entity (Identifier (Stmt)))
          and then Has_Loop_Entry_Attributes (Entity (Identifier (Stmt)));
   end Subject_To_Loop_Entry_Attributes;

   ---------------------
   -- Subprogram_Name --
   ---------------------

   function Subprogram_Name (N : Node_Id) return String is
      Buf : Bounded_String;
      Ent : Node_Id := N;
      Nod : Node_Id;

   begin
      while Present (Ent) loop
         case Nkind (Ent) is
            when N_Subprogram_Body =>
               Ent := Defining_Unit_Name (Specification (Ent));
               exit;

            when N_Subprogram_Declaration =>
               Nod := Corresponding_Body (Ent);

               if Present (Nod) then
                  Ent := Nod;
               else
                  Ent := Defining_Unit_Name (Specification (Ent));
               end if;

               exit;

            when N_Subprogram_Instantiation
               | N_Package_Body
               | N_Package_Specification
            =>
               Ent := Defining_Unit_Name (Ent);
               exit;

            when N_Protected_Type_Declaration =>
               Ent := Corresponding_Body (Ent);
               exit;

            when N_Protected_Body
               | N_Task_Body
            =>
               Ent := Defining_Identifier (Ent);
               exit;

            when N_Entity =>
               exit;

            when others =>
               null;
         end case;

         Ent := Parent (Ent);
      end loop;

      if No (Ent) then
         return "unknown subprogram:unknown file:0:0";
      end if;

      --  If the subprogram is a child unit, use its simple name to start the
      --  construction of the fully qualified name.

      if Nkind (Ent) = N_Defining_Program_Unit_Name then
         Ent := Defining_Identifier (Ent);
      end if;

      Append_Entity_Name (Buf, Ent);

      --  Append homonym number if needed

      if Nkind (N) in N_Entity and then Has_Homonym (N) then
         declare
            H  : Entity_Id := Homonym (N);
            Nr : Nat := 1;

         begin
            while Present (H) loop
               if Scope (H) = Scope (N) then
                  Nr := Nr + 1;
               end if;

               H := Homonym (H);
            end loop;

            if Nr > 1 then
               Append (Buf, '#');
               Append (Buf, Nr);
            end if;
         end;
      end if;

      --  Append source location of Ent to Buf so that the string will
      --  look like "subp:file:line:col".

      declare
         Loc : constant Source_Ptr := Sloc (Ent);
      begin
         Append (Buf, ':');
         Append (Buf, Reference_Name (Get_Source_File_Index (Loc)));
         Append (Buf, ':');
         Append (Buf, Nat (Get_Logical_Line_Number (Loc)));
         Append (Buf, ':');
         Append (Buf, Nat (Get_Column_Number (Loc)));
      end;

      return +Buf;
   end Subprogram_Name;

   -------------------------------
   -- Support_Atomic_Primitives --
   -------------------------------

   function Support_Atomic_Primitives (Typ : Entity_Id) return Boolean is
      Size : Int;

   begin
      --  Verify the alignment of Typ is known

      if not Known_Alignment (Typ) then
         return False;
      end if;

      if Known_Static_Esize (Typ) then
         Size := UI_To_Int (Esize (Typ));

      --  If the Esize (Object_Size) is unknown at compile time, look at the
      --  RM_Size (Value_Size) which may have been set by an explicit rep item.

      elsif Known_Static_RM_Size (Typ) then
         Size := UI_To_Int (RM_Size (Typ));

      --  Otherwise, the size is considered to be unknown.

      else
         return False;
      end if;

      --  Check that the size of the component is 8, 16, 32, or 64 bits and
      --  that Typ is properly aligned.

      case Size is
         when 8 | 16 | 32 | 64 =>
            return Size = UI_To_Int (Alignment (Typ)) * 8;

         when others =>
            return False;
      end case;
   end Support_Atomic_Primitives;

   -----------------
   -- Trace_Scope --
   -----------------

   procedure Trace_Scope (N : Node_Id; E : Entity_Id; Msg : String) is
   begin
      if Debug_Flag_W then
         for J in 0 .. Scope_Stack.Last loop
            Write_Str ("  ");
         end loop;

         Write_Str (Msg);
         Write_Name (Chars (E));
         Write_Str (" from ");
         Write_Location (Sloc (N));
         Write_Eol;
      end if;
   end Trace_Scope;

   -----------------------
   -- Transfer_Entities --
   -----------------------

   procedure Transfer_Entities (From : Entity_Id; To : Entity_Id) is
      procedure Set_Public_Status_Of (Id : Entity_Id);
      --  Set the Is_Public attribute of arbitrary entity Id by calling routine
      --  Set_Public_Status. If successful and Id denotes a record type, set
      --  the Is_Public attribute of its fields.

      --------------------------
      -- Set_Public_Status_Of --
      --------------------------

      procedure Set_Public_Status_Of (Id : Entity_Id) is
         Field : Entity_Id;

      begin
         if not Is_Public (Id) then
            Set_Public_Status (Id);

            --  When the input entity is a public record type, ensure that all
            --  its internal fields are also exposed to the linker. The fields
            --  of a class-wide type are never made public.

            if Is_Public (Id)
              and then Is_Record_Type (Id)
              and then not Is_Class_Wide_Type (Id)
            then
               Field := First_Entity (Id);
               while Present (Field) loop
                  Set_Is_Public (Field);
                  Next_Entity (Field);
               end loop;
            end if;
         end if;
      end Set_Public_Status_Of;

      --  Local variables

      Full_Id : Entity_Id;
      Id      : Entity_Id;

   --  Start of processing for Transfer_Entities

   begin
      Id := First_Entity (From);

      if Present (Id) then

         --  Merge the entity chain of the source scope with that of the
         --  destination scope.

         if Present (Last_Entity (To)) then
            Link_Entities (Last_Entity (To), Id);
         else
            Set_First_Entity (To, Id);
         end if;

         Set_Last_Entity (To, Last_Entity (From));

         --  Inspect the entities of the source scope and update their Scope
         --  attribute.

         while Present (Id) loop
            Set_Scope            (Id, To);
            Set_Public_Status_Of (Id);

            --  Handle an internally generated full view for a private type

            if Is_Private_Type (Id)
              and then Present (Full_View (Id))
              and then Is_Itype (Full_View (Id))
            then
               Full_Id := Full_View (Id);

               Set_Scope            (Full_Id, To);
               Set_Public_Status_Of (Full_Id);
            end if;

            Next_Entity (Id);
         end loop;

         Set_First_Entity (From, Empty);
         Set_Last_Entity  (From, Empty);
      end if;
   end Transfer_Entities;

   ------------------------
   -- Traverse_More_Func --
   ------------------------

   function Traverse_More_Func (Node : Node_Id) return Traverse_Final_Result is

      Processing_Itype : Boolean := False;
      --  Set to True while traversing the nodes under an Itype, to prevent
      --  looping on Itype handling during that traversal.

      function Process_More (N : Node_Id) return Traverse_Result;
      --  Wrapper over the Process callback to handle parts of the AST that
      --  are not normally traversed as syntactic children.

      function Traverse_Rec (N : Node_Id) return Traverse_Final_Result;
      --  Main recursive traversal implemented as an instantiation of
      --  Traverse_Func over a modified Process callback.

      ------------------
      -- Process_More --
      ------------------

      function Process_More (N : Node_Id) return Traverse_Result is

         procedure Traverse_More (N   : Node_Id;
                                  Res : in out Traverse_Result);
         procedure Traverse_More (L   : List_Id;
                                  Res : in out Traverse_Result);
         --  Traverse a node or list and update the traversal result to value
         --  Abandon when needed.

         -------------------
         -- Traverse_More --
         -------------------

         procedure Traverse_More (N   : Node_Id;
                                  Res : in out Traverse_Result)
         is
         begin
            --  Do not process any more nodes if Abandon was reached

            if Res = Abandon then
               return;
            end if;

            if Traverse_Rec (N) = Abandon then
               Res := Abandon;
            end if;
         end Traverse_More;

         procedure Traverse_More (L   : List_Id;
                                  Res : in out Traverse_Result)
         is
            N : Node_Id := First (L);

         begin
            --  Do not process any more nodes if Abandon was reached

            if Res = Abandon then
               return;
            end if;

            while Present (N) loop
               Traverse_More (N, Res);
               Next (N);
            end loop;
         end Traverse_More;

         --  Local variables

         Node   : Node_Id;
         Result : Traverse_Result;

      --  Start of processing for Process_More

      begin
         --  Initial callback to Process. Return immediately on Skip/Abandon.
         --  Otherwise update the value of Node for further processing of
         --  non-syntactic children.

         Result := Process (N);

         case Result is
            when OK      => Node := N;
            when OK_Orig => Node := Original_Node (N);
            when Skip    => return Skip;
            when Abandon => return Abandon;
         end case;

         --  Process the relevant semantic children which are a logical part of
         --  the AST under this node before returning for the processing of
         --  syntactic children.

         --  Start with all non-syntactic lists of action nodes

         case Nkind (Node) is
            when N_Component_Association =>
               Traverse_More (Loop_Actions (Node),      Result);

            when N_Elsif_Part =>
               Traverse_More (Condition_Actions (Node), Result);

            when N_Short_Circuit =>
               Traverse_More (Actions (Node),           Result);

            when N_Case_Expression_Alternative =>
               Traverse_More (Actions (Node),           Result);

            when N_Iterated_Component_Association =>
               Traverse_More (Loop_Actions (Node),      Result);

            when N_Iterated_Element_Association =>
               Traverse_More (Loop_Actions (Node),      Result);

            when N_Iteration_Scheme =>
               Traverse_More (Condition_Actions (Node), Result);

            when N_If_Expression =>
               Traverse_More (Then_Actions (Node),      Result);
               Traverse_More (Else_Actions (Node),      Result);

            --  Various nodes have a field Actions as a syntactic node,
            --  so it will be traversed in the regular syntactic traversal.

            when N_Compilation_Unit_Aux
               | N_Compound_Statement
               | N_Expression_With_Actions
               | N_Freeze_Entity
            =>
               null;

            when others =>
               null;
         end case;

         --  If Process_Itypes is True, process unattached nodes which come
         --  from Itypes. This only concerns currently ranges of scalar
         --  (possibly as index) types. This traversal is protected against
         --  looping with Processing_Itype.

         if Process_Itypes
           and then not Processing_Itype
           and then Nkind (Node) in N_Has_Etype
           and then Present (Etype (Node))
           and then Is_Itype (Etype (Node))
         then
            declare
               Typ : constant Entity_Id := Etype (Node);
            begin
               Processing_Itype := True;

               case Ekind (Typ) is
                  when Scalar_Kind =>
                     Traverse_More (Scalar_Range (Typ), Result);

                  when Array_Kind =>
                     declare
                        Index : Node_Id := First_Index (Typ);
                        Rng   : Node_Id;
                     begin
                        while Present (Index) loop
                           if Nkind (Index) in N_Has_Entity then
                              Rng := Scalar_Range (Entity (Index));
                           else
                              Rng := Index;
                           end if;

                           Traverse_More (Rng,          Result);
                           Next_Index (Index);
                        end loop;
                     end;
                  when others =>
                     null;
               end case;

               Processing_Itype := False;
            end;
         end if;

         return Result;
      end Process_More;

      --  Define Traverse_Rec as a renaming of the instantiation, as an
      --  instantiation cannot complete a previous spec.

      function Traverse_Recursive is new Traverse_Func (Process_More);
      function Traverse_Rec (N : Node_Id) return Traverse_Final_Result
                             renames Traverse_Recursive;

   --  Start of processing for Traverse_More_Func

   begin
      return Traverse_Rec (Node);
   end Traverse_More_Func;

   ------------------------
   -- Traverse_More_Proc --
   ------------------------

   procedure Traverse_More_Proc (Node : Node_Id) is
      function Traverse is new Traverse_More_Func (Process, Process_Itypes);
      Discard : Traverse_Final_Result;
      pragma Warnings (Off, Discard);
   begin
      Discard := Traverse (Node);
   end Traverse_More_Proc;

   ------------------------------------
   -- Type_Without_Stream_Operation  --
   ------------------------------------

   function Type_Without_Stream_Operation
     (T  : Entity_Id;
      Op : TSS_Name_Type := TSS_Null) return Entity_Id
   is
      BT         : constant Entity_Id := Base_Type (T);
      Op_Missing : Boolean;

   begin
      if not Restriction_Active (No_Default_Stream_Attributes) then
         return Empty;
      end if;

      if Is_Elementary_Type (T) then
         if Op = TSS_Null then
            Op_Missing :=
              No (TSS (BT, TSS_Stream_Read))
                or else No (TSS (BT, TSS_Stream_Write));

         else
            Op_Missing := No (TSS (BT, Op));
         end if;

         if Op_Missing then
            return T;
         else
            return Empty;
         end if;

      elsif Is_Array_Type (T) then
         return Type_Without_Stream_Operation (Component_Type (T), Op);

      elsif Is_Record_Type (T) then
         declare
            Comp  : Entity_Id;
            C_Typ : Entity_Id;

         begin
            Comp := First_Component (T);
            while Present (Comp) loop
               C_Typ := Type_Without_Stream_Operation (Etype (Comp), Op);

               if Present (C_Typ) then
                  return C_Typ;
               end if;

               Next_Component (Comp);
            end loop;

            return Empty;
         end;

      elsif Is_Private_Type (T) and then Present (Full_View (T)) then
         return Type_Without_Stream_Operation (Full_View (T), Op);
      else
         return Empty;
      end if;
   end Type_Without_Stream_Operation;

   ------------------------------
   -- Ultimate_Overlaid_Entity --
   ------------------------------

   function Ultimate_Overlaid_Entity (E : Entity_Id) return Entity_Id is
      Address : Node_Id;
      Alias   : Entity_Id := E;
      Offset  : Boolean;

   begin
      --  Currently this routine is only called for stand-alone objects that
      --  have been analysed, since the analysis of the Address aspect is often
      --  delayed.

      pragma Assert (Ekind (E) in E_Constant | E_Variable);

      loop
         Address := Address_Clause (Alias);
         if Present (Address) then
            Find_Overlaid_Entity (Address, Alias, Offset);
            if Present (Alias) then
               null;
            else
               return Empty;
            end if;
         elsif Alias = E then
            return Empty;
         else
            return Alias;
         end if;
      end loop;
   end Ultimate_Overlaid_Entity;

   ---------------------
   -- Ultimate_Prefix --
   ---------------------

   function Ultimate_Prefix (N : Node_Id) return Node_Id is
      Pref : Node_Id;

   begin
      Pref := N;
      while Nkind (Pref) in N_Explicit_Dereference
                          | N_Indexed_Component
                          | N_Selected_Component
                          | N_Slice
      loop
         Pref := Prefix (Pref);
      end loop;

      return Pref;
   end Ultimate_Prefix;

   ----------------------------
   -- Unique_Defining_Entity --
   ----------------------------

   function Unique_Defining_Entity (N : Node_Id) return Entity_Id is
   begin
      return Unique_Entity (Defining_Entity (N));
   end Unique_Defining_Entity;

   -------------------
   -- Unique_Entity --
   -------------------

   function Unique_Entity (E : Entity_Id) return Entity_Id is
      U : Entity_Id := E;
      P : Node_Id;

   begin
      case Ekind (E) is
         when E_Constant =>
            if Present (Full_View (E)) then
               U := Full_View (E);
            end if;

         when Entry_Kind =>
            if Nkind (Parent (E)) = N_Entry_Body then
               declare
                  Prot_Item : Entity_Id;
                  Prot_Type : Entity_Id;

               begin
                  if Ekind (E) = E_Entry then
                     Prot_Type := Scope (E);

                  --  Bodies of entry families are nested within an extra scope
                  --  that contains an entry index declaration.

                  else
                     Prot_Type := Scope (Scope (E));
                  end if;

                  --  A protected type may be declared as a private type, in
                  --  which case we need to get its full view.

                  if Is_Private_Type (Prot_Type) then
                     Prot_Type := Full_View (Prot_Type);
                  end if;

                  --  Full view may not be present on error, in which case
                  --  return E by default.

                  if Present (Prot_Type) then
                     pragma Assert (Ekind (Prot_Type) = E_Protected_Type);

                     --  Traverse the entity list of the protected type and
                     --  locate an entry declaration which matches the entry
                     --  body.

                     Prot_Item := First_Entity (Prot_Type);
                     while Present (Prot_Item) loop
                        if Ekind (Prot_Item) in Entry_Kind
                          and then Corresponding_Body (Parent (Prot_Item)) = E
                        then
                           U := Prot_Item;
                           exit;
                        end if;

                        Next_Entity (Prot_Item);
                     end loop;
                  end if;
               end;
            end if;

         when Formal_Kind =>
            if Present (Spec_Entity (E)) then
               U := Spec_Entity (E);
            end if;

         when E_Package_Body =>
            P := Parent (E);

            if Nkind (P) = N_Defining_Program_Unit_Name then
               P := Parent (P);
            end if;

            if Nkind (P) = N_Package_Body
              and then Present (Corresponding_Spec (P))
            then
               U := Corresponding_Spec (P);

            elsif Nkind (P) = N_Package_Body_Stub
              and then Present (Corresponding_Spec_Of_Stub (P))
            then
               U := Corresponding_Spec_Of_Stub (P);
            end if;

         when E_Protected_Body =>
            P := Parent (E);

            if Nkind (P) = N_Protected_Body
              and then Present (Corresponding_Spec (P))
            then
               U := Corresponding_Spec (P);

            elsif Nkind (P) = N_Protected_Body_Stub
              and then Present (Corresponding_Spec_Of_Stub (P))
            then
               U := Corresponding_Spec_Of_Stub (P);

               if Is_Single_Protected_Object (U) then
                  U := Etype (U);
               end if;
            end if;

            if Is_Private_Type (U) then
               U := Full_View (U);
            end if;

         when E_Subprogram_Body =>
            P := Parent (E);

            if Nkind (P) = N_Defining_Program_Unit_Name then
               P := Parent (P);
            end if;

            P := Parent (P);

            if Nkind (P) = N_Subprogram_Body
              and then Present (Corresponding_Spec (P))
            then
               U := Corresponding_Spec (P);

            elsif Nkind (P) = N_Subprogram_Body_Stub
              and then Present (Corresponding_Spec_Of_Stub (P))
            then
               U := Corresponding_Spec_Of_Stub (P);

            elsif Nkind (P) = N_Subprogram_Renaming_Declaration then
               U := Corresponding_Spec (P);
            end if;

         when E_Task_Body =>
            P := Parent (E);

            if Nkind (P) = N_Task_Body
              and then Present (Corresponding_Spec (P))
            then
               U := Corresponding_Spec (P);

            elsif Nkind (P) = N_Task_Body_Stub
              and then Present (Corresponding_Spec_Of_Stub (P))
            then
               U := Corresponding_Spec_Of_Stub (P);

               if Is_Single_Task_Object (U) then
                  U := Etype (U);
               end if;
            end if;

            if Is_Private_Type (U) then
               U := Full_View (U);
            end if;

         when Type_Kind =>
            if Present (Full_View (E)) then
               U := Full_View (E);
            end if;

         when others =>
            null;
      end case;

      return U;
   end Unique_Entity;

   -----------------
   -- Unique_Name --
   -----------------

   function Unique_Name (E : Entity_Id) return String is

      --  Local subprograms

      function Add_Homonym_Suffix (E : Entity_Id) return String;

      function This_Name return String;

      ------------------------
      -- Add_Homonym_Suffix --
      ------------------------

      function Add_Homonym_Suffix (E : Entity_Id) return String is

         --  Names in E_Subprogram_Body or E_Package_Body entities are not
         --  reliable, as they may not include the overloading suffix.
         --  Instead, when looking for the name of E or one of its enclosing
         --  scope, we get the name of the corresponding Unique_Entity.

         U   : constant Entity_Id := Unique_Entity (E);
         Nam : constant String := Get_Name_String (Chars (U));

      begin
         --  If E has homonyms but is not fully qualified, as done in
         --  GNATprove mode, append the homonym number on the fly. Strip the
         --  leading space character in the image of natural numbers. Also do
         --  not print the homonym value of 1.

         if Has_Homonym (U) then
            declare
               N : constant Pos := Homonym_Number (U);
               S : constant String := N'Img;
            begin
               if N > 1 then
                  return Nam & "__" & S (2 .. S'Last);
               end if;
            end;
         end if;

         return Nam;
      end Add_Homonym_Suffix;

      ---------------
      -- This_Name --
      ---------------

      function This_Name return String is
      begin
         return Add_Homonym_Suffix (E);
      end This_Name;

      --  Local variables

      U : constant Entity_Id := Unique_Entity (E);

   --  Start of processing for Unique_Name

   begin
      if E = Standard_Standard
        or else Has_Fully_Qualified_Name (E)
      then
         return This_Name;

      elsif Ekind (E) = E_Enumeration_Literal then
         return Unique_Name (Etype (E)) & "__" & This_Name;

      else
         declare
            S : constant Entity_Id := Scope (U);
            pragma Assert (Present (S));

         begin
            --  Prefix names of predefined types with standard__, but leave
            --  names of user-defined packages and subprograms without prefix
            --  (even if technically they are nested in the Standard package).

            if S = Standard_Standard then
               if Ekind (U) = E_Package or else Is_Subprogram (U) then
                  return This_Name;
               else
                  return Unique_Name (S) & "__" & This_Name;
               end if;

            --  For intances of generic subprograms use the name of the related
            --  instance and skip the scope of its wrapper package.

            elsif Is_Wrapper_Package (S) then
               pragma Assert (Scope (S) = Scope (Related_Instance (S)));
               --  Wrapper package and the instantiation are in the same scope

               declare
                  Related_Name : constant String :=
                    Add_Homonym_Suffix (Related_Instance (S));
                  Enclosing_Name : constant String :=
                    Unique_Name (Scope (S)) & "__" & Related_Name;

               begin
                  if Is_Subprogram (U)
                    and then not Is_Generic_Actual_Subprogram (U)
                  then
                     return Enclosing_Name;
                  else
                     return Enclosing_Name & "__" & This_Name;
                  end if;
               end;

            elsif Is_Child_Unit (U) then
               return Child_Prefix & Unique_Name (S) & "__" & This_Name;
            else
               return Unique_Name (S) & "__" & This_Name;
            end if;
         end;
      end if;
   end Unique_Name;

   ---------------------
   -- Unit_Is_Visible --
   ---------------------

   function Unit_Is_Visible (U : Entity_Id) return Boolean is
      Curr        : constant Node_Id   := Cunit (Current_Sem_Unit);
      Curr_Entity : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);

      function Unit_In_Parent_Context (Par_Unit : Node_Id) return Boolean;
      --  For a child unit, check whether unit appears in a with_clause
      --  of a parent.

      function Unit_In_Context (Comp_Unit : Node_Id) return Boolean;
      --  Scan the context clause of one compilation unit looking for a
      --  with_clause for the unit in question.

      ----------------------------
      -- Unit_In_Parent_Context --
      ----------------------------

      function Unit_In_Parent_Context (Par_Unit : Node_Id) return Boolean is
      begin
         if Unit_In_Context (Par_Unit) then
            return True;

         elsif Is_Child_Unit (Defining_Entity (Unit (Par_Unit))) then
            return Unit_In_Parent_Context (Parent_Spec (Unit (Par_Unit)));

         else
            return False;
         end if;
      end Unit_In_Parent_Context;

      ---------------------
      -- Unit_In_Context --
      ---------------------

      function Unit_In_Context (Comp_Unit : Node_Id) return Boolean is
         Clause : Node_Id;

      begin
         Clause := First (Context_Items (Comp_Unit));
         while Present (Clause) loop
            if Nkind (Clause) = N_With_Clause then
               if Library_Unit (Clause) = U then
                  return True;

               --  The with_clause may denote a renaming of the unit we are
               --  looking for, eg. Text_IO which renames Ada.Text_IO.

               elsif
                 Renamed_Entity (Entity (Name (Clause))) =
                                                Defining_Entity (Unit (U))
               then
                  return True;
               end if;
            end if;

            Next (Clause);
         end loop;

         return False;
      end Unit_In_Context;

   --  Start of processing for Unit_Is_Visible

   begin
      --  The currrent unit is directly visible

      if Curr = U then
         return True;

      elsif Unit_In_Context (Curr) then
         return True;

      --  If the current unit is a body, check the context of the spec

      elsif Nkind (Unit (Curr)) = N_Package_Body
        or else
          (Nkind (Unit (Curr)) = N_Subprogram_Body
            and then not Acts_As_Spec (Unit (Curr)))
      then
         if Unit_In_Context (Library_Unit (Curr)) then
            return True;
         end if;
      end if;

      --  If the spec is a child unit, examine the parents

      if Is_Child_Unit (Curr_Entity) then
         if Nkind (Unit (Curr)) in N_Unit_Body then
            return
              Unit_In_Parent_Context
                (Parent_Spec (Unit (Library_Unit (Curr))));
         else
            return Unit_In_Parent_Context (Parent_Spec (Unit (Curr)));
         end if;

      else
         return False;
      end if;
   end Unit_Is_Visible;

   ------------------------------
   -- Universal_Interpretation --
   ------------------------------

   function Universal_Interpretation (Opnd : Node_Id) return Entity_Id is
      Index : Interp_Index;
      It    : Interp;

   begin
      --  The argument may be a formal parameter of an operator or subprogram
      --  with multiple interpretations, or else an expression for an actual.

      if Nkind (Opnd) = N_Defining_Identifier
        or else not Is_Overloaded (Opnd)
      then
         if Is_Universal_Numeric_Type (Etype (Opnd)) then
            return Etype (Opnd);
         else
            return Empty;
         end if;

      else
         Get_First_Interp (Opnd, Index, It);
         while Present (It.Typ) loop
            if Is_Universal_Numeric_Type (It.Typ) then
               return It.Typ;
            end if;

            Get_Next_Interp (Index, It);
         end loop;

         return Empty;
      end if;
   end Universal_Interpretation;

   ---------------
   -- Unqualify --
   ---------------

   function Unqualify (Expr : Node_Id) return Node_Id is
   begin
      --  Recurse to handle unlikely case of multiple levels of qualification

      if Nkind (Expr) = N_Qualified_Expression then
         return Unqualify (Expression (Expr));

      --  Normal case, not a qualified expression

      else
         return Expr;
      end if;
   end Unqualify;

   -----------------
   -- Unqual_Conv --
   -----------------

   function Unqual_Conv (Expr : Node_Id) return Node_Id is
   begin
      --  Recurse to handle unlikely case of multiple levels of qualification
      --  and/or conversion.

      if Nkind (Expr) in N_Qualified_Expression
                       | N_Type_Conversion
                       | N_Unchecked_Type_Conversion
      then
         return Unqual_Conv (Expression (Expr));

      --  Normal case, not a qualified expression

      else
         return Expr;
      end if;
   end Unqual_Conv;

   --------------------
   -- Validated_View --
   --------------------

   function Validated_View (Typ : Entity_Id) return Entity_Id is
   begin
      --  Scalar types can be always validated. In fast, switiching to the base
      --  type would drop the range constraints and force validation to use a
      --  larger type than necessary.

      if Is_Scalar_Type (Typ) then
         return Typ;

      --  Array types can be validated even when they are derived, because
      --  validation only requires their bounds and component types to be
      --  accessible. In fact, switching to the parent type would pollute
      --  expansion of attribute Valid_Scalars with unnecessary conversion
      --  that might not be eliminated by the frontend.

      elsif Is_Array_Type (Typ) then
         return Typ;

      --  For other types, in particular for record subtypes, we switch to the
      --  base type.

      elsif not Is_Base_Type (Typ) then
         return Validated_View (Base_Type (Typ));

      --  Obtain the full view of the input type by stripping away concurrency,
      --  derivations, and privacy.

      elsif Is_Concurrent_Type (Typ) then
         if Present (Corresponding_Record_Type (Typ)) then
            return Corresponding_Record_Type (Typ);
         else
            return Typ;
         end if;

      elsif Is_Derived_Type (Typ) then
         return Validated_View (Etype (Typ));

      elsif Is_Private_Type (Typ) then
         if Present (Underlying_Full_View (Typ)) then
            return Validated_View (Underlying_Full_View (Typ));

         elsif Present (Full_View (Typ)) then
            return Validated_View (Full_View (Typ));
         else
            return Typ;
         end if;

      else
         return Typ;
      end if;
   end Validated_View;

   -----------------------
   -- Visible_Ancestors --
   -----------------------

   function Visible_Ancestors (Typ : Entity_Id) return Elist_Id is
      List_1 : Elist_Id;
      List_2 : Elist_Id;
      Elmt   : Elmt_Id;

   begin
      pragma Assert (Is_Record_Type (Typ) and then Is_Tagged_Type (Typ));

      --  Collect all the parents and progenitors of Typ. If the full-view of
      --  private parents and progenitors is available then it is used to
      --  generate the list of visible ancestors; otherwise their partial
      --  view is added to the resulting list.

      Collect_Parents
        (T               => Typ,
         List            => List_1,
         Use_Full_View   => True);

      Collect_Interfaces
        (T               => Typ,
         Ifaces_List     => List_2,
         Exclude_Parents => True,
         Use_Full_View   => True);

      --  Join the two lists. Avoid duplications because an interface may
      --  simultaneously be parent and progenitor of a type.

      Elmt := First_Elmt (List_2);
      while Present (Elmt) loop
         Append_Unique_Elmt (Node (Elmt), List_1);
         Next_Elmt (Elmt);
      end loop;

      return List_1;
   end Visible_Ancestors;

   ---------------------------
   -- Warn_On_Hiding_Entity --
   ---------------------------

   procedure Warn_On_Hiding_Entity
     (N               : Node_Id;
      Hidden, Visible : Entity_Id;
      On_Use_Clause   : Boolean)
   is
   begin
      --  Don't warn for record components since they always have a well
      --  defined scope which does not confuse other uses. Note that in
      --  some cases, Ekind has not been set yet.

      if Ekind (Hidden) /= E_Component
        and then Ekind (Hidden) /= E_Discriminant
        and then Nkind (Parent (Hidden)) /= N_Component_Declaration
        and then Ekind (Visible) /= E_Component
        and then Ekind (Visible) /= E_Discriminant
        and then Nkind (Parent (Visible)) /= N_Component_Declaration

        --  Don't warn for one character variables. It is too common to use
        --  such variables as locals and will just cause too many false hits.

        and then Length_Of_Name (Chars (Hidden)) /= 1

        --  Don't warn for non-source entities

        and then Comes_From_Source (Hidden)
        and then Comes_From_Source (Visible)

        --  Don't warn within a generic instantiation

        and then not In_Instance

        --  Don't warn unless entity in question is in extended main source

        and then In_Extended_Main_Source_Unit (Visible)

        --  Finally, in the case of a declaration, the hidden entity must
        --  be either immediately visible or use visible (i.e. from a used
        --  package). In the case of a use clause, the visible entity must
        --  be immediately visible.

        and then
          (if On_Use_Clause then
             Is_Immediately_Visible (Visible)
           else
             (Is_Immediately_Visible (Hidden)
               or else
              Is_Potentially_Use_Visible (Hidden)))
      then
         if On_Use_Clause then
            Error_Msg_Sloc := Sloc (Visible);
            Error_Msg_NE ("visible declaration of&# hides homonym "
                          & "from use clause?h?", N, Hidden);
         else
            Error_Msg_Sloc := Sloc (Hidden);
            Error_Msg_NE ("declaration hides &#?h?", N, Visible);
         end if;
      end if;
   end Warn_On_Hiding_Entity;

   ----------------------
   -- Within_Init_Proc --
   ----------------------

   function Within_Init_Proc return Boolean is
      S : Entity_Id;

   begin
      S := Current_Scope;
      while not Is_Overloadable (S) loop
         if S = Standard_Standard then
            return False;
         else
            S := Scope (S);
         end if;
      end loop;

      return Is_Init_Proc (S);
   end Within_Init_Proc;

   ---------------------------
   -- Within_Protected_Type --
   ---------------------------

   function Within_Protected_Type (E : Entity_Id) return Boolean is
      Scop : Entity_Id := Scope (E);

   begin
      while Present (Scop) loop
         if Ekind (Scop) = E_Protected_Type then
            return True;
         end if;

         Scop := Scope (Scop);
      end loop;

      return False;
   end Within_Protected_Type;

   ------------------
   -- Within_Scope --
   ------------------

   function Within_Scope (E : Entity_Id; S : Entity_Id) return Boolean is
   begin
      return Scope_Within_Or_Same (Scope (E), S);
   end Within_Scope;

   ----------------
   -- Wrong_Type --
   ----------------

   procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id) is
      Found_Type : constant Entity_Id := First_Subtype (Etype (Expr));
      Expec_Type : constant Entity_Id := First_Subtype (Expected_Type);

      Err_Msg_Exp_Typ : Entity_Id := Expected_Type;
      --  Type entity used when printing errors concerning the expected type

      Matching_Field : Entity_Id;
      --  Entity to give a more precise suggestion on how to write a one-
      --  element positional aggregate.

      function Has_One_Matching_Field return Boolean;
      --  Determines if Expec_Type is a record type with a single component or
      --  discriminant whose type matches the found type or is one dimensional
      --  array whose component type matches the found type. In the case of
      --  one discriminant, we ignore the variant parts. That's not accurate,
      --  but good enough for the warning.

      ----------------------------
      -- Has_One_Matching_Field --
      ----------------------------

      function Has_One_Matching_Field return Boolean is
         E : Entity_Id;

      begin
         Matching_Field := Empty;

         if Is_Array_Type (Expec_Type)
           and then Number_Dimensions (Expec_Type) = 1
           and then Covers (Etype (Component_Type (Expec_Type)), Found_Type)
         then
            --  Use type name if available. This excludes multidimensional
            --  arrays and anonymous arrays.

            if Comes_From_Source (Expec_Type) then
               Matching_Field := Expec_Type;

            --  For an assignment, use name of target

            elsif Nkind (Parent (Expr)) = N_Assignment_Statement
              and then Is_Entity_Name (Name (Parent (Expr)))
            then
               Matching_Field := Entity (Name (Parent (Expr)));
            end if;

            return True;

         elsif not Is_Record_Type (Expec_Type) then
            return False;

         else
            E := First_Entity (Expec_Type);
            loop
               if No (E) then
                  return False;

               elsif Ekind (E) not in E_Discriminant | E_Component
                 or else Chars (E) in Name_uTag | Name_uParent
               then
                  Next_Entity (E);

               else
                  exit;
               end if;
            end loop;

            if not Covers (Etype (E), Found_Type) then
               return False;

            elsif Present (Next_Entity (E))
              and then (Ekind (E) = E_Component
                         or else Ekind (Next_Entity (E)) = E_Discriminant)
            then
               return False;

            else
               Matching_Field := E;
               return True;
            end if;
         end if;
      end Has_One_Matching_Field;

   --  Start of processing for Wrong_Type

   begin
      --  Don't output message if either type is Any_Type, or if a message
      --  has already been posted for this node. We need to do the latter
      --  check explicitly (it is ordinarily done in Errout), because we
      --  are using ! to force the output of the error messages.

      if Expec_Type = Any_Type
        or else Found_Type = Any_Type
        or else Error_Posted (Expr)
      then
         return;

      --  If one of the types is a Taft-Amendment type and the other it its
      --  completion, it must be an illegal use of a TAT in the spec, for
      --  which an error was already emitted. Avoid cascaded errors.

      elsif Is_Incomplete_Type (Expec_Type)
        and then Has_Completion_In_Body (Expec_Type)
        and then Full_View (Expec_Type) = Etype (Expr)
      then
         return;

      elsif Is_Incomplete_Type (Etype (Expr))
        and then Has_Completion_In_Body (Etype (Expr))
        and then Full_View (Etype (Expr)) = Expec_Type
      then
         return;
      end if;

      --  Avoid printing internally generated subtypes in error messages and
      --  instead use the corresponding first subtype in such cases.

      if not Comes_From_Source (Err_Msg_Exp_Typ)
        or else not Comes_From_Source (Declaration_Node (Err_Msg_Exp_Typ))
      then
         Err_Msg_Exp_Typ := First_Subtype (Err_Msg_Exp_Typ);
      end if;

      --  An interesting special check. If the expression is parenthesized
      --  and its type corresponds to the type of the sole component of the
      --  expected record type, or to the component type of the expected one
      --  dimensional array type, then assume we have a bad aggregate attempt.

      if Nkind (Expr) in N_Subexpr
        and then Paren_Count (Expr) /= 0
        and then Has_One_Matching_Field
      then
         Error_Msg_N ("positional aggregate cannot have one component", Expr);

         if Present (Matching_Field) then
            if Is_Array_Type (Expec_Type) then
               Error_Msg_NE
                 ("\write instead `&''First ='> ...`", Expr, Matching_Field);
            else
               Error_Msg_NE
                 ("\write instead `& ='> ...`", Expr, Matching_Field);
            end if;
         end if;

      --  Another special check, if we are looking for a pool-specific access
      --  type and we found an E_Access_Attribute_Type, then we have the case
      --  of an Access attribute being used in a context which needs a pool-
      --  specific type, which is never allowed. The one extra check we make
      --  is that the expected designated type covers the Found_Type.

      elsif Is_Access_Type (Expec_Type)
        and then Ekind (Found_Type) = E_Access_Attribute_Type
        and then Ekind (Base_Type (Expec_Type)) /= E_General_Access_Type
        and then Ekind (Base_Type (Expec_Type)) /= E_Anonymous_Access_Type
        and then Covers
          (Designated_Type (Expec_Type), Designated_Type (Found_Type))
      then
         Error_Msg_N
           ("result must be general access type!", Expr);
         Error_Msg_NE -- CODEFIX
           ("\add ALL to }!", Expr, Err_Msg_Exp_Typ);

      --  Another special check, if the expected type is an integer type,
      --  but the expression is of type System.Address, and the parent is
      --  an addition or subtraction operation whose left operand is the
      --  expression in question and whose right operand is of an integral
      --  type, then this is an attempt at address arithmetic, so give
      --  appropriate message.

      elsif Is_Integer_Type (Expec_Type)
        and then Is_RTE (Found_Type, RE_Address)
        and then Nkind (Parent (Expr)) in N_Op_Add | N_Op_Subtract
        and then Expr = Left_Opnd (Parent (Expr))
        and then Is_Integer_Type (Etype (Right_Opnd (Parent (Expr))))
      then
         Error_Msg_N
           ("address arithmetic not predefined in package System",
            Parent (Expr));
         Error_Msg_N
           ("\possible missing with/use of System.Storage_Elements",
            Parent (Expr));
         return;

      --  If the expected type is an anonymous access type, as for access
      --  parameters and discriminants, the error is on the designated types.

      elsif Ekind (Expec_Type) = E_Anonymous_Access_Type then
         if Comes_From_Source (Expec_Type) then
            Error_Msg_NE ("expected}!", Expr, Expec_Type);
         else
            Error_Msg_NE
              ("expected an access type with designated}",
                 Expr, Designated_Type (Expec_Type));
         end if;

         if Is_Access_Type (Found_Type)
           and then not Comes_From_Source (Found_Type)
         then
            Error_Msg_NE
              ("\\found an access type with designated}!",
                Expr, Designated_Type (Found_Type));
         else
            if From_Limited_With (Found_Type) then
               Error_Msg_NE ("\\found incomplete}!", Expr, Found_Type);
               Error_Msg_Qual_Level := 99;
               Error_Msg_NE -- CODEFIX
                 ("\\missing `WITH &;", Expr, Scope (Found_Type));
               Error_Msg_Qual_Level := 0;
            else
               Error_Msg_NE ("found}!", Expr, Found_Type);
            end if;
         end if;

      --  Normal case of one type found, some other type expected

      else
         --  If the names of the two types are the same, see if some number
         --  of levels of qualification will help. Don't try more than three
         --  levels, and if we get to standard, it's no use (and probably
         --  represents an error in the compiler) Also do not bother with
         --  internal scope names.

         declare
            Expec_Scope : Entity_Id;
            Found_Scope : Entity_Id;

         begin
            Expec_Scope := Expec_Type;
            Found_Scope := Found_Type;

            for Levels in Nat range 0 .. 3 loop
               if Chars (Expec_Scope) /= Chars (Found_Scope) then
                  Error_Msg_Qual_Level := Levels;
                  exit;
               end if;

               Expec_Scope := Scope (Expec_Scope);
               Found_Scope := Scope (Found_Scope);

               exit when Expec_Scope = Standard_Standard
                 or else Found_Scope = Standard_Standard
                 or else not Comes_From_Source (Expec_Scope)
                 or else not Comes_From_Source (Found_Scope);
            end loop;
         end;

         if Is_Record_Type (Expec_Type)
           and then Present (Corresponding_Remote_Type (Expec_Type))
         then
            Error_Msg_NE ("expected}!", Expr,
                          Corresponding_Remote_Type (Expec_Type));
         else
            Error_Msg_NE ("expected}!", Expr, Err_Msg_Exp_Typ);
         end if;

         if Is_Entity_Name (Expr)
           and then Is_Package_Or_Generic_Package (Entity (Expr))
         then
            Error_Msg_N ("\\found package name!", Expr);

         elsif Is_Entity_Name (Expr)
           and then Ekind (Entity (Expr)) in E_Procedure | E_Generic_Procedure
         then
            if Ekind (Expec_Type) = E_Access_Subprogram_Type then
               Error_Msg_N
                 ("found procedure name, possibly missing Access attribute!",
                   Expr);
            else
               Error_Msg_N
                 ("\\found procedure name instead of function!", Expr);
            end if;

         elsif Nkind (Expr) = N_Function_Call
           and then Ekind (Expec_Type) = E_Access_Subprogram_Type
           and then Etype (Designated_Type (Expec_Type)) = Etype (Expr)
           and then No (Parameter_Associations (Expr))
         then
            Error_Msg_N
              ("found function name, possibly missing Access attribute!",
               Expr);

         --  Catch common error: a prefix or infix operator which is not
         --  directly visible because the type isn't.

         elsif Nkind (Expr) in N_Op
            and then Is_Overloaded (Expr)
            and then not Is_Immediately_Visible (Expec_Type)
            and then not Is_Potentially_Use_Visible (Expec_Type)
            and then not In_Use (Expec_Type)
            and then Has_Compatible_Type (Right_Opnd (Expr), Expec_Type)
         then
            Error_Msg_N
              ("operator of the type is not directly visible!", Expr);

         elsif Ekind (Found_Type) = E_Void
           and then Present (Parent (Found_Type))
           and then Nkind (Parent (Found_Type)) = N_Full_Type_Declaration
         then
            Error_Msg_NE ("\\found premature usage of}!", Expr, Found_Type);

         else
            Error_Msg_NE ("\\found}!", Expr, Found_Type);
         end if;

         --  A special check for cases like M1 and M2 = 0 where M1 and M2 are
         --  of the same modular type, and (M1 and M2) = 0 was intended.

         if Expec_Type = Standard_Boolean
           and then Is_Modular_Integer_Type (Found_Type)
           and then Nkind (Parent (Expr)) in N_Op_And | N_Op_Or | N_Op_Xor
           and then Nkind (Right_Opnd (Parent (Expr))) in N_Op_Compare
         then
            declare
               Op : constant Node_Id := Right_Opnd (Parent (Expr));
               L  : constant Node_Id := Left_Opnd (Op);
               R  : constant Node_Id := Right_Opnd (Op);

            begin
               --  The case for the message is when the left operand of the
               --  comparison is the same modular type, or when it is an
               --  integer literal (or other universal integer expression),
               --  which would have been typed as the modular type if the
               --  parens had been there.

               if (Etype (L) = Found_Type
                     or else
                   Etype (L) = Universal_Integer)
                 and then Is_Integer_Type (Etype (R))
               then
                  Error_Msg_N
                    ("\\possible missing parens for modular operation", Expr);
               end if;
            end;
         end if;

         --  Reset error message qualification indication

         Error_Msg_Qual_Level := 0;
      end if;
   end Wrong_Type;

   --------------------------------
   -- Yields_Synchronized_Object --
   --------------------------------

   function Yields_Synchronized_Object (Typ : Entity_Id) return Boolean is
      Has_Sync_Comp : Boolean := False;
      Id            : Entity_Id;

   begin
      --  An array type yields a synchronized object if its component type
      --  yields a synchronized object.

      if Is_Array_Type (Typ) then
         return Yields_Synchronized_Object (Component_Type (Typ));

      --  A descendant of type Ada.Synchronous_Task_Control.Suspension_Object
      --  yields a synchronized object by default.

      elsif Is_Descendant_Of_Suspension_Object (Typ) then
         return True;

      --  A protected type yields a synchronized object by default

      elsif Is_Protected_Type (Typ) then
         return True;

      --  A record type or type extension yields a synchronized object when its
      --  discriminants (if any) lack default values and all components are of
      --  a type that yields a synchronized object.

      elsif Is_Record_Type (Typ) then

         --  Inspect all entities defined in the scope of the type, looking for
         --  components of a type that does not yield a synchronized object or
         --  for discriminants with default values.

         Id := First_Entity (Typ);
         while Present (Id) loop
            if Comes_From_Source (Id) then
               if Ekind (Id) = E_Component then
                  if Yields_Synchronized_Object (Etype (Id)) then
                     Has_Sync_Comp := True;

                  --  The component does not yield a synchronized object

                  else
                     return False;
                  end if;

               elsif Ekind (Id) = E_Discriminant
                 and then Present (Expression (Parent (Id)))
               then
                  return False;
               end if;
            end if;

            Next_Entity (Id);
         end loop;

         --  Ensure that the parent type of a type extension yields a
         --  synchronized object.

         if Etype (Typ) /= Typ
           and then not Is_Private_Type (Etype (Typ))
           and then not Yields_Synchronized_Object (Etype (Typ))
         then
            return False;
         end if;

         --  If we get here, then all discriminants lack default values and all
         --  components are of a type that yields a synchronized object.

         return Has_Sync_Comp;

      --  A synchronized interface type yields a synchronized object by default

      elsif Is_Synchronized_Interface (Typ) then
         return True;

      --  A task type yields a synchronized object by default

      elsif Is_Task_Type (Typ) then
         return True;

      --  A private type yields a synchronized object if its underlying type
      --  does.

      elsif Is_Private_Type (Typ)
        and then Present (Underlying_Type (Typ))
      then
         return Yields_Synchronized_Object (Underlying_Type (Typ));

      --  Otherwise the type does not yield a synchronized object

      else
         return False;
      end if;
   end Yields_Synchronized_Object;

   ---------------------------
   -- Yields_Universal_Type --
   ---------------------------

   function Yields_Universal_Type (N : Node_Id) return Boolean is
   begin
      --  Integer and real literals are of a universal type

      if Nkind (N) in N_Integer_Literal | N_Real_Literal then
         return True;

      --  The values of certain attributes are of a universal type

      elsif Nkind (N) = N_Attribute_Reference then
         return
           Universal_Type_Attribute (Get_Attribute_Id (Attribute_Name (N)));

      --  ??? There are possibly other cases to consider

      else
         return False;
      end if;
   end Yields_Universal_Type;

   package body Interval_Lists is

      procedure Check_Consistency (Intervals : Discrete_Interval_List);
      --  Check that list is sorted, lacks null intervals, and has gaps
      --  between intervals.

      function Chosen_Interval (Choice : Node_Id) return Discrete_Interval;
      --  Given an element of a Discrete_Choices list, a
      --  Static_Discrete_Predicate list, or an Others_Discrete_Choices
      --  list (but not an N_Others_Choice node) return the corresponding
      --  interval. If an element that does not represent a single
      --  contiguous interval due to a static predicate (or which
      --  represents a single contiguous interval whose bounds depend on
      --  a static predicate) is encountered, then that is an error on the
      --  part of whoever built the list in question.

      function In_Interval
        (Value : Uint; Interval : Discrete_Interval) return Boolean;
      --  Does the given value lie within the given interval?

      procedure Normalize_Interval_List
         (List : in out Discrete_Interval_List; Last : out Nat);
      --  Perform sorting and merging as required by Check_Consistency

      -------------------------
      -- Aggregate_Intervals --
      -------------------------

      function Aggregate_Intervals (N : Node_Id) return Discrete_Interval_List
      is
         pragma Assert (Nkind (N) = N_Aggregate
           and then Is_Array_Type (Etype (N)));

         function Unmerged_Intervals_Count return Nat;
         --  Count the number of intervals given in the aggregate N; the others
         --  choice (if present) is not taken into account.

         ------------------------------
         -- Unmerged_Intervals_Count --
         ------------------------------

         function Unmerged_Intervals_Count return Nat is
            Count  : Nat := 0;
            Choice : Node_Id;
            Comp   : Node_Id;
         begin
            Comp := First (Component_Associations (N));
            while Present (Comp) loop
               Choice := First (Choices (Comp));

               while Present (Choice) loop
                  if Nkind (Choice) /= N_Others_Choice then
                     Count := Count + 1;
                  end if;

                  Next (Choice);
               end loop;

               Next (Comp);
            end loop;

            return Count;
         end Unmerged_Intervals_Count;

         --  Local variables

         Comp      : Node_Id;
         Max_I     : constant Nat := Unmerged_Intervals_Count;
         Intervals : Discrete_Interval_List (1 .. Max_I);
         Num_I     : Nat := 0;

      --  Start of processing for Aggregate_Intervals

      begin
         --  No action needed if there are no intervals

         if Max_I = 0 then
            return Intervals;
         end if;

         --  Internally store all the unsorted intervals

         Comp := First (Component_Associations (N));
         while Present (Comp) loop
            declare
               Choice_Intervals : constant Discrete_Interval_List
                 := Choice_List_Intervals (Choices (Comp));
            begin
               for J in Choice_Intervals'Range loop
                  Num_I := Num_I + 1;
                  Intervals (Num_I) := Choice_Intervals (J);
               end loop;
            end;

            Next (Comp);
         end loop;

         --  Normalize the lists sorting and merging the intervals

         declare
            Aggr_Intervals : Discrete_Interval_List (1 .. Num_I)
                               := Intervals (1 .. Num_I);
         begin
            Normalize_Interval_List (Aggr_Intervals, Num_I);
            Check_Consistency (Aggr_Intervals (1 .. Num_I));
            return Aggr_Intervals (1 .. Num_I);
         end;
      end Aggregate_Intervals;

      ------------------------
      --  Check_Consistency --
      ------------------------

      procedure Check_Consistency (Intervals : Discrete_Interval_List) is
      begin
         if Serious_Errors_Detected > 0 then
            return;
         end if;

         --  low bound is 1 and high bound equals length
         pragma Assert (Intervals'First = 1 and Intervals'Last >= 0);
         for Idx in Intervals'Range loop
            --  each interval is non-null
            pragma Assert (Intervals (Idx).Low <= Intervals (Idx).High);
            if Idx /= Intervals'First then
               --  intervals are sorted with non-empty gaps between them
               pragma Assert
                 (Intervals (Idx - 1).High < (Intervals (Idx).Low - 1));
               null;
            end if;
         end loop;
      end Check_Consistency;

      ---------------------------
      -- Choice_List_Intervals --
      ---------------------------

      function Choice_List_Intervals
        (Discrete_Choices : List_Id) return Discrete_Interval_List
      is
         function Unmerged_Choice_Count return Nat;
         --  The number of intervals before adjacent intervals are merged

         ---------------------------
         -- Unmerged_Choice_Count --
         ---------------------------

         function Unmerged_Choice_Count return Nat is
            Choice : Node_Id := First (Discrete_Choices);
            Count  : Nat := 0;
         begin
            while Present (Choice) loop
               --  Non-contiguous choices involving static predicates
               --  have already been normalized away.

               if Nkind (Choice) = N_Others_Choice then
                  Count :=
                    Count + List_Length (Others_Discrete_Choices (Choice));
               else
                  Count := Count + 1;  -- an ordinary expression or range
               end if;

               Next (Choice);
            end loop;
            return Count;
         end Unmerged_Choice_Count;

         --  Local variables

         Choice : Node_Id := First (Discrete_Choices);
         Result : Discrete_Interval_List (1 .. Unmerged_Choice_Count);
         Count  : Nat := 0;

      --  Start of processing for Choice_List_Intervals

      begin
         while Present (Choice) loop
            if Nkind (Choice) = N_Others_Choice then
               declare
                  Others_Choice : Node_Id
                    := First (Others_Discrete_Choices (Choice));
               begin
                  while Present (Others_Choice) loop
                     Count := Count + 1;
                     Result (Count) := Chosen_Interval (Others_Choice);
                     Next (Others_Choice);
                  end loop;
               end;
            else
               Count := Count + 1;
               Result (Count) := Chosen_Interval (Choice);
            end if;

            Next (Choice);
         end loop;

         pragma Assert (Count = Result'Last);
         Normalize_Interval_List (Result, Count);
         Check_Consistency (Result (1 .. Count));
         return Result (1 .. Count);
      end Choice_List_Intervals;

      ---------------------
      -- Chosen_Interval --
      ---------------------

      function Chosen_Interval (Choice : Node_Id) return Discrete_Interval is
      begin
         case Nkind (Choice) is
            when N_Range =>
               return (Low  => Expr_Value (Low_Bound (Choice)),
                       High => Expr_Value (High_Bound (Choice)));

            when N_Subtype_Indication =>
               declare
                  Range_Exp : constant Node_Id
                    := Range_Expression (Constraint (Choice));
               begin
                  return (Low  => Expr_Value (Low_Bound (Range_Exp)),
                          High => Expr_Value (High_Bound (Range_Exp)));
               end;

            when N_Others_Choice =>
               raise Program_Error;

            when others =>
               if Is_Entity_Name (Choice) and then Is_Type (Entity (Choice))
               then
                  return
                    (Low  => Expr_Value (Type_Low_Bound (Entity (Choice))),
                     High => Expr_Value (Type_High_Bound (Entity (Choice))));
               else
                  --  an expression
                  return (Low | High => Expr_Value (Choice));
               end if;
         end case;
      end Chosen_Interval;

      -----------------
      -- In_Interval --
      -----------------

      function In_Interval
        (Value : Uint; Interval : Discrete_Interval) return Boolean is
      begin
         return Value >= Interval.Low and then Value <= Interval.High;
      end In_Interval;

      ---------------
      -- Is_Subset --
      ---------------

      function Is_Subset
        (Subset, Of_Set : Discrete_Interval_List) return Boolean
      is
         --  Returns True iff for each interval of Subset we can find
         --  a single interval of Of_Set which contains the Subset interval.
      begin
         if Of_Set'Length = 0 then
            return Subset'Length = 0;
         end if;

         declare
            Set_Index : Pos range Of_Set'Range := Of_Set'First;

         begin
            for Ss_Idx in Subset'Range loop
               while not In_Interval
                 (Value    => Subset (Ss_Idx).Low,
                  Interval => Of_Set (Set_Index))
               loop
                  if Set_Index = Of_Set'Last then
                     return False;
                  end if;

                  Set_Index := Set_Index + 1;
               end loop;

               if not In_Interval
                 (Value    => Subset (Ss_Idx).High,
                  Interval => Of_Set (Set_Index))
               then
                  return False;
               end if;
            end loop;
         end;

         return True;
      end Is_Subset;

      -----------------------------
      -- Normalize_Interval_List --
      -----------------------------

      procedure Normalize_Interval_List
        (List : in out Discrete_Interval_List; Last : out Nat)
      is
         Temp_0 : Discrete_Interval := (others => Uint_0);
         --  Cope with Heap_Sort_G idiosyncrasies.

         function Is_Null (Idx : Pos) return Boolean;
         --  True iff List (Idx) defines a null range

         function Lt_Interval (Idx1, Idx2 : Natural) return Boolean;
         --  Compare two list elements

         procedure Merge_Intervals (Null_Interval_Count : out Nat);
         --  Merge contiguous ranges by replacing one with merged range and
         --  the other with a null value. Return a count of the null intervals,
         --  both preexisting and those introduced by merging.

         procedure Move_Interval (From, To : Natural);
         --  Copy interval from one location to another

         function Read_Interval (From : Natural) return Discrete_Interval;
         --  Normal array indexing unless From = 0

         ----------------------
         -- Interval_Sorting --
         ----------------------

         package Interval_Sorting is
           new Gnat.Heap_Sort_G (Move_Interval, Lt_Interval);

         -------------
         -- Is_Null --
         -------------

         function Is_Null (Idx : Pos) return Boolean is
         begin
            return List (Idx).Low > List (Idx).High;
         end Is_Null;

         -----------------
         -- Lt_Interval --
         -----------------

         function Lt_Interval (Idx1, Idx2 : Natural) return Boolean is
            Elem1  : constant Discrete_Interval := Read_Interval (Idx1);
            Elem2  : constant Discrete_Interval := Read_Interval (Idx2);
            Null_1 : constant Boolean := Elem1.Low > Elem1.High;
            Null_2 : constant Boolean := Elem2.Low > Elem2.High;
         begin
            if Null_1 /= Null_2 then
               --  So that sorting moves null intervals to high end
               return Null_2;

            elsif Elem1.Low /= Elem2.Low then
               return Elem1.Low < Elem2.Low;

            else
               return Elem1.High < Elem2.High;
            end if;
         end Lt_Interval;

         ---------------------
         -- Merge_Intervals --
         ---------------------

         procedure Merge_Intervals (Null_Interval_Count : out Nat) is
            Not_Null : Pos range List'Range;
            --  Index of the most recently examined non-null interval

            Null_Interval : constant Discrete_Interval
              := (Low => Uint_1, High => Uint_0); -- any null range ok here
         begin
            if List'Length = 0 or else Is_Null (List'First) then
               Null_Interval_Count := List'Length;
               --  no non-null elements, so no merge candidates
               return;
            end if;

            Null_Interval_Count := 0;
            Not_Null := List'First;

            for Idx in List'First + 1 .. List'Last loop
               if Is_Null (Idx) then

                  --  all remaining elements are null

                  Null_Interval_Count :=
                    Null_Interval_Count + List (Idx .. List'Last)'Length;
                  return;

               elsif List (Idx).Low = List (Not_Null).High + 1 then

                  --  Merge the two intervals into one; discard the other

                  List (Not_Null).High := List (Idx).High;
                  List (Idx) := Null_Interval;
                  Null_Interval_Count := Null_Interval_Count + 1;

               else
                  if List (Idx).Low <= List (Not_Null).High then
                     raise Intervals_Error;
                  end if;

                  pragma Assert (List (Idx).Low > List (Not_Null).High);
                  Not_Null := Idx;
               end if;
            end loop;
         end Merge_Intervals;

         -------------------
         -- Move_Interval --
         -------------------

         procedure Move_Interval (From, To : Natural) is
            Rhs : constant Discrete_Interval := Read_Interval (From);
         begin
            if To = 0 then
               Temp_0 := Rhs;
            else
               List (Pos (To)) := Rhs;
            end if;
         end Move_Interval;

         -------------------
         -- Read_Interval --
         -------------------

         function Read_Interval (From : Natural) return Discrete_Interval is
         begin
            if From = 0 then
               return Temp_0;
            else
               return List (Pos (From));
            end if;
         end Read_Interval;

      --  Start of processing for Normalize_Interval_Lists

      begin
         Interval_Sorting.Sort (Natural (List'Last));

         declare
            Null_Interval_Count : Nat;

         begin
            Merge_Intervals (Null_Interval_Count);
            Last := List'Last - Null_Interval_Count;

            if Null_Interval_Count /= 0 then
               --  Move null intervals introduced during merging to high end
               Interval_Sorting.Sort (Natural (List'Last));
            end if;
         end;
      end Normalize_Interval_List;

      --------------------
      -- Type_Intervals --
      --------------------

      function Type_Intervals (Typ : Entity_Id) return Discrete_Interval_List
      is
      begin
         if Has_Static_Predicate (Typ) then
            declare
               --  No sorting or merging needed
               SDP_List : constant List_Id := Static_Discrete_Predicate (Typ);
               Range_Or_Expr : Node_Id := First (SDP_List);
               Result : Discrete_Interval_List (1 .. List_Length (SDP_List));

            begin
               for Idx in Result'Range loop
                  Result (Idx) := Chosen_Interval (Range_Or_Expr);
                  Next (Range_Or_Expr);
               end loop;

               pragma Assert (No (Range_Or_Expr));
               Check_Consistency (Result);
               return Result;
            end;
         else
            declare
               Low  : constant Uint := Expr_Value (Type_Low_Bound (Typ));
               High : constant Uint := Expr_Value (Type_High_Bound (Typ));
            begin
               if Low > High then
                  declare
                     Null_Array : Discrete_Interval_List (1 .. 0);
                  begin
                     return Null_Array;
                  end;
               else
                  return (1 => (Low => Low, High => High));
               end if;
            end;
         end if;
      end Type_Intervals;

   end Interval_Lists;

   package body Old_Attr_Util is
      package body Conditional_Evaluation is
         type Determining_Expr_Context is
           (No_Context, If_Expr, Case_Expr, Short_Circuit_Op, Membership_Test);

         --  Determining_Expr_Context enumeration elements (except for
         --  No_Context) correspond to the list items in RM 6.1.1 definition
         --  of "determining expression".

         type Determining_Expr
           (Context : Determining_Expr_Context := No_Context)
         is record
            Expr : Node_Id := Empty;
            case Context is
               when Short_Circuit_Op =>
                  Is_And_Then         : Boolean;
               when If_Expr =>
                  Is_Then_Part        : Boolean;
               when Case_Expr =>
                  Alternatives        : Node_Id;
               when Membership_Test =>
                  --  Given a subexpression of <exp4> in a membership test
                  --    <exp1> in <exp2> | <exp3> | <exp4> | <exp5>
                  --  the corresponding determining expression value would
                  --  have First_Non_Preceding = <exp4> (See RM 6.1.1).
                  First_Non_Preceding : Node_Id;
               when No_Context =>
                  null;
            end case;
         end record;

         type Determining_Expression_List is
           array (Positive range <>) of Determining_Expr;

         function Determining_Condition (Det : Determining_Expr)
           return Node_Id;
         --  Given a determining expression, build a Boolean-valued
         --  condition that incorporates that expression into condition
         --  suitable for deciding whether to initialize a 'Old constant.
         --  Polarity is "True => initialize the constant".

         function Determining_Expressions
           (Expr : Node_Id; Expr_Trailer : Node_Id := Empty)
           return Determining_Expression_List;
         --  Given a conditionally evaluated expression, return its
         --  determining expressions.
         --  See RM 6.1.1 for definition of term "determining expressions".
         --  Tests should be performed in the order they occur in the
         --  array, with short circuiting.
         --  A determining expression need not be of a boolean type (e.g.,
         --  it might be the determining expression of a case expression).
         --  The Expr_Trailer parameter should be defaulted for nonrecursive
         --  calls.

         function Is_Conditionally_Evaluated (Expr : Node_Id) return Boolean;
         --  See RM 6.1.1 for definition of term "conditionally evaluated".

         function Is_Known_On_Entry (Expr : Node_Id) return Boolean;
         --  See RM 6.1.1 for definition of term "known on entry".

         --------------------------------------
         -- Conditional_Evaluation_Condition --
         --------------------------------------

         function Conditional_Evaluation_Condition
           (Expr : Node_Id) return Node_Id
         is
            Determiners : constant Determining_Expression_List :=
              Determining_Expressions (Expr);
            Loc         : constant Source_Ptr := Sloc (Expr);
            Result      : Node_Id :=
              New_Occurrence_Of (Standard_True, Loc);
         begin
            pragma Assert (Determiners'Length > 0 or else
                           Is_Anonymous_Access_Type (Etype (Expr)));

            for I in Determiners'Range loop
               Result := Make_And_Then
                          (Loc,
                           Left_Opnd  => Result,
                           Right_Opnd =>
                             Determining_Condition (Determiners (I)));
            end loop;
            return Result;
         end Conditional_Evaluation_Condition;

         ---------------------------
         -- Determining_Condition --
         ---------------------------

         function Determining_Condition (Det : Determining_Expr) return Node_Id
         is
            Loc : constant Source_Ptr := Sloc (Det.Expr);
         begin
            case Det.Context is
               when Short_Circuit_Op =>
                  if Det.Is_And_Then then
                     return New_Copy_Tree (Det.Expr);
                  else
                     return Make_Op_Not (Loc, New_Copy_Tree (Det.Expr));
                  end if;

               when If_Expr =>
                  if Det.Is_Then_Part then
                     return New_Copy_Tree (Det.Expr);
                  else
                     return Make_Op_Not (Loc, New_Copy_Tree (Det.Expr));
                  end if;

               when Case_Expr =>
                  declare
                     Alts : List_Id := Discrete_Choices (Det.Alternatives);
                  begin
                     if Nkind (First (Alts)) = N_Others_Choice then
                        Alts := Others_Discrete_Choices (First (Alts));
                     end if;

                     return Make_In (Loc,
                       Left_Opnd    => New_Copy_Tree (Det.Expr),
                       Right_Opnd   => Empty,
                       Alternatives => New_Copy_List (Alts));
                  end;

               when Membership_Test =>
                  declare
                     function Copy_Prefix
                       (List : List_Id; Suffix_Start : Node_Id)
                       return List_Id;
                     --  Given a list and a member of that list, returns
                     --  a copy (similar to Nlists.New_Copy_List) of the
                     --  prefix of the list up to but not including
                     --  Suffix_Start.

                     -----------------
                     -- Copy_Prefix --
                     -----------------

                     function Copy_Prefix
                       (List : List_Id; Suffix_Start : Node_Id)
                       return List_Id
                     is
                        Result : constant List_Id := New_List;
                        Elem   : Node_Id := First (List);
                     begin
                        while Elem /= Suffix_Start loop
                           Append (New_Copy (Elem), Result);
                           Next (Elem);
                           pragma Assert (Present (Elem));
                        end loop;
                        return Result;
                     end Copy_Prefix;

                  begin
                     return Make_In (Loc,
                       Left_Opnd    => New_Copy_Tree (Left_Opnd (Det.Expr)),
                       Right_Opnd   => Empty,
                       Alternatives => Copy_Prefix
                                         (Alternatives (Det.Expr),
                                          Det.First_Non_Preceding));
                  end;

               when No_Context =>
                  raise Program_Error;
            end case;
         end Determining_Condition;

         -----------------------------
         -- Determining_Expressions --
         -----------------------------

         function Determining_Expressions
           (Expr : Node_Id; Expr_Trailer : Node_Id := Empty)
           return Determining_Expression_List
         is
            Par          : Node_Id := Expr;
            Trailer      : Node_Id := Expr_Trailer;
            Next_Element : Determining_Expr;
         begin
            --  We want to stop climbing up the tree when we reach the
            --  postcondition expression. An aspect_specification is
            --  transformed into a pragma, so reaching a pragma is our
            --  termination condition. This relies on the fact that
            --  pragmas are not allowed in declare expressions (or any
            --  other kind of expression).

            loop
               Next_Element.Expr := Empty;

               case Nkind (Par) is
                  when N_Short_Circuit =>
                     if Trailer = Right_Opnd (Par) then
                        Next_Element :=
                          (Expr        => Left_Opnd (Par),
                           Context     => Short_Circuit_Op,
                           Is_And_Then => Nkind (Par) = N_And_Then);
                     end if;

                  when N_If_Expression =>
                     --  For an expression like
                     --    (if C1 then ... elsif C2 then ... else Foo'Old)
                     --  the RM says are two determining expressions,
                     --  C1 and C2. Our treatment here (where we only add
                     --  one determining expression to the list) is ok because
                     --  we will see two if-expressions, one within the other.

                     if Trailer /= First (Expressions (Par)) then
                        Next_Element :=
                           (Expr         => First (Expressions (Par)),
                            Context      => If_Expr,
                            Is_Then_Part =>
                              Trailer = Next (First (Expressions (Par))));
                     end if;

                  when N_Case_Expression_Alternative =>
                     pragma Assert (Nkind (Parent (Par)) = N_Case_Expression);

                     Next_Element :=
                       (Expr         => Expression (Parent (Par)),
                        Context      => Case_Expr,
                        Alternatives => Par);

                  when N_Membership_Test =>
                     if Trailer /= Left_Opnd (Par)
                       and then Is_Non_Empty_List (Alternatives (Par))
                       and then Trailer /= First (Alternatives (Par))
                     then
                        pragma Assert (No (Right_Opnd (Par)));
                        pragma Assert
                          (Is_List_Member (Trailer)
                           and then List_Containing (Trailer)
                                    = Alternatives (Par));

                        --  This one is different than the others
                        --  because one element in the array result
                        --  may represent multiple determining
                        --  expressions (i.e. every member of the list
                        --     Alternatives (Par)
                        --  up to but not including Trailer).

                        Next_Element :=
                          (Expr                => Par,
                           Context             => Membership_Test,
                           First_Non_Preceding => Trailer);
                     end if;

                  when N_Pragma =>
                     declare
                        Previous : constant Node_Id := Prev (Par);
                        Prev_Expr : Node_Id;
                     begin
                        if Nkind (Previous) = N_Pragma and then
                          Split_PPC (Previous)
                        then
                           --  A source-level postcondition of
                           --    A and then B and then C
                           --  results in
                           --    pragma Postcondition (A);
                           --    pragma Postcondition (B);
                           --    pragma Postcondition (C);
                           --  with Split_PPC set to True on all but the
                           --  last pragma. We account for that here.

                           Prev_Expr :=
                             Expression (First
                               (Pragma_Argument_Associations (Previous)));

                           --  This Analyze call is needed in the case when
                           --  Sem_Attr.Analyze_Attribute calls
                           --  Eligible_For_Conditional_Evaluation. Without
                           --  it, we end up passing an unanalyzed expression
                           --  to Is_Known_On_Entry and that doesn't work.

                           Analyze (Prev_Expr);

                           Next_Element :=
                             (Expr        => Prev_Expr,
                              Context     => Short_Circuit_Op,
                              Is_And_Then => True);

                           return Determining_Expressions (Prev_Expr)
                             & Next_Element;
                        else
                           pragma Assert
                             (Get_Pragma_Id (Pragma_Name (Par)) in
                                Pragma_Check
                              | Pragma_Contract_Cases
                              | Pragma_Exceptional_Cases
                              | Pragma_Post
                              | Pragma_Postcondition
                              | Pragma_Post_Class
                              | Pragma_Refined_Post);

                           return (1 .. 0 => <>); -- recursion terminates here
                        end if;
                     end;

                  when N_Empty =>
                     --  This case should be impossible, but if it does
                     --  happen somehow then we don't want an infinite loop.
                     raise Program_Error;

                  when others =>
                     null;
               end case;

               Trailer := Par;
               Par := Parent (Par);

               if Present (Next_Element.Expr) then
                  return Determining_Expressions
                           (Expr => Par, Expr_Trailer => Trailer)
                         & Next_Element;
               end if;
            end loop;
         end Determining_Expressions;

         -----------------------------------------
         -- Eligible_For_Conditional_Evaluation --
         -----------------------------------------

         function Eligible_For_Conditional_Evaluation
           (Expr : Node_Id) return Boolean
         is
         begin
            if Is_Anonymous_Access_Type (Etype (Expr)) then
               --  The code in exp_attr.adb that also builds declarations
               --  for 'Old constants doesn't handle the anonymous access
               --  type case correctly, so we avoid that problem by
               --  returning True here.
               return True;

            elsif Ada_Version < Ada_2022 then
               return False;

            elsif Inside_Class_Condition_Preanalysis then
               --  No need to evaluate it during preanalysis of a class-wide
               --  pre/postcondition since the expression is not installed yet
               --  on its definite context.
               return False;

            elsif not Is_Conditionally_Evaluated (Expr) then
               return False;
            else
               declare
                  Determiners : constant Determining_Expression_List :=
                    Determining_Expressions (Expr);
               begin
                  pragma Assert (Determiners'Length > 0);

                  for Idx in Determiners'Range loop
                     if not Is_Known_On_Entry (Determiners (Idx).Expr) then
                        return False;
                     end if;
                  end loop;
               end;
               return True;
            end if;
         end Eligible_For_Conditional_Evaluation;

         --------------------------------
         -- Is_Conditionally_Evaluated --
         --------------------------------

         function Is_Conditionally_Evaluated (Expr : Node_Id) return Boolean
         is
            --  There are three possibilities - the expression is
            --  unconditionally evaluated, repeatedly evaluated, or
            --  conditionally evaluated (see RM 6.1.1). So we implement
            --  this test by testing for the other two.

            function Is_Repeatedly_Evaluated (Expr : Node_Id) return Boolean;
            --  See RM 6.1.1 for definition of "repeatedly evaluated".

            -----------------------------
            -- Is_Repeatedly_Evaluated --
            -----------------------------

            function Is_Repeatedly_Evaluated (Expr : Node_Id) return Boolean is
               Par : Node_Id := Expr;
               Trailer : Node_Id := Empty;

               --  There are three ways that an expression can be repeatedly
               --  evaluated.
            begin
               --  An aspect_specification is transformed into a pragma, so
               --  reaching a pragma is our termination condition. We want to
               --  stop when we reach the postcondition expression.

               while Nkind (Par) /= N_Pragma loop
                  pragma Assert (Present (Par));

                  --  test for case 1:
                  --    A subexpression of a predicate of a
                  --    quantified_expression.

                  if Nkind (Par) = N_Quantified_Expression
                    and then Trailer = Condition (Par)
                  then
                     return True;
                  elsif Nkind (Par) = N_Expression_With_Actions
                    and then
                      Nkind (Original_Node (Par)) = N_Quantified_Expression
                  then
                     return True;
                  end if;

                  --  test for cases 2 and 3:
                  --    A subexpression of the expression of an
                  --    array_component_association or of
                  --    a container_element_associatiation.

                  if Nkind (Par) in N_Component_Association
                                  | N_Iterated_Component_Association
                    and then Trailer = Expression (Par)
                  then
                     --  determine whether Par is part of an array aggregate
                     --  or a container aggregate
                     declare
                        Rover : Node_Id := Par;
                     begin
                        while Nkind (Rover) not in N_Has_Etype loop
                           pragma Assert (Present (Rover));
                           Rover := Parent (Rover);
                        end loop;
                        if Present (Etype (Rover)) then
                           if Is_Array_Type (Etype (Rover))
                             or else Is_Container_Aggregate (Rover)
                           then
                              return True;
                           end if;
                        end if;
                     end;
                  end if;

                  Trailer := Par;
                  Par := Parent (Par);
               end loop;

               return False;
            end Is_Repeatedly_Evaluated;

         begin
            if not Is_Potentially_Unevaluated (Expr) then
               --  the expression is unconditionally evaluated
               return False;
            elsif Is_Repeatedly_Evaluated (Expr) then
               return False;
            end if;

            return True;
         end Is_Conditionally_Evaluated;

         -----------------------
         -- Is_Known_On_Entry --
         -----------------------

         function Is_Known_On_Entry (Expr : Node_Id) return Boolean is
            --  ??? This implementation is incomplete. See RM 6.1.1
            --  for details. In particular, this function *should* return
            --  True for a function call (or a user-defined literal, which
            --  is equivalent to a function call) if all actual parameters
            --  (including defaulted params) are known on entry and the
            --  function has "Globals => null" specified; the current
            --  implementation will incorrectly return False in this case.

            function All_Exps_Known_On_Entry
              (Expr_List : List_Id) return Boolean;
            --  Given a list of expressions, returns False iff
            --  Is_Known_On_Entry is False for at least one list element.

            -----------------------------
            -- All_Exps_Known_On_Entry --
            -----------------------------

            function All_Exps_Known_On_Entry
              (Expr_List : List_Id) return Boolean
            is
               Expr : Node_Id := First (Expr_List);
            begin
               while Present (Expr) loop
                  if not Is_Known_On_Entry (Expr) then
                     return False;
                  end if;
                  Next (Expr);
               end loop;
               return True;
            end All_Exps_Known_On_Entry;

         begin
            if Is_Static_Expression (Expr) then
               return True;
            end if;

            if Is_Attribute_Old (Expr) then
               return True;
            end if;

            declare
               Pref : Node_Id := Expr;
            begin
               loop
                  case Nkind (Pref) is
                     when N_Selected_Component =>
                        null;

                     when N_Indexed_Component =>
                        if not All_Exps_Known_On_Entry (Expressions (Pref))
                        then
                           return False;
                        end if;

                     when N_Slice =>
                        return False; -- just to be clear about this case

                     when others =>
                        exit;
                  end case;

                  Pref := Prefix (Pref);
               end loop;

               if Is_Entity_Name (Pref)
                 and then Is_Constant_Object (Entity (Pref))
               then
                  declare
                     Obj     : constant Entity_Id := Entity (Pref);
                     Obj_Typ : constant Entity_Id := Etype (Obj);
                  begin
                     case Ekind (Obj) is
                        when E_In_Parameter =>
                           if not Is_Elementary_Type (Obj_Typ) then
                              return False;
                           elsif Is_Aliased (Obj) then
                              return False;
                           end if;

                        when E_Constant =>
                           --  return False for a deferred constant
                           if Present (Full_View (Obj)) then
                              return False;
                           end if;

                           --  return False if not "all views are constant".
                           if Is_Immutably_Limited_Type (Obj_Typ)
                             or Needs_Finalization (Obj_Typ)
                           then
                              return False;
                           end if;

                        when others =>
                           null;
                     end case;
                  end;

                  return True;
               end if;

               --  ??? Cope with a malformed tree. Code to cope with a
               --  nonstatic use of an enumeration literal should not be
               --  necessary.
               if Is_Entity_Name (Pref)
                 and then Ekind (Entity (Pref)) = E_Enumeration_Literal
               then
                  return True;
               end if;
            end;

            case Nkind (Expr) is
               when N_Unary_Op =>
                  return Is_Known_On_Entry (Right_Opnd (Expr));

               when N_Binary_Op =>
                  return Is_Known_On_Entry (Left_Opnd (Expr))
                    and then Is_Known_On_Entry (Right_Opnd (Expr));

               when N_Type_Conversion | N_Qualified_Expression =>
                  return Is_Known_On_Entry (Expression (Expr));

               when N_If_Expression =>
                  if not All_Exps_Known_On_Entry (Expressions (Expr)) then
                     return False;
                  end if;

               when N_Case_Expression =>
                  if not Is_Known_On_Entry (Expression (Expr)) then
                     return False;
                  end if;

                  declare
                     Alt : Node_Id := First (Alternatives (Expr));
                  begin
                     while Present (Alt) loop
                        if not Is_Known_On_Entry (Expression (Alt)) then
                           return False;
                        end if;
                        Next (Alt);
                     end loop;
                  end;

                  return True;

               when others =>
                  null;
            end case;

            return False;
         end Is_Known_On_Entry;

      end Conditional_Evaluation;

      package body Indirect_Temps is

         Indirect_Temp_Access_Type_Char : constant Character := 'K';
         --  The character passed to Make_Temporary when declaring
         --  the access type that is used in the implementation of an
         --  indirect temporary.

         --------------------------
         -- Indirect_Temp_Needed --
         --------------------------

         function Indirect_Temp_Needed (Typ : Entity_Id) return Boolean is
         begin
            --  There should be no correctness issues if the only cases where
            --  this function returns False are cases where Typ is an
            --  anonymous access type and we need to generate a saooaaat (a
            --  stand-alone object of an anonymous access type) in order get
            --  accessibility right. In other cases where this function
            --  returns False, there would be no correctness problems with
            --  returning True instead; however, returning False when we can
            --  generally results in simpler code.

            return False

               --  If Typ is not definite, then we cannot generate
               --    Temp : Typ;

              or else not Is_Definite_Subtype (Typ)

              --  If Typ is tagged, then generating
              --    Temp : Typ;
              --  might generate an object with the wrong tag. If we had
              --  a predicate that indicated whether the nominal tag is
              --  trustworthy, we could use that predicate here.

              or else Is_Tagged_Type (Typ)

              --  If Typ needs finalization, then generating an implicit
              --    Temp : Typ;
              --  declaration could have user-visible side effects.

              or else Needs_Finalization (Typ)

              --  In the anonymous access type case, we need to
              --  generate a saooaaat. We don't want the code in
              --  in exp_attr.adb that deals with the case where this
              --  function returns False to have to deal with that case
              --  (just to avoid code duplication). So we cheat a little
              --  bit and return True here for an anonymous access type.

              or else Is_Anonymous_Access_Type (Typ);

            --  ??? Unimplemented - spec description says:
            --    For an unconstrained-but-definite discriminated subtype,
            --    returns True if the potential difference in size between an
            --    unconstrained object and a constrained object is large.
            --
            --  For example,
            --    type Typ (Len : Natural := 0) is
            --      record F : String (1 .. Len); end record;
            --
            --  See Large_Max_Size_Mutable function elsewhere in this file,
            --  currently declared inside of Needs_Secondary_Stack, so it
            --  would have to be moved if we want it to be callable from here.

         end Indirect_Temp_Needed;

         ---------------------------
         -- Declare_Indirect_Temp --
         ---------------------------

         procedure Declare_Indirect_Temp
           (Attr_Prefix : Node_Id; Indirect_Temp : out Entity_Id)
         is
            Loc         : constant Source_Ptr := Sloc (Attr_Prefix);
            Prefix_Type : constant Entity_Id := Etype (Attr_Prefix);
            Temp_Id     : constant Entity_Id :=
              Make_Temporary (Loc, 'P', Attr_Prefix);

            procedure Declare_Indirect_Temp_Via_Allocation;
            --  Handle the usual case.

            -------------------------------------------
            --  Declare_Indirect_Temp_Via_Allocation --
            -------------------------------------------

            procedure Declare_Indirect_Temp_Via_Allocation is
               Access_Type_Id : constant Entity_Id
                 := Make_Temporary
                      (Loc, Indirect_Temp_Access_Type_Char, Attr_Prefix);

               Temp_Decl : constant Node_Id :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Temp_Id,
                   Object_Definition   =>
                     New_Occurrence_Of (Access_Type_Id, Loc));

               Allocate_Class_Wide : constant Boolean :=
                 Is_Specific_Tagged_Type (Prefix_Type);
               --  If True then access type designates the class-wide type in
               --  order to preserve (at run time) the value of the underlying
               --  tag.
               --  ??? We could do better here (in the case where Prefix_Type
               --  is tagged and specific) if we had a predicate which takes an
               --  expression and returns True iff the expression is of
               --  a specific tagged type and the underlying tag (at run time)
               --  is statically known to match that of the specific type.
               --  In that case, Allocate_Class_Wide could safely be False.

               function Designated_Subtype_Mark return Node_Id;
               --  Usually, a subtype mark indicating the subtype of the
               --  attribute prefix. If that subtype is a specific tagged
               --  type, then returns the corresponding class-wide type.
               --  If the prefix is of an anonymous access type, then returns
               --  the designated type of that type.

               -----------------------------
               -- Designated_Subtype_Mark --
               -----------------------------

               function Designated_Subtype_Mark return Node_Id is
                  Typ : Entity_Id := Prefix_Type;
               begin
                  if Allocate_Class_Wide then
                     if Is_Private_Type (Typ)
                       and then Present (Full_View (Typ))
                     then
                        Typ := Full_View (Typ);
                     end if;
                     Typ := Class_Wide_Type (Typ);
                  end if;

                  return New_Occurrence_Of (Typ, Loc);
               end Designated_Subtype_Mark;

               Access_Type_Def : constant Node_Id
                 := Make_Access_To_Object_Definition
                      (Loc, Subtype_Indication => Designated_Subtype_Mark);

               Access_Type_Decl : constant Node_Id
                 := Make_Full_Type_Declaration
                      (Loc, Access_Type_Id,
                       Type_Definition => Access_Type_Def);
            begin
               Mutate_Ekind (Temp_Id, E_Variable);
               Set_Etype (Temp_Id, Access_Type_Id);
               Mutate_Ekind (Access_Type_Id, E_Access_Type);

               if Append_Decls_In_Reverse_Order then
                  Append_Item (Temp_Decl, Is_Eval_Stmt => False);
                  Append_Item (Access_Type_Decl, Is_Eval_Stmt => False);
               else
                  Append_Item (Access_Type_Decl, Is_Eval_Stmt => False);
                  Append_Item (Temp_Decl, Is_Eval_Stmt => False);
               end if;

               --  When a type associated with an indirect temporary gets
               --  created for a 'Old attribute reference we need to mark
               --  the type as such. This allows, for example, finalization
               --  masters associated with them to be finalized in the correct
               --  order after postcondition checks.

               if Attribute_Name (Parent (Attr_Prefix)) = Name_Old then
                  Set_Stores_Attribute_Old_Prefix (Access_Type_Id);
               end if;

               Analyze (Access_Type_Decl);
               Analyze (Temp_Decl);

               pragma Assert
                 (Is_Access_Type_For_Indirect_Temp (Access_Type_Id));

               declare
                  Expression : Node_Id := Attr_Prefix;
                  Allocator  : Node_Id;
               begin
                  if Allocate_Class_Wide then
                     --  generate T'Class'(T'Class (<prefix>))
                     Expression :=
                       Make_Type_Conversion (Loc,
                         Subtype_Mark => Designated_Subtype_Mark,
                         Expression   => Expression);
                  end if;

                  Allocator :=
                    Make_Allocator (Loc,
                      Make_Qualified_Expression
                        (Loc,
                         Subtype_Mark => Designated_Subtype_Mark,
                         Expression   => Expression));

                  --  Allocate saved prefix value on the secondary stack
                  --  in order to avoid introducing a storage leak. This
                  --  allocated object is never explicitly reclaimed.
                  --
                  --  ??? Emit storage leak warning if RE_SS_Pool
                  --  unavailable?

                  if RTE_Available (RE_SS_Pool) then
                     Set_Storage_Pool (Allocator, RTE (RE_SS_Pool));
                     Set_Procedure_To_Call
                       (Allocator, RTE (RE_SS_Allocate));
                     Set_Uses_Sec_Stack (Current_Scope);
                  end if;

                  Append_Item
                    (Make_Assignment_Statement (Loc,
                       Name       => New_Occurrence_Of (Temp_Id, Loc),
                       Expression => Allocator),
                     Is_Eval_Stmt => True);
               end;
            end Declare_Indirect_Temp_Via_Allocation;

         begin
            Indirect_Temp := Temp_Id;

            if Is_Anonymous_Access_Type (Prefix_Type) then
               --  In the anonymous access type case, we do not want a level
               --  indirection (which would result in declaring an
               --  access-to-access type); that would result in correctness
               --  problems - the accessibility level of the type of the
               --  'Old constant would be wrong (See 6.1.1.). So in that case,
               --  we do not generate an allocator. Instead we generate
               --     Temp : access Designated := null;
               --  which is unconditionally elaborated and then
               --     Temp := <attribute prefix>;
               --  which is conditionally executed.

               declare
                  Temp_Decl : constant Node_Id :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Temp_Id,
                      Object_Definition   =>
                        Make_Access_Definition
                          (Loc,
                           Constant_Present =>
                             Is_Access_Constant (Prefix_Type),
                           Subtype_Mark =>
                             New_Occurrence_Of
                               (Designated_Type (Prefix_Type), Loc)));
               begin
                  Append_Item (Temp_Decl, Is_Eval_Stmt => False);
                  Analyze (Temp_Decl);
                  Append_Item
                    (Make_Assignment_Statement (Loc,
                       Name       => New_Occurrence_Of (Temp_Id, Loc),
                       Expression => Attr_Prefix),
                     Is_Eval_Stmt => True);
               end;
            else
               --  the usual case
               Declare_Indirect_Temp_Via_Allocation;
            end if;
         end Declare_Indirect_Temp;

         -------------------------
         -- Indirect_Temp_Value --
         -------------------------

         function Indirect_Temp_Value
           (Temp : Entity_Id;
            Typ  : Entity_Id;
            Loc  : Source_Ptr) return Node_Id
         is
            Result : Node_Id;
         begin
            if Is_Anonymous_Access_Type (Typ) then
               --  No indirection in this case; just evaluate the temp.
               Result := New_Occurrence_Of (Temp, Loc);
               Set_Etype (Result, Etype (Temp));

            else
               Result := Make_Explicit_Dereference (Loc,
                                     New_Occurrence_Of (Temp, Loc));

               Set_Etype (Result, Designated_Type (Etype (Temp)));

               if Is_Specific_Tagged_Type (Typ) then
                  --  The designated type of the access type is class-wide, so
                  --  convert to the specific type.

                  Result :=
                    Make_Type_Conversion (Loc,
                      Subtype_Mark => New_Occurrence_Of (Typ, Loc),
                      Expression   => Result);

                  Set_Etype (Result, Typ);
               end if;
            end if;

            return Result;
         end Indirect_Temp_Value;

         function Is_Access_Type_For_Indirect_Temp
           (T : Entity_Id) return Boolean is
         begin
            if Is_Access_Type (T)
               and then not Comes_From_Source (T)
               and then Is_Internal_Name (Chars (T))
               and then Nkind (Scope (T)) in N_Entity
               and then Ekind (Scope (T))
                 in E_Entry | E_Entry_Family | E_Function | E_Procedure
               and then
                 (Present (Wrapped_Statements (Scope (T)))
                  or else Present (Contract (Scope (T))))
            then
               --  ??? Should define a flag for this. We could incorrectly
               --  return True if other clients of Make_Temporary happen to
               --  pass in the same character.
               declare
                  Name : constant String := Get_Name_String (Chars (T));
               begin
                  if Name (Name'First) = Indirect_Temp_Access_Type_Char then
                     return True;
                  end if;
               end;
            end if;

            return False;
         end Is_Access_Type_For_Indirect_Temp;

      end Indirect_Temps;
   end Old_Attr_Util;

   package body Storage_Model_Support is

      -----------------------------------------
      -- Has_Designated_Storage_Model_Aspect --
      -----------------------------------------

      function Has_Designated_Storage_Model_Aspect
        (Typ : Entity_Id) return Boolean
      is
      begin
         return Has_Aspect (Typ, Aspect_Designated_Storage_Model);
      end Has_Designated_Storage_Model_Aspect;

      -----------------------------------
      -- Has_Storage_Model_Type_Aspect --
      -----------------------------------

      function Has_Storage_Model_Type_Aspect (Typ : Entity_Id) return Boolean
      is
      begin
         return Has_Aspect (Typ, Aspect_Storage_Model_Type);
      end Has_Storage_Model_Type_Aspect;

      --------------------------
      -- Storage_Model_Object --
      --------------------------

      function Storage_Model_Object (Typ : Entity_Id) return Entity_Id is
      begin
         pragma Assert (Has_Designated_Storage_Model_Aspect (Typ));

         return
           Entity
             (Find_Value_Of_Aspect (Typ, Aspect_Designated_Storage_Model));
      end Storage_Model_Object;

      ------------------------
      -- Storage_Model_Type --
      ------------------------

      function Storage_Model_Type (Obj : Entity_Id) return Entity_Id is
      begin
         pragma Assert (Has_Storage_Model_Type_Aspect (Etype (Obj)));

         return Etype (Obj);
      end Storage_Model_Type;

      -----------------------------------
      -- Get_Storage_Model_Type_Entity --
      -----------------------------------

      function Get_Storage_Model_Type_Entity
        (SM_Obj_Or_Type : Entity_Id;
         Nam            : Name_Id) return Entity_Id
      is
         Typ : constant Entity_Id := (if Is_Object (SM_Obj_Or_Type) then
                                         Storage_Model_Type (SM_Obj_Or_Type)
                                      else
                                         SM_Obj_Or_Type);
         pragma Assert
           (Is_Type (Typ)
             and then
               Nam in Name_Address_Type
                    | Name_Null_Address
                    | Name_Allocate
                    | Name_Deallocate
                    | Name_Copy_From
                    | Name_Copy_To
                    | Name_Storage_Size);

         Assoc            : Node_Id;
         SMT_Aspect_Value : constant Node_Id :=
           Find_Value_Of_Aspect (Typ, Aspect_Storage_Model_Type);

      begin
         --  When the aspect has an aggregate expression, search through it
         --  to locate a match for the name of the given "subaspect" and return
         --  the entity of the aggregate association's expression.

         if Present (SMT_Aspect_Value) then
            Assoc := First (Component_Associations (SMT_Aspect_Value));
            while Present (Assoc) loop
               if Chars (First (Choices (Assoc))) = Nam then
                  return Entity (Expression (Assoc));
               end if;

               Next (Assoc);
            end loop;
         end if;

         --  The aggregate argument of Storage_Model_Type is optional, and when
         --  not present the aspect defaults to the native storage model, where
         --  the address type is System.Address. In that case, we return
         --  System.Address for Name_Address_Type and System.Null_Address for
         --  Name_Null_Address, but return Empty for other cases, and leave it
         --  to the back end to map those to the appropriate native operations.

         if Nam = Name_Address_Type then
            return RTE (RE_Address);

         elsif Nam = Name_Null_Address then
            return RTE (RE_Null_Address);

         else
            return Empty;
         end if;
      end Get_Storage_Model_Type_Entity;

      --------------------------------
      -- Storage_Model_Address_Type --
      --------------------------------

      function Storage_Model_Address_Type
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Address_Type);
      end Storage_Model_Address_Type;

      --------------------------------
      -- Storage_Model_Null_Address --
      --------------------------------

      function Storage_Model_Null_Address
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Null_Address);
      end Storage_Model_Null_Address;

      ----------------------------
      -- Storage_Model_Allocate --
      ----------------------------

      function Storage_Model_Allocate
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Allocate);
      end Storage_Model_Allocate;

      ------------------------------
      -- Storage_Model_Deallocate --
      ------------------------------

      function Storage_Model_Deallocate
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Deallocate);
      end Storage_Model_Deallocate;

      -----------------------------
      -- Storage_Model_Copy_From --
      -----------------------------

      function Storage_Model_Copy_From
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Copy_From);
      end Storage_Model_Copy_From;

      ---------------------------
      -- Storage_Model_Copy_To --
      ---------------------------

      function Storage_Model_Copy_To
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Copy_To);
      end Storage_Model_Copy_To;

      --------------------------------
      -- Storage_Model_Storage_Size --
      --------------------------------

      function Storage_Model_Storage_Size
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Storage_Size);
      end Storage_Model_Storage_Size;

   end Storage_Model_Support;

begin
   Erroutc.Subprogram_Name_Ptr := Subprogram_Name'Access;
end Sem_Util;
