------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ U T I L                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2022, 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 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_Ch3;        use Exp_Ch3;
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 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).

   function Is_Container_Aggregate (Exp : Node_Id) return Boolean;
   --  Is the given expression a container aggregate?

   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;

   -------------------------
   -- Accessibility_Level --
   -------------------------

   function Accessibility_Level
     (Expr              : Node_Id;
      Level             : Accessibility_Level_Kind;
      In_Return_Context : Boolean := False;
      Allow_Alt_Model   : Boolean := True) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Expr);

      function Accessibility_Level (Expr : Node_Id) return Node_Id
        is (Accessibility_Level (Expr, Level, In_Return_Context));
      --  Renaming of the enclosing function to facilitate recursive calls

      function Make_Level_Literal (Level : Uint) return Node_Id;
      --  Construct an integer literal representing an accessibility level
      --  with its type set to Natural.

      function Innermost_Master_Scope_Depth (N : Node_Id) return Uint;
      --  Returns the scope depth of the given node's innermost enclosing
      --  scope (effectively the accessibility level of the innermost
      --  enclosing master).

      function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id;
      --  Centralized processing of subprogram calls which may appear in
      --  prefix notation.

      function Typ_Access_Level (Typ : Entity_Id) return Uint
        is (Type_Access_Level (Typ, Allow_Alt_Model));
      --  Renaming of Type_Access_Level with Allow_Alt_Model specified to avoid
      --  passing the parameter specifically in every call.

      ----------------------------------
      -- Innermost_Master_Scope_Depth --
      ----------------------------------

      function Innermost_Master_Scope_Depth (N : Node_Id) return Uint is
         Encl_Scop           : Entity_Id;
         Ent                 : Entity_Id;
         Node_Par            : Node_Id := Parent (N);
         Master_Lvl_Modifier : Int     := 0;

      begin
         --  Locate the nearest enclosing node (by traversing Parents)
         --  that Defining_Entity can be applied to, and return the
         --  depth of that entity's nearest enclosing scope.

         --  The rules that define what a master are defined in
         --  RM 7.6.1 (3), and include statements and conditions for loops
         --  among other things. These cases are detected properly ???

         while Present (Node_Par) loop
            Ent := Defining_Entity_Or_Empty (Node_Par);

            if Present (Ent) then
               Encl_Scop := Find_Enclosing_Scope (Ent);

               --  Ignore transient scopes made during expansion

               if Comes_From_Source (Node_Par) then
                  --  Note that in some rare cases the scope depth may not be
                  --  set, for example, when we are in the middle of analyzing
                  --  a type and the enclosing scope is said type. So, instead,
                  --  continue to move up the parent chain since the scope
                  --  depth of the type's parent is the same as that of the
                  --  type.

                  if not Scope_Depth_Set (Encl_Scop) then
                     pragma Assert (Nkind (Parent (Encl_Scop))
                                     = N_Full_Type_Declaration);
                  else
                     return
                       Scope_Depth (Encl_Scop) + Master_Lvl_Modifier;
                  end if;
               end if;

            --  For a return statement within a function, return
            --  the depth of the function itself. This is not just
            --  a small optimization, but matters when analyzing
            --  the expression in an expression function before
            --  the body is created.

            elsif Nkind (Node_Par) in N_Extended_Return_Statement
                                    | N_Simple_Return_Statement
            then
               return Scope_Depth (Enclosing_Subprogram (Node_Par));

            --  Statements are counted as masters

            elsif Is_Master (Node_Par) then
               Master_Lvl_Modifier := Master_Lvl_Modifier + 1;

            end if;

            Node_Par := Parent (Node_Par);
         end loop;

         --  Should never reach the following return

         pragma Assert (False);

         return Scope_Depth (Current_Scope) + 1;
      end Innermost_Master_Scope_Depth;

      ------------------------
      -- Make_Level_Literal --
      ------------------------

      function Make_Level_Literal (Level : Uint) return Node_Id is
         Result : constant Node_Id := Make_Integer_Literal (Loc, Level);

      begin
         Set_Etype (Result, Standard_Natural);
         return Result;
      end Make_Level_Literal;

      --------------------------------------
      -- Function_Call_Or_Allocator_Level --
      --------------------------------------

      function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id is
         Par      : Node_Id;
         Prev_Par : Node_Id;
      begin
         --  Results of functions are objects, so we either get the
         --  accessibility of the function or, in case of a call which is
         --  indirect, the level of the access-to-subprogram type.

         --  This code looks wrong ???

         if Nkind (N) = N_Function_Call
           and then Ada_Version < Ada_2005
         then
            if Is_Entity_Name (Name (N)) then
               return Make_Level_Literal
                        (Subprogram_Access_Level (Entity (Name (N))));
            else
               return Make_Level_Literal
                        (Typ_Access_Level (Etype (Prefix (Name (N)))));
            end if;

         --  We ignore coextensions as they cannot be implemented under the
         --  "small-integer" model.

         elsif Nkind (N) = N_Allocator
           and then (Is_Static_Coextension (N)
                      or else Is_Dynamic_Coextension (N))
         then
            return Make_Level_Literal (Scope_Depth (Standard_Standard));
         end if;

         --  Named access types have a designated level

         if Is_Named_Access_Type (Etype (N)) then
            return Make_Level_Literal (Typ_Access_Level (Etype (N)));

         --  Otherwise, the level is dictated by RM 3.10.2 (10.7/3)

         else
            --  Check No_Dynamic_Accessibility_Checks restriction override for
            --  alternative accessibility model.

            if Allow_Alt_Model
              and then No_Dynamic_Accessibility_Checks_Enabled (N)
              and then Is_Anonymous_Access_Type (Etype (N))
            then
               --  In the alternative model the level is that of the
               --  designated type.

               if Debug_Flag_Underscore_B then
                  return Make_Level_Literal (Typ_Access_Level (Etype (N)));

               --  For function calls the level is that of the innermost
               --  master, otherwise (for allocators etc.) we get the level
               --  of the corresponding anonymous access type, which is
               --  calculated through the normal path of execution.

               elsif Nkind (N) = N_Function_Call then
                  return Make_Level_Literal
                           (Innermost_Master_Scope_Depth (Expr));
               end if;
            end if;

            if Nkind (N) = N_Function_Call then
               --  Dynamic checks are generated when we are within a return
               --  value or we are in a function call within an anonymous
               --  access discriminant constraint of a return object (signified
               --  by In_Return_Context) on the side of the callee.

               --  So, in this case, return accessibility level of the
               --  enclosing subprogram.

               if In_Return_Value (N)
                 or else In_Return_Context
               then
                  return Make_Level_Literal
                           (Subprogram_Access_Level (Current_Subprogram));
               end if;
            end if;

            --  When the call is being dereferenced the level is that of the
            --  enclosing master of the dereferenced call.

            if Nkind (Parent (N)) in N_Explicit_Dereference
                                   | N_Indexed_Component
                                   | N_Selected_Component
            then
               return Make_Level_Literal
                        (Innermost_Master_Scope_Depth (Expr));
            end if;

            --  Find any relevant enclosing parent nodes that designate an
            --  object being initialized.

            --  Note: The above is only relevant if the result is used "in its
            --  entirety" as RM 3.10.2 (10.2/3) states. However, this is
            --  accounted for in the case statement in the main body of
            --  Accessibility_Level for N_Selected_Component.

            Par      := Parent (Expr);
            Prev_Par := Empty;
            while Present (Par) loop
               --  Detect an expanded implicit conversion, typically this
               --  occurs on implicitly converted actuals in calls.

               --  Does this catch all implicit conversions ???

               if Nkind (Par) = N_Type_Conversion
                 and then Is_Named_Access_Type (Etype (Par))
               then
                  return Make_Level_Literal
                           (Typ_Access_Level (Etype (Par)));
               end if;

               --  Jump out when we hit an object declaration or the right-hand
               --  side of an assignment, or a construct such as an aggregate
               --  subtype indication which would be the result is not used
               --  "in its entirety."

               exit when Nkind (Par) in N_Object_Declaration
                           or else (Nkind (Par) = N_Assignment_Statement
                                     and then Name (Par) /= Prev_Par);

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

            --  Assignment statements are handled in a similar way in
            --  accordance to the left-hand part. However, strictly speaking,
            --  this is illegal according to the RM, but this change is needed
            --  to pass an ACATS C-test and is useful in general ???

            case Nkind (Par) is
               when N_Object_Declaration =>
                  return Make_Level_Literal
                           (Scope_Depth
                             (Scope (Defining_Identifier (Par))));

               when N_Assignment_Statement =>
                  --  Return the accessibility level of the left-hand part

                  return Accessibility_Level
                           (Expr              => Name (Par),
                            Level             => Object_Decl_Level,
                            In_Return_Context => In_Return_Context);

               when others =>
                  return Make_Level_Literal
                           (Innermost_Master_Scope_Depth (Expr));
            end case;
         end if;
      end Function_Call_Or_Allocator_Level;

      --  Local variables

      E   : Node_Id := Original_Node (Expr);
      Pre : Node_Id;

   --  Start of processing for Accessibility_Level

   begin
      --  We could be looking at a reference to a formal due to the expansion
      --  of entries and other cases, so obtain the renaming if necessary.

      if Present (Param_Entity (Expr)) then
         E := Param_Entity (Expr);
      end if;

      --  Extract the entity

      if Nkind (E) in N_Has_Entity and then Present (Entity (E)) then
         E := Entity (E);

         --  Deal with a possible renaming of a private protected component

         if Ekind (E) in E_Constant | E_Variable and then Is_Prival (E) then
            E := Prival_Link (E);
         end if;
      end if;

      --  Perform the processing on the expression

      case Nkind (E) is
         --  The level of an aggregate is that of the innermost master that
         --  evaluates it as defined in RM 3.10.2 (10/4).

         when N_Aggregate =>
            return Make_Level_Literal (Innermost_Master_Scope_Depth (Expr));

         --  The accessibility level is that of the access type, except for an
         --  anonymous allocators which have special rules defined in RM 3.10.2
         --  (14/3).

         when N_Allocator =>
            return Function_Call_Or_Allocator_Level (E);

         --  We could reach this point for two reasons. Either the expression
         --  applies to a special attribute ('Loop_Entry, 'Result, or 'Old), or
         --  we are looking at the access attributes directly ('Access,
         --  'Address, or 'Unchecked_Access).

         when N_Attribute_Reference =>
            Pre := Original_Node (Prefix (E));

            --  Regular 'Access attribute presence means we have to look at the
            --  prefix.

            if Attribute_Name (E) = Name_Access then
               return Accessibility_Level (Prefix (E));

            --  Unchecked or unrestricted attributes have unlimited depth

            elsif Attribute_Name (E) in Name_Address
                                      | Name_Unchecked_Access
                                      | Name_Unrestricted_Access
            then
               return Make_Level_Literal (Scope_Depth (Standard_Standard));

            --  'Access can be taken further against other special attributes,
            --  so handle these cases explicitly.

            elsif Attribute_Name (E)
                    in Name_Old | Name_Loop_Entry | Name_Result
            then
               --  Named access types

               if Is_Named_Access_Type (Etype (Pre)) then
                  return Make_Level_Literal
                           (Typ_Access_Level (Etype (Pre)));

               --  Anonymous access types

               elsif Nkind (Pre) in N_Has_Entity
                 and then Ekind (Entity (Pre)) not in Subprogram_Kind
                 and then Present (Get_Dynamic_Accessibility (Entity (Pre)))
                 and then Level = Dynamic_Level
               then
                  return New_Occurrence_Of
                           (Get_Dynamic_Accessibility (Entity (Pre)), Loc);

               --  Otherwise the level is treated in a similar way as
               --  aggregates according to RM 6.1.1 (35.1/4) which concerns
               --  an implicit constant declaration - in turn defining the
               --  accessibility level to be that of the implicit constant
               --  declaration.

               else
                  return Make_Level_Literal
                           (Innermost_Master_Scope_Depth (Expr));
               end if;

            else
               raise Program_Error;
            end if;

         --  This is the "base case" for accessibility level calculations which
         --  means we are near the end of our recursive traversal.

         when N_Defining_Identifier =>
            --  A dynamic check is performed on the side of the callee when we
            --  are within a return statement, so return a library-level
            --  accessibility level to null out checks on the side of the
            --  caller.

            if Is_Explicitly_Aliased (E)
              and then (In_Return_Context
                         or else (Level /= Dynamic_Level
                                   and then In_Return_Value (Expr)))
            then
               return Make_Level_Literal (Scope_Depth (Standard_Standard));

            --  Something went wrong and an extra accessibility formal has not
            --  been generated when one should have ???

            elsif Is_Formal (E)
              and then not Present (Get_Dynamic_Accessibility (E))
              and then Ekind (Etype (E)) = E_Anonymous_Access_Type
            then
               return Make_Level_Literal (Scope_Depth (Standard_Standard));

            --  Stand-alone object of an anonymous access type "SAOAAT"

            elsif (Is_Formal (E)
                    or else Ekind (E) in E_Variable
                                       | E_Constant)
              and then Present (Get_Dynamic_Accessibility (E))
              and then (Level = Dynamic_Level
                         or else Level = Zero_On_Dynamic_Level)
            then
               if Level = Zero_On_Dynamic_Level then
                  return Make_Level_Literal
                           (Scope_Depth (Standard_Standard));
               end if;

               --  No_Dynamic_Accessibility_Checks restriction override for
               --  alternative accessibility model.

               if Allow_Alt_Model
                 and then No_Dynamic_Accessibility_Checks_Enabled (E)
               then
                  --  In the alternative model the level is that of the
                  --  designated type entity's context.

                  if Debug_Flag_Underscore_B then
                     return Make_Level_Literal (Typ_Access_Level (Etype (E)));

                  --  Otherwise the level depends on the entity's context

                  elsif Is_Formal (E) then
                     return Make_Level_Literal
                              (Subprogram_Access_Level
                                (Enclosing_Subprogram (E)));
                  else
                     return Make_Level_Literal
                              (Scope_Depth (Enclosing_Dynamic_Scope (E)));
                  end if;
               end if;

               --  Return the dynamic level in the normal case

               return New_Occurrence_Of
                        (Get_Dynamic_Accessibility (E), Loc);

            --  Initialization procedures have a special extra accessibility
            --  parameter associated with the level at which the object
            --  being initialized exists

            elsif Ekind (E) = E_Record_Type
              and then Is_Limited_Record (E)
              and then Current_Scope = Init_Proc (E)
              and then Present (Init_Proc_Level_Formal (Current_Scope))
            then
               return New_Occurrence_Of
                        (Init_Proc_Level_Formal (Current_Scope), Loc);

            --  Current instance of the type is deeper than that of the type
            --  according to RM 3.10.2 (21).

            elsif Is_Type (E) then
               --  When restriction No_Dynamic_Accessibility_Checks is active
               --  along with -gnatd_b.

               if Allow_Alt_Model
                 and then No_Dynamic_Accessibility_Checks_Enabled (E)
                 and then Debug_Flag_Underscore_B
               then
                  return Make_Level_Literal (Typ_Access_Level (E));
               end if;

               --  Normal path

               return Make_Level_Literal (Typ_Access_Level (E) + 1);

            --  Move up the renamed entity or object if it came from source
            --  since expansion may have created a dummy renaming under
            --  certain circumstances.

            --  Note: We check if the original node of the renaming comes
            --  from source because the node may have been rewritten.

            elsif Present (Renamed_Entity_Or_Object (E))
              and then Comes_From_Source
                (Original_Node (Renamed_Entity_Or_Object (E)))
            then
               return Accessibility_Level (Renamed_Entity_Or_Object (E));

            --  Named access types get their level from their associated type

            elsif Is_Named_Access_Type (Etype (E)) then
               return Make_Level_Literal
                        (Typ_Access_Level (Etype (E)));

            --  Check if E is an expansion-generated renaming of an iterator
            --  by examining Related_Expression. If so, determine the
            --  accessibility level based on the original expression.

            elsif Ekind (E) in E_Constant | E_Variable
              and then Present (Related_Expression (E))
            then
               return Accessibility_Level (Related_Expression (E));

            elsif Level = Dynamic_Level
               and then Ekind (E) in E_In_Parameter | E_In_Out_Parameter
               and then Present (Init_Proc_Level_Formal (Scope (E)))
            then
               return New_Occurrence_Of
                        (Init_Proc_Level_Formal (Scope (E)), Loc);

            --  Normal object - get the level of the enclosing scope

            else
               return Make_Level_Literal
                        (Scope_Depth (Enclosing_Dynamic_Scope (E)));
            end if;

         --  Handle indexed and selected components including the special cases
         --  whereby there is an implicit dereference, a component of a
         --  composite type, or a function call in prefix notation.

         --  We don't handle function calls in prefix notation correctly ???

         when N_Indexed_Component | N_Selected_Component | N_Slice =>
            Pre := Prefix (E);

            --  Fetch the original node when the prefix comes from the result
            --  of expanding a function call since we want to find the level
            --  of the original source call.

            if not Comes_From_Source (Pre)
              and then Nkind (Original_Node (Pre)) = N_Function_Call
            then
               Pre := Original_Node (Pre);
            end if;

            --  When E is an indexed component or selected component and
            --  the current Expr is a function call, we know that we are
            --  looking at an expanded call in prefix notation.

            if Nkind (Expr) = N_Function_Call then
               return Function_Call_Or_Allocator_Level (Expr);

            --  If the prefix is a named access type, then we are dealing
            --  with an implicit deferences. In that case the level is that
            --  of the named access type in the prefix.

            elsif Is_Named_Access_Type (Etype (Pre)) then
               return Make_Level_Literal
                        (Typ_Access_Level (Etype (Pre)));

            --  The current expression is a named access type, so there is no
            --  reason to look at the prefix. Instead obtain the level of E's
            --  named access type.

            elsif Is_Named_Access_Type (Etype (E)) then
               return Make_Level_Literal
                        (Typ_Access_Level (Etype (E)));

            --  A nondiscriminant selected component where the component
            --  is an anonymous access type means that its associated
            --  level is that of the containing type - see RM 3.10.2 (16).

            --  Note that when restriction No_Dynamic_Accessibility_Checks is
            --  in effect we treat discriminant components as regular
            --  components.

            elsif
              (Nkind (E) = N_Selected_Component
                and then Ekind (Etype (E))   =  E_Anonymous_Access_Type
                and then Ekind (Etype (Pre)) /= E_Anonymous_Access_Type
                and then (not (Nkind (Selector_Name (E)) in N_Has_Entity
                                and then Ekind (Entity (Selector_Name (E)))
                                           = E_Discriminant)

                           --  The alternative accessibility models both treat
                           --  discriminants as regular components.

                           or else (No_Dynamic_Accessibility_Checks_Enabled (E)
                                     and then Allow_Alt_Model)))

              --  Arrays featuring components of anonymous access components
              --  get their corresponding level from their containing type's
              --  declaration.

              or else
                (Nkind (E) = N_Indexed_Component
                  and then Ekind (Etype (E)) = E_Anonymous_Access_Type
                  and then Ekind (Etype (Pre)) in Array_Kind
                  and then Ekind (Component_Type (Base_Type (Etype (Pre))))
                             = E_Anonymous_Access_Type)
            then
               --  When restriction No_Dynamic_Accessibility_Checks is active
               --  and -gnatd_b set, the level is that of the designated type.

               if Allow_Alt_Model
                 and then No_Dynamic_Accessibility_Checks_Enabled (E)
                 and then Debug_Flag_Underscore_B
               then
                  return Make_Level_Literal
                           (Typ_Access_Level (Etype (E)));
               end if;

               --  Otherwise proceed normally

               return Make_Level_Literal
                        (Typ_Access_Level (Etype (Prefix (E))));

            --  The accessibility calculation routine that handles function
            --  calls (Function_Call_Level) assumes, in the case the
            --  result is of an anonymous access type, that the result will be
            --  used "in its entirety" when the call is present within an
            --  assignment or object declaration.

            --  To properly handle cases where the result is not used in its
            --  entirety, we test if the prefix of the component in question is
            --  a function call, which tells us that one of its components has
            --  been identified and is being accessed. Therefore we can
            --  conclude that the result is not used "in its entirety"
            --  according to RM 3.10.2 (10.2/3).

            elsif Nkind (Pre) = N_Function_Call
              and then not Is_Named_Access_Type (Etype (Pre))
            then
               --  Dynamic checks are generated when we are within a return
               --  value or we are in a function call within an anonymous
               --  access discriminant constraint of a return object (signified
               --  by In_Return_Context) on the side of the callee.

               --  So, in this case, return a library accessibility level to
               --  null out the check on the side of the caller.

               if (In_Return_Value (E)
                    or else In_Return_Context)
                 and then Level /= Dynamic_Level
               then
                  return Make_Level_Literal
                           (Scope_Depth (Standard_Standard));
               end if;

               return Make_Level_Literal
                        (Innermost_Master_Scope_Depth (Expr));

            --  Otherwise, continue recursing over the expression prefixes

            else
               return Accessibility_Level (Prefix (E));
            end if;

         --  Qualified expressions

         when N_Qualified_Expression =>
            if Is_Named_Access_Type (Etype (E)) then
               return Make_Level_Literal
                        (Typ_Access_Level (Etype (E)));
            else
               return Accessibility_Level (Expression (E));
            end if;

         --  Handle function calls

         when N_Function_Call =>
            return Function_Call_Or_Allocator_Level (E);

         --  Explicit dereference accessibility level calculation

         when N_Explicit_Dereference =>
            Pre := Original_Node (Prefix (E));

            --  The prefix is a named access type so the level is taken from
            --  its type.

            if Is_Named_Access_Type (Etype (Pre)) then
               return Make_Level_Literal (Typ_Access_Level (Etype (Pre)));

            --  Otherwise, recurse deeper

            else
               return Accessibility_Level (Prefix (E));
            end if;

         --  Type conversions

         when N_Type_Conversion | N_Unchecked_Type_Conversion =>
            --  View conversions are special in that they require use to
            --  inspect the expression of the type conversion.

            --  Allocators of anonymous access types are internally generated,
            --  so recurse deeper in that case as well.

            if Is_View_Conversion (E)
              or else Ekind (Etype (E)) = E_Anonymous_Access_Type
            then
               return Accessibility_Level (Expression (E));

            --  We don't care about the master if we are looking at a named
            --  access type.

            elsif Is_Named_Access_Type (Etype (E)) then
               return Make_Level_Literal
                        (Typ_Access_Level (Etype (E)));

            --  In section RM 3.10.2 (10/4) the accessibility rules for
            --  aggregates and value conversions are outlined. Are these
            --  followed in the case of initialization of an object ???

            --  Should use Innermost_Master_Scope_Depth ???

            else
               return Accessibility_Level (Current_Scope);
            end if;

         --  Default to the type accessibility level for the type of the
         --  expression's entity.

         when others =>
            return Make_Level_Literal (Typ_Access_Level (Etype (E)));
      end case;
   end Accessibility_Level;

   --------------------------------
   -- Static_Accessibility_Level --
   --------------------------------

   function Static_Accessibility_Level
     (Expr              : Node_Id;
      Level             : Static_Accessibility_Level_Kind;
      In_Return_Context : Boolean := False) return Uint
   is
   begin
      return Intval
               (Accessibility_Level (Expr, Level, In_Return_Context));
   end Static_Accessibility_Level;

   ----------------------------------
   -- 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) 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, Current_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 (Inside_A_Generic or not Full_Analysis or not GNATprove_Mode)
      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
              not Present (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 have no dynamic predicates.

            if Nkind (Parent (N)) = N_Loop_Parameter_Specification
              and then not Has_Dynamic_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 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));
         end if;

         --  Nothing needs to be done for access parameters

         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 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;

         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_In | N_Not_In
                 and then Present (Alternatives (N))
               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

               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_In
                           | N_Not_In
                        =>
                           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;
               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 (not Present (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);
      Subp_Decl    : constant Node_Id := Unit_Declaration_Node (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      : Entity_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;
      end if;

      --  Retrieve the entity of the subprogram spec (if any)

      if Nkind (Subp_Decl) = N_Subprogram_Body
        and then Present (Corresponding_Spec (Subp_Decl))
      then
         Spec_Id := Corresponding_Spec (Subp_Decl);

      elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
        and then Present (Corresponding_Spec_Of_Stub (Subp_Decl))
      then
         Spec_Id := Corresponding_Spec_Of_Stub (Subp_Decl);

      else
         Spec_Id := Subp_Id;
      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 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 any form of
                  --  refinement.

                  if not Is_Null_State (State_Id)
                    and then not Has_Null_Refinement (State_Id)
                    and then not Has_Non_Null_Refinement (State_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 Init_Proc_Type in E_Record_Type_Id
                        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

      elsif Is_Limited_View (Typ) 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
            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)));
            Set_Has_Aspects (To, True);
         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)));
            Set_Has_Aspects (To, True);
         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
      Typ  : constant Entity_Id := Find_Dispatching_Type (Ancestor_Op);
      Elmt : Elmt_Id;
      Subp : Entity_Id;

      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).

      ------------------------------
      -- 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;

   --  Start of processing for Corresponding_Primitive_Op

   begin
      pragma Assert (Is_Dispatching_Operation (Ancestor_Op));
      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;

   -------------------------------
   -- Deepest_Type_Access_Level --
   -------------------------------

   function Deepest_Type_Access_Level
     (Typ             : Entity_Id;
      Allow_Alt_Model : Boolean := True) return Uint
   is
   begin
      if Ekind (Typ) = E_Anonymous_Access_Type
        and then not Is_Local_Anonymous_Access (Typ)
        and then Nkind (Associated_Node_For_Itype (Typ)) = N_Object_Declaration
      then
         --  No_Dynamic_Accessibility_Checks override for alternative
         --  accessibility model.

         if Allow_Alt_Model
           and then No_Dynamic_Accessibility_Checks_Enabled (Typ)
         then
            return Type_Access_Level (Typ, Allow_Alt_Model);
         end if;

         --  Typ is the type of an Ada 2012 stand-alone object of an anonymous
         --  access type.

         return
           Scope_Depth (Enclosing_Dynamic_Scope
                         (Defining_Identifier
                           (Associated_Node_For_Itype (Typ))));

      --  For generic formal type, return Int'Last (infinite).
      --  See comment preceding Is_Generic_Type call in Type_Access_Level.

      elsif Is_Generic_Type (Root_Type (Typ)) then
         return UI_From_Int (Int'Last);

      else
         return Type_Access_Level (Typ, Allow_Alt_Model);
      end if;
   end Deepest_Type_Access_Level;

   ---------------------
   -- 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_Extra_Accessibility --
   -----------------------------------

   function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id is
   begin
      if Present (Renamed_Object (Id))
        and then Is_Entity_Name (Renamed_Object (Id))
      then
         return Effective_Extra_Accessibility (Entity (Renamed_Object (Id)));
      else
         return Extra_Accessibility (Id);
      end if;
   end Effective_Extra_Accessibility;

   -----------------------------
   -- 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_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;

      --  Otherwise, the kind E_Void insures that premature uses of the entity
      --  will be detected. Any_Type insures that no cascaded errors will occur

      else
         Mutate_Ekind (Def_Id, E_Void);
         Set_Etype (Def_Id, Any_Type);
      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;

   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 Is_Entity_Name (Call_Nam)
           and then Present (Entity (Call_Nam))
           and then (Is_Generic_Subprogram (Entity (Call_Nam))
                      or else Is_Overloadable (Entity (Call_Nam))
                      or else Ekind (Entity (Call_Nam)) 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 (Entity (Call_Nam));
            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;

      elsif Present (Component_Items (Comp_List)) then
         Comp_Item := First (Component_Items (Comp_List));

      else
         Comp_Item := Empty;
      end if;

      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));
         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;

         if No (Next (Assoc)) then
            Error_Msg_NE
              (" missing value for discriminant&",
               First (Governed_By), Discrim_Name);

            Report_Errors := True;
            return;
         end if;

         Next (Assoc);
      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_Dynamic_Accessibility --
   -------------------------------

   function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id is
   begin
      --  When minimum accessibility is set for E then we utilize it - except
      --  in a few edge cases like the expansion of select statements where
      --  generated subprogram may attempt to unnecessarily use a minimum
      --  accessibility object declared outside of scope.

      --  To avoid these situations where expansion may get complex we verify
      --  that the minimum accessibility object is within scope.

      if Is_Formal (E)
        and then Present (Minimum_Accessibility (E))
        and then In_Open_Scopes (Scope (Minimum_Accessibility (E)))
      then
         return Minimum_Accessibility (E);
      end if;

      return Extra_Accessibility (E);
   end Get_Dynamic_Accessibility;

   ------------------------
   -- 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));

      --  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));

      --  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 not Present (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_Access_Values --
   -----------------------

   function Has_Access_Values (T : Entity_Id) return Boolean
   is
      Typ : constant Entity_Id := Underlying_Type (T);

   begin
      --  Case of a private type which is not completed yet. This can only
      --  happen in the case of a generic formal type appearing directly, or
      --  as a component of the type to which this function is being applied
      --  at the top level. Return False in this case, since we certainly do
      --  not know that the type contains access types.

      if No (Typ) then
         return False;

      elsif Is_Access_Type (Typ) then
         return True;

      elsif Is_Array_Type (Typ) then
         return Has_Access_Values (Component_Type (Typ));

      elsif Is_Record_Type (Typ) then
         declare
            Comp : Entity_Id;

         begin
            --  Loop to check components

            Comp := First_Component_Or_Discriminant (Typ);
            while Present (Comp) loop

               --  Check for access component, tag field does not count, even
               --  though it is implemented internally using an access type.

               if Has_Access_Values (Etype (Comp))
                 and then Chars (Comp) /= Name_uTag
               then
                  return True;
               end if;

               Next_Component_Or_Discriminant (Comp);
            end loop;
         end;

         return False;

      else
         return False;
      end if;
   end Has_Access_Values;

   ---------------------------------------
   -- Has_Anonymous_Access_Discriminant --
   ---------------------------------------

   function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean
   is
      Disc : Node_Id;

   begin
      if not Has_Discriminants (Typ) then
         return False;
      end if;

      Disc := First_Discriminant (Typ);
      while Present (Disc) loop
         if Ekind (Etype (Disc)) = E_Anonymous_Access_Type then
            return True;
         end if;

         Next_Discriminant (Disc);
      end loop;

      return False;
   end Has_Anonymous_Access_Discriminant;

   ------------------------------
   -- 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 not Present (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 Present (Find_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 entities of record or protected type

         Ent := E;
         while Present (Ent) loop

            --  We are interested only in components and discriminants

            Exp := Empty;

            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));
                  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 =>
                  goto Check_Next_Entity;
            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;

         <<Check_Next_Entity>>
            Next_Entity (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 (First_Entity (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 (First_Entity (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 (First_Entity (E));
            Check_Components (First_Private_Entity (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_Unconstrained_Access_Discriminants --
   --------------------------------------------

   function Has_Unconstrained_Access_Discriminants
     (Subtyp : Entity_Id) return Boolean
   is
      Discr : Entity_Id;

   begin
      if Has_Discriminants (Subtyp)
        and then not Is_Constrained (Subtyp)
      then
         Discr := First_Discriminant (Subtyp);
         while Present (Discr) loop
            if Ekind (Etype (Discr)) = E_Anonymous_Access_Type then
               return True;
            end if;

            Next_Discriminant (Discr);
         end loop;
      end if;

      return False;
   end Has_Unconstrained_Access_Discriminants;

   -----------------------------
   -- 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_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;
         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;
         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) 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));

      --  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 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_Anonymous_Access_Actual --
   --------------------------------

   function Is_Anonymous_Access_Actual (N : Node_Id) return Boolean is
      Par : Node_Id;
   begin
      if Ekind (Etype (N)) /= E_Anonymous_Access_Type then
         return False;
      end if;

      Par := Parent (N);
      while Present (Par)
        and then Nkind (Par) in N_Case_Expression
                              | N_If_Expression
                              | N_Parameter_Association
      loop
         Par := Parent (Par);
      end loop;
      return Nkind (Par) in N_Subprogram_Call;
   end Is_Anonymous_Access_Actual;

   ------------------------
   -- 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_Actual_Tagged_Parameter --
   --------------------------------

   function Is_Actual_Tagged_Parameter (N : Node_Id) return Boolean is
      Formal : Entity_Id;
      Call   : Node_Id;
   begin
      Find_Actual (N, Formal, Call);
      return Present (Formal) and then Is_Tagged_Type (Etype (Formal));
   end Is_Actual_Tagged_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));

      elsif Nkind (Obj) = N_Explicit_Dereference then
         return Nkind (Original_Node (Obj)) /= N_Function_Call;

      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
   begin
      return Nkind (N) = N_Function_Call
        and then Is_CPP_Class (Etype (Etype (N)))
        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.

         if Is_Volatile (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_Inherited_Operation_For_Type --
   -------------------------------------

   function Is_Inherited_Operation_For_Type
     (E   : Entity_Id;
      Typ : Entity_Id) return Boolean
   is
   begin
      --  Check that the operation has been created by the type declaration

      return Is_Inherited_Operation (E)
        and then Defining_Identifier (Parent (E)) = Typ;
   end Is_Inherited_Operation_For_Type;

   --------------------------------------
   -- 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_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 not Present (Component_List (Record_Def)) then
         return True;
      end if;

      Item := First (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;
         elsif Nkind (Item) = N_Pragma then
            null;
         else
            return False;
         end if;
         Item := Next (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) = N_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.

         elsif Nkind (Par) = N_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_Special_Aliased_Formal_Access --
   --------------------------------------

   function Is_Special_Aliased_Formal_Access
     (Exp               : Node_Id;
      In_Return_Context : Boolean := False) return Boolean
   is
      Scop : constant Entity_Id := Current_Subprogram;
   begin
      --  Verify the expression is an access reference to 'Access within a
      --  return statement as this is the only time an explicitly aliased
      --  formal has different semantics.

      if Nkind (Exp) /= N_Attribute_Reference
        or else Get_Attribute_Id (Attribute_Name (Exp)) /= Attribute_Access
        or else not (In_Return_Value (Exp)
                      or else In_Return_Context)
        or else not Needs_Result_Accessibility_Level (Scop)
      then
         return False;
      end if;

      --  Check if the prefix of the reference is indeed an explicitly aliased
      --  formal parameter for the function Scop. Additionally, we must check
      --  that Scop returns an anonymous access type, otherwise the special
      --  rules dictating a need for a dynamic check are not in effect.

      return Is_Entity_Name (Prefix (Exp))
               and then Is_Explicitly_Aliased (Entity (Prefix (Exp)));
   end Is_Special_Aliased_Formal_Access;

   -----------------------------
   -- 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_Contract_Cases
        or else Nam = Name_Depends
        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_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 Present (Find_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
                      Present (Find_Aspect (Typ, Aspect_Integer_Literal)))
                   or else
                     (Ekind (Entity (N)) = E_Named_Real
                        and then
                          Present (Find_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)))
                 or else
                   (Nkind (N) = N_Expanded_Name
                     and then Scope (Entity (N)) = Entity (Prefix (N)));

            --  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;

      procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id);
      --  Clear current value for entity E and all entities chained to E

      ------------------------------------------
      -- Kill_Current_Values_For_Entity_Chain --
      ------------------------------------------

      procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id) is
         Ent : Entity_Id;
      begin
         Ent := E;
         while Present (Ent) loop
            Kill_Current_Values (Ent, Last_Assignment_Only);
            Next_Entity (Ent);
         end loop;
      end Kill_Current_Values_For_Entity_Chain;

   --  Start of processing for Kill_Current_Values

   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

         Kill_Current_Values_For_Entity_Chain (First_Entity (S));

         --  If scope is a package, also clear current values of all private
         --  entities in the scope.

         if Is_Package_Or_Generic_Package (S)
           or else Is_Concurrent_Type (S)
         then
            Kill_Current_Values_For_Entity_Chain (First_Private_Entity (S));
         end if;

         --  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_Result_Accessibility_Level --
   --------------------------------------

   function Needs_Result_Accessibility_Level
     (Func_Id : Entity_Id) return Boolean
   is
      Func_Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));

      function Has_Unconstrained_Access_Discriminant_Component
        (Comp_Typ : Entity_Id) return Boolean;
      --  Returns True if any component of the type has an unconstrained access
      --  discriminant.

      -----------------------------------------------------
      -- Has_Unconstrained_Access_Discriminant_Component --
      -----------------------------------------------------

      function Has_Unconstrained_Access_Discriminant_Component
        (Comp_Typ :  Entity_Id) return Boolean
      is
      begin
         if not Is_Limited_Type (Comp_Typ) then
            return False;

         --  Only limited types can have access discriminants with
         --  defaults.

         elsif Has_Unconstrained_Access_Discriminants (Comp_Typ) then
            return True;

         elsif Is_Array_Type (Comp_Typ) then
            return Has_Unconstrained_Access_Discriminant_Component
                     (Underlying_Type (Component_Type (Comp_Typ)));

         elsif Is_Record_Type (Comp_Typ) then
            declare
               Comp : Entity_Id;

            begin
               Comp := First_Component (Comp_Typ);
               while Present (Comp) loop
                  if Has_Unconstrained_Access_Discriminant_Component
                       (Underlying_Type (Etype (Comp)))
                  then
                     return True;
                  end if;

                  Next_Component (Comp);
               end loop;
            end;
         end if;

         return False;
      end Has_Unconstrained_Access_Discriminant_Component;

      Disable_Tagged_Cases : constant Boolean := True;
      --  Flag used to temporarily disable a "True" result for tagged types.
      --  See comments further below for details.

   --  Start of processing for Needs_Result_Accessibility_Level

   begin
      --  False if completion unavailable, which can happen when we are
      --  analyzing an abstract subprogram or if the subprogram has
      --  delayed freezing.

      if No (Func_Typ) then
         return False;

      --  False if not a function, also handle enum-lit renames case

      elsif Func_Typ = Standard_Void_Type
        or else Is_Scalar_Type (Func_Typ)
      then
         return False;

      --  Handle a corner case, a cross-dialect subp renaming. For example,
      --  an Ada 2012 renaming of an Ada 2005 subprogram. This can occur when
      --  an Ada 2005 (or earlier) unit references predefined run-time units.

      elsif Present (Alias (Func_Id)) then

         --  Unimplemented: a cross-dialect subp renaming which does not set
         --  the Alias attribute (e.g., a rename of a dereference of an access
         --  to subprogram value). ???

         return Present (Extra_Accessibility_Of_Result (Alias (Func_Id)));

      --  Remaining cases require Ada 2012 mode

      elsif Ada_Version < Ada_2012 then
         return False;

      --  Handle the situation where a result is an anonymous access type
      --  RM 3.10.2 (10.3/3).

      elsif Ekind (Func_Typ) = E_Anonymous_Access_Type then
         return True;

      --  In the case of, say, a null tagged record result type, the need for
      --  this extra parameter might not be obvious so this function returns
      --  True for all tagged types for compatibility reasons.

      --  A function with, say, a tagged null controlling result type might
      --  be overridden by a primitive of an extension having an access
      --  discriminant and the overrider and overridden must have compatible
      --  calling conventions (including implicitly declared parameters).

      --  Similarly, values of one access-to-subprogram type might designate
      --  both a primitive subprogram of a given type and a function which is,
      --  for example, not a primitive subprogram of any type. Again, this
      --  requires calling convention compatibility. It might be possible to
      --  solve these issues by introducing wrappers, but that is not the
      --  approach that was chosen.

      --  Note: Despite the reasoning noted above, the extra accessibility
      --  parameter for tagged types is disabled for performance reasons.

      elsif Is_Tagged_Type (Func_Typ) then
         return not Disable_Tagged_Cases;

      elsif Has_Unconstrained_Access_Discriminants (Func_Typ) then
         return True;

      elsif Has_Unconstrained_Access_Discriminant_Component (Func_Typ) then
         return True;

      --  False for all other cases

      else
         return False;
      end if;
   end Needs_Result_Accessibility_Level;

   ----------------------------
   --  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 not Is_Definite_Subtype (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_Separate_List --
   ----------------------------

   function New_Copy_Separate_List (List : List_Id) return List_Id is
   begin
      if List = No_List then
         return No_List;

      else
         declare
            List_Copy : constant List_Id := New_List;
            N         : Node_Id := First (List);

         begin
            while Present (N) loop
               Append (New_Copy_Separate_Tree (N), List_Copy);
               Next (N);
            end loop;

            return List_Copy;
         end;
      end if;
   end New_Copy_Separate_List;

   ----------------------------
   -- New_Copy_Separate_Tree --
   ----------------------------

   function New_Copy_Separate_Tree (Source : Node_Id) return Node_Id is
      function Search_Decl (N : Node_Id) return Traverse_Result;
      --  Subtree visitor which collects declarations

      procedure Search_Declarations is new Traverse_Proc (Search_Decl);
      --  Subtree visitor instantiation

      -----------------
      -- Search_Decl --
      -----------------

      Decls : Elist_Id;

      function Search_Decl (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) in N_Declaration then
            Append_New_Elmt (N, Decls);
         end if;

         return OK;
      end Search_Decl;

      --  Local variables

      Source_Copy : constant Node_Id := New_Copy_Tree (Source);

   --  Start of processing for New_Copy_Separate_Tree

   begin
      Decls := No_Elist;
      Search_Declarations (Source_Copy);

      --  Associate a new Entity with all the subtree declarations (keeping
      --  their original name).

      if Present (Decls) then
         declare
            Elmt  : Elmt_Id;
            Decl  : Node_Id;
            New_E : Entity_Id;

         begin
            Elmt := First_Elmt (Decls);
            while Present (Elmt) loop
               Decl  := Node (Elmt);
               New_E := Make_Temporary (Sloc (Decl), 'P');

               if Nkind (Decl) = N_Expression_Function then
                  Decl := Specification (Decl);
               end if;

               if Nkind (Decl) in 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
               then
                  Set_Chars (New_E, Chars (Defining_Unit_Name (Decl)));
                  Set_Defining_Unit_Name (Decl, New_E);
               else
                  Set_Chars (New_E, Chars (Defining_Identifier (Decl)));
                  Set_Defining_Identifier (Decl, New_E);
               end if;

               Next_Elmt (Elmt);
            end loop;
         end;
      end if;

      return Source_Copy;
   end New_Copy_Separate_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;
      Scopes_In_EWA_OK : Boolean    := False) 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_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
         function Has_More_Ids (N : Node_Id) return Boolean;
         --  Return True when N has attribute More_Ids set to True

         function Is_Syntactic_Node return Boolean;
         --  Return True when Field is a syntactic node

         ------------------
         -- Has_More_Ids --
         ------------------

         function Has_More_Ids (N : Node_Id) return Boolean is
         begin
            if Nkind (N) in N_Component_Declaration
                          | N_Discriminant_Specification
                          | N_Exception_Declaration
                          | N_Formal_Object_Declaration
                          | N_Number_Declaration
                          | N_Object_Declaration
                          | N_Parameter_Specification
                          | N_Use_Package_Clause
                          | N_Use_Type_Clause
            then
               return More_Ids (N);
            else
               return False;
            end if;
         end Has_More_Ids;

         -----------------------
         -- Is_Syntactic_Node --
         -----------------------

         function Is_Syntactic_Node return Boolean is
            Old_N : constant Node_Id := Node_Id (Field);

         begin
            if Parent (Old_N) = Old_Par then
               return True;

            elsif not Has_More_Ids (Old_Par) then
               return False;

            --  Perform the check using the last last id in the syntactic chain

            else
               declare
                  N : Node_Id := Old_Par;

               begin
                  while Present (N) and then More_Ids (N) loop
                     Next (N);
                  end loop;

                  pragma Assert (Prev_Ids (N));
                  return Parent (Old_N) = N;
               end;
            end if;
         end Is_Syntactic_Node;

      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;

               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 for a replicated
            --  call.

            if Nkind (N) in N_Entry_Call_Statement
                          | N_Function_Call
                          | N_Procedure_Call_Statement
            then
               Update_Named_Associations
                 (Old_Call => N,
                  New_Call => Result);

            --  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_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 (Present (Entity_Map)
                        and then 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, unless the caller has
         --  requested their replication.

         --  ??? should this restriction be eliminated?

         elsif EWA_Inner_Scope_Level > 0 and then not Scopes_In_EWA_OK 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.

         if Present (List) then
            Elmt := First (List);
            while Present (Elmt) loop
               Visit_Node (Elmt);

               Next (Elmt);
            end loop;
         end if;
      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 and then Present (Declarations (N))
         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 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
      pragma Assert (Ekind (Id) = E_Variable);
      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         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;

         --  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_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)) 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_Access_Level --
   -----------------------------

   function Subprogram_Access_Level (Subp : Entity_Id) return Uint is
   begin
      if Present (Alias (Subp)) then
         return Subprogram_Access_Level (Alias (Subp));
      else
         return Scope_Depth (Enclosing_Dynamic_Scope (Subp));
      end if;
   end Subprogram_Access_Level;

   ---------------------
   -- 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 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_Access_Level --
   -----------------------

   function Type_Access_Level
     (Typ             : Entity_Id;
      Allow_Alt_Model : Boolean   := True;
      Assoc_Ent       : Entity_Id := Empty) return Uint
   is
      Btyp    : Entity_Id := Base_Type (Typ);
      Def_Ent : Entity_Id;

   begin
      --  Ada 2005 (AI-230): For most cases of anonymous access types, we
      --  simply use the level where the type is declared. This is true for
      --  stand-alone object declarations, and for anonymous access types
      --  associated with components the level is the same as that of the
      --  enclosing composite type. However, special treatment is needed for
      --  the cases of access parameters, return objects of an anonymous access
      --  type, and, in Ada 95, access discriminants of limited types.

      if Is_Access_Type (Btyp) then
         if Ekind (Btyp) = E_Anonymous_Access_Type then
            --  No_Dynamic_Accessibility_Checks restriction override for
            --  alternative accessibility model.

            if Allow_Alt_Model
              and then No_Dynamic_Accessibility_Checks_Enabled (Btyp)
            then
               --  In the -gnatd_b model, the level of an anonymous access
               --  type is always that of the designated type.

               if Debug_Flag_Underscore_B then
                  return Type_Access_Level
                           (Designated_Type (Btyp), Allow_Alt_Model);
               end if;

               --  When an anonymous access type's Assoc_Ent is specified,
               --  calculate the result based on the general accessibility
               --  level routine.

               --  We would like to use Associated_Node_For_Itype here instead,
               --  but in some cases it is not fine grained enough ???

               if Present (Assoc_Ent) then
                  return Static_Accessibility_Level
                           (Assoc_Ent, Object_Decl_Level);
               end if;

               --  Otherwise take the context of the anonymous access type into
               --  account.

               --  Obtain the defining entity for the internally generated
               --  anonymous access type.

               Def_Ent := Defining_Entity_Or_Empty
                            (Associated_Node_For_Itype (Typ));

               if Present (Def_Ent) then
                  --  When the defining entity is a subprogram then we know the
                  --  anonymous access type Typ has been generated to either
                  --  describe an anonymous access type formal or an anonymous
                  --  access result type.

                  --  Since we are only interested in the formal case, avoid
                  --  the anonymous access result type.

                  if Is_Subprogram (Def_Ent)
                    and then not (Ekind (Def_Ent) = E_Function
                                   and then Etype (Def_Ent) = Typ)
                  then
                     --  When the type comes from an anonymous access
                     --  parameter, the level is that of the subprogram
                     --  declaration.

                     return Scope_Depth (Def_Ent);

                  --  When the type is an access discriminant, the level is
                  --  that of the type.

                  elsif Ekind (Def_Ent) = E_Discriminant then
                     return Scope_Depth (Scope (Def_Ent));
                  end if;
               end if;

            --  If the type is a nonlocal anonymous access type (such as for
            --  an access parameter) we treat it as being declared at the
            --  library level to ensure that names such as X.all'access don't
            --  fail static accessibility checks.

            elsif not Is_Local_Anonymous_Access (Typ) then
               return Scope_Depth (Standard_Standard);

            --  If this is a return object, the accessibility level is that of
            --  the result subtype of the enclosing function. The test here is
            --  little complicated, because we have to account for extended
            --  return statements that have been rewritten as blocks, in which
            --  case we have to find and the Is_Return_Object attribute of the
            --  itype's associated object. It would be nice to find a way to
            --  simplify this test, but it doesn't seem worthwhile to add a new
            --  flag just for purposes of this test. ???

            elsif Ekind (Scope (Btyp)) = E_Return_Statement
              or else
                (Is_Itype (Btyp)
                  and then Nkind (Associated_Node_For_Itype (Btyp)) =
                                                         N_Object_Declaration
                  and then Is_Return_Object
                             (Defining_Identifier
                                (Associated_Node_For_Itype (Btyp))))
            then
               declare
                  Scop : Entity_Id;

               begin
                  Scop := Scope (Scope (Btyp));
                  while Present (Scop) loop
                     exit when Ekind (Scop) = E_Function;
                     Scop := Scope (Scop);
                  end loop;

                  --  Treat the return object's type as having the level of the
                  --  function's result subtype (as per RM05-6.5(5.3/2)).

                  return Type_Access_Level (Etype (Scop), Allow_Alt_Model);
               end;
            end if;
         end if;

         Btyp := Root_Type (Btyp);

         --  The accessibility level of anonymous access types associated with
         --  discriminants is that of the current instance of the type, and
         --  that's deeper than the type itself (AARM 3.10.2 (12.3.21)).

         --  AI-402: access discriminants have accessibility based on the
         --  object rather than the type in Ada 2005, so the above paragraph
         --  doesn't apply.

         --  ??? Needs completion with rules from AI-416

         if Ada_Version <= Ada_95
           and then Ekind (Typ) = E_Anonymous_Access_Type
           and then Present (Associated_Node_For_Itype (Typ))
           and then Nkind (Associated_Node_For_Itype (Typ)) =
                                                 N_Discriminant_Specification
         then
            return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1;
         end if;
      end if;

      --  Return library level for a generic formal type. This is done because
      --  RM(10.3.2) says that "The statically deeper relationship does not
      --  apply to ... a descendant of a generic formal type". Rather than
      --  checking at each point where a static accessibility check is
      --  performed to see if we are dealing with a formal type, this rule is
      --  implemented by having Type_Access_Level and Deepest_Type_Access_Level
      --  return extreme values for a formal type; Deepest_Type_Access_Level
      --  returns Int'Last. By calling the appropriate function from among the
      --  two, we ensure that the static accessibility check will pass if we
      --  happen to run into a formal type. More specifically, we should call
      --  Deepest_Type_Access_Level instead of Type_Access_Level whenever the
      --  call occurs as part of a static accessibility check and the error
      --  case is the case where the type's level is too shallow (as opposed
      --  to too deep).

      if Is_Generic_Type (Root_Type (Btyp)) then
         return Scope_Depth (Standard_Standard);
      end if;

      return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
   end Type_Access_Level;

   ------------------------------------
   -- 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;

      --  In an instance, there is an ongoing problem with completion of
      --  types derived from private types. Their structure is what Gigi
      --  expects, but the Etype is the parent type rather than the derived
      --  private type itself. Do not flag error in this case. The private
      --  completion is an entity without a parent, like an Itype. Similarly,
      --  full and partial views may be incorrect in the instance.
      --  There is no simple way to insure that it is consistent ???

      --  A similar view discrepancy can happen in an inlined body, for the
      --  same reason: inserted body may be outside of the original package
      --  and only partial views are visible at the point of insertion.

      --  If In_Generic_Actual (Expr) is True then we cannot assume that
      --  the successful semantic analysis of the generic guarantees anything
      --  useful about type checking of this instance, so we ignore
      --  In_Instance in that case. There may be cases where this is not
      --  right (the symptom would probably be rejecting something
      --  that ought to be accepted) but we don't currently have any
      --  concrete examples of this.

      elsif (In_Instance and then not In_Generic_Actual (Expr))
        or else In_Inlined_Body
      then
         if Etype (Etype (Expr)) = Etype (Expected_Type)
           and then
             (Has_Private_Declaration (Expected_Type)
               or else Has_Private_Declaration (Etype (Expr)))
           and then No (Parent (Expected_Type))
         then
            return;

         elsif Nkind (Parent (Expr)) = N_Qualified_Expression
           and then Entity (Subtype_Mark (Parent (Expr))) = Expected_Type
         then
            return;

         elsif Is_Private_Type (Expected_Type)
           and then Present (Full_View (Expected_Type))
           and then Covers (Full_View (Expected_Type), Etype (Expr))
         then
            return;

         --  Conversely, type of expression may be the private one

         elsif Is_Private_Type (Base_Type (Etype (Expr)))
           and then Full_View (Base_Type (Etype (Expr))) = Expected_Type
         then
            return;
         end if;
      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 (not Present (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 (not Present (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_Post | Pragma_Postcondition
                                | Pragma_Post_Class | Pragma_Refined_Post
                                | Pragma_Check | Pragma_Contract_Cases);

                           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) = N_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 Present (Find_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 Present (Find_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;
