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

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

package body Sem_Util is

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

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

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

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

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

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

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

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

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

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

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

   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 No (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;
        Scope : Entity_Id := Current_Scope)
   is
      Loc : constant Source_Ptr := Sloc (N);
   begin
      pragma Assert (Nkind (N) = N_Block_Statement);

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

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

      --  Create a new block label and set its attributes

      else
         Id := New_Internal_Entity (E_Block, Scope, Loc, 'B');
         Set_Etype  (Id, Standard_Void_Type);
         Set_Parent (Id, N);

         Set_Identifier (N, New_Occurrence_Of (Id, Loc));
         Set_Block_Node (Id, Identifier (N));
      end if;
   end Add_Block_Identifier;

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

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

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

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

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

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

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

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

   begin
      loop
         --  For constant, get constant expression

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

         --  For unchecked conversion, get result to convert

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

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

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

         --  We finally have the real expression

         else
            exit;
         end if;
      end loop;

      return Expr;
   end Address_Value;

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

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

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

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

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

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

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

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

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

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

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

      if not Expander_Active
        and (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
              No (Etype (Constr)) -- previous error
                or else not Is_Discrete_Type (Etype (Constr))
                or else Is_OK_Static_Expression (Constr);

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

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

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

                  Next (One_Cstr);
               end loop;
            end;

            return True;

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

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

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

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

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

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

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

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

         declare
            E_Name : Bounded_String;

         begin
            Append (E_Name, Chars (E));

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

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

         Scop := Scope (E);

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

         if Scop = Standard_Standard then
            null;

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

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

         --  If in wrapper package skip past it

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

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

         else
            null;
         end if;

         --  Output the name

         declare
            E_Name : Bounded_String;

         begin
            Append_Unqualified_Decoded (E_Name, Chars (E));

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

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

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

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

   --  Start of processing for Append_Entity_Name

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

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

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

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

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

      Decl   : Node_Id;
      Next_E : Entity_Id;

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

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

               else
                  exit;
               end if;
            end if;

            Next (Decl);
         end loop;
      end if;

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

      Append_Entity (S, Current_Scope);
   end Append_Inherited_Subprogram;

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

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

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

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

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

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

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

      --  Now deal with possible local raise handling

      Possible_Local_Raise (N, Standard_Constraint_Error);

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

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

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

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

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

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

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

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

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

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

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

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

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

      --  Check for possible misspelling

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

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

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

   begin
      --  Avoid cascaded errors

      if Error_Posted (N) then
         return;
      end if;

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

         if No (Gen) then
            return;
         end if;

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

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

            --  The restriction on loop parameters is only that the type
            --  should 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 All_Extensions_Allowed then
         Actual := First_Actual (Call);
         while Present (Actual) loop
            if Nkind (Actual) = N_Aggregate then
               Error_Msg_N
                 ("\add type qualification to aggregate actual", Actual);
               exit;
            end if;
            Next_Actual (Actual);
         end loop;
      end if;
   end Check_Ambiguous_Aggregate;

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

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

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

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

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

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

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

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

            null;

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

      --  Need comments for these tests ???

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

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

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

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

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

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

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

         Next_Formal (F);
      end loop;
   end Check_Function_With_Address_Parameter;

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

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

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

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

      procedure Collect_Identifiers (N : Node_Id) is

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

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

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

         function Check_Node (N : Node_Id) return Traverse_Result is
            Is_Writable_Actual : Boolean := False;
            Id                 : Entity_Id;

         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 (No (Ifc));
         if Present (Parent_Type) then
            return Parent_Type & Ifc_Ancestors;
         else
            return Ifc_Ancestors;
         end if;
      end Ancestor_Entities;

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

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

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

      Ancestors : constant Entity_Array := Ancestor_Entities;

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

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

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

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

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

   begin
      --  Inspect all formal parameters

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

         Next_Formal (Formal);
      end loop;

      --  Inspect the return type

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

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

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

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

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

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

         return OK;
      end Check_Node;

      function Traverse is new Traverse_Func_With_Parent (Check_Node);

   --  Start of processing for Check_Parents

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

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

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

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

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

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

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

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

      begin
         --  Find the context of the object declaration

         Obj_Context := Parent (Declaration_Node (Obj_Id));

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

         --  The object appears immediately within the package body

         if Obj_Context = Body_Decl then
            return True;

         --  The object appears immediately within the corresponding spec

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

         return False;
      end Is_Enclosing_Package_Body;

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

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

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

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

         return True;
      end Is_Internal_Declaration_Or_Body;

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

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

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

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

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

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

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

      --  Local variables

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

   --  Start of processing for Check_Part_Of_Reference

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

      if No (Conc_Obj) then
         return;
      end if;

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

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

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

            if Prag_Nam in Name_Initial_Condition | Name_Initializes then
               return;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

         procedure Check_Function_Result is
           new Traverse_Proc (Is_Function_Result);

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

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

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

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

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

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

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

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

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

               return Nkind (Parent (Expr)) in N_Subexpr

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

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

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

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

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

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

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

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

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

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

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

                        Next (Assoc);
                     end loop;

                     return False;
                  end if;

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

               else
                  return False;
               end if;
            end Has_Global_Output;

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

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

            begin
               --  A function has its result as output

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

               --  An OUT or IN OUT parameter is an output

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

                  Next_Formal (Param);
               end loop;

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

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

               return True;
            end Has_No_Output;

            --  Local variables

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

         --  Start of processing for Check_Conjunct

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

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

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

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

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

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

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

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

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

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

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

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

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

            --  Continue the traversal

            else
               return OK;
            end if;
         end Is_Function_Result;

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

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

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

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

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

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

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

                  --  Treat an undecorated reference as OK

                  if No (Ent)

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

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

                    --  The reference may be modified through a dereference

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

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

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

               return OK;
            end Is_Post_State;

            procedure Find_Post_State is new Traverse_Proc (Is_Post_State);

         --  Start of processing for Mentions_Post_State

         begin
            Find_Post_State (N);

            return Post_State_Seen;
         end Mentions_Post_State;

         --  Local variables

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

      --  Start of processing for Check_Result_And_Post_State_In_Pragma

      begin
         --  Examine all consequences

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

               Next (CCase);
            end loop;

         --  Examine the expression of a postcondition

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

      --  Local variables

      Items        : constant Node_Id := Contract (Subp_Id);
      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)));
         end if;
      end if;
   end Copy_Ghost_Aspect;

   -------------------------
   -- Copy_Parameter_List --
   -------------------------

   function Copy_Parameter_List (Subp_Id : Entity_Id) return List_Id is
      Loc    : constant Source_Ptr := Sloc (Subp_Id);
      Plist  : List_Id;
      Formal : Entity_Id := First_Formal (Subp_Id);

   begin
      if Present (Formal) then
         Plist := New_List;
         while Present (Formal) loop
            Append_To (Plist,
              Make_Parameter_Specification (Loc,
                Defining_Identifier =>
                  Make_Defining_Identifier (Sloc (Formal), Chars (Formal)),
                In_Present          => In_Present (Parent (Formal)),
                Out_Present         => Out_Present (Parent (Formal)),
                Parameter_Type      =>
                  New_Occurrence_Of (Etype (Formal), Loc),
                Expression          =>
                  New_Copy_Tree (Expression (Parent (Formal)))));

            Next_Formal (Formal);
         end loop;
      else
         Plist := No_List;
      end if;

      return Plist;
   end Copy_Parameter_List;

   ----------------------------
   -- Copy_SPARK_Mode_Aspect --
   ----------------------------

   procedure Copy_SPARK_Mode_Aspect (From : Node_Id; To : Node_Id) is
      pragma Assert (not Has_Aspects (To));
      Asp : Node_Id;

   begin
      if Has_Aspects (From) then
         Asp := Find_Aspect (Defining_Entity (From), Aspect_SPARK_Mode);

         if Present (Asp) then
            Set_Aspect_Specifications (To, New_List (New_Copy_Tree (Asp)));
         end if;
      end if;
   end Copy_SPARK_Mode_Aspect;

   --------------------------
   -- Copy_Subprogram_Spec --
   --------------------------

   function Copy_Subprogram_Spec
     (Spec     : Node_Id;
      New_Sloc : Source_Ptr := No_Location) return Node_Id
   is
      Def_Id      : Node_Id;
      Formal_Spec : Node_Id;
      Result      : Node_Id;

   begin
      --  The structure of the original tree must be replicated without any
      --  alterations. Use New_Copy_Tree for this purpose.

      Result := New_Copy_Tree (Spec, New_Sloc => New_Sloc);

      --  However, the spec of a null procedure carries the corresponding null
      --  statement of the body (created by the parser), and this cannot be
      --  shared with the new subprogram spec.

      if Nkind (Result) = N_Procedure_Specification then
         Set_Null_Statement (Result, Empty);
      end if;

      --  Create a new entity for the defining unit name

      Def_Id := Defining_Unit_Name (Result);
      Set_Defining_Unit_Name (Result,
        Make_Defining_Identifier (Sloc (Def_Id), Chars (Def_Id)));

      --  Create new entities for the formal parameters

      Formal_Spec := First (Parameter_Specifications (Result));
      while Present (Formal_Spec) loop
         Def_Id := Defining_Identifier (Formal_Spec);
         Set_Defining_Identifier (Formal_Spec,
           Make_Defining_Identifier (Sloc (Def_Id), Chars (Def_Id)));

         Next (Formal_Spec);
      end loop;

      return Result;
   end Copy_Subprogram_Spec;

   --------------------------------
   -- Corresponding_Generic_Type --
   --------------------------------

   function Corresponding_Generic_Type (T : Entity_Id) return Entity_Id is
      Inst : Entity_Id;
      Gen  : Entity_Id;
      Typ  : Entity_Id;

   begin
      if not Is_Generic_Actual_Type (T) then
         return Any_Type;

      --  If the actual is the actual of an enclosing instance, resolution
      --  was correct in the generic.

      elsif Nkind (Parent (T)) = N_Subtype_Declaration
        and then Is_Entity_Name (Subtype_Indication (Parent (T)))
        and then
          Is_Generic_Actual_Type (Entity (Subtype_Indication (Parent (T))))
      then
         return Any_Type;

      else
         Inst := Scope (T);

         if Is_Wrapper_Package (Inst) then
            Inst := Related_Instance (Inst);
         end if;

         Gen  :=
           Generic_Parent
             (Specification (Unit_Declaration_Node (Inst)));

         --  Generic actual has the same name as the corresponding formal

         Typ := First_Entity (Gen);
         while Present (Typ) loop
            if Chars (Typ) = Chars (T) then
               return Typ;
            end if;

            Next_Entity (Typ);
         end loop;

         return Any_Type;
      end if;
   end Corresponding_Generic_Type;

   --------------------------------
   -- Corresponding_Primitive_Op --
   --------------------------------

   function Corresponding_Primitive_Op
     (Ancestor_Op     : Entity_Id;
      Descendant_Type : Entity_Id) return Entity_Id
   is
      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_Declaration_Or_Statement --
   ----------------------------------------

   function Enclosing_Declaration_Or_Statement
     (N : Node_Id) return Node_Id
   is
      Par : Node_Id;

   begin
      Par := N;
      while Present (Par) loop
         if Is_Declaration (Par) or else Is_Statement (Par) then
            return Par;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            exit;
         end if;

         Par := Parent (Par);
      end loop;

      return N;
   end Enclosing_Declaration_Or_Statement;

   ----------------------------
   -- Enclosing_Generic_Body --
   ----------------------------

   function Enclosing_Generic_Body (N : Node_Id) return Node_Id is
      Par     : Node_Id;
      Spec_Id : Entity_Id;

   begin
      Par := Parent (N);
      while Present (Par) loop
         if Nkind (Par) in N_Package_Body | N_Subprogram_Body then
            Spec_Id := Corresponding_Spec (Par);

            if Present (Spec_Id)
              and then Nkind (Unit_Declaration_Node (Spec_Id)) in
                         N_Generic_Declaration
            then
               return Par;
            end if;
         end if;

         Par := Parent (Par);
      end loop;

      return Empty;
   end Enclosing_Generic_Body;

   ----------------------------
   -- Enclosing_Generic_Unit --
   ----------------------------

   function Enclosing_Generic_Unit (N : Node_Id) return Node_Id is
      Par       : Node_Id;
      Spec_Decl : Node_Id;
      Spec_Id   : Entity_Id;

   begin
      Par := Parent (N);
      while Present (Par) loop
         if Nkind (Par) in N_Generic_Declaration then
            return Par;

         elsif Nkind (Par) in N_Package_Body | N_Subprogram_Body then
            Spec_Id := Corresponding_Spec (Par);

            if Present (Spec_Id) then
               Spec_Decl := Unit_Declaration_Node (Spec_Id);

               if Nkind (Spec_Decl) in N_Generic_Declaration then
                  return Spec_Decl;
               end if;
            end if;
         end if;

         Par := Parent (Par);
      end loop;

      return Empty;
   end Enclosing_Generic_Unit;

   -------------------
   -- Enclosing_HSS --
   -------------------

   function Enclosing_HSS (Stmt : Node_Id) return Node_Id is
      Par : Node_Id;
   begin
      pragma Assert (Is_Statement (Stmt));

      Par := Parent (Stmt);
      while Present (Par) loop

         if Nkind (Par) = N_Handled_Sequence_Of_Statements then
            return Par;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            return Empty;

         end if;

         Par := Parent (Par);
      end loop;

      return Par;
   end Enclosing_HSS;

   -------------------------------
   -- Enclosing_Lib_Unit_Entity --
   -------------------------------

   function Enclosing_Lib_Unit_Entity
      (E : Entity_Id := Current_Scope) return Entity_Id
   is
      Unit_Entity : Entity_Id;

   begin
      --  Look for enclosing library unit entity by following scope links.
      --  Equivalent to, but faster than indexing through the scope stack.

      Unit_Entity := E;
      while (Present (Scope (Unit_Entity))
        and then Scope (Unit_Entity) /= Standard_Standard)
        and not Is_Child_Unit (Unit_Entity)
      loop
         Unit_Entity := Scope (Unit_Entity);
      end loop;

      return Unit_Entity;
   end Enclosing_Lib_Unit_Entity;

   -----------------------------
   -- Enclosing_Lib_Unit_Node --
   -----------------------------

   function Enclosing_Lib_Unit_Node (N : Node_Id) return Node_Id is
      Encl_Unit : Node_Id;

   begin
      Encl_Unit := Enclosing_Comp_Unit_Node (N);
      while Present (Encl_Unit)
        and then Nkind (Unit (Encl_Unit)) = N_Subunit
      loop
         Encl_Unit := Library_Unit (Encl_Unit);
      end loop;

      pragma Assert (Nkind (Encl_Unit) = N_Compilation_Unit);
      return Encl_Unit;
   end Enclosing_Lib_Unit_Node;

   -----------------------
   -- Enclosing_Package --
   -----------------------

   function Enclosing_Package (N : Node_Or_Entity_Id) return Entity_Id is
      Dynamic_Scope : Entity_Id;

   begin
      --  Obtain the enclosing scope when N is a Node_Id - taking care to
      --  handle the case when the enclosing scope is already a package.

      if Nkind (N) not in N_Entity then
         declare
            Encl_Scop : constant Entity_Id := Find_Enclosing_Scope (N);
         begin
            if No (Encl_Scop) then
               return Empty;
            elsif Ekind (Encl_Scop) in
                    E_Generic_Package | E_Package | E_Package_Body
            then
               return Encl_Scop;
            end if;

            return Enclosing_Package (Encl_Scop);
         end;
      end if;

      --  When N is already an Entity_Id proceed

      Dynamic_Scope := Enclosing_Dynamic_Scope (N);
      if Dynamic_Scope = Standard_Standard then
         return Standard_Standard;

      elsif Dynamic_Scope = Empty then
         return Empty;

      elsif Ekind (Dynamic_Scope) in
              E_Generic_Package | E_Package | E_Package_Body
      then
         return Dynamic_Scope;

      else
         return Enclosing_Package (Dynamic_Scope);
      end if;
   end Enclosing_Package;

   -------------------------------------
   -- Enclosing_Package_Or_Subprogram --
   -------------------------------------

   function Enclosing_Package_Or_Subprogram (E : Entity_Id) return Entity_Id is
      S : Entity_Id;

   begin
      S := Scope (E);
      while Present (S) loop
         if Is_Package_Or_Generic_Package (S)
           or else Is_Subprogram_Or_Generic_Subprogram (S)
         then
            return S;

         else
            S := Scope (S);
         end if;
      end loop;

      return Empty;
   end Enclosing_Package_Or_Subprogram;

   --------------------------
   -- Enclosing_Subprogram --
   --------------------------

   function Enclosing_Subprogram (N : Node_Or_Entity_Id) return Entity_Id is
      Dyn_Scop  : Entity_Id;
      Encl_Scop : Entity_Id;

   begin
      --  Obtain the enclosing scope when N is a Node_Id - taking care to
      --  handle the case when the enclosing scope is already a subprogram.

      if Nkind (N) not in N_Entity then
         Encl_Scop := Find_Enclosing_Scope (N);

         if No (Encl_Scop) then
            return Empty;
         elsif Ekind (Encl_Scop) in Subprogram_Kind then
            return Encl_Scop;
         end if;

         return Enclosing_Subprogram (Encl_Scop);
      end if;

      --  When N is already an Entity_Id proceed

      Dyn_Scop := Enclosing_Dynamic_Scope (N);
      if Dyn_Scop = Standard_Standard then
         return Empty;

      elsif Dyn_Scop = Empty then
         return Empty;

      elsif Ekind (Dyn_Scop) = E_Subprogram_Body then
         return Corresponding_Spec (Parent (Parent (Dyn_Scop)));

      elsif Ekind (Dyn_Scop) in E_Block | E_Loop | E_Return_Statement then
         return Enclosing_Subprogram (Dyn_Scop);

      elsif Ekind (Dyn_Scop) in E_Entry | E_Entry_Family then

         --  For a task entry or entry family, return the enclosing subprogram
         --  of the task itself.

         if Ekind (Scope (Dyn_Scop)) = E_Task_Type then
            return Enclosing_Subprogram (Dyn_Scop);

         --  A protected entry or entry family is rewritten as a protected
         --  procedure which is the desired enclosing subprogram. This is
         --  relevant when unnesting a procedure local to an entry body.

         else
            return Protected_Body_Subprogram (Dyn_Scop);
         end if;

      elsif Ekind (Dyn_Scop) = E_Task_Type then
         return Get_Task_Body_Procedure (Dyn_Scop);

      --  The scope may appear as a private type or as a private extension
      --  whose completion is a task or protected type.

      elsif Ekind (Dyn_Scop) in
              E_Limited_Private_Type | E_Record_Type_With_Private
        and then Present (Full_View (Dyn_Scop))
        and then Ekind (Full_View (Dyn_Scop)) in E_Task_Type | E_Protected_Type
      then
         return Get_Task_Body_Procedure (Full_View (Dyn_Scop));

      --  No body is generated if the protected operation is eliminated

      elsif not Is_Eliminated (Dyn_Scop)
        and then Present (Protected_Body_Subprogram (Dyn_Scop))
      then
         return Protected_Body_Subprogram (Dyn_Scop);

      else
         return Dyn_Scop;
      end if;
   end Enclosing_Subprogram;

   --------------------------
   -- End_Keyword_Location --
   --------------------------

   function End_Keyword_Location (N : Node_Id) return Source_Ptr is
      function End_Label_Loc (Nod : Node_Id) return Source_Ptr;
      --  Return the source location of Nod's end label according to the
      --  following precedence rules:
      --
      --    1) If the end label exists, return its location
      --    2) If Nod exists, return its location
      --    3) Return the location of N

      -------------------
      -- End_Label_Loc --
      -------------------

      function End_Label_Loc (Nod : Node_Id) return Source_Ptr is
         Label : Node_Id;

      begin
         if Present (Nod) then
            Label := End_Label (Nod);

            if Present (Label) then
               return Sloc (Label);
            else
               return Sloc (Nod);
            end if;

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

      --  Local variables

      Owner : Node_Id := Empty;

   --  Start of processing for End_Keyword_Location

   begin
      if Nkind (N) in N_Block_Statement
                    | N_Entry_Body
                    | N_Package_Body
                    | N_Subprogram_Body
                    | N_Task_Body
      then
         Owner := Handled_Statement_Sequence (N);

      elsif Nkind (N) = N_Package_Declaration then
         Owner := Specification (N);

      elsif Nkind (N) = N_Protected_Body then
         Owner := N;

      elsif Nkind (N) in N_Protected_Type_Declaration
                       | N_Single_Protected_Declaration
      then
         Owner := Protected_Definition (N);

      elsif Nkind (N) in N_Single_Task_Declaration | N_Task_Type_Declaration
      then
         Owner := Task_Definition (N);

      --  This routine should not be called with other contexts

      else
         pragma Assert (False);
         null;
      end if;

      return End_Label_Loc (Owner);
   end End_Keyword_Location;

   ------------------------
   -- Ensure_Freeze_Node --
   ------------------------

   procedure Ensure_Freeze_Node (E : Entity_Id) is
      FN : Node_Id;
   begin
      if No (Freeze_Node (E)) then
         FN := Make_Freeze_Entity (Sloc (E));
         Set_Has_Delayed_Freeze (E);
         Set_Freeze_Node (E, FN);
         Set_Access_Types_To_Process (FN, No_Elist);
         Set_TSS_Elist (FN, No_Elist);
         Set_Entity (FN, E);
      end if;
   end Ensure_Freeze_Node;

   ----------------
   -- Enter_Name --
   ----------------

   procedure Enter_Name (Def_Id : Entity_Id) is
      C : constant Entity_Id := Current_Entity (Def_Id);
      E : constant Entity_Id := Current_Entity_In_Scope (Def_Id);
      S : constant Entity_Id := Current_Scope;

   begin
      Generate_Definition (Def_Id);

      --  Add new name to current scope declarations. Check for duplicate
      --  declaration, which may or may not be a genuine error.

      if Present (E) then

         --  Case of previous entity entered because of a missing declaration
         --  or else a bad subtype indication. Best is to use the new entity,
         --  and make the previous one invisible.

         if Etype (E) = Any_Type then
            Set_Is_Immediately_Visible (E, False);

         --  Case of renaming declaration constructed for package instances.
         --  if there is an explicit declaration with the same identifier,
         --  the renaming is not immediately visible any longer, but remains
         --  visible through selected component notation.

         elsif Nkind (Parent (E)) = N_Package_Renaming_Declaration
           and then not Comes_From_Source (E)
         then
            Set_Is_Immediately_Visible (E, False);

         --  The new entity may be the package renaming, which has the same
         --  same name as a generic formal which has been seen already.

         elsif Nkind (Parent (Def_Id)) = N_Package_Renaming_Declaration
           and then not Comes_From_Source (Def_Id)
         then
            Set_Is_Immediately_Visible (E, False);

         --  For a fat pointer corresponding to a remote access to subprogram,
         --  we use the same identifier as the RAS type, so that the proper
         --  name appears in the stub. This type is only retrieved through
         --  the RAS type and never by visibility, and is not added to the
         --  visibility list (see below).

         elsif Nkind (Parent (Def_Id)) = N_Full_Type_Declaration
           and then Ekind (Def_Id) = E_Record_Type
           and then Present (Corresponding_Remote_Type (Def_Id))
         then
            null;

         --  Case of an implicit operation or derived literal. The new entity
         --  hides the implicit one,  which is removed from all visibility,
         --  i.e. the entity list of its scope, and homonym chain of its name.

         elsif (Is_Overloadable (E) and then Is_Inherited_Operation (E))
           or else Is_Internal (E)
         then
            declare
               Decl     : constant Node_Id := Parent (E);
               Prev     : Entity_Id;
               Prev_Vis : Entity_Id;

            begin
               --  If E is an implicit declaration, it cannot be the first
               --  entity in the scope.

               Prev := First_Entity (Current_Scope);
               while Present (Prev) and then Next_Entity (Prev) /= E loop
                  Next_Entity (Prev);
               end loop;

               if No (Prev) then

                  --  If E is not on the entity chain of the current scope,
                  --  it is an implicit declaration in the generic formal
                  --  part of a generic subprogram. When analyzing the body,
                  --  the generic formals are visible but not on the entity
                  --  chain of the subprogram. The new entity will become
                  --  the visible one in the body.

                  pragma Assert
                    (Nkind (Parent (Decl)) = N_Generic_Subprogram_Declaration);
                  null;

               else
                  Link_Entities (Prev, Next_Entity (E));

                  if No (Next_Entity (Prev)) then
                     Set_Last_Entity (Current_Scope, Prev);
                  end if;

                  if E = Current_Entity (E) then
                     Prev_Vis := Empty;

                  else
                     Prev_Vis := Current_Entity (E);
                     while Homonym (Prev_Vis) /= E loop
                        Prev_Vis := Homonym (Prev_Vis);
                     end loop;
                  end if;

                  if Present (Prev_Vis) then

                     --  Skip E in the visibility chain

                     Set_Homonym (Prev_Vis, Homonym (E));

                  else
                     Set_Name_Entity_Id (Chars (E), Homonym (E));
                  end if;

                  --  The inherited operation cannot be retrieved
                  --  by name, even though it may remain accesssible
                  --  in some cases involving subprogram bodies without
                  --  specs appearing in with_clauses..

                  Set_Is_Immediately_Visible (E, False);
               end if;
            end;

         --  This section of code could use a comment ???

         elsif Present (Etype (E))
           and then Is_Concurrent_Type (Etype (E))
           and then E = Def_Id
         then
            return;

         --  If the homograph is a protected component renaming, it should not
         --  be hiding the current entity. Such renamings are treated as weak
         --  declarations.

         elsif Is_Prival (E) then
            Set_Is_Immediately_Visible (E, False);

         --  In this case the current entity is a protected component renaming.
         --  Perform minimal decoration by setting the scope and return since
         --  the prival should not be hiding other visible entities.

         elsif Is_Prival (Def_Id) then
            Set_Scope (Def_Id, Current_Scope);
            return;

         --  Analogous to privals, the discriminal generated for an entry index
         --  parameter acts as a weak declaration. Perform minimal decoration
         --  to avoid bogus errors.

         elsif Is_Discriminal (Def_Id)
           and then Ekind (Discriminal_Link (Def_Id)) = E_Entry_Index_Parameter
         then
            Set_Scope (Def_Id, Current_Scope);
            return;

         --  In the body or private part of an instance, a type extension may
         --  introduce a component with the same name as that of an actual. The
         --  legality rule is not enforced, but the semantics of the full type
         --  with two components of same name are not clear at this point???

         elsif In_Instance_Not_Visible then
            null;

         --  When compiling a package body, some child units may have become
         --  visible. They cannot conflict with local entities that hide them.

         elsif Is_Child_Unit (E)
           and then In_Open_Scopes (Scope (E))
           and then not Is_Immediately_Visible (E)
         then
            null;

         --  Conversely, with front-end inlining we may compile the parent body
         --  first, and a child unit subsequently. The context is now the
         --  parent spec, and body entities are not visible.

         elsif Is_Child_Unit (Def_Id)
           and then Is_Package_Body_Entity (E)
           and then not In_Package_Body (Current_Scope)
         then
            null;

         --  Case of genuine duplicate declaration

         else
            Error_Msg_Sloc := Sloc (E);

            --  If the previous declaration is an incomplete type declaration
            --  this may be an attempt to complete it with a private type. The
            --  following avoids confusing cascaded errors.

            if Nkind (Parent (E)) = N_Incomplete_Type_Declaration
              and then Nkind (Parent (Def_Id)) = N_Private_Type_Declaration
            then
               Error_Msg_N
                 ("incomplete type cannot be completed with a private " &
                  "declaration", Parent (Def_Id));
               Set_Is_Immediately_Visible (E, False);
               Set_Full_View (E, Def_Id);

            --  An inherited component of a record conflicts with a new
            --  discriminant. The discriminant is inserted first in the scope,
            --  but the error should be posted on it, not on the component.

            elsif Ekind (E) = E_Discriminant
              and then Present (Scope (Def_Id))
              and then Scope (Def_Id) /= Current_Scope
            then
               Error_Msg_Sloc := Sloc (Def_Id);
               Error_Msg_N ("& conflicts with declaration#", E);
               return;

            --  If the name of the unit appears in its own context clause, a
            --  dummy package with the name has already been created, and the
            --  error emitted. Try to continue quietly.

            elsif Error_Posted (E)
              and then Sloc (E) = No_Location
              and then Nkind (Parent (E)) = N_Package_Specification
              and then Current_Scope = Standard_Standard
            then
               Set_Scope (Def_Id, Current_Scope);
               return;

            else
               Error_Msg_N ("& conflicts with declaration#", Def_Id);

               --  Avoid cascaded messages with duplicate components in
               --  derived types.

               if Ekind (E) in E_Component | E_Discriminant then
                  return;
               end if;
            end if;

            if Nkind (Parent (Parent (Def_Id))) =
                                             N_Generic_Subprogram_Declaration
              and then Def_Id =
                Defining_Entity (Specification (Parent (Parent (Def_Id))))
            then
               Error_Msg_N ("\generic units cannot be overloaded", Def_Id);
            end if;

            --  If entity is in standard, then we are in trouble, because it
            --  means that we have a library package with a duplicated name.
            --  That's hard to recover from, so abort.

            if S = Standard_Standard then
               raise Unrecoverable_Error;

            --  Otherwise we continue with the declaration. Having two
            --  identical declarations should not cause us too much trouble.

            else
               null;
            end if;
         end if;
      end if;

      --  If we fall through, declaration is OK, at least OK enough to continue

      --  If Def_Id is a discriminant or a record component we are in the midst
      --  of inheriting components in a derived record definition. Preserve
      --  their Ekind and Etype.

      if Ekind (Def_Id) in E_Discriminant | E_Component then
         null;

      --  If a type is already set, leave it alone (happens when a type
      --  declaration is reanalyzed following a call to the optimizer).

      elsif Present (Etype (Def_Id)) then
         null;

      --  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 No (Prag) then
         return Uint_0;
      end if;

      Max := Expr_Value
        (Expression (First (Pragma_Argument_Associations (Prag))));

      --  Since -1 and 0 are equivalent, return 0 for instances of -1 for
      --  uniformity.

      if Max = -1 then
         return Uint_0;
      end if;

      return Max;
   end Get_Max_Queue_Length;

   ------------------------
   -- Get_Name_Entity_Id --
   ------------------------

   function Get_Name_Entity_Id (Id : Name_Id) return Entity_Id is
   begin
      return Entity_Id (Get_Name_Table_Int (Id));
   end Get_Name_Entity_Id;

   ------------------------------
   -- Get_Name_From_CTC_Pragma --
   ------------------------------

   function Get_Name_From_CTC_Pragma (N : Node_Id) return String_Id is
      Arg : constant Node_Id :=
              Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
   begin
      return Strval (Expr_Value_S (Arg));
   end Get_Name_From_CTC_Pragma;

   -----------------------
   -- Get_Parent_Entity --
   -----------------------

   function Get_Parent_Entity (Unit : Node_Id) return Entity_Id is
   begin
      if Nkind (Unit) = N_Package_Body
        and then Nkind (Original_Node (Unit)) = N_Package_Instantiation
      then
         return Defining_Entity
                  (Specification (Instance_Spec (Original_Node (Unit))));
      elsif Nkind (Unit) = N_Package_Instantiation then
         return Defining_Entity (Specification (Instance_Spec (Unit)));
      else
         return Defining_Entity (Unit);
      end if;
   end Get_Parent_Entity;

   -------------------
   -- Get_Pragma_Id --
   -------------------

   function Get_Pragma_Id (N : Node_Id) return Pragma_Id is
   begin
      return Get_Pragma_Id (Pragma_Name_Unmapped (N));
   end Get_Pragma_Id;

   ------------------------
   -- Get_Qualified_Name --
   ------------------------

   function Get_Qualified_Name
     (Id     : Entity_Id;
      Suffix : Entity_Id := Empty) return Name_Id
   is
      Suffix_Nam : Name_Id := No_Name;

   begin
      if Present (Suffix) then
         Suffix_Nam := Chars (Suffix);
      end if;

      return Get_Qualified_Name (Chars (Id), Suffix_Nam, Scope (Id));
   end Get_Qualified_Name;

   function Get_Qualified_Name
     (Nam    : Name_Id;
      Suffix : Name_Id   := No_Name;
      Scop   : Entity_Id := Current_Scope) return Name_Id
   is
      procedure Add_Scope (S : Entity_Id);
      --  Add the fully qualified form of scope S to the name buffer. The
      --  format is:
      --    s-1__s__

      ---------------
      -- Add_Scope --
      ---------------

      procedure Add_Scope (S : Entity_Id) is
      begin
         if S = Empty then
            null;

         elsif S = Standard_Standard then
            null;

         else
            Add_Scope (Scope (S));
            Get_Name_String_And_Append (Chars (S));
            Add_Str_To_Name_Buffer ("__");
         end if;
      end Add_Scope;

   --  Start of processing for Get_Qualified_Name

   begin
      Name_Len := 0;
      Add_Scope (Scop);

      --  Append the base name after all scopes have been chained

      Get_Name_String_And_Append (Nam);

      --  Append the suffix (if present)

      if Suffix /= No_Name then
         Add_Str_To_Name_Buffer ("__");
         Get_Name_String_And_Append (Suffix);
      end if;

      return Name_Find;
   end Get_Qualified_Name;

   -----------------------
   -- Get_Reason_String --
   -----------------------

   procedure Get_Reason_String (N : Node_Id) is
   begin
      if Nkind (N) = N_String_Literal then
         Store_String_Chars (Strval (N));

      elsif Nkind (N) = N_Op_Concat then
         Get_Reason_String (Left_Opnd (N));
         Get_Reason_String (Right_Opnd (N));

      --  If not of required form, error

      else
         Error_Msg_N
           ("Reason for pragma Warnings has wrong form", N);
         Error_Msg_N
           ("\must be string literal or concatenation of string literals", N);
         return;
      end if;
   end Get_Reason_String;

   --------------------------------
   -- Get_Reference_Discriminant --
   --------------------------------

   function Get_Reference_Discriminant (Typ : Entity_Id) return Entity_Id is
      D : Entity_Id;

   begin
      D := First_Discriminant (Typ);
      while Present (D) loop
         if Has_Implicit_Dereference (D) then
            return D;
         end if;
         Next_Discriminant (D);
      end loop;

      return Empty;
   end Get_Reference_Discriminant;

   ---------------------------
   -- Get_Referenced_Object --
   ---------------------------

   function Get_Referenced_Object (N : Node_Id) return Node_Id is
      R : Node_Id;

   begin
      R := N;
      while Is_Entity_Name (R)
        and then Is_Object (Entity (R))
        and then Present (Renamed_Object (Entity (R)))
      loop
         R := Renamed_Object (Entity (R));
      end loop;

      return R;
   end Get_Referenced_Object;

   ------------------------
   -- Get_Renamed_Entity --
   ------------------------

   function Get_Renamed_Entity (E : Entity_Id) return Entity_Id is
      R : Entity_Id := E;
   begin
      while Present (Renamed_Entity (R)) loop
         R := Renamed_Entity (R);
      end loop;

      return R;
   end Get_Renamed_Entity;

   -----------------------
   -- Get_Return_Object --
   -----------------------

   function Get_Return_Object (N : Node_Id) return Entity_Id is
      Decl : Node_Id;

   begin
      Decl := First (Return_Object_Declarations (N));
      while Present (Decl) loop
         exit when Nkind (Decl) = N_Object_Declaration
           and then Is_Return_Object (Defining_Identifier (Decl));
         Next (Decl);
      end loop;

      pragma Assert (Present (Decl));
      return Defining_Identifier (Decl);
   end Get_Return_Object;

   ---------------------------
   -- Get_Subprogram_Entity --
   ---------------------------

   function Get_Subprogram_Entity (Nod : Node_Id) return Entity_Id is
      Subp    : Node_Id;
      Subp_Id : Entity_Id;

   begin
      if Nkind (Nod) = N_Accept_Statement then
         Subp := Entry_Direct_Name (Nod);

      elsif Nkind (Nod) = N_Slice then
         Subp := Prefix (Nod);

      else
         Subp := Name (Nod);
      end if;

      --  Strip the subprogram call

      loop
         if Nkind (Subp) in N_Explicit_Dereference
                          | N_Indexed_Component
                          | N_Selected_Component
         then
            Subp := Prefix (Subp);

         elsif Nkind (Subp) in N_Type_Conversion
                             | N_Unchecked_Type_Conversion
         then
            Subp := Expression (Subp);

         else
            exit;
         end if;
      end loop;

      --  Extract the entity of the subprogram call

      if Is_Entity_Name (Subp) then
         Subp_Id := Entity (Subp);

         if Ekind (Subp_Id) = E_Access_Subprogram_Type then
            Subp_Id := Directly_Designated_Type (Subp_Id);
         end if;

         if Is_Subprogram (Subp_Id) then
            return Subp_Id;
         else
            return Empty;
         end if;

      --  The search did not find a construct that denotes a subprogram

      else
         return Empty;
      end if;
   end Get_Subprogram_Entity;

   -----------------------------
   -- Get_Task_Body_Procedure --
   -----------------------------

   function Get_Task_Body_Procedure (E : Entity_Id) return Entity_Id is
   begin
      --  Note: A task type may be the completion of a private type with
      --  discriminants. When performing elaboration checks on a task
      --  declaration, the current view of the type may be the private one,
      --  and the procedure that holds the body of the task is held in its
      --  underlying type.

      --  This is an odd function, why not have Task_Body_Procedure do
      --  the following digging???

      return Task_Body_Procedure (Underlying_Type (Root_Type (E)));
   end Get_Task_Body_Procedure;

   -------------------------------
   -- Get_User_Defined_Equality --
   -------------------------------

   function Get_User_Defined_Equality (E : Entity_Id) return Entity_Id is
      Prim : Elmt_Id;

   begin
      Prim := First_Elmt (Collect_Primitive_Operations (E));
      while Present (Prim) loop
         if Is_User_Defined_Equality (Node (Prim)) then
            return Node (Prim);
         end if;

         Next_Elmt (Prim);
      end loop;

      return Empty;
   end Get_User_Defined_Equality;

   ---------------
   -- Get_Views --
   ---------------

   procedure Get_Views
     (Typ       : Entity_Id;
      Priv_Typ  : out Entity_Id;
      Full_Typ  : out Entity_Id;
      UFull_Typ : out Entity_Id;
      CRec_Typ  : out Entity_Id)
   is
      IP_View : Entity_Id;

   begin
      --  Assume that none of the views can be recovered

      Priv_Typ  := Empty;
      Full_Typ  := Empty;
      UFull_Typ := Empty;
      CRec_Typ  := Empty;

      --  The input type is the corresponding record type of a protected or a
      --  task type.

      if Ekind (Typ) = E_Record_Type
        and then Is_Concurrent_Record_Type (Typ)
      then
         CRec_Typ := Typ;
         Full_Typ := Corresponding_Concurrent_Type (CRec_Typ);
         Priv_Typ := Incomplete_Or_Partial_View (Full_Typ);

      --  Otherwise the input type denotes an arbitrary type

      else
         IP_View := Incomplete_Or_Partial_View (Typ);

         --  The input type denotes the full view of a private type

         if Present (IP_View) then
            Priv_Typ := IP_View;
            Full_Typ := Typ;

         --  The input type is a private type

         elsif Is_Private_Type (Typ) then
            Priv_Typ := Typ;
            Full_Typ := Full_View (Priv_Typ);

         --  Otherwise the input type does not have any views

         else
            Full_Typ := Typ;
         end if;

         if Present (Full_Typ) and then Is_Private_Type (Full_Typ) then
            UFull_Typ := Underlying_Full_View (Full_Typ);

            if Present (UFull_Typ)
              and then Ekind (UFull_Typ) in E_Protected_Type | E_Task_Type
            then
               CRec_Typ := Corresponding_Record_Type (UFull_Typ);
            end if;

         else
            if Present (Full_Typ)
              and then Ekind (Full_Typ) in E_Protected_Type | E_Task_Type
            then
               CRec_Typ := Corresponding_Record_Type (Full_Typ);
            end if;
         end if;
      end if;
   end Get_Views;

   -----------------------
   -- Has_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 No (Typ)
        or else not Is_Record_Type (Typ)
        or else not Is_Tagged_Type (Typ)
      then
         return False;
      end if;

      --  Handle private types

      if Use_Full_View and then Present (Full_View (Typ)) then
         Typ := Full_View (Typ);
      end if;

      --  Handle concurrent record types

      if Is_Concurrent_Record_Type (Typ)
        and then Is_Non_Empty_List (Abstract_Interface_List (Typ))
      then
         return True;
      end if;

      loop
         if Is_Interface (Typ)
           or else
             (Is_Record_Type (Typ)
               and then Present (Interfaces (Typ))
               and then not Is_Empty_Elmt_List (Interfaces (Typ)))
         then
            return True;
         end if;

         exit when Etype (Typ) = Typ

            --  Handle private types

            or else (Present (Full_View (Etype (Typ)))
                      and then Full_View (Etype (Typ)) = Typ)

            --  Protect frontend against wrong sources with cyclic derivations

            or else Etype (Typ) = T;

         --  Climb to the ancestor type handling private types

         if Present (Full_View (Etype (Typ))) then
            Typ := Full_View (Etype (Typ));
         else
            Typ := Etype (Typ);
         end if;
      end loop;

      return False;
   end Has_Interfaces;

   --------------------------
   -- Has_Max_Queue_Length --
   --------------------------

   function Has_Max_Queue_Length (Id : Entity_Id) return Boolean is
   begin
      return
        Ekind (Id) = E_Entry
          and then Present (Get_Pragma (Id, Pragma_Max_Queue_Length));
   end Has_Max_Queue_Length;

   ---------------------------------
   -- Has_No_Obvious_Side_Effects --
   ---------------------------------

   function Has_No_Obvious_Side_Effects (N : Node_Id) return Boolean is
   begin
      --  For now handle literals, constants, and non-volatile variables and
      --  expressions combining these with operators or short circuit forms.

      if Nkind (N) in N_Numeric_Or_String_Literal then
         return True;

      elsif Nkind (N) = N_Character_Literal then
         return True;

      elsif Nkind (N) in N_Unary_Op then
         return Has_No_Obvious_Side_Effects (Right_Opnd (N));

      elsif Nkind (N) in N_Binary_Op or else Nkind (N) in N_Short_Circuit then
         return Has_No_Obvious_Side_Effects (Left_Opnd  (N))
                   and then
                Has_No_Obvious_Side_Effects (Right_Opnd (N));

      elsif Nkind (N) = N_Expression_With_Actions
        and then Is_Empty_List (Actions (N))
      then
         return Has_No_Obvious_Side_Effects (Expression (N));

      elsif Nkind (N) in N_Has_Entity then
         return Present (Entity (N))
           and then
             Ekind (Entity (N)) in
               E_Variable     | E_Constant      | E_Enumeration_Literal |
               E_In_Parameter | E_Out_Parameter | E_In_Out_Parameter
           and then not Is_Volatile (Entity (N));

      else
         return False;
      end if;
   end Has_No_Obvious_Side_Effects;

   -----------------------------
   -- Has_Non_Null_Refinement --
   -----------------------------

   function Has_Non_Null_Refinement (Id : Entity_Id) return Boolean is
      Constits : Elist_Id;

   begin
      pragma Assert (Ekind (Id) = E_Abstract_State);
      Constits := Refinement_Constituents (Id);

      --  For a refinement to be non-null, the first constituent must be
      --  anything other than null.

      return
        Present (Constits)
          and then Nkind (Node (First_Elmt (Constits))) /= N_Null;
   end Has_Non_Null_Refinement;

   -----------------------------
   -- Has_Non_Null_Statements --
   -----------------------------

   function Has_Non_Null_Statements (L : List_Id) return Boolean is
      Node : Node_Id;

   begin
      Node := First (L);

      while Present (Node) loop
         if Nkind (Node) not in N_Null_Statement | N_Call_Marker then
            return True;
         end if;

         Next (Node);
      end loop;

      return False;
   end Has_Non_Null_Statements;

   ----------------------------------
   -- Is_Access_Subprogram_Wrapper --
   ----------------------------------

   function Is_Access_Subprogram_Wrapper (E : Entity_Id) return Boolean is
      Formal : constant Entity_Id := Last_Formal (E);
   begin
      return Present (Formal)
        and then Ekind (Etype (Formal)) in Access_Subprogram_Kind
        and then Access_Subprogram_Wrapper
           (Directly_Designated_Type (Etype (Formal))) = E;
   end Is_Access_Subprogram_Wrapper;

   ---------------------------
   -- Is_Explicitly_Aliased --
   ---------------------------

   function Is_Explicitly_Aliased (N : Node_Id) return Boolean is
   begin
      return Is_Formal (N)
               and then Present (Parent (N))
               and then Nkind (Parent (N)) = N_Parameter_Specification
               and then Aliased_Present (Parent (N));
   end Is_Explicitly_Aliased;

   ----------------------------
   -- Is_Container_Aggregate --
   ----------------------------

   function Is_Container_Aggregate (Exp : Node_Id) return Boolean is

      function Is_Record_Aggregate return Boolean is (False);
      --  ??? Unimplemented. Given an aggregate whose type is a
      --  record type with specified Aggregate aspect, how do we
      --  determine whether it is a record aggregate or a container
      --  aggregate? If the code where the aggregate occurs can see only
      --  a partial view of the aggregate's type then the aggregate
      --  cannot be a record type; an aggregate of a private type has to
      --  be a container aggregate.

   begin
      return Nkind (Exp) = N_Aggregate
        and then Has_Aspect (Etype (Exp), Aspect_Aggregate)
        and then not Is_Record_Aggregate;
   end Is_Container_Aggregate;

   ---------------------------------
   -- Side_Effect_Free_Statements --
   ---------------------------------

   function Side_Effect_Free_Statements (L : List_Id) return Boolean is
      Node : Node_Id;

   begin
      Node := First (L);

      while Present (Node) loop
         case Nkind (Node) is
            when N_Null_Statement | N_Call_Marker | N_Raise_xxx_Error =>
               null;

            when N_Object_Declaration =>
               if Present (Expression (Node))
                 and then not Side_Effect_Free (Expression (Node))
               then
                  return False;
               end if;

            when others =>
               return False;
         end case;

         Next (Node);
      end loop;

      return True;
   end Side_Effect_Free_Statements;

   ---------------------------
   -- Side_Effect_Free_Loop --
   ---------------------------

   function Side_Effect_Free_Loop (N : Node_Id) return Boolean is
      Scheme : Node_Id;
      Spec   : Node_Id;
      Subt   : Node_Id;

   begin
      --  If this is not a loop (e.g. because the loop has been rewritten),
      --  then return false.

      if Nkind (N) /= N_Loop_Statement then
         return False;
      end if;

      --  First check the statements

      if Side_Effect_Free_Statements (Statements (N)) then

         --  Then check the loop condition/indexes

         if Present (Iteration_Scheme (N)) then
            Scheme := Iteration_Scheme (N);

            if Present (Condition (Scheme))
              or else Present (Iterator_Specification (Scheme))
            then
               return False;
            elsif Present (Loop_Parameter_Specification (Scheme)) then
               Spec := Loop_Parameter_Specification (Scheme);
               Subt := Discrete_Subtype_Definition (Spec);

               if Present (Subt) then
                  if Nkind (Subt) = N_Range then
                     return Side_Effect_Free (Low_Bound (Subt))
                       and then Side_Effect_Free (High_Bound (Subt));
                  else
                     --  subtype indication

                     return True;
                  end if;
               end if;
            end if;
         end if;
      end if;

      return False;
   end Side_Effect_Free_Loop;

   ----------------------------------
   -- Has_Non_Trivial_Precondition --
   ----------------------------------

   function Has_Non_Trivial_Precondition (Subp : Entity_Id) return Boolean is
      Pre : constant Node_Id := Find_Aspect (Subp, Aspect_Pre,
                                             Class_Present => True);
   begin
      return
        Present (Pre)
          and then not Is_Entity_Name (Expression (Pre));
   end Has_Non_Trivial_Precondition;

   -------------------
   -- Has_Null_Body --
   -------------------

   function Has_Null_Body (Proc_Id : Entity_Id) return Boolean is
      Body_Id : Entity_Id;
      Decl    : Node_Id;
      Spec    : Node_Id;
      Stmt1   : Node_Id;
      Stmt2   : Node_Id;

   begin
      Spec := Parent (Proc_Id);
      Decl := Parent (Spec);

      --  Retrieve the entity of the procedure body (e.g. invariant proc).

      if Nkind (Spec) = N_Procedure_Specification
        and then Nkind (Decl) = N_Subprogram_Declaration
      then
         Body_Id := Corresponding_Body (Decl);

      --  The body acts as a spec

      else
         Body_Id := Proc_Id;
      end if;

      --  The body will be generated later

      if No (Body_Id) then
         return False;
      end if;

      Spec := Parent (Body_Id);
      Decl := Parent (Spec);

      pragma Assert
        (Nkind (Spec) = N_Procedure_Specification
          and then Nkind (Decl) = N_Subprogram_Body);

      Stmt1 := First (Statements (Handled_Statement_Sequence (Decl)));

      --  Look for a null statement followed by an optional return
      --  statement.

      if Nkind (Stmt1) = N_Null_Statement then
         Stmt2 := Next (Stmt1);

         if Present (Stmt2) then
            return Nkind (Stmt2) = N_Simple_Return_Statement;
         else
            return True;
         end if;
      end if;

      return False;
   end Has_Null_Body;

   ------------------------
   -- Has_Null_Exclusion --
   ------------------------

   function Has_Null_Exclusion (N : Node_Id) return Boolean is
   begin
      case Nkind (N) is
         when N_Access_Definition
            | N_Access_Function_Definition
            | N_Access_Procedure_Definition
            | N_Access_To_Object_Definition
            | N_Allocator
            | N_Derived_Type_Definition
            | N_Function_Specification
            | N_Subtype_Declaration
         =>
            return Null_Exclusion_Present (N);

         when N_Component_Definition
            | N_Formal_Object_Declaration
         =>
            if Present (Subtype_Mark (N)) then
               return Null_Exclusion_Present (N);
            else pragma Assert (Present (Access_Definition (N)));
               return Null_Exclusion_Present (Access_Definition (N));
            end if;

         when N_Object_Renaming_Declaration =>
            if Present (Subtype_Mark (N)) then
               return Null_Exclusion_Present (N);
            elsif Present (Access_Definition (N)) then
               return Null_Exclusion_Present (Access_Definition (N));
            else
               return False;  -- Case of no subtype in renaming (AI12-0275)
            end if;

         when N_Discriminant_Specification =>
            if Nkind (Discriminant_Type (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Discriminant_Type (N));
            else
               return Null_Exclusion_Present (N);
            end if;

         when N_Object_Declaration =>
            if Nkind (Object_Definition (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Object_Definition (N));
            else
               return Null_Exclusion_Present (N);
            end if;

         when N_Parameter_Specification =>
            if Nkind (Parameter_Type (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Parameter_Type (N))
                 or else Null_Exclusion_Present (N);
            else
               return Null_Exclusion_Present (N);
            end if;

         when others =>
            return False;
      end case;
   end Has_Null_Exclusion;

   ------------------------
   -- Has_Null_Extension --
   ------------------------

   function Has_Null_Extension (T : Entity_Id) return Boolean is
      B     : constant Entity_Id := Base_Type (T);
      Comps : Node_Id;
      Ext   : Node_Id;

   begin
      if Nkind (Parent (B)) = N_Full_Type_Declaration
        and then Present (Record_Extension_Part (Type_Definition (Parent (B))))
      then
         Ext := Record_Extension_Part (Type_Definition (Parent (B)));

         if Present (Ext) then
            if Null_Present (Ext) then
               return True;
            else
               Comps := Component_List (Ext);

               --  The null component list is rewritten during analysis to
               --  include the parent component. Any other component indicates
               --  that the extension was not originally null.

               return Null_Present (Comps)
                 or else No (Next (First (Component_Items (Comps))));
            end if;
         else
            return False;
         end if;

      else
         return False;
      end if;
   end Has_Null_Extension;

   -------------------------
   -- Has_Null_Refinement --
   -------------------------

   function Has_Null_Refinement (Id : Entity_Id) return Boolean is
      Constits : Elist_Id;

   begin
      pragma Assert (Ekind (Id) = E_Abstract_State);
      Constits := Refinement_Constituents (Id);

      --  For a refinement to be null, the state's sole constituent must be a
      --  null.

      return
        Present (Constits)
          and then Nkind (Node (First_Elmt (Constits))) = N_Null;
   end Has_Null_Refinement;

   ------------------------------------------
   -- Has_Nonstatic_Class_Wide_Pre_Or_Post --
   ------------------------------------------

   function Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post
     (Subp : Entity_Id) return Boolean
   is
      Disp_Type  : constant Entity_Id := Find_Dispatching_Type (Subp);
      Prag       : Node_Id;
      Pragma_Arg : Node_Id;

   begin
      if Present (Disp_Type)
        and then Is_Abstract_Type (Disp_Type)
        and then Present (Contract (Subp))
      then
         Prag := Pre_Post_Conditions (Contract (Subp));

         while Present (Prag) loop
            if Pragma_Name (Prag) in Name_Precondition | Name_Postcondition
              and then Class_Present (Prag)
            then
               Pragma_Arg :=
                 Nlists.First
                   (Pragma_Argument_Associations (Prag));

               if not Is_Static_Expression (Expression (Pragma_Arg)) then
                  return True;
               end if;
            end if;

            Prag := Next_Pragma (Prag);
         end loop;
      end if;

      return False;
   end Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post;

   -------------------------------
   -- Has_Overriding_Initialize --
   -------------------------------

   function Has_Overriding_Initialize (T : Entity_Id) return Boolean is
      BT   : constant Entity_Id := Base_Type (T);
      P    : Elmt_Id;

   begin
      if Is_Controlled (BT) then
         if Is_RTU (Scope (BT), Ada_Finalization) then
            return False;

         elsif Present (Primitive_Operations (BT)) then
            P := First_Elmt (Primitive_Operations (BT));
            while Present (P) loop
               declare
                  Init : constant Entity_Id := Node (P);
                  Formal : constant Entity_Id := First_Formal (Init);
               begin
                  if Ekind (Init) = E_Procedure
                    and then Chars (Init) = Name_Initialize
                    and then Comes_From_Source (Init)
                    and then Present (Formal)
                    and then Etype (Formal) = BT
                    and then No (Next_Formal (Formal))
                    and then (Ada_Version < Ada_2012
                               or else not Null_Present (Parent (Init)))
                  then
                     return True;
                  end if;
               end;

               Next_Elmt (P);
            end loop;
         end if;

         --  Here if type itself does not have a non-null Initialize operation:
         --  check immediate ancestor.

         if Is_Derived_Type (BT)
           and then Has_Overriding_Initialize (Etype (BT))
         then
            return True;
         end if;
      end if;

      return False;
   end Has_Overriding_Initialize;

   --------------------------------------
   -- Has_Preelaborable_Initialization --
   --------------------------------------

   function Has_Preelaborable_Initialization
     (E                 : Entity_Id;
      Preelab_Init_Expr : Node_Id := Empty) return Boolean
   is
      Has_PE : Boolean;

      procedure Check_Components (E : Entity_Id);
      --  Check component/discriminant chain, sets Has_PE False if a component
      --  or discriminant does not meet the preelaborable initialization rules.

      function Type_Named_In_Preelab_Init_Expression
        (Typ  : Entity_Id;
         Expr : Node_Id) return Boolean;
      --  Returns True iff Typ'Preelaborable_Initialization occurs in Expr
      --  (where Expr may be a conjunction of one or more P_I attributes).

      ----------------------
      -- Check_Components --
      ----------------------

      procedure Check_Components (E : Entity_Id) is
         Ent : Entity_Id;
         Exp : Node_Id;

      begin
         --  Loop through components and discriminants of record or protected
         --  type.

         Ent := First_Component_Or_Discriminant (E);
         while Present (Ent) loop

            case Ekind (Ent) is
               when E_Component =>

                  --  Get default expression if any. If there is no declaration
                  --  node, it means we have an internal entity. The parent and
                  --  tag fields are examples of such entities. For such cases,
                  --  we just test the type of the entity.

                  if Present (Declaration_Node (Ent)) then
                     Exp := Expression (Declaration_Node (Ent));
                  else
                     Exp := Empty;
                  end if;

               when E_Discriminant =>

                  --  Note: for a renamed discriminant, the Declaration_Node
                  --  may point to the one from the ancestor, and have a
                  --  different expression, so use the proper attribute to
                  --  retrieve the expression from the derived constraint.

                  Exp := Discriminant_Default_Value (Ent);

               when others =>
                  raise Program_Error;
            end case;

            --  A component has PI if it has no default expression and the
            --  component type has PI.

            if No (Exp) then
               if not Has_Preelaborable_Initialization
                        (Etype (Ent), Preelab_Init_Expr)
               then
                  Has_PE := False;
                  exit;
               end if;

            --  Require the default expression to be preelaborable

            elsif not Is_Preelaborable_Construct (Exp) then
               Has_PE := False;
               exit;
            end if;

            Next_Component_Or_Discriminant (Ent);
         end loop;
      end Check_Components;

      --------------------------------------
      -- Type_Named_In_Preelab_Expression --
      --------------------------------------

      function Type_Named_In_Preelab_Init_Expression
        (Typ  : Entity_Id;
         Expr : Node_Id) return Boolean
      is
      begin
         --  Return True if Expr is a Preelaborable_Initialization attribute
         --  and the prefix is a subtype that has the same type as Typ.

         if Nkind (Expr) = N_Attribute_Reference
           and then Attribute_Name (Expr) = Name_Preelaborable_Initialization
           and then Is_Entity_Name (Prefix (Expr))
           and then Base_Type (Entity (Prefix (Expr))) = Base_Type (Typ)
         then
            return True;

         --  In the case where Expr is a conjunction, test whether either
         --  operand is a Preelaborable_Initialization attribute whose prefix
         --  has the same type as Typ, and return True if so.

         elsif Nkind (Expr) = N_Op_And
           and then
            (Type_Named_In_Preelab_Init_Expression (Typ, Left_Opnd (Expr))
              or else
             Type_Named_In_Preelab_Init_Expression (Typ, Right_Opnd (Expr)))
         then
            return True;

         --  Typ not named in a Preelaborable_Initialization attribute of Expr

         else
            return False;
         end if;
      end Type_Named_In_Preelab_Init_Expression;

   --  Start of processing for Has_Preelaborable_Initialization

   begin
      --  Immediate return if already marked as known preelaborable init. This
      --  covers types for which this function has already been called once
      --  and returned True (in which case the result is cached), and also
      --  types to which a pragma Preelaborable_Initialization applies.

      if Known_To_Have_Preelab_Init (E) then
         return True;
      end if;

      --  If the type is a subtype representing a generic actual type, then
      --  test whether its base type has preelaborable initialization since
      --  the subtype representing the actual does not inherit this attribute
      --  from the actual or formal. (but maybe it should???)

      if Is_Generic_Actual_Type (E) then
         return Has_Preelaborable_Initialization (Base_Type (E));
      end if;

      --  All elementary types have preelaborable initialization

      if Is_Elementary_Type (E) then
         Has_PE := True;

      --  Array types have PI if the component type has PI

      elsif Is_Array_Type (E) then
         Has_PE := Has_Preelaborable_Initialization
                     (Component_Type (E), Preelab_Init_Expr);

      --  A derived type has preelaborable initialization if its parent type
      --  has preelaborable initialization and (in the case of a derived record
      --  extension) if the non-inherited components all have preelaborable
      --  initialization. However, a user-defined controlled type with an
      --  overriding Initialize procedure does not have preelaborable
      --  initialization.

      elsif Is_Derived_Type (E) then

         --  When the rule of RM 10.2.1(11.8/5) applies, we presume a component
         --  of a generic formal derived type has preelaborable initialization.
         --  (See comment on spec of Has_Preelaborable_Initialization.)

         if Is_Generic_Type (E)
           and then Present (Preelab_Init_Expr)
           and then
             Type_Named_In_Preelab_Init_Expression (E, Preelab_Init_Expr)
         then
            return True;
         end if;

         --  If the derived type is a private extension then it doesn't have
         --  preelaborable initialization.

         if Ekind (Base_Type (E)) = E_Record_Type_With_Private then
            return False;
         end if;

         --  First check whether ancestor type has preelaborable initialization

         Has_PE := Has_Preelaborable_Initialization
                     (Etype (Base_Type (E)), Preelab_Init_Expr);

         --  If OK, check extension components (if any)

         if Has_PE and then Is_Record_Type (E) then
            Check_Components (E);
         end if;

         --  Check specifically for 10.2.1(11.4/2) exception: a controlled type
         --  with a user defined Initialize procedure does not have PI. If
         --  the type is untagged, the control primitives come from a component
         --  that has already been checked.

         if Has_PE
           and then Is_Controlled (E)
           and then Is_Tagged_Type (E)
           and then Has_Overriding_Initialize (E)
         then
            Has_PE := False;
         end if;

      --  Private types not derived from a type having preelaborable init and
      --  that are not marked with pragma Preelaborable_Initialization do not
      --  have preelaborable initialization.

      elsif Is_Private_Type (E) then

         --  When the rule of RM 10.2.1(11.8/5) applies, we presume a component
         --  of a generic formal private type has preelaborable initialization.
         --  (See comment on spec of Has_Preelaborable_Initialization.)

         if Is_Generic_Type (E)
           and then Present (Preelab_Init_Expr)
           and then
             Type_Named_In_Preelab_Init_Expression (E, Preelab_Init_Expr)
         then
            return True;
         else
            return False;
         end if;

      --  Record type has PI if it is non private and all components have PI

      elsif Is_Record_Type (E) then
         Has_PE := True;
         Check_Components (E);

      --  Protected types must not have entries, and components must meet
      --  same set of rules as for record components.

      elsif Is_Protected_Type (E) then
         if Has_Entries (E) then
            Has_PE := False;
         else
            Has_PE := True;
            Check_Components (E);
         end if;

      --  Type System.Address always has preelaborable initialization

      elsif Is_RTE (E, RE_Address) then
         Has_PE := True;

      --  In all other cases, type does not have preelaborable initialization

      else
         return False;
      end if;

      --  If type has preelaborable initialization, cache result

      if Has_PE then
         Set_Known_To_Have_Preelab_Init (E);
      end if;

      return Has_PE;
   end Has_Preelaborable_Initialization;

   ----------------
   -- Has_Prefix --
   ----------------

   function Has_Prefix (N : Node_Id) return Boolean is
   begin
      return Nkind (N) in
        N_Attribute_Reference | N_Expanded_Name | N_Explicit_Dereference |
        N_Indexed_Component   | N_Reference     | N_Selected_Component   |
        N_Slice;
   end Has_Prefix;

   ---------------------------
   -- Has_Private_Component --
   ---------------------------

   function Has_Private_Component (Type_Id : Entity_Id) return Boolean is
      Btype     : Entity_Id := Base_Type (Type_Id);
      Component : Entity_Id;

   begin
      if Error_Posted (Type_Id)
        or else Error_Posted (Btype)
      then
         return False;
      end if;

      if Is_Class_Wide_Type (Btype) then
         Btype := Root_Type (Btype);
      end if;

      if Is_Private_Type (Btype) then
         declare
            UT : constant Entity_Id := Underlying_Type (Btype);
         begin
            if No (UT) then
               if No (Full_View (Btype)) then
                  return not Is_Generic_Type (Btype)
                            and then
                         not Is_Generic_Type (Root_Type (Btype));
               else
                  return not Is_Generic_Type (Root_Type (Full_View (Btype)));
               end if;
            else
               return not Is_Frozen (UT) and then Has_Private_Component (UT);
            end if;
         end;

      elsif Is_Array_Type (Btype) then
         return Has_Private_Component (Component_Type (Btype));

      elsif Is_Record_Type (Btype) then
         Component := First_Component (Btype);
         while Present (Component) loop
            if Has_Private_Component (Etype (Component)) then
               return True;
            end if;

            Next_Component (Component);
         end loop;

         return False;

      elsif Is_Protected_Type (Btype)
        and then Present (Corresponding_Record_Type (Btype))
      then
         return Has_Private_Component (Corresponding_Record_Type (Btype));

      else
         return False;
      end if;
   end Has_Private_Component;

   --------------------------------
   -- Has_Relaxed_Initialization --
   --------------------------------

   function Has_Relaxed_Initialization (E : Entity_Id) return Boolean is

      function Denotes_Relaxed_Parameter
        (Expr  : Node_Id;
         Param : Entity_Id)
         return Boolean;
      --  Returns True iff expression Expr denotes a formal parameter or
      --  function Param (through its attribute Result).

      -------------------------------
      -- Denotes_Relaxed_Parameter --
      -------------------------------

      function Denotes_Relaxed_Parameter
        (Expr  : Node_Id;
         Param : Entity_Id) return Boolean is
      begin
         if Nkind (Expr) in N_Identifier | N_Expanded_Name then
            return Entity (Expr) = Param;
         else
            pragma Assert (Is_Attribute_Result (Expr));
            return Entity (Prefix (Expr)) = Param;
         end if;
      end Denotes_Relaxed_Parameter;

   --  Start of processing for Has_Relaxed_Initialization

   begin
      --  When analyzing, we checked all syntax legality rules for the aspect
      --  Relaxed_Initialization, but didn't store the property anywhere (e.g.
      --  as an Einfo flag). To query the property we look directly at the AST,
      --  but now without any syntactic checks.

      case Ekind (E) is
         --  Abstract states have option Relaxed_Initialization

         when E_Abstract_State =>
            return Is_Relaxed_Initialization_State (E);

         --  Constants have this aspect attached directly; for deferred
         --  constants, the aspect is attached to the partial view.

         when E_Constant =>
            return Has_Aspect (E, Aspect_Relaxed_Initialization);

         --  Variables have this aspect attached directly

         when E_Variable =>
            return Has_Aspect (E, Aspect_Relaxed_Initialization);

         --  Types have this aspect attached directly (though we only allow it
         --  to be specified for the first subtype). For private types, the
         --  aspect is attached to the partial view.

         when Type_Kind =>
            pragma Assert (Is_First_Subtype (E));
            return Has_Aspect (E, Aspect_Relaxed_Initialization);

         --  Formal parameters and functions have the Relaxed_Initialization
         --  aspect attached to the subprogram entity and must be listed in
         --  the aspect expression.

         when Formal_Kind
            | E_Function
         =>
            declare
               Subp_Id     : Entity_Id;
               Aspect_Expr : Node_Id;
               Param_Expr  : Node_Id;
               Assoc       : Node_Id;

            begin
               if Is_Formal (E) then
                  Subp_Id := Scope (E);
               else
                  Subp_Id := E;
               end if;

               if Has_Aspect (Subp_Id, Aspect_Relaxed_Initialization) then
                  Aspect_Expr :=
                    Find_Value_Of_Aspect
                      (Subp_Id, Aspect_Relaxed_Initialization);

                  --  Aspect expression is either an aggregate with an optional
                  --  Boolean expression (which defaults to True), e.g.:
                  --
                  --    function F (X : Integer) return Integer
                  --      with Relaxed_Initialization => (X => True, F'Result);

                  if Nkind (Aspect_Expr) = N_Aggregate then

                     if Present (Component_Associations (Aspect_Expr)) then
                        Assoc := First (Component_Associations (Aspect_Expr));

                        while Present (Assoc) loop
                           if Denotes_Relaxed_Parameter
                             (First (Choices (Assoc)), E)
                           then
                              return
                                Is_True
                                  (Static_Boolean (Expression (Assoc)));
                           end if;

                           Next (Assoc);
                        end loop;
                     end if;

                     Param_Expr := First (Expressions (Aspect_Expr));

                     while Present (Param_Expr) loop
                        if Denotes_Relaxed_Parameter (Param_Expr, E) then
                           return True;
                        end if;

                        Next (Param_Expr);
                     end loop;

                     return False;

                  --  or it is a single identifier, e.g.:
                  --
                  --    function F (X : Integer) return Integer
                  --      with Relaxed_Initialization => X;

                  else
                     return Denotes_Relaxed_Parameter (Aspect_Expr, E);
                  end if;
               else
                  return False;
               end if;
            end;

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

   ----------------------
   -- Has_Signed_Zeros --
   ----------------------

   function Has_Signed_Zeros (E : Entity_Id) return Boolean is
   begin
      return Is_Floating_Point_Type (E) and then Signed_Zeros_On_Target;
   end Has_Signed_Zeros;

   ------------------------------
   -- Has_Significant_Contract --
   ------------------------------

   function Has_Significant_Contract (Subp_Id : Entity_Id) return Boolean is
      Subp_Nam : constant Name_Id := Chars (Subp_Id);

   begin
      --  _Finalizer procedure

      if Subp_Nam = Name_uFinalizer then
         return False;

      --  _Wrapped_Statements procedure which gets generated as part of the
      --  expansion of postconditions.

      elsif Subp_Nam = Name_uWrapped_Statements then
         return False;

      --  Predicate function

      elsif Ekind (Subp_Id) = E_Function
        and then Is_Predicate_Function (Subp_Id)
      then
         return False;

      --  TSS subprogram

      elsif Get_TSS_Name (Subp_Id) /= TSS_Null then
         return False;

      else
         return True;
      end if;
   end Has_Significant_Contract;

   -----------------------------
   -- Has_Static_Array_Bounds --
   -----------------------------

   function Has_Static_Array_Bounds (Typ : Node_Id) return Boolean is
      All_Static : Boolean;
      Dummy      : Boolean;

   begin
      Examine_Array_Bounds (Typ, All_Static, Dummy);

      return All_Static;
   end Has_Static_Array_Bounds;

   ---------------------------------------
   -- Has_Static_Non_Empty_Array_Bounds --
   ---------------------------------------

   function Has_Static_Non_Empty_Array_Bounds (Typ : Node_Id) return Boolean is
      All_Static : Boolean;
      Has_Empty  : Boolean;

   begin
      Examine_Array_Bounds (Typ, All_Static, Has_Empty);

      return All_Static and not Has_Empty;
   end Has_Static_Non_Empty_Array_Bounds;

   ----------------
   -- Has_Stream --
   ----------------

   function Has_Stream (T : Entity_Id) return Boolean is
      E : Entity_Id;

   begin
      if No (T) then
         return False;

      elsif Is_RTE (Root_Type (T), RE_Root_Stream_Type) then
         return True;

      elsif Is_Array_Type (T) then
         return Has_Stream (Component_Type (T));

      elsif Is_Record_Type (T) then
         E := First_Component (T);
         while Present (E) loop
            if Has_Stream (Etype (E)) then
               return True;
            else
               Next_Component (E);
            end if;
         end loop;

         return False;

      elsif Is_Private_Type (T) then
         return Has_Stream (Underlying_Type (T));

      else
         return False;
      end if;
   end Has_Stream;

   ----------------
   -- Has_Suffix --
   ----------------

   function Has_Suffix (E : Entity_Id; Suffix : Character) return Boolean is
   begin
      Get_Name_String (Chars (E));
      return Name_Buffer (Name_Len) = Suffix;
   end Has_Suffix;

   ----------------
   -- Add_Suffix --
   ----------------

   function Add_Suffix (E : Entity_Id; Suffix : Character) return Name_Id is
   begin
      Get_Name_String (Chars (E));
      Add_Char_To_Name_Buffer (Suffix);
      return Name_Find;
   end Add_Suffix;

   -------------------
   -- Remove_Suffix --
   -------------------

   function Remove_Suffix (E : Entity_Id; Suffix : Character) return Name_Id is
   begin
      pragma Assert (Has_Suffix (E, Suffix));
      Get_Name_String (Chars (E));
      Name_Len := Name_Len - 1;
      return Name_Find;
   end Remove_Suffix;

   ----------------------------------
   -- Replace_Null_By_Null_Address --
   ----------------------------------

   procedure Replace_Null_By_Null_Address (N : Node_Id) is
      procedure Replace_Null_Operand (Op : Node_Id; Other_Op : Node_Id);
      --  Replace operand Op with a reference to Null_Address when the operand
      --  denotes a null Address. Other_Op denotes the other operand.

      --------------------------
      -- Replace_Null_Operand --
      --------------------------

      procedure Replace_Null_Operand (Op : Node_Id; Other_Op : Node_Id) is
      begin
         --  Check the type of the complementary operand since the N_Null node
         --  has not been decorated yet.

         if Nkind (Op) = N_Null
           and then Is_Descendant_Of_Address (Etype (Other_Op))
         then
            Rewrite (Op, New_Occurrence_Of (RTE (RE_Null_Address), Sloc (Op)));
         end if;
      end Replace_Null_Operand;

   --  Start of processing for Replace_Null_By_Null_Address

   begin
      pragma Assert (Relaxed_RM_Semantics);
      pragma Assert (Nkind (N) in N_Null | N_Op_Compare);

      if Nkind (N) = N_Null then
         Rewrite (N, New_Occurrence_Of (RTE (RE_Null_Address), Sloc (N)));

      else
         declare
            L : constant Node_Id := Left_Opnd  (N);
            R : constant Node_Id := Right_Opnd (N);

         begin
            Replace_Null_Operand (L, Other_Op => R);
            Replace_Null_Operand (R, Other_Op => L);
         end;
      end if;
   end Replace_Null_By_Null_Address;

   --------------------------
   -- Has_Tagged_Component --
   --------------------------

   function Has_Tagged_Component (Typ : Entity_Id) return Boolean is
      Comp : Entity_Id;

   begin
      if Is_Private_Type (Typ) and then Present (Underlying_Type (Typ)) then
         return Has_Tagged_Component (Underlying_Type (Typ));

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

      elsif Is_Tagged_Type (Typ) then
         return True;

      elsif Is_Record_Type (Typ) then
         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Has_Tagged_Component (Etype (Comp)) then
               return True;
            end if;

            Next_Component (Comp);
         end loop;

         return False;

      else
         return False;
      end if;
   end Has_Tagged_Component;

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

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (P) then
            return False;

         elsif Nkind (P) = N_Pragma and then Pragma_Name (P) = Nam then
            return True;

         else
            P := Parent (P);
         end if;
      end loop;
   end In_Pragma_Expression;

   ---------------------------
   -- In_Pre_Post_Condition --
   ---------------------------

   function In_Pre_Post_Condition
     (N : Node_Id; Class_Wide_Only : Boolean := False) return Boolean
   is
      Par     : Node_Id;
      Prag    : Node_Id := Empty;
      Prag_Id : Pragma_Id;

   begin
      --  Climb the parent chain looking for an enclosing pragma

      Par := N;
      while Present (Par) loop
         if Nkind (Par) = N_Pragma then
            Prag := Par;
            exit;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (Par) then
            exit;
         end if;

         Par := Parent (Par);
      end loop;

      if Present (Prag) then
         Prag_Id := Get_Pragma_Id (Prag);

         if Class_Wide_Only then
            return
              Prag_Id = Pragma_Post_Class
                or else Prag_Id = Pragma_Pre_Class
                or else (Class_Present (Prag)
                          and then (Prag_Id = Pragma_Post
                                     or else Prag_Id = Pragma_Postcondition
                                     or else Prag_Id = Pragma_Pre
                                     or else Prag_Id = Pragma_Precondition));
         else
            return
              Prag_Id = Pragma_Post
                or else Prag_Id = Pragma_Post_Class
                or else Prag_Id = Pragma_Postcondition
                or else Prag_Id = Pragma_Pre
                or else Prag_Id = Pragma_Pre_Class
                or else Prag_Id = Pragma_Precondition;
         end if;

      --  Otherwise the node is not enclosed by a pre/postcondition pragma

      else
         return False;
      end if;
   end In_Pre_Post_Condition;

   ------------------------------
   -- In_Quantified_Expression --
   ------------------------------

   function In_Quantified_Expression (N : Node_Id) return Boolean is
      P : Node_Id;
   begin
      P := Parent (N);
      loop
         if No (P) then
            return False;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (P) then
            return False;

         elsif Nkind (P) = N_Quantified_Expression then
            return True;
         else
            P := Parent (P);
         end if;
      end loop;
   end In_Quantified_Expression;

   -------------------------------------
   -- In_Reverse_Storage_Order_Object --
   -------------------------------------

   function In_Reverse_Storage_Order_Object (N : Node_Id) return Boolean is
      Pref : Node_Id;
      Btyp : Entity_Id := Empty;

   begin
      --  Climb up indexed components

      Pref := N;
      loop
         case Nkind (Pref) is
            when N_Selected_Component =>
               Pref := Prefix (Pref);
               exit;

            when N_Indexed_Component =>
               Pref := Prefix (Pref);

            when others =>
               Pref := Empty;
               exit;
         end case;
      end loop;

      if Present (Pref) then
         Btyp := Base_Type (Etype (Pref));
      end if;

      return Present (Btyp)
        and then (Is_Record_Type (Btyp) or else Is_Array_Type (Btyp))
        and then Reverse_Storage_Order (Btyp);
   end In_Reverse_Storage_Order_Object;

   ------------------------------
   -- In_Same_Declarative_Part --
   ------------------------------

   function In_Same_Declarative_Part
     (Context : Node_Id;
      N       : Node_Id) return Boolean
   is
      Cont : Node_Id := Context;
      Nod  : Node_Id;

   begin
      if Nkind (Cont) = N_Compilation_Unit_Aux then
         Cont := Parent (Cont);
      end if;

      Nod := Parent (N);
      while Present (Nod) loop
         if Nod = Cont then
            return True;

         elsif Nkind (Nod) in N_Accept_Statement
                            | N_Block_Statement
                            | N_Compilation_Unit
                            | N_Entry_Body
                            | N_Package_Body
                            | N_Package_Declaration
                            | N_Protected_Body
                            | N_Subprogram_Body
                            | N_Task_Body
         then
            return False;

         elsif Nkind (Nod) = N_Subunit then
            Nod := Corresponding_Stub (Nod);

         else
            Nod := Parent (Nod);
         end if;
      end loop;

      return False;
   end In_Same_Declarative_Part;

   --------------------------------------
   -- In_Subprogram_Or_Concurrent_Unit --
   --------------------------------------

   function In_Subprogram_Or_Concurrent_Unit return Boolean is
      E : Entity_Id;
      K : Entity_Kind;

   begin
      --  Use scope chain to check successively outer scopes

      E := Current_Scope;
      loop
         K := Ekind (E);

         if K in Subprogram_Kind
           or else K in Concurrent_Kind
           or else K in Generic_Subprogram_Kind
         then
            return True;

         elsif E = Standard_Standard then
            return False;
         end if;

         E := Scope (E);
      end loop;
   end In_Subprogram_Or_Concurrent_Unit;

   ----------------
   -- In_Subtree --
   ----------------

   function In_Subtree (N : Node_Id; Root : Node_Id) return Boolean is
      Curr : Node_Id;

   begin
      Curr := N;
      while Present (Curr) loop
         if Curr = Root then
            return True;
         end if;

         Curr := Parent (Curr);
      end loop;

      return False;
   end In_Subtree;

   ----------------
   -- In_Subtree --
   ----------------

   function In_Subtree
     (N     : Node_Id;
      Root1 : Node_Id;
      Root2 : Node_Id) return Boolean
   is
      Curr : Node_Id;

   begin
      Curr := N;
      while Present (Curr) loop
         if Curr = Root1 or else Curr = Root2 then
            return True;
         end if;

         Curr := Parent (Curr);
      end loop;

      return False;
   end In_Subtree;

   ---------------------
   -- In_Return_Value --
   ---------------------

   function In_Return_Value (Expr : Node_Id) return Boolean is
      Par              : Node_Id;
      Prev_Par         : Node_Id;
      Pre              : Node_Id;
      In_Function_Call : Boolean := False;

   begin
      --  Move through parent nodes to determine if Expr contributes to the
      --  return value of the current subprogram.

      Par      := Expr;
      Prev_Par := Empty;
      while Present (Par) loop

         case Nkind (Par) is
            --  Ignore ranges and they don't contribute to the result

            when N_Range =>
               return False;

            --  An object declaration whose parent is an extended return
            --  statement is a return object.

            when N_Object_Declaration =>
               if Present (Parent (Par))
                 and then Nkind (Parent (Par)) = N_Extended_Return_Statement
               then
                  return True;
               end if;

            --  We hit a simple return statement, so we know we are in one

            when N_Simple_Return_Statement =>
               return True;

            --  Only include one nexting level of function calls

            when N_Function_Call =>
               if not In_Function_Call then
                  In_Function_Call := True;

                  --  When the function return type has implicit dereference
                  --  specified we know it cannot directly contribute to the
                  --  return value.

                  if Present (Etype (Par))
                    and then Has_Implicit_Dereference
                               (Get_Full_View (Etype (Par)))
                  then
                     return False;
                  end if;
               else
                  return False;
               end if;

            --  Check if we are on the right-hand side of an assignment
            --  statement to a return object.

            --  This is not specified in the RM ???

            when N_Assignment_Statement =>
               if Prev_Par = Name (Par) then
                  return False;
               end if;

               Pre := Name (Par);
               while Present (Pre) loop
                  if Is_Entity_Name (Pre)
                    and then Is_Return_Object (Entity (Pre))
                  then
                     return True;
                  end if;

                  exit when Nkind (Pre) not in N_Selected_Component
                                             | N_Indexed_Component
                                             | N_Slice;

                  Pre := Prefix (Pre);
               end loop;

            --  Otherwise, we hit a master which was not relevant

            when others =>
               if Is_Master (Par) then
                  return False;
               end if;
         end case;

         --  Iterate up to the next parent, keeping track of the previous one

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

      return False;
   end In_Return_Value;

   -----------------------------------------
   -- In_Statement_Condition_With_Actions --
   -----------------------------------------

   function In_Statement_Condition_With_Actions (N : Node_Id) return Boolean is
      Prev : Node_Id := N;
      P    : Node_Id := Parent (N);
      --  P and Prev will be used for traversing the AST, while maintaining an
      --  invariant that P = Parent (Prev).
   begin
      while Present (P) loop
         if Nkind (P) = N_Iteration_Scheme
           and then Prev = Condition (P)
         then
            return True;

         elsif Nkind (P) = N_Elsif_Part
           and then Prev = Condition (P)
         then
            return True;

         --  No point in going beyond statements

         elsif Nkind (N) in N_Statement_Other_Than_Procedure_Call
                          | N_Procedure_Call_Statement
         then
            exit;

         --  Prevent the search from going too far

         elsif Is_Body_Or_Package_Declaration (P) then
            exit;
         end if;

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

      return False;
   end In_Statement_Condition_With_Actions;

   ---------------------
   -- In_Visible_Part --
   ---------------------

   function In_Visible_Part (Scope_Id : Entity_Id) return Boolean is
   begin
      return Is_Package_Or_Generic_Package (Scope_Id)
        and then In_Open_Scopes (Scope_Id)
        and then not In_Package_Body (Scope_Id)
        and then not In_Private_Part (Scope_Id);
   end In_Visible_Part;

   --------------------------------
   -- Incomplete_Or_Partial_View --
   --------------------------------

   function Incomplete_Or_Partial_View (Id : Entity_Id) return Entity_Id is
      S : constant Entity_Id := Scope (Id);

      function Inspect_Decls
        (Decls : List_Id;
         Taft  : Boolean := False) return Entity_Id;
      --  Check whether a declarative region contains the incomplete or partial
      --  view of Id.

      -------------------
      -- Inspect_Decls --
      -------------------

      function Inspect_Decls
        (Decls : List_Id;
         Taft  : Boolean := False) return Entity_Id
      is
         Decl  : Node_Id;
         Match : Node_Id;

      begin
         Decl := First (Decls);
         while Present (Decl) loop
            Match := Empty;

            --  The partial view of a Taft-amendment type is an incomplete
            --  type.

            if Taft then
               if Nkind (Decl) = N_Incomplete_Type_Declaration then
                  Match := Defining_Identifier (Decl);
               end if;

            --  Otherwise look for a private type whose full view matches the
            --  input type. Note that this checks full_type_declaration nodes
            --  to account for derivations from a private type where the type
            --  declaration hold the partial view and the full view is an
            --  itype.

            elsif Nkind (Decl) in N_Full_Type_Declaration
                                | N_Private_Extension_Declaration
                                | N_Private_Type_Declaration
            then
               Match := Defining_Identifier (Decl);
            end if;

            --  Guard against unanalyzed entities

            if Present (Match)
              and then Is_Type (Match)
              and then Present (Full_View (Match))
              and then Full_View (Match) = Id
            then
               return Match;
            end if;

            Next (Decl);
         end loop;

         return Empty;
      end Inspect_Decls;

      --  Local variables

      Prev : Entity_Id;

   --  Start of processing for Incomplete_Or_Partial_View

   begin
      --  Deferred constant or incomplete type case

      Prev := Current_Entity (Id);

      while Present (Prev) loop
         exit when Scope (Prev) = S;

         Prev := Homonym (Prev);
      end loop;

      if Present (Prev)
        and then (Is_Incomplete_Type (Prev) or else Ekind (Prev) = E_Constant)
        and then Present (Full_View (Prev))
        and then Full_View (Prev) = Id
      then
         return Prev;
      end if;

      --  Private or Taft amendment type case

      if Present (S) and then Is_Package_Or_Generic_Package (S) then
         declare
            Pkg_Decl : constant Node_Id := Package_Specification (S);

         begin
            --  It is knows that Typ has a private view, look for it in the
            --  visible declarations of the enclosing scope. A special case
            --  of this is when the two views have been exchanged - the full
            --  appears earlier than the private.

            if Has_Private_Declaration (Id) then
               Prev := Inspect_Decls (Visible_Declarations (Pkg_Decl));

               --  Exchanged view case, look in the private declarations

               if No (Prev) then
                  Prev := Inspect_Decls (Private_Declarations (Pkg_Decl));
               end if;

               return Prev;

            --  Otherwise if this is the package body, then Typ is a potential
            --  Taft amendment type. The incomplete view should be located in
            --  the private declarations of the enclosing scope.

            elsif In_Package_Body (S) then
               return Inspect_Decls (Private_Declarations (Pkg_Decl), True);
            end if;
         end;
      end if;

      --  The type has no incomplete or private view

      return Empty;
   end Incomplete_Or_Partial_View;

   ---------------------------------------
   -- Incomplete_View_From_Limited_With --
   ---------------------------------------

   function Incomplete_View_From_Limited_With
     (Typ : Entity_Id) return Entity_Id
   is
   begin
      --  It might make sense to make this an attribute in Einfo, and set it
      --  in Sem_Ch10 in Build_Shadow_Entity. However, we're running short on
      --  slots for new attributes, and it seems a bit simpler to just search
      --  the Limited_View (if it exists) for an incomplete type whose
      --  Non_Limited_View is Typ.

      if Ekind (Scope (Typ)) = E_Package
        and then Present (Limited_View (Scope (Typ)))
      then
         declare
            Ent : Entity_Id := First_Entity (Limited_View (Scope (Typ)));
         begin
            while Present (Ent) loop
               if Is_Incomplete_Type (Ent)
                 and then Non_Limited_View (Ent) = Typ
               then
                  return Ent;
               end if;

               Next_Entity (Ent);
            end loop;
         end;
      end if;

      return Typ;
   end Incomplete_View_From_Limited_With;

   ----------------------------------
   -- Indexed_Component_Bit_Offset --
   ----------------------------------

   function Indexed_Component_Bit_Offset (N : Node_Id) return Uint is
      Exp : constant Node_Id   := First (Expressions (N));
      Typ : constant Entity_Id := Etype (Prefix (N));
      Off : constant Uint      := Component_Size (Typ);
      Ind : Node_Id;

   begin
      --  Return early if the component size is not known or variable

      if No (Off) or else Off < Uint_0 then
         return No_Uint;
      end if;

      --  Deal with the degenerate case of an empty component

      if Off = Uint_0 then
         return Off;
      end if;

      --  Check that both the index value and the low bound are known

      if not Compile_Time_Known_Value (Exp) then
         return No_Uint;
      end if;

      Ind := First_Index (Typ);
      if No (Ind) then
         return No_Uint;
      end if;

      --  Do not attempt to compute offsets within multi-dimensional arrays

      if Present (Next_Index (Ind)) then
         return No_Uint;
      end if;

      if Nkind (Ind) = N_Subtype_Indication then
         Ind := Constraint (Ind);

         if Nkind (Ind) = N_Range_Constraint then
            Ind := Range_Expression (Ind);
         end if;
      end if;

      if Nkind (Ind) /= N_Range
        or else not Compile_Time_Known_Value (Low_Bound (Ind))
      then
         return No_Uint;
      end if;

      --  Return the scaled offset

      return Off * (Expr_Value (Exp) - Expr_Value (Low_Bound (Ind)));
   end Indexed_Component_Bit_Offset;

   -----------------------------
   -- Inherit_Predicate_Flags --
   -----------------------------

   procedure Inherit_Predicate_Flags (Subt, Par : Entity_Id) 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 No (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 Has_Aspect (Typ, Literal_Aspect_Map (Nkind (N))))
          or else
            (Is_Entity_Name (N)
              and then Present (Entity (N))
              and then
                ((Ekind (Entity (N)) = E_Named_Integer
                    and then Has_Aspect (Typ, Aspect_Integer_Literal))
                   or else
                     (Ekind (Entity (N)) = E_Named_Real
                        and then Has_Aspect (Typ, Aspect_Real_Literal))));
   end Is_User_Defined_Literal;

   --------------------------------------
   -- Is_Validation_Variable_Reference --
   --------------------------------------

   function Is_Validation_Variable_Reference (N : Node_Id) return Boolean is
      Var    : constant Node_Id := Unqual_Conv (N);
      Var_Id : Entity_Id;

   begin
      Var_Id := Empty;

      if Is_Entity_Name (Var) then
         Var_Id := Entity (Var);
      end if;

      return
        Present (Var_Id)
          and then Ekind (Var_Id) = E_Variable
          and then Present (Validated_Object (Var_Id));
   end Is_Validation_Variable_Reference;

   ----------------------------
   -- Is_Variable_Size_Array --
   ----------------------------

   function Is_Variable_Size_Array (E : Entity_Id) return Boolean is
      Idx : Node_Id;

   begin
      pragma Assert (Is_Array_Type (E));

      --  Check if some index is initialized with a non-constant value

      Idx := First_Index (E);
      while Present (Idx) loop
         if Nkind (Idx) = N_Range then
            if not Is_Constant_Bound (Low_Bound (Idx))
              or else not Is_Constant_Bound (High_Bound (Idx))
            then
               return True;
            end if;
         end if;

         Next_Index (Idx);
      end loop;

      return False;
   end Is_Variable_Size_Array;

   -----------------------------
   -- Is_Variable_Size_Record --
   -----------------------------

   function Is_Variable_Size_Record (E : Entity_Id) return Boolean is
      Comp     : Entity_Id;
      Comp_Typ : Entity_Id;

   begin
      pragma Assert (Is_Record_Type (E));

      Comp := First_Component (E);
      while Present (Comp) loop
         Comp_Typ := Underlying_Type (Etype (Comp));

         --  Recursive call if the record type has discriminants

         if Is_Record_Type (Comp_Typ)
           and then Has_Discriminants (Comp_Typ)
           and then Is_Variable_Size_Record (Comp_Typ)
         then
            return True;

         elsif Is_Array_Type (Comp_Typ)
           and then Is_Variable_Size_Array (Comp_Typ)
         then
            return True;
         end if;

         Next_Component (Comp);
      end loop;

      return False;
   end Is_Variable_Size_Record;

   -----------------
   -- Is_Variable --
   -----------------

   --  Should Is_Variable be refactored to better handle dereferences and
   --  technical debt ???

   function Is_Variable
     (N                 : Node_Id;
      Use_Original_Node : Boolean := True) return Boolean
   is
      Orig_Node : Node_Id;

      function In_Protected_Function (E : Entity_Id) return Boolean;
      --  Within a protected function, the private components of the enclosing
      --  protected type are constants. A function nested within a (protected)
      --  procedure is not itself protected. Within the body of a protected
      --  function the current instance of the protected type is a constant.

      function Is_Variable_Prefix (P : Node_Id) return Boolean;
      --  Prefixes can involve implicit dereferences, in which case we must
      --  test for the case of a reference of a constant access type, which can
      --  can never be a variable.

      ---------------------------
      -- In_Protected_Function --
      ---------------------------

      function In_Protected_Function (E : Entity_Id) return Boolean is
         Prot : Entity_Id;
         S    : Entity_Id;

      begin
         --  E is the current instance of a type

         if Is_Type (E) then
            Prot := E;

         --  E is an object

         else
            Prot := Scope (E);
         end if;

         if not Is_Protected_Type (Prot) then
            return False;

         else
            S := Current_Scope;
            while Present (S) and then S /= Prot loop
               if Ekind (S) = E_Function and then Scope (S) = Prot then
                  return True;
               end if;

               S := Scope (S);
            end loop;

            return False;
         end if;
      end In_Protected_Function;

      ------------------------
      -- Is_Variable_Prefix --
      ------------------------

      function Is_Variable_Prefix (P : Node_Id) return Boolean is
      begin
         if Is_Access_Type (Etype (P)) then
            return not Is_Access_Constant (Root_Type (Etype (P)));

         --  For the case of an indexed component whose prefix has a packed
         --  array type, the prefix has been rewritten into a type conversion.
         --  Determine variable-ness from the converted expression.

         elsif Nkind (P) = N_Type_Conversion
           and then not Comes_From_Source (P)
           and then Is_Packed_Array (Etype (P))
         then
            return Is_Variable (Expression (P));

         else
            return Is_Variable (P);
         end if;
      end Is_Variable_Prefix;

   --  Start of processing for Is_Variable

   begin
      --  Special check, allow x'Deref(expr) as a variable

      if Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Deref
      then
         return True;
      end if;

      --  Check if we perform the test on the original node since this may be a
      --  test of syntactic categories which must not be disturbed by whatever
      --  rewriting might have occurred. For example, an aggregate, which is
      --  certainly NOT a variable, could be turned into a variable by
      --  expansion.

      if Use_Original_Node then
         Orig_Node := Original_Node (N);
      else
         Orig_Node := N;
      end if;

      --  Definitely OK if Assignment_OK is set. Since this is something that
      --  only gets set for expanded nodes, the test is on N, not Orig_Node.

      if Nkind (N) in N_Subexpr and then Assignment_OK (N) then
         return True;

      --  Normally we go to the original node, but there is one exception where
      --  we use the rewritten node, namely when it is an explicit dereference.
      --  The generated code may rewrite a prefix which is an access type with
      --  an explicit dereference. The dereference is a variable, even though
      --  the original node may not be (since it could be a constant of the
      --  access type).

      --  In Ada 2005 we have a further case to consider: the prefix may be a
      --  function call given in prefix notation. The original node appears to
      --  be a selected component, but we need to examine the call.

      elsif Nkind (N) = N_Explicit_Dereference
        and then Nkind (Orig_Node) /= N_Explicit_Dereference
        and then Present (Etype (Orig_Node))
        and then Is_Access_Type (Etype (Orig_Node))
      then
         --  Note that if the prefix is an explicit dereference that does not
         --  come from source, we must check for a rewritten function call in
         --  prefixed notation before other forms of rewriting, to prevent a
         --  compiler crash.

         return
           (Nkind (Orig_Node) = N_Function_Call
             and then not Is_Access_Constant (Etype (Prefix (N))))
           or else
             Is_Variable_Prefix (Original_Node (Prefix (N)));

      --  Generalized indexing operations are rewritten as explicit
      --  dereferences, and it is only during resolution that we can
      --  check whether the context requires an access_to_variable type.

      elsif Nkind (N) = N_Explicit_Dereference
        and then Present (Etype (Orig_Node))
        and then Has_Implicit_Dereference (Etype (Orig_Node))
        and then Ada_Version >= Ada_2012
      then
         return not Is_Access_Constant (Etype (Prefix (N)));

      --  A function call is never a variable

      elsif Nkind (N) = N_Function_Call then
         return False;

      --  All remaining checks use the original node

      elsif Is_Entity_Name (Orig_Node)
        and then Present (Entity (Orig_Node))
      then
         declare
            E : constant Entity_Id := Entity (Orig_Node);
            K : constant Entity_Kind := Ekind (E);

         begin
            if Is_Loop_Parameter (E) then
               return False;
            end if;

            return    (K = E_Variable
                        and then Nkind (Parent (E)) /= N_Exception_Handler)
              or else (K = E_Component
                        and then not In_Protected_Function (E))
              or else (Present (Etype (E))
                        and then Is_Access_Variable (Etype (E))
                        and then Is_Dereferenced (N))
              or else K = E_Out_Parameter
              or else K = E_In_Out_Parameter
              or else K = E_Generic_In_Out_Parameter

              --  Current instance of type. If this is a protected type, check
              --  we are not within the body of one of its protected functions.

              or else (Is_Type (E)
                        and then In_Open_Scopes (E)
                        and then not In_Protected_Function (E))

              or else (Is_Incomplete_Or_Private_Type (E)
                        and then In_Open_Scopes (Full_View (E)));
         end;

      else
         case Nkind (Orig_Node) is
            when N_Indexed_Component
               | N_Slice
            =>
               return Is_Variable_Prefix (Prefix (Orig_Node));

            when N_Selected_Component =>
               return (Is_Variable (Selector_Name (Orig_Node))
                        and then Is_Variable_Prefix (Prefix (Orig_Node)))
                 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;

   begin
      --  Kill all saved checks, a special case of killing saved values

      if not Last_Assignment_Only then
         Kill_All_Checks;
      end if;

      --  Loop through relevant scopes, which includes the current scope and
      --  any parent scopes if the current scope is a block or a package.

      S := Current_Scope;
      Scope_Loop : loop

         --  Clear current values of all entities in current scope

         declare
            Ent : Entity_Id;
         begin
            Ent := First_Entity (S);
            while Present (Ent) loop
               Kill_Current_Values (Ent, Last_Assignment_Only);
               Next_Entity (Ent);
            end loop;
         end;

         --  If this is a not a subprogram, deal with parents

         if not Is_Subprogram (S) then
            S := Scope (S);
            exit Scope_Loop when S = Standard_Standard;
         else
            exit Scope_Loop;
         end if;
      end loop Scope_Loop;
   end Kill_Current_Values;

   --------------------------
   -- Kill_Size_Check_Code --
   --------------------------

   procedure Kill_Size_Check_Code (E : Entity_Id) is
   begin
      if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable)
        and then Present (Size_Check_Code (E))
      then
         Remove (Size_Check_Code (E));
         Set_Size_Check_Code (E, Empty);
      end if;
   end Kill_Size_Check_Code;

   --------------------
   -- Known_Non_Null --
   --------------------

   function Known_Non_Null (N : Node_Id) return Boolean is
      Status : constant Null_Status_Kind := Null_Status (N);

      Id  : Entity_Id;
      Op  : Node_Kind;
      Val : Node_Id;

   begin
      --  The expression yields a non-null value ignoring simple flow analysis

      if Status = Is_Non_Null then
         return True;

      --  Otherwise check whether N is a reference to an entity that appears
      --  within a conditional construct.

      elsif Is_Entity_Name (N) and then Present (Entity (N)) then

         --  First check if we are in decisive conditional

         Get_Current_Value_Condition (N, Op, Val);

         if Known_Null (Val) then
            if Op = N_Op_Eq then
               return False;
            elsif Op = N_Op_Ne then
               return True;
            end if;
         end if;

         --  If OK to do replacement, test Is_Known_Non_Null flag

         Id := Entity (N);

         if OK_To_Do_Constant_Replacement (Id) then
            return Is_Known_Non_Null (Id);
         end if;
      end if;

      --  Otherwise it is not possible to determine whether N yields a non-null
      --  value.

      return False;
   end Known_Non_Null;

   ----------------
   -- Known_Null --
   ----------------

   function Known_Null (N : Node_Id) return Boolean is
      Status : constant Null_Status_Kind := Null_Status (N);

      Id  : Entity_Id;
      Op  : Node_Kind;
      Val : Node_Id;

   begin
      --  The expression yields a null value ignoring simple flow analysis

      if Status = Is_Null then
         return True;

      --  Otherwise check whether N is a reference to an entity that appears
      --  within a conditional construct.

      elsif Is_Entity_Name (N) and then Present (Entity (N)) then

         --  First check if we are in decisive conditional

         Get_Current_Value_Condition (N, Op, Val);

         --  If Get_Current_Value_Condition were to return Val = N, then the
         --  recursion below could be infinite.

         if Val = N then
            raise Program_Error;
         end if;

         if Known_Null (Val) then
            if Op = N_Op_Eq then
               return True;
            elsif Op = N_Op_Ne then
               return False;
            end if;
         end if;

         --  If OK to do replacement, test Is_Known_Null flag

         Id := Entity (N);

         if OK_To_Do_Constant_Replacement (Id) then
            return Is_Known_Null (Id);
         end if;
      end if;

      --  Otherwise it is not possible to determine whether N yields a null
      --  value.

      return False;
   end Known_Null;

   ---------------------------
   -- Last_Source_Statement --
   ---------------------------

   function Last_Source_Statement (HSS : Node_Id) return Node_Id is
      N : Node_Id;

   begin
      N := Last (Statements (HSS));
      while Present (N) loop
         exit when Comes_From_Source (N);
         Prev (N);
      end loop;

      return N;
   end Last_Source_Statement;

   -----------------------
   -- Mark_Coextensions --
   -----------------------

   procedure Mark_Coextensions (Context_Nod : Node_Id; Root_Nod : Node_Id) is
      Is_Dynamic : Boolean;
      --  Indicates whether the context causes nested coextensions to be
      --  dynamic or static

      function Mark_Allocator (N : Node_Id) return Traverse_Result;
      --  Recognize an allocator node and label it as a dynamic coextension

      --------------------
      -- Mark_Allocator --
      --------------------

      function Mark_Allocator (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Allocator then
            if Is_Dynamic then
               Set_Is_Static_Coextension (N, False);
               Set_Is_Dynamic_Coextension (N);

            --  If the allocator expression is potentially dynamic, it may
            --  be expanded out of order and require dynamic allocation
            --  anyway, so we treat the coextension itself as dynamic.
            --  Potential optimization ???

            elsif Nkind (Expression (N)) = N_Qualified_Expression
              and then Nkind (Expression (Expression (N))) = N_Op_Concat
            then
               Set_Is_Static_Coextension (N, False);
               Set_Is_Dynamic_Coextension (N);
            else
               Set_Is_Dynamic_Coextension (N, False);
               Set_Is_Static_Coextension (N);
            end if;
         end if;

         return OK;
      end Mark_Allocator;

      procedure Mark_Allocators is new Traverse_Proc (Mark_Allocator);

   --  Start of processing for Mark_Coextensions

   begin
      --  An allocator that appears on the right-hand side of an assignment is
      --  treated as a potentially dynamic coextension when the right-hand side
      --  is an allocator or a qualified expression.

      --    Obj := new ...'(new Coextension ...);

      if Nkind (Context_Nod) = N_Assignment_Statement then
         Is_Dynamic := Nkind (Expression (Context_Nod)) in
                         N_Allocator | N_Qualified_Expression;

      --  An allocator that appears within the expression of a simple return
      --  statement is treated as a potentially dynamic coextension when the
      --  expression is either aggregate, allocator, or qualified expression.

      --    return (new Coextension ...);
      --    return new ...'(new Coextension ...);

      elsif Nkind (Context_Nod) = N_Simple_Return_Statement then
         Is_Dynamic := Nkind (Expression (Context_Nod)) in
                         N_Aggregate | N_Allocator | N_Qualified_Expression;

      --  An alloctor that appears within the initialization expression of an
      --  object declaration is considered a potentially dynamic coextension
      --  when the initialization expression is an allocator or a qualified
      --  expression.

      --    Obj : ... := new ...'(new Coextension ...);

      --  A similar case arises when the object declaration is part of an
      --  extended return statement.

      --    return Obj : ... := new ...'(new Coextension ...);
      --    return Obj : ... := (new Coextension ...);

      elsif Nkind (Context_Nod) = N_Object_Declaration then
         Is_Dynamic := Nkind (Root_Nod) in N_Allocator | N_Qualified_Expression
           or else Nkind (Parent (Context_Nod)) = N_Extended_Return_Statement;

      --  This routine should not be called with constructs that cannot contain
      --  coextensions.

      else
         raise Program_Error;
      end if;

      Mark_Allocators (Root_Nod);
   end Mark_Coextensions;

   ---------------------------------
   -- Mark_Elaboration_Attributes --
   ---------------------------------

   procedure Mark_Elaboration_Attributes
     (N_Id     : Node_Or_Entity_Id;
      Checks   : Boolean := False;
      Level    : Boolean := False;
      Modes    : Boolean := False;
      Warnings : Boolean := False)
   is
      function Elaboration_Checks_OK
        (Target_Id  : Entity_Id;
         Context_Id : Entity_Id) return Boolean;
      --  Determine whether elaboration checks are enabled for target Target_Id
      --  which resides within context Context_Id.

      procedure Mark_Elaboration_Attributes_Id (Id : Entity_Id);
      --  Preserve relevant attributes of the context in arbitrary entity Id

      procedure Mark_Elaboration_Attributes_Node (N : Node_Id);
      --  Preserve relevant attributes of the context in arbitrary node N

      ---------------------------
      -- Elaboration_Checks_OK --
      ---------------------------

      function Elaboration_Checks_OK
        (Target_Id  : Entity_Id;
         Context_Id : Entity_Id) return Boolean
      is
         Encl_Scop : Entity_Id;

      begin
         --  Elaboration checks are suppressed for the target

         if Elaboration_Checks_Suppressed (Target_Id) then
            return False;
         end if;

         --  Otherwise elaboration checks are OK for the target, but may be
         --  suppressed for the context where the target is declared.

         Encl_Scop := Context_Id;
         while Present (Encl_Scop) and then Encl_Scop /= Standard_Standard loop
            if Elaboration_Checks_Suppressed (Encl_Scop) then
               return False;
            end if;

            Encl_Scop := Scope (Encl_Scop);
         end loop;

         --  Neither the target nor its declarative context have elaboration
         --  checks suppressed.

         return True;
      end Elaboration_Checks_OK;

      ------------------------------------
      -- Mark_Elaboration_Attributes_Id --
      ------------------------------------

      procedure Mark_Elaboration_Attributes_Id (Id : Entity_Id) is
      begin
         --  Mark the status of elaboration checks in effect. Do not reset the
         --  status in case the entity is reanalyzed with checks suppressed.

         if Checks and then not Is_Elaboration_Checks_OK_Id (Id) then
            Set_Is_Elaboration_Checks_OK_Id (Id,
              Elaboration_Checks_OK
                (Target_Id  => Id,
                 Context_Id => Scope (Id)));
         end if;

         --  Mark the status of elaboration warnings in effect. Do not reset
         --  the status in case the entity is reanalyzed with warnings off.

         if Warnings and then not Is_Elaboration_Warnings_OK_Id (Id) then
            Set_Is_Elaboration_Warnings_OK_Id (Id, Elab_Warnings);
         end if;
      end Mark_Elaboration_Attributes_Id;

      --------------------------------------
      -- Mark_Elaboration_Attributes_Node --
      --------------------------------------

      procedure Mark_Elaboration_Attributes_Node (N : Node_Id) is
         function Extract_Name (N : Node_Id) return Node_Id;
         --  Obtain the Name attribute of call or instantiation N

         ------------------
         -- Extract_Name --
         ------------------

         function Extract_Name (N : Node_Id) return Node_Id is
            Nam : Node_Id;

         begin
            Nam := Name (N);

            --  A call to an entry family appears in indexed form

            if Nkind (Nam) = N_Indexed_Component then
               Nam := Prefix (Nam);
            end if;

            --  The name may also appear in qualified form

            if Nkind (Nam) = N_Selected_Component then
               Nam := Selector_Name (Nam);
            end if;

            return Nam;
         end Extract_Name;

         --  Local variables

         Context_Id : Entity_Id;
         Nam        : Node_Id;

      --  Start of processing for Mark_Elaboration_Attributes_Node

      begin
         --  Mark the status of elaboration checks in effect. Do not reset the
         --  status in case the node is reanalyzed with checks suppressed.

         if Checks and then not Is_Elaboration_Checks_OK_Node (N) then

            --  Assignments, attribute references, and variable references do
            --  not have a "declarative" context.

            Context_Id := Empty;

            --  The status of elaboration checks for calls and instantiations
            --  depends on the most recent pragma Suppress/Unsuppress, as well
            --  as the suppression status of the context where the target is
            --  defined.

            --    package Pack is
            --       function Func ...;
            --    end Pack;

            --    with Pack;
            --    procedure Main is
            --       pragma Suppress (Elaboration_Checks, Pack);
            --       X : ... := Pack.Func;
            --    ...

            --  In the example above, the call to Func has elaboration checks
            --  enabled because there is no active general purpose suppression
            --  pragma, however the elaboration checks of Pack are explicitly
            --  suppressed. As a result the elaboration checks of the call must
            --  be disabled in order to preserve this dependency.

            if Nkind (N) in N_Entry_Call_Statement
                          | N_Function_Call
                          | N_Function_Instantiation
                          | N_Package_Instantiation
                          | N_Procedure_Call_Statement
                          | N_Procedure_Instantiation
            then
               Nam := Extract_Name (N);

               if Is_Entity_Name (Nam) and then Present (Entity (Nam)) then
                  Context_Id := Scope (Entity (Nam));
               end if;
            end if;

            Set_Is_Elaboration_Checks_OK_Node (N,
              Elaboration_Checks_OK
                (Target_Id  => Empty,
                 Context_Id => Context_Id));
         end if;

         --  Mark the enclosing level of the node. Do not reset the status in
         --  case the node is relocated and reanalyzed.

         if Level and then not Is_Declaration_Level_Node (N) then
            Set_Is_Declaration_Level_Node (N,
              Find_Enclosing_Level (N) = Declaration_Level);
         end if;

         --  Mark the Ghost and SPARK mode in effect

         if Modes then
            if Ghost_Mode = Ignore then
               Set_Is_Ignored_Ghost_Node (N);
            end if;

            if SPARK_Mode = On then
               Set_Is_SPARK_Mode_On_Node (N);
            end if;
         end if;

         --  Mark the status of elaboration warnings in effect. Do not reset
         --  the status in case the node is reanalyzed with warnings off.

         if Warnings and then not Is_Elaboration_Warnings_OK_Node (N) then
            Set_Is_Elaboration_Warnings_OK_Node (N, Elab_Warnings);
         end if;
      end Mark_Elaboration_Attributes_Node;

   --  Start of processing for Mark_Elaboration_Attributes

   begin
      --  Do not capture any elaboration-related attributes when switch -gnatH
      --  (legacy elaboration checking mode enabled) is in effect because the
      --  attributes are useless to the legacy model.

      if Legacy_Elaboration_Checks then
         return;
      end if;

      if Nkind (N_Id) in N_Entity then
         Mark_Elaboration_Attributes_Id (N_Id);
      else
         Mark_Elaboration_Attributes_Node (N_Id);
      end if;
   end Mark_Elaboration_Attributes;

   ----------------------------------------
   -- Mark_Save_Invocation_Graph_Of_Body --
   ----------------------------------------

   procedure Mark_Save_Invocation_Graph_Of_Body is
      Main      : constant Node_Id := Cunit (Main_Unit);
      Main_Unit : constant Node_Id := Unit (Main);
      Aux_Id    : Entity_Id;

   begin
      Set_Save_Invocation_Graph_Of_Body (Main);

      --  Assume that the main unit does not have a complimentary unit

      Aux_Id := Empty;

      --  Obtain the complimentary unit of the main unit

      if Nkind (Main_Unit) in N_Generic_Package_Declaration
                            | N_Generic_Subprogram_Declaration
                            | N_Package_Declaration
                            | N_Subprogram_Declaration
      then
         Aux_Id := Corresponding_Body (Main_Unit);

      elsif Nkind (Main_Unit) in N_Package_Body
                               | N_Subprogram_Body
                               | N_Subprogram_Renaming_Declaration
      then
         Aux_Id := Corresponding_Spec (Main_Unit);
      end if;

      if Present (Aux_Id) then
         Set_Save_Invocation_Graph_Of_Body
           (Parent (Unit_Declaration_Node (Aux_Id)));
      end if;
   end Mark_Save_Invocation_Graph_Of_Body;

   ----------------------------------
   -- Matching_Static_Array_Bounds --
   ----------------------------------

   function Matching_Static_Array_Bounds
     (L_Typ : Node_Id;
      R_Typ : Node_Id) return Boolean
   is
      L_Ndims : constant Nat := Number_Dimensions (L_Typ);
      R_Ndims : constant Nat := Number_Dimensions (R_Typ);

      L_Index : Node_Id := Empty; -- init to ...
      R_Index : Node_Id := Empty; -- ...avoid warnings
      L_Low   : Node_Id;
      L_High  : Node_Id;
      L_Len   : Uint;
      R_Low   : Node_Id;
      R_High  : Node_Id;
      R_Len   : Uint;

   begin
      if L_Ndims /= R_Ndims then
         return False;
      end if;

      --  Unconstrained types do not have static bounds

      if not Is_Constrained (L_Typ) or else not Is_Constrained (R_Typ) then
         return False;
      end if;

      --  First treat specially the first dimension, as the lower bound and
      --  length of string literals are not stored like those of arrays.

      if Ekind (L_Typ) = E_String_Literal_Subtype then
         L_Low := String_Literal_Low_Bound (L_Typ);
         L_Len := String_Literal_Length (L_Typ);
      else
         L_Index := First_Index (L_Typ);
         Get_Index_Bounds (L_Index, L_Low, L_High);

         if Is_OK_Static_Expression (L_Low)
              and then
            Is_OK_Static_Expression (L_High)
         then
            if Expr_Value (L_High) < Expr_Value (L_Low) then
               L_Len := Uint_0;
            else
               L_Len := (Expr_Value (L_High) - Expr_Value (L_Low)) + 1;
            end if;
         else
            return False;
         end if;
      end if;

      if Ekind (R_Typ) = E_String_Literal_Subtype then
         R_Low := String_Literal_Low_Bound (R_Typ);
         R_Len := String_Literal_Length (R_Typ);
      else
         R_Index := First_Index (R_Typ);
         Get_Index_Bounds (R_Index, R_Low, R_High);

         if Is_OK_Static_Expression (R_Low)
              and then
            Is_OK_Static_Expression (R_High)
         then
            if Expr_Value (R_High) < Expr_Value (R_Low) then
               R_Len := Uint_0;
            else
               R_Len := (Expr_Value (R_High) - Expr_Value (R_Low)) + 1;
            end if;
         else
            return False;
         end if;
      end if;

      if (Is_OK_Static_Expression (L_Low)
            and then
          Is_OK_Static_Expression (R_Low))
        and then Expr_Value (L_Low) = Expr_Value (R_Low)
        and then L_Len = R_Len
      then
         null;
      else
         return False;
      end if;

      --  Then treat all other dimensions

      for Indx in 2 .. L_Ndims loop
         Next (L_Index);
         Next (R_Index);

         Get_Index_Bounds (L_Index, L_Low, L_High);
         Get_Index_Bounds (R_Index, R_Low, R_High);

         if (Is_OK_Static_Expression (L_Low)  and then
             Is_OK_Static_Expression (L_High) and then
             Is_OK_Static_Expression (R_Low)  and then
             Is_OK_Static_Expression (R_High))
           and then (Expr_Value (L_Low)  = Expr_Value (R_Low)
                       and then
                     Expr_Value (L_High) = Expr_Value (R_High))
         then
            null;
         else
            return False;
         end if;
      end loop;

      --  If we fall through the loop, all indexes matched

      return True;
   end Matching_Static_Array_Bounds;

   -----------------
   -- Might_Raise --
   -----------------

   function Might_Raise (N : Node_Id) return Boolean is
      Result : Boolean := False;

      function Process (N : Node_Id) return Traverse_Result;
      --  Set Result to True if we find something that could raise an exception

      -------------
      -- Process --
      -------------

      function Process (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) in N_Procedure_Call_Statement
                       | N_Function_Call
                       | N_Raise_Statement
                       | N_Raise_xxx_Error
                       | N_Raise_Expression
         then
            Result := True;
            return Abandon;
         else
            return OK;
         end if;
      end Process;

      procedure Set_Result is new Traverse_Proc (Process);

   --  Start of processing for Might_Raise

   begin
      --  False if exceptions can't be propagated

      if No_Exception_Handlers_Set then
         return False;
      end if;

      --  If the checks handled by the back end are not disabled, we cannot
      --  ensure that no exception will be raised.

      if not Access_Checks_Suppressed (Empty)
        or else not Discriminant_Checks_Suppressed (Empty)
        or else not Range_Checks_Suppressed (Empty)
        or else not Index_Checks_Suppressed (Empty)
        or else Opt.Stack_Checking_Enabled
      then
         return True;
      end if;

      Set_Result (N);
      return Result;
   end Might_Raise;

   ----------------------------------------
   -- Nearest_Class_Condition_Subprogram --
   ----------------------------------------

   function Nearest_Class_Condition_Subprogram
     (Kind    : Condition_Kind;
      Spec_Id : Entity_Id) return Entity_Id
   is
      Subp_Id : constant Entity_Id := Ultimate_Alias (Spec_Id);

   begin
      --  Prevent cascaded errors

      if not Is_Dispatching_Operation (Subp_Id) then
         return Empty;

      --  No need to search if this subprogram has class-wide postconditions

      elsif Present (Class_Condition (Kind, Subp_Id)) then
         return Subp_Id;
      end if;

      --  Process the contracts of inherited subprograms, looking for
      --  class-wide pre/postconditions.

      declare
         Subps   : constant Subprogram_List := Inherited_Subprograms (Subp_Id);
         Subp_Id : Entity_Id;

      begin
         for Index in Subps'Range loop
            Subp_Id := Subps (Index);

            if Present (Alias (Subp_Id)) then
               Subp_Id := Ultimate_Alias (Subp_Id);
            end if;

            --  Wrappers of class-wide pre/postconditions reference the
            --  parent primitive that has the inherited contract.

            if Is_Wrapper (Subp_Id)
              and then Present (LSP_Subprogram (Subp_Id))
            then
               Subp_Id := LSP_Subprogram (Subp_Id);
            end if;

            if Present (Class_Condition (Kind, Subp_Id)) then
               return Subp_Id;
            end if;
         end loop;
      end;

      return Empty;
   end Nearest_Class_Condition_Subprogram;

   --------------------------------
   -- Nearest_Enclosing_Instance --
   --------------------------------

   function Nearest_Enclosing_Instance (E : Entity_Id) return Entity_Id is
      Inst : Entity_Id;

   begin
      Inst := Scope (E);
      while Present (Inst) and then Inst /= Standard_Standard loop
         if Is_Generic_Instance (Inst) then
            return Inst;
         end if;

         Inst := Scope (Inst);
      end loop;

      return Empty;
   end Nearest_Enclosing_Instance;

   ------------------------
   -- Needs_Finalization --
   ------------------------

   function Needs_Finalization (Typ : Entity_Id) return Boolean is
      function Has_Some_Controlled_Component
        (Input_Typ : Entity_Id) return Boolean;
      --  Determine whether type Input_Typ has at least one controlled
      --  component.

      -----------------------------------
      -- Has_Some_Controlled_Component --
      -----------------------------------

      function Has_Some_Controlled_Component
        (Input_Typ : Entity_Id) return Boolean
      is
         Comp : Entity_Id;

      begin
         --  When a type is already frozen and has at least one controlled
         --  component, or is manually decorated, it is sufficient to inspect
         --  flag Has_Controlled_Component.

         if Has_Controlled_Component (Input_Typ) then
            return True;

         --  Otherwise inspect the internals of the type

         elsif not Is_Frozen (Input_Typ) then
            if Is_Array_Type (Input_Typ) then
               return Needs_Finalization (Component_Type (Input_Typ));

            elsif Is_Record_Type (Input_Typ) then
               Comp := First_Component (Input_Typ);
               while Present (Comp) loop
                  if Needs_Finalization (Etype (Comp)) then
                     return True;
                  end if;

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

         return False;
      end Has_Some_Controlled_Component;

   --  Start of processing for Needs_Finalization

   begin
      --  Certain run-time configurations and targets do not provide support
      --  for controlled types.

      if Restriction_Active (No_Finalization) then
         return False;

      --  C++ types are not considered controlled. It is assumed that the non-
      --  Ada side will handle their clean up.

      elsif Convention (Typ) = Convention_CPP then
         return False;

      --  Class-wide types are treated as controlled because derivations from
      --  the root type may introduce controlled components.

      elsif Is_Class_Wide_Type (Typ) then
         return True;

      --  Concurrent types are controlled as long as their corresponding record
      --  is controlled.

      elsif Is_Concurrent_Type (Typ)
        and then Present (Corresponding_Record_Type (Typ))
        and then Needs_Finalization (Corresponding_Record_Type (Typ))
      then
         return True;

      --  Otherwise the type is controlled when it is either derived from type
      --  [Limited_]Controlled and not subject to aspect Disable_Controlled, or
      --  contains at least one controlled component.

      else
         return
           Is_Controlled (Typ) or else Has_Some_Controlled_Component (Typ);
      end if;
   end Needs_Finalization;

   ----------------------
   -- Needs_One_Actual --
   ----------------------

   function Needs_One_Actual (E : Entity_Id) return Boolean is
      Formal : Entity_Id;

   begin
      --  Ada 2005 or later, and formals present. The first formal must be
      --  of a type that supports prefix notation: a controlling argument,
      --  a class-wide type, or an access to such.

      if Ada_Version >= Ada_2005
        and then Present (First_Formal (E))
        and then No (Default_Value (First_Formal (E)))
        and then
          (Is_Controlling_Formal (First_Formal (E))
            or else Is_Class_Wide_Type (Etype (First_Formal (E)))
            or else Is_Anonymous_Access_Type (Etype (First_Formal (E))))
      then
         Formal := Next_Formal (First_Formal (E));
         while Present (Formal) loop
            if No (Default_Value (Formal)) then
               return False;
            end if;

            Next_Formal (Formal);
         end loop;

         return True;

      --  Ada 83/95 or no formals

      else
         return False;
      end if;
   end Needs_One_Actual;

   --------------------------------------
   -- Needs_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, unless they are dispatching
      --  operations, since they may be overridden by Ada_2012 primitives.

      elsif Ada_Version < Ada_2012
        and then not Is_Dispatching_Operation (Func_Id)
      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 then not Is_Constrained (Typ));
         return True;
      end if;
   end Needs_Secondary_Stack;

   ---------------------------------
   -- Needs_Simple_Initialization --
   ---------------------------------

   function Needs_Simple_Initialization
     (Typ         : Entity_Id;
      Consider_IS : Boolean := True) return Boolean
   is
      Consider_IS_NS : constant Boolean :=
        Normalize_Scalars or (Initialize_Scalars and Consider_IS);

   begin
      --  Never need initialization if it is suppressed

      if Initialization_Suppressed (Typ) then
         return False;
      end if;

      --  Check for private type, in which case test applies to the underlying
      --  type of the private type.

      if Is_Private_Type (Typ) then
         declare
            RT : constant Entity_Id := Underlying_Type (Typ);
         begin
            if Present (RT) then
               return Needs_Simple_Initialization (RT);
            else
               return False;
            end if;
         end;

      --  Scalar type with Default_Value aspect requires initialization

      elsif Is_Scalar_Type (Typ) and then Has_Default_Aspect (Typ) then
         return True;

      --  Cases needing simple initialization are access types, and, if pragma
      --  Normalize_Scalars or Initialize_Scalars is in effect, then all scalar
      --  types.

      elsif Is_Access_Type (Typ)
        or else (Consider_IS_NS and then Is_Scalar_Type (Typ))
      then
         return True;

      --  If Initialize/Normalize_Scalars is in effect, string objects also
      --  need initialization, unless they are created in the course of
      --  expanding an aggregate (since in the latter case they will be
      --  filled with appropriate initializing values before they are used).

      elsif Consider_IS_NS
        and then Is_Standard_String_Type (Typ)
        and then
          (not Is_Itype (Typ)
            or else Nkind (Associated_Node_For_Itype (Typ)) /= N_Aggregate)
      then
         return True;

      else
         return False;
      end if;
   end Needs_Simple_Initialization;

   -------------------------------------
   -- Needs_Variable_Reference_Marker --
   -------------------------------------

   function Needs_Variable_Reference_Marker
     (N        : Node_Id;
      Calls_OK : Boolean) return Boolean
   is
      function Within_Suitable_Context (Ref : Node_Id) return Boolean;
      --  Deteremine whether variable reference Ref appears within a suitable
      --  context that allows the creation of a marker.

      -----------------------------
      -- Within_Suitable_Context --
      -----------------------------

      function Within_Suitable_Context (Ref : Node_Id) return Boolean is
         Par : Node_Id;

      begin
         Par := Ref;
         while Present (Par) loop

            --  The context is not suitable when the reference appears within
            --  the formal part of an instantiation which acts as compilation
            --  unit because there is no proper list for the insertion of the
            --  marker.

            if Nkind (Par) = N_Generic_Association
              and then Nkind (Parent (Par)) in N_Generic_Instantiation
              and then Nkind (Parent (Parent (Par))) = N_Compilation_Unit
            then
               return False;

            --  The context is not suitable when the reference appears within
            --  a pragma. If the pragma has run-time semantics, the reference
            --  will be reconsidered once the pragma is expanded.

            elsif Nkind (Par) = N_Pragma then
               return False;

            --  The context is not suitable when the reference appears within a
            --  subprogram call, and the caller requests this behavior.

            elsif not Calls_OK
              and then Nkind (Par) in N_Entry_Call_Statement
                                    | N_Function_Call
                                    | N_Procedure_Call_Statement
            then
               return False;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);
         end loop;

         return True;
      end Within_Suitable_Context;

      --  Local variables

      Prag   : Node_Id;
      Var_Id : Entity_Id;

   --  Start of processing for Needs_Variable_Reference_Marker

   begin
      --  No marker needs to be created when switch -gnatH (legacy elaboration
      --  checking mode enabled) is in effect because the legacy ABE mechanism
      --  does not use markers.

      if Legacy_Elaboration_Checks then
         return False;

      --  No marker needs to be created when the reference is preanalyzed
      --  because the marker will be inserted in the wrong place.

      elsif Preanalysis_Active then
         return False;

      --  Only references warrant a marker

      elsif Nkind (N) not in N_Expanded_Name | N_Identifier then
         return False;

      --  Only source references warrant a marker

      elsif not Comes_From_Source (N) then
         return False;

      --  No marker needs to be created when the reference is erroneous, left
      --  in a bad state, or does not denote a variable.

      elsif not (Present (Entity (N))
                  and then Ekind (Entity (N)) = E_Variable
                  and then Entity (N) /= Any_Id)
      then
         return False;
      end if;

      Var_Id := Entity (N);
      Prag   := SPARK_Pragma (Var_Id);

      --  Both the variable and reference must appear in SPARK_Mode On regions
      --  because this elaboration scenario falls under the SPARK rules.

      if not (Comes_From_Source (Var_Id)
               and then Present (Prag)
               and then Get_SPARK_Mode_From_Annotation (Prag) = On
               and then Is_SPARK_Mode_On_Node (N))
      then
         return False;

      --  No marker needs to be created when the reference does not appear
      --  within a suitable context (see body for details).

      --  Performance note: parent traversal

      elsif not Within_Suitable_Context (N) then
         return False;
      end if;

      --  At this point it is known that the variable reference will play a
      --  role in ABE diagnostics and requires a marker.

      return True;
   end Needs_Variable_Reference_Marker;

   ------------------------
   -- New_Copy_List_Tree --
   ------------------------

   function New_Copy_List_Tree (List : List_Id) return List_Id is
      NL : List_Id;
      E  : Node_Id;

   begin
      if List = No_List then
         return No_List;

      else
         NL := New_List;
         E := First (List);

         while Present (E) loop
            Append (New_Copy_Tree (E), NL);
            Next (E);
         end loop;

         return NL;
      end if;
   end New_Copy_List_Tree;

   ----------------------------
   -- New_Copy_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 Is_Body (P) then
               return True;

            elsif      Nkind (P) = N_If_Statement
              or else  Nkind (P) = N_Case_Statement
              or else (Nkind (P) in N_Short_Circuit
                        and then Desc = Right_Opnd (P))
              or else (Nkind (P) = N_If_Expression
                        and then Desc /= First (Expressions (P)))
              or else  Nkind (P) = N_Exception_Handler
              or else  Nkind (P) = N_Selective_Accept
              or else  Nkind (P) = N_Conditional_Entry_Call
              or else  Nkind (P) = N_Timed_Entry_Call
              or else  Nkind (P) = N_Asynchronous_Select
            then
               return False;

            else
               Desc := P;
               P := Parent (P);

               --  A special Ada 2012 case: the original node may be part
               --  of the else_actions of a conditional expression, in which
               --  case it might not have been expanded yet, and appears in
               --  a non-syntactic list of actions. In that case it is clearly
               --  not safe to save a value.

               if No (P)
                 and then Is_List_Member (Desc)
                 and then No (Parent (List_Containing (Desc)))
               then
                  return False;
               end if;
            end if;
         end loop;
      end;

      --  OK, looks safe to set value

      return True;
   end Safe_To_Capture_Value;

   ---------------
   -- Same_Name --
   ---------------

   function Same_Name (N1, N2 : Node_Id) return Boolean is
      K1 : constant Node_Kind := Nkind (N1);
      K2 : constant Node_Kind := Nkind (N2);

   begin
      if (K1 = N_Identifier or else K1 = N_Defining_Identifier)
        and then (K2 = N_Identifier or else K2 = N_Defining_Identifier)
      then
         return Chars (N1) = Chars (N2);

      elsif (K1 = N_Selected_Component or else K1 = N_Expanded_Name)
        and then (K2 = N_Selected_Component or else K2 = N_Expanded_Name)
      then
         return Same_Name (Selector_Name (N1), Selector_Name (N2))
           and then Same_Name (Prefix (N1), Prefix (N2));

      else
         return False;
      end if;
   end Same_Name;

   -----------------
   -- Same_Object --
   -----------------

   function Same_Object (Node1, Node2 : Node_Id) return Boolean is
      N1 : constant Node_Id := Original_Node (Node1);
      N2 : constant Node_Id := Original_Node (Node2);
      --  We do the tests on original nodes, since we are most interested
      --  in the original source, not any expansion that got in the way.

      K1 : constant Node_Kind := Nkind (N1);
      K2 : constant Node_Kind := Nkind (N2);

   begin
      --  First case, both are entities with same entity

      if K1 in N_Has_Entity and then K2 in N_Has_Entity then
         declare
            EN1 : constant Entity_Id := Entity (N1);
            EN2 : constant Entity_Id := Entity (N2);
         begin
            if Present (EN1) and then Present (EN2)
              and then (Ekind (EN1) in E_Variable | E_Constant
                         or else Is_Formal (EN1))
              and then EN1 = EN2
            then
               return True;
            end if;
         end;
      end if;

      --  Second case, selected component with same selector, same record

      if K1 = N_Selected_Component
        and then K2 = N_Selected_Component
        and then Chars (Selector_Name (N1)) = Chars (Selector_Name (N2))
      then
         return Same_Object (Prefix (N1), Prefix (N2));

      --  Third case, indexed component with same subscripts, same array

      elsif K1 = N_Indexed_Component
        and then K2 = N_Indexed_Component
        and then Same_Object (Prefix (N1), Prefix (N2))
      then
         declare
            E1, E2 : Node_Id;
         begin
            E1 := First (Expressions (N1));
            E2 := First (Expressions (N2));
            while Present (E1) loop
               if not Same_Value (E1, E2) then
                  return False;
               else
                  Next (E1);
                  Next (E2);
               end if;
            end loop;

            return True;
         end;

      --  Fourth case, slice of same array with same bounds

      elsif K1 = N_Slice
        and then K2 = N_Slice
        and then Nkind (Discrete_Range (N1)) = N_Range
        and then Nkind (Discrete_Range (N2)) = N_Range
        and then Same_Value (Low_Bound (Discrete_Range (N1)),
                             Low_Bound (Discrete_Range (N2)))
        and then Same_Value (High_Bound (Discrete_Range (N1)),
                             High_Bound (Discrete_Range (N2)))
      then
         return Same_Name (Prefix (N1), Prefix (N2));

      --  All other cases, not clearly the same object

      else
         return False;
      end if;
   end Same_Object;

   ---------------------------------
   -- Same_Or_Aliased_Subprograms --
   ---------------------------------

   function Same_Or_Aliased_Subprograms
     (S : Entity_Id;
      E : Entity_Id) return Boolean
   is
      Subp_Alias : constant Entity_Id := Alias (S);
      Subp       : Entity_Id := E;
   begin
      --  During expansion of subprograms with postconditions the original
      --  subprogram's declarations and statements get wrapped into a local
      --  _Wrapped_Statements subprogram.

      if Chars (Subp) = Name_uWrapped_Statements then
         Subp := Enclosing_Subprogram (Subp);
      end if;

      return S = Subp
        or else (Present (Subp_Alias) and then Subp_Alias = Subp);
   end Same_Or_Aliased_Subprograms;

   ---------------
   -- Same_Type --
   ---------------

   function Same_Type (T1, T2 : Entity_Id) return Boolean is
   begin
      if T1 = T2 then
         return True;

      elsif not Is_Constrained (T1)
        and then not Is_Constrained (T2)
        and then Base_Type (T1) = Base_Type (T2)
      then
         return True;

      --  For now don't bother with case of identical constraints, to be
      --  fiddled with later on perhaps (this is only used for optimization
      --  purposes, so it is not critical to do a best possible job)

      else
         return False;
      end if;
   end Same_Type;

   ----------------
   -- Same_Value --
   ----------------

   function Same_Value (Node1, Node2 : Node_Id) return Boolean is
   begin
      if Compile_Time_Known_Value (Node1)
        and then Compile_Time_Known_Value (Node2)
      then
         --  Handle properly compile-time expressions that are not
         --  scalar.

         if Is_String_Type (Etype (Node1)) then
            return Expr_Value_S (Node1) = Expr_Value_S (Node2);

         else
            return Expr_Value (Node1) = Expr_Value (Node2);
         end if;

      elsif Same_Object (Node1, Node2) then
         return True;
      else
         return False;
      end if;
   end Same_Value;

   --------------------
   -- Set_SPARK_Mode --
   --------------------

   procedure Set_SPARK_Mode (Context : Entity_Id) is
   begin
      --  Do not consider illegal or partially decorated constructs

      if Ekind (Context) = E_Void or else Error_Posted (Context) then
         null;

      elsif Present (SPARK_Pragma (Context)) then
         Install_SPARK_Mode
           (Mode => Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Context)),
            Prag => SPARK_Pragma (Context));
      end if;
   end Set_SPARK_Mode;

   -------------------------
   -- Scalar_Part_Present --
   -------------------------

   function Scalar_Part_Present (Typ : Entity_Id) return Boolean is
      Val_Typ : constant Entity_Id := Validated_View (Typ);
      Field   : Entity_Id;

   begin
      if Is_Scalar_Type (Val_Typ) then
         return True;

      elsif Is_Array_Type (Val_Typ) then
         return Scalar_Part_Present (Component_Type (Val_Typ));

      elsif Is_Record_Type (Val_Typ) then
         Field := First_Component_Or_Discriminant (Val_Typ);
         while Present (Field) loop
            if Scalar_Part_Present (Etype (Field)) then
               return True;
            end if;

            Next_Component_Or_Discriminant (Field);
         end loop;
      end if;

      return False;
   end Scalar_Part_Present;

   ------------------------
   -- Scope_Is_Transient --
   ------------------------

   function Scope_Is_Transient return Boolean is
   begin
      return Scope_Stack.Table (Scope_Stack.Last).Is_Transient;
   end Scope_Is_Transient;

   ------------------
   -- Scope_Within --
   ------------------

   function Scope_Within
     (Inner : Entity_Id;
      Outer : Entity_Id) return Boolean
   is
      Curr : Entity_Id;

   begin
      Curr := Inner;
      while Present (Curr) and then Curr /= Standard_Standard loop
         Curr := Scope (Curr);

         if Curr = Outer then
            return True;

         --  A selective accept body appears within a task type, but the
         --  enclosing subprogram is the procedure of the task body.

         elsif Ekind (Implementation_Base_Type (Curr)) = E_Task_Type
           and then
             Outer = Task_Body_Procedure (Implementation_Base_Type (Curr))
         then
            return True;

         --  Ditto for the body of a protected operation

         elsif Is_Subprogram (Curr)
           and then Outer = Protected_Body_Subprogram (Curr)
         then
            return True;

         --  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 (No (Range_Or_Expr));
               Check_Consistency (Result);
               return Result;
            end;
         else
            declare
               Low  : constant Uint := Expr_Value (Type_Low_Bound (Typ));
               High : constant Uint := Expr_Value (Type_High_Bound (Typ));
            begin
               if Low > High then
                  declare
                     Null_Array : Discrete_Interval_List (1 .. 0);
                  begin
                     return Null_Array;
                  end;
               else
                  return (1 => (Low => Low, High => High));
               end if;
            end;
         end if;
      end Type_Intervals;

   end Interval_Lists;

   package body Old_Attr_Util is
      package body Conditional_Evaluation is
         type Determining_Expr_Context is
           (No_Context, If_Expr, Case_Expr, Short_Circuit_Op, Membership_Test);

         --  Determining_Expr_Context enumeration elements (except for
         --  No_Context) correspond to the list items in RM 6.1.1 definition
         --  of "determining expression".

         type Determining_Expr
           (Context : Determining_Expr_Context := No_Context)
         is record
            Expr : Node_Id := Empty;
            case Context is
               when Short_Circuit_Op =>
                  Is_And_Then         : Boolean;
               when If_Expr =>
                  Is_Then_Part        : Boolean;
               when Case_Expr =>
                  Alternatives        : Node_Id;
               when Membership_Test =>
                  --  Given a subexpression of <exp4> in a membership test
                  --    <exp1> in <exp2> | <exp3> | <exp4> | <exp5>
                  --  the corresponding determining expression value would
                  --  have First_Non_Preceding = <exp4> (See RM 6.1.1).
                  First_Non_Preceding : Node_Id;
               when No_Context =>
                  null;
            end case;
         end record;

         type Determining_Expression_List is
           array (Positive range <>) of Determining_Expr;

         function Determining_Condition (Det : Determining_Expr)
           return Node_Id;
         --  Given a determining expression, build a Boolean-valued
         --  condition that incorporates that expression into condition
         --  suitable for deciding whether to initialize a 'Old constant.
         --  Polarity is "True => initialize the constant".

         function Determining_Expressions
           (Expr : Node_Id; Expr_Trailer : Node_Id := Empty)
           return Determining_Expression_List;
         --  Given a conditionally evaluated expression, return its
         --  determining expressions.
         --  See RM 6.1.1 for definition of term "determining expressions".
         --  Tests should be performed in the order they occur in the
         --  array, with short circuiting.
         --  A determining expression need not be of a boolean type (e.g.,
         --  it might be the determining expression of a case expression).
         --  The Expr_Trailer parameter should be defaulted for nonrecursive
         --  calls.

         function Is_Conditionally_Evaluated (Expr : Node_Id) return Boolean;
         --  See RM 6.1.1 for definition of term "conditionally evaluated".

         function Is_Known_On_Entry (Expr : Node_Id) return Boolean;
         --  See RM 6.1.1 for definition of term "known on entry".

         --------------------------------------
         -- Conditional_Evaluation_Condition --
         --------------------------------------

         function Conditional_Evaluation_Condition
           (Expr : Node_Id) return Node_Id
         is
            Determiners : constant Determining_Expression_List :=
              Determining_Expressions (Expr);
            Loc         : constant Source_Ptr := Sloc (Expr);
            Result      : Node_Id :=
              New_Occurrence_Of (Standard_True, Loc);
         begin
            pragma Assert (Determiners'Length > 0 or else
                           Is_Anonymous_Access_Type (Etype (Expr)));

            for I in Determiners'Range loop
               Result := Make_And_Then
                          (Loc,
                           Left_Opnd  => Result,
                           Right_Opnd =>
                             Determining_Condition (Determiners (I)));
            end loop;
            return Result;
         end Conditional_Evaluation_Condition;

         ---------------------------
         -- Determining_Condition --
         ---------------------------

         function Determining_Condition (Det : Determining_Expr) return Node_Id
         is
            Loc : constant Source_Ptr := Sloc (Det.Expr);
         begin
            case Det.Context is
               when Short_Circuit_Op =>
                  if Det.Is_And_Then then
                     return New_Copy_Tree (Det.Expr);
                  else
                     return Make_Op_Not (Loc, New_Copy_Tree (Det.Expr));
                  end if;

               when If_Expr =>
                  if Det.Is_Then_Part then
                     return New_Copy_Tree (Det.Expr);
                  else
                     return Make_Op_Not (Loc, New_Copy_Tree (Det.Expr));
                  end if;

               when Case_Expr =>
                  declare
                     Alts : List_Id := Discrete_Choices (Det.Alternatives);
                  begin
                     if Nkind (First (Alts)) = N_Others_Choice then
                        Alts := Others_Discrete_Choices (First (Alts));
                     end if;

                     return Make_In (Loc,
                       Left_Opnd    => New_Copy_Tree (Det.Expr),
                       Right_Opnd   => Empty,
                       Alternatives => New_Copy_List (Alts));
                  end;

               when Membership_Test =>
                  declare
                     function Copy_Prefix
                       (List : List_Id; Suffix_Start : Node_Id)
                       return List_Id;
                     --  Given a list and a member of that list, returns
                     --  a copy (similar to Nlists.New_Copy_List) of the
                     --  prefix of the list up to but not including
                     --  Suffix_Start.

                     -----------------
                     -- Copy_Prefix --
                     -----------------

                     function Copy_Prefix
                       (List : List_Id; Suffix_Start : Node_Id)
                       return List_Id
                     is
                        Result : constant List_Id := New_List;
                        Elem   : Node_Id := First (List);
                     begin
                        while Elem /= Suffix_Start loop
                           Append (New_Copy (Elem), Result);
                           Next (Elem);
                           pragma Assert (Present (Elem));
                        end loop;
                        return Result;
                     end Copy_Prefix;

                  begin
                     return Make_In (Loc,
                       Left_Opnd    => New_Copy_Tree (Left_Opnd (Det.Expr)),
                       Right_Opnd   => Empty,
                       Alternatives => Copy_Prefix
                                         (Alternatives (Det.Expr),
                                          Det.First_Non_Preceding));
                  end;

               when No_Context =>
                  raise Program_Error;
            end case;
         end Determining_Condition;

         -----------------------------
         -- Determining_Expressions --
         -----------------------------

         function Determining_Expressions
           (Expr : Node_Id; Expr_Trailer : Node_Id := Empty)
           return Determining_Expression_List
         is
            Par           : Node_Id := Expr;
            Trailer       : Node_Id := Expr_Trailer;
            Next_Element  : Determining_Expr;
         begin
            --  We want to stop climbing up the tree when we reach the
            --  postcondition expression. An aspect_specification is
            --  transformed into a pragma, so reaching a pragma is our
            --  termination condition. This relies on the fact that
            --  pragmas are not allowed in declare expressions (or any
            --  other kind of expression).

            loop
               Next_Element.Expr := Empty;

               case Nkind (Par) is
                  when N_Short_Circuit =>
                     if Trailer = Right_Opnd (Par) then
                        Next_Element :=
                          (Expr        => Left_Opnd (Par),
                           Context     => Short_Circuit_Op,
                           Is_And_Then => Nkind (Par) = N_And_Then);
                     end if;

                  when N_If_Expression =>
                     --  For an expression like
                     --    (if C1 then ... elsif C2 then ... else Foo'Old)
                     --  the RM says are two determining expressions,
                     --  C1 and C2. Our treatment here (where we only add
                     --  one determining expression to the list) is ok because
                     --  we will see two if-expressions, one within the other.

                     if Trailer /= First (Expressions (Par)) then
                        Next_Element :=
                           (Expr         => First (Expressions (Par)),
                            Context      => If_Expr,
                            Is_Then_Part =>
                              Trailer = Next (First (Expressions (Par))));
                     end if;

                  when N_Case_Expression_Alternative =>
                     pragma Assert (Nkind (Parent (Par)) = N_Case_Expression);

                     Next_Element :=
                       (Expr         => Expression (Parent (Par)),
                        Context      => Case_Expr,
                        Alternatives => Par);

                  when N_Membership_Test =>
                     if Trailer /= Left_Opnd (Par)
                       and then Is_Non_Empty_List (Alternatives (Par))
                       and then Trailer /= First (Alternatives (Par))
                     then
                        pragma Assert (No (Right_Opnd (Par)));
                        pragma Assert
                          (Is_List_Member (Trailer)
                           and then List_Containing (Trailer)
                                    = Alternatives (Par));

                        --  This one is different than the others
                        --  because one element in the array result
                        --  may represent multiple determining
                        --  expressions (i.e. every member of the list
                        --     Alternatives (Par)
                        --  up to but not including Trailer).

                        Next_Element :=
                          (Expr                => Par,
                           Context             => Membership_Test,
                           First_Non_Preceding => Trailer);
                     end if;

                  when N_Pragma =>
                     declare
                        Previous : constant Node_Id := Prev (Par);
                        Prev_Expr : Node_Id;
                     begin
                        if Nkind (Previous) = N_Pragma and then
                          Split_PPC (Previous)
                        then
                           --  A source-level postcondition of
                           --    A and then B and then C
                           --  results in
                           --    pragma Postcondition (A);
                           --    pragma Postcondition (B);
                           --    pragma Postcondition (C);
                           --  with Split_PPC set to True on all but the
                           --  last pragma. We account for that here.

                           Prev_Expr :=
                             Expression (First
                               (Pragma_Argument_Associations (Previous)));

                           --  This Analyze call is needed in the case when
                           --  Sem_Attr.Analyze_Attribute calls
                           --  Eligible_For_Conditional_Evaluation. Without
                           --  it, we end up passing an unanalyzed expression
                           --  to Is_Known_On_Entry and that doesn't work.

                           Analyze (Prev_Expr);

                           Next_Element :=
                             (Expr        => Prev_Expr,
                              Context     => Short_Circuit_Op,
                              Is_And_Then => True);

                           return Determining_Expressions (Prev_Expr)
                             & Next_Element;
                        else
                           pragma Assert
                             (Get_Pragma_Id (Pragma_Name (Par)) in
                                Pragma_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 Has_Aspect (Typ, Aspect_Designated_Storage_Model);
      end Has_Designated_Storage_Model_Aspect;

      -----------------------------------
      -- Has_Storage_Model_Type_Aspect --
      -----------------------------------

      function Has_Storage_Model_Type_Aspect (Typ : Entity_Id) return Boolean
      is
      begin
         return Has_Aspect (Typ, Aspect_Storage_Model_Type);
      end Has_Storage_Model_Type_Aspect;

      --------------------------
      -- Storage_Model_Object --
      --------------------------

      function Storage_Model_Object (Typ : Entity_Id) return Entity_Id is
      begin
         pragma Assert (Has_Designated_Storage_Model_Aspect (Typ));

         return
           Entity
             (Find_Value_Of_Aspect (Typ, Aspect_Designated_Storage_Model));
      end Storage_Model_Object;

      ------------------------
      -- Storage_Model_Type --
      ------------------------

      function Storage_Model_Type (Obj : Entity_Id) return Entity_Id is
      begin
         pragma Assert (Has_Storage_Model_Type_Aspect (Etype (Obj)));

         return Etype (Obj);
      end Storage_Model_Type;

      -----------------------------------
      -- Get_Storage_Model_Type_Entity --
      -----------------------------------

      function Get_Storage_Model_Type_Entity
        (SM_Obj_Or_Type : Entity_Id;
         Nam            : Name_Id) return Entity_Id
      is
         Typ : constant Entity_Id := (if Is_Object (SM_Obj_Or_Type) then
                                         Storage_Model_Type (SM_Obj_Or_Type)
                                      else
                                         SM_Obj_Or_Type);
         pragma Assert
           (Is_Type (Typ)
             and then
               Nam in Name_Address_Type
                    | Name_Null_Address
                    | Name_Allocate
                    | Name_Deallocate
                    | Name_Copy_From
                    | Name_Copy_To
                    | Name_Storage_Size);

         Assoc            : Node_Id;
         SMT_Aspect_Value : constant Node_Id :=
           Find_Value_Of_Aspect (Typ, Aspect_Storage_Model_Type);

      begin
         --  When the aspect has an aggregate expression, search through it
         --  to locate a match for the name of the given "subaspect" and return
         --  the entity of the aggregate association's expression.

         if Present (SMT_Aspect_Value) then
            Assoc := First (Component_Associations (SMT_Aspect_Value));
            while Present (Assoc) loop
               if Chars (First (Choices (Assoc))) = Nam then
                  return Entity (Expression (Assoc));
               end if;

               Next (Assoc);
            end loop;
         end if;

         --  The aggregate argument of Storage_Model_Type is optional, and when
         --  not present the aspect defaults to the native storage model, where
         --  the address type is System.Address. In that case, we return
         --  System.Address for Name_Address_Type and System.Null_Address for
         --  Name_Null_Address, but return Empty for other cases, and leave it
         --  to the back end to map those to the appropriate native operations.

         if Nam = Name_Address_Type then
            return RTE (RE_Address);

         elsif Nam = Name_Null_Address then
            return RTE (RE_Null_Address);

         else
            return Empty;
         end if;
      end Get_Storage_Model_Type_Entity;

      --------------------------------
      -- Storage_Model_Address_Type --
      --------------------------------

      function Storage_Model_Address_Type
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Address_Type);
      end Storage_Model_Address_Type;

      --------------------------------
      -- Storage_Model_Null_Address --
      --------------------------------

      function Storage_Model_Null_Address
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Null_Address);
      end Storage_Model_Null_Address;

      ----------------------------
      -- Storage_Model_Allocate --
      ----------------------------

      function Storage_Model_Allocate
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Allocate);
      end Storage_Model_Allocate;

      ------------------------------
      -- Storage_Model_Deallocate --
      ------------------------------

      function Storage_Model_Deallocate
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Deallocate);
      end Storage_Model_Deallocate;

      -----------------------------
      -- Storage_Model_Copy_From --
      -----------------------------

      function Storage_Model_Copy_From
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Copy_From);
      end Storage_Model_Copy_From;

      ---------------------------
      -- Storage_Model_Copy_To --
      ---------------------------

      function Storage_Model_Copy_To
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Copy_To);
      end Storage_Model_Copy_To;

      --------------------------------
      -- Storage_Model_Storage_Size --
      --------------------------------

      function Storage_Model_Storage_Size
        (SM_Obj_Or_Type : Entity_Id) return Entity_Id
      is
      begin
         return
           Get_Storage_Model_Type_Entity (SM_Obj_Or_Type, Name_Storage_Size);
      end Storage_Model_Storage_Size;

   end Storage_Model_Support;

begin
   Erroutc.Subprogram_Name_Ptr := Subprogram_Name'Access;
end Sem_Util;
