OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [ada/] [sem_util.adb] - Diff between revs 281 and 384

Only display areas with differences | Details | Blame | View Log

Rev 281 Rev 384
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--                                                                          --
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                                                          --
--                             S E M _ U T I L                              --
--                             S E M _ U T I L                              --
--                                                                          --
--                                                                          --
--                                 B o d y                                  --
--                                 B o d y                                  --
--                                                                          --
--                                                                          --
--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
--                                                                          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- 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- --
-- 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- --
-- 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- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- 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 --
-- 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 --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
--                                                                          --
------------------------------------------------------------------------------
------------------------------------------------------------------------------
 
 
with Atree;    use Atree;
with Atree;    use Atree;
with Casing;   use Casing;
with Casing;   use Casing;
with Checks;   use Checks;
with Checks;   use Checks;
with Debug;    use Debug;
with Debug;    use Debug;
with Errout;   use Errout;
with Errout;   use Errout;
with Elists;   use Elists;
with Elists;   use Elists;
with Exp_Ch11; use Exp_Ch11;
with Exp_Ch11; use Exp_Ch11;
with Exp_Disp; use Exp_Disp;
with Exp_Disp; use Exp_Disp;
with Exp_Tss;  use Exp_Tss;
with Exp_Tss;  use Exp_Tss;
with Exp_Util; use Exp_Util;
with Exp_Util; use Exp_Util;
with Fname;    use Fname;
with Fname;    use Fname;
with Freeze;   use Freeze;
with Freeze;   use Freeze;
with Lib;      use Lib;
with Lib;      use Lib;
with Lib.Xref; use Lib.Xref;
with Lib.Xref; use Lib.Xref;
with Nlists;   use Nlists;
with Nlists;   use Nlists;
with Output;   use Output;
with Output;   use Output;
with Opt;      use Opt;
with Opt;      use Opt;
with Rtsfind;  use Rtsfind;
with Rtsfind;  use Rtsfind;
with Scans;    use Scans;
with Scans;    use Scans;
with Scn;      use Scn;
with Scn;      use Scn;
with Sem;      use Sem;
with Sem;      use Sem;
with Sem_Aux;  use Sem_Aux;
with Sem_Aux;  use Sem_Aux;
with Sem_Attr; use Sem_Attr;
with Sem_Attr; use Sem_Attr;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Disp; use Sem_Disp;
with Sem_Disp; use Sem_Disp;
with Sem_Eval; use Sem_Eval;
with Sem_Eval; use Sem_Eval;
with Sem_Res;  use Sem_Res;
with Sem_Res;  use Sem_Res;
with Sem_SCIL; use Sem_SCIL;
with Sem_SCIL; use Sem_SCIL;
with Sem_Type; use Sem_Type;
with Sem_Type; use Sem_Type;
with Sinfo;    use Sinfo;
with Sinfo;    use Sinfo;
with Sinput;   use Sinput;
with Sinput;   use Sinput;
with Stand;    use Stand;
with Stand;    use Stand;
with Style;
with Style;
with Stringt;  use Stringt;
with Stringt;  use Stringt;
with Targparm; use Targparm;
with Targparm; use Targparm;
with Tbuild;   use Tbuild;
with Tbuild;   use Tbuild;
with Ttypes;   use Ttypes;
with Ttypes;   use Ttypes;
with Uname;    use Uname;
with Uname;    use Uname;
 
 
with GNAT.HTable; use GNAT.HTable;
with GNAT.HTable; use GNAT.HTable;
package body Sem_Util is
package body Sem_Util is
 
 
   ----------------------------------------
   ----------------------------------------
   -- Global_Variables for New_Copy_Tree --
   -- Global_Variables for New_Copy_Tree --
   ----------------------------------------
   ----------------------------------------
 
 
   --  These global variables are used by New_Copy_Tree. See description
   --  These global variables are used by New_Copy_Tree. See description
   --  of the body of this subprogram for details. Global variables can be
   --  of the body of this subprogram for details. Global variables can be
   --  safely used by New_Copy_Tree, since there is no case of a recursive
   --  safely used by New_Copy_Tree, since there is no case of a recursive
   --  call from the processing inside New_Copy_Tree.
   --  call from the processing inside New_Copy_Tree.
 
 
   NCT_Hash_Threshhold : constant := 20;
   NCT_Hash_Threshhold : constant := 20;
   --  If there are more than this number of pairs of entries in the
   --  If there are more than this number of pairs of entries in the
   --  map, then Hash_Tables_Used will be set, and the hash tables will
   --  map, then Hash_Tables_Used will be set, and the hash tables will
   --  be initialized and used for the searches.
   --  be initialized and used for the searches.
 
 
   NCT_Hash_Tables_Used : Boolean := False;
   NCT_Hash_Tables_Used : Boolean := False;
   --  Set to True if hash tables are in use
   --  Set to True if hash tables are in use
 
 
   NCT_Table_Entries : Nat;
   NCT_Table_Entries : Nat;
   --  Count entries in table to see if threshhold is reached
   --  Count entries in table to see if threshhold is reached
 
 
   NCT_Hash_Table_Setup : Boolean := False;
   NCT_Hash_Table_Setup : Boolean := False;
   --  Set to True if hash table contains data. We set this True if we
   --  Set to True if hash table contains data. We set this True if we
   --  setup the hash table with data, and leave it set permanently
   --  setup the hash table with data, and leave it set permanently
   --  from then on, this is a signal that second and subsequent users
   --  from then on, this is a signal that second and subsequent users
   --  of the hash table must clear the old entries before reuse.
   --  of the hash table must clear the old entries before reuse.
 
 
   subtype NCT_Header_Num is Int range 0 .. 511;
   subtype NCT_Header_Num is Int range 0 .. 511;
   --  Defines range of headers in hash tables (512 headers)
   --  Defines range of headers in hash tables (512 headers)
 
 
   -----------------------
   -----------------------
   -- Local Subprograms --
   -- Local Subprograms --
   -----------------------
   -----------------------
 
 
   function Build_Component_Subtype
   function Build_Component_Subtype
     (C   : List_Id;
     (C   : List_Id;
      Loc : Source_Ptr;
      Loc : Source_Ptr;
      T   : Entity_Id) return Node_Id;
      T   : Entity_Id) return Node_Id;
   --  This function builds the subtype for Build_Actual_Subtype_Of_Component
   --  This function builds the subtype for Build_Actual_Subtype_Of_Component
   --  and Build_Discriminal_Subtype_Of_Component. C is a list of constraints,
   --  and Build_Discriminal_Subtype_Of_Component. C is a list of constraints,
   --  Loc is the source location, T is the original subtype.
   --  Loc is the source location, T is the original subtype.
 
 
   function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean;
   function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean;
   --  Subsidiary to Is_Fully_Initialized_Type. For an unconstrained type
   --  Subsidiary to Is_Fully_Initialized_Type. For an unconstrained type
   --  with discriminants whose default values are static, examine only the
   --  with discriminants whose default values are static, examine only the
   --  components in the selected variant to determine whether all of them
   --  components in the selected variant to determine whether all of them
   --  have a default.
   --  have a default.
 
 
   function Has_Null_Extension (T : Entity_Id) return Boolean;
   function Has_Null_Extension (T : Entity_Id) return Boolean;
   --  T is a derived tagged type. Check whether the type extension is null.
   --  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.
   --  If the parent type is fully initialized, T can be treated as such.
 
 
   ------------------------------
   ------------------------------
   --  Abstract_Interface_List --
   --  Abstract_Interface_List --
   ------------------------------
   ------------------------------
 
 
   function Abstract_Interface_List (Typ : Entity_Id) return List_Id is
   function Abstract_Interface_List (Typ : Entity_Id) return List_Id is
      Nod : Node_Id;
      Nod : Node_Id;
 
 
   begin
   begin
      if Is_Concurrent_Type (Typ) then
      if Is_Concurrent_Type (Typ) then
 
 
         --  If we are dealing with a synchronized subtype, go to the base
         --  If we are dealing with a synchronized subtype, go to the base
         --  type, whose declaration has the interface list.
         --  type, whose declaration has the interface list.
 
 
         --  Shouldn't this be Declaration_Node???
         --  Shouldn't this be Declaration_Node???
 
 
         Nod := Parent (Base_Type (Typ));
         Nod := Parent (Base_Type (Typ));
 
 
         if Nkind (Nod) = N_Full_Type_Declaration then
         if Nkind (Nod) = N_Full_Type_Declaration then
            return Empty_List;
            return Empty_List;
         end if;
         end if;
 
 
      elsif Ekind (Typ) = E_Record_Type_With_Private then
      elsif Ekind (Typ) = E_Record_Type_With_Private then
         if Nkind (Parent (Typ)) = N_Full_Type_Declaration then
         if Nkind (Parent (Typ)) = N_Full_Type_Declaration then
            Nod := Type_Definition (Parent (Typ));
            Nod := Type_Definition (Parent (Typ));
 
 
         elsif Nkind (Parent (Typ)) = N_Private_Type_Declaration then
         elsif Nkind (Parent (Typ)) = N_Private_Type_Declaration then
            if Present (Full_View (Typ)) then
            if Present (Full_View (Typ)) then
               Nod := Type_Definition (Parent (Full_View (Typ)));
               Nod := Type_Definition (Parent (Full_View (Typ)));
 
 
            --  If the full-view is not available we cannot do anything else
            --  If the full-view is not available we cannot do anything else
            --  here (the source has errors).
            --  here (the source has errors).
 
 
            else
            else
               return Empty_List;
               return Empty_List;
            end if;
            end if;
 
 
         --  Support for generic formals with interfaces is still missing ???
         --  Support for generic formals with interfaces is still missing ???
 
 
         elsif Nkind (Parent (Typ)) = N_Formal_Type_Declaration then
         elsif Nkind (Parent (Typ)) = N_Formal_Type_Declaration then
            return Empty_List;
            return Empty_List;
 
 
         else
         else
            pragma Assert
            pragma Assert
              (Nkind (Parent (Typ)) = N_Private_Extension_Declaration);
              (Nkind (Parent (Typ)) = N_Private_Extension_Declaration);
            Nod := Parent (Typ);
            Nod := Parent (Typ);
         end if;
         end if;
 
 
      elsif Ekind (Typ) = E_Record_Subtype then
      elsif Ekind (Typ) = E_Record_Subtype then
         Nod := Type_Definition (Parent (Etype (Typ)));
         Nod := Type_Definition (Parent (Etype (Typ)));
 
 
      elsif Ekind (Typ) = E_Record_Subtype_With_Private then
      elsif Ekind (Typ) = E_Record_Subtype_With_Private then
 
 
         --  Recurse, because parent may still be a private extension. Also
         --  Recurse, because parent may still be a private extension. Also
         --  note that the full view of the subtype or the full view of its
         --  note that the full view of the subtype or the full view of its
         --  base type may (both) be unavailable.
         --  base type may (both) be unavailable.
 
 
         return Abstract_Interface_List (Etype (Typ));
         return Abstract_Interface_List (Etype (Typ));
 
 
      else pragma Assert ((Ekind (Typ)) = E_Record_Type);
      else pragma Assert ((Ekind (Typ)) = E_Record_Type);
         if Nkind (Parent (Typ)) = N_Formal_Type_Declaration then
         if Nkind (Parent (Typ)) = N_Formal_Type_Declaration then
            Nod := Formal_Type_Definition (Parent (Typ));
            Nod := Formal_Type_Definition (Parent (Typ));
         else
         else
            Nod := Type_Definition (Parent (Typ));
            Nod := Type_Definition (Parent (Typ));
         end if;
         end if;
      end if;
      end if;
 
 
      return Interface_List (Nod);
      return Interface_List (Nod);
   end Abstract_Interface_List;
   end Abstract_Interface_List;
 
 
   --------------------------------
   --------------------------------
   -- Add_Access_Type_To_Process --
   -- Add_Access_Type_To_Process --
   --------------------------------
   --------------------------------
 
 
   procedure Add_Access_Type_To_Process (E : Entity_Id; A : Entity_Id) is
   procedure Add_Access_Type_To_Process (E : Entity_Id; A : Entity_Id) is
      L : Elist_Id;
      L : Elist_Id;
 
 
   begin
   begin
      Ensure_Freeze_Node (E);
      Ensure_Freeze_Node (E);
      L := Access_Types_To_Process (Freeze_Node (E));
      L := Access_Types_To_Process (Freeze_Node (E));
 
 
      if No (L) then
      if No (L) then
         L := New_Elmt_List;
         L := New_Elmt_List;
         Set_Access_Types_To_Process (Freeze_Node (E), L);
         Set_Access_Types_To_Process (Freeze_Node (E), L);
      end if;
      end if;
 
 
      Append_Elmt (A, L);
      Append_Elmt (A, L);
   end Add_Access_Type_To_Process;
   end Add_Access_Type_To_Process;
 
 
   ----------------------------
   ----------------------------
   -- Add_Global_Declaration --
   -- Add_Global_Declaration --
   ----------------------------
   ----------------------------
 
 
   procedure Add_Global_Declaration (N : Node_Id) is
   procedure Add_Global_Declaration (N : Node_Id) is
      Aux_Node : constant Node_Id := Aux_Decls_Node (Cunit (Current_Sem_Unit));
      Aux_Node : constant Node_Id := Aux_Decls_Node (Cunit (Current_Sem_Unit));
 
 
   begin
   begin
      if No (Declarations (Aux_Node)) then
      if No (Declarations (Aux_Node)) then
         Set_Declarations (Aux_Node, New_List);
         Set_Declarations (Aux_Node, New_List);
      end if;
      end if;
 
 
      Append_To (Declarations (Aux_Node), N);
      Append_To (Declarations (Aux_Node), N);
      Analyze (N);
      Analyze (N);
   end Add_Global_Declaration;
   end Add_Global_Declaration;
 
 
   -----------------------
   -----------------------
   -- Alignment_In_Bits --
   -- Alignment_In_Bits --
   -----------------------
   -----------------------
 
 
   function Alignment_In_Bits (E : Entity_Id) return Uint is
   function Alignment_In_Bits (E : Entity_Id) return Uint is
   begin
   begin
      return Alignment (E) * System_Storage_Unit;
      return Alignment (E) * System_Storage_Unit;
   end Alignment_In_Bits;
   end Alignment_In_Bits;
 
 
   -----------------------------------------
   -----------------------------------------
   -- Apply_Compile_Time_Constraint_Error --
   -- Apply_Compile_Time_Constraint_Error --
   -----------------------------------------
   -----------------------------------------
 
 
   procedure Apply_Compile_Time_Constraint_Error
   procedure Apply_Compile_Time_Constraint_Error
     (N      : Node_Id;
     (N      : Node_Id;
      Msg    : String;
      Msg    : String;
      Reason : RT_Exception_Code;
      Reason : RT_Exception_Code;
      Ent    : Entity_Id  := Empty;
      Ent    : Entity_Id  := Empty;
      Typ    : Entity_Id  := Empty;
      Typ    : Entity_Id  := Empty;
      Loc    : Source_Ptr := No_Location;
      Loc    : Source_Ptr := No_Location;
      Rep    : Boolean    := True;
      Rep    : Boolean    := True;
      Warn   : Boolean    := False)
      Warn   : Boolean    := False)
   is
   is
      Stat   : constant Boolean := Is_Static_Expression (N);
      Stat   : constant Boolean := Is_Static_Expression (N);
      R_Stat : constant Node_Id :=
      R_Stat : constant Node_Id :=
                 Make_Raise_Constraint_Error (Sloc (N), Reason => Reason);
                 Make_Raise_Constraint_Error (Sloc (N), Reason => Reason);
      Rtyp   : Entity_Id;
      Rtyp   : Entity_Id;
 
 
   begin
   begin
      if No (Typ) then
      if No (Typ) then
         Rtyp := Etype (N);
         Rtyp := Etype (N);
      else
      else
         Rtyp := Typ;
         Rtyp := Typ;
      end if;
      end if;
 
 
      Discard_Node
      Discard_Node
        (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn));
        (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn));
 
 
      if not Rep then
      if not Rep then
         return;
         return;
      end if;
      end if;
 
 
      --  Now we replace the node by an N_Raise_Constraint_Error node
      --  Now we replace the node by an N_Raise_Constraint_Error node
      --  This does not need reanalyzing, so set it as analyzed now.
      --  This does not need reanalyzing, so set it as analyzed now.
 
 
      Rewrite (N, R_Stat);
      Rewrite (N, R_Stat);
      Set_Analyzed (N, True);
      Set_Analyzed (N, True);
 
 
      Set_Etype (N, Rtyp);
      Set_Etype (N, Rtyp);
      Set_Raises_Constraint_Error (N);
      Set_Raises_Constraint_Error (N);
 
 
      --  Now deal with possible local raise handling
      --  Now deal with possible local raise handling
 
 
      Possible_Local_Raise (N, Standard_Constraint_Error);
      Possible_Local_Raise (N, Standard_Constraint_Error);
 
 
      --  If the original expression was marked as static, the result is
      --  If the original expression was marked as static, the result is
      --  still marked as static, but the Raises_Constraint_Error flag is
      --  still marked as static, but the Raises_Constraint_Error flag is
      --  always set so that further static evaluation is not attempted.
      --  always set so that further static evaluation is not attempted.
 
 
      if Stat then
      if Stat then
         Set_Is_Static_Expression (N);
         Set_Is_Static_Expression (N);
      end if;
      end if;
   end Apply_Compile_Time_Constraint_Error;
   end Apply_Compile_Time_Constraint_Error;
 
 
   --------------------------
   --------------------------
   -- Build_Actual_Subtype --
   -- Build_Actual_Subtype --
   --------------------------
   --------------------------
 
 
   function Build_Actual_Subtype
   function Build_Actual_Subtype
     (T : Entity_Id;
     (T : Entity_Id;
      N : Node_Or_Entity_Id) return Node_Id
      N : Node_Or_Entity_Id) return Node_Id
   is
   is
      Loc : Source_Ptr;
      Loc : Source_Ptr;
      --  Normally Sloc (N), but may point to corresponding body in some cases
      --  Normally Sloc (N), but may point to corresponding body in some cases
 
 
      Constraints : List_Id;
      Constraints : List_Id;
      Decl        : Node_Id;
      Decl        : Node_Id;
      Discr       : Entity_Id;
      Discr       : Entity_Id;
      Hi          : Node_Id;
      Hi          : Node_Id;
      Lo          : Node_Id;
      Lo          : Node_Id;
      Subt        : Entity_Id;
      Subt        : Entity_Id;
      Disc_Type   : Entity_Id;
      Disc_Type   : Entity_Id;
      Obj         : Node_Id;
      Obj         : Node_Id;
 
 
   begin
   begin
      Loc := Sloc (N);
      Loc := Sloc (N);
 
 
      if Nkind (N) = N_Defining_Identifier then
      if Nkind (N) = N_Defining_Identifier then
         Obj := New_Reference_To (N, Loc);
         Obj := New_Reference_To (N, Loc);
 
 
         --  If this is a formal parameter of a subprogram declaration, and
         --  If this is a formal parameter of a subprogram declaration, and
         --  we are compiling the body, we want the declaration for the
         --  we are compiling the body, we want the declaration for the
         --  actual subtype to carry the source position of the body, to
         --  actual subtype to carry the source position of the body, to
         --  prevent anomalies in gdb when stepping through the code.
         --  prevent anomalies in gdb when stepping through the code.
 
 
         if Is_Formal (N) then
         if Is_Formal (N) then
            declare
            declare
               Decl : constant Node_Id := Unit_Declaration_Node (Scope (N));
               Decl : constant Node_Id := Unit_Declaration_Node (Scope (N));
            begin
            begin
               if Nkind (Decl) = N_Subprogram_Declaration
               if Nkind (Decl) = N_Subprogram_Declaration
                 and then Present (Corresponding_Body (Decl))
                 and then Present (Corresponding_Body (Decl))
               then
               then
                  Loc := Sloc (Corresponding_Body (Decl));
                  Loc := Sloc (Corresponding_Body (Decl));
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
      else
      else
         Obj := N;
         Obj := N;
      end if;
      end if;
 
 
      if Is_Array_Type (T) then
      if Is_Array_Type (T) then
         Constraints := New_List;
         Constraints := New_List;
         for J in 1 .. Number_Dimensions (T) loop
         for J in 1 .. Number_Dimensions (T) loop
 
 
            --  Build an array subtype declaration with the nominal subtype and
            --  Build an array subtype declaration with the nominal subtype and
            --  the bounds of the actual. Add the declaration in front of the
            --  the bounds of the actual. Add the declaration in front of the
            --  local declarations for the subprogram, for analysis before any
            --  local declarations for the subprogram, for analysis before any
            --  reference to the formal in the body.
            --  reference to the formal in the body.
 
 
            Lo :=
            Lo :=
              Make_Attribute_Reference (Loc,
              Make_Attribute_Reference (Loc,
                Prefix         =>
                Prefix         =>
                  Duplicate_Subexpr_No_Checks (Obj, Name_Req => True),
                  Duplicate_Subexpr_No_Checks (Obj, Name_Req => True),
                Attribute_Name => Name_First,
                Attribute_Name => Name_First,
                Expressions    => New_List (
                Expressions    => New_List (
                  Make_Integer_Literal (Loc, J)));
                  Make_Integer_Literal (Loc, J)));
 
 
            Hi :=
            Hi :=
              Make_Attribute_Reference (Loc,
              Make_Attribute_Reference (Loc,
                Prefix         =>
                Prefix         =>
                  Duplicate_Subexpr_No_Checks (Obj, Name_Req => True),
                  Duplicate_Subexpr_No_Checks (Obj, Name_Req => True),
                Attribute_Name => Name_Last,
                Attribute_Name => Name_Last,
                Expressions    => New_List (
                Expressions    => New_List (
                  Make_Integer_Literal (Loc, J)));
                  Make_Integer_Literal (Loc, J)));
 
 
            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Append (Make_Range (Loc, Lo, Hi), Constraints);
         end loop;
         end loop;
 
 
      --  If the type has unknown discriminants there is no constrained
      --  If the type has unknown discriminants there is no constrained
      --  subtype to build. This is never called for a formal or for a
      --  subtype to build. This is never called for a formal or for a
      --  lhs, so returning the type is ok ???
      --  lhs, so returning the type is ok ???
 
 
      elsif Has_Unknown_Discriminants (T) then
      elsif Has_Unknown_Discriminants (T) then
         return T;
         return T;
 
 
      else
      else
         Constraints := New_List;
         Constraints := New_List;
 
 
         --  Type T is a generic derived type, inherit the discriminants from
         --  Type T is a generic derived type, inherit the discriminants from
         --  the parent type.
         --  the parent type.
 
 
         if Is_Private_Type (T)
         if Is_Private_Type (T)
           and then No (Full_View (T))
           and then No (Full_View (T))
 
 
            --  T was flagged as an error if it was declared as a formal
            --  T was flagged as an error if it was declared as a formal
            --  derived type with known discriminants. In this case there
            --  derived type with known discriminants. In this case there
            --  is no need to look at the parent type since T already carries
            --  is no need to look at the parent type since T already carries
            --  its own discriminants.
            --  its own discriminants.
 
 
           and then not Error_Posted (T)
           and then not Error_Posted (T)
         then
         then
            Disc_Type := Etype (Base_Type (T));
            Disc_Type := Etype (Base_Type (T));
         else
         else
            Disc_Type := T;
            Disc_Type := T;
         end if;
         end if;
 
 
         Discr := First_Discriminant (Disc_Type);
         Discr := First_Discriminant (Disc_Type);
         while Present (Discr) loop
         while Present (Discr) loop
            Append_To (Constraints,
            Append_To (Constraints,
              Make_Selected_Component (Loc,
              Make_Selected_Component (Loc,
                Prefix =>
                Prefix =>
                  Duplicate_Subexpr_No_Checks (Obj),
                  Duplicate_Subexpr_No_Checks (Obj),
                Selector_Name => New_Occurrence_Of (Discr, Loc)));
                Selector_Name => New_Occurrence_Of (Discr, Loc)));
            Next_Discriminant (Discr);
            Next_Discriminant (Discr);
         end loop;
         end loop;
      end if;
      end if;
 
 
      Subt :=
      Subt :=
        Make_Defining_Identifier (Loc,
        Make_Defining_Identifier (Loc,
          Chars => New_Internal_Name ('S'));
          Chars => New_Internal_Name ('S'));
      Set_Is_Internal (Subt);
      Set_Is_Internal (Subt);
 
 
      Decl :=
      Decl :=
        Make_Subtype_Declaration (Loc,
        Make_Subtype_Declaration (Loc,
          Defining_Identifier => Subt,
          Defining_Identifier => Subt,
          Subtype_Indication =>
          Subtype_Indication =>
            Make_Subtype_Indication (Loc,
            Make_Subtype_Indication (Loc,
              Subtype_Mark => New_Reference_To (T,  Loc),
              Subtype_Mark => New_Reference_To (T,  Loc),
              Constraint  =>
              Constraint  =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints => Constraints)));
                  Constraints => Constraints)));
 
 
      Mark_Rewrite_Insertion (Decl);
      Mark_Rewrite_Insertion (Decl);
      return Decl;
      return Decl;
   end Build_Actual_Subtype;
   end Build_Actual_Subtype;
 
 
   ---------------------------------------
   ---------------------------------------
   -- Build_Actual_Subtype_Of_Component --
   -- Build_Actual_Subtype_Of_Component --
   ---------------------------------------
   ---------------------------------------
 
 
   function Build_Actual_Subtype_Of_Component
   function Build_Actual_Subtype_Of_Component
     (T : Entity_Id;
     (T : Entity_Id;
      N : Node_Id) return Node_Id
      N : Node_Id) return Node_Id
   is
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Loc       : constant Source_Ptr := Sloc (N);
      P         : constant Node_Id    := Prefix (N);
      P         : constant Node_Id    := Prefix (N);
      D         : Elmt_Id;
      D         : Elmt_Id;
      Id        : Node_Id;
      Id        : Node_Id;
      Indx_Type : Entity_Id;
      Indx_Type : Entity_Id;
 
 
      Deaccessed_T : Entity_Id;
      Deaccessed_T : Entity_Id;
      --  This is either a copy of T, or if T is an access type, then it is
      --  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.
      --  the directly designated type of this access type.
 
 
      function Build_Actual_Array_Constraint return List_Id;
      function Build_Actual_Array_Constraint return List_Id;
      --  If one or more of the bounds of the component depends on
      --  If one or more of the bounds of the component depends on
      --  discriminants, build  actual constraint using the discriminants
      --  discriminants, build  actual constraint using the discriminants
      --  of the prefix.
      --  of the prefix.
 
 
      function Build_Actual_Record_Constraint return List_Id;
      function Build_Actual_Record_Constraint return List_Id;
      --  Similar to previous one, for discriminated components constrained
      --  Similar to previous one, for discriminated components constrained
      --  by the discriminant of the enclosing object.
      --  by the discriminant of the enclosing object.
 
 
      -----------------------------------
      -----------------------------------
      -- Build_Actual_Array_Constraint --
      -- Build_Actual_Array_Constraint --
      -----------------------------------
      -----------------------------------
 
 
      function Build_Actual_Array_Constraint return List_Id is
      function Build_Actual_Array_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         Constraints : constant List_Id := New_List;
         Indx        : Node_Id;
         Indx        : Node_Id;
         Hi          : Node_Id;
         Hi          : Node_Id;
         Lo          : Node_Id;
         Lo          : Node_Id;
         Old_Hi      : Node_Id;
         Old_Hi      : Node_Id;
         Old_Lo      : Node_Id;
         Old_Lo      : Node_Id;
 
 
      begin
      begin
         Indx := First_Index (Deaccessed_T);
         Indx := First_Index (Deaccessed_T);
         while Present (Indx) loop
         while Present (Indx) loop
            Old_Lo := Type_Low_Bound  (Etype (Indx));
            Old_Lo := Type_Low_Bound  (Etype (Indx));
            Old_Hi := Type_High_Bound (Etype (Indx));
            Old_Hi := Type_High_Bound (Etype (Indx));
 
 
            if Denotes_Discriminant (Old_Lo) then
            if Denotes_Discriminant (Old_Lo) then
               Lo :=
               Lo :=
                 Make_Selected_Component (Loc,
                 Make_Selected_Component (Loc,
                   Prefix => New_Copy_Tree (P),
                   Prefix => New_Copy_Tree (P),
                   Selector_Name => New_Occurrence_Of (Entity (Old_Lo), Loc));
                   Selector_Name => New_Occurrence_Of (Entity (Old_Lo), Loc));
 
 
            else
            else
               Lo := New_Copy_Tree (Old_Lo);
               Lo := New_Copy_Tree (Old_Lo);
 
 
               --  The new bound will be reanalyzed in the enclosing
               --  The new bound will be reanalyzed in the enclosing
               --  declaration. For literal bounds that come from a type
               --  declaration. For literal bounds that come from a type
               --  declaration, the type of the context must be imposed, so
               --  declaration, the type of the context must be imposed, so
               --  insure that analysis will take place. For non-universal
               --  insure that analysis will take place. For non-universal
               --  types this is not strictly necessary.
               --  types this is not strictly necessary.
 
 
               Set_Analyzed (Lo, False);
               Set_Analyzed (Lo, False);
            end if;
            end if;
 
 
            if Denotes_Discriminant (Old_Hi) then
            if Denotes_Discriminant (Old_Hi) then
               Hi :=
               Hi :=
                 Make_Selected_Component (Loc,
                 Make_Selected_Component (Loc,
                   Prefix => New_Copy_Tree (P),
                   Prefix => New_Copy_Tree (P),
                   Selector_Name => New_Occurrence_Of (Entity (Old_Hi), Loc));
                   Selector_Name => New_Occurrence_Of (Entity (Old_Hi), Loc));
 
 
            else
            else
               Hi := New_Copy_Tree (Old_Hi);
               Hi := New_Copy_Tree (Old_Hi);
               Set_Analyzed (Hi, False);
               Set_Analyzed (Hi, False);
            end if;
            end if;
 
 
            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Next_Index (Indx);
            Next_Index (Indx);
         end loop;
         end loop;
 
 
         return Constraints;
         return Constraints;
      end Build_Actual_Array_Constraint;
      end Build_Actual_Array_Constraint;
 
 
      ------------------------------------
      ------------------------------------
      -- Build_Actual_Record_Constraint --
      -- Build_Actual_Record_Constraint --
      ------------------------------------
      ------------------------------------
 
 
      function Build_Actual_Record_Constraint return List_Id is
      function Build_Actual_Record_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         Constraints : constant List_Id := New_List;
         D           : Elmt_Id;
         D           : Elmt_Id;
         D_Val       : Node_Id;
         D_Val       : Node_Id;
 
 
      begin
      begin
         D := First_Elmt (Discriminant_Constraint (Deaccessed_T));
         D := First_Elmt (Discriminant_Constraint (Deaccessed_T));
         while Present (D) loop
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
            if Denotes_Discriminant (Node (D)) then
               D_Val :=  Make_Selected_Component (Loc,
               D_Val :=  Make_Selected_Component (Loc,
                 Prefix => New_Copy_Tree (P),
                 Prefix => New_Copy_Tree (P),
                Selector_Name => New_Occurrence_Of (Entity (Node (D)), Loc));
                Selector_Name => New_Occurrence_Of (Entity (Node (D)), Loc));
 
 
            else
            else
               D_Val := New_Copy_Tree (Node (D));
               D_Val := New_Copy_Tree (Node (D));
            end if;
            end if;
 
 
            Append (D_Val, Constraints);
            Append (D_Val, Constraints);
            Next_Elmt (D);
            Next_Elmt (D);
         end loop;
         end loop;
 
 
         return Constraints;
         return Constraints;
      end Build_Actual_Record_Constraint;
      end Build_Actual_Record_Constraint;
 
 
   --  Start of processing for Build_Actual_Subtype_Of_Component
   --  Start of processing for Build_Actual_Subtype_Of_Component
 
 
   begin
   begin
      --  Why the test for Spec_Expression mode here???
      --  Why the test for Spec_Expression mode here???
 
 
      if In_Spec_Expression then
      if In_Spec_Expression then
         return Empty;
         return Empty;
 
 
      --  More comments for the rest of this body would be good ???
      --  More comments for the rest of this body would be good ???
 
 
      elsif Nkind (N) = N_Explicit_Dereference then
      elsif Nkind (N) = N_Explicit_Dereference then
         if Is_Composite_Type (T)
         if Is_Composite_Type (T)
           and then not Is_Constrained (T)
           and then not Is_Constrained (T)
           and then not (Is_Class_Wide_Type (T)
           and then not (Is_Class_Wide_Type (T)
                          and then Is_Constrained (Root_Type (T)))
                          and then Is_Constrained (Root_Type (T)))
           and then not Has_Unknown_Discriminants (T)
           and then not Has_Unknown_Discriminants (T)
         then
         then
            --  If the type of the dereference is already constrained, it
            --  If the type of the dereference is already constrained, it
            --  is an actual subtype.
            --  is an actual subtype.
 
 
            if Is_Array_Type (Etype (N))
            if Is_Array_Type (Etype (N))
              and then Is_Constrained (Etype (N))
              and then Is_Constrained (Etype (N))
            then
            then
               return Empty;
               return Empty;
            else
            else
               Remove_Side_Effects (P);
               Remove_Side_Effects (P);
               return Build_Actual_Subtype (T, N);
               return Build_Actual_Subtype (T, N);
            end if;
            end if;
         else
         else
            return Empty;
            return Empty;
         end if;
         end if;
      end if;
      end if;
 
 
      if Ekind (T) = E_Access_Subtype then
      if Ekind (T) = E_Access_Subtype then
         Deaccessed_T := Designated_Type (T);
         Deaccessed_T := Designated_Type (T);
      else
      else
         Deaccessed_T := T;
         Deaccessed_T := T;
      end if;
      end if;
 
 
      if Ekind (Deaccessed_T) = E_Array_Subtype then
      if Ekind (Deaccessed_T) = E_Array_Subtype then
         Id := First_Index (Deaccessed_T);
         Id := First_Index (Deaccessed_T);
         while Present (Id) loop
         while Present (Id) loop
            Indx_Type := Underlying_Type (Etype (Id));
            Indx_Type := Underlying_Type (Etype (Id));
 
 
            if Denotes_Discriminant (Type_Low_Bound  (Indx_Type))
            if Denotes_Discriminant (Type_Low_Bound  (Indx_Type))
                 or else
                 or else
               Denotes_Discriminant (Type_High_Bound (Indx_Type))
               Denotes_Discriminant (Type_High_Bound (Indx_Type))
            then
            then
               Remove_Side_Effects (P);
               Remove_Side_Effects (P);
               return
               return
                 Build_Component_Subtype
                 Build_Component_Subtype
                   (Build_Actual_Array_Constraint, Loc, Base_Type (T));
                   (Build_Actual_Array_Constraint, Loc, Base_Type (T));
            end if;
            end if;
 
 
            Next_Index (Id);
            Next_Index (Id);
         end loop;
         end loop;
 
 
      elsif Is_Composite_Type (Deaccessed_T)
      elsif Is_Composite_Type (Deaccessed_T)
        and then Has_Discriminants (Deaccessed_T)
        and then Has_Discriminants (Deaccessed_T)
        and then not Has_Unknown_Discriminants (Deaccessed_T)
        and then not Has_Unknown_Discriminants (Deaccessed_T)
      then
      then
         D := First_Elmt (Discriminant_Constraint (Deaccessed_T));
         D := First_Elmt (Discriminant_Constraint (Deaccessed_T));
         while Present (D) loop
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
            if Denotes_Discriminant (Node (D)) then
               Remove_Side_Effects (P);
               Remove_Side_Effects (P);
               return
               return
                 Build_Component_Subtype (
                 Build_Component_Subtype (
                   Build_Actual_Record_Constraint, Loc, Base_Type (T));
                   Build_Actual_Record_Constraint, Loc, Base_Type (T));
            end if;
            end if;
 
 
            Next_Elmt (D);
            Next_Elmt (D);
         end loop;
         end loop;
      end if;
      end if;
 
 
      --  If none of the above, the actual and nominal subtypes are the same
      --  If none of the above, the actual and nominal subtypes are the same
 
 
      return Empty;
      return Empty;
   end Build_Actual_Subtype_Of_Component;
   end Build_Actual_Subtype_Of_Component;
 
 
   -----------------------------
   -----------------------------
   -- Build_Component_Subtype --
   -- Build_Component_Subtype --
   -----------------------------
   -----------------------------
 
 
   function Build_Component_Subtype
   function Build_Component_Subtype
     (C   : List_Id;
     (C   : List_Id;
      Loc : Source_Ptr;
      Loc : Source_Ptr;
      T   : Entity_Id) return Node_Id
      T   : Entity_Id) return Node_Id
   is
   is
      Subt : Entity_Id;
      Subt : Entity_Id;
      Decl : Node_Id;
      Decl : Node_Id;
 
 
   begin
   begin
      --  Unchecked_Union components do not require component subtypes
      --  Unchecked_Union components do not require component subtypes
 
 
      if Is_Unchecked_Union (T) then
      if Is_Unchecked_Union (T) then
         return Empty;
         return Empty;
      end if;
      end if;
 
 
      Subt :=
      Subt :=
        Make_Defining_Identifier (Loc,
        Make_Defining_Identifier (Loc,
          Chars => New_Internal_Name ('S'));
          Chars => New_Internal_Name ('S'));
      Set_Is_Internal (Subt);
      Set_Is_Internal (Subt);
 
 
      Decl :=
      Decl :=
        Make_Subtype_Declaration (Loc,
        Make_Subtype_Declaration (Loc,
          Defining_Identifier => Subt,
          Defining_Identifier => Subt,
          Subtype_Indication =>
          Subtype_Indication =>
            Make_Subtype_Indication (Loc,
            Make_Subtype_Indication (Loc,
              Subtype_Mark => New_Reference_To (Base_Type (T),  Loc),
              Subtype_Mark => New_Reference_To (Base_Type (T),  Loc),
              Constraint  =>
              Constraint  =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints => C)));
                  Constraints => C)));
 
 
      Mark_Rewrite_Insertion (Decl);
      Mark_Rewrite_Insertion (Decl);
      return Decl;
      return Decl;
   end Build_Component_Subtype;
   end Build_Component_Subtype;
 
 
   ---------------------------
   ---------------------------
   -- Build_Default_Subtype --
   -- Build_Default_Subtype --
   ---------------------------
   ---------------------------
 
 
   function Build_Default_Subtype
   function Build_Default_Subtype
     (T : Entity_Id;
     (T : Entity_Id;
      N : Node_Id) return Entity_Id
      N : Node_Id) return Entity_Id
   is
   is
      Loc  : constant Source_Ptr := Sloc (N);
      Loc  : constant Source_Ptr := Sloc (N);
      Disc : Entity_Id;
      Disc : Entity_Id;
 
 
   begin
   begin
      if not Has_Discriminants (T) or else Is_Constrained (T) then
      if not Has_Discriminants (T) or else Is_Constrained (T) then
         return T;
         return T;
      end if;
      end if;
 
 
      Disc := First_Discriminant (T);
      Disc := First_Discriminant (T);
 
 
      if No (Discriminant_Default_Value (Disc)) then
      if No (Discriminant_Default_Value (Disc)) then
         return T;
         return T;
      end if;
      end if;
 
 
      declare
      declare
         Act : constant Entity_Id :=
         Act : constant Entity_Id :=
                 Make_Defining_Identifier (Loc,
                 Make_Defining_Identifier (Loc,
                   Chars => New_Internal_Name ('S'));
                   Chars => New_Internal_Name ('S'));
 
 
         Constraints : constant List_Id := New_List;
         Constraints : constant List_Id := New_List;
         Decl        : Node_Id;
         Decl        : Node_Id;
 
 
      begin
      begin
         while Present (Disc) loop
         while Present (Disc) loop
            Append_To (Constraints,
            Append_To (Constraints,
              New_Copy_Tree (Discriminant_Default_Value (Disc)));
              New_Copy_Tree (Discriminant_Default_Value (Disc)));
            Next_Discriminant (Disc);
            Next_Discriminant (Disc);
         end loop;
         end loop;
 
 
         Decl :=
         Decl :=
           Make_Subtype_Declaration (Loc,
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => Act,
             Defining_Identifier => Act,
             Subtype_Indication =>
             Subtype_Indication =>
               Make_Subtype_Indication (Loc,
               Make_Subtype_Indication (Loc,
                 Subtype_Mark => New_Occurrence_Of (T, Loc),
                 Subtype_Mark => New_Occurrence_Of (T, Loc),
                 Constraint =>
                 Constraint =>
                   Make_Index_Or_Discriminant_Constraint (Loc,
                   Make_Index_Or_Discriminant_Constraint (Loc,
                     Constraints => Constraints)));
                     Constraints => Constraints)));
 
 
         Insert_Action (N, Decl);
         Insert_Action (N, Decl);
         Analyze (Decl);
         Analyze (Decl);
         return Act;
         return Act;
      end;
      end;
   end Build_Default_Subtype;
   end Build_Default_Subtype;
 
 
   --------------------------------------------
   --------------------------------------------
   -- Build_Discriminal_Subtype_Of_Component --
   -- Build_Discriminal_Subtype_Of_Component --
   --------------------------------------------
   --------------------------------------------
 
 
   function Build_Discriminal_Subtype_Of_Component
   function Build_Discriminal_Subtype_Of_Component
     (T : Entity_Id) return Node_Id
     (T : Entity_Id) return Node_Id
   is
   is
      Loc : constant Source_Ptr := Sloc (T);
      Loc : constant Source_Ptr := Sloc (T);
      D   : Elmt_Id;
      D   : Elmt_Id;
      Id  : Node_Id;
      Id  : Node_Id;
 
 
      function Build_Discriminal_Array_Constraint return List_Id;
      function Build_Discriminal_Array_Constraint return List_Id;
      --  If one or more of the bounds of the component depends on
      --  If one or more of the bounds of the component depends on
      --  discriminants, build  actual constraint using the discriminants
      --  discriminants, build  actual constraint using the discriminants
      --  of the prefix.
      --  of the prefix.
 
 
      function Build_Discriminal_Record_Constraint return List_Id;
      function Build_Discriminal_Record_Constraint return List_Id;
      --  Similar to previous one, for discriminated components constrained
      --  Similar to previous one, for discriminated components constrained
      --  by the discriminant of the enclosing object.
      --  by the discriminant of the enclosing object.
 
 
      ----------------------------------------
      ----------------------------------------
      -- Build_Discriminal_Array_Constraint --
      -- Build_Discriminal_Array_Constraint --
      ----------------------------------------
      ----------------------------------------
 
 
      function Build_Discriminal_Array_Constraint return List_Id is
      function Build_Discriminal_Array_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         Constraints : constant List_Id := New_List;
         Indx        : Node_Id;
         Indx        : Node_Id;
         Hi          : Node_Id;
         Hi          : Node_Id;
         Lo          : Node_Id;
         Lo          : Node_Id;
         Old_Hi      : Node_Id;
         Old_Hi      : Node_Id;
         Old_Lo      : Node_Id;
         Old_Lo      : Node_Id;
 
 
      begin
      begin
         Indx := First_Index (T);
         Indx := First_Index (T);
         while Present (Indx) loop
         while Present (Indx) loop
            Old_Lo := Type_Low_Bound  (Etype (Indx));
            Old_Lo := Type_Low_Bound  (Etype (Indx));
            Old_Hi := Type_High_Bound (Etype (Indx));
            Old_Hi := Type_High_Bound (Etype (Indx));
 
 
            if Denotes_Discriminant (Old_Lo) then
            if Denotes_Discriminant (Old_Lo) then
               Lo := New_Occurrence_Of (Discriminal (Entity (Old_Lo)), Loc);
               Lo := New_Occurrence_Of (Discriminal (Entity (Old_Lo)), Loc);
 
 
            else
            else
               Lo := New_Copy_Tree (Old_Lo);
               Lo := New_Copy_Tree (Old_Lo);
            end if;
            end if;
 
 
            if Denotes_Discriminant (Old_Hi) then
            if Denotes_Discriminant (Old_Hi) then
               Hi := New_Occurrence_Of (Discriminal (Entity (Old_Hi)), Loc);
               Hi := New_Occurrence_Of (Discriminal (Entity (Old_Hi)), Loc);
 
 
            else
            else
               Hi := New_Copy_Tree (Old_Hi);
               Hi := New_Copy_Tree (Old_Hi);
            end if;
            end if;
 
 
            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Append (Make_Range (Loc, Lo, Hi), Constraints);
            Next_Index (Indx);
            Next_Index (Indx);
         end loop;
         end loop;
 
 
         return Constraints;
         return Constraints;
      end Build_Discriminal_Array_Constraint;
      end Build_Discriminal_Array_Constraint;
 
 
      -----------------------------------------
      -----------------------------------------
      -- Build_Discriminal_Record_Constraint --
      -- Build_Discriminal_Record_Constraint --
      -----------------------------------------
      -----------------------------------------
 
 
      function Build_Discriminal_Record_Constraint return List_Id is
      function Build_Discriminal_Record_Constraint return List_Id is
         Constraints : constant List_Id := New_List;
         Constraints : constant List_Id := New_List;
         D           : Elmt_Id;
         D           : Elmt_Id;
         D_Val       : Node_Id;
         D_Val       : Node_Id;
 
 
      begin
      begin
         D := First_Elmt (Discriminant_Constraint (T));
         D := First_Elmt (Discriminant_Constraint (T));
         while Present (D) loop
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
            if Denotes_Discriminant (Node (D)) then
               D_Val :=
               D_Val :=
                 New_Occurrence_Of (Discriminal (Entity (Node (D))), Loc);
                 New_Occurrence_Of (Discriminal (Entity (Node (D))), Loc);
 
 
            else
            else
               D_Val := New_Copy_Tree (Node (D));
               D_Val := New_Copy_Tree (Node (D));
            end if;
            end if;
 
 
            Append (D_Val, Constraints);
            Append (D_Val, Constraints);
            Next_Elmt (D);
            Next_Elmt (D);
         end loop;
         end loop;
 
 
         return Constraints;
         return Constraints;
      end Build_Discriminal_Record_Constraint;
      end Build_Discriminal_Record_Constraint;
 
 
   --  Start of processing for Build_Discriminal_Subtype_Of_Component
   --  Start of processing for Build_Discriminal_Subtype_Of_Component
 
 
   begin
   begin
      if Ekind (T) = E_Array_Subtype then
      if Ekind (T) = E_Array_Subtype then
         Id := First_Index (T);
         Id := First_Index (T);
         while Present (Id) loop
         while Present (Id) loop
            if Denotes_Discriminant (Type_Low_Bound  (Etype (Id))) or else
            if Denotes_Discriminant (Type_Low_Bound  (Etype (Id))) or else
               Denotes_Discriminant (Type_High_Bound (Etype (Id)))
               Denotes_Discriminant (Type_High_Bound (Etype (Id)))
            then
            then
               return Build_Component_Subtype
               return Build_Component_Subtype
                 (Build_Discriminal_Array_Constraint, Loc, T);
                 (Build_Discriminal_Array_Constraint, Loc, T);
            end if;
            end if;
 
 
            Next_Index (Id);
            Next_Index (Id);
         end loop;
         end loop;
 
 
      elsif Ekind (T) = E_Record_Subtype
      elsif Ekind (T) = E_Record_Subtype
        and then Has_Discriminants (T)
        and then Has_Discriminants (T)
        and then not Has_Unknown_Discriminants (T)
        and then not Has_Unknown_Discriminants (T)
      then
      then
         D := First_Elmt (Discriminant_Constraint (T));
         D := First_Elmt (Discriminant_Constraint (T));
         while Present (D) loop
         while Present (D) loop
            if Denotes_Discriminant (Node (D)) then
            if Denotes_Discriminant (Node (D)) then
               return Build_Component_Subtype
               return Build_Component_Subtype
                 (Build_Discriminal_Record_Constraint, Loc, T);
                 (Build_Discriminal_Record_Constraint, Loc, T);
            end if;
            end if;
 
 
            Next_Elmt (D);
            Next_Elmt (D);
         end loop;
         end loop;
      end if;
      end if;
 
 
      --  If none of the above, the actual and nominal subtypes are the same
      --  If none of the above, the actual and nominal subtypes are the same
 
 
      return Empty;
      return Empty;
   end Build_Discriminal_Subtype_Of_Component;
   end Build_Discriminal_Subtype_Of_Component;
 
 
   ------------------------------
   ------------------------------
   -- Build_Elaboration_Entity --
   -- Build_Elaboration_Entity --
   ------------------------------
   ------------------------------
 
 
   procedure Build_Elaboration_Entity (N : Node_Id; Spec_Id : Entity_Id) is
   procedure Build_Elaboration_Entity (N : Node_Id; Spec_Id : Entity_Id) is
      Loc      : constant Source_Ptr := Sloc (N);
      Loc      : constant Source_Ptr := Sloc (N);
      Decl     : Node_Id;
      Decl     : Node_Id;
      Elab_Ent : Entity_Id;
      Elab_Ent : Entity_Id;
 
 
      procedure Set_Package_Name (Ent : Entity_Id);
      procedure Set_Package_Name (Ent : Entity_Id);
      --  Given an entity, sets the fully qualified name of the entity in
      --  Given an entity, sets the fully qualified name of the entity in
      --  Name_Buffer, with components separated by double underscores. This
      --  Name_Buffer, with components separated by double underscores. This
      --  is a recursive routine that climbs the scope chain to Standard.
      --  is a recursive routine that climbs the scope chain to Standard.
 
 
      ----------------------
      ----------------------
      -- Set_Package_Name --
      -- Set_Package_Name --
      ----------------------
      ----------------------
 
 
      procedure Set_Package_Name (Ent : Entity_Id) is
      procedure Set_Package_Name (Ent : Entity_Id) is
      begin
      begin
         if Scope (Ent) /= Standard_Standard then
         if Scope (Ent) /= Standard_Standard then
            Set_Package_Name (Scope (Ent));
            Set_Package_Name (Scope (Ent));
 
 
            declare
            declare
               Nam : constant String := Get_Name_String (Chars (Ent));
               Nam : constant String := Get_Name_String (Chars (Ent));
            begin
            begin
               Name_Buffer (Name_Len + 1) := '_';
               Name_Buffer (Name_Len + 1) := '_';
               Name_Buffer (Name_Len + 2) := '_';
               Name_Buffer (Name_Len + 2) := '_';
               Name_Buffer (Name_Len + 3 .. Name_Len + Nam'Length + 2) := Nam;
               Name_Buffer (Name_Len + 3 .. Name_Len + Nam'Length + 2) := Nam;
               Name_Len := Name_Len + Nam'Length + 2;
               Name_Len := Name_Len + Nam'Length + 2;
            end;
            end;
 
 
         else
         else
            Get_Name_String (Chars (Ent));
            Get_Name_String (Chars (Ent));
         end if;
         end if;
      end Set_Package_Name;
      end Set_Package_Name;
 
 
   --  Start of processing for Build_Elaboration_Entity
   --  Start of processing for Build_Elaboration_Entity
 
 
   begin
   begin
      --  Ignore if already constructed
      --  Ignore if already constructed
 
 
      if Present (Elaboration_Entity (Spec_Id)) then
      if Present (Elaboration_Entity (Spec_Id)) then
         return;
         return;
      end if;
      end if;
 
 
      --  Construct name of elaboration entity as xxx_E, where xxx is the unit
      --  Construct name of elaboration entity as xxx_E, where xxx is the unit
      --  name with dots replaced by double underscore. We have to manually
      --  name with dots replaced by double underscore. We have to manually
      --  construct this name, since it will be elaborated in the outer scope,
      --  construct this name, since it will be elaborated in the outer scope,
      --  and thus will not have the unit name automatically prepended.
      --  and thus will not have the unit name automatically prepended.
 
 
      Set_Package_Name (Spec_Id);
      Set_Package_Name (Spec_Id);
 
 
      --  Append _E
      --  Append _E
 
 
      Name_Buffer (Name_Len + 1) := '_';
      Name_Buffer (Name_Len + 1) := '_';
      Name_Buffer (Name_Len + 2) := 'E';
      Name_Buffer (Name_Len + 2) := 'E';
      Name_Len := Name_Len + 2;
      Name_Len := Name_Len + 2;
 
 
      --  Create elaboration flag
      --  Create elaboration flag
 
 
      Elab_Ent :=
      Elab_Ent :=
        Make_Defining_Identifier (Loc, Chars => Name_Find);
        Make_Defining_Identifier (Loc, Chars => Name_Find);
      Set_Elaboration_Entity (Spec_Id, Elab_Ent);
      Set_Elaboration_Entity (Spec_Id, Elab_Ent);
 
 
      Decl :=
      Decl :=
         Make_Object_Declaration (Loc,
         Make_Object_Declaration (Loc,
           Defining_Identifier => Elab_Ent,
           Defining_Identifier => Elab_Ent,
           Object_Definition   =>
           Object_Definition   =>
             New_Occurrence_Of (Standard_Boolean, Loc),
             New_Occurrence_Of (Standard_Boolean, Loc),
           Expression          =>
           Expression          =>
             New_Occurrence_Of (Standard_False, Loc));
             New_Occurrence_Of (Standard_False, Loc));
 
 
      Push_Scope (Standard_Standard);
      Push_Scope (Standard_Standard);
      Add_Global_Declaration (Decl);
      Add_Global_Declaration (Decl);
      Pop_Scope;
      Pop_Scope;
 
 
      --  Reset True_Constant indication, since we will indeed assign a value
      --  Reset True_Constant indication, since we will indeed assign a value
      --  to the variable in the binder main. We also kill the Current_Value
      --  to the variable in the binder main. We also kill the Current_Value
      --  and Last_Assignment fields for the same reason.
      --  and Last_Assignment fields for the same reason.
 
 
      Set_Is_True_Constant (Elab_Ent, False);
      Set_Is_True_Constant (Elab_Ent, False);
      Set_Current_Value    (Elab_Ent, Empty);
      Set_Current_Value    (Elab_Ent, Empty);
      Set_Last_Assignment  (Elab_Ent, Empty);
      Set_Last_Assignment  (Elab_Ent, Empty);
 
 
      --  We do not want any further qualification of the name (if we did
      --  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
      --  not do this, we would pick up the name of the generic package
      --  in the case of a library level generic instantiation).
      --  in the case of a library level generic instantiation).
 
 
      Set_Has_Qualified_Name       (Elab_Ent);
      Set_Has_Qualified_Name       (Elab_Ent);
      Set_Has_Fully_Qualified_Name (Elab_Ent);
      Set_Has_Fully_Qualified_Name (Elab_Ent);
   end Build_Elaboration_Entity;
   end Build_Elaboration_Entity;
 
 
   -----------------------------------
   -----------------------------------
   -- Cannot_Raise_Constraint_Error --
   -- Cannot_Raise_Constraint_Error --
   -----------------------------------
   -----------------------------------
 
 
   function Cannot_Raise_Constraint_Error (Expr : Node_Id) return Boolean is
   function Cannot_Raise_Constraint_Error (Expr : Node_Id) return Boolean is
   begin
   begin
      if Compile_Time_Known_Value (Expr) then
      if Compile_Time_Known_Value (Expr) then
         return True;
         return True;
 
 
      elsif Do_Range_Check (Expr) then
      elsif Do_Range_Check (Expr) then
         return False;
         return False;
 
 
      elsif Raises_Constraint_Error (Expr) then
      elsif Raises_Constraint_Error (Expr) then
         return False;
         return False;
 
 
      else
      else
         case Nkind (Expr) is
         case Nkind (Expr) is
            when N_Identifier =>
            when N_Identifier =>
               return True;
               return True;
 
 
            when N_Expanded_Name =>
            when N_Expanded_Name =>
               return True;
               return True;
 
 
            when N_Selected_Component =>
            when N_Selected_Component =>
               return not Do_Discriminant_Check (Expr);
               return not Do_Discriminant_Check (Expr);
 
 
            when N_Attribute_Reference =>
            when N_Attribute_Reference =>
               if Do_Overflow_Check (Expr) then
               if Do_Overflow_Check (Expr) then
                  return False;
                  return False;
 
 
               elsif No (Expressions (Expr)) then
               elsif No (Expressions (Expr)) then
                  return True;
                  return True;
 
 
               else
               else
                  declare
                  declare
                     N : Node_Id;
                     N : Node_Id;
 
 
                  begin
                  begin
                     N := First (Expressions (Expr));
                     N := First (Expressions (Expr));
                     while Present (N) loop
                     while Present (N) loop
                        if Cannot_Raise_Constraint_Error (N) then
                        if Cannot_Raise_Constraint_Error (N) then
                           Next (N);
                           Next (N);
                        else
                        else
                           return False;
                           return False;
                        end if;
                        end if;
                     end loop;
                     end loop;
 
 
                     return True;
                     return True;
                  end;
                  end;
               end if;
               end if;
 
 
            when N_Type_Conversion =>
            when N_Type_Conversion =>
               if Do_Overflow_Check (Expr)
               if Do_Overflow_Check (Expr)
                 or else Do_Length_Check (Expr)
                 or else Do_Length_Check (Expr)
                 or else Do_Tag_Check (Expr)
                 or else Do_Tag_Check (Expr)
               then
               then
                  return False;
                  return False;
               else
               else
                  return
                  return
                    Cannot_Raise_Constraint_Error (Expression (Expr));
                    Cannot_Raise_Constraint_Error (Expression (Expr));
               end if;
               end if;
 
 
            when N_Unchecked_Type_Conversion =>
            when N_Unchecked_Type_Conversion =>
               return Cannot_Raise_Constraint_Error (Expression (Expr));
               return Cannot_Raise_Constraint_Error (Expression (Expr));
 
 
            when N_Unary_Op =>
            when N_Unary_Op =>
               if Do_Overflow_Check (Expr) then
               if Do_Overflow_Check (Expr) then
                  return False;
                  return False;
               else
               else
                  return
                  return
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
               end if;
               end if;
 
 
            when N_Op_Divide |
            when N_Op_Divide |
                 N_Op_Mod    |
                 N_Op_Mod    |
                 N_Op_Rem
                 N_Op_Rem
            =>
            =>
               if Do_Division_Check (Expr)
               if Do_Division_Check (Expr)
                 or else Do_Overflow_Check (Expr)
                 or else Do_Overflow_Check (Expr)
               then
               then
                  return False;
                  return False;
               else
               else
                  return
                  return
                    Cannot_Raise_Constraint_Error (Left_Opnd (Expr))
                    Cannot_Raise_Constraint_Error (Left_Opnd (Expr))
                      and then
                      and then
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
               end if;
               end if;
 
 
            when N_Op_Add                    |
            when N_Op_Add                    |
                 N_Op_And                    |
                 N_Op_And                    |
                 N_Op_Concat                 |
                 N_Op_Concat                 |
                 N_Op_Eq                     |
                 N_Op_Eq                     |
                 N_Op_Expon                  |
                 N_Op_Expon                  |
                 N_Op_Ge                     |
                 N_Op_Ge                     |
                 N_Op_Gt                     |
                 N_Op_Gt                     |
                 N_Op_Le                     |
                 N_Op_Le                     |
                 N_Op_Lt                     |
                 N_Op_Lt                     |
                 N_Op_Multiply               |
                 N_Op_Multiply               |
                 N_Op_Ne                     |
                 N_Op_Ne                     |
                 N_Op_Or                     |
                 N_Op_Or                     |
                 N_Op_Rotate_Left            |
                 N_Op_Rotate_Left            |
                 N_Op_Rotate_Right           |
                 N_Op_Rotate_Right           |
                 N_Op_Shift_Left             |
                 N_Op_Shift_Left             |
                 N_Op_Shift_Right            |
                 N_Op_Shift_Right            |
                 N_Op_Shift_Right_Arithmetic |
                 N_Op_Shift_Right_Arithmetic |
                 N_Op_Subtract               |
                 N_Op_Subtract               |
                 N_Op_Xor
                 N_Op_Xor
            =>
            =>
               if Do_Overflow_Check (Expr) then
               if Do_Overflow_Check (Expr) then
                  return False;
                  return False;
               else
               else
                  return
                  return
                    Cannot_Raise_Constraint_Error (Left_Opnd (Expr))
                    Cannot_Raise_Constraint_Error (Left_Opnd (Expr))
                      and then
                      and then
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
                    Cannot_Raise_Constraint_Error (Right_Opnd (Expr));
               end if;
               end if;
 
 
            when others =>
            when others =>
               return False;
               return False;
         end case;
         end case;
      end if;
      end if;
   end Cannot_Raise_Constraint_Error;
   end Cannot_Raise_Constraint_Error;
 
 
   -----------------------------------------
   -----------------------------------------
   -- Check_Dynamically_Tagged_Expression --
   -- Check_Dynamically_Tagged_Expression --
   -----------------------------------------
   -----------------------------------------
 
 
   procedure Check_Dynamically_Tagged_Expression
   procedure Check_Dynamically_Tagged_Expression
     (Expr        : Node_Id;
     (Expr        : Node_Id;
      Typ         : Entity_Id;
      Typ         : Entity_Id;
      Related_Nod : Node_Id)
      Related_Nod : Node_Id)
   is
   is
   begin
   begin
      pragma Assert (Is_Tagged_Type (Typ));
      pragma Assert (Is_Tagged_Type (Typ));
 
 
      --  In order to avoid spurious errors when analyzing the expanded code,
      --  In order to avoid spurious errors when analyzing the expanded code,
      --  this check is done only for nodes that come from source and for
      --  this check is done only for nodes that come from source and for
      --  actuals of generic instantiations.
      --  actuals of generic instantiations.
 
 
      if (Comes_From_Source (Related_Nod)
      if (Comes_From_Source (Related_Nod)
           or else In_Generic_Actual (Expr))
           or else In_Generic_Actual (Expr))
        and then (Is_Class_Wide_Type (Etype (Expr))
        and then (Is_Class_Wide_Type (Etype (Expr))
                   or else Is_Dynamically_Tagged (Expr))
                   or else Is_Dynamically_Tagged (Expr))
        and then Is_Tagged_Type (Typ)
        and then Is_Tagged_Type (Typ)
        and then not Is_Class_Wide_Type (Typ)
        and then not Is_Class_Wide_Type (Typ)
      then
      then
         Error_Msg_N ("dynamically tagged expression not allowed!", Expr);
         Error_Msg_N ("dynamically tagged expression not allowed!", Expr);
      end if;
      end if;
   end Check_Dynamically_Tagged_Expression;
   end Check_Dynamically_Tagged_Expression;
 
 
   --------------------------
   --------------------------
   -- Check_Fully_Declared --
   -- Check_Fully_Declared --
   --------------------------
   --------------------------
 
 
   procedure Check_Fully_Declared (T : Entity_Id; N : Node_Id) is
   procedure Check_Fully_Declared (T : Entity_Id; N : Node_Id) is
   begin
   begin
      if Ekind (T) = E_Incomplete_Type then
      if Ekind (T) = E_Incomplete_Type then
 
 
         --  Ada 2005 (AI-50217): If the type is available through a limited
         --  Ada 2005 (AI-50217): If the type is available through a limited
         --  with_clause, verify that its full view has been analyzed.
         --  with_clause, verify that its full view has been analyzed.
 
 
         if From_With_Type (T)
         if From_With_Type (T)
           and then Present (Non_Limited_View (T))
           and then Present (Non_Limited_View (T))
           and then Ekind (Non_Limited_View (T)) /= E_Incomplete_Type
           and then Ekind (Non_Limited_View (T)) /= E_Incomplete_Type
         then
         then
            --  The non-limited view is fully declared
            --  The non-limited view is fully declared
            null;
            null;
 
 
         else
         else
            Error_Msg_NE
            Error_Msg_NE
              ("premature usage of incomplete}", N, First_Subtype (T));
              ("premature usage of incomplete}", N, First_Subtype (T));
         end if;
         end if;
 
 
      --  Need comments for these tests ???
      --  Need comments for these tests ???
 
 
      elsif Has_Private_Component (T)
      elsif Has_Private_Component (T)
        and then not Is_Generic_Type (Root_Type (T))
        and then not Is_Generic_Type (Root_Type (T))
        and then not In_Spec_Expression
        and then not In_Spec_Expression
      then
      then
         --  Special case: if T is the anonymous type created for a single
         --  Special case: if T is the anonymous type created for a single
         --  task or protected object, use the name of the source object.
         --  task or protected object, use the name of the source object.
 
 
         if Is_Concurrent_Type (T)
         if Is_Concurrent_Type (T)
           and then not Comes_From_Source (T)
           and then not Comes_From_Source (T)
           and then Nkind (N) = N_Object_Declaration
           and then Nkind (N) = N_Object_Declaration
         then
         then
            Error_Msg_NE ("type of& has incomplete component", N,
            Error_Msg_NE ("type of& has incomplete component", N,
              Defining_Identifier (N));
              Defining_Identifier (N));
 
 
         else
         else
            Error_Msg_NE
            Error_Msg_NE
              ("premature usage of incomplete}", N, First_Subtype (T));
              ("premature usage of incomplete}", N, First_Subtype (T));
         end if;
         end if;
      end if;
      end if;
   end Check_Fully_Declared;
   end Check_Fully_Declared;
 
 
   -------------------------
   -------------------------
   -- Check_Nested_Access --
   -- Check_Nested_Access --
   -------------------------
   -------------------------
 
 
   procedure Check_Nested_Access (Ent : Entity_Id) is
   procedure Check_Nested_Access (Ent : Entity_Id) is
      Scop         : constant Entity_Id := Current_Scope;
      Scop         : constant Entity_Id := Current_Scope;
      Current_Subp : Entity_Id;
      Current_Subp : Entity_Id;
      Enclosing    : Entity_Id;
      Enclosing    : Entity_Id;
 
 
   begin
   begin
      --  Currently only enabled for VM back-ends for efficiency, should we
      --  Currently only enabled for VM back-ends for efficiency, should we
      --  enable it more systematically ???
      --  enable it more systematically ???
 
 
      --  Check for Is_Imported needs commenting below ???
      --  Check for Is_Imported needs commenting below ???
 
 
      if VM_Target /= No_VM
      if VM_Target /= No_VM
        and then (Ekind (Ent) = E_Variable
        and then (Ekind (Ent) = E_Variable
                    or else
                    or else
                  Ekind (Ent) = E_Constant
                  Ekind (Ent) = E_Constant
                    or else
                    or else
                  Ekind (Ent) = E_Loop_Parameter)
                  Ekind (Ent) = E_Loop_Parameter)
        and then Scope (Ent) /= Empty
        and then Scope (Ent) /= Empty
        and then not Is_Library_Level_Entity (Ent)
        and then not Is_Library_Level_Entity (Ent)
        and then not Is_Imported (Ent)
        and then not Is_Imported (Ent)
      then
      then
         if Is_Subprogram (Scop)
         if Is_Subprogram (Scop)
           or else Is_Generic_Subprogram (Scop)
           or else Is_Generic_Subprogram (Scop)
           or else Is_Entry (Scop)
           or else Is_Entry (Scop)
         then
         then
            Current_Subp := Scop;
            Current_Subp := Scop;
         else
         else
            Current_Subp := Current_Subprogram;
            Current_Subp := Current_Subprogram;
         end if;
         end if;
 
 
         Enclosing := Enclosing_Subprogram (Ent);
         Enclosing := Enclosing_Subprogram (Ent);
 
 
         if Enclosing /= Empty
         if Enclosing /= Empty
           and then Enclosing /= Current_Subp
           and then Enclosing /= Current_Subp
         then
         then
            Set_Has_Up_Level_Access (Ent, True);
            Set_Has_Up_Level_Access (Ent, True);
         end if;
         end if;
      end if;
      end if;
   end Check_Nested_Access;
   end Check_Nested_Access;
 
 
   ------------------------------------------
   ------------------------------------------
   -- Check_Potentially_Blocking_Operation --
   -- Check_Potentially_Blocking_Operation --
   ------------------------------------------
   ------------------------------------------
 
 
   procedure Check_Potentially_Blocking_Operation (N : Node_Id) is
   procedure Check_Potentially_Blocking_Operation (N : Node_Id) is
      S : Entity_Id;
      S : Entity_Id;
   begin
   begin
      --  N is one of the potentially blocking operations listed in 9.5.1(8).
      --  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
      --  When pragma Detect_Blocking is active, the run time will raise
      --  Program_Error. Here we only issue a warning, since we generally
      --  Program_Error. Here we only issue a warning, since we generally
      --  support the use of potentially blocking operations in the absence
      --  support the use of potentially blocking operations in the absence
      --  of the pragma.
      --  of the pragma.
 
 
      --  Indirect blocking through a subprogram call cannot be diagnosed
      --  Indirect blocking through a subprogram call cannot be diagnosed
      --  statically without interprocedural analysis, so we do not attempt
      --  statically without interprocedural analysis, so we do not attempt
      --  to do it here.
      --  to do it here.
 
 
      S := Scope (Current_Scope);
      S := Scope (Current_Scope);
      while Present (S) and then S /= Standard_Standard loop
      while Present (S) and then S /= Standard_Standard loop
         if Is_Protected_Type (S) then
         if Is_Protected_Type (S) then
            Error_Msg_N
            Error_Msg_N
              ("potentially blocking operation in protected operation?", N);
              ("potentially blocking operation in protected operation?", N);
 
 
            return;
            return;
         end if;
         end if;
 
 
         S := Scope (S);
         S := Scope (S);
      end loop;
      end loop;
   end Check_Potentially_Blocking_Operation;
   end Check_Potentially_Blocking_Operation;
 
 
   ------------------------------
   ------------------------------
   -- Check_Unprotected_Access --
   -- Check_Unprotected_Access --
   ------------------------------
   ------------------------------
 
 
   procedure Check_Unprotected_Access
   procedure Check_Unprotected_Access
     (Context : Node_Id;
     (Context : Node_Id;
      Expr    : Node_Id)
      Expr    : Node_Id)
   is
   is
      Cont_Encl_Typ : Entity_Id;
      Cont_Encl_Typ : Entity_Id;
      Pref_Encl_Typ : Entity_Id;
      Pref_Encl_Typ : Entity_Id;
 
 
      function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id;
      function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id;
      --  Check whether Obj is a private component of a protected object.
      --  Check whether Obj is a private component of a protected object.
      --  Return the protected type where the component resides, Empty
      --  Return the protected type where the component resides, Empty
      --  otherwise.
      --  otherwise.
 
 
      function Is_Public_Operation return Boolean;
      function Is_Public_Operation return Boolean;
      --  Verify that the enclosing operation is callable from outside the
      --  Verify that the enclosing operation is callable from outside the
      --  protected object, to minimize false positives.
      --  protected object, to minimize false positives.
 
 
      ------------------------------
      ------------------------------
      -- Enclosing_Protected_Type --
      -- Enclosing_Protected_Type --
      ------------------------------
      ------------------------------
 
 
      function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id is
      function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id is
      begin
      begin
         if Is_Entity_Name (Obj) then
         if Is_Entity_Name (Obj) then
            declare
            declare
               Ent : Entity_Id := Entity (Obj);
               Ent : Entity_Id := Entity (Obj);
 
 
            begin
            begin
               --  The object can be a renaming of a private component, use
               --  The object can be a renaming of a private component, use
               --  the original record component.
               --  the original record component.
 
 
               if Is_Prival (Ent) then
               if Is_Prival (Ent) then
                  Ent := Prival_Link (Ent);
                  Ent := Prival_Link (Ent);
               end if;
               end if;
 
 
               if Is_Protected_Type (Scope (Ent)) then
               if Is_Protected_Type (Scope (Ent)) then
                  return Scope (Ent);
                  return Scope (Ent);
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
         --  For indexed and selected components, recursively check the prefix
         --  For indexed and selected components, recursively check the prefix
 
 
         if Nkind_In (Obj, N_Indexed_Component, N_Selected_Component) then
         if Nkind_In (Obj, N_Indexed_Component, N_Selected_Component) then
            return Enclosing_Protected_Type (Prefix (Obj));
            return Enclosing_Protected_Type (Prefix (Obj));
 
 
         --  The object does not denote a protected component
         --  The object does not denote a protected component
 
 
         else
         else
            return Empty;
            return Empty;
         end if;
         end if;
      end Enclosing_Protected_Type;
      end Enclosing_Protected_Type;
 
 
      -------------------------
      -------------------------
      -- Is_Public_Operation --
      -- Is_Public_Operation --
      -------------------------
      -------------------------
 
 
      function Is_Public_Operation return Boolean is
      function Is_Public_Operation return Boolean is
         S : Entity_Id;
         S : Entity_Id;
         E : Entity_Id;
         E : Entity_Id;
 
 
      begin
      begin
         S := Current_Scope;
         S := Current_Scope;
         while Present (S)
         while Present (S)
           and then S /= Pref_Encl_Typ
           and then S /= Pref_Encl_Typ
         loop
         loop
            if Scope (S) = Pref_Encl_Typ then
            if Scope (S) = Pref_Encl_Typ then
               E := First_Entity (Pref_Encl_Typ);
               E := First_Entity (Pref_Encl_Typ);
               while Present (E)
               while Present (E)
                 and then E /= First_Private_Entity (Pref_Encl_Typ)
                 and then E /= First_Private_Entity (Pref_Encl_Typ)
               loop
               loop
                  if E = S then
                  if E = S then
                     return True;
                     return True;
                  end if;
                  end if;
                  Next_Entity (E);
                  Next_Entity (E);
               end loop;
               end loop;
            end if;
            end if;
 
 
            S := Scope (S);
            S := Scope (S);
         end loop;
         end loop;
 
 
         return False;
         return False;
      end Is_Public_Operation;
      end Is_Public_Operation;
 
 
   --  Start of processing for Check_Unprotected_Access
   --  Start of processing for Check_Unprotected_Access
 
 
   begin
   begin
      if Nkind (Expr) = N_Attribute_Reference
      if Nkind (Expr) = N_Attribute_Reference
        and then Attribute_Name (Expr) = Name_Unchecked_Access
        and then Attribute_Name (Expr) = Name_Unchecked_Access
      then
      then
         Cont_Encl_Typ := Enclosing_Protected_Type (Context);
         Cont_Encl_Typ := Enclosing_Protected_Type (Context);
         Pref_Encl_Typ := Enclosing_Protected_Type (Prefix (Expr));
         Pref_Encl_Typ := Enclosing_Protected_Type (Prefix (Expr));
 
 
         --  Check whether we are trying to export a protected component to a
         --  Check whether we are trying to export a protected component to a
         --  context with an equal or lower access level.
         --  context with an equal or lower access level.
 
 
         if Present (Pref_Encl_Typ)
         if Present (Pref_Encl_Typ)
           and then No (Cont_Encl_Typ)
           and then No (Cont_Encl_Typ)
           and then Is_Public_Operation
           and then Is_Public_Operation
           and then Scope_Depth (Pref_Encl_Typ) >=
           and then Scope_Depth (Pref_Encl_Typ) >=
                      Object_Access_Level (Context)
                      Object_Access_Level (Context)
         then
         then
            Error_Msg_N
            Error_Msg_N
              ("?possible unprotected access to protected data", Expr);
              ("?possible unprotected access to protected data", Expr);
         end if;
         end if;
      end if;
      end if;
   end Check_Unprotected_Access;
   end Check_Unprotected_Access;
 
 
   ---------------
   ---------------
   -- Check_VMS --
   -- Check_VMS --
   ---------------
   ---------------
 
 
   procedure Check_VMS (Construct : Node_Id) is
   procedure Check_VMS (Construct : Node_Id) is
   begin
   begin
      if not OpenVMS_On_Target then
      if not OpenVMS_On_Target then
         Error_Msg_N
         Error_Msg_N
           ("this construct is allowed only in Open'V'M'S", Construct);
           ("this construct is allowed only in Open'V'M'S", Construct);
      end if;
      end if;
   end Check_VMS;
   end Check_VMS;
 
 
   ------------------------
   ------------------------
   -- Collect_Interfaces --
   -- Collect_Interfaces --
   ------------------------
   ------------------------
 
 
   procedure Collect_Interfaces
   procedure Collect_Interfaces
     (T               : Entity_Id;
     (T               : Entity_Id;
      Ifaces_List     : out Elist_Id;
      Ifaces_List     : out Elist_Id;
      Exclude_Parents : Boolean := False;
      Exclude_Parents : Boolean := False;
      Use_Full_View   : Boolean := True)
      Use_Full_View   : Boolean := True)
   is
   is
      procedure Collect (Typ : Entity_Id);
      procedure Collect (Typ : Entity_Id);
      --  Subsidiary subprogram used to traverse the whole list
      --  Subsidiary subprogram used to traverse the whole list
      --  of directly and indirectly implemented interfaces
      --  of directly and indirectly implemented interfaces
 
 
      -------------
      -------------
      -- Collect --
      -- Collect --
      -------------
      -------------
 
 
      procedure Collect (Typ : Entity_Id) is
      procedure Collect (Typ : Entity_Id) is
         Ancestor   : Entity_Id;
         Ancestor   : Entity_Id;
         Full_T     : Entity_Id;
         Full_T     : Entity_Id;
         Id         : Node_Id;
         Id         : Node_Id;
         Iface      : Entity_Id;
         Iface      : Entity_Id;
 
 
      begin
      begin
         Full_T := Typ;
         Full_T := Typ;
 
 
         --  Handle private types
         --  Handle private types
 
 
         if Use_Full_View
         if Use_Full_View
           and then Is_Private_Type (Typ)
           and then Is_Private_Type (Typ)
           and then Present (Full_View (Typ))
           and then Present (Full_View (Typ))
         then
         then
            Full_T := Full_View (Typ);
            Full_T := Full_View (Typ);
         end if;
         end if;
 
 
         --  Include the ancestor if we are generating the whole list of
         --  Include the ancestor if we are generating the whole list of
         --  abstract interfaces.
         --  abstract interfaces.
 
 
         if Etype (Full_T) /= Typ
         if Etype (Full_T) /= Typ
 
 
            --  Protect the frontend against wrong sources. For example:
            --  Protect the frontend against wrong sources. For example:
 
 
            --    package P is
            --    package P is
            --      type A is tagged null record;
            --      type A is tagged null record;
            --      type B is new A with private;
            --      type B is new A with private;
            --      type C is new A with private;
            --      type C is new A with private;
            --    private
            --    private
            --      type B is new C with null record;
            --      type B is new C with null record;
            --      type C is new B with null record;
            --      type C is new B with null record;
            --    end P;
            --    end P;
 
 
           and then Etype (Full_T) /= T
           and then Etype (Full_T) /= T
         then
         then
            Ancestor := Etype (Full_T);
            Ancestor := Etype (Full_T);
            Collect (Ancestor);
            Collect (Ancestor);
 
 
            if Is_Interface (Ancestor)
            if Is_Interface (Ancestor)
              and then not Exclude_Parents
              and then not Exclude_Parents
            then
            then
               Append_Unique_Elmt (Ancestor, Ifaces_List);
               Append_Unique_Elmt (Ancestor, Ifaces_List);
            end if;
            end if;
         end if;
         end if;
 
 
         --  Traverse the graph of ancestor interfaces
         --  Traverse the graph of ancestor interfaces
 
 
         if Is_Non_Empty_List (Abstract_Interface_List (Full_T)) then
         if Is_Non_Empty_List (Abstract_Interface_List (Full_T)) then
            Id := First (Abstract_Interface_List (Full_T));
            Id := First (Abstract_Interface_List (Full_T));
            while Present (Id) loop
            while Present (Id) loop
               Iface := Etype (Id);
               Iface := Etype (Id);
 
 
               --  Protect against wrong uses. For example:
               --  Protect against wrong uses. For example:
               --    type I is interface;
               --    type I is interface;
               --    type O is tagged null record;
               --    type O is tagged null record;
               --    type Wrong is new I and O with null record; -- ERROR
               --    type Wrong is new I and O with null record; -- ERROR
 
 
               if Is_Interface (Iface) then
               if Is_Interface (Iface) then
                  if Exclude_Parents
                  if Exclude_Parents
                    and then Etype (T) /= T
                    and then Etype (T) /= T
                    and then Interface_Present_In_Ancestor (Etype (T), Iface)
                    and then Interface_Present_In_Ancestor (Etype (T), Iface)
                  then
                  then
                     null;
                     null;
                  else
                  else
                     Collect (Iface);
                     Collect (Iface);
                     Append_Unique_Elmt (Iface, Ifaces_List);
                     Append_Unique_Elmt (Iface, Ifaces_List);
                  end if;
                  end if;
               end if;
               end if;
 
 
               Next (Id);
               Next (Id);
            end loop;
            end loop;
         end if;
         end if;
      end Collect;
      end Collect;
 
 
   --  Start of processing for Collect_Interfaces
   --  Start of processing for Collect_Interfaces
 
 
   begin
   begin
      pragma Assert (Is_Tagged_Type (T) or else Is_Concurrent_Type (T));
      pragma Assert (Is_Tagged_Type (T) or else Is_Concurrent_Type (T));
      Ifaces_List := New_Elmt_List;
      Ifaces_List := New_Elmt_List;
      Collect (T);
      Collect (T);
   end Collect_Interfaces;
   end Collect_Interfaces;
 
 
   ----------------------------------
   ----------------------------------
   -- Collect_Interface_Components --
   -- Collect_Interface_Components --
   ----------------------------------
   ----------------------------------
 
 
   procedure Collect_Interface_Components
   procedure Collect_Interface_Components
     (Tagged_Type     : Entity_Id;
     (Tagged_Type     : Entity_Id;
      Components_List : out Elist_Id)
      Components_List : out Elist_Id)
   is
   is
      procedure Collect (Typ : Entity_Id);
      procedure Collect (Typ : Entity_Id);
      --  Subsidiary subprogram used to climb to the parents
      --  Subsidiary subprogram used to climb to the parents
 
 
      -------------
      -------------
      -- Collect --
      -- Collect --
      -------------
      -------------
 
 
      procedure Collect (Typ : Entity_Id) is
      procedure Collect (Typ : Entity_Id) is
         Tag_Comp   : Entity_Id;
         Tag_Comp   : Entity_Id;
         Parent_Typ : Entity_Id;
         Parent_Typ : Entity_Id;
 
 
      begin
      begin
         --  Handle private types
         --  Handle private types
 
 
         if Present (Full_View (Etype (Typ))) then
         if Present (Full_View (Etype (Typ))) then
            Parent_Typ := Full_View (Etype (Typ));
            Parent_Typ := Full_View (Etype (Typ));
         else
         else
            Parent_Typ := Etype (Typ);
            Parent_Typ := Etype (Typ);
         end if;
         end if;
 
 
         if Parent_Typ /= Typ
         if Parent_Typ /= Typ
 
 
            --  Protect the frontend against wrong sources. For example:
            --  Protect the frontend against wrong sources. For example:
 
 
            --    package P is
            --    package P is
            --      type A is tagged null record;
            --      type A is tagged null record;
            --      type B is new A with private;
            --      type B is new A with private;
            --      type C is new A with private;
            --      type C is new A with private;
            --    private
            --    private
            --      type B is new C with null record;
            --      type B is new C with null record;
            --      type C is new B with null record;
            --      type C is new B with null record;
            --    end P;
            --    end P;
 
 
           and then Parent_Typ /= Tagged_Type
           and then Parent_Typ /= Tagged_Type
         then
         then
            Collect (Parent_Typ);
            Collect (Parent_Typ);
         end if;
         end if;
 
 
         --  Collect the components containing tags of secondary dispatch
         --  Collect the components containing tags of secondary dispatch
         --  tables.
         --  tables.
 
 
         Tag_Comp := Next_Tag_Component (First_Tag_Component (Typ));
         Tag_Comp := Next_Tag_Component (First_Tag_Component (Typ));
         while Present (Tag_Comp) loop
         while Present (Tag_Comp) loop
            pragma Assert (Present (Related_Type (Tag_Comp)));
            pragma Assert (Present (Related_Type (Tag_Comp)));
            Append_Elmt (Tag_Comp, Components_List);
            Append_Elmt (Tag_Comp, Components_List);
 
 
            Tag_Comp := Next_Tag_Component (Tag_Comp);
            Tag_Comp := Next_Tag_Component (Tag_Comp);
         end loop;
         end loop;
      end Collect;
      end Collect;
 
 
   --  Start of processing for Collect_Interface_Components
   --  Start of processing for Collect_Interface_Components
 
 
   begin
   begin
      pragma Assert (Ekind (Tagged_Type) = E_Record_Type
      pragma Assert (Ekind (Tagged_Type) = E_Record_Type
        and then Is_Tagged_Type (Tagged_Type));
        and then Is_Tagged_Type (Tagged_Type));
 
 
      Components_List := New_Elmt_List;
      Components_List := New_Elmt_List;
      Collect (Tagged_Type);
      Collect (Tagged_Type);
   end Collect_Interface_Components;
   end Collect_Interface_Components;
 
 
   -----------------------------
   -----------------------------
   -- Collect_Interfaces_Info --
   -- Collect_Interfaces_Info --
   -----------------------------
   -----------------------------
 
 
   procedure Collect_Interfaces_Info
   procedure Collect_Interfaces_Info
     (T               : Entity_Id;
     (T               : Entity_Id;
      Ifaces_List     : out Elist_Id;
      Ifaces_List     : out Elist_Id;
      Components_List : out Elist_Id;
      Components_List : out Elist_Id;
      Tags_List       : out Elist_Id)
      Tags_List       : out Elist_Id)
   is
   is
      Comps_List : Elist_Id;
      Comps_List : Elist_Id;
      Comp_Elmt  : Elmt_Id;
      Comp_Elmt  : Elmt_Id;
      Comp_Iface : Entity_Id;
      Comp_Iface : Entity_Id;
      Iface_Elmt : Elmt_Id;
      Iface_Elmt : Elmt_Id;
      Iface      : Entity_Id;
      Iface      : Entity_Id;
 
 
      function Search_Tag (Iface : Entity_Id) return Entity_Id;
      function Search_Tag (Iface : Entity_Id) return Entity_Id;
      --  Search for the secondary tag associated with the interface type
      --  Search for the secondary tag associated with the interface type
      --  Iface that is implemented by T.
      --  Iface that is implemented by T.
 
 
      ----------------
      ----------------
      -- Search_Tag --
      -- Search_Tag --
      ----------------
      ----------------
 
 
      function Search_Tag (Iface : Entity_Id) return Entity_Id is
      function Search_Tag (Iface : Entity_Id) return Entity_Id is
         ADT : Elmt_Id;
         ADT : Elmt_Id;
 
 
      begin
      begin
         ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (T))));
         ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (T))));
         while Present (ADT)
         while Present (ADT)
            and then Ekind (Node (ADT)) = E_Constant
            and then Ekind (Node (ADT)) = E_Constant
            and then Related_Type (Node (ADT)) /= Iface
            and then Related_Type (Node (ADT)) /= Iface
         loop
         loop
            --  Skip the secondary dispatch tables of Iface
            --  Skip the secondary dispatch tables of Iface
 
 
            Next_Elmt (ADT);
            Next_Elmt (ADT);
            Next_Elmt (ADT);
            Next_Elmt (ADT);
            Next_Elmt (ADT);
            Next_Elmt (ADT);
            Next_Elmt (ADT);
            Next_Elmt (ADT);
         end loop;
         end loop;
 
 
         pragma Assert (Ekind (Node (ADT)) = E_Constant);
         pragma Assert (Ekind (Node (ADT)) = E_Constant);
         return Node (ADT);
         return Node (ADT);
      end Search_Tag;
      end Search_Tag;
 
 
   --  Start of processing for Collect_Interfaces_Info
   --  Start of processing for Collect_Interfaces_Info
 
 
   begin
   begin
      Collect_Interfaces (T, Ifaces_List);
      Collect_Interfaces (T, Ifaces_List);
      Collect_Interface_Components (T, Comps_List);
      Collect_Interface_Components (T, Comps_List);
 
 
      --  Search for the record component and tag associated with each
      --  Search for the record component and tag associated with each
      --  interface type of T.
      --  interface type of T.
 
 
      Components_List := New_Elmt_List;
      Components_List := New_Elmt_List;
      Tags_List       := New_Elmt_List;
      Tags_List       := New_Elmt_List;
 
 
      Iface_Elmt := First_Elmt (Ifaces_List);
      Iface_Elmt := First_Elmt (Ifaces_List);
      while Present (Iface_Elmt) loop
      while Present (Iface_Elmt) loop
         Iface := Node (Iface_Elmt);
         Iface := Node (Iface_Elmt);
 
 
         --  Associate the primary tag component and the primary dispatch table
         --  Associate the primary tag component and the primary dispatch table
         --  with all the interfaces that are parents of T
         --  with all the interfaces that are parents of T
 
 
         if Is_Ancestor (Iface, T) then
         if Is_Ancestor (Iface, T) then
            Append_Elmt (First_Tag_Component (T), Components_List);
            Append_Elmt (First_Tag_Component (T), Components_List);
            Append_Elmt (Node (First_Elmt (Access_Disp_Table (T))), Tags_List);
            Append_Elmt (Node (First_Elmt (Access_Disp_Table (T))), Tags_List);
 
 
         --  Otherwise search for the tag component and secondary dispatch
         --  Otherwise search for the tag component and secondary dispatch
         --  table of Iface
         --  table of Iface
 
 
         else
         else
            Comp_Elmt := First_Elmt (Comps_List);
            Comp_Elmt := First_Elmt (Comps_List);
            while Present (Comp_Elmt) loop
            while Present (Comp_Elmt) loop
               Comp_Iface := Related_Type (Node (Comp_Elmt));
               Comp_Iface := Related_Type (Node (Comp_Elmt));
 
 
               if Comp_Iface = Iface
               if Comp_Iface = Iface
                 or else Is_Ancestor (Iface, Comp_Iface)
                 or else Is_Ancestor (Iface, Comp_Iface)
               then
               then
                  Append_Elmt (Node (Comp_Elmt), Components_List);
                  Append_Elmt (Node (Comp_Elmt), Components_List);
                  Append_Elmt (Search_Tag (Comp_Iface), Tags_List);
                  Append_Elmt (Search_Tag (Comp_Iface), Tags_List);
                  exit;
                  exit;
               end if;
               end if;
 
 
               Next_Elmt (Comp_Elmt);
               Next_Elmt (Comp_Elmt);
            end loop;
            end loop;
            pragma Assert (Present (Comp_Elmt));
            pragma Assert (Present (Comp_Elmt));
         end if;
         end if;
 
 
         Next_Elmt (Iface_Elmt);
         Next_Elmt (Iface_Elmt);
      end loop;
      end loop;
   end Collect_Interfaces_Info;
   end Collect_Interfaces_Info;
 
 
   ----------------------------------
   ----------------------------------
   -- Collect_Primitive_Operations --
   -- Collect_Primitive_Operations --
   ----------------------------------
   ----------------------------------
 
 
   function Collect_Primitive_Operations (T : Entity_Id) return Elist_Id is
   function Collect_Primitive_Operations (T : Entity_Id) return Elist_Id is
      B_Type         : constant Entity_Id := Base_Type (T);
      B_Type         : constant Entity_Id := Base_Type (T);
      B_Decl         : constant Node_Id   := Original_Node (Parent (B_Type));
      B_Decl         : constant Node_Id   := Original_Node (Parent (B_Type));
      B_Scope        : Entity_Id          := Scope (B_Type);
      B_Scope        : Entity_Id          := Scope (B_Type);
      Op_List        : Elist_Id;
      Op_List        : Elist_Id;
      Formal         : Entity_Id;
      Formal         : Entity_Id;
      Is_Prim        : Boolean;
      Is_Prim        : Boolean;
      Formal_Derived : Boolean := False;
      Formal_Derived : Boolean := False;
      Id             : Entity_Id;
      Id             : Entity_Id;
 
 
   begin
   begin
      --  For tagged types, the primitive operations are collected as they
      --  For tagged types, the primitive operations are collected as they
      --  are declared, and held in an explicit list which is simply returned.
      --  are declared, and held in an explicit list which is simply returned.
 
 
      if Is_Tagged_Type (B_Type) then
      if Is_Tagged_Type (B_Type) then
         return Primitive_Operations (B_Type);
         return Primitive_Operations (B_Type);
 
 
      --  An untagged generic type that is a derived type inherits the
      --  An untagged generic type that is a derived type inherits the
      --  primitive operations of its parent type. Other formal types only
      --  primitive operations of its parent type. Other formal types only
      --  have predefined operators, which are not explicitly represented.
      --  have predefined operators, which are not explicitly represented.
 
 
      elsif Is_Generic_Type (B_Type) then
      elsif Is_Generic_Type (B_Type) then
         if Nkind (B_Decl) = N_Formal_Type_Declaration
         if Nkind (B_Decl) = N_Formal_Type_Declaration
           and then Nkind (Formal_Type_Definition (B_Decl))
           and then Nkind (Formal_Type_Definition (B_Decl))
             = N_Formal_Derived_Type_Definition
             = N_Formal_Derived_Type_Definition
         then
         then
            Formal_Derived := True;
            Formal_Derived := True;
         else
         else
            return New_Elmt_List;
            return New_Elmt_List;
         end if;
         end if;
      end if;
      end if;
 
 
      Op_List := New_Elmt_List;
      Op_List := New_Elmt_List;
 
 
      if B_Scope = Standard_Standard then
      if B_Scope = Standard_Standard then
         if B_Type = Standard_String then
         if B_Type = Standard_String then
            Append_Elmt (Standard_Op_Concat, Op_List);
            Append_Elmt (Standard_Op_Concat, Op_List);
 
 
         elsif B_Type = Standard_Wide_String then
         elsif B_Type = Standard_Wide_String then
            Append_Elmt (Standard_Op_Concatw, Op_List);
            Append_Elmt (Standard_Op_Concatw, Op_List);
 
 
         else
         else
            null;
            null;
         end if;
         end if;
 
 
      elsif (Is_Package_Or_Generic_Package (B_Scope)
      elsif (Is_Package_Or_Generic_Package (B_Scope)
              and then
              and then
                Nkind (Parent (Declaration_Node (First_Subtype (T)))) /=
                Nkind (Parent (Declaration_Node (First_Subtype (T)))) /=
                                                            N_Package_Body)
                                                            N_Package_Body)
        or else Is_Derived_Type (B_Type)
        or else Is_Derived_Type (B_Type)
      then
      then
         --  The primitive operations appear after the base type, except
         --  The primitive operations appear after the base type, except
         --  if the derivation happens within the private part of B_Scope
         --  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 the type is a private type, in which case both the type
         --  and some primitive operations may appear before the base
         --  and some primitive operations may appear before the base
         --  type, and the list of candidates starts after the type.
         --  type, and the list of candidates starts after the type.
 
 
         if In_Open_Scopes (B_Scope)
         if In_Open_Scopes (B_Scope)
           and then Scope (T) = B_Scope
           and then Scope (T) = B_Scope
           and then In_Private_Part (B_Scope)
           and then In_Private_Part (B_Scope)
         then
         then
            Id := Next_Entity (T);
            Id := Next_Entity (T);
         else
         else
            Id := Next_Entity (B_Type);
            Id := Next_Entity (B_Type);
         end if;
         end if;
 
 
         while Present (Id) loop
         while Present (Id) loop
 
 
            --  Note that generic formal subprograms are not
            --  Note that generic formal subprograms are not
            --  considered to be primitive operations and thus
            --  considered to be primitive operations and thus
            --  are never inherited.
            --  are never inherited.
 
 
            if Is_Overloadable (Id)
            if Is_Overloadable (Id)
              and then Nkind (Parent (Parent (Id)))
              and then Nkind (Parent (Parent (Id)))
                         not in N_Formal_Subprogram_Declaration
                         not in N_Formal_Subprogram_Declaration
            then
            then
               Is_Prim := False;
               Is_Prim := False;
 
 
               if Base_Type (Etype (Id)) = B_Type then
               if Base_Type (Etype (Id)) = B_Type then
                  Is_Prim := True;
                  Is_Prim := True;
               else
               else
                  Formal := First_Formal (Id);
                  Formal := First_Formal (Id);
                  while Present (Formal) loop
                  while Present (Formal) loop
                     if Base_Type (Etype (Formal)) = B_Type then
                     if Base_Type (Etype (Formal)) = B_Type then
                        Is_Prim := True;
                        Is_Prim := True;
                        exit;
                        exit;
 
 
                     elsif Ekind (Etype (Formal)) = E_Anonymous_Access_Type
                     elsif Ekind (Etype (Formal)) = E_Anonymous_Access_Type
                       and then Base_Type
                       and then Base_Type
                         (Designated_Type (Etype (Formal))) = B_Type
                         (Designated_Type (Etype (Formal))) = B_Type
                     then
                     then
                        Is_Prim := True;
                        Is_Prim := True;
                        exit;
                        exit;
                     end if;
                     end if;
 
 
                     Next_Formal (Formal);
                     Next_Formal (Formal);
                  end loop;
                  end loop;
               end if;
               end if;
 
 
               --  For a formal derived type, the only primitives are the
               --  For a formal derived type, the only primitives are the
               --  ones inherited from the parent type. Operations appearing
               --  ones inherited from the parent type. Operations appearing
               --  in the package declaration are not primitive for it.
               --  in the package declaration are not primitive for it.
 
 
               if Is_Prim
               if Is_Prim
                 and then (not Formal_Derived
                 and then (not Formal_Derived
                            or else Present (Alias (Id)))
                            or else Present (Alias (Id)))
               then
               then
                  Append_Elmt (Id, Op_List);
                  Append_Elmt (Id, Op_List);
               end if;
               end if;
            end if;
            end if;
 
 
            Next_Entity (Id);
            Next_Entity (Id);
 
 
            --  For a type declared in System, some of its operations
            --  For a type declared in System, some of its operations
            --  may appear in  the target-specific extension to System.
            --  may appear in  the target-specific extension to System.
 
 
            if No (Id)
            if No (Id)
              and then Chars (B_Scope) = Name_System
              and then Chars (B_Scope) = Name_System
              and then Scope (B_Scope) = Standard_Standard
              and then Scope (B_Scope) = Standard_Standard
              and then Present_System_Aux
              and then Present_System_Aux
            then
            then
               B_Scope := System_Aux_Id;
               B_Scope := System_Aux_Id;
               Id := First_Entity (System_Aux_Id);
               Id := First_Entity (System_Aux_Id);
            end if;
            end if;
         end loop;
         end loop;
      end if;
      end if;
 
 
      return Op_List;
      return Op_List;
   end Collect_Primitive_Operations;
   end Collect_Primitive_Operations;
 
 
   -----------------------------------
   -----------------------------------
   -- Compile_Time_Constraint_Error --
   -- Compile_Time_Constraint_Error --
   -----------------------------------
   -----------------------------------
 
 
   function Compile_Time_Constraint_Error
   function Compile_Time_Constraint_Error
     (N    : Node_Id;
     (N    : Node_Id;
      Msg  : String;
      Msg  : String;
      Ent  : Entity_Id  := Empty;
      Ent  : Entity_Id  := Empty;
      Loc  : Source_Ptr := No_Location;
      Loc  : Source_Ptr := No_Location;
      Warn : Boolean    := False) return Node_Id
      Warn : Boolean    := False) return Node_Id
   is
   is
      Msgc : String (1 .. Msg'Length + 2);
      Msgc : String (1 .. Msg'Length + 2);
      --  Copy of message, with room for possible ? and ! at end
      --  Copy of message, with room for possible ? and ! at end
 
 
      Msgl : Natural;
      Msgl : Natural;
      Wmsg : Boolean;
      Wmsg : Boolean;
      P    : Node_Id;
      P    : Node_Id;
      OldP : Node_Id;
      OldP : Node_Id;
      Msgs : Boolean;
      Msgs : Boolean;
      Eloc : Source_Ptr;
      Eloc : Source_Ptr;
 
 
   begin
   begin
      --  A static constraint error in an instance body is not a fatal error.
      --  A static constraint error in an instance body is not a fatal error.
      --  we choose to inhibit the message altogether, because there is no
      --  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
      --  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.
      --  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
      --  No messages are generated if we already posted an error on this node
 
 
      if not Error_Posted (N) then
      if not Error_Posted (N) then
         if Loc /= No_Location then
         if Loc /= No_Location then
            Eloc := Loc;
            Eloc := Loc;
         else
         else
            Eloc := Sloc (N);
            Eloc := Sloc (N);
         end if;
         end if;
 
 
         Msgc (1 .. Msg'Length) := Msg;
         Msgc (1 .. Msg'Length) := Msg;
         Msgl := Msg'Length;
         Msgl := Msg'Length;
 
 
         --  Message is a warning, even in Ada 95 case
         --  Message is a warning, even in Ada 95 case
 
 
         if Msg (Msg'Last) = '?' then
         if Msg (Msg'Last) = '?' then
            Wmsg := True;
            Wmsg := True;
 
 
         --  In Ada 83, all messages are warnings. In the private part and
         --  In Ada 83, all messages are warnings. In the private part and
         --  the body of an instance, constraint_checks are only warnings.
         --  the body of an instance, constraint_checks are only warnings.
         --  We also make this a warning if the Warn parameter is set.
         --  We also make this a warning if the Warn parameter is set.
 
 
         elsif Warn
         elsif Warn
           or else (Ada_Version = Ada_83 and then Comes_From_Source (N))
           or else (Ada_Version = Ada_83 and then Comes_From_Source (N))
         then
         then
            Msgl := Msgl + 1;
            Msgl := Msgl + 1;
            Msgc (Msgl) := '?';
            Msgc (Msgl) := '?';
            Wmsg := True;
            Wmsg := True;
 
 
         elsif In_Instance_Not_Visible then
         elsif In_Instance_Not_Visible then
            Msgl := Msgl + 1;
            Msgl := Msgl + 1;
            Msgc (Msgl) := '?';
            Msgc (Msgl) := '?';
            Wmsg := True;
            Wmsg := True;
 
 
         --  Otherwise we have a real error message (Ada 95 static case)
         --  Otherwise we have a real error message (Ada 95 static case)
         --  and we make this an unconditional message. Note that in the
         --  and we make this an unconditional message. Note that in the
         --  warning case we do not make the message unconditional, it seems
         --  warning case we do not make the message unconditional, it seems
         --  quite reasonable to delete messages like this (about exceptions
         --  quite reasonable to delete messages like this (about exceptions
         --  that will be raised) in dead code.
         --  that will be raised) in dead code.
 
 
         else
         else
            Wmsg := False;
            Wmsg := False;
            Msgl := Msgl + 1;
            Msgl := Msgl + 1;
            Msgc (Msgl) := '!';
            Msgc (Msgl) := '!';
         end if;
         end if;
 
 
         --  Should we generate a warning? The answer is not quite yes. The
         --  Should we generate a warning? The answer is not quite yes. The
         --  very annoying exception occurs in the case of a short circuit
         --  very annoying exception occurs in the case of a short circuit
         --  operator where the left operand is static and decisive. Climb
         --  operator where the left operand is static and decisive. Climb
         --  parents to see if that is the case we have here. Conditional
         --  parents to see if that is the case we have here. Conditional
         --  expressions with decisive conditions are a similar situation.
         --  expressions with decisive conditions are a similar situation.
 
 
         Msgs := True;
         Msgs := True;
         P := N;
         P := N;
         loop
         loop
            OldP := P;
            OldP := P;
            P := Parent (P);
            P := Parent (P);
 
 
            --  And then with False as left operand
            --  And then with False as left operand
 
 
            if Nkind (P) = N_And_Then
            if Nkind (P) = N_And_Then
              and then Compile_Time_Known_Value (Left_Opnd (P))
              and then Compile_Time_Known_Value (Left_Opnd (P))
              and then Is_False (Expr_Value (Left_Opnd (P)))
              and then Is_False (Expr_Value (Left_Opnd (P)))
            then
            then
               Msgs := False;
               Msgs := False;
               exit;
               exit;
 
 
            --  OR ELSE with True as left operand
            --  OR ELSE with True as left operand
 
 
            elsif Nkind (P) = N_Or_Else
            elsif Nkind (P) = N_Or_Else
              and then Compile_Time_Known_Value (Left_Opnd (P))
              and then Compile_Time_Known_Value (Left_Opnd (P))
              and then Is_True (Expr_Value (Left_Opnd (P)))
              and then Is_True (Expr_Value (Left_Opnd (P)))
            then
            then
               Msgs := False;
               Msgs := False;
               exit;
               exit;
 
 
            --  Conditional expression
            --  Conditional expression
 
 
            elsif Nkind (P) = N_Conditional_Expression then
            elsif Nkind (P) = N_Conditional_Expression then
               declare
               declare
                  Cond : constant Node_Id := First (Expressions (P));
                  Cond : constant Node_Id := First (Expressions (P));
                  Texp : constant Node_Id := Next (Cond);
                  Texp : constant Node_Id := Next (Cond);
                  Fexp : constant Node_Id := Next (Texp);
                  Fexp : constant Node_Id := Next (Texp);
 
 
               begin
               begin
                  if Compile_Time_Known_Value (Cond) then
                  if Compile_Time_Known_Value (Cond) then
 
 
                     --  Condition is True and we are in the right operand
                     --  Condition is True and we are in the right operand
 
 
                     if Is_True (Expr_Value (Cond))
                     if Is_True (Expr_Value (Cond))
                       and then OldP = Fexp
                       and then OldP = Fexp
                     then
                     then
                        Msgs := False;
                        Msgs := False;
                        exit;
                        exit;
 
 
                     --  Condition is False and we are in the left operand
                     --  Condition is False and we are in the left operand
 
 
                     elsif Is_False (Expr_Value (Cond))
                     elsif Is_False (Expr_Value (Cond))
                       and then OldP = Texp
                       and then OldP = Texp
                     then
                     then
                        Msgs := False;
                        Msgs := False;
                        exit;
                        exit;
                     end if;
                     end if;
                  end if;
                  end if;
               end;
               end;
 
 
            --  Special case for component association in aggregates, where
            --  Special case for component association in aggregates, where
            --  we want to keep climbing up to the parent aggregate.
            --  we want to keep climbing up to the parent aggregate.
 
 
            elsif Nkind (P) = N_Component_Association
            elsif Nkind (P) = N_Component_Association
              and then Nkind (Parent (P)) = N_Aggregate
              and then Nkind (Parent (P)) = N_Aggregate
            then
            then
               null;
               null;
 
 
            --  Keep going if within subexpression
            --  Keep going if within subexpression
 
 
            else
            else
               exit when Nkind (P) not in N_Subexpr;
               exit when Nkind (P) not in N_Subexpr;
            end if;
            end if;
         end loop;
         end loop;
 
 
         if Msgs then
         if Msgs then
            if Present (Ent) then
            if Present (Ent) then
               Error_Msg_NEL (Msgc (1 .. Msgl), N, Ent, Eloc);
               Error_Msg_NEL (Msgc (1 .. Msgl), N, Ent, Eloc);
            else
            else
               Error_Msg_NEL (Msgc (1 .. Msgl), N, Etype (N), Eloc);
               Error_Msg_NEL (Msgc (1 .. Msgl), N, Etype (N), Eloc);
            end if;
            end if;
 
 
            if Wmsg then
            if Wmsg then
               if Inside_Init_Proc then
               if Inside_Init_Proc then
                  Error_Msg_NEL
                  Error_Msg_NEL
                    ("\?& will be raised for objects of this type",
                    ("\?& will be raised for objects of this type",
                     N, Standard_Constraint_Error, Eloc);
                     N, Standard_Constraint_Error, Eloc);
               else
               else
                  Error_Msg_NEL
                  Error_Msg_NEL
                    ("\?& will be raised at run time",
                    ("\?& will be raised at run time",
                     N, Standard_Constraint_Error, Eloc);
                     N, Standard_Constraint_Error, Eloc);
               end if;
               end if;
 
 
            else
            else
               Error_Msg
               Error_Msg
                 ("\static expression fails Constraint_Check", Eloc);
                 ("\static expression fails Constraint_Check", Eloc);
               Set_Error_Posted (N);
               Set_Error_Posted (N);
            end if;
            end if;
         end if;
         end if;
      end if;
      end if;
 
 
      return N;
      return N;
   end Compile_Time_Constraint_Error;
   end Compile_Time_Constraint_Error;
 
 
   -----------------------
   -----------------------
   -- Conditional_Delay --
   -- Conditional_Delay --
   -----------------------
   -----------------------
 
 
   procedure Conditional_Delay (New_Ent, Old_Ent : Entity_Id) is
   procedure Conditional_Delay (New_Ent, Old_Ent : Entity_Id) is
   begin
   begin
      if Has_Delayed_Freeze (Old_Ent) and then not Is_Frozen (Old_Ent) then
      if Has_Delayed_Freeze (Old_Ent) and then not Is_Frozen (Old_Ent) then
         Set_Has_Delayed_Freeze (New_Ent);
         Set_Has_Delayed_Freeze (New_Ent);
      end if;
      end if;
   end Conditional_Delay;
   end Conditional_Delay;
 
 
   -------------------------
   -------------------------
   -- Copy_Parameter_List --
   -- Copy_Parameter_List --
   -------------------------
   -------------------------
 
 
   function Copy_Parameter_List (Subp_Id : Entity_Id) return List_Id is
   function Copy_Parameter_List (Subp_Id : Entity_Id) return List_Id is
      Loc    : constant Source_Ptr := Sloc (Subp_Id);
      Loc    : constant Source_Ptr := Sloc (Subp_Id);
      Plist  : List_Id;
      Plist  : List_Id;
      Formal : Entity_Id;
      Formal : Entity_Id;
 
 
   begin
   begin
      if No (First_Formal (Subp_Id)) then
      if No (First_Formal (Subp_Id)) then
         return No_List;
         return No_List;
      else
      else
         Plist := New_List;
         Plist := New_List;
         Formal := First_Formal (Subp_Id);
         Formal := First_Formal (Subp_Id);
         while Present (Formal) loop
         while Present (Formal) loop
            Append
            Append
              (Make_Parameter_Specification (Loc,
              (Make_Parameter_Specification (Loc,
                Defining_Identifier =>
                Defining_Identifier =>
                  Make_Defining_Identifier (Sloc (Formal),
                  Make_Defining_Identifier (Sloc (Formal),
                    Chars => Chars (Formal)),
                    Chars => Chars (Formal)),
                In_Present  => In_Present (Parent (Formal)),
                In_Present  => In_Present (Parent (Formal)),
                Out_Present => Out_Present (Parent (Formal)),
                Out_Present => Out_Present (Parent (Formal)),
             Parameter_Type =>
             Parameter_Type =>
                  New_Reference_To (Etype (Formal), Loc),
                  New_Reference_To (Etype (Formal), Loc),
                Expression =>
                Expression =>
                  New_Copy_Tree (Expression (Parent (Formal)))),
                  New_Copy_Tree (Expression (Parent (Formal)))),
              Plist);
              Plist);
 
 
            Next_Formal (Formal);
            Next_Formal (Formal);
         end loop;
         end loop;
      end if;
      end if;
 
 
      return Plist;
      return Plist;
   end Copy_Parameter_List;
   end Copy_Parameter_List;
 
 
   --------------------
   --------------------
   -- Current_Entity --
   -- Current_Entity --
   --------------------
   --------------------
 
 
   --  The currently visible definition for a given identifier is the
   --  The currently visible definition for a given identifier is the
   --  one most chained at the start of the visibility chain, i.e. 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
   --  one that is referenced by the Node_Id value of the name of the
   --  given identifier.
   --  given identifier.
 
 
   function Current_Entity (N : Node_Id) return Entity_Id is
   function Current_Entity (N : Node_Id) return Entity_Id is
   begin
   begin
      return Get_Name_Entity_Id (Chars (N));
      return Get_Name_Entity_Id (Chars (N));
   end Current_Entity;
   end Current_Entity;
 
 
   -----------------------------
   -----------------------------
   -- Current_Entity_In_Scope --
   -- Current_Entity_In_Scope --
   -----------------------------
   -----------------------------
 
 
   function Current_Entity_In_Scope (N : Node_Id) return Entity_Id is
   function Current_Entity_In_Scope (N : Node_Id) return Entity_Id is
      E  : Entity_Id;
      E  : Entity_Id;
      CS : constant Entity_Id := Current_Scope;
      CS : constant Entity_Id := Current_Scope;
 
 
      Transient_Case : constant Boolean := Scope_Is_Transient;
      Transient_Case : constant Boolean := Scope_Is_Transient;
 
 
   begin
   begin
      E := Get_Name_Entity_Id (Chars (N));
      E := Get_Name_Entity_Id (Chars (N));
      while Present (E)
      while Present (E)
        and then Scope (E) /= CS
        and then Scope (E) /= CS
        and then (not Transient_Case or else Scope (E) /= Scope (CS))
        and then (not Transient_Case or else Scope (E) /= Scope (CS))
      loop
      loop
         E := Homonym (E);
         E := Homonym (E);
      end loop;
      end loop;
 
 
      return E;
      return E;
   end Current_Entity_In_Scope;
   end Current_Entity_In_Scope;
 
 
   -------------------
   -------------------
   -- Current_Scope --
   -- Current_Scope --
   -------------------
   -------------------
 
 
   function Current_Scope return Entity_Id is
   function Current_Scope return Entity_Id is
   begin
   begin
      if Scope_Stack.Last = -1 then
      if Scope_Stack.Last = -1 then
         return Standard_Standard;
         return Standard_Standard;
      else
      else
         declare
         declare
            C : constant Entity_Id :=
            C : constant Entity_Id :=
                  Scope_Stack.Table (Scope_Stack.Last).Entity;
                  Scope_Stack.Table (Scope_Stack.Last).Entity;
         begin
         begin
            if Present (C) then
            if Present (C) then
               return C;
               return C;
            else
            else
               return Standard_Standard;
               return Standard_Standard;
            end if;
            end if;
         end;
         end;
      end if;
      end if;
   end Current_Scope;
   end Current_Scope;
 
 
   ------------------------
   ------------------------
   -- Current_Subprogram --
   -- Current_Subprogram --
   ------------------------
   ------------------------
 
 
   function Current_Subprogram return Entity_Id is
   function Current_Subprogram return Entity_Id is
      Scop : constant Entity_Id := Current_Scope;
      Scop : constant Entity_Id := Current_Scope;
   begin
   begin
      if Is_Subprogram (Scop) or else Is_Generic_Subprogram (Scop) then
      if Is_Subprogram (Scop) or else Is_Generic_Subprogram (Scop) then
         return Scop;
         return Scop;
      else
      else
         return Enclosing_Subprogram (Scop);
         return Enclosing_Subprogram (Scop);
      end if;
      end if;
   end Current_Subprogram;
   end Current_Subprogram;
 
 
   ---------------------
   ---------------------
   -- Defining_Entity --
   -- Defining_Entity --
   ---------------------
   ---------------------
 
 
   function Defining_Entity (N : Node_Id) return Entity_Id is
   function Defining_Entity (N : Node_Id) return Entity_Id is
      K   : constant Node_Kind := Nkind (N);
      K   : constant Node_Kind := Nkind (N);
      Err : Entity_Id := Empty;
      Err : Entity_Id := Empty;
 
 
   begin
   begin
      case K is
      case K is
         when
         when
           N_Subprogram_Declaration                 |
           N_Subprogram_Declaration                 |
           N_Abstract_Subprogram_Declaration        |
           N_Abstract_Subprogram_Declaration        |
           N_Subprogram_Body                        |
           N_Subprogram_Body                        |
           N_Package_Declaration                    |
           N_Package_Declaration                    |
           N_Subprogram_Renaming_Declaration        |
           N_Subprogram_Renaming_Declaration        |
           N_Subprogram_Body_Stub                   |
           N_Subprogram_Body_Stub                   |
           N_Generic_Subprogram_Declaration         |
           N_Generic_Subprogram_Declaration         |
           N_Generic_Package_Declaration            |
           N_Generic_Package_Declaration            |
           N_Formal_Subprogram_Declaration
           N_Formal_Subprogram_Declaration
         =>
         =>
            return Defining_Entity (Specification (N));
            return Defining_Entity (Specification (N));
 
 
         when
         when
           N_Component_Declaration                  |
           N_Component_Declaration                  |
           N_Defining_Program_Unit_Name             |
           N_Defining_Program_Unit_Name             |
           N_Discriminant_Specification             |
           N_Discriminant_Specification             |
           N_Entry_Body                             |
           N_Entry_Body                             |
           N_Entry_Declaration                      |
           N_Entry_Declaration                      |
           N_Entry_Index_Specification              |
           N_Entry_Index_Specification              |
           N_Exception_Declaration                  |
           N_Exception_Declaration                  |
           N_Exception_Renaming_Declaration         |
           N_Exception_Renaming_Declaration         |
           N_Formal_Object_Declaration              |
           N_Formal_Object_Declaration              |
           N_Formal_Package_Declaration             |
           N_Formal_Package_Declaration             |
           N_Formal_Type_Declaration                |
           N_Formal_Type_Declaration                |
           N_Full_Type_Declaration                  |
           N_Full_Type_Declaration                  |
           N_Implicit_Label_Declaration             |
           N_Implicit_Label_Declaration             |
           N_Incomplete_Type_Declaration            |
           N_Incomplete_Type_Declaration            |
           N_Loop_Parameter_Specification           |
           N_Loop_Parameter_Specification           |
           N_Number_Declaration                     |
           N_Number_Declaration                     |
           N_Object_Declaration                     |
           N_Object_Declaration                     |
           N_Object_Renaming_Declaration            |
           N_Object_Renaming_Declaration            |
           N_Package_Body_Stub                      |
           N_Package_Body_Stub                      |
           N_Parameter_Specification                |
           N_Parameter_Specification                |
           N_Private_Extension_Declaration          |
           N_Private_Extension_Declaration          |
           N_Private_Type_Declaration               |
           N_Private_Type_Declaration               |
           N_Protected_Body                         |
           N_Protected_Body                         |
           N_Protected_Body_Stub                    |
           N_Protected_Body_Stub                    |
           N_Protected_Type_Declaration             |
           N_Protected_Type_Declaration             |
           N_Single_Protected_Declaration           |
           N_Single_Protected_Declaration           |
           N_Single_Task_Declaration                |
           N_Single_Task_Declaration                |
           N_Subtype_Declaration                    |
           N_Subtype_Declaration                    |
           N_Task_Body                              |
           N_Task_Body                              |
           N_Task_Body_Stub                         |
           N_Task_Body_Stub                         |
           N_Task_Type_Declaration
           N_Task_Type_Declaration
         =>
         =>
            return Defining_Identifier (N);
            return Defining_Identifier (N);
 
 
         when N_Subunit =>
         when N_Subunit =>
            return Defining_Entity (Proper_Body (N));
            return Defining_Entity (Proper_Body (N));
 
 
         when
         when
           N_Function_Instantiation                 |
           N_Function_Instantiation                 |
           N_Function_Specification                 |
           N_Function_Specification                 |
           N_Generic_Function_Renaming_Declaration  |
           N_Generic_Function_Renaming_Declaration  |
           N_Generic_Package_Renaming_Declaration   |
           N_Generic_Package_Renaming_Declaration   |
           N_Generic_Procedure_Renaming_Declaration |
           N_Generic_Procedure_Renaming_Declaration |
           N_Package_Body                           |
           N_Package_Body                           |
           N_Package_Instantiation                  |
           N_Package_Instantiation                  |
           N_Package_Renaming_Declaration           |
           N_Package_Renaming_Declaration           |
           N_Package_Specification                  |
           N_Package_Specification                  |
           N_Procedure_Instantiation                |
           N_Procedure_Instantiation                |
           N_Procedure_Specification
           N_Procedure_Specification
         =>
         =>
            declare
            declare
               Nam : constant Node_Id := Defining_Unit_Name (N);
               Nam : constant Node_Id := Defining_Unit_Name (N);
 
 
            begin
            begin
               if Nkind (Nam) in N_Entity then
               if Nkind (Nam) in N_Entity then
                  return Nam;
                  return Nam;
 
 
               --  For Error, make up a name and attach to declaration
               --  For Error, make up a name and attach to declaration
               --  so we can continue semantic analysis
               --  so we can continue semantic analysis
 
 
               elsif Nam = Error then
               elsif Nam = Error then
                  Err :=
                  Err :=
                    Make_Defining_Identifier (Sloc (N),
                    Make_Defining_Identifier (Sloc (N),
                      Chars => New_Internal_Name ('T'));
                      Chars => New_Internal_Name ('T'));
                  Set_Defining_Unit_Name (N, Err);
                  Set_Defining_Unit_Name (N, Err);
 
 
                  return Err;
                  return Err;
               --  If not an entity, get defining identifier
               --  If not an entity, get defining identifier
 
 
               else
               else
                  return Defining_Identifier (Nam);
                  return Defining_Identifier (Nam);
               end if;
               end if;
            end;
            end;
 
 
         when N_Block_Statement =>
         when N_Block_Statement =>
            return Entity (Identifier (N));
            return Entity (Identifier (N));
 
 
         when others =>
         when others =>
            raise Program_Error;
            raise Program_Error;
 
 
      end case;
      end case;
   end Defining_Entity;
   end Defining_Entity;
 
 
   --------------------------
   --------------------------
   -- Denotes_Discriminant --
   -- Denotes_Discriminant --
   --------------------------
   --------------------------
 
 
   function Denotes_Discriminant
   function Denotes_Discriminant
     (N                : Node_Id;
     (N                : Node_Id;
      Check_Concurrent : Boolean := False) return Boolean
      Check_Concurrent : Boolean := False) return Boolean
   is
   is
      E : Entity_Id;
      E : Entity_Id;
   begin
   begin
      if not Is_Entity_Name (N)
      if not Is_Entity_Name (N)
        or else No (Entity (N))
        or else No (Entity (N))
      then
      then
         return False;
         return False;
      else
      else
         E := Entity (N);
         E := Entity (N);
      end if;
      end if;
 
 
      --  If we are checking for a protected type, the discriminant may have
      --  If we are checking for a protected type, the discriminant may have
      --  been rewritten as the corresponding discriminal of the original type
      --  been rewritten as the corresponding discriminal of the original type
      --  or of the corresponding concurrent record, depending on whether we
      --  or of the corresponding concurrent record, depending on whether we
      --  are in the spec or body of the protected type.
      --  are in the spec or body of the protected type.
 
 
      return Ekind (E) = E_Discriminant
      return Ekind (E) = E_Discriminant
        or else
        or else
          (Check_Concurrent
          (Check_Concurrent
            and then Ekind (E) = E_In_Parameter
            and then Ekind (E) = E_In_Parameter
            and then Present (Discriminal_Link (E))
            and then Present (Discriminal_Link (E))
            and then
            and then
              (Is_Concurrent_Type (Scope (Discriminal_Link (E)))
              (Is_Concurrent_Type (Scope (Discriminal_Link (E)))
                or else
                or else
                  Is_Concurrent_Record_Type (Scope (Discriminal_Link (E)))));
                  Is_Concurrent_Record_Type (Scope (Discriminal_Link (E)))));
 
 
   end Denotes_Discriminant;
   end Denotes_Discriminant;
 
 
   -------------------------
   -------------------------
   -- Denotes_Same_Object --
   -- Denotes_Same_Object --
   -------------------------
   -------------------------
 
 
   function Denotes_Same_Object (A1, A2 : Node_Id) return Boolean is
   function Denotes_Same_Object (A1, A2 : Node_Id) return Boolean is
   begin
   begin
      --  If we have entity names, then must be same entity
      --  If we have entity names, then must be same entity
 
 
      if Is_Entity_Name (A1) then
      if Is_Entity_Name (A1) then
         if Is_Entity_Name (A2) then
         if Is_Entity_Name (A2) then
            return Entity (A1) = Entity (A2);
            return Entity (A1) = Entity (A2);
         else
         else
            return False;
            return False;
         end if;
         end if;
 
 
      --  No match if not same node kind
      --  No match if not same node kind
 
 
      elsif Nkind (A1) /= Nkind (A2) then
      elsif Nkind (A1) /= Nkind (A2) then
         return False;
         return False;
 
 
      --  For selected components, must have same prefix and selector
      --  For selected components, must have same prefix and selector
 
 
      elsif Nkind (A1) = N_Selected_Component then
      elsif Nkind (A1) = N_Selected_Component then
         return Denotes_Same_Object (Prefix (A1), Prefix (A2))
         return Denotes_Same_Object (Prefix (A1), Prefix (A2))
           and then
           and then
         Entity (Selector_Name (A1)) = Entity (Selector_Name (A2));
         Entity (Selector_Name (A1)) = Entity (Selector_Name (A2));
 
 
      --  For explicit dereferences, prefixes must be same
      --  For explicit dereferences, prefixes must be same
 
 
      elsif Nkind (A1) = N_Explicit_Dereference then
      elsif Nkind (A1) = N_Explicit_Dereference then
         return Denotes_Same_Object (Prefix (A1), Prefix (A2));
         return Denotes_Same_Object (Prefix (A1), Prefix (A2));
 
 
      --  For indexed components, prefixes and all subscripts must be the same
      --  For indexed components, prefixes and all subscripts must be the same
 
 
      elsif Nkind (A1) = N_Indexed_Component then
      elsif Nkind (A1) = N_Indexed_Component then
         if Denotes_Same_Object (Prefix (A1), Prefix (A2)) then
         if Denotes_Same_Object (Prefix (A1), Prefix (A2)) then
            declare
            declare
               Indx1 : Node_Id;
               Indx1 : Node_Id;
               Indx2 : Node_Id;
               Indx2 : Node_Id;
 
 
            begin
            begin
               Indx1 := First (Expressions (A1));
               Indx1 := First (Expressions (A1));
               Indx2 := First (Expressions (A2));
               Indx2 := First (Expressions (A2));
               while Present (Indx1) loop
               while Present (Indx1) loop
 
 
                  --  Shouldn't we be checking that values are the same???
                  --  Shouldn't we be checking that values are the same???
 
 
                  if not Denotes_Same_Object (Indx1, Indx2) then
                  if not Denotes_Same_Object (Indx1, Indx2) then
                     return False;
                     return False;
                  end if;
                  end if;
 
 
                  Next (Indx1);
                  Next (Indx1);
                  Next (Indx2);
                  Next (Indx2);
               end loop;
               end loop;
 
 
               return True;
               return True;
            end;
            end;
         else
         else
            return False;
            return False;
         end if;
         end if;
 
 
      --  For slices, prefixes must match and bounds must match
      --  For slices, prefixes must match and bounds must match
 
 
      elsif Nkind (A1) = N_Slice
      elsif Nkind (A1) = N_Slice
        and then Denotes_Same_Object (Prefix (A1), Prefix (A2))
        and then Denotes_Same_Object (Prefix (A1), Prefix (A2))
      then
      then
         declare
         declare
            Lo1, Lo2, Hi1, Hi2 : Node_Id;
            Lo1, Lo2, Hi1, Hi2 : Node_Id;
 
 
         begin
         begin
            Get_Index_Bounds (Etype (A1), Lo1, Hi1);
            Get_Index_Bounds (Etype (A1), Lo1, Hi1);
            Get_Index_Bounds (Etype (A2), Lo2, Hi2);
            Get_Index_Bounds (Etype (A2), Lo2, Hi2);
 
 
            --  Check whether bounds are statically identical. There is no
            --  Check whether bounds are statically identical. There is no
            --  attempt to detect partial overlap of slices.
            --  attempt to detect partial overlap of slices.
 
 
            --  What about an array and a slice of an array???
            --  What about an array and a slice of an array???
 
 
            return Denotes_Same_Object (Lo1, Lo2)
            return Denotes_Same_Object (Lo1, Lo2)
              and then Denotes_Same_Object (Hi1, Hi2);
              and then Denotes_Same_Object (Hi1, Hi2);
         end;
         end;
 
 
         --  Literals will appear as indices. Isn't this where we should check
         --  Literals will appear as indices. Isn't this where we should check
         --  Known_At_Compile_Time at least if we are generating warnings ???
         --  Known_At_Compile_Time at least if we are generating warnings ???
 
 
      elsif Nkind (A1) = N_Integer_Literal then
      elsif Nkind (A1) = N_Integer_Literal then
         return Intval (A1) = Intval (A2);
         return Intval (A1) = Intval (A2);
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Denotes_Same_Object;
   end Denotes_Same_Object;
 
 
   -------------------------
   -------------------------
   -- Denotes_Same_Prefix --
   -- Denotes_Same_Prefix --
   -------------------------
   -------------------------
 
 
   function Denotes_Same_Prefix (A1, A2 : Node_Id) return Boolean is
   function Denotes_Same_Prefix (A1, A2 : Node_Id) return Boolean is
 
 
   begin
   begin
      if Is_Entity_Name (A1) then
      if Is_Entity_Name (A1) then
         if Nkind_In (A2, N_Selected_Component, N_Indexed_Component) then
         if Nkind_In (A2, N_Selected_Component, N_Indexed_Component) then
            return Denotes_Same_Object (A1, Prefix (A2))
            return Denotes_Same_Object (A1, Prefix (A2))
              or else Denotes_Same_Prefix (A1, Prefix (A2));
              or else Denotes_Same_Prefix (A1, Prefix (A2));
         else
         else
            return False;
            return False;
         end if;
         end if;
 
 
      elsif Is_Entity_Name (A2) then
      elsif Is_Entity_Name (A2) then
         return Denotes_Same_Prefix (A2, A1);
         return Denotes_Same_Prefix (A2, A1);
 
 
      elsif Nkind_In (A1, N_Selected_Component, N_Indexed_Component, N_Slice)
      elsif Nkind_In (A1, N_Selected_Component, N_Indexed_Component, N_Slice)
              and then
              and then
            Nkind_In (A2, N_Selected_Component, N_Indexed_Component, N_Slice)
            Nkind_In (A2, N_Selected_Component, N_Indexed_Component, N_Slice)
      then
      then
         declare
         declare
            Root1, Root2 : Node_Id;
            Root1, Root2 : Node_Id;
            Depth1, Depth2 : Int := 0;
            Depth1, Depth2 : Int := 0;
 
 
         begin
         begin
            Root1 := Prefix (A1);
            Root1 := Prefix (A1);
            while not Is_Entity_Name (Root1) loop
            while not Is_Entity_Name (Root1) loop
               if not Nkind_In
               if not Nkind_In
                 (Root1, N_Selected_Component, N_Indexed_Component)
                 (Root1, N_Selected_Component, N_Indexed_Component)
               then
               then
                  return False;
                  return False;
               else
               else
                  Root1 := Prefix (Root1);
                  Root1 := Prefix (Root1);
               end if;
               end if;
 
 
               Depth1 := Depth1 + 1;
               Depth1 := Depth1 + 1;
            end loop;
            end loop;
 
 
            Root2 := Prefix (A2);
            Root2 := Prefix (A2);
            while not Is_Entity_Name (Root2) loop
            while not Is_Entity_Name (Root2) loop
               if not Nkind_In
               if not Nkind_In
                 (Root2, N_Selected_Component, N_Indexed_Component)
                 (Root2, N_Selected_Component, N_Indexed_Component)
               then
               then
                  return False;
                  return False;
               else
               else
                  Root2 := Prefix (Root2);
                  Root2 := Prefix (Root2);
               end if;
               end if;
 
 
               Depth2 := Depth2 + 1;
               Depth2 := Depth2 + 1;
            end loop;
            end loop;
 
 
            --  If both have the same depth and they do not denote the same
            --  If both have the same depth and they do not denote the same
            --  object, they are disjoint and not warning is needed.
            --  object, they are disjoint and not warning is needed.
 
 
            if Depth1 = Depth2 then
            if Depth1 = Depth2 then
               return False;
               return False;
 
 
            elsif Depth1 > Depth2 then
            elsif Depth1 > Depth2 then
               Root1 := Prefix (A1);
               Root1 := Prefix (A1);
               for I in 1 .. Depth1 - Depth2 - 1 loop
               for I in 1 .. Depth1 - Depth2 - 1 loop
                  Root1 := Prefix (Root1);
                  Root1 := Prefix (Root1);
               end loop;
               end loop;
 
 
               return Denotes_Same_Object (Root1, A2);
               return Denotes_Same_Object (Root1, A2);
 
 
            else
            else
               Root2 := Prefix (A2);
               Root2 := Prefix (A2);
               for I in 1 .. Depth2 - Depth1 - 1 loop
               for I in 1 .. Depth2 - Depth1 - 1 loop
                  Root2 := Prefix (Root2);
                  Root2 := Prefix (Root2);
               end loop;
               end loop;
 
 
               return Denotes_Same_Object (A1, Root2);
               return Denotes_Same_Object (A1, Root2);
            end if;
            end if;
         end;
         end;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Denotes_Same_Prefix;
   end Denotes_Same_Prefix;
 
 
   ----------------------
   ----------------------
   -- Denotes_Variable --
   -- Denotes_Variable --
   ----------------------
   ----------------------
 
 
   function Denotes_Variable (N : Node_Id) return Boolean is
   function Denotes_Variable (N : Node_Id) return Boolean is
   begin
   begin
      return Is_Variable (N) and then Paren_Count (N) = 0;
      return Is_Variable (N) and then Paren_Count (N) = 0;
   end Denotes_Variable;
   end Denotes_Variable;
 
 
   -----------------------------
   -----------------------------
   -- Depends_On_Discriminant --
   -- Depends_On_Discriminant --
   -----------------------------
   -----------------------------
 
 
   function Depends_On_Discriminant (N : Node_Id) return Boolean is
   function Depends_On_Discriminant (N : Node_Id) return Boolean is
      L : Node_Id;
      L : Node_Id;
      H : Node_Id;
      H : Node_Id;
 
 
   begin
   begin
      Get_Index_Bounds (N, L, H);
      Get_Index_Bounds (N, L, H);
      return Denotes_Discriminant (L) or else Denotes_Discriminant (H);
      return Denotes_Discriminant (L) or else Denotes_Discriminant (H);
   end Depends_On_Discriminant;
   end Depends_On_Discriminant;
 
 
   -------------------------
   -------------------------
   -- Designate_Same_Unit --
   -- Designate_Same_Unit --
   -------------------------
   -------------------------
 
 
   function Designate_Same_Unit
   function Designate_Same_Unit
     (Name1 : Node_Id;
     (Name1 : Node_Id;
      Name2 : Node_Id) return Boolean
      Name2 : Node_Id) return Boolean
   is
   is
      K1 : constant Node_Kind := Nkind (Name1);
      K1 : constant Node_Kind := Nkind (Name1);
      K2 : constant Node_Kind := Nkind (Name2);
      K2 : constant Node_Kind := Nkind (Name2);
 
 
      function Prefix_Node (N : Node_Id) return Node_Id;
      function Prefix_Node (N : Node_Id) return Node_Id;
      --  Returns the parent unit name node of a defining program unit name
      --  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.
      --  or the prefix if N is a selected component or an expanded name.
 
 
      function Select_Node (N : Node_Id) return Node_Id;
      function Select_Node (N : Node_Id) return Node_Id;
      --  Returns the defining identifier node of a defining program unit
      --  Returns the defining identifier node of a defining program unit
      --  name or  the selector node if N is a selected component or an
      --  name or  the selector node if N is a selected component or an
      --  expanded name.
      --  expanded name.
 
 
      -----------------
      -----------------
      -- Prefix_Node --
      -- Prefix_Node --
      -----------------
      -----------------
 
 
      function Prefix_Node (N : Node_Id) return Node_Id is
      function Prefix_Node (N : Node_Id) return Node_Id is
      begin
      begin
         if Nkind (N) = N_Defining_Program_Unit_Name then
         if Nkind (N) = N_Defining_Program_Unit_Name then
            return Name (N);
            return Name (N);
 
 
         else
         else
            return Prefix (N);
            return Prefix (N);
         end if;
         end if;
      end Prefix_Node;
      end Prefix_Node;
 
 
      -----------------
      -----------------
      -- Select_Node --
      -- Select_Node --
      -----------------
      -----------------
 
 
      function Select_Node (N : Node_Id) return Node_Id is
      function Select_Node (N : Node_Id) return Node_Id is
      begin
      begin
         if Nkind (N) = N_Defining_Program_Unit_Name then
         if Nkind (N) = N_Defining_Program_Unit_Name then
            return Defining_Identifier (N);
            return Defining_Identifier (N);
 
 
         else
         else
            return Selector_Name (N);
            return Selector_Name (N);
         end if;
         end if;
      end Select_Node;
      end Select_Node;
 
 
   --  Start of processing for Designate_Next_Unit
   --  Start of processing for Designate_Next_Unit
 
 
   begin
   begin
      if (K1 = N_Identifier or else
      if (K1 = N_Identifier or else
          K1 = N_Defining_Identifier)
          K1 = N_Defining_Identifier)
        and then
        and then
         (K2 = N_Identifier or else
         (K2 = N_Identifier or else
          K2 = N_Defining_Identifier)
          K2 = N_Defining_Identifier)
      then
      then
         return Chars (Name1) = Chars (Name2);
         return Chars (Name1) = Chars (Name2);
 
 
      elsif
      elsif
         (K1 = N_Expanded_Name      or else
         (K1 = N_Expanded_Name      or else
          K1 = N_Selected_Component or else
          K1 = N_Selected_Component or else
          K1 = N_Defining_Program_Unit_Name)
          K1 = N_Defining_Program_Unit_Name)
        and then
        and then
         (K2 = N_Expanded_Name      or else
         (K2 = N_Expanded_Name      or else
          K2 = N_Selected_Component or else
          K2 = N_Selected_Component or else
          K2 = N_Defining_Program_Unit_Name)
          K2 = N_Defining_Program_Unit_Name)
      then
      then
         return
         return
           (Chars (Select_Node (Name1)) = Chars (Select_Node (Name2)))
           (Chars (Select_Node (Name1)) = Chars (Select_Node (Name2)))
             and then
             and then
               Designate_Same_Unit (Prefix_Node (Name1), Prefix_Node (Name2));
               Designate_Same_Unit (Prefix_Node (Name1), Prefix_Node (Name2));
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Designate_Same_Unit;
   end Designate_Same_Unit;
 
 
   ----------------------------
   ----------------------------
   -- Enclosing_Generic_Body --
   -- Enclosing_Generic_Body --
   ----------------------------
   ----------------------------
 
 
   function Enclosing_Generic_Body
   function Enclosing_Generic_Body
     (N : Node_Id) return Node_Id
     (N : Node_Id) return Node_Id
   is
   is
      P    : Node_Id;
      P    : Node_Id;
      Decl : Node_Id;
      Decl : Node_Id;
      Spec : Node_Id;
      Spec : Node_Id;
 
 
   begin
   begin
      P := Parent (N);
      P := Parent (N);
      while Present (P) loop
      while Present (P) loop
         if Nkind (P) = N_Package_Body
         if Nkind (P) = N_Package_Body
           or else Nkind (P) = N_Subprogram_Body
           or else Nkind (P) = N_Subprogram_Body
         then
         then
            Spec := Corresponding_Spec (P);
            Spec := Corresponding_Spec (P);
 
 
            if Present (Spec) then
            if Present (Spec) then
               Decl := Unit_Declaration_Node (Spec);
               Decl := Unit_Declaration_Node (Spec);
 
 
               if Nkind (Decl) = N_Generic_Package_Declaration
               if Nkind (Decl) = N_Generic_Package_Declaration
                 or else Nkind (Decl) = N_Generic_Subprogram_Declaration
                 or else Nkind (Decl) = N_Generic_Subprogram_Declaration
               then
               then
                  return P;
                  return P;
               end if;
               end if;
            end if;
            end if;
         end if;
         end if;
 
 
         P := Parent (P);
         P := Parent (P);
      end loop;
      end loop;
 
 
      return Empty;
      return Empty;
   end Enclosing_Generic_Body;
   end Enclosing_Generic_Body;
 
 
   ----------------------------
   ----------------------------
   -- Enclosing_Generic_Unit --
   -- Enclosing_Generic_Unit --
   ----------------------------
   ----------------------------
 
 
   function Enclosing_Generic_Unit
   function Enclosing_Generic_Unit
     (N : Node_Id) return Node_Id
     (N : Node_Id) return Node_Id
   is
   is
      P    : Node_Id;
      P    : Node_Id;
      Decl : Node_Id;
      Decl : Node_Id;
      Spec : Node_Id;
      Spec : Node_Id;
 
 
   begin
   begin
      P := Parent (N);
      P := Parent (N);
      while Present (P) loop
      while Present (P) loop
         if Nkind (P) = N_Generic_Package_Declaration
         if Nkind (P) = N_Generic_Package_Declaration
           or else Nkind (P) = N_Generic_Subprogram_Declaration
           or else Nkind (P) = N_Generic_Subprogram_Declaration
         then
         then
            return P;
            return P;
 
 
         elsif Nkind (P) = N_Package_Body
         elsif Nkind (P) = N_Package_Body
           or else Nkind (P) = N_Subprogram_Body
           or else Nkind (P) = N_Subprogram_Body
         then
         then
            Spec := Corresponding_Spec (P);
            Spec := Corresponding_Spec (P);
 
 
            if Present (Spec) then
            if Present (Spec) then
               Decl := Unit_Declaration_Node (Spec);
               Decl := Unit_Declaration_Node (Spec);
 
 
               if Nkind (Decl) = N_Generic_Package_Declaration
               if Nkind (Decl) = N_Generic_Package_Declaration
                 or else Nkind (Decl) = N_Generic_Subprogram_Declaration
                 or else Nkind (Decl) = N_Generic_Subprogram_Declaration
               then
               then
                  return Decl;
                  return Decl;
               end if;
               end if;
            end if;
            end if;
         end if;
         end if;
 
 
         P := Parent (P);
         P := Parent (P);
      end loop;
      end loop;
 
 
      return Empty;
      return Empty;
   end Enclosing_Generic_Unit;
   end Enclosing_Generic_Unit;
 
 
   -------------------------------
   -------------------------------
   -- Enclosing_Lib_Unit_Entity --
   -- Enclosing_Lib_Unit_Entity --
   -------------------------------
   -------------------------------
 
 
   function Enclosing_Lib_Unit_Entity return Entity_Id is
   function Enclosing_Lib_Unit_Entity return Entity_Id is
      Unit_Entity : Entity_Id;
      Unit_Entity : Entity_Id;
 
 
   begin
   begin
      --  Look for enclosing library unit entity by following scope links.
      --  Look for enclosing library unit entity by following scope links.
      --  Equivalent to, but faster than indexing through the scope stack.
      --  Equivalent to, but faster than indexing through the scope stack.
 
 
      Unit_Entity := Current_Scope;
      Unit_Entity := Current_Scope;
      while (Present (Scope (Unit_Entity))
      while (Present (Scope (Unit_Entity))
        and then Scope (Unit_Entity) /= Standard_Standard)
        and then Scope (Unit_Entity) /= Standard_Standard)
        and not Is_Child_Unit (Unit_Entity)
        and not Is_Child_Unit (Unit_Entity)
      loop
      loop
         Unit_Entity := Scope (Unit_Entity);
         Unit_Entity := Scope (Unit_Entity);
      end loop;
      end loop;
 
 
      return Unit_Entity;
      return Unit_Entity;
   end Enclosing_Lib_Unit_Entity;
   end Enclosing_Lib_Unit_Entity;
 
 
   -----------------------------
   -----------------------------
   -- Enclosing_Lib_Unit_Node --
   -- Enclosing_Lib_Unit_Node --
   -----------------------------
   -----------------------------
 
 
   function Enclosing_Lib_Unit_Node (N : Node_Id) return Node_Id is
   function Enclosing_Lib_Unit_Node (N : Node_Id) return Node_Id is
      Current_Node : Node_Id;
      Current_Node : Node_Id;
 
 
   begin
   begin
      Current_Node := N;
      Current_Node := N;
      while Present (Current_Node)
      while Present (Current_Node)
        and then Nkind (Current_Node) /= N_Compilation_Unit
        and then Nkind (Current_Node) /= N_Compilation_Unit
      loop
      loop
         Current_Node := Parent (Current_Node);
         Current_Node := Parent (Current_Node);
      end loop;
      end loop;
 
 
      if Nkind (Current_Node) /= N_Compilation_Unit then
      if Nkind (Current_Node) /= N_Compilation_Unit then
         return Empty;
         return Empty;
      end if;
      end if;
 
 
      return Current_Node;
      return Current_Node;
   end Enclosing_Lib_Unit_Node;
   end Enclosing_Lib_Unit_Node;
 
 
   --------------------------
   --------------------------
   -- Enclosing_Subprogram --
   -- Enclosing_Subprogram --
   --------------------------
   --------------------------
 
 
   function Enclosing_Subprogram (E : Entity_Id) return Entity_Id is
   function Enclosing_Subprogram (E : Entity_Id) return Entity_Id is
      Dynamic_Scope : constant Entity_Id := Enclosing_Dynamic_Scope (E);
      Dynamic_Scope : constant Entity_Id := Enclosing_Dynamic_Scope (E);
 
 
   begin
   begin
      if Dynamic_Scope = Standard_Standard then
      if Dynamic_Scope = Standard_Standard then
         return Empty;
         return Empty;
 
 
      elsif Dynamic_Scope = Empty then
      elsif Dynamic_Scope = Empty then
         return Empty;
         return Empty;
 
 
      elsif Ekind (Dynamic_Scope) = E_Subprogram_Body then
      elsif Ekind (Dynamic_Scope) = E_Subprogram_Body then
         return Corresponding_Spec (Parent (Parent (Dynamic_Scope)));
         return Corresponding_Spec (Parent (Parent (Dynamic_Scope)));
 
 
      elsif Ekind (Dynamic_Scope) = E_Block
      elsif Ekind (Dynamic_Scope) = E_Block
        or else Ekind (Dynamic_Scope) = E_Return_Statement
        or else Ekind (Dynamic_Scope) = E_Return_Statement
      then
      then
         return Enclosing_Subprogram (Dynamic_Scope);
         return Enclosing_Subprogram (Dynamic_Scope);
 
 
      elsif Ekind (Dynamic_Scope) = E_Task_Type then
      elsif Ekind (Dynamic_Scope) = E_Task_Type then
         return Get_Task_Body_Procedure (Dynamic_Scope);
         return Get_Task_Body_Procedure (Dynamic_Scope);
 
 
      elsif Convention (Dynamic_Scope) = Convention_Protected then
      elsif Convention (Dynamic_Scope) = Convention_Protected then
         return Protected_Body_Subprogram (Dynamic_Scope);
         return Protected_Body_Subprogram (Dynamic_Scope);
 
 
      else
      else
         return Dynamic_Scope;
         return Dynamic_Scope;
      end if;
      end if;
   end Enclosing_Subprogram;
   end Enclosing_Subprogram;
 
 
   ------------------------
   ------------------------
   -- Ensure_Freeze_Node --
   -- Ensure_Freeze_Node --
   ------------------------
   ------------------------
 
 
   procedure Ensure_Freeze_Node (E : Entity_Id) is
   procedure Ensure_Freeze_Node (E : Entity_Id) is
      FN : Node_Id;
      FN : Node_Id;
 
 
   begin
   begin
      if No (Freeze_Node (E)) then
      if No (Freeze_Node (E)) then
         FN := Make_Freeze_Entity (Sloc (E));
         FN := Make_Freeze_Entity (Sloc (E));
         Set_Has_Delayed_Freeze (E);
         Set_Has_Delayed_Freeze (E);
         Set_Freeze_Node (E, FN);
         Set_Freeze_Node (E, FN);
         Set_Access_Types_To_Process (FN, No_Elist);
         Set_Access_Types_To_Process (FN, No_Elist);
         Set_TSS_Elist (FN, No_Elist);
         Set_TSS_Elist (FN, No_Elist);
         Set_Entity (FN, E);
         Set_Entity (FN, E);
      end if;
      end if;
   end Ensure_Freeze_Node;
   end Ensure_Freeze_Node;
 
 
   ----------------
   ----------------
   -- Enter_Name --
   -- Enter_Name --
   ----------------
   ----------------
 
 
   procedure Enter_Name (Def_Id : Entity_Id) is
   procedure Enter_Name (Def_Id : Entity_Id) is
      C : constant Entity_Id := Current_Entity (Def_Id);
      C : constant Entity_Id := Current_Entity (Def_Id);
      E : constant Entity_Id := Current_Entity_In_Scope (Def_Id);
      E : constant Entity_Id := Current_Entity_In_Scope (Def_Id);
      S : constant Entity_Id := Current_Scope;
      S : constant Entity_Id := Current_Scope;
 
 
   begin
   begin
      Generate_Definition (Def_Id);
      Generate_Definition (Def_Id);
 
 
      --  Add new name to current scope declarations. Check for duplicate
      --  Add new name to current scope declarations. Check for duplicate
      --  declaration, which may or may not be a genuine error.
      --  declaration, which may or may not be a genuine error.
 
 
      if Present (E) then
      if Present (E) then
 
 
         --  Case of previous entity entered because of a missing declaration
         --  Case of previous entity entered because of a missing declaration
         --  or else a bad subtype indication. Best is to use the new entity,
         --  or else a bad subtype indication. Best is to use the new entity,
         --  and make the previous one invisible.
         --  and make the previous one invisible.
 
 
         if Etype (E) = Any_Type then
         if Etype (E) = Any_Type then
            Set_Is_Immediately_Visible (E, False);
            Set_Is_Immediately_Visible (E, False);
 
 
         --  Case of renaming declaration constructed for package instances.
         --  Case of renaming declaration constructed for package instances.
         --  if there is an explicit declaration with the same identifier,
         --  if there is an explicit declaration with the same identifier,
         --  the renaming is not immediately visible any longer, but remains
         --  the renaming is not immediately visible any longer, but remains
         --  visible through selected component notation.
         --  visible through selected component notation.
 
 
         elsif Nkind (Parent (E)) = N_Package_Renaming_Declaration
         elsif Nkind (Parent (E)) = N_Package_Renaming_Declaration
           and then not Comes_From_Source (E)
           and then not Comes_From_Source (E)
         then
         then
            Set_Is_Immediately_Visible (E, False);
            Set_Is_Immediately_Visible (E, False);
 
 
         --  The new entity may be the package renaming, which has the same
         --  The new entity may be the package renaming, which has the same
         --  same name as a generic formal which has been seen already.
         --  same name as a generic formal which has been seen already.
 
 
         elsif Nkind (Parent (Def_Id)) = N_Package_Renaming_Declaration
         elsif Nkind (Parent (Def_Id)) = N_Package_Renaming_Declaration
            and then not Comes_From_Source (Def_Id)
            and then not Comes_From_Source (Def_Id)
         then
         then
            Set_Is_Immediately_Visible (E, False);
            Set_Is_Immediately_Visible (E, False);
 
 
         --  For a fat pointer corresponding to a remote access to subprogram,
         --  For a fat pointer corresponding to a remote access to subprogram,
         --  we use the same identifier as the RAS type, so that the proper
         --  we use the same identifier as the RAS type, so that the proper
         --  name appears in the stub. This type is only retrieved through
         --  name appears in the stub. This type is only retrieved through
         --  the RAS type and never by visibility, and is not added to the
         --  the RAS type and never by visibility, and is not added to the
         --  visibility list (see below).
         --  visibility list (see below).
 
 
         elsif Nkind (Parent (Def_Id)) = N_Full_Type_Declaration
         elsif Nkind (Parent (Def_Id)) = N_Full_Type_Declaration
           and then Present (Corresponding_Remote_Type (Def_Id))
           and then Present (Corresponding_Remote_Type (Def_Id))
         then
         then
            null;
            null;
 
 
         --  A controller component for a type extension overrides the
         --  A controller component for a type extension overrides the
         --  inherited component.
         --  inherited component.
 
 
         elsif Chars (E) = Name_uController then
         elsif Chars (E) = Name_uController then
            null;
            null;
 
 
         --  Case of an implicit operation or derived literal. The new entity
         --  Case of an implicit operation or derived literal. The new entity
         --  hides the implicit one,  which is removed from all visibility,
         --  hides the implicit one,  which is removed from all visibility,
         --  i.e. the entity list of its scope, and homonym chain of its name.
         --  i.e. the entity list of its scope, and homonym chain of its name.
 
 
         elsif (Is_Overloadable (E) and then Is_Inherited_Operation (E))
         elsif (Is_Overloadable (E) and then Is_Inherited_Operation (E))
           or else Is_Internal (E)
           or else Is_Internal (E)
         then
         then
            declare
            declare
               Prev     : Entity_Id;
               Prev     : Entity_Id;
               Prev_Vis : Entity_Id;
               Prev_Vis : Entity_Id;
               Decl     : constant Node_Id := Parent (E);
               Decl     : constant Node_Id := Parent (E);
 
 
            begin
            begin
               --  If E is an implicit declaration, it cannot be the first
               --  If E is an implicit declaration, it cannot be the first
               --  entity in the scope.
               --  entity in the scope.
 
 
               Prev := First_Entity (Current_Scope);
               Prev := First_Entity (Current_Scope);
               while Present (Prev)
               while Present (Prev)
                 and then Next_Entity (Prev) /= E
                 and then Next_Entity (Prev) /= E
               loop
               loop
                  Next_Entity (Prev);
                  Next_Entity (Prev);
               end loop;
               end loop;
 
 
               if No (Prev) then
               if No (Prev) then
 
 
                  --  If E is not on the entity chain of the current scope,
                  --  If E is not on the entity chain of the current scope,
                  --  it is an implicit declaration in the generic formal
                  --  it is an implicit declaration in the generic formal
                  --  part of a generic subprogram. When analyzing the body,
                  --  part of a generic subprogram. When analyzing the body,
                  --  the generic formals are visible but not on the entity
                  --  the generic formals are visible but not on the entity
                  --  chain of the subprogram. The new entity will become
                  --  chain of the subprogram. The new entity will become
                  --  the visible one in the body.
                  --  the visible one in the body.
 
 
                  pragma Assert
                  pragma Assert
                    (Nkind (Parent (Decl)) = N_Generic_Subprogram_Declaration);
                    (Nkind (Parent (Decl)) = N_Generic_Subprogram_Declaration);
                  null;
                  null;
 
 
               else
               else
                  Set_Next_Entity (Prev, Next_Entity (E));
                  Set_Next_Entity (Prev, Next_Entity (E));
 
 
                  if No (Next_Entity (Prev)) then
                  if No (Next_Entity (Prev)) then
                     Set_Last_Entity (Current_Scope, Prev);
                     Set_Last_Entity (Current_Scope, Prev);
                  end if;
                  end if;
 
 
                  if E = Current_Entity (E) then
                  if E = Current_Entity (E) then
                     Prev_Vis := Empty;
                     Prev_Vis := Empty;
 
 
                  else
                  else
                     Prev_Vis := Current_Entity (E);
                     Prev_Vis := Current_Entity (E);
                     while Homonym (Prev_Vis) /= E loop
                     while Homonym (Prev_Vis) /= E loop
                        Prev_Vis := Homonym (Prev_Vis);
                        Prev_Vis := Homonym (Prev_Vis);
                     end loop;
                     end loop;
                  end if;
                  end if;
 
 
                  if Present (Prev_Vis)  then
                  if Present (Prev_Vis)  then
 
 
                     --  Skip E in the visibility chain
                     --  Skip E in the visibility chain
 
 
                     Set_Homonym (Prev_Vis, Homonym (E));
                     Set_Homonym (Prev_Vis, Homonym (E));
 
 
                  else
                  else
                     Set_Name_Entity_Id (Chars (E), Homonym (E));
                     Set_Name_Entity_Id (Chars (E), Homonym (E));
                  end if;
                  end if;
               end if;
               end if;
            end;
            end;
 
 
         --  This section of code could use a comment ???
         --  This section of code could use a comment ???
 
 
         elsif Present (Etype (E))
         elsif Present (Etype (E))
           and then Is_Concurrent_Type (Etype (E))
           and then Is_Concurrent_Type (Etype (E))
           and then E = Def_Id
           and then E = Def_Id
         then
         then
            return;
            return;
 
 
         --  If the homograph is a protected component renaming, it should not
         --  If the homograph is a protected component renaming, it should not
         --  be hiding the current entity. Such renamings are treated as weak
         --  be hiding the current entity. Such renamings are treated as weak
         --  declarations.
         --  declarations.
 
 
         elsif Is_Prival (E) then
         elsif Is_Prival (E) then
            Set_Is_Immediately_Visible (E, False);
            Set_Is_Immediately_Visible (E, False);
 
 
         --  In this case the current entity is a protected component renaming.
         --  In this case the current entity is a protected component renaming.
         --  Perform minimal decoration by setting the scope and return since
         --  Perform minimal decoration by setting the scope and return since
         --  the prival should not be hiding other visible entities.
         --  the prival should not be hiding other visible entities.
 
 
         elsif Is_Prival (Def_Id) then
         elsif Is_Prival (Def_Id) then
            Set_Scope (Def_Id, Current_Scope);
            Set_Scope (Def_Id, Current_Scope);
            return;
            return;
 
 
         --  Analogous to privals, the discriminal generated for an entry
         --  Analogous to privals, the discriminal generated for an entry
         --  index parameter acts as a weak declaration. Perform minimal
         --  index parameter acts as a weak declaration. Perform minimal
         --  decoration to avoid bogus errors.
         --  decoration to avoid bogus errors.
 
 
         elsif Is_Discriminal (Def_Id)
         elsif Is_Discriminal (Def_Id)
           and then Ekind (Discriminal_Link (Def_Id)) = E_Entry_Index_Parameter
           and then Ekind (Discriminal_Link (Def_Id)) = E_Entry_Index_Parameter
         then
         then
            Set_Scope (Def_Id, Current_Scope);
            Set_Scope (Def_Id, Current_Scope);
            return;
            return;
 
 
         --  In the body or private part of an instance, a type extension
         --  In the body or private part of an instance, a type extension
         --  may introduce a component with the same name as that of an
         --  may introduce a component with the same name as that of an
         --  actual. The legality rule is not enforced, but the semantics
         --  actual. The legality rule is not enforced, but the semantics
         --  of the full type with two components of the same name are not
         --  of the full type with two components of the same name are not
         --  clear at this point ???
         --  clear at this point ???
 
 
         elsif In_Instance_Not_Visible then
         elsif In_Instance_Not_Visible then
            null;
            null;
 
 
         --  When compiling a package body, some child units may have become
         --  When compiling a package body, some child units may have become
         --  visible. They cannot conflict with local entities that hide them.
         --  visible. They cannot conflict with local entities that hide them.
 
 
         elsif Is_Child_Unit (E)
         elsif Is_Child_Unit (E)
           and then In_Open_Scopes (Scope (E))
           and then In_Open_Scopes (Scope (E))
           and then not Is_Immediately_Visible (E)
           and then not Is_Immediately_Visible (E)
         then
         then
            null;
            null;
 
 
         --  Conversely, with front-end inlining we may compile the parent
         --  Conversely, with front-end inlining we may compile the parent
         --  body first, and a child unit subsequently. The context is now
         --  body first, and a child unit subsequently. The context is now
         --  the parent spec, and body entities are not visible.
         --  the parent spec, and body entities are not visible.
 
 
         elsif Is_Child_Unit (Def_Id)
         elsif Is_Child_Unit (Def_Id)
           and then Is_Package_Body_Entity (E)
           and then Is_Package_Body_Entity (E)
           and then not In_Package_Body (Current_Scope)
           and then not In_Package_Body (Current_Scope)
         then
         then
            null;
            null;
 
 
         --  Case of genuine duplicate declaration
         --  Case of genuine duplicate declaration
 
 
         else
         else
            Error_Msg_Sloc := Sloc (E);
            Error_Msg_Sloc := Sloc (E);
 
 
            --  If the previous declaration is an incomplete type declaration
            --  If the previous declaration is an incomplete type declaration
            --  this may be an attempt to complete it with a private type.
            --  this may be an attempt to complete it with a private type.
            --  The following avoids confusing cascaded errors.
            --  The following avoids confusing cascaded errors.
 
 
            if Nkind (Parent (E)) = N_Incomplete_Type_Declaration
            if Nkind (Parent (E)) = N_Incomplete_Type_Declaration
              and then Nkind (Parent (Def_Id)) = N_Private_Type_Declaration
              and then Nkind (Parent (Def_Id)) = N_Private_Type_Declaration
            then
            then
               Error_Msg_N
               Error_Msg_N
                 ("incomplete type cannot be completed with a private " &
                 ("incomplete type cannot be completed with a private " &
                  "declaration", Parent (Def_Id));
                  "declaration", Parent (Def_Id));
               Set_Is_Immediately_Visible (E, False);
               Set_Is_Immediately_Visible (E, False);
               Set_Full_View (E, Def_Id);
               Set_Full_View (E, Def_Id);
 
 
            --  An inherited component of a record conflicts with a new
            --  An inherited component of a record conflicts with a new
            --  discriminant. The discriminant is inserted first in the scope,
            --  discriminant. The discriminant is inserted first in the scope,
            --  but the error should be posted on it, not on the component.
            --  but the error should be posted on it, not on the component.
 
 
            elsif Ekind (E) = E_Discriminant
            elsif Ekind (E) = E_Discriminant
              and then Present (Scope (Def_Id))
              and then Present (Scope (Def_Id))
              and then Scope (Def_Id) /= Current_Scope
              and then Scope (Def_Id) /= Current_Scope
            then
            then
               Error_Msg_Sloc := Sloc (Def_Id);
               Error_Msg_Sloc := Sloc (Def_Id);
               Error_Msg_N ("& conflicts with declaration#", E);
               Error_Msg_N ("& conflicts with declaration#", E);
               return;
               return;
 
 
            --  If the name of the unit appears in its own context clause,
            --  If the name of the unit appears in its own context clause,
            --  a dummy package with the name has already been created, and
            --  a dummy package with the name has already been created, and
            --  the error emitted. Try to continue quietly.
            --  the error emitted. Try to continue quietly.
 
 
            elsif Error_Posted (E)
            elsif Error_Posted (E)
              and then Sloc (E) = No_Location
              and then Sloc (E) = No_Location
              and then Nkind (Parent (E)) = N_Package_Specification
              and then Nkind (Parent (E)) = N_Package_Specification
              and then Current_Scope = Standard_Standard
              and then Current_Scope = Standard_Standard
            then
            then
               Set_Scope (Def_Id, Current_Scope);
               Set_Scope (Def_Id, Current_Scope);
               return;
               return;
 
 
            else
            else
               Error_Msg_N ("& conflicts with declaration#", Def_Id);
               Error_Msg_N ("& conflicts with declaration#", Def_Id);
 
 
               --  Avoid cascaded messages with duplicate components in
               --  Avoid cascaded messages with duplicate components in
               --  derived types.
               --  derived types.
 
 
               if Ekind (E) = E_Component
               if Ekind (E) = E_Component
                 or else Ekind (E) = E_Discriminant
                 or else Ekind (E) = E_Discriminant
               then
               then
                  return;
                  return;
               end if;
               end if;
            end if;
            end if;
 
 
            if Nkind (Parent (Parent (Def_Id))) =
            if Nkind (Parent (Parent (Def_Id))) =
                N_Generic_Subprogram_Declaration
                N_Generic_Subprogram_Declaration
              and then Def_Id =
              and then Def_Id =
                Defining_Entity (Specification (Parent (Parent (Def_Id))))
                Defining_Entity (Specification (Parent (Parent (Def_Id))))
            then
            then
               Error_Msg_N ("\generic units cannot be overloaded", Def_Id);
               Error_Msg_N ("\generic units cannot be overloaded", Def_Id);
            end if;
            end if;
 
 
            --  If entity is in standard, then we are in trouble, because
            --  If entity is in standard, then we are in trouble, because
            --  it means that we have a library package with a duplicated
            --  it means that we have a library package with a duplicated
            --  name. That's hard to recover from, so abort!
            --  name. That's hard to recover from, so abort!
 
 
            if S = Standard_Standard then
            if S = Standard_Standard then
               raise Unrecoverable_Error;
               raise Unrecoverable_Error;
 
 
            --  Otherwise we continue with the declaration. Having two
            --  Otherwise we continue with the declaration. Having two
            --  identical declarations should not cause us too much trouble!
            --  identical declarations should not cause us too much trouble!
 
 
            else
            else
               null;
               null;
            end if;
            end if;
         end if;
         end if;
      end if;
      end if;
 
 
      --  If we fall through, declaration is OK , or OK enough to continue
      --  If we fall through, declaration is OK , or OK enough to continue
 
 
      --  If Def_Id is a discriminant or a record component we are in the
      --  If Def_Id is a discriminant or a record component we are in the
      --  midst of inheriting components in a derived record definition.
      --  midst of inheriting components in a derived record definition.
      --  Preserve their Ekind and Etype.
      --  Preserve their Ekind and Etype.
 
 
      if Ekind (Def_Id) = E_Discriminant
      if Ekind (Def_Id) = E_Discriminant
        or else Ekind (Def_Id) = E_Component
        or else Ekind (Def_Id) = E_Component
      then
      then
         null;
         null;
 
 
      --  If a type is already set, leave it alone (happens whey a type
      --  If a type is already set, leave it alone (happens whey a type
      --  declaration is reanalyzed following a call to the optimizer)
      --  declaration is reanalyzed following a call to the optimizer)
 
 
      elsif Present (Etype (Def_Id)) then
      elsif Present (Etype (Def_Id)) then
         null;
         null;
 
 
      --  Otherwise, the kind E_Void insures that premature uses of the entity
      --  Otherwise, the kind E_Void insures that premature uses of the entity
      --  will be detected. Any_Type insures that no cascaded errors will occur
      --  will be detected. Any_Type insures that no cascaded errors will occur
 
 
      else
      else
         Set_Ekind (Def_Id, E_Void);
         Set_Ekind (Def_Id, E_Void);
         Set_Etype (Def_Id, Any_Type);
         Set_Etype (Def_Id, Any_Type);
      end if;
      end if;
 
 
      --  Inherited discriminants and components in derived record types are
      --  Inherited discriminants and components in derived record types are
      --  immediately visible. Itypes are not.
      --  immediately visible. Itypes are not.
 
 
      if Ekind (Def_Id) = E_Discriminant
      if Ekind (Def_Id) = E_Discriminant
        or else Ekind (Def_Id) = E_Component
        or else Ekind (Def_Id) = E_Component
        or else (No (Corresponding_Remote_Type (Def_Id))
        or else (No (Corresponding_Remote_Type (Def_Id))
                 and then not Is_Itype (Def_Id))
                 and then not Is_Itype (Def_Id))
      then
      then
         Set_Is_Immediately_Visible (Def_Id);
         Set_Is_Immediately_Visible (Def_Id);
         Set_Current_Entity         (Def_Id);
         Set_Current_Entity         (Def_Id);
      end if;
      end if;
 
 
      Set_Homonym       (Def_Id, C);
      Set_Homonym       (Def_Id, C);
      Append_Entity     (Def_Id, S);
      Append_Entity     (Def_Id, S);
      Set_Public_Status (Def_Id);
      Set_Public_Status (Def_Id);
 
 
      --  Warn if new entity hides an old one
      --  Warn if new entity hides an old one
 
 
      if Warn_On_Hiding and then Present (C)
      if Warn_On_Hiding and then Present (C)
 
 
         --  Don't warn for record components since they always have a well
         --  Don't warn for record components since they always have a well
         --  defined scope which does not confuse other uses. Note that in
         --  defined scope which does not confuse other uses. Note that in
         --  some cases, Ekind has not been set yet.
         --  some cases, Ekind has not been set yet.
 
 
         and then Ekind (C) /= E_Component
         and then Ekind (C) /= E_Component
         and then Ekind (C) /= E_Discriminant
         and then Ekind (C) /= E_Discriminant
         and then Nkind (Parent (C)) /= N_Component_Declaration
         and then Nkind (Parent (C)) /= N_Component_Declaration
         and then Ekind (Def_Id) /= E_Component
         and then Ekind (Def_Id) /= E_Component
         and then Ekind (Def_Id) /= E_Discriminant
         and then Ekind (Def_Id) /= E_Discriminant
         and then Nkind (Parent (Def_Id)) /= N_Component_Declaration
         and then Nkind (Parent (Def_Id)) /= N_Component_Declaration
 
 
         --  Don't warn for one character variables. It is too common to use
         --  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.
         --  such variables as locals and will just cause too many false hits.
 
 
         and then Length_Of_Name (Chars (C)) /= 1
         and then Length_Of_Name (Chars (C)) /= 1
 
 
         --  Don't warn for non-source entities
         --  Don't warn for non-source entities
 
 
         and then Comes_From_Source (C)
         and then Comes_From_Source (C)
         and then Comes_From_Source (Def_Id)
         and then Comes_From_Source (Def_Id)
 
 
         --  Don't warn unless entity in question is in extended main source
         --  Don't warn unless entity in question is in extended main source
 
 
         and then In_Extended_Main_Source_Unit (Def_Id)
         and then In_Extended_Main_Source_Unit (Def_Id)
 
 
         --  Finally, the hidden entity must be either immediately visible
         --  Finally, the hidden entity must be either immediately visible
         --  or use visible (from a used package)
         --  or use visible (from a used package)
 
 
         and then
         and then
           (Is_Immediately_Visible (C)
           (Is_Immediately_Visible (C)
              or else
              or else
            Is_Potentially_Use_Visible (C))
            Is_Potentially_Use_Visible (C))
      then
      then
         Error_Msg_Sloc := Sloc (C);
         Error_Msg_Sloc := Sloc (C);
         Error_Msg_N ("declaration hides &#?", Def_Id);
         Error_Msg_N ("declaration hides &#?", Def_Id);
      end if;
      end if;
   end Enter_Name;
   end Enter_Name;
 
 
   --------------------------
   --------------------------
   -- Explain_Limited_Type --
   -- Explain_Limited_Type --
   --------------------------
   --------------------------
 
 
   procedure Explain_Limited_Type (T : Entity_Id; N : Node_Id) is
   procedure Explain_Limited_Type (T : Entity_Id; N : Node_Id) is
      C : Entity_Id;
      C : Entity_Id;
 
 
   begin
   begin
      --  For array, component type must be limited
      --  For array, component type must be limited
 
 
      if Is_Array_Type (T) then
      if Is_Array_Type (T) then
         Error_Msg_Node_2 := T;
         Error_Msg_Node_2 := T;
         Error_Msg_NE
         Error_Msg_NE
           ("\component type& of type& is limited", N, Component_Type (T));
           ("\component type& of type& is limited", N, Component_Type (T));
         Explain_Limited_Type (Component_Type (T), N);
         Explain_Limited_Type (Component_Type (T), N);
 
 
      elsif Is_Record_Type (T) then
      elsif Is_Record_Type (T) then
 
 
         --  No need for extra messages if explicit limited record
         --  No need for extra messages if explicit limited record
 
 
         if Is_Limited_Record (Base_Type (T)) then
         if Is_Limited_Record (Base_Type (T)) then
            return;
            return;
         end if;
         end if;
 
 
         --  Otherwise find a limited component. Check only components that
         --  Otherwise find a limited component. Check only components that
         --  come from source, or inherited components that appear in the
         --  come from source, or inherited components that appear in the
         --  source of the ancestor.
         --  source of the ancestor.
 
 
         C := First_Component (T);
         C := First_Component (T);
         while Present (C) loop
         while Present (C) loop
            if Is_Limited_Type (Etype (C))
            if Is_Limited_Type (Etype (C))
              and then
              and then
                (Comes_From_Source (C)
                (Comes_From_Source (C)
                   or else
                   or else
                     (Present (Original_Record_Component (C))
                     (Present (Original_Record_Component (C))
                       and then
                       and then
                         Comes_From_Source (Original_Record_Component (C))))
                         Comes_From_Source (Original_Record_Component (C))))
            then
            then
               Error_Msg_Node_2 := T;
               Error_Msg_Node_2 := T;
               Error_Msg_NE ("\component& of type& has limited type", N, C);
               Error_Msg_NE ("\component& of type& has limited type", N, C);
               Explain_Limited_Type (Etype (C), N);
               Explain_Limited_Type (Etype (C), N);
               return;
               return;
            end if;
            end if;
 
 
            Next_Component (C);
            Next_Component (C);
         end loop;
         end loop;
 
 
         --  The type may be declared explicitly limited, even if no component
         --  The type may be declared explicitly limited, even if no component
         --  of it is limited, in which case we fall out of the loop.
         --  of it is limited, in which case we fall out of the loop.
         return;
         return;
      end if;
      end if;
   end Explain_Limited_Type;
   end Explain_Limited_Type;
 
 
   -----------------
   -----------------
   -- Find_Actual --
   -- Find_Actual --
   -----------------
   -----------------
 
 
   procedure Find_Actual
   procedure Find_Actual
     (N        : Node_Id;
     (N        : Node_Id;
      Formal   : out Entity_Id;
      Formal   : out Entity_Id;
      Call     : out Node_Id)
      Call     : out Node_Id)
   is
   is
      Parnt  : constant Node_Id := Parent (N);
      Parnt  : constant Node_Id := Parent (N);
      Actual : Node_Id;
      Actual : Node_Id;
 
 
   begin
   begin
      if (Nkind (Parnt) = N_Indexed_Component
      if (Nkind (Parnt) = N_Indexed_Component
            or else
            or else
          Nkind (Parnt) = N_Selected_Component)
          Nkind (Parnt) = N_Selected_Component)
        and then N = Prefix (Parnt)
        and then N = Prefix (Parnt)
      then
      then
         Find_Actual (Parnt, Formal, Call);
         Find_Actual (Parnt, Formal, Call);
         return;
         return;
 
 
      elsif Nkind (Parnt) = N_Parameter_Association
      elsif Nkind (Parnt) = N_Parameter_Association
        and then N = Explicit_Actual_Parameter (Parnt)
        and then N = Explicit_Actual_Parameter (Parnt)
      then
      then
         Call := Parent (Parnt);
         Call := Parent (Parnt);
 
 
      elsif Nkind (Parnt) = N_Procedure_Call_Statement then
      elsif Nkind (Parnt) = N_Procedure_Call_Statement then
         Call := Parnt;
         Call := Parnt;
 
 
      else
      else
         Formal := Empty;
         Formal := Empty;
         Call   := Empty;
         Call   := Empty;
         return;
         return;
      end if;
      end if;
 
 
      --  If we have a call to a subprogram look for the parameter. Note that
      --  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
      --  we exclude overloaded calls, since we don't know enough to be sure
      --  of giving the right answer in this case.
      --  of giving the right answer in this case.
 
 
      if Is_Entity_Name (Name (Call))
      if Is_Entity_Name (Name (Call))
        and then Present (Entity (Name (Call)))
        and then Present (Entity (Name (Call)))
        and then Is_Overloadable (Entity (Name (Call)))
        and then Is_Overloadable (Entity (Name (Call)))
        and then not Is_Overloaded (Name (Call))
        and then not Is_Overloaded (Name (Call))
      then
      then
         --  Fall here if we are definitely a parameter
         --  Fall here if we are definitely a parameter
 
 
         Actual := First_Actual (Call);
         Actual := First_Actual (Call);
         Formal := First_Formal (Entity (Name (Call)));
         Formal := First_Formal (Entity (Name (Call)));
         while Present (Formal) and then Present (Actual) loop
         while Present (Formal) and then Present (Actual) loop
            if Actual = N then
            if Actual = N then
               return;
               return;
            else
            else
               Actual := Next_Actual (Actual);
               Actual := Next_Actual (Actual);
               Formal := Next_Formal (Formal);
               Formal := Next_Formal (Formal);
            end if;
            end if;
         end loop;
         end loop;
      end if;
      end if;
 
 
      --  Fall through here if we did not find matching actual
      --  Fall through here if we did not find matching actual
 
 
      Formal := Empty;
      Formal := Empty;
      Call   := Empty;
      Call   := Empty;
   end Find_Actual;
   end Find_Actual;
 
 
   -------------------------------------
   -------------------------------------
   -- Find_Corresponding_Discriminant --
   -- Find_Corresponding_Discriminant --
   -------------------------------------
   -------------------------------------
 
 
   function Find_Corresponding_Discriminant
   function Find_Corresponding_Discriminant
     (Id  : Node_Id;
     (Id  : Node_Id;
      Typ : Entity_Id) return Entity_Id
      Typ : Entity_Id) return Entity_Id
   is
   is
      Par_Disc : Entity_Id;
      Par_Disc : Entity_Id;
      Old_Disc : Entity_Id;
      Old_Disc : Entity_Id;
      New_Disc : Entity_Id;
      New_Disc : Entity_Id;
 
 
   begin
   begin
      Par_Disc := Original_Record_Component (Original_Discriminant (Id));
      Par_Disc := Original_Record_Component (Original_Discriminant (Id));
 
 
      --  The original type may currently be private, and the discriminant
      --  The original type may currently be private, and the discriminant
      --  only appear on its full view.
      --  only appear on its full view.
 
 
      if Is_Private_Type (Scope (Par_Disc))
      if Is_Private_Type (Scope (Par_Disc))
        and then not Has_Discriminants (Scope (Par_Disc))
        and then not Has_Discriminants (Scope (Par_Disc))
        and then Present (Full_View (Scope (Par_Disc)))
        and then Present (Full_View (Scope (Par_Disc)))
      then
      then
         Old_Disc := First_Discriminant (Full_View (Scope (Par_Disc)));
         Old_Disc := First_Discriminant (Full_View (Scope (Par_Disc)));
      else
      else
         Old_Disc := First_Discriminant (Scope (Par_Disc));
         Old_Disc := First_Discriminant (Scope (Par_Disc));
      end if;
      end if;
 
 
      if Is_Class_Wide_Type (Typ) then
      if Is_Class_Wide_Type (Typ) then
         New_Disc := First_Discriminant (Root_Type (Typ));
         New_Disc := First_Discriminant (Root_Type (Typ));
      else
      else
         New_Disc := First_Discriminant (Typ);
         New_Disc := First_Discriminant (Typ);
      end if;
      end if;
 
 
      while Present (Old_Disc) and then Present (New_Disc) loop
      while Present (Old_Disc) and then Present (New_Disc) loop
         if Old_Disc = Par_Disc  then
         if Old_Disc = Par_Disc  then
            return New_Disc;
            return New_Disc;
         else
         else
            Next_Discriminant (Old_Disc);
            Next_Discriminant (Old_Disc);
            Next_Discriminant (New_Disc);
            Next_Discriminant (New_Disc);
         end if;
         end if;
      end loop;
      end loop;
 
 
      --  Should always find it
      --  Should always find it
 
 
      raise Program_Error;
      raise Program_Error;
   end Find_Corresponding_Discriminant;
   end Find_Corresponding_Discriminant;
 
 
   --------------------------
   --------------------------
   -- Find_Overlaid_Entity --
   -- Find_Overlaid_Entity --
   --------------------------
   --------------------------
 
 
   procedure Find_Overlaid_Entity
   procedure Find_Overlaid_Entity
     (N   : Node_Id;
     (N   : Node_Id;
      Ent : out Entity_Id;
      Ent : out Entity_Id;
      Off : out Boolean)
      Off : out Boolean)
   is
   is
      Expr : Node_Id;
      Expr : Node_Id;
 
 
   begin
   begin
      --  We are looking for one of the two following forms:
      --  We are looking for one of the two following forms:
 
 
      --    for X'Address use Y'Address
      --    for X'Address use Y'Address
 
 
      --  or
      --  or
 
 
      --    Const : constant Address := expr;
      --    Const : constant Address := expr;
      --    ...
      --    ...
      --    for X'Address use Const;
      --    for X'Address use Const;
 
 
      --  In the second case, the expr is either Y'Address, or recursively a
      --  In the second case, the expr is either Y'Address, or recursively a
      --  constant that eventually references Y'Address.
      --  constant that eventually references Y'Address.
 
 
      Ent := Empty;
      Ent := Empty;
      Off := False;
      Off := False;
 
 
      if Nkind (N) = N_Attribute_Definition_Clause
      if Nkind (N) = N_Attribute_Definition_Clause
        and then Chars (N) = Name_Address
        and then Chars (N) = Name_Address
      then
      then
         Expr := Expression (N);
         Expr := Expression (N);
 
 
         --  This loop checks the form of the expression for Y'Address,
         --  This loop checks the form of the expression for Y'Address,
         --  using recursion to deal with intermediate constants.
         --  using recursion to deal with intermediate constants.
 
 
         loop
         loop
            --  Check for Y'Address
            --  Check for Y'Address
 
 
            if Nkind (Expr) = N_Attribute_Reference
            if Nkind (Expr) = N_Attribute_Reference
              and then Attribute_Name (Expr) = Name_Address
              and then Attribute_Name (Expr) = Name_Address
            then
            then
               Expr := Prefix (Expr);
               Expr := Prefix (Expr);
               exit;
               exit;
 
 
               --  Check for Const where Const is a constant entity
               --  Check for Const where Const is a constant entity
 
 
            elsif Is_Entity_Name (Expr)
            elsif Is_Entity_Name (Expr)
              and then Ekind (Entity (Expr)) = E_Constant
              and then Ekind (Entity (Expr)) = E_Constant
            then
            then
               Expr := Constant_Value (Entity (Expr));
               Expr := Constant_Value (Entity (Expr));
 
 
            --  Anything else does not need checking
            --  Anything else does not need checking
 
 
            else
            else
               return;
               return;
            end if;
            end if;
         end loop;
         end loop;
 
 
         --  This loop checks the form of the prefix for an entity,
         --  This loop checks the form of the prefix for an entity,
         --  using recursion to deal with intermediate components.
         --  using recursion to deal with intermediate components.
 
 
         loop
         loop
            --  Check for Y where Y is an entity
            --  Check for Y where Y is an entity
 
 
            if Is_Entity_Name (Expr) then
            if Is_Entity_Name (Expr) then
               Ent := Entity (Expr);
               Ent := Entity (Expr);
               return;
               return;
 
 
            --  Check for components
            --  Check for components
 
 
            elsif
            elsif
               Nkind_In (Expr, N_Selected_Component, N_Indexed_Component) then
               Nkind_In (Expr, N_Selected_Component, N_Indexed_Component) then
 
 
               Expr := Prefix (Expr);
               Expr := Prefix (Expr);
               Off := True;
               Off := True;
 
 
            --  Anything else does not need checking
            --  Anything else does not need checking
 
 
            else
            else
               return;
               return;
            end if;
            end if;
         end loop;
         end loop;
      end if;
      end if;
   end Find_Overlaid_Entity;
   end Find_Overlaid_Entity;
 
 
   -------------------------
   -------------------------
   -- Find_Parameter_Type --
   -- Find_Parameter_Type --
   -------------------------
   -------------------------
 
 
   function Find_Parameter_Type (Param : Node_Id) return Entity_Id is
   function Find_Parameter_Type (Param : Node_Id) return Entity_Id is
   begin
   begin
      if Nkind (Param) /= N_Parameter_Specification then
      if Nkind (Param) /= N_Parameter_Specification then
         return Empty;
         return Empty;
 
 
      --  For an access parameter, obtain the type from the formal entity
      --  For an access parameter, obtain the type from the formal entity
      --  itself, because access to subprogram nodes do not carry a type.
      --  itself, because access to subprogram nodes do not carry a type.
      --  Shouldn't we always use the formal entity ???
      --  Shouldn't we always use the formal entity ???
 
 
      elsif Nkind (Parameter_Type (Param)) = N_Access_Definition then
      elsif Nkind (Parameter_Type (Param)) = N_Access_Definition then
         return Etype (Defining_Identifier (Param));
         return Etype (Defining_Identifier (Param));
 
 
      else
      else
         return Etype (Parameter_Type (Param));
         return Etype (Parameter_Type (Param));
      end if;
      end if;
   end Find_Parameter_Type;
   end Find_Parameter_Type;
 
 
   -----------------------------
   -----------------------------
   -- Find_Static_Alternative --
   -- Find_Static_Alternative --
   -----------------------------
   -----------------------------
 
 
   function Find_Static_Alternative (N : Node_Id) return Node_Id is
   function Find_Static_Alternative (N : Node_Id) return Node_Id is
      Expr   : constant Node_Id := Expression (N);
      Expr   : constant Node_Id := Expression (N);
      Val    : constant Uint    := Expr_Value (Expr);
      Val    : constant Uint    := Expr_Value (Expr);
      Alt    : Node_Id;
      Alt    : Node_Id;
      Choice : Node_Id;
      Choice : Node_Id;
 
 
   begin
   begin
      Alt := First (Alternatives (N));
      Alt := First (Alternatives (N));
 
 
      Search : loop
      Search : loop
         if Nkind (Alt) /= N_Pragma then
         if Nkind (Alt) /= N_Pragma then
            Choice := First (Discrete_Choices (Alt));
            Choice := First (Discrete_Choices (Alt));
            while Present (Choice) loop
            while Present (Choice) loop
 
 
               --  Others choice, always matches
               --  Others choice, always matches
 
 
               if Nkind (Choice) = N_Others_Choice then
               if Nkind (Choice) = N_Others_Choice then
                  exit Search;
                  exit Search;
 
 
               --  Range, check if value is in the range
               --  Range, check if value is in the range
 
 
               elsif Nkind (Choice) = N_Range then
               elsif Nkind (Choice) = N_Range then
                  exit Search when
                  exit Search when
                    Val >= Expr_Value (Low_Bound (Choice))
                    Val >= Expr_Value (Low_Bound (Choice))
                      and then
                      and then
                    Val <= Expr_Value (High_Bound (Choice));
                    Val <= Expr_Value (High_Bound (Choice));
 
 
               --  Choice is a subtype name. Note that we know it must
               --  Choice is a subtype name. Note that we know it must
               --  be a static subtype, since otherwise it would have
               --  be a static subtype, since otherwise it would have
               --  been diagnosed as illegal.
               --  been diagnosed as illegal.
 
 
               elsif Is_Entity_Name (Choice)
               elsif Is_Entity_Name (Choice)
                 and then Is_Type (Entity (Choice))
                 and then Is_Type (Entity (Choice))
               then
               then
                  exit Search when Is_In_Range (Expr, Etype (Choice),
                  exit Search when Is_In_Range (Expr, Etype (Choice),
                                                Assume_Valid => False);
                                                Assume_Valid => False);
 
 
               --  Choice is a subtype indication
               --  Choice is a subtype indication
 
 
               elsif Nkind (Choice) = N_Subtype_Indication then
               elsif Nkind (Choice) = N_Subtype_Indication then
                  declare
                  declare
                     C : constant Node_Id := Constraint (Choice);
                     C : constant Node_Id := Constraint (Choice);
                     R : constant Node_Id := Range_Expression (C);
                     R : constant Node_Id := Range_Expression (C);
 
 
                  begin
                  begin
                     exit Search when
                     exit Search when
                       Val >= Expr_Value (Low_Bound (R))
                       Val >= Expr_Value (Low_Bound (R))
                         and then
                         and then
                       Val <= Expr_Value (High_Bound (R));
                       Val <= Expr_Value (High_Bound (R));
                  end;
                  end;
 
 
               --  Choice is a simple expression
               --  Choice is a simple expression
 
 
               else
               else
                  exit Search when Val = Expr_Value (Choice);
                  exit Search when Val = Expr_Value (Choice);
               end if;
               end if;
 
 
               Next (Choice);
               Next (Choice);
            end loop;
            end loop;
         end if;
         end if;
 
 
         Next (Alt);
         Next (Alt);
         pragma Assert (Present (Alt));
         pragma Assert (Present (Alt));
      end loop Search;
      end loop Search;
 
 
      --  The above loop *must* terminate by finding a match, since
      --  The above loop *must* terminate by finding a match, since
      --  we know the case statement is valid, and the value of the
      --  we know the case statement is valid, and the value of the
      --  expression is known at compile time. When we fall out of
      --  expression is known at compile time. When we fall out of
      --  the loop, Alt points to the alternative that we know will
      --  the loop, Alt points to the alternative that we know will
      --  be selected at run time.
      --  be selected at run time.
 
 
      return Alt;
      return Alt;
   end Find_Static_Alternative;
   end Find_Static_Alternative;
 
 
   ------------------
   ------------------
   -- First_Actual --
   -- First_Actual --
   ------------------
   ------------------
 
 
   function First_Actual (Node : Node_Id) return Node_Id is
   function First_Actual (Node : Node_Id) return Node_Id is
      N : Node_Id;
      N : Node_Id;
 
 
   begin
   begin
      if No (Parameter_Associations (Node)) then
      if No (Parameter_Associations (Node)) then
         return Empty;
         return Empty;
      end if;
      end if;
 
 
      N := First (Parameter_Associations (Node));
      N := First (Parameter_Associations (Node));
 
 
      if Nkind (N) = N_Parameter_Association then
      if Nkind (N) = N_Parameter_Association then
         return First_Named_Actual (Node);
         return First_Named_Actual (Node);
      else
      else
         return N;
         return N;
      end if;
      end if;
   end First_Actual;
   end First_Actual;
 
 
   -------------------------
   -------------------------
   -- Full_Qualified_Name --
   -- Full_Qualified_Name --
   -------------------------
   -------------------------
 
 
   function Full_Qualified_Name (E : Entity_Id) return String_Id is
   function Full_Qualified_Name (E : Entity_Id) return String_Id is
      Res : String_Id;
      Res : String_Id;
      pragma Warnings (Off, Res);
      pragma Warnings (Off, Res);
 
 
      function Internal_Full_Qualified_Name (E : Entity_Id) return String_Id;
      function Internal_Full_Qualified_Name (E : Entity_Id) return String_Id;
      --  Compute recursively the qualified name without NUL at the end
      --  Compute recursively the qualified name without NUL at the end
 
 
      ----------------------------------
      ----------------------------------
      -- Internal_Full_Qualified_Name --
      -- Internal_Full_Qualified_Name --
      ----------------------------------
      ----------------------------------
 
 
      function Internal_Full_Qualified_Name (E : Entity_Id) return String_Id is
      function Internal_Full_Qualified_Name (E : Entity_Id) return String_Id is
         Ent         : Entity_Id := E;
         Ent         : Entity_Id := E;
         Parent_Name : String_Id := No_String;
         Parent_Name : String_Id := No_String;
 
 
      begin
      begin
         --  Deals properly with child units
         --  Deals properly with child units
 
 
         if Nkind (Ent) = N_Defining_Program_Unit_Name then
         if Nkind (Ent) = N_Defining_Program_Unit_Name then
            Ent := Defining_Identifier (Ent);
            Ent := Defining_Identifier (Ent);
         end if;
         end if;
 
 
         --  Compute qualification recursively (only "Standard" has no scope)
         --  Compute qualification recursively (only "Standard" has no scope)
 
 
         if Present (Scope (Scope (Ent))) then
         if Present (Scope (Scope (Ent))) then
            Parent_Name := Internal_Full_Qualified_Name (Scope (Ent));
            Parent_Name := Internal_Full_Qualified_Name (Scope (Ent));
         end if;
         end if;
 
 
         --  Every entity should have a name except some expanded blocks
         --  Every entity should have a name except some expanded blocks
         --  don't bother about those.
         --  don't bother about those.
 
 
         if Chars (Ent) = No_Name then
         if Chars (Ent) = No_Name then
            return Parent_Name;
            return Parent_Name;
         end if;
         end if;
 
 
         --  Add a period between Name and qualification
         --  Add a period between Name and qualification
 
 
         if Parent_Name /= No_String then
         if Parent_Name /= No_String then
            Start_String (Parent_Name);
            Start_String (Parent_Name);
            Store_String_Char (Get_Char_Code ('.'));
            Store_String_Char (Get_Char_Code ('.'));
 
 
         else
         else
            Start_String;
            Start_String;
         end if;
         end if;
 
 
         --  Generates the entity name in upper case
         --  Generates the entity name in upper case
 
 
         Get_Decoded_Name_String (Chars (Ent));
         Get_Decoded_Name_String (Chars (Ent));
         Set_All_Upper_Case;
         Set_All_Upper_Case;
         Store_String_Chars (Name_Buffer (1 .. Name_Len));
         Store_String_Chars (Name_Buffer (1 .. Name_Len));
         return End_String;
         return End_String;
      end Internal_Full_Qualified_Name;
      end Internal_Full_Qualified_Name;
 
 
   --  Start of processing for Full_Qualified_Name
   --  Start of processing for Full_Qualified_Name
 
 
   begin
   begin
      Res := Internal_Full_Qualified_Name (E);
      Res := Internal_Full_Qualified_Name (E);
      Store_String_Char (Get_Char_Code (ASCII.NUL));
      Store_String_Char (Get_Char_Code (ASCII.NUL));
      return End_String;
      return End_String;
   end Full_Qualified_Name;
   end Full_Qualified_Name;
 
 
   -----------------------
   -----------------------
   -- Gather_Components --
   -- Gather_Components --
   -----------------------
   -----------------------
 
 
   procedure Gather_Components
   procedure Gather_Components
     (Typ           : Entity_Id;
     (Typ           : Entity_Id;
      Comp_List     : Node_Id;
      Comp_List     : Node_Id;
      Governed_By   : List_Id;
      Governed_By   : List_Id;
      Into          : Elist_Id;
      Into          : Elist_Id;
      Report_Errors : out Boolean)
      Report_Errors : out Boolean)
   is
   is
      Assoc           : Node_Id;
      Assoc           : Node_Id;
      Variant         : Node_Id;
      Variant         : Node_Id;
      Discrete_Choice : Node_Id;
      Discrete_Choice : Node_Id;
      Comp_Item       : Node_Id;
      Comp_Item       : Node_Id;
 
 
      Discrim       : Entity_Id;
      Discrim       : Entity_Id;
      Discrim_Name  : Node_Id;
      Discrim_Name  : Node_Id;
      Discrim_Value : Node_Id;
      Discrim_Value : Node_Id;
 
 
   begin
   begin
      Report_Errors := False;
      Report_Errors := False;
 
 
      if No (Comp_List) or else Null_Present (Comp_List) then
      if No (Comp_List) or else Null_Present (Comp_List) then
         return;
         return;
 
 
      elsif Present (Component_Items (Comp_List)) then
      elsif Present (Component_Items (Comp_List)) then
         Comp_Item := First (Component_Items (Comp_List));
         Comp_Item := First (Component_Items (Comp_List));
 
 
      else
      else
         Comp_Item := Empty;
         Comp_Item := Empty;
      end if;
      end if;
 
 
      while Present (Comp_Item) loop
      while Present (Comp_Item) loop
 
 
         --  Skip the tag of a tagged record, the interface tags, as well
         --  Skip the tag of a tagged record, the interface tags, as well
         --  as all items that are not user components (anonymous types,
         --  as all items that are not user components (anonymous types,
         --  rep clauses, Parent field, controller field).
         --  rep clauses, Parent field, controller field).
 
 
         if Nkind (Comp_Item) = N_Component_Declaration then
         if Nkind (Comp_Item) = N_Component_Declaration then
            declare
            declare
               Comp : constant Entity_Id := Defining_Identifier (Comp_Item);
               Comp : constant Entity_Id := Defining_Identifier (Comp_Item);
            begin
            begin
               if not Is_Tag (Comp)
               if not Is_Tag (Comp)
                 and then Chars (Comp) /= Name_uParent
                 and then Chars (Comp) /= Name_uParent
                 and then Chars (Comp) /= Name_uController
                 and then Chars (Comp) /= Name_uController
               then
               then
                  Append_Elmt (Comp, Into);
                  Append_Elmt (Comp, Into);
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
         Next (Comp_Item);
         Next (Comp_Item);
      end loop;
      end loop;
 
 
      if No (Variant_Part (Comp_List)) then
      if No (Variant_Part (Comp_List)) then
         return;
         return;
      else
      else
         Discrim_Name := Name (Variant_Part (Comp_List));
         Discrim_Name := Name (Variant_Part (Comp_List));
         Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
         Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
      end if;
      end if;
 
 
      --  Look for the discriminant that governs this variant part.
      --  Look for the discriminant that governs this variant part.
      --  The discriminant *must* be in the Governed_By List
      --  The discriminant *must* be in the Governed_By List
 
 
      Assoc := First (Governed_By);
      Assoc := First (Governed_By);
      Find_Constraint : loop
      Find_Constraint : loop
         Discrim := First (Choices (Assoc));
         Discrim := First (Choices (Assoc));
         exit Find_Constraint when Chars (Discrim_Name) = Chars (Discrim)
         exit Find_Constraint when Chars (Discrim_Name) = Chars (Discrim)
           or else (Present (Corresponding_Discriminant (Entity (Discrim)))
           or else (Present (Corresponding_Discriminant (Entity (Discrim)))
                      and then
                      and then
                    Chars (Corresponding_Discriminant (Entity (Discrim)))
                    Chars (Corresponding_Discriminant (Entity (Discrim)))
                         = Chars  (Discrim_Name))
                         = Chars  (Discrim_Name))
           or else Chars (Original_Record_Component (Entity (Discrim)))
           or else Chars (Original_Record_Component (Entity (Discrim)))
                         = Chars (Discrim_Name);
                         = Chars (Discrim_Name);
 
 
         if No (Next (Assoc)) then
         if No (Next (Assoc)) then
            if not Is_Constrained (Typ)
            if not Is_Constrained (Typ)
              and then Is_Derived_Type (Typ)
              and then Is_Derived_Type (Typ)
              and then Present (Stored_Constraint (Typ))
              and then Present (Stored_Constraint (Typ))
            then
            then
               --  If the type is a tagged type with inherited discriminants,
               --  If the type is a tagged type with inherited discriminants,
               --  use the stored constraint on the parent in order to find
               --  use the stored constraint on the parent in order to find
               --  the values of discriminants that are otherwise hidden by an
               --  the values of discriminants that are otherwise hidden by an
               --  explicit constraint. Renamed discriminants are handled in
               --  explicit constraint. Renamed discriminants are handled in
               --  the code above.
               --  the code above.
 
 
               --  If several parent discriminants are renamed by a single
               --  If several parent discriminants are renamed by a single
               --  discriminant of the derived type, the call to obtain the
               --  discriminant of the derived type, the call to obtain the
               --  Corresponding_Discriminant field only retrieves the last
               --  Corresponding_Discriminant field only retrieves the last
               --  of them. We recover the constraint on the others from the
               --  of them. We recover the constraint on the others from the
               --  Stored_Constraint as well.
               --  Stored_Constraint as well.
 
 
               declare
               declare
                  D : Entity_Id;
                  D : Entity_Id;
                  C : Elmt_Id;
                  C : Elmt_Id;
 
 
               begin
               begin
                  D := First_Discriminant (Etype (Typ));
                  D := First_Discriminant (Etype (Typ));
                  C := First_Elmt (Stored_Constraint (Typ));
                  C := First_Elmt (Stored_Constraint (Typ));
                  while Present (D) and then Present (C) loop
                  while Present (D) and then Present (C) loop
                     if Chars (Discrim_Name) = Chars (D) then
                     if Chars (Discrim_Name) = Chars (D) then
                        if Is_Entity_Name (Node (C))
                        if Is_Entity_Name (Node (C))
                          and then Entity (Node (C)) = Entity (Discrim)
                          and then Entity (Node (C)) = Entity (Discrim)
                        then
                        then
                           --  D is renamed by Discrim, whose value is given in
                           --  D is renamed by Discrim, whose value is given in
                           --  Assoc.
                           --  Assoc.
 
 
                           null;
                           null;
 
 
                        else
                        else
                           Assoc :=
                           Assoc :=
                             Make_Component_Association (Sloc (Typ),
                             Make_Component_Association (Sloc (Typ),
                               New_List
                               New_List
                                 (New_Occurrence_Of (D, Sloc (Typ))),
                                 (New_Occurrence_Of (D, Sloc (Typ))),
                                  Duplicate_Subexpr_No_Checks (Node (C)));
                                  Duplicate_Subexpr_No_Checks (Node (C)));
                        end if;
                        end if;
                        exit Find_Constraint;
                        exit Find_Constraint;
                     end if;
                     end if;
 
 
                     Next_Discriminant (D);
                     Next_Discriminant (D);
                     Next_Elmt (C);
                     Next_Elmt (C);
                  end loop;
                  end loop;
               end;
               end;
            end if;
            end if;
         end if;
         end if;
 
 
         if No (Next (Assoc)) then
         if No (Next (Assoc)) then
            Error_Msg_NE (" missing value for discriminant&",
            Error_Msg_NE (" missing value for discriminant&",
              First (Governed_By), Discrim_Name);
              First (Governed_By), Discrim_Name);
            Report_Errors := True;
            Report_Errors := True;
            return;
            return;
         end if;
         end if;
 
 
         Next (Assoc);
         Next (Assoc);
      end loop Find_Constraint;
      end loop Find_Constraint;
 
 
      Discrim_Value := Expression (Assoc);
      Discrim_Value := Expression (Assoc);
 
 
      if not Is_OK_Static_Expression (Discrim_Value) then
      if not Is_OK_Static_Expression (Discrim_Value) then
         Error_Msg_FE
         Error_Msg_FE
           ("value for discriminant & must be static!",
           ("value for discriminant & must be static!",
            Discrim_Value, Discrim);
            Discrim_Value, Discrim);
         Why_Not_Static (Discrim_Value);
         Why_Not_Static (Discrim_Value);
         Report_Errors := True;
         Report_Errors := True;
         return;
         return;
      end if;
      end if;
 
 
      Search_For_Discriminant_Value : declare
      Search_For_Discriminant_Value : declare
         Low  : Node_Id;
         Low  : Node_Id;
         High : Node_Id;
         High : Node_Id;
 
 
         UI_High          : Uint;
         UI_High          : Uint;
         UI_Low           : Uint;
         UI_Low           : Uint;
         UI_Discrim_Value : constant Uint := Expr_Value (Discrim_Value);
         UI_Discrim_Value : constant Uint := Expr_Value (Discrim_Value);
 
 
      begin
      begin
         Find_Discrete_Value : while Present (Variant) loop
         Find_Discrete_Value : while Present (Variant) loop
            Discrete_Choice := First (Discrete_Choices (Variant));
            Discrete_Choice := First (Discrete_Choices (Variant));
            while Present (Discrete_Choice) loop
            while Present (Discrete_Choice) loop
 
 
               exit Find_Discrete_Value when
               exit Find_Discrete_Value when
                 Nkind (Discrete_Choice) = N_Others_Choice;
                 Nkind (Discrete_Choice) = N_Others_Choice;
 
 
               Get_Index_Bounds (Discrete_Choice, Low, High);
               Get_Index_Bounds (Discrete_Choice, Low, High);
 
 
               UI_Low  := Expr_Value (Low);
               UI_Low  := Expr_Value (Low);
               UI_High := Expr_Value (High);
               UI_High := Expr_Value (High);
 
 
               exit Find_Discrete_Value when
               exit Find_Discrete_Value when
                 UI_Low <= UI_Discrim_Value
                 UI_Low <= UI_Discrim_Value
                   and then
                   and then
                 UI_High >= UI_Discrim_Value;
                 UI_High >= UI_Discrim_Value;
 
 
               Next (Discrete_Choice);
               Next (Discrete_Choice);
            end loop;
            end loop;
 
 
            Next_Non_Pragma (Variant);
            Next_Non_Pragma (Variant);
         end loop Find_Discrete_Value;
         end loop Find_Discrete_Value;
      end Search_For_Discriminant_Value;
      end Search_For_Discriminant_Value;
 
 
      if No (Variant) then
      if No (Variant) then
         Error_Msg_NE
         Error_Msg_NE
           ("value of discriminant & is out of range", Discrim_Value, Discrim);
           ("value of discriminant & is out of range", Discrim_Value, Discrim);
         Report_Errors := True;
         Report_Errors := True;
         return;
         return;
      end  if;
      end  if;
 
 
      --  If we have found the corresponding choice, recursively add its
      --  If we have found the corresponding choice, recursively add its
      --  components to the Into list.
      --  components to the Into list.
 
 
      Gather_Components (Empty,
      Gather_Components (Empty,
        Component_List (Variant), Governed_By, Into, Report_Errors);
        Component_List (Variant), Governed_By, Into, Report_Errors);
   end Gather_Components;
   end Gather_Components;
 
 
   ------------------------
   ------------------------
   -- Get_Actual_Subtype --
   -- Get_Actual_Subtype --
   ------------------------
   ------------------------
 
 
   function Get_Actual_Subtype (N : Node_Id) return Entity_Id is
   function Get_Actual_Subtype (N : Node_Id) return Entity_Id is
      Typ  : constant Entity_Id := Etype (N);
      Typ  : constant Entity_Id := Etype (N);
      Utyp : Entity_Id := Underlying_Type (Typ);
      Utyp : Entity_Id := Underlying_Type (Typ);
      Decl : Node_Id;
      Decl : Node_Id;
      Atyp : Entity_Id;
      Atyp : Entity_Id;
 
 
   begin
   begin
      if No (Utyp) then
      if No (Utyp) then
         Utyp := Typ;
         Utyp := Typ;
      end if;
      end if;
 
 
      --  If what we have is an identifier that references a subprogram
      --  If what we have is an identifier that references a subprogram
      --  formal, or a variable or constant object, then we get the actual
      --  formal, or a variable or constant object, then we get the actual
      --  subtype from the referenced entity if one has been built.
      --  subtype from the referenced entity if one has been built.
 
 
      if Nkind (N) = N_Identifier
      if Nkind (N) = N_Identifier
        and then
        and then
          (Is_Formal (Entity (N))
          (Is_Formal (Entity (N))
            or else Ekind (Entity (N)) = E_Constant
            or else Ekind (Entity (N)) = E_Constant
            or else Ekind (Entity (N)) = E_Variable)
            or else Ekind (Entity (N)) = E_Variable)
        and then Present (Actual_Subtype (Entity (N)))
        and then Present (Actual_Subtype (Entity (N)))
      then
      then
         return Actual_Subtype (Entity (N));
         return Actual_Subtype (Entity (N));
 
 
      --  Actual subtype of unchecked union is always itself. We never need
      --  Actual subtype of unchecked union is always itself. We never need
      --  the "real" actual subtype. If we did, we couldn't get it anyway
      --  the "real" actual subtype. If we did, we couldn't get it anyway
      --  because the discriminant is not available. The restrictions on
      --  because the discriminant is not available. The restrictions on
      --  Unchecked_Union are designed to make sure that this is OK.
      --  Unchecked_Union are designed to make sure that this is OK.
 
 
      elsif Is_Unchecked_Union (Base_Type (Utyp)) then
      elsif Is_Unchecked_Union (Base_Type (Utyp)) then
         return Typ;
         return Typ;
 
 
      --  Here for the unconstrained case, we must find actual subtype
      --  Here for the unconstrained case, we must find actual subtype
      --  No actual subtype is available, so we must build it on the fly.
      --  No actual subtype is available, so we must build it on the fly.
 
 
      --  Checking the type, not the underlying type, for constrainedness
      --  Checking the type, not the underlying type, for constrainedness
      --  seems to be necessary. Maybe all the tests should be on the type???
      --  seems to be necessary. Maybe all the tests should be on the type???
 
 
      elsif (not Is_Constrained (Typ))
      elsif (not Is_Constrained (Typ))
           and then (Is_Array_Type (Utyp)
           and then (Is_Array_Type (Utyp)
                      or else (Is_Record_Type (Utyp)
                      or else (Is_Record_Type (Utyp)
                                and then Has_Discriminants (Utyp)))
                                and then Has_Discriminants (Utyp)))
           and then not Has_Unknown_Discriminants (Utyp)
           and then not Has_Unknown_Discriminants (Utyp)
           and then not (Ekind (Utyp) = E_String_Literal_Subtype)
           and then not (Ekind (Utyp) = E_String_Literal_Subtype)
      then
      then
         --  Nothing to do if in spec expression (why not???)
         --  Nothing to do if in spec expression (why not???)
 
 
         if In_Spec_Expression then
         if In_Spec_Expression then
            return Typ;
            return Typ;
 
 
         elsif Is_Private_Type (Typ)
         elsif Is_Private_Type (Typ)
           and then not Has_Discriminants (Typ)
           and then not Has_Discriminants (Typ)
         then
         then
            --  If the type has no discriminants, there is no subtype to
            --  If the type has no discriminants, there is no subtype to
            --  build, even if the underlying type is discriminated.
            --  build, even if the underlying type is discriminated.
 
 
            return Typ;
            return Typ;
 
 
         --  Else build the actual subtype
         --  Else build the actual subtype
 
 
         else
         else
            Decl := Build_Actual_Subtype (Typ, N);
            Decl := Build_Actual_Subtype (Typ, N);
            Atyp := Defining_Identifier (Decl);
            Atyp := Defining_Identifier (Decl);
 
 
            --  If Build_Actual_Subtype generated a new declaration then use it
            --  If Build_Actual_Subtype generated a new declaration then use it
 
 
            if Atyp /= Typ then
            if Atyp /= Typ then
 
 
               --  The actual subtype is an Itype, so analyze the declaration,
               --  The actual subtype is an Itype, so analyze the declaration,
               --  but do not attach it to the tree, to get the type defined.
               --  but do not attach it to the tree, to get the type defined.
 
 
               Set_Parent (Decl, N);
               Set_Parent (Decl, N);
               Set_Is_Itype (Atyp);
               Set_Is_Itype (Atyp);
               Analyze (Decl, Suppress => All_Checks);
               Analyze (Decl, Suppress => All_Checks);
               Set_Associated_Node_For_Itype (Atyp, N);
               Set_Associated_Node_For_Itype (Atyp, N);
               Set_Has_Delayed_Freeze (Atyp, False);
               Set_Has_Delayed_Freeze (Atyp, False);
 
 
               --  We need to freeze the actual subtype immediately. This is
               --  We need to freeze the actual subtype immediately. This is
               --  needed, because otherwise this Itype will not get frozen
               --  needed, because otherwise this Itype will not get frozen
               --  at all, and it is always safe to freeze on creation because
               --  at all, and it is always safe to freeze on creation because
               --  any associated types must be frozen at this point.
               --  any associated types must be frozen at this point.
 
 
               Freeze_Itype (Atyp, N);
               Freeze_Itype (Atyp, N);
               return Atyp;
               return Atyp;
 
 
            --  Otherwise we did not build a declaration, so return original
            --  Otherwise we did not build a declaration, so return original
 
 
            else
            else
               return Typ;
               return Typ;
            end if;
            end if;
         end if;
         end if;
 
 
      --  For all remaining cases, the actual subtype is the same as
      --  For all remaining cases, the actual subtype is the same as
      --  the nominal type.
      --  the nominal type.
 
 
      else
      else
         return Typ;
         return Typ;
      end if;
      end if;
   end Get_Actual_Subtype;
   end Get_Actual_Subtype;
 
 
   -------------------------------------
   -------------------------------------
   -- Get_Actual_Subtype_If_Available --
   -- Get_Actual_Subtype_If_Available --
   -------------------------------------
   -------------------------------------
 
 
   function Get_Actual_Subtype_If_Available (N : Node_Id) return Entity_Id is
   function Get_Actual_Subtype_If_Available (N : Node_Id) return Entity_Id is
      Typ  : constant Entity_Id := Etype (N);
      Typ  : constant Entity_Id := Etype (N);
 
 
   begin
   begin
      --  If what we have is an identifier that references a subprogram
      --  If what we have is an identifier that references a subprogram
      --  formal, or a variable or constant object, then we get the actual
      --  formal, or a variable or constant object, then we get the actual
      --  subtype from the referenced entity if one has been built.
      --  subtype from the referenced entity if one has been built.
 
 
      if Nkind (N) = N_Identifier
      if Nkind (N) = N_Identifier
        and then
        and then
          (Is_Formal (Entity (N))
          (Is_Formal (Entity (N))
            or else Ekind (Entity (N)) = E_Constant
            or else Ekind (Entity (N)) = E_Constant
            or else Ekind (Entity (N)) = E_Variable)
            or else Ekind (Entity (N)) = E_Variable)
        and then Present (Actual_Subtype (Entity (N)))
        and then Present (Actual_Subtype (Entity (N)))
      then
      then
         return Actual_Subtype (Entity (N));
         return Actual_Subtype (Entity (N));
 
 
      --  Otherwise the Etype of N is returned unchanged
      --  Otherwise the Etype of N is returned unchanged
 
 
      else
      else
         return Typ;
         return Typ;
      end if;
      end if;
   end Get_Actual_Subtype_If_Available;
   end Get_Actual_Subtype_If_Available;
 
 
   -------------------------------
   -------------------------------
   -- Get_Default_External_Name --
   -- Get_Default_External_Name --
   -------------------------------
   -------------------------------
 
 
   function Get_Default_External_Name (E : Node_Or_Entity_Id) return Node_Id is
   function Get_Default_External_Name (E : Node_Or_Entity_Id) return Node_Id is
   begin
   begin
      Get_Decoded_Name_String (Chars (E));
      Get_Decoded_Name_String (Chars (E));
 
 
      if Opt.External_Name_Imp_Casing = Uppercase then
      if Opt.External_Name_Imp_Casing = Uppercase then
         Set_Casing (All_Upper_Case);
         Set_Casing (All_Upper_Case);
      else
      else
         Set_Casing (All_Lower_Case);
         Set_Casing (All_Lower_Case);
      end if;
      end if;
 
 
      return
      return
        Make_String_Literal (Sloc (E),
        Make_String_Literal (Sloc (E),
          Strval => String_From_Name_Buffer);
          Strval => String_From_Name_Buffer);
   end Get_Default_External_Name;
   end Get_Default_External_Name;
 
 
   ---------------------------
   ---------------------------
   -- Get_Enum_Lit_From_Pos --
   -- Get_Enum_Lit_From_Pos --
   ---------------------------
   ---------------------------
 
 
   function Get_Enum_Lit_From_Pos
   function Get_Enum_Lit_From_Pos
     (T   : Entity_Id;
     (T   : Entity_Id;
      Pos : Uint;
      Pos : Uint;
      Loc : Source_Ptr) return Node_Id
      Loc : Source_Ptr) return Node_Id
   is
   is
      Lit : Node_Id;
      Lit : Node_Id;
 
 
   begin
   begin
      --  In the case where the literal is of type Character, Wide_Character
      --  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
      --  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
      --  to be some special handling since there is no explicit chain of
      --  literals to search. Instead, an N_Character_Literal node is created
      --  literals to search. Instead, an N_Character_Literal node is created
      --  with the appropriate Char_Code and Chars fields.
      --  with the appropriate Char_Code and Chars fields.
 
 
      if Is_Standard_Character_Type (T) then
      if Is_Standard_Character_Type (T) then
         Set_Character_Literal_Name (UI_To_CC (Pos));
         Set_Character_Literal_Name (UI_To_CC (Pos));
         return
         return
           Make_Character_Literal (Loc,
           Make_Character_Literal (Loc,
             Chars              => Name_Find,
             Chars              => Name_Find,
             Char_Literal_Value => Pos);
             Char_Literal_Value => Pos);
 
 
      --  For all other cases, we have a complete table of literals, and
      --  For all other cases, we have a complete table of literals, and
      --  we simply iterate through the chain of literal until the one
      --  we simply iterate through the chain of literal until the one
      --  with the desired position value is found.
      --  with the desired position value is found.
      --
      --
 
 
      else
      else
         Lit := First_Literal (Base_Type (T));
         Lit := First_Literal (Base_Type (T));
         for J in 1 .. UI_To_Int (Pos) loop
         for J in 1 .. UI_To_Int (Pos) loop
            Next_Literal (Lit);
            Next_Literal (Lit);
         end loop;
         end loop;
 
 
         return New_Occurrence_Of (Lit, Loc);
         return New_Occurrence_Of (Lit, Loc);
      end if;
      end if;
   end Get_Enum_Lit_From_Pos;
   end Get_Enum_Lit_From_Pos;
 
 
   ------------------------
   ------------------------
   -- Get_Generic_Entity --
   -- Get_Generic_Entity --
   ------------------------
   ------------------------
 
 
   function Get_Generic_Entity (N : Node_Id) return Entity_Id is
   function Get_Generic_Entity (N : Node_Id) return Entity_Id is
      Ent : constant Entity_Id := Entity (Name (N));
      Ent : constant Entity_Id := Entity (Name (N));
   begin
   begin
      if Present (Renamed_Object (Ent)) then
      if Present (Renamed_Object (Ent)) then
         return Renamed_Object (Ent);
         return Renamed_Object (Ent);
      else
      else
         return Ent;
         return Ent;
      end if;
      end if;
   end Get_Generic_Entity;
   end Get_Generic_Entity;
 
 
   ----------------------
   ----------------------
   -- Get_Index_Bounds --
   -- Get_Index_Bounds --
   ----------------------
   ----------------------
 
 
   procedure Get_Index_Bounds (N : Node_Id; L, H : out Node_Id) is
   procedure Get_Index_Bounds (N : Node_Id; L, H : out Node_Id) is
      Kind : constant Node_Kind := Nkind (N);
      Kind : constant Node_Kind := Nkind (N);
      R    : Node_Id;
      R    : Node_Id;
 
 
   begin
   begin
      if Kind = N_Range then
      if Kind = N_Range then
         L := Low_Bound (N);
         L := Low_Bound (N);
         H := High_Bound (N);
         H := High_Bound (N);
 
 
      elsif Kind = N_Subtype_Indication then
      elsif Kind = N_Subtype_Indication then
         R := Range_Expression (Constraint (N));
         R := Range_Expression (Constraint (N));
 
 
         if R = Error then
         if R = Error then
            L := Error;
            L := Error;
            H := Error;
            H := Error;
            return;
            return;
 
 
         else
         else
            L := Low_Bound  (Range_Expression (Constraint (N)));
            L := Low_Bound  (Range_Expression (Constraint (N)));
            H := High_Bound (Range_Expression (Constraint (N)));
            H := High_Bound (Range_Expression (Constraint (N)));
         end if;
         end if;
 
 
      elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
      elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
         if Error_Posted (Scalar_Range (Entity (N))) then
         if Error_Posted (Scalar_Range (Entity (N))) then
            L := Error;
            L := Error;
            H := Error;
            H := Error;
 
 
         elsif Nkind (Scalar_Range (Entity (N))) = N_Subtype_Indication then
         elsif Nkind (Scalar_Range (Entity (N))) = N_Subtype_Indication then
            Get_Index_Bounds (Scalar_Range (Entity (N)), L, H);
            Get_Index_Bounds (Scalar_Range (Entity (N)), L, H);
 
 
         else
         else
            L := Low_Bound  (Scalar_Range (Entity (N)));
            L := Low_Bound  (Scalar_Range (Entity (N)));
            H := High_Bound (Scalar_Range (Entity (N)));
            H := High_Bound (Scalar_Range (Entity (N)));
         end if;
         end if;
 
 
      else
      else
         --  N is an expression, indicating a range with one value
         --  N is an expression, indicating a range with one value
 
 
         L := N;
         L := N;
         H := N;
         H := N;
      end if;
      end if;
   end Get_Index_Bounds;
   end Get_Index_Bounds;
 
 
   ----------------------------------
   ----------------------------------
   -- Get_Library_Unit_Name_string --
   -- Get_Library_Unit_Name_string --
   ----------------------------------
   ----------------------------------
 
 
   procedure Get_Library_Unit_Name_String (Decl_Node : Node_Id) is
   procedure Get_Library_Unit_Name_String (Decl_Node : Node_Id) is
      Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
      Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
 
 
   begin
   begin
      Get_Unit_Name_String (Unit_Name_Id);
      Get_Unit_Name_String (Unit_Name_Id);
 
 
      --  Remove seven last character (" (spec)" or " (body)")
      --  Remove seven last character (" (spec)" or " (body)")
 
 
      Name_Len := Name_Len - 7;
      Name_Len := Name_Len - 7;
      pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
      pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
   end Get_Library_Unit_Name_String;
   end Get_Library_Unit_Name_String;
 
 
   ------------------------
   ------------------------
   -- Get_Name_Entity_Id --
   -- Get_Name_Entity_Id --
   ------------------------
   ------------------------
 
 
   function Get_Name_Entity_Id (Id : Name_Id) return Entity_Id is
   function Get_Name_Entity_Id (Id : Name_Id) return Entity_Id is
   begin
   begin
      return Entity_Id (Get_Name_Table_Info (Id));
      return Entity_Id (Get_Name_Table_Info (Id));
   end Get_Name_Entity_Id;
   end Get_Name_Entity_Id;
 
 
   -------------------
   -------------------
   -- Get_Pragma_Id --
   -- Get_Pragma_Id --
   -------------------
   -------------------
 
 
   function Get_Pragma_Id (N : Node_Id) return Pragma_Id is
   function Get_Pragma_Id (N : Node_Id) return Pragma_Id is
   begin
   begin
      return Get_Pragma_Id (Pragma_Name (N));
      return Get_Pragma_Id (Pragma_Name (N));
   end Get_Pragma_Id;
   end Get_Pragma_Id;
 
 
   ---------------------------
   ---------------------------
   -- Get_Referenced_Object --
   -- Get_Referenced_Object --
   ---------------------------
   ---------------------------
 
 
   function Get_Referenced_Object (N : Node_Id) return Node_Id is
   function Get_Referenced_Object (N : Node_Id) return Node_Id is
      R : Node_Id;
      R : Node_Id;
 
 
   begin
   begin
      R := N;
      R := N;
      while Is_Entity_Name (R)
      while Is_Entity_Name (R)
        and then Present (Renamed_Object (Entity (R)))
        and then Present (Renamed_Object (Entity (R)))
      loop
      loop
         R := Renamed_Object (Entity (R));
         R := Renamed_Object (Entity (R));
      end loop;
      end loop;
 
 
      return R;
      return R;
   end Get_Referenced_Object;
   end Get_Referenced_Object;
 
 
   ------------------------
   ------------------------
   -- Get_Renamed_Entity --
   -- Get_Renamed_Entity --
   ------------------------
   ------------------------
 
 
   function Get_Renamed_Entity (E : Entity_Id) return Entity_Id is
   function Get_Renamed_Entity (E : Entity_Id) return Entity_Id is
      R : Entity_Id;
      R : Entity_Id;
 
 
   begin
   begin
      R := E;
      R := E;
      while Present (Renamed_Entity (R)) loop
      while Present (Renamed_Entity (R)) loop
         R := Renamed_Entity (R);
         R := Renamed_Entity (R);
      end loop;
      end loop;
 
 
      return R;
      return R;
   end Get_Renamed_Entity;
   end Get_Renamed_Entity;
 
 
   -------------------------
   -------------------------
   -- Get_Subprogram_Body --
   -- Get_Subprogram_Body --
   -------------------------
   -------------------------
 
 
   function Get_Subprogram_Body (E : Entity_Id) return Node_Id is
   function Get_Subprogram_Body (E : Entity_Id) return Node_Id is
      Decl : Node_Id;
      Decl : Node_Id;
 
 
   begin
   begin
      Decl := Unit_Declaration_Node (E);
      Decl := Unit_Declaration_Node (E);
 
 
      if Nkind (Decl) = N_Subprogram_Body then
      if Nkind (Decl) = N_Subprogram_Body then
         return Decl;
         return Decl;
 
 
      --  The below comment is bad, because it is possible for
      --  The below comment is bad, because it is possible for
      --  Nkind (Decl) to be an N_Subprogram_Body_Stub ???
      --  Nkind (Decl) to be an N_Subprogram_Body_Stub ???
 
 
      else           --  Nkind (Decl) = N_Subprogram_Declaration
      else           --  Nkind (Decl) = N_Subprogram_Declaration
 
 
         if Present (Corresponding_Body (Decl)) then
         if Present (Corresponding_Body (Decl)) then
            return Unit_Declaration_Node (Corresponding_Body (Decl));
            return Unit_Declaration_Node (Corresponding_Body (Decl));
 
 
         --  Imported subprogram case
         --  Imported subprogram case
 
 
         else
         else
            return Empty;
            return Empty;
         end if;
         end if;
      end if;
      end if;
   end Get_Subprogram_Body;
   end Get_Subprogram_Body;
 
 
   ---------------------------
   ---------------------------
   -- Get_Subprogram_Entity --
   -- Get_Subprogram_Entity --
   ---------------------------
   ---------------------------
 
 
   function Get_Subprogram_Entity (Nod : Node_Id) return Entity_Id is
   function Get_Subprogram_Entity (Nod : Node_Id) return Entity_Id is
      Nam  : Node_Id;
      Nam  : Node_Id;
      Proc : Entity_Id;
      Proc : Entity_Id;
 
 
   begin
   begin
      if Nkind (Nod) = N_Accept_Statement then
      if Nkind (Nod) = N_Accept_Statement then
         Nam := Entry_Direct_Name (Nod);
         Nam := Entry_Direct_Name (Nod);
 
 
      --  For an entry call, the prefix of the call is a selected component.
      --  For an entry call, the prefix of the call is a selected component.
      --  Need additional code for internal calls ???
      --  Need additional code for internal calls ???
 
 
      elsif Nkind (Nod) = N_Entry_Call_Statement then
      elsif Nkind (Nod) = N_Entry_Call_Statement then
         if Nkind (Name (Nod)) = N_Selected_Component then
         if Nkind (Name (Nod)) = N_Selected_Component then
            Nam := Entity (Selector_Name (Name (Nod)));
            Nam := Entity (Selector_Name (Name (Nod)));
         else
         else
            Nam := Empty;
            Nam := Empty;
         end if;
         end if;
 
 
      else
      else
         Nam := Name (Nod);
         Nam := Name (Nod);
      end if;
      end if;
 
 
      if Nkind (Nam) = N_Explicit_Dereference then
      if Nkind (Nam) = N_Explicit_Dereference then
         Proc := Etype (Prefix (Nam));
         Proc := Etype (Prefix (Nam));
      elsif Is_Entity_Name (Nam) then
      elsif Is_Entity_Name (Nam) then
         Proc := Entity (Nam);
         Proc := Entity (Nam);
      else
      else
         return Empty;
         return Empty;
      end if;
      end if;
 
 
      if Is_Object (Proc) then
      if Is_Object (Proc) then
         Proc := Etype (Proc);
         Proc := Etype (Proc);
      end if;
      end if;
 
 
      if Ekind (Proc) = E_Access_Subprogram_Type then
      if Ekind (Proc) = E_Access_Subprogram_Type then
         Proc := Directly_Designated_Type (Proc);
         Proc := Directly_Designated_Type (Proc);
      end if;
      end if;
 
 
      if not Is_Subprogram (Proc)
      if not Is_Subprogram (Proc)
        and then Ekind (Proc) /= E_Subprogram_Type
        and then Ekind (Proc) /= E_Subprogram_Type
      then
      then
         return Empty;
         return Empty;
      else
      else
         return Proc;
         return Proc;
      end if;
      end if;
   end Get_Subprogram_Entity;
   end Get_Subprogram_Entity;
 
 
   -----------------------------
   -----------------------------
   -- Get_Task_Body_Procedure --
   -- Get_Task_Body_Procedure --
   -----------------------------
   -----------------------------
 
 
   function Get_Task_Body_Procedure (E : Entity_Id) return Node_Id is
   function Get_Task_Body_Procedure (E : Entity_Id) return Node_Id is
   begin
   begin
      --  Note: A task type may be the completion of a private type with
      --  Note: A task type may be the completion of a private type with
      --  discriminants. When performing elaboration checks on a task
      --  discriminants. When performing elaboration checks on a task
      --  declaration, the current view of the type may be the private one,
      --  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
      --  and the procedure that holds the body of the task is held in its
      --  underlying type.
      --  underlying type.
 
 
      --  This is an odd function, why not have Task_Body_Procedure do
      --  This is an odd function, why not have Task_Body_Procedure do
      --  the following digging???
      --  the following digging???
 
 
      return Task_Body_Procedure (Underlying_Type (Root_Type (E)));
      return Task_Body_Procedure (Underlying_Type (Root_Type (E)));
   end Get_Task_Body_Procedure;
   end Get_Task_Body_Procedure;
 
 
   -----------------------
   -----------------------
   -- Has_Access_Values --
   -- Has_Access_Values --
   -----------------------
   -----------------------
 
 
   function Has_Access_Values (T : Entity_Id) return Boolean is
   function Has_Access_Values (T : Entity_Id) return Boolean is
      Typ : constant Entity_Id := Underlying_Type (T);
      Typ : constant Entity_Id := Underlying_Type (T);
 
 
   begin
   begin
      --  Case of a private type which is not completed yet. This can only
      --  Case of a private type which is not completed yet. This can only
      --  happen in the case of a generic format type appearing directly, or
      --  happen in the case of a generic format type appearing directly, or
      --  as a component of the type to which this function is being applied
      --  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
      --  at the top level. Return False in this case, since we certainly do
      --  not know that the type contains access types.
      --  not know that the type contains access types.
 
 
      if No (Typ) then
      if No (Typ) then
         return False;
         return False;
 
 
      elsif Is_Access_Type (Typ) then
      elsif Is_Access_Type (Typ) then
         return True;
         return True;
 
 
      elsif Is_Array_Type (Typ) then
      elsif Is_Array_Type (Typ) then
         return Has_Access_Values (Component_Type (Typ));
         return Has_Access_Values (Component_Type (Typ));
 
 
      elsif Is_Record_Type (Typ) then
      elsif Is_Record_Type (Typ) then
         declare
         declare
            Comp : Entity_Id;
            Comp : Entity_Id;
 
 
         begin
         begin
            --  Loop to Check components
            --  Loop to Check components
 
 
            Comp := First_Component_Or_Discriminant (Typ);
            Comp := First_Component_Or_Discriminant (Typ);
            while Present (Comp) loop
            while Present (Comp) loop
 
 
               --  Check for access component, tag field does not count, even
               --  Check for access component, tag field does not count, even
               --  though it is implemented internally using an access type.
               --  though it is implemented internally using an access type.
 
 
               if Has_Access_Values (Etype (Comp))
               if Has_Access_Values (Etype (Comp))
                 and then Chars (Comp) /= Name_uTag
                 and then Chars (Comp) /= Name_uTag
               then
               then
                  return True;
                  return True;
               end if;
               end if;
 
 
               Next_Component_Or_Discriminant (Comp);
               Next_Component_Or_Discriminant (Comp);
            end loop;
            end loop;
         end;
         end;
 
 
         return False;
         return False;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Has_Access_Values;
   end Has_Access_Values;
 
 
   ------------------------------
   ------------------------------
   -- Has_Compatible_Alignment --
   -- Has_Compatible_Alignment --
   ------------------------------
   ------------------------------
 
 
   function Has_Compatible_Alignment
   function Has_Compatible_Alignment
     (Obj  : Entity_Id;
     (Obj  : Entity_Id;
      Expr : Node_Id) return Alignment_Result
      Expr : Node_Id) return Alignment_Result
   is
   is
      function Has_Compatible_Alignment_Internal
      function Has_Compatible_Alignment_Internal
        (Obj     : Entity_Id;
        (Obj     : Entity_Id;
         Expr    : Node_Id;
         Expr    : Node_Id;
         Default : Alignment_Result) return Alignment_Result;
         Default : Alignment_Result) return Alignment_Result;
      --  This is the internal recursive function that actually does the work.
      --  This is the internal recursive function that actually does the work.
      --  There is one additional parameter, which says what the result should
      --  There is one additional parameter, which says what the result should
      --  be if no alignment information is found, and there is no definite
      --  be if no alignment information is found, and there is no definite
      --  indication of compatible alignments. At the outer level, this is set
      --  indication of compatible alignments. At the outer level, this is set
      --  to Unknown, but for internal recursive calls in the case where types
      --  to Unknown, but for internal recursive calls in the case where types
      --  are known to be correct, it is set to Known_Compatible.
      --  are known to be correct, it is set to Known_Compatible.
 
 
      ---------------------------------------
      ---------------------------------------
      -- Has_Compatible_Alignment_Internal --
      -- Has_Compatible_Alignment_Internal --
      ---------------------------------------
      ---------------------------------------
 
 
      function Has_Compatible_Alignment_Internal
      function Has_Compatible_Alignment_Internal
        (Obj     : Entity_Id;
        (Obj     : Entity_Id;
         Expr    : Node_Id;
         Expr    : Node_Id;
         Default : Alignment_Result) return Alignment_Result
         Default : Alignment_Result) return Alignment_Result
      is
      is
         Result : Alignment_Result := Known_Compatible;
         Result : Alignment_Result := Known_Compatible;
         --  Holds the current status of the result. Note that once a value of
         --  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
         --  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,
         --  to Unknown (the value in Result only gets worse as we go along,
         --  never better).
         --  never better).
 
 
         Offs : Uint := No_Uint;
         Offs : Uint := No_Uint;
         --  Set to a factor of the offset from the base object when Expr is a
         --  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
         --  selected or indexed component, based on Component_Bit_Offset and
         --  Component_Size respectively. A negative value is used to represent
         --  Component_Size respectively. A negative value is used to represent
         --  a value which is not known at compile time.
         --  a value which is not known at compile time.
 
 
         procedure Check_Prefix;
         procedure Check_Prefix;
         --  Checks the prefix recursively in the case where the expression
         --  Checks the prefix recursively in the case where the expression
         --  is an indexed or selected component.
         --  is an indexed or selected component.
 
 
         procedure Set_Result (R : Alignment_Result);
         procedure Set_Result (R : Alignment_Result);
         --  If R represents a worse outcome (unknown instead of known
         --  If R represents a worse outcome (unknown instead of known
         --  compatible, or known incompatible), then set Result to R.
         --  compatible, or known incompatible), then set Result to R.
 
 
         ------------------
         ------------------
         -- Check_Prefix --
         -- Check_Prefix --
         ------------------
         ------------------
 
 
         procedure Check_Prefix is
         procedure Check_Prefix is
         begin
         begin
            --  The subtlety here is that in doing a recursive call to check
            --  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
            --  the prefix, we have to decide what to do in the case where we
            --  don't find any specific indication of an alignment problem.
            --  don't find any specific indication of an alignment problem.
 
 
            --  At the outer level, we normally set Unknown as the result in
            --  At the outer level, we normally set Unknown as the result in
            --  this case, since we can only set Known_Compatible if we really
            --  this case, since we can only set Known_Compatible if we really
            --  know that the alignment value is OK, but for the recursive
            --  know that the alignment value is OK, but for the recursive
            --  call, in the case where the types match, and we have not
            --  call, in the case where the types match, and we have not
            --  specified a peculiar alignment for the object, we are only
            --  specified a peculiar alignment for the object, we are only
            --  concerned about suspicious rep clauses, the default case does
            --  concerned about suspicious rep clauses, the default case does
            --  not affect us, since the compiler will, in the absence of such
            --  not affect us, since the compiler will, in the absence of such
            --  rep clauses, ensure that the alignment is correct.
            --  rep clauses, ensure that the alignment is correct.
 
 
            if Default = Known_Compatible
            if Default = Known_Compatible
              or else
              or else
                (Etype (Obj) = Etype (Expr)
                (Etype (Obj) = Etype (Expr)
                  and then (Unknown_Alignment (Obj)
                  and then (Unknown_Alignment (Obj)
                             or else
                             or else
                               Alignment (Obj) = Alignment (Etype (Obj))))
                               Alignment (Obj) = Alignment (Etype (Obj))))
            then
            then
               Set_Result
               Set_Result
                 (Has_Compatible_Alignment_Internal
                 (Has_Compatible_Alignment_Internal
                    (Obj, Prefix (Expr), Known_Compatible));
                    (Obj, Prefix (Expr), Known_Compatible));
 
 
            --  In all other cases, we need a full check on the prefix
            --  In all other cases, we need a full check on the prefix
 
 
            else
            else
               Set_Result
               Set_Result
                 (Has_Compatible_Alignment_Internal
                 (Has_Compatible_Alignment_Internal
                    (Obj, Prefix (Expr), Unknown));
                    (Obj, Prefix (Expr), Unknown));
            end if;
            end if;
         end Check_Prefix;
         end Check_Prefix;
 
 
         ----------------
         ----------------
         -- Set_Result --
         -- Set_Result --
         ----------------
         ----------------
 
 
         procedure Set_Result (R : Alignment_Result) is
         procedure Set_Result (R : Alignment_Result) is
         begin
         begin
            if R > Result then
            if R > Result then
               Result := R;
               Result := R;
            end if;
            end if;
         end Set_Result;
         end Set_Result;
 
 
      --  Start of processing for Has_Compatible_Alignment_Internal
      --  Start of processing for Has_Compatible_Alignment_Internal
 
 
      begin
      begin
         --  If Expr is a selected component, we must make sure there is no
         --  If Expr is a selected component, we must make sure there is no
         --  potentially troublesome component clause, and that the record is
         --  potentially troublesome component clause, and that the record is
         --  not packed.
         --  not packed.
 
 
         if Nkind (Expr) = N_Selected_Component then
         if Nkind (Expr) = N_Selected_Component then
 
 
            --  Packed record always generate unknown alignment
            --  Packed record always generate unknown alignment
 
 
            if Is_Packed (Etype (Prefix (Expr))) then
            if Is_Packed (Etype (Prefix (Expr))) then
               Set_Result (Unknown);
               Set_Result (Unknown);
            end if;
            end if;
 
 
            --  Check prefix and component offset
            --  Check prefix and component offset
 
 
            Check_Prefix;
            Check_Prefix;
            Offs := Component_Bit_Offset (Entity (Selector_Name (Expr)));
            Offs := Component_Bit_Offset (Entity (Selector_Name (Expr)));
 
 
         --  If Expr is an indexed component, we must make sure there is no
         --  If Expr is an indexed component, we must make sure there is no
         --  potentially troublesome Component_Size clause and that the array
         --  potentially troublesome Component_Size clause and that the array
         --  is not bit-packed.
         --  is not bit-packed.
 
 
         elsif Nkind (Expr) = N_Indexed_Component then
         elsif Nkind (Expr) = N_Indexed_Component then
            declare
            declare
               Typ : constant Entity_Id := Etype (Prefix (Expr));
               Typ : constant Entity_Id := Etype (Prefix (Expr));
               Ind : constant Node_Id   := First_Index (Typ);
               Ind : constant Node_Id   := First_Index (Typ);
 
 
            begin
            begin
               --  Bit packed array always generates unknown alignment
               --  Bit packed array always generates unknown alignment
 
 
               if Is_Bit_Packed_Array (Typ) then
               if Is_Bit_Packed_Array (Typ) then
                  Set_Result (Unknown);
                  Set_Result (Unknown);
               end if;
               end if;
 
 
               --  Check prefix and component offset
               --  Check prefix and component offset
 
 
               Check_Prefix;
               Check_Prefix;
               Offs := Component_Size (Typ);
               Offs := Component_Size (Typ);
 
 
               --  Small optimization: compute the full offset when possible
               --  Small optimization: compute the full offset when possible
 
 
               if Offs /= No_Uint
               if Offs /= No_Uint
                 and then Offs > Uint_0
                 and then Offs > Uint_0
                 and then Present (Ind)
                 and then Present (Ind)
                 and then Nkind (Ind) = N_Range
                 and then Nkind (Ind) = N_Range
                 and then Compile_Time_Known_Value (Low_Bound (Ind))
                 and then Compile_Time_Known_Value (Low_Bound (Ind))
                 and then Compile_Time_Known_Value (First (Expressions (Expr)))
                 and then Compile_Time_Known_Value (First (Expressions (Expr)))
               then
               then
                  Offs := Offs * (Expr_Value (First (Expressions (Expr)))
                  Offs := Offs * (Expr_Value (First (Expressions (Expr)))
                                    - Expr_Value (Low_Bound ((Ind))));
                                    - Expr_Value (Low_Bound ((Ind))));
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
         --  If we have a null offset, the result is entirely determined by
         --  If we have a null offset, the result is entirely determined by
         --  the base object and has already been computed recursively.
         --  the base object and has already been computed recursively.
 
 
         if Offs = Uint_0 then
         if Offs = Uint_0 then
            null;
            null;
 
 
         --  Case where we know the alignment of the object
         --  Case where we know the alignment of the object
 
 
         elsif Known_Alignment (Obj) then
         elsif Known_Alignment (Obj) then
            declare
            declare
               ObjA : constant Uint := Alignment (Obj);
               ObjA : constant Uint := Alignment (Obj);
               ExpA : Uint          := No_Uint;
               ExpA : Uint          := No_Uint;
               SizA : Uint          := No_Uint;
               SizA : Uint          := No_Uint;
 
 
            begin
            begin
               --  If alignment of Obj is 1, then we are always OK
               --  If alignment of Obj is 1, then we are always OK
 
 
               if ObjA = 1 then
               if ObjA = 1 then
                  Set_Result (Known_Compatible);
                  Set_Result (Known_Compatible);
 
 
               --  Alignment of Obj is greater than 1, so we need to check
               --  Alignment of Obj is greater than 1, so we need to check
 
 
               else
               else
                  --  If we have an offset, see if it is compatible
                  --  If we have an offset, see if it is compatible
 
 
                  if Offs /= No_Uint and Offs > Uint_0 then
                  if Offs /= No_Uint and Offs > Uint_0 then
                     if Offs mod (System_Storage_Unit * ObjA) /= 0 then
                     if Offs mod (System_Storage_Unit * ObjA) /= 0 then
                        Set_Result (Known_Incompatible);
                        Set_Result (Known_Incompatible);
                     end if;
                     end if;
 
 
                     --  See if Expr is an object with known alignment
                     --  See if Expr is an object with known alignment
 
 
                  elsif Is_Entity_Name (Expr)
                  elsif Is_Entity_Name (Expr)
                    and then Known_Alignment (Entity (Expr))
                    and then Known_Alignment (Entity (Expr))
                  then
                  then
                     ExpA := Alignment (Entity (Expr));
                     ExpA := Alignment (Entity (Expr));
 
 
                     --  Otherwise, we can use the alignment of the type of
                     --  Otherwise, we can use the alignment of the type of
                     --  Expr given that we already checked for
                     --  Expr given that we already checked for
                     --  discombobulating rep clauses for the cases of indexed
                     --  discombobulating rep clauses for the cases of indexed
                     --  and selected components above.
                     --  and selected components above.
 
 
                  elsif Known_Alignment (Etype (Expr)) then
                  elsif Known_Alignment (Etype (Expr)) then
                     ExpA := Alignment (Etype (Expr));
                     ExpA := Alignment (Etype (Expr));
 
 
                     --  Otherwise the alignment is unknown
                     --  Otherwise the alignment is unknown
 
 
                  else
                  else
                     Set_Result (Default);
                     Set_Result (Default);
                  end if;
                  end if;
 
 
                  --  If we got an alignment, see if it is acceptable
                  --  If we got an alignment, see if it is acceptable
 
 
                  if ExpA /= No_Uint and then ExpA < ObjA then
                  if ExpA /= No_Uint and then ExpA < ObjA then
                     Set_Result (Known_Incompatible);
                     Set_Result (Known_Incompatible);
                  end if;
                  end if;
 
 
                  --  If Expr is not a piece of a larger object, see if size
                  --  If Expr is not a piece of a larger object, see if size
                  --  is given. If so, check that it is not too small for the
                  --  is given. If so, check that it is not too small for the
                  --  required alignment.
                  --  required alignment.
 
 
                  if Offs /= No_Uint then
                  if Offs /= No_Uint then
                     null;
                     null;
 
 
                     --  See if Expr is an object with known size
                     --  See if Expr is an object with known size
 
 
                  elsif Is_Entity_Name (Expr)
                  elsif Is_Entity_Name (Expr)
                    and then Known_Static_Esize (Entity (Expr))
                    and then Known_Static_Esize (Entity (Expr))
                  then
                  then
                     SizA := Esize (Entity (Expr));
                     SizA := Esize (Entity (Expr));
 
 
                     --  Otherwise, we check the object size of the Expr type
                     --  Otherwise, we check the object size of the Expr type
 
 
                  elsif Known_Static_Esize (Etype (Expr)) then
                  elsif Known_Static_Esize (Etype (Expr)) then
                     SizA := Esize (Etype (Expr));
                     SizA := Esize (Etype (Expr));
                  end if;
                  end if;
 
 
                  --  If we got a size, see if it is a multiple of the Obj
                  --  If we got a size, see if it is a multiple of the Obj
                  --  alignment, if not, then the alignment cannot be
                  --  alignment, if not, then the alignment cannot be
                  --  acceptable, since the size is always a multiple of the
                  --  acceptable, since the size is always a multiple of the
                  --  alignment.
                  --  alignment.
 
 
                  if SizA /= No_Uint then
                  if SizA /= No_Uint then
                     if SizA mod (ObjA * Ttypes.System_Storage_Unit) /= 0 then
                     if SizA mod (ObjA * Ttypes.System_Storage_Unit) /= 0 then
                        Set_Result (Known_Incompatible);
                        Set_Result (Known_Incompatible);
                     end if;
                     end if;
                  end if;
                  end if;
               end if;
               end if;
            end;
            end;
 
 
         --  If we do not know required alignment, any non-zero offset is a
         --  If we do not know required alignment, any non-zero offset is a
         --  potential problem (but certainly may be OK, so result is unknown).
         --  potential problem (but certainly may be OK, so result is unknown).
 
 
         elsif Offs /= No_Uint then
         elsif Offs /= No_Uint then
            Set_Result (Unknown);
            Set_Result (Unknown);
 
 
         --  If we can't find the result by direct comparison of alignment
         --  If we can't find the result by direct comparison of alignment
         --  values, then there is still one case that we can determine known
         --  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
         --  result, and that is when we can determine that the types are the
         --  same, and no alignments are specified. Then we known that the
         --  same, and no alignments are specified. Then we known that the
         --  alignments are compatible, even if we don't know the alignment
         --  alignments are compatible, even if we don't know the alignment
         --  value in the front end.
         --  value in the front end.
 
 
         elsif Etype (Obj) = Etype (Expr) then
         elsif Etype (Obj) = Etype (Expr) then
 
 
            --  Types are the same, but we have to check for possible size
            --  Types are the same, but we have to check for possible size
            --  and alignments on the Expr object that may make the alignment
            --  and alignments on the Expr object that may make the alignment
            --  different, even though the types are the same.
            --  different, even though the types are the same.
 
 
            if Is_Entity_Name (Expr) then
            if Is_Entity_Name (Expr) then
 
 
               --  First check alignment of the Expr object. Any alignment less
               --  First check alignment of the Expr object. Any alignment less
               --  than Maximum_Alignment is worrisome since this is the case
               --  than Maximum_Alignment is worrisome since this is the case
               --  where we do not know the alignment of Obj.
               --  where we do not know the alignment of Obj.
 
 
               if Known_Alignment (Entity (Expr))
               if Known_Alignment (Entity (Expr))
                 and then
                 and then
                   UI_To_Int (Alignment (Entity (Expr))) <
                   UI_To_Int (Alignment (Entity (Expr))) <
                                                    Ttypes.Maximum_Alignment
                                                    Ttypes.Maximum_Alignment
               then
               then
                  Set_Result (Unknown);
                  Set_Result (Unknown);
 
 
                  --  Now check size of Expr object. Any size that is not an
                  --  Now check size of Expr object. Any size that is not an
                  --  even multiple of Maximum_Alignment is also worrisome
                  --  even multiple of Maximum_Alignment is also worrisome
                  --  since it may cause the alignment of the object to be less
                  --  since it may cause the alignment of the object to be less
                  --  than the alignment of the type.
                  --  than the alignment of the type.
 
 
               elsif Known_Static_Esize (Entity (Expr))
               elsif Known_Static_Esize (Entity (Expr))
                 and then
                 and then
                   (UI_To_Int (Esize (Entity (Expr))) mod
                   (UI_To_Int (Esize (Entity (Expr))) mod
                     (Ttypes.Maximum_Alignment * Ttypes.System_Storage_Unit))
                     (Ttypes.Maximum_Alignment * Ttypes.System_Storage_Unit))
                                                                        /= 0
                                                                        /= 0
               then
               then
                  Set_Result (Unknown);
                  Set_Result (Unknown);
 
 
                  --  Otherwise same type is decisive
                  --  Otherwise same type is decisive
 
 
               else
               else
                  Set_Result (Known_Compatible);
                  Set_Result (Known_Compatible);
               end if;
               end if;
            end if;
            end if;
 
 
         --  Another case to deal with is when there is an explicit size or
         --  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
         --  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
         --  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.
         --  Unknown, since that result will be set in any case.
 
 
         elsif Default /= Unknown
         elsif Default /= Unknown
           and then (Has_Size_Clause      (Etype (Expr))
           and then (Has_Size_Clause      (Etype (Expr))
                      or else
                      or else
                     Has_Alignment_Clause (Etype (Expr)))
                     Has_Alignment_Clause (Etype (Expr)))
         then
         then
            Set_Result (Unknown);
            Set_Result (Unknown);
 
 
         --  If no indication found, set default
         --  If no indication found, set default
 
 
         else
         else
            Set_Result (Default);
            Set_Result (Default);
         end if;
         end if;
 
 
         --  Return worst result found
         --  Return worst result found
 
 
         return Result;
         return Result;
      end Has_Compatible_Alignment_Internal;
      end Has_Compatible_Alignment_Internal;
 
 
   --  Start of processing for Has_Compatible_Alignment
   --  Start of processing for Has_Compatible_Alignment
 
 
   begin
   begin
      --  If Obj has no specified alignment, then set alignment from the type
      --  If Obj has no specified alignment, then set alignment from the type
      --  alignment. Perhaps we should always do this, but for sure we should
      --  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
      --  do it when there is an address clause since we can do more if the
      --  alignment is known.
      --  alignment is known.
 
 
      if Unknown_Alignment (Obj) then
      if Unknown_Alignment (Obj) then
         Set_Alignment (Obj, Alignment (Etype (Obj)));
         Set_Alignment (Obj, Alignment (Etype (Obj)));
      end if;
      end if;
 
 
      --  Now do the internal call that does all the work
      --  Now do the internal call that does all the work
 
 
      return Has_Compatible_Alignment_Internal (Obj, Expr, Unknown);
      return Has_Compatible_Alignment_Internal (Obj, Expr, Unknown);
   end Has_Compatible_Alignment;
   end Has_Compatible_Alignment;
 
 
   ----------------------
   ----------------------
   -- Has_Declarations --
   -- Has_Declarations --
   ----------------------
   ----------------------
 
 
   function Has_Declarations (N : Node_Id) return Boolean is
   function Has_Declarations (N : Node_Id) return Boolean is
   begin
   begin
      return Nkind_In (Nkind (N), N_Accept_Statement,
      return Nkind_In (Nkind (N), N_Accept_Statement,
                                  N_Block_Statement,
                                  N_Block_Statement,
                                  N_Compilation_Unit_Aux,
                                  N_Compilation_Unit_Aux,
                                  N_Entry_Body,
                                  N_Entry_Body,
                                  N_Package_Body,
                                  N_Package_Body,
                                  N_Protected_Body,
                                  N_Protected_Body,
                                  N_Subprogram_Body,
                                  N_Subprogram_Body,
                                  N_Task_Body,
                                  N_Task_Body,
                                  N_Package_Specification);
                                  N_Package_Specification);
   end Has_Declarations;
   end Has_Declarations;
 
 
   -------------------------------------------
   -------------------------------------------
   -- Has_Discriminant_Dependent_Constraint --
   -- Has_Discriminant_Dependent_Constraint --
   -------------------------------------------
   -------------------------------------------
 
 
   function Has_Discriminant_Dependent_Constraint
   function Has_Discriminant_Dependent_Constraint
     (Comp : Entity_Id) return Boolean
     (Comp : Entity_Id) return Boolean
   is
   is
      Comp_Decl  : constant Node_Id := Parent (Comp);
      Comp_Decl  : constant Node_Id := Parent (Comp);
      Subt_Indic : constant Node_Id :=
      Subt_Indic : constant Node_Id :=
                     Subtype_Indication (Component_Definition (Comp_Decl));
                     Subtype_Indication (Component_Definition (Comp_Decl));
      Constr     : Node_Id;
      Constr     : Node_Id;
      Assn       : Node_Id;
      Assn       : Node_Id;
 
 
   begin
   begin
      if Nkind (Subt_Indic) = N_Subtype_Indication then
      if Nkind (Subt_Indic) = N_Subtype_Indication then
         Constr := Constraint (Subt_Indic);
         Constr := Constraint (Subt_Indic);
 
 
         if Nkind (Constr) = N_Index_Or_Discriminant_Constraint then
         if Nkind (Constr) = N_Index_Or_Discriminant_Constraint then
            Assn := First (Constraints (Constr));
            Assn := First (Constraints (Constr));
            while Present (Assn) loop
            while Present (Assn) loop
               case Nkind (Assn) is
               case Nkind (Assn) is
                  when N_Subtype_Indication |
                  when N_Subtype_Indication |
                       N_Range              |
                       N_Range              |
                       N_Identifier
                       N_Identifier
                  =>
                  =>
                     if Depends_On_Discriminant (Assn) then
                     if Depends_On_Discriminant (Assn) then
                        return True;
                        return True;
                     end if;
                     end if;
 
 
                  when N_Discriminant_Association =>
                  when N_Discriminant_Association =>
                     if Depends_On_Discriminant (Expression (Assn)) then
                     if Depends_On_Discriminant (Expression (Assn)) then
                        return True;
                        return True;
                     end if;
                     end if;
 
 
                  when others =>
                  when others =>
                     null;
                     null;
 
 
               end case;
               end case;
 
 
               Next (Assn);
               Next (Assn);
            end loop;
            end loop;
         end if;
         end if;
      end if;
      end if;
 
 
      return False;
      return False;
   end Has_Discriminant_Dependent_Constraint;
   end Has_Discriminant_Dependent_Constraint;
 
 
   --------------------
   --------------------
   -- Has_Infinities --
   -- Has_Infinities --
   --------------------
   --------------------
 
 
   function Has_Infinities (E : Entity_Id) return Boolean is
   function Has_Infinities (E : Entity_Id) return Boolean is
   begin
   begin
      return
      return
        Is_Floating_Point_Type (E)
        Is_Floating_Point_Type (E)
          and then Nkind (Scalar_Range (E)) = N_Range
          and then Nkind (Scalar_Range (E)) = N_Range
          and then Includes_Infinities (Scalar_Range (E));
          and then Includes_Infinities (Scalar_Range (E));
   end Has_Infinities;
   end Has_Infinities;
 
 
   --------------------
   --------------------
   -- Has_Interfaces --
   -- Has_Interfaces --
   --------------------
   --------------------
 
 
   function Has_Interfaces
   function Has_Interfaces
     (T             : Entity_Id;
     (T             : Entity_Id;
      Use_Full_View : Boolean := True) return Boolean
      Use_Full_View : Boolean := True) return Boolean
   is
   is
      Typ : Entity_Id;
      Typ : Entity_Id;
 
 
   begin
   begin
      --  Handle concurrent types
      --  Handle concurrent types
 
 
      if Is_Concurrent_Type (T) then
      if Is_Concurrent_Type (T) then
         Typ := Corresponding_Record_Type (T);
         Typ := Corresponding_Record_Type (T);
      else
      else
         Typ := T;
         Typ := T;
      end if;
      end if;
 
 
      if not Present (Typ)
      if not Present (Typ)
        or else not Is_Record_Type (Typ)
        or else not Is_Record_Type (Typ)
        or else not Is_Tagged_Type (Typ)
        or else not Is_Tagged_Type (Typ)
      then
      then
         return False;
         return False;
      end if;
      end if;
 
 
      --  Handle private types
      --  Handle private types
 
 
      if Use_Full_View
      if Use_Full_View
        and then Present (Full_View (Typ))
        and then Present (Full_View (Typ))
      then
      then
         Typ := Full_View (Typ);
         Typ := Full_View (Typ);
      end if;
      end if;
 
 
      --  Handle concurrent record types
      --  Handle concurrent record types
 
 
      if Is_Concurrent_Record_Type (Typ)
      if Is_Concurrent_Record_Type (Typ)
        and then Is_Non_Empty_List (Abstract_Interface_List (Typ))
        and then Is_Non_Empty_List (Abstract_Interface_List (Typ))
      then
      then
         return True;
         return True;
      end if;
      end if;
 
 
      loop
      loop
         if Is_Interface (Typ)
         if Is_Interface (Typ)
           or else
           or else
             (Is_Record_Type (Typ)
             (Is_Record_Type (Typ)
               and then Present (Interfaces (Typ))
               and then Present (Interfaces (Typ))
               and then not Is_Empty_Elmt_List (Interfaces (Typ)))
               and then not Is_Empty_Elmt_List (Interfaces (Typ)))
         then
         then
            return True;
            return True;
         end if;
         end if;
 
 
         exit when Etype (Typ) = Typ
         exit when Etype (Typ) = Typ
 
 
            --  Handle private types
            --  Handle private types
 
 
            or else (Present (Full_View (Etype (Typ)))
            or else (Present (Full_View (Etype (Typ)))
                       and then Full_View (Etype (Typ)) = Typ)
                       and then Full_View (Etype (Typ)) = Typ)
 
 
            --  Protect the frontend against wrong source with cyclic
            --  Protect the frontend against wrong source with cyclic
            --  derivations
            --  derivations
 
 
            or else Etype (Typ) = T;
            or else Etype (Typ) = T;
 
 
         --  Climb to the ancestor type handling private types
         --  Climb to the ancestor type handling private types
 
 
         if Present (Full_View (Etype (Typ))) then
         if Present (Full_View (Etype (Typ))) then
            Typ := Full_View (Etype (Typ));
            Typ := Full_View (Etype (Typ));
         else
         else
            Typ := Etype (Typ);
            Typ := Etype (Typ);
         end if;
         end if;
      end loop;
      end loop;
 
 
      return False;
      return False;
   end Has_Interfaces;
   end Has_Interfaces;
 
 
   ------------------------
   ------------------------
   -- Has_Null_Exclusion --
   -- Has_Null_Exclusion --
   ------------------------
   ------------------------
 
 
   function Has_Null_Exclusion (N : Node_Id) return Boolean is
   function Has_Null_Exclusion (N : Node_Id) return Boolean is
   begin
   begin
      case Nkind (N) is
      case Nkind (N) is
         when N_Access_Definition               |
         when N_Access_Definition               |
              N_Access_Function_Definition      |
              N_Access_Function_Definition      |
              N_Access_Procedure_Definition     |
              N_Access_Procedure_Definition     |
              N_Access_To_Object_Definition     |
              N_Access_To_Object_Definition     |
              N_Allocator                       |
              N_Allocator                       |
              N_Derived_Type_Definition         |
              N_Derived_Type_Definition         |
              N_Function_Specification          |
              N_Function_Specification          |
              N_Subtype_Declaration             =>
              N_Subtype_Declaration             =>
            return Null_Exclusion_Present (N);
            return Null_Exclusion_Present (N);
 
 
         when N_Component_Definition            |
         when N_Component_Definition            |
              N_Formal_Object_Declaration       |
              N_Formal_Object_Declaration       |
              N_Object_Renaming_Declaration     =>
              N_Object_Renaming_Declaration     =>
            if Present (Subtype_Mark (N)) then
            if Present (Subtype_Mark (N)) then
               return Null_Exclusion_Present (N);
               return Null_Exclusion_Present (N);
            else pragma Assert (Present (Access_Definition (N)));
            else pragma Assert (Present (Access_Definition (N)));
               return Null_Exclusion_Present (Access_Definition (N));
               return Null_Exclusion_Present (Access_Definition (N));
            end if;
            end if;
 
 
         when N_Discriminant_Specification =>
         when N_Discriminant_Specification =>
            if Nkind (Discriminant_Type (N)) = N_Access_Definition then
            if Nkind (Discriminant_Type (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Discriminant_Type (N));
               return Null_Exclusion_Present (Discriminant_Type (N));
            else
            else
               return Null_Exclusion_Present (N);
               return Null_Exclusion_Present (N);
            end if;
            end if;
 
 
         when N_Object_Declaration =>
         when N_Object_Declaration =>
            if Nkind (Object_Definition (N)) = N_Access_Definition then
            if Nkind (Object_Definition (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Object_Definition (N));
               return Null_Exclusion_Present (Object_Definition (N));
            else
            else
               return Null_Exclusion_Present (N);
               return Null_Exclusion_Present (N);
            end if;
            end if;
 
 
         when N_Parameter_Specification =>
         when N_Parameter_Specification =>
            if Nkind (Parameter_Type (N)) = N_Access_Definition then
            if Nkind (Parameter_Type (N)) = N_Access_Definition then
               return Null_Exclusion_Present (Parameter_Type (N));
               return Null_Exclusion_Present (Parameter_Type (N));
            else
            else
               return Null_Exclusion_Present (N);
               return Null_Exclusion_Present (N);
            end if;
            end if;
 
 
         when others =>
         when others =>
            return False;
            return False;
 
 
      end case;
      end case;
   end Has_Null_Exclusion;
   end Has_Null_Exclusion;
 
 
   ------------------------
   ------------------------
   -- Has_Null_Extension --
   -- Has_Null_Extension --
   ------------------------
   ------------------------
 
 
   function Has_Null_Extension (T : Entity_Id) return Boolean is
   function Has_Null_Extension (T : Entity_Id) return Boolean is
      B     : constant Entity_Id := Base_Type (T);
      B     : constant Entity_Id := Base_Type (T);
      Comps : Node_Id;
      Comps : Node_Id;
      Ext   : Node_Id;
      Ext   : Node_Id;
 
 
   begin
   begin
      if Nkind (Parent (B)) = N_Full_Type_Declaration
      if Nkind (Parent (B)) = N_Full_Type_Declaration
        and then Present (Record_Extension_Part (Type_Definition (Parent (B))))
        and then Present (Record_Extension_Part (Type_Definition (Parent (B))))
      then
      then
         Ext := Record_Extension_Part (Type_Definition (Parent (B)));
         Ext := Record_Extension_Part (Type_Definition (Parent (B)));
 
 
         if Present (Ext) then
         if Present (Ext) then
            if Null_Present (Ext) then
            if Null_Present (Ext) then
               return True;
               return True;
            else
            else
               Comps := Component_List (Ext);
               Comps := Component_List (Ext);
 
 
               --  The null component list is rewritten during analysis to
               --  The null component list is rewritten during analysis to
               --  include the parent component. Any other component indicates
               --  include the parent component. Any other component indicates
               --  that the extension was not originally null.
               --  that the extension was not originally null.
 
 
               return Null_Present (Comps)
               return Null_Present (Comps)
                 or else No (Next (First (Component_Items (Comps))));
                 or else No (Next (First (Component_Items (Comps))));
            end if;
            end if;
         else
         else
            return False;
            return False;
         end if;
         end if;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Has_Null_Extension;
   end Has_Null_Extension;
 
 
   -------------------------------
   -------------------------------
   -- Has_Overriding_Initialize --
   -- Has_Overriding_Initialize --
   -------------------------------
   -------------------------------
 
 
   function Has_Overriding_Initialize (T : Entity_Id) return Boolean is
   function Has_Overriding_Initialize (T : Entity_Id) return Boolean is
      BT   : constant Entity_Id := Base_Type (T);
      BT   : constant Entity_Id := Base_Type (T);
      Comp : Entity_Id;
      Comp : Entity_Id;
      P    : Elmt_Id;
      P    : Elmt_Id;
 
 
   begin
   begin
      if Is_Controlled (BT) then
      if Is_Controlled (BT) then
 
 
         --  For derived types, check immediate ancestor, excluding
         --  For derived types, check immediate ancestor, excluding
         --  Controlled itself.
         --  Controlled itself.
 
 
         if Is_Derived_Type (BT)
         if Is_Derived_Type (BT)
           and then not In_Predefined_Unit (Etype (BT))
           and then not In_Predefined_Unit (Etype (BT))
           and then Has_Overriding_Initialize (Etype (BT))
           and then Has_Overriding_Initialize (Etype (BT))
         then
         then
            return True;
            return True;
 
 
         elsif Present (Primitive_Operations (BT)) then
         elsif Present (Primitive_Operations (BT)) then
            P := First_Elmt (Primitive_Operations (BT));
            P := First_Elmt (Primitive_Operations (BT));
            while Present (P) loop
            while Present (P) loop
               if Chars (Node (P)) = Name_Initialize
               if Chars (Node (P)) = Name_Initialize
                 and then Comes_From_Source (Node (P))
                 and then Comes_From_Source (Node (P))
               then
               then
                  return True;
                  return True;
               end if;
               end if;
 
 
               Next_Elmt (P);
               Next_Elmt (P);
            end loop;
            end loop;
         end if;
         end if;
 
 
         return False;
         return False;
 
 
      elsif Has_Controlled_Component (BT) then
      elsif Has_Controlled_Component (BT) then
         Comp := First_Component (BT);
         Comp := First_Component (BT);
         while Present (Comp) loop
         while Present (Comp) loop
            if Has_Overriding_Initialize (Etype (Comp)) then
            if Has_Overriding_Initialize (Etype (Comp)) then
               return True;
               return True;
            end if;
            end if;
 
 
            Next_Component (Comp);
            Next_Component (Comp);
         end loop;
         end loop;
 
 
         return False;
         return False;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Has_Overriding_Initialize;
   end Has_Overriding_Initialize;
 
 
   --------------------------------------
   --------------------------------------
   -- Has_Preelaborable_Initialization --
   -- Has_Preelaborable_Initialization --
   --------------------------------------
   --------------------------------------
 
 
   function Has_Preelaborable_Initialization (E : Entity_Id) return Boolean is
   function Has_Preelaborable_Initialization (E : Entity_Id) return Boolean is
      Has_PE : Boolean;
      Has_PE : Boolean;
 
 
      procedure Check_Components (E : Entity_Id);
      procedure Check_Components (E : Entity_Id);
      --  Check component/discriminant chain, sets Has_PE False if a component
      --  Check component/discriminant chain, sets Has_PE False if a component
      --  or discriminant does not meet the preelaborable initialization rules.
      --  or discriminant does not meet the preelaborable initialization rules.
 
 
      ----------------------
      ----------------------
      -- Check_Components --
      -- Check_Components --
      ----------------------
      ----------------------
 
 
      procedure Check_Components (E : Entity_Id) is
      procedure Check_Components (E : Entity_Id) is
         Ent : Entity_Id;
         Ent : Entity_Id;
         Exp : Node_Id;
         Exp : Node_Id;
 
 
         function Is_Preelaborable_Expression (N : Node_Id) return Boolean;
         function Is_Preelaborable_Expression (N : Node_Id) return Boolean;
         --  Returns True if and only if the expression denoted by N does not
         --  Returns True if and only if the expression denoted by N does not
         --  violate restrictions on preelaborable constructs (RM-10.2.1(5-9)).
         --  violate restrictions on preelaborable constructs (RM-10.2.1(5-9)).
 
 
         ---------------------------------
         ---------------------------------
         -- Is_Preelaborable_Expression --
         -- Is_Preelaborable_Expression --
         ---------------------------------
         ---------------------------------
 
 
         function Is_Preelaborable_Expression (N : Node_Id) return Boolean is
         function Is_Preelaborable_Expression (N : Node_Id) return Boolean is
            Exp           : Node_Id;
            Exp           : Node_Id;
            Assn          : Node_Id;
            Assn          : Node_Id;
            Choice        : Node_Id;
            Choice        : Node_Id;
            Comp_Type     : Entity_Id;
            Comp_Type     : Entity_Id;
            Is_Array_Aggr : Boolean;
            Is_Array_Aggr : Boolean;
 
 
         begin
         begin
            if Is_Static_Expression (N) then
            if Is_Static_Expression (N) then
               return True;
               return True;
 
 
            elsif Nkind (N) = N_Null then
            elsif Nkind (N) = N_Null then
               return True;
               return True;
 
 
            --  Attributes are allowed in general, even if their prefix is a
            --  Attributes are allowed in general, even if their prefix is a
            --  formal type. (It seems that certain attributes known not to be
            --  formal type. (It seems that certain attributes known not to be
            --  static might not be allowed, but there are no rules to prevent
            --  static might not be allowed, but there are no rules to prevent
            --  them.)
            --  them.)
 
 
            elsif Nkind (N) = N_Attribute_Reference then
            elsif Nkind (N) = N_Attribute_Reference then
               return True;
               return True;
 
 
            --  The name of a discriminant evaluated within its parent type is
            --  The name of a discriminant evaluated within its parent type is
            --  defined to be preelaborable (10.2.1(8)). Note that we test for
            --  defined to be preelaborable (10.2.1(8)). Note that we test for
            --  names that denote discriminals as well as discriminants to
            --  names that denote discriminals as well as discriminants to
            --  catch references occurring within init procs.
            --  catch references occurring within init procs.
 
 
            elsif Is_Entity_Name (N)
            elsif Is_Entity_Name (N)
              and then
              and then
                (Ekind (Entity (N)) = E_Discriminant
                (Ekind (Entity (N)) = E_Discriminant
                  or else
                  or else
                    ((Ekind (Entity (N)) = E_Constant
                    ((Ekind (Entity (N)) = E_Constant
                       or else Ekind (Entity (N)) = E_In_Parameter)
                       or else Ekind (Entity (N)) = E_In_Parameter)
                     and then Present (Discriminal_Link (Entity (N)))))
                     and then Present (Discriminal_Link (Entity (N)))))
            then
            then
               return True;
               return True;
 
 
            elsif Nkind (N) = N_Qualified_Expression then
            elsif Nkind (N) = N_Qualified_Expression then
               return Is_Preelaborable_Expression (Expression (N));
               return Is_Preelaborable_Expression (Expression (N));
 
 
            --  For aggregates we have to check that each of the associations
            --  For aggregates we have to check that each of the associations
            --  is preelaborable.
            --  is preelaborable.
 
 
            elsif Nkind (N) = N_Aggregate
            elsif Nkind (N) = N_Aggregate
              or else Nkind (N) = N_Extension_Aggregate
              or else Nkind (N) = N_Extension_Aggregate
            then
            then
               Is_Array_Aggr := Is_Array_Type (Etype (N));
               Is_Array_Aggr := Is_Array_Type (Etype (N));
 
 
               if Is_Array_Aggr then
               if Is_Array_Aggr then
                  Comp_Type := Component_Type (Etype (N));
                  Comp_Type := Component_Type (Etype (N));
               end if;
               end if;
 
 
               --  Check the ancestor part of extension aggregates, which must
               --  Check the ancestor part of extension aggregates, which must
               --  be either the name of a type that has preelaborable init or
               --  be either the name of a type that has preelaborable init or
               --  an expression that is preelaborable.
               --  an expression that is preelaborable.
 
 
               if Nkind (N) = N_Extension_Aggregate then
               if Nkind (N) = N_Extension_Aggregate then
                  declare
                  declare
                     Anc_Part : constant Node_Id := Ancestor_Part (N);
                     Anc_Part : constant Node_Id := Ancestor_Part (N);
 
 
                  begin
                  begin
                     if Is_Entity_Name (Anc_Part)
                     if Is_Entity_Name (Anc_Part)
                       and then Is_Type (Entity (Anc_Part))
                       and then Is_Type (Entity (Anc_Part))
                     then
                     then
                        if not Has_Preelaborable_Initialization
                        if not Has_Preelaborable_Initialization
                                 (Entity (Anc_Part))
                                 (Entity (Anc_Part))
                        then
                        then
                           return False;
                           return False;
                        end if;
                        end if;
 
 
                     elsif not Is_Preelaborable_Expression (Anc_Part) then
                     elsif not Is_Preelaborable_Expression (Anc_Part) then
                        return False;
                        return False;
                     end if;
                     end if;
                  end;
                  end;
               end if;
               end if;
 
 
               --  Check positional associations
               --  Check positional associations
 
 
               Exp := First (Expressions (N));
               Exp := First (Expressions (N));
               while Present (Exp) loop
               while Present (Exp) loop
                  if not Is_Preelaborable_Expression (Exp) then
                  if not Is_Preelaborable_Expression (Exp) then
                     return False;
                     return False;
                  end if;
                  end if;
 
 
                  Next (Exp);
                  Next (Exp);
               end loop;
               end loop;
 
 
               --  Check named associations
               --  Check named associations
 
 
               Assn := First (Component_Associations (N));
               Assn := First (Component_Associations (N));
               while Present (Assn) loop
               while Present (Assn) loop
                  Choice := First (Choices (Assn));
                  Choice := First (Choices (Assn));
                  while Present (Choice) loop
                  while Present (Choice) loop
                     if Is_Array_Aggr then
                     if Is_Array_Aggr then
                        if Nkind (Choice) = N_Others_Choice then
                        if Nkind (Choice) = N_Others_Choice then
                           null;
                           null;
 
 
                        elsif Nkind (Choice) = N_Range then
                        elsif Nkind (Choice) = N_Range then
                           if not Is_Static_Range (Choice) then
                           if not Is_Static_Range (Choice) then
                              return False;
                              return False;
                           end if;
                           end if;
 
 
                        elsif not Is_Static_Expression (Choice) then
                        elsif not Is_Static_Expression (Choice) then
                           return False;
                           return False;
                        end if;
                        end if;
 
 
                     else
                     else
                        Comp_Type := Etype (Choice);
                        Comp_Type := Etype (Choice);
                     end if;
                     end if;
 
 
                     Next (Choice);
                     Next (Choice);
                  end loop;
                  end loop;
 
 
                  --  If the association has a <> at this point, then we have
                  --  If the association has a <> at this point, then we have
                  --  to check whether the component's type has preelaborable
                  --  to check whether the component's type has preelaborable
                  --  initialization. Note that this only occurs when the
                  --  initialization. Note that this only occurs when the
                  --  association's corresponding component does not have a
                  --  association's corresponding component does not have a
                  --  default expression, the latter case having already been
                  --  default expression, the latter case having already been
                  --  expanded as an expression for the association.
                  --  expanded as an expression for the association.
 
 
                  if Box_Present (Assn) then
                  if Box_Present (Assn) then
                     if not Has_Preelaborable_Initialization (Comp_Type) then
                     if not Has_Preelaborable_Initialization (Comp_Type) then
                        return False;
                        return False;
                     end if;
                     end if;
 
 
                  --  In the expression case we check whether the expression
                  --  In the expression case we check whether the expression
                  --  is preelaborable.
                  --  is preelaborable.
 
 
                  elsif
                  elsif
                    not Is_Preelaborable_Expression (Expression (Assn))
                    not Is_Preelaborable_Expression (Expression (Assn))
                  then
                  then
                     return False;
                     return False;
                  end if;
                  end if;
 
 
                  Next (Assn);
                  Next (Assn);
               end loop;
               end loop;
 
 
               --  If we get here then aggregate as a whole is preelaborable
               --  If we get here then aggregate as a whole is preelaborable
 
 
               return True;
               return True;
 
 
            --  All other cases are not preelaborable
            --  All other cases are not preelaborable
 
 
            else
            else
               return False;
               return False;
            end if;
            end if;
         end Is_Preelaborable_Expression;
         end Is_Preelaborable_Expression;
 
 
      --  Start of processing for Check_Components
      --  Start of processing for Check_Components
 
 
      begin
      begin
         --  Loop through entities of record or protected type
         --  Loop through entities of record or protected type
 
 
         Ent := E;
         Ent := E;
         while Present (Ent) loop
         while Present (Ent) loop
 
 
            --  We are interested only in components and discriminants
            --  We are interested only in components and discriminants
 
 
            if Ekind (Ent) = E_Component
            if Ekind (Ent) = E_Component
                or else
                or else
               Ekind (Ent) = E_Discriminant
               Ekind (Ent) = E_Discriminant
            then
            then
               --  Get default expression if any. If there is no declaration
               --  Get default expression if any. If there is no declaration
               --  node, it means we have an internal entity. The parent and
               --  node, it means we have an internal entity. The parent and
               --  tag fields are examples of such entities. For these cases,
               --  tag fields are examples of such entities. For these cases,
               --  we just test the type of the entity.
               --  we just test the type of the entity.
 
 
               if Present (Declaration_Node (Ent)) then
               if Present (Declaration_Node (Ent)) then
                  Exp := Expression (Declaration_Node (Ent));
                  Exp := Expression (Declaration_Node (Ent));
               else
               else
                  Exp := Empty;
                  Exp := Empty;
               end if;
               end if;
 
 
               --  A component has PI if it has no default expression and the
               --  A component has PI if it has no default expression and the
               --  component type has PI.
               --  component type has PI.
 
 
               if No (Exp) then
               if No (Exp) then
                  if not Has_Preelaborable_Initialization (Etype (Ent)) then
                  if not Has_Preelaborable_Initialization (Etype (Ent)) then
                     Has_PE := False;
                     Has_PE := False;
                     exit;
                     exit;
                  end if;
                  end if;
 
 
               --  Require the default expression to be preelaborable
               --  Require the default expression to be preelaborable
 
 
               elsif not Is_Preelaborable_Expression (Exp) then
               elsif not Is_Preelaborable_Expression (Exp) then
                  Has_PE := False;
                  Has_PE := False;
                  exit;
                  exit;
               end if;
               end if;
            end if;
            end if;
 
 
            Next_Entity (Ent);
            Next_Entity (Ent);
         end loop;
         end loop;
      end Check_Components;
      end Check_Components;
 
 
   --  Start of processing for Has_Preelaborable_Initialization
   --  Start of processing for Has_Preelaborable_Initialization
 
 
   begin
   begin
      --  Immediate return if already marked as known preelaborable init. This
      --  Immediate return if already marked as known preelaborable init. This
      --  covers types for which this function has already been called once
      --  covers types for which this function has already been called once
      --  and returned True (in which case the result is cached), and also
      --  and returned True (in which case the result is cached), and also
      --  types to which a pragma Preelaborable_Initialization applies.
      --  types to which a pragma Preelaborable_Initialization applies.
 
 
      if Known_To_Have_Preelab_Init (E) then
      if Known_To_Have_Preelab_Init (E) then
         return True;
         return True;
      end if;
      end if;
 
 
      --  If the type is a subtype representing a generic actual type, then
      --  If the type is a subtype representing a generic actual type, then
      --  test whether its base type has preelaborable initialization since
      --  test whether its base type has preelaborable initialization since
      --  the subtype representing the actual does not inherit this attribute
      --  the subtype representing the actual does not inherit this attribute
      --  from the actual or formal. (but maybe it should???)
      --  from the actual or formal. (but maybe it should???)
 
 
      if Is_Generic_Actual_Type (E) then
      if Is_Generic_Actual_Type (E) then
         return Has_Preelaborable_Initialization (Base_Type (E));
         return Has_Preelaborable_Initialization (Base_Type (E));
      end if;
      end if;
 
 
      --  All elementary types have preelaborable initialization
      --  All elementary types have preelaborable initialization
 
 
      if Is_Elementary_Type (E) then
      if Is_Elementary_Type (E) then
         Has_PE := True;
         Has_PE := True;
 
 
      --  Array types have PI if the component type has PI
      --  Array types have PI if the component type has PI
 
 
      elsif Is_Array_Type (E) then
      elsif Is_Array_Type (E) then
         Has_PE := Has_Preelaborable_Initialization (Component_Type (E));
         Has_PE := Has_Preelaborable_Initialization (Component_Type (E));
 
 
      --  A derived type has preelaborable initialization if its parent type
      --  A derived type has preelaborable initialization if its parent type
      --  has preelaborable initialization and (in the case of a derived record
      --  has preelaborable initialization and (in the case of a derived record
      --  extension) if the non-inherited components all have preelaborable
      --  extension) if the non-inherited components all have preelaborable
      --  initialization. However, a user-defined controlled type with an
      --  initialization. However, a user-defined controlled type with an
      --  overriding Initialize procedure does not have preelaborable
      --  overriding Initialize procedure does not have preelaborable
      --  initialization.
      --  initialization.
 
 
      elsif Is_Derived_Type (E) then
      elsif Is_Derived_Type (E) then
 
 
         --  If the derived type is a private extension then it doesn't have
         --  If the derived type is a private extension then it doesn't have
         --  preelaborable initialization.
         --  preelaborable initialization.
 
 
         if Ekind (Base_Type (E)) = E_Record_Type_With_Private then
         if Ekind (Base_Type (E)) = E_Record_Type_With_Private then
            return False;
            return False;
         end if;
         end if;
 
 
         --  First check whether ancestor type has preelaborable initialization
         --  First check whether ancestor type has preelaborable initialization
 
 
         Has_PE := Has_Preelaborable_Initialization (Etype (Base_Type (E)));
         Has_PE := Has_Preelaborable_Initialization (Etype (Base_Type (E)));
 
 
         --  If OK, check extension components (if any)
         --  If OK, check extension components (if any)
 
 
         if Has_PE and then Is_Record_Type (E) then
         if Has_PE and then Is_Record_Type (E) then
            Check_Components (First_Entity (E));
            Check_Components (First_Entity (E));
         end if;
         end if;
 
 
         --  Check specifically for 10.2.1(11.4/2) exception: a controlled type
         --  Check specifically for 10.2.1(11.4/2) exception: a controlled type
         --  with a user defined Initialize procedure does not have PI.
         --  with a user defined Initialize procedure does not have PI.
 
 
         if Has_PE
         if Has_PE
           and then Is_Controlled (E)
           and then Is_Controlled (E)
           and then Has_Overriding_Initialize (E)
           and then Has_Overriding_Initialize (E)
         then
         then
            Has_PE := False;
            Has_PE := False;
         end if;
         end if;
 
 
      --  Private types not derived from a type having preelaborable init and
      --  Private types not derived from a type having preelaborable init and
      --  that are not marked with pragma Preelaborable_Initialization do not
      --  that are not marked with pragma Preelaborable_Initialization do not
      --  have preelaborable initialization.
      --  have preelaborable initialization.
 
 
      elsif Is_Private_Type (E) then
      elsif Is_Private_Type (E) then
         return False;
         return False;
 
 
      --  Record type has PI if it is non private and all components have PI
      --  Record type has PI if it is non private and all components have PI
 
 
      elsif Is_Record_Type (E) then
      elsif Is_Record_Type (E) then
         Has_PE := True;
         Has_PE := True;
         Check_Components (First_Entity (E));
         Check_Components (First_Entity (E));
 
 
      --  Protected types must not have entries, and components must meet
      --  Protected types must not have entries, and components must meet
      --  same set of rules as for record components.
      --  same set of rules as for record components.
 
 
      elsif Is_Protected_Type (E) then
      elsif Is_Protected_Type (E) then
         if Has_Entries (E) then
         if Has_Entries (E) then
            Has_PE := False;
            Has_PE := False;
         else
         else
            Has_PE := True;
            Has_PE := True;
            Check_Components (First_Entity (E));
            Check_Components (First_Entity (E));
            Check_Components (First_Private_Entity (E));
            Check_Components (First_Private_Entity (E));
         end if;
         end if;
 
 
      --  Type System.Address always has preelaborable initialization
      --  Type System.Address always has preelaborable initialization
 
 
      elsif Is_RTE (E, RE_Address) then
      elsif Is_RTE (E, RE_Address) then
         Has_PE := True;
         Has_PE := True;
 
 
      --  In all other cases, type does not have preelaborable initialization
      --  In all other cases, type does not have preelaborable initialization
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
 
 
      --  If type has preelaborable initialization, cache result
      --  If type has preelaborable initialization, cache result
 
 
      if Has_PE then
      if Has_PE then
         Set_Known_To_Have_Preelab_Init (E);
         Set_Known_To_Have_Preelab_Init (E);
      end if;
      end if;
 
 
      return Has_PE;
      return Has_PE;
   end Has_Preelaborable_Initialization;
   end Has_Preelaborable_Initialization;
 
 
   ---------------------------
   ---------------------------
   -- Has_Private_Component --
   -- Has_Private_Component --
   ---------------------------
   ---------------------------
 
 
   function Has_Private_Component (Type_Id : Entity_Id) return Boolean is
   function Has_Private_Component (Type_Id : Entity_Id) return Boolean is
      Btype     : Entity_Id := Base_Type (Type_Id);
      Btype     : Entity_Id := Base_Type (Type_Id);
      Component : Entity_Id;
      Component : Entity_Id;
 
 
   begin
   begin
      if Error_Posted (Type_Id)
      if Error_Posted (Type_Id)
        or else Error_Posted (Btype)
        or else Error_Posted (Btype)
      then
      then
         return False;
         return False;
      end if;
      end if;
 
 
      if Is_Class_Wide_Type (Btype) then
      if Is_Class_Wide_Type (Btype) then
         Btype := Root_Type (Btype);
         Btype := Root_Type (Btype);
      end if;
      end if;
 
 
      if Is_Private_Type (Btype) then
      if Is_Private_Type (Btype) then
         declare
         declare
            UT : constant Entity_Id := Underlying_Type (Btype);
            UT : constant Entity_Id := Underlying_Type (Btype);
         begin
         begin
            if No (UT) then
            if No (UT) then
               if No (Full_View (Btype)) then
               if No (Full_View (Btype)) then
                  return not Is_Generic_Type (Btype)
                  return not Is_Generic_Type (Btype)
                    and then not Is_Generic_Type (Root_Type (Btype));
                    and then not Is_Generic_Type (Root_Type (Btype));
               else
               else
                  return not Is_Generic_Type (Root_Type (Full_View (Btype)));
                  return not Is_Generic_Type (Root_Type (Full_View (Btype)));
               end if;
               end if;
            else
            else
               return not Is_Frozen (UT) and then Has_Private_Component (UT);
               return not Is_Frozen (UT) and then Has_Private_Component (UT);
            end if;
            end if;
         end;
         end;
 
 
      elsif Is_Array_Type (Btype) then
      elsif Is_Array_Type (Btype) then
         return Has_Private_Component (Component_Type (Btype));
         return Has_Private_Component (Component_Type (Btype));
 
 
      elsif Is_Record_Type (Btype) then
      elsif Is_Record_Type (Btype) then
         Component := First_Component (Btype);
         Component := First_Component (Btype);
         while Present (Component) loop
         while Present (Component) loop
            if Has_Private_Component (Etype (Component)) then
            if Has_Private_Component (Etype (Component)) then
               return True;
               return True;
            end if;
            end if;
 
 
            Next_Component (Component);
            Next_Component (Component);
         end loop;
         end loop;
 
 
         return False;
         return False;
 
 
      elsif Is_Protected_Type (Btype)
      elsif Is_Protected_Type (Btype)
        and then Present (Corresponding_Record_Type (Btype))
        and then Present (Corresponding_Record_Type (Btype))
      then
      then
         return Has_Private_Component (Corresponding_Record_Type (Btype));
         return Has_Private_Component (Corresponding_Record_Type (Btype));
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Has_Private_Component;
   end Has_Private_Component;
 
 
   ----------------
   ----------------
   -- Has_Stream --
   -- Has_Stream --
   ----------------
   ----------------
 
 
   function Has_Stream (T : Entity_Id) return Boolean is
   function Has_Stream (T : Entity_Id) return Boolean is
      E : Entity_Id;
      E : Entity_Id;
 
 
   begin
   begin
      if No (T) then
      if No (T) then
         return False;
         return False;
 
 
      elsif Is_RTE (Root_Type (T), RE_Root_Stream_Type) then
      elsif Is_RTE (Root_Type (T), RE_Root_Stream_Type) then
         return True;
         return True;
 
 
      elsif Is_Array_Type (T) then
      elsif Is_Array_Type (T) then
         return Has_Stream (Component_Type (T));
         return Has_Stream (Component_Type (T));
 
 
      elsif Is_Record_Type (T) then
      elsif Is_Record_Type (T) then
         E := First_Component (T);
         E := First_Component (T);
         while Present (E) loop
         while Present (E) loop
            if Has_Stream (Etype (E)) then
            if Has_Stream (Etype (E)) then
               return True;
               return True;
            else
            else
               Next_Component (E);
               Next_Component (E);
            end if;
            end if;
         end loop;
         end loop;
 
 
         return False;
         return False;
 
 
      elsif Is_Private_Type (T) then
      elsif Is_Private_Type (T) then
         return Has_Stream (Underlying_Type (T));
         return Has_Stream (Underlying_Type (T));
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Has_Stream;
   end Has_Stream;
 
 
   --------------------------
   --------------------------
   -- Has_Tagged_Component --
   -- Has_Tagged_Component --
   --------------------------
   --------------------------
 
 
   function Has_Tagged_Component (Typ : Entity_Id) return Boolean is
   function Has_Tagged_Component (Typ : Entity_Id) return Boolean is
      Comp : Entity_Id;
      Comp : Entity_Id;
 
 
   begin
   begin
      if Is_Private_Type (Typ)
      if Is_Private_Type (Typ)
        and then Present (Underlying_Type (Typ))
        and then Present (Underlying_Type (Typ))
      then
      then
         return Has_Tagged_Component (Underlying_Type (Typ));
         return Has_Tagged_Component (Underlying_Type (Typ));
 
 
      elsif Is_Array_Type (Typ) then
      elsif Is_Array_Type (Typ) then
         return Has_Tagged_Component (Component_Type (Typ));
         return Has_Tagged_Component (Component_Type (Typ));
 
 
      elsif Is_Tagged_Type (Typ) then
      elsif Is_Tagged_Type (Typ) then
         return True;
         return True;
 
 
      elsif Is_Record_Type (Typ) then
      elsif Is_Record_Type (Typ) then
         Comp := First_Component (Typ);
         Comp := First_Component (Typ);
         while Present (Comp) loop
         while Present (Comp) loop
            if Has_Tagged_Component (Etype (Comp)) then
            if Has_Tagged_Component (Etype (Comp)) then
               return True;
               return True;
            end if;
            end if;
 
 
            Next_Component (Comp);
            Next_Component (Comp);
         end loop;
         end loop;
 
 
         return False;
         return False;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Has_Tagged_Component;
   end Has_Tagged_Component;
 
 
   --------------------------
   --------------------------
   -- Implements_Interface --
   -- Implements_Interface --
   --------------------------
   --------------------------
 
 
   function Implements_Interface
   function Implements_Interface
     (Typ_Ent         : Entity_Id;
     (Typ_Ent         : Entity_Id;
      Iface_Ent       : Entity_Id;
      Iface_Ent       : Entity_Id;
      Exclude_Parents : Boolean := False) return Boolean
      Exclude_Parents : Boolean := False) return Boolean
   is
   is
      Ifaces_List : Elist_Id;
      Ifaces_List : Elist_Id;
      Elmt        : Elmt_Id;
      Elmt        : Elmt_Id;
      Iface       : Entity_Id := Base_Type (Iface_Ent);
      Iface       : Entity_Id := Base_Type (Iface_Ent);
      Typ         : Entity_Id := Base_Type (Typ_Ent);
      Typ         : Entity_Id := Base_Type (Typ_Ent);
 
 
   begin
   begin
      if Is_Class_Wide_Type (Typ) then
      if Is_Class_Wide_Type (Typ) then
         Typ := Root_Type (Typ);
         Typ := Root_Type (Typ);
      end if;
      end if;
 
 
      if not Has_Interfaces (Typ) then
      if not Has_Interfaces (Typ) then
         return False;
         return False;
      end if;
      end if;
 
 
      if Is_Class_Wide_Type (Iface) then
      if Is_Class_Wide_Type (Iface) then
         Iface := Root_Type (Iface);
         Iface := Root_Type (Iface);
      end if;
      end if;
 
 
      Collect_Interfaces (Typ, Ifaces_List);
      Collect_Interfaces (Typ, Ifaces_List);
 
 
      Elmt := First_Elmt (Ifaces_List);
      Elmt := First_Elmt (Ifaces_List);
      while Present (Elmt) loop
      while Present (Elmt) loop
         if Is_Ancestor (Node (Elmt), Typ)
         if Is_Ancestor (Node (Elmt), Typ)
           and then Exclude_Parents
           and then Exclude_Parents
         then
         then
            null;
            null;
 
 
         elsif Node (Elmt) = Iface then
         elsif Node (Elmt) = Iface then
            return True;
            return True;
         end if;
         end if;
 
 
         Next_Elmt (Elmt);
         Next_Elmt (Elmt);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end Implements_Interface;
   end Implements_Interface;
 
 
   -----------------
   -----------------
   -- In_Instance --
   -- In_Instance --
   -----------------
   -----------------
 
 
   function In_Instance return Boolean is
   function In_Instance return Boolean is
      Curr_Unit : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
      Curr_Unit : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
      S         : Entity_Id;
      S         : Entity_Id;
 
 
   begin
   begin
      S := Current_Scope;
      S := Current_Scope;
      while Present (S)
      while Present (S)
        and then S /= Standard_Standard
        and then S /= Standard_Standard
      loop
      loop
         if (Ekind (S) = E_Function
         if (Ekind (S) = E_Function
              or else Ekind (S) = E_Package
              or else Ekind (S) = E_Package
              or else Ekind (S) = E_Procedure)
              or else Ekind (S) = E_Procedure)
           and then Is_Generic_Instance (S)
           and then Is_Generic_Instance (S)
         then
         then
            --  A child instance is always compiled in the context of a parent
            --  A child instance is always compiled in the context of a parent
            --  instance. Nevertheless, the actuals are not analyzed in an
            --  instance. Nevertheless, the actuals are not analyzed in an
            --  instance context. We detect this case by examining the current
            --  instance context. We detect this case by examining the current
            --  compilation unit, which must be a child instance, and checking
            --  compilation unit, which must be a child instance, and checking
            --  that it is not currently on the scope stack.
            --  that it is not currently on the scope stack.
 
 
            if Is_Child_Unit (Curr_Unit)
            if Is_Child_Unit (Curr_Unit)
              and then
              and then
                Nkind (Unit (Cunit (Current_Sem_Unit)))
                Nkind (Unit (Cunit (Current_Sem_Unit)))
                  = N_Package_Instantiation
                  = N_Package_Instantiation
              and then not In_Open_Scopes (Curr_Unit)
              and then not In_Open_Scopes (Curr_Unit)
            then
            then
               return False;
               return False;
            else
            else
               return True;
               return True;
            end if;
            end if;
         end if;
         end if;
 
 
         S := Scope (S);
         S := Scope (S);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end In_Instance;
   end In_Instance;
 
 
   ----------------------
   ----------------------
   -- In_Instance_Body --
   -- In_Instance_Body --
   ----------------------
   ----------------------
 
 
   function In_Instance_Body return Boolean is
   function In_Instance_Body return Boolean is
      S : Entity_Id;
      S : Entity_Id;
 
 
   begin
   begin
      S := Current_Scope;
      S := Current_Scope;
      while Present (S)
      while Present (S)
        and then S /= Standard_Standard
        and then S /= Standard_Standard
      loop
      loop
         if (Ekind (S) = E_Function
         if (Ekind (S) = E_Function
              or else Ekind (S) = E_Procedure)
              or else Ekind (S) = E_Procedure)
           and then Is_Generic_Instance (S)
           and then Is_Generic_Instance (S)
         then
         then
            return True;
            return True;
 
 
         elsif Ekind (S) = E_Package
         elsif Ekind (S) = E_Package
           and then In_Package_Body (S)
           and then In_Package_Body (S)
           and then Is_Generic_Instance (S)
           and then Is_Generic_Instance (S)
         then
         then
            return True;
            return True;
         end if;
         end if;
 
 
         S := Scope (S);
         S := Scope (S);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end In_Instance_Body;
   end In_Instance_Body;
 
 
   -----------------------------
   -----------------------------
   -- In_Instance_Not_Visible --
   -- In_Instance_Not_Visible --
   -----------------------------
   -----------------------------
 
 
   function In_Instance_Not_Visible return Boolean is
   function In_Instance_Not_Visible return Boolean is
      S : Entity_Id;
      S : Entity_Id;
 
 
   begin
   begin
      S := Current_Scope;
      S := Current_Scope;
      while Present (S)
      while Present (S)
        and then S /= Standard_Standard
        and then S /= Standard_Standard
      loop
      loop
         if (Ekind (S) = E_Function
         if (Ekind (S) = E_Function
              or else Ekind (S) = E_Procedure)
              or else Ekind (S) = E_Procedure)
           and then Is_Generic_Instance (S)
           and then Is_Generic_Instance (S)
         then
         then
            return True;
            return True;
 
 
         elsif Ekind (S) = E_Package
         elsif Ekind (S) = E_Package
           and then (In_Package_Body (S) or else In_Private_Part (S))
           and then (In_Package_Body (S) or else In_Private_Part (S))
           and then Is_Generic_Instance (S)
           and then Is_Generic_Instance (S)
         then
         then
            return True;
            return True;
         end if;
         end if;
 
 
         S := Scope (S);
         S := Scope (S);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end In_Instance_Not_Visible;
   end In_Instance_Not_Visible;
 
 
   ------------------------------
   ------------------------------
   -- In_Instance_Visible_Part --
   -- In_Instance_Visible_Part --
   ------------------------------
   ------------------------------
 
 
   function In_Instance_Visible_Part return Boolean is
   function In_Instance_Visible_Part return Boolean is
      S : Entity_Id;
      S : Entity_Id;
 
 
   begin
   begin
      S := Current_Scope;
      S := Current_Scope;
      while Present (S)
      while Present (S)
        and then S /= Standard_Standard
        and then S /= Standard_Standard
      loop
      loop
         if Ekind (S) = E_Package
         if Ekind (S) = E_Package
           and then Is_Generic_Instance (S)
           and then Is_Generic_Instance (S)
           and then not In_Package_Body (S)
           and then not In_Package_Body (S)
           and then not In_Private_Part (S)
           and then not In_Private_Part (S)
         then
         then
            return True;
            return True;
         end if;
         end if;
 
 
         S := Scope (S);
         S := Scope (S);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end In_Instance_Visible_Part;
   end In_Instance_Visible_Part;
 
 
   ---------------------
   ---------------------
   -- In_Package_Body --
   -- In_Package_Body --
   ---------------------
   ---------------------
 
 
   function In_Package_Body return Boolean is
   function In_Package_Body return Boolean is
      S : Entity_Id;
      S : Entity_Id;
 
 
   begin
   begin
      S := Current_Scope;
      S := Current_Scope;
      while Present (S)
      while Present (S)
        and then S /= Standard_Standard
        and then S /= Standard_Standard
      loop
      loop
         if Ekind (S) = E_Package
         if Ekind (S) = E_Package
           and then In_Package_Body (S)
           and then In_Package_Body (S)
         then
         then
            return True;
            return True;
         else
         else
            S := Scope (S);
            S := Scope (S);
         end if;
         end if;
      end loop;
      end loop;
 
 
      return False;
      return False;
   end In_Package_Body;
   end In_Package_Body;
 
 
   --------------------------------
   --------------------------------
   -- In_Parameter_Specification --
   -- In_Parameter_Specification --
   --------------------------------
   --------------------------------
 
 
   function In_Parameter_Specification (N : Node_Id) return Boolean is
   function In_Parameter_Specification (N : Node_Id) return Boolean is
      PN : Node_Id;
      PN : Node_Id;
 
 
   begin
   begin
      PN := Parent (N);
      PN := Parent (N);
      while Present (PN) loop
      while Present (PN) loop
         if Nkind (PN) = N_Parameter_Specification then
         if Nkind (PN) = N_Parameter_Specification then
            return True;
            return True;
         end if;
         end if;
 
 
         PN := Parent (PN);
         PN := Parent (PN);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end In_Parameter_Specification;
   end In_Parameter_Specification;
 
 
   --------------------------------------
   --------------------------------------
   -- In_Subprogram_Or_Concurrent_Unit --
   -- In_Subprogram_Or_Concurrent_Unit --
   --------------------------------------
   --------------------------------------
 
 
   function In_Subprogram_Or_Concurrent_Unit return Boolean is
   function In_Subprogram_Or_Concurrent_Unit return Boolean is
      E : Entity_Id;
      E : Entity_Id;
      K : Entity_Kind;
      K : Entity_Kind;
 
 
   begin
   begin
      --  Use scope chain to check successively outer scopes
      --  Use scope chain to check successively outer scopes
 
 
      E := Current_Scope;
      E := Current_Scope;
      loop
      loop
         K := Ekind (E);
         K := Ekind (E);
 
 
         if K in Subprogram_Kind
         if K in Subprogram_Kind
           or else K in Concurrent_Kind
           or else K in Concurrent_Kind
           or else K in Generic_Subprogram_Kind
           or else K in Generic_Subprogram_Kind
         then
         then
            return True;
            return True;
 
 
         elsif E = Standard_Standard then
         elsif E = Standard_Standard then
            return False;
            return False;
         end if;
         end if;
 
 
         E := Scope (E);
         E := Scope (E);
      end loop;
      end loop;
   end In_Subprogram_Or_Concurrent_Unit;
   end In_Subprogram_Or_Concurrent_Unit;
 
 
   ---------------------
   ---------------------
   -- In_Visible_Part --
   -- In_Visible_Part --
   ---------------------
   ---------------------
 
 
   function In_Visible_Part (Scope_Id : Entity_Id) return Boolean is
   function In_Visible_Part (Scope_Id : Entity_Id) return Boolean is
   begin
   begin
      return
      return
        Is_Package_Or_Generic_Package (Scope_Id)
        Is_Package_Or_Generic_Package (Scope_Id)
          and then In_Open_Scopes (Scope_Id)
          and then In_Open_Scopes (Scope_Id)
          and then not In_Package_Body (Scope_Id)
          and then not In_Package_Body (Scope_Id)
          and then not In_Private_Part (Scope_Id);
          and then not In_Private_Part (Scope_Id);
   end In_Visible_Part;
   end In_Visible_Part;
 
 
   ---------------------------------
   ---------------------------------
   -- Insert_Explicit_Dereference --
   -- Insert_Explicit_Dereference --
   ---------------------------------
   ---------------------------------
 
 
   procedure Insert_Explicit_Dereference (N : Node_Id) is
   procedure Insert_Explicit_Dereference (N : Node_Id) is
      New_Prefix : constant Node_Id := Relocate_Node (N);
      New_Prefix : constant Node_Id := Relocate_Node (N);
      Ent        : Entity_Id := Empty;
      Ent        : Entity_Id := Empty;
      Pref       : Node_Id;
      Pref       : Node_Id;
      I          : Interp_Index;
      I          : Interp_Index;
      It         : Interp;
      It         : Interp;
      T          : Entity_Id;
      T          : Entity_Id;
 
 
   begin
   begin
      Save_Interps (N, New_Prefix);
      Save_Interps (N, New_Prefix);
 
 
      --  Check if the node relocation requires readjustment of some SCIL
      --  Check if the node relocation requires readjustment of some SCIL
      --  dispatching node.
      --  dispatching node.
 
 
      if Generate_SCIL
      if Generate_SCIL
        and then Nkind (N) = N_Function_Call
        and then Nkind (N) = N_Function_Call
      then
      then
         Adjust_SCIL_Node (N, New_Prefix);
         Adjust_SCIL_Node (N, New_Prefix);
      end if;
      end if;
 
 
      Rewrite (N, Make_Explicit_Dereference (Sloc (N), Prefix => New_Prefix));
      Rewrite (N, Make_Explicit_Dereference (Sloc (N), Prefix => New_Prefix));
 
 
      Set_Etype (N, Designated_Type (Etype (New_Prefix)));
      Set_Etype (N, Designated_Type (Etype (New_Prefix)));
 
 
      if Is_Overloaded (New_Prefix) then
      if Is_Overloaded (New_Prefix) then
 
 
         --  The dereference is also overloaded, and its interpretations are
         --  The dereference is also overloaded, and its interpretations are
         --  the designated types of the interpretations of the original node.
         --  the designated types of the interpretations of the original node.
 
 
         Set_Etype (N, Any_Type);
         Set_Etype (N, Any_Type);
 
 
         Get_First_Interp (New_Prefix, I, It);
         Get_First_Interp (New_Prefix, I, It);
         while Present (It.Nam) loop
         while Present (It.Nam) loop
            T := It.Typ;
            T := It.Typ;
 
 
            if Is_Access_Type (T) then
            if Is_Access_Type (T) then
               Add_One_Interp (N, Designated_Type (T), Designated_Type (T));
               Add_One_Interp (N, Designated_Type (T), Designated_Type (T));
            end if;
            end if;
 
 
            Get_Next_Interp (I, It);
            Get_Next_Interp (I, It);
         end loop;
         end loop;
 
 
         End_Interp_List;
         End_Interp_List;
 
 
      else
      else
         --  Prefix is unambiguous: mark the original prefix (which might
         --  Prefix is unambiguous: mark the original prefix (which might
         --  Come_From_Source) as a reference, since the new (relocated) one
         --  Come_From_Source) as a reference, since the new (relocated) one
         --  won't be taken into account.
         --  won't be taken into account.
 
 
         if Is_Entity_Name (New_Prefix) then
         if Is_Entity_Name (New_Prefix) then
            Ent := Entity (New_Prefix);
            Ent := Entity (New_Prefix);
 
 
         --  For a retrieval of a subcomponent of some composite object,
         --  For a retrieval of a subcomponent of some composite object,
         --  retrieve the ultimate entity if there is one.
         --  retrieve the ultimate entity if there is one.
 
 
         elsif Nkind (New_Prefix) = N_Selected_Component
         elsif Nkind (New_Prefix) = N_Selected_Component
           or else Nkind (New_Prefix) = N_Indexed_Component
           or else Nkind (New_Prefix) = N_Indexed_Component
         then
         then
            Pref := Prefix (New_Prefix);
            Pref := Prefix (New_Prefix);
            while Present (Pref)
            while Present (Pref)
              and then
              and then
                (Nkind (Pref) = N_Selected_Component
                (Nkind (Pref) = N_Selected_Component
                  or else Nkind (Pref) = N_Indexed_Component)
                  or else Nkind (Pref) = N_Indexed_Component)
            loop
            loop
               Pref := Prefix (Pref);
               Pref := Prefix (Pref);
            end loop;
            end loop;
 
 
            if Present (Pref) and then Is_Entity_Name (Pref) then
            if Present (Pref) and then Is_Entity_Name (Pref) then
               Ent := Entity (Pref);
               Ent := Entity (Pref);
            end if;
            end if;
         end if;
         end if;
 
 
         if Present (Ent) then
         if Present (Ent) then
            Generate_Reference (Ent, New_Prefix);
            Generate_Reference (Ent, New_Prefix);
         end if;
         end if;
      end if;
      end if;
   end Insert_Explicit_Dereference;
   end Insert_Explicit_Dereference;
 
 
   ------------------------------------------
   ------------------------------------------
   -- Inspect_Deferred_Constant_Completion --
   -- Inspect_Deferred_Constant_Completion --
   ------------------------------------------
   ------------------------------------------
 
 
   procedure Inspect_Deferred_Constant_Completion (Decls : List_Id) is
   procedure Inspect_Deferred_Constant_Completion (Decls : List_Id) is
      Decl   : Node_Id;
      Decl   : Node_Id;
 
 
   begin
   begin
      Decl := First (Decls);
      Decl := First (Decls);
      while Present (Decl) loop
      while Present (Decl) loop
 
 
         --  Deferred constant signature
         --  Deferred constant signature
 
 
         if Nkind (Decl) = N_Object_Declaration
         if Nkind (Decl) = N_Object_Declaration
           and then Constant_Present (Decl)
           and then Constant_Present (Decl)
           and then No (Expression (Decl))
           and then No (Expression (Decl))
 
 
            --  No need to check internally generated constants
            --  No need to check internally generated constants
 
 
           and then Comes_From_Source (Decl)
           and then Comes_From_Source (Decl)
 
 
            --  The constant is not completed. A full object declaration
            --  The constant is not completed. A full object declaration
            --  or a pragma Import complete a deferred constant.
            --  or a pragma Import complete a deferred constant.
 
 
           and then not Has_Completion (Defining_Identifier (Decl))
           and then not Has_Completion (Defining_Identifier (Decl))
         then
         then
            Error_Msg_N
            Error_Msg_N
              ("constant declaration requires initialization expression",
              ("constant declaration requires initialization expression",
              Defining_Identifier (Decl));
              Defining_Identifier (Decl));
         end if;
         end if;
 
 
         Decl := Next (Decl);
         Decl := Next (Decl);
      end loop;
      end loop;
   end Inspect_Deferred_Constant_Completion;
   end Inspect_Deferred_Constant_Completion;
 
 
   -------------------
   -------------------
   -- Is_AAMP_Float --
   -- Is_AAMP_Float --
   -------------------
   -------------------
 
 
   function Is_AAMP_Float (E : Entity_Id) return Boolean is
   function Is_AAMP_Float (E : Entity_Id) return Boolean is
      pragma Assert (Is_Type (E));
      pragma Assert (Is_Type (E));
   begin
   begin
      return AAMP_On_Target
      return AAMP_On_Target
         and then Is_Floating_Point_Type (E)
         and then Is_Floating_Point_Type (E)
         and then E = Base_Type (E);
         and then E = Base_Type (E);
   end Is_AAMP_Float;
   end Is_AAMP_Float;
 
 
   -----------------------------
   -----------------------------
   -- Is_Actual_Out_Parameter --
   -- Is_Actual_Out_Parameter --
   -----------------------------
   -----------------------------
 
 
   function Is_Actual_Out_Parameter (N : Node_Id) return Boolean is
   function Is_Actual_Out_Parameter (N : Node_Id) return Boolean is
      Formal : Entity_Id;
      Formal : Entity_Id;
      Call   : Node_Id;
      Call   : Node_Id;
   begin
   begin
      Find_Actual (N, Formal, Call);
      Find_Actual (N, Formal, Call);
      return Present (Formal)
      return Present (Formal)
        and then Ekind (Formal) = E_Out_Parameter;
        and then Ekind (Formal) = E_Out_Parameter;
   end Is_Actual_Out_Parameter;
   end Is_Actual_Out_Parameter;
 
 
   -------------------------
   -------------------------
   -- Is_Actual_Parameter --
   -- Is_Actual_Parameter --
   -------------------------
   -------------------------
 
 
   function Is_Actual_Parameter (N : Node_Id) return Boolean is
   function Is_Actual_Parameter (N : Node_Id) return Boolean is
      PK : constant Node_Kind := Nkind (Parent (N));
      PK : constant Node_Kind := Nkind (Parent (N));
 
 
   begin
   begin
      case PK is
      case PK is
         when N_Parameter_Association =>
         when N_Parameter_Association =>
            return N = Explicit_Actual_Parameter (Parent (N));
            return N = Explicit_Actual_Parameter (Parent (N));
 
 
         when N_Function_Call | N_Procedure_Call_Statement =>
         when N_Function_Call | N_Procedure_Call_Statement =>
            return Is_List_Member (N)
            return Is_List_Member (N)
              and then
              and then
                List_Containing (N) = Parameter_Associations (Parent (N));
                List_Containing (N) = Parameter_Associations (Parent (N));
 
 
         when others =>
         when others =>
            return False;
            return False;
      end case;
      end case;
   end Is_Actual_Parameter;
   end Is_Actual_Parameter;
 
 
   ---------------------
   ---------------------
   -- Is_Aliased_View --
   -- Is_Aliased_View --
   ---------------------
   ---------------------
 
 
   function Is_Aliased_View (Obj : Node_Id) return Boolean is
   function Is_Aliased_View (Obj : Node_Id) return Boolean is
      E : Entity_Id;
      E : Entity_Id;
 
 
   begin
   begin
      if Is_Entity_Name (Obj) then
      if Is_Entity_Name (Obj) then
 
 
         E := Entity (Obj);
         E := Entity (Obj);
 
 
         return
         return
           (Is_Object (E)
           (Is_Object (E)
             and then
             and then
               (Is_Aliased (E)
               (Is_Aliased (E)
                  or else (Present (Renamed_Object (E))
                  or else (Present (Renamed_Object (E))
                             and then Is_Aliased_View (Renamed_Object (E)))))
                             and then Is_Aliased_View (Renamed_Object (E)))))
 
 
           or else ((Is_Formal (E)
           or else ((Is_Formal (E)
                      or else Ekind (E) = E_Generic_In_Out_Parameter
                      or else Ekind (E) = E_Generic_In_Out_Parameter
                      or else Ekind (E) = E_Generic_In_Parameter)
                      or else Ekind (E) = E_Generic_In_Parameter)
                    and then Is_Tagged_Type (Etype (E)))
                    and then Is_Tagged_Type (Etype (E)))
 
 
           or else (Is_Concurrent_Type (E)
           or else (Is_Concurrent_Type (E)
                     and then In_Open_Scopes (E))
                     and then In_Open_Scopes (E))
 
 
            --  Current instance of type, either directly or as rewritten
            --  Current instance of type, either directly or as rewritten
            --  reference to the current object.
            --  reference to the current object.
 
 
           or else (Is_Entity_Name (Original_Node (Obj))
           or else (Is_Entity_Name (Original_Node (Obj))
                     and then Present (Entity (Original_Node (Obj)))
                     and then Present (Entity (Original_Node (Obj)))
                     and then Is_Type (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_Type (E) and then E = Current_Scope)
 
 
           or else (Is_Incomplete_Or_Private_Type (E)
           or else (Is_Incomplete_Or_Private_Type (E)
                     and then Full_View (E) = Current_Scope);
                     and then Full_View (E) = Current_Scope);
 
 
      elsif Nkind (Obj) = N_Selected_Component then
      elsif Nkind (Obj) = N_Selected_Component then
         return Is_Aliased (Entity (Selector_Name (Obj)));
         return Is_Aliased (Entity (Selector_Name (Obj)));
 
 
      elsif Nkind (Obj) = N_Indexed_Component then
      elsif Nkind (Obj) = N_Indexed_Component then
         return Has_Aliased_Components (Etype (Prefix (Obj)))
         return Has_Aliased_Components (Etype (Prefix (Obj)))
           or else
           or else
             (Is_Access_Type (Etype (Prefix (Obj)))
             (Is_Access_Type (Etype (Prefix (Obj)))
               and then
               and then
              Has_Aliased_Components
              Has_Aliased_Components
                (Designated_Type (Etype (Prefix (Obj)))));
                (Designated_Type (Etype (Prefix (Obj)))));
 
 
      elsif Nkind (Obj) = N_Unchecked_Type_Conversion
      elsif Nkind (Obj) = N_Unchecked_Type_Conversion
        or else Nkind (Obj) = N_Type_Conversion
        or else Nkind (Obj) = N_Type_Conversion
      then
      then
         return Is_Tagged_Type (Etype (Obj))
         return Is_Tagged_Type (Etype (Obj))
           and then Is_Aliased_View (Expression (Obj));
           and then Is_Aliased_View (Expression (Obj));
 
 
      elsif Nkind (Obj) = N_Explicit_Dereference then
      elsif Nkind (Obj) = N_Explicit_Dereference then
         return Nkind (Original_Node (Obj)) /= N_Function_Call;
         return Nkind (Original_Node (Obj)) /= N_Function_Call;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Aliased_View;
   end Is_Aliased_View;
 
 
   -------------------------
   -------------------------
   -- Is_Ancestor_Package --
   -- Is_Ancestor_Package --
   -------------------------
   -------------------------
 
 
   function Is_Ancestor_Package
   function Is_Ancestor_Package
     (E1 : Entity_Id;
     (E1 : Entity_Id;
      E2 : Entity_Id) return Boolean
      E2 : Entity_Id) return Boolean
   is
   is
      Par : Entity_Id;
      Par : Entity_Id;
 
 
   begin
   begin
      Par := E2;
      Par := E2;
      while Present (Par)
      while Present (Par)
        and then Par /= Standard_Standard
        and then Par /= Standard_Standard
      loop
      loop
         if Par = E1 then
         if Par = E1 then
            return True;
            return True;
         end if;
         end if;
 
 
         Par := Scope (Par);
         Par := Scope (Par);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end Is_Ancestor_Package;
   end Is_Ancestor_Package;
 
 
   ----------------------
   ----------------------
   -- Is_Atomic_Object --
   -- Is_Atomic_Object --
   ----------------------
   ----------------------
 
 
   function Is_Atomic_Object (N : Node_Id) return Boolean is
   function Is_Atomic_Object (N : Node_Id) return Boolean is
 
 
      function Object_Has_Atomic_Components (N : Node_Id) return Boolean;
      function Object_Has_Atomic_Components (N : Node_Id) return Boolean;
      --  Determines if given object has atomic components
      --  Determines if given object has atomic components
 
 
      function Is_Atomic_Prefix (N : Node_Id) return Boolean;
      function Is_Atomic_Prefix (N : Node_Id) return Boolean;
      --  If prefix is an implicit dereference, examine designated type
      --  If prefix is an implicit dereference, examine designated type
 
 
      ----------------------
      ----------------------
      -- Is_Atomic_Prefix --
      -- Is_Atomic_Prefix --
      ----------------------
      ----------------------
 
 
      function Is_Atomic_Prefix (N : Node_Id) return Boolean is
      function Is_Atomic_Prefix (N : Node_Id) return Boolean is
      begin
      begin
         if Is_Access_Type (Etype (N)) then
         if Is_Access_Type (Etype (N)) then
            return
            return
              Has_Atomic_Components (Designated_Type (Etype (N)));
              Has_Atomic_Components (Designated_Type (Etype (N)));
         else
         else
            return Object_Has_Atomic_Components (N);
            return Object_Has_Atomic_Components (N);
         end if;
         end if;
      end Is_Atomic_Prefix;
      end Is_Atomic_Prefix;
 
 
      ----------------------------------
      ----------------------------------
      -- Object_Has_Atomic_Components --
      -- Object_Has_Atomic_Components --
      ----------------------------------
      ----------------------------------
 
 
      function Object_Has_Atomic_Components (N : Node_Id) return Boolean is
      function Object_Has_Atomic_Components (N : Node_Id) return Boolean is
      begin
      begin
         if Has_Atomic_Components (Etype (N))
         if Has_Atomic_Components (Etype (N))
           or else Is_Atomic (Etype (N))
           or else Is_Atomic (Etype (N))
         then
         then
            return True;
            return True;
 
 
         elsif Is_Entity_Name (N)
         elsif Is_Entity_Name (N)
           and then (Has_Atomic_Components (Entity (N))
           and then (Has_Atomic_Components (Entity (N))
                      or else Is_Atomic (Entity (N)))
                      or else Is_Atomic (Entity (N)))
         then
         then
            return True;
            return True;
 
 
         elsif Nkind (N) = N_Indexed_Component
         elsif Nkind (N) = N_Indexed_Component
           or else Nkind (N) = N_Selected_Component
           or else Nkind (N) = N_Selected_Component
         then
         then
            return Is_Atomic_Prefix (Prefix (N));
            return Is_Atomic_Prefix (Prefix (N));
 
 
         else
         else
            return False;
            return False;
         end if;
         end if;
      end Object_Has_Atomic_Components;
      end Object_Has_Atomic_Components;
 
 
   --  Start of processing for Is_Atomic_Object
   --  Start of processing for Is_Atomic_Object
 
 
   begin
   begin
      if Is_Atomic (Etype (N))
      if Is_Atomic (Etype (N))
        or else (Is_Entity_Name (N) and then Is_Atomic (Entity (N)))
        or else (Is_Entity_Name (N) and then Is_Atomic (Entity (N)))
      then
      then
         return True;
         return True;
 
 
      elsif Nkind (N) = N_Indexed_Component
      elsif Nkind (N) = N_Indexed_Component
        or else Nkind (N) = N_Selected_Component
        or else Nkind (N) = N_Selected_Component
      then
      then
         return Is_Atomic_Prefix (Prefix (N));
         return Is_Atomic_Prefix (Prefix (N));
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Atomic_Object;
   end Is_Atomic_Object;
 
 
   -------------------------
   -------------------------
   -- Is_Coextension_Root --
   -- Is_Coextension_Root --
   -------------------------
   -------------------------
 
 
   function Is_Coextension_Root (N : Node_Id) return Boolean is
   function Is_Coextension_Root (N : Node_Id) return Boolean is
   begin
   begin
      return
      return
        Nkind (N) = N_Allocator
        Nkind (N) = N_Allocator
          and then Present (Coextensions (N))
          and then Present (Coextensions (N))
 
 
         --  Anonymous access discriminants carry a list of all nested
         --  Anonymous access discriminants carry a list of all nested
         --  controlled coextensions.
         --  controlled coextensions.
 
 
          and then not Is_Dynamic_Coextension (N)
          and then not Is_Dynamic_Coextension (N)
          and then not Is_Static_Coextension (N);
          and then not Is_Static_Coextension (N);
   end Is_Coextension_Root;
   end Is_Coextension_Root;
 
 
   -----------------------------
   -----------------------------
   -- Is_Concurrent_Interface --
   -- Is_Concurrent_Interface --
   -----------------------------
   -----------------------------
 
 
   function Is_Concurrent_Interface (T : Entity_Id) return Boolean is
   function Is_Concurrent_Interface (T : Entity_Id) return Boolean is
   begin
   begin
      return
      return
        Is_Interface (T)
        Is_Interface (T)
          and then
          and then
            (Is_Protected_Interface (T)
            (Is_Protected_Interface (T)
               or else Is_Synchronized_Interface (T)
               or else Is_Synchronized_Interface (T)
               or else Is_Task_Interface (T));
               or else Is_Task_Interface (T));
   end Is_Concurrent_Interface;
   end Is_Concurrent_Interface;
 
 
   --------------------------------------
   --------------------------------------
   -- Is_Controlling_Limited_Procedure --
   -- Is_Controlling_Limited_Procedure --
   --------------------------------------
   --------------------------------------
 
 
   function Is_Controlling_Limited_Procedure
   function Is_Controlling_Limited_Procedure
     (Proc_Nam : Entity_Id) return Boolean
     (Proc_Nam : Entity_Id) return Boolean
   is
   is
      Param_Typ : Entity_Id := Empty;
      Param_Typ : Entity_Id := Empty;
 
 
   begin
   begin
      if Ekind (Proc_Nam) = E_Procedure
      if Ekind (Proc_Nam) = E_Procedure
        and then Present (Parameter_Specifications (Parent (Proc_Nam)))
        and then Present (Parameter_Specifications (Parent (Proc_Nam)))
      then
      then
         Param_Typ := Etype (Parameter_Type (First (
         Param_Typ := Etype (Parameter_Type (First (
                        Parameter_Specifications (Parent (Proc_Nam)))));
                        Parameter_Specifications (Parent (Proc_Nam)))));
 
 
      --  In this case where an Itype was created, the procedure call has been
      --  In this case where an Itype was created, the procedure call has been
      --  rewritten.
      --  rewritten.
 
 
      elsif Present (Associated_Node_For_Itype (Proc_Nam))
      elsif Present (Associated_Node_For_Itype (Proc_Nam))
        and then Present (Original_Node (Associated_Node_For_Itype (Proc_Nam)))
        and then Present (Original_Node (Associated_Node_For_Itype (Proc_Nam)))
        and then
        and then
          Present (Parameter_Associations
          Present (Parameter_Associations
                     (Associated_Node_For_Itype (Proc_Nam)))
                     (Associated_Node_For_Itype (Proc_Nam)))
      then
      then
         Param_Typ :=
         Param_Typ :=
           Etype (First (Parameter_Associations
           Etype (First (Parameter_Associations
                          (Associated_Node_For_Itype (Proc_Nam))));
                          (Associated_Node_For_Itype (Proc_Nam))));
      end if;
      end if;
 
 
      if Present (Param_Typ) then
      if Present (Param_Typ) then
         return
         return
           Is_Interface (Param_Typ)
           Is_Interface (Param_Typ)
             and then Is_Limited_Record (Param_Typ);
             and then Is_Limited_Record (Param_Typ);
      end if;
      end if;
 
 
      return False;
      return False;
   end Is_Controlling_Limited_Procedure;
   end Is_Controlling_Limited_Procedure;
 
 
   -----------------------------
   -----------------------------
   -- Is_CPP_Constructor_Call --
   -- Is_CPP_Constructor_Call --
   -----------------------------
   -----------------------------
 
 
   function Is_CPP_Constructor_Call (N : Node_Id) return Boolean is
   function Is_CPP_Constructor_Call (N : Node_Id) return Boolean is
   begin
   begin
      return Nkind (N) = N_Function_Call
      return Nkind (N) = N_Function_Call
        and then Is_CPP_Class (Etype (Etype (N)))
        and then Is_CPP_Class (Etype (Etype (N)))
        and then Is_Constructor (Entity (Name (N)))
        and then Is_Constructor (Entity (Name (N)))
        and then Is_Imported (Entity (Name (N)));
        and then Is_Imported (Entity (Name (N)));
   end Is_CPP_Constructor_Call;
   end Is_CPP_Constructor_Call;
 
 
   ----------------------------------------------
   ----------------------------------------------
   -- Is_Dependent_Component_Of_Mutable_Object --
   -- Is_Dependent_Component_Of_Mutable_Object --
   ----------------------------------------------
   ----------------------------------------------
 
 
   function Is_Dependent_Component_Of_Mutable_Object
   function Is_Dependent_Component_Of_Mutable_Object
     (Object : Node_Id) return   Boolean
     (Object : Node_Id) return   Boolean
   is
   is
      P           : Node_Id;
      P           : Node_Id;
      Prefix_Type : Entity_Id;
      Prefix_Type : Entity_Id;
      P_Aliased   : Boolean := False;
      P_Aliased   : Boolean := False;
      Comp        : Entity_Id;
      Comp        : Entity_Id;
 
 
      function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean;
      function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean;
      --  Returns True if and only if Comp is declared within a variant part
      --  Returns True if and only if Comp is declared within a variant part
 
 
      --------------------------------
      --------------------------------
      -- Is_Declared_Within_Variant --
      -- Is_Declared_Within_Variant --
      --------------------------------
      --------------------------------
 
 
      function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean is
      function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean is
         Comp_Decl : constant Node_Id   := Parent (Comp);
         Comp_Decl : constant Node_Id   := Parent (Comp);
         Comp_List : constant Node_Id   := Parent (Comp_Decl);
         Comp_List : constant Node_Id   := Parent (Comp_Decl);
      begin
      begin
         return Nkind (Parent (Comp_List)) = N_Variant;
         return Nkind (Parent (Comp_List)) = N_Variant;
      end Is_Declared_Within_Variant;
      end Is_Declared_Within_Variant;
 
 
   --  Start of processing for Is_Dependent_Component_Of_Mutable_Object
   --  Start of processing for Is_Dependent_Component_Of_Mutable_Object
 
 
   begin
   begin
      if Is_Variable (Object) then
      if Is_Variable (Object) then
 
 
         if Nkind (Object) = N_Selected_Component then
         if Nkind (Object) = N_Selected_Component then
            P := Prefix (Object);
            P := Prefix (Object);
            Prefix_Type := Etype (P);
            Prefix_Type := Etype (P);
 
 
            if Is_Entity_Name (P) then
            if Is_Entity_Name (P) then
 
 
               if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then
               if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then
                  Prefix_Type := Base_Type (Prefix_Type);
                  Prefix_Type := Base_Type (Prefix_Type);
               end if;
               end if;
 
 
               if Is_Aliased (Entity (P)) then
               if Is_Aliased (Entity (P)) then
                  P_Aliased := True;
                  P_Aliased := True;
               end if;
               end if;
 
 
            --  A discriminant check on a selected component may be
            --  A discriminant check on a selected component may be
            --  expanded into a dereference when removing side-effects.
            --  expanded into a dereference when removing side-effects.
            --  Recover the original node and its type, which may be
            --  Recover the original node and its type, which may be
            --  unconstrained.
            --  unconstrained.
 
 
            elsif Nkind (P) = N_Explicit_Dereference
            elsif Nkind (P) = N_Explicit_Dereference
              and then not (Comes_From_Source (P))
              and then not (Comes_From_Source (P))
            then
            then
               P := Original_Node (P);
               P := Original_Node (P);
               Prefix_Type := Etype (P);
               Prefix_Type := Etype (P);
 
 
            else
            else
               --  Check for prefix being an aliased component ???
               --  Check for prefix being an aliased component ???
               null;
               null;
 
 
            end if;
            end if;
 
 
            --  A heap object is constrained by its initial value
            --  A heap object is constrained by its initial value
 
 
            --  Ada 2005 (AI-363): Always assume the object could be mutable in
            --  Ada 2005 (AI-363): Always assume the object could be mutable in
            --  the dereferenced case, since the access value might denote an
            --  the dereferenced case, since the access value might denote an
            --  unconstrained aliased object, whereas in Ada 95 the designated
            --  unconstrained aliased object, whereas in Ada 95 the designated
            --  object is guaranteed to be constrained. A worst-case assumption
            --  object is guaranteed to be constrained. A worst-case assumption
            --  has to apply in Ada 2005 because we can't tell at compile time
            --  has to apply in Ada 2005 because we can't tell at compile time
            --  whether the object is "constrained by its initial value"
            --  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
            --  (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).
            --  semantic rules -- these rules are acknowledged to need fixing).
 
 
            if Ada_Version < Ada_05 then
            if Ada_Version < Ada_05 then
               if Is_Access_Type (Prefix_Type)
               if Is_Access_Type (Prefix_Type)
                 or else Nkind (P) = N_Explicit_Dereference
                 or else Nkind (P) = N_Explicit_Dereference
               then
               then
                  return False;
                  return False;
               end if;
               end if;
 
 
            elsif Ada_Version >= Ada_05 then
            elsif Ada_Version >= Ada_05 then
               if Is_Access_Type (Prefix_Type) then
               if Is_Access_Type (Prefix_Type) then
 
 
                  --  If the access type is pool-specific, and there is no
                  --  If the access type is pool-specific, and there is no
                  --  constrained partial view of the designated type, then the
                  --  constrained partial view of the designated type, then the
                  --  designated object is known to be constrained.
                  --  designated object is known to be constrained.
 
 
                  if Ekind (Prefix_Type) = E_Access_Type
                  if Ekind (Prefix_Type) = E_Access_Type
                    and then not Has_Constrained_Partial_View
                    and then not Has_Constrained_Partial_View
                                   (Designated_Type (Prefix_Type))
                                   (Designated_Type (Prefix_Type))
                  then
                  then
                     return False;
                     return False;
 
 
                  --  Otherwise (general access type, or there is a constrained
                  --  Otherwise (general access type, or there is a constrained
                  --  partial view of the designated type), we need to check
                  --  partial view of the designated type), we need to check
                  --  based on the designated type.
                  --  based on the designated type.
 
 
                  else
                  else
                     Prefix_Type := Designated_Type (Prefix_Type);
                     Prefix_Type := Designated_Type (Prefix_Type);
                  end if;
                  end if;
               end if;
               end if;
            end if;
            end if;
 
 
            Comp :=
            Comp :=
              Original_Record_Component (Entity (Selector_Name (Object)));
              Original_Record_Component (Entity (Selector_Name (Object)));
 
 
            --  As per AI-0017, the renaming is illegal in a generic body,
            --  As per AI-0017, the renaming is illegal in a generic body,
            --  even if the subtype is indefinite.
            --  even if the subtype is indefinite.
 
 
            --  Ada 2005 (AI-363): In Ada 2005 an aliased object can be mutable
            --  Ada 2005 (AI-363): In Ada 2005 an aliased object can be mutable
 
 
            if not Is_Constrained (Prefix_Type)
            if not Is_Constrained (Prefix_Type)
              and then (not Is_Indefinite_Subtype (Prefix_Type)
              and then (not Is_Indefinite_Subtype (Prefix_Type)
                         or else
                         or else
                          (Is_Generic_Type (Prefix_Type)
                          (Is_Generic_Type (Prefix_Type)
                            and then Ekind (Current_Scope) = E_Generic_Package
                            and then Ekind (Current_Scope) = E_Generic_Package
                            and then In_Package_Body (Current_Scope)))
                            and then In_Package_Body (Current_Scope)))
 
 
              and then (Is_Declared_Within_Variant (Comp)
              and then (Is_Declared_Within_Variant (Comp)
                          or else Has_Discriminant_Dependent_Constraint (Comp))
                          or else Has_Discriminant_Dependent_Constraint (Comp))
              and then (not P_Aliased or else Ada_Version >= Ada_05)
              and then (not P_Aliased or else Ada_Version >= Ada_05)
            then
            then
               return True;
               return True;
 
 
            else
            else
               return
               return
                 Is_Dependent_Component_Of_Mutable_Object (Prefix (Object));
                 Is_Dependent_Component_Of_Mutable_Object (Prefix (Object));
 
 
            end if;
            end if;
 
 
         elsif Nkind (Object) = N_Indexed_Component
         elsif Nkind (Object) = N_Indexed_Component
           or else Nkind (Object) = N_Slice
           or else Nkind (Object) = N_Slice
         then
         then
            return Is_Dependent_Component_Of_Mutable_Object (Prefix (Object));
            return Is_Dependent_Component_Of_Mutable_Object (Prefix (Object));
 
 
         --  A type conversion that Is_Variable is a view conversion:
         --  A type conversion that Is_Variable is a view conversion:
         --  go back to the denoted object.
         --  go back to the denoted object.
 
 
         elsif Nkind (Object) = N_Type_Conversion then
         elsif Nkind (Object) = N_Type_Conversion then
            return
            return
              Is_Dependent_Component_Of_Mutable_Object (Expression (Object));
              Is_Dependent_Component_Of_Mutable_Object (Expression (Object));
         end if;
         end if;
      end if;
      end if;
 
 
      return False;
      return False;
   end Is_Dependent_Component_Of_Mutable_Object;
   end Is_Dependent_Component_Of_Mutable_Object;
 
 
   ---------------------
   ---------------------
   -- Is_Dereferenced --
   -- Is_Dereferenced --
   ---------------------
   ---------------------
 
 
   function Is_Dereferenced (N : Node_Id) return Boolean is
   function Is_Dereferenced (N : Node_Id) return Boolean is
      P : constant Node_Id := Parent (N);
      P : constant Node_Id := Parent (N);
   begin
   begin
      return
      return
         (Nkind (P) = N_Selected_Component
         (Nkind (P) = N_Selected_Component
            or else
            or else
          Nkind (P) = N_Explicit_Dereference
          Nkind (P) = N_Explicit_Dereference
            or else
            or else
          Nkind (P) = N_Indexed_Component
          Nkind (P) = N_Indexed_Component
            or else
            or else
          Nkind (P) = N_Slice)
          Nkind (P) = N_Slice)
        and then Prefix (P) = N;
        and then Prefix (P) = N;
   end Is_Dereferenced;
   end Is_Dereferenced;
 
 
   ----------------------
   ----------------------
   -- Is_Descendent_Of --
   -- Is_Descendent_Of --
   ----------------------
   ----------------------
 
 
   function Is_Descendent_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean is
   function Is_Descendent_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean is
      T    : Entity_Id;
      T    : Entity_Id;
      Etyp : Entity_Id;
      Etyp : Entity_Id;
 
 
   begin
   begin
      pragma Assert (Nkind (T1) in N_Entity);
      pragma Assert (Nkind (T1) in N_Entity);
      pragma Assert (Nkind (T2) in N_Entity);
      pragma Assert (Nkind (T2) in N_Entity);
 
 
      T := Base_Type (T1);
      T := Base_Type (T1);
 
 
      --  Immediate return if the types match
      --  Immediate return if the types match
 
 
      if T = T2 then
      if T = T2 then
         return True;
         return True;
 
 
      --  Comment needed here ???
      --  Comment needed here ???
 
 
      elsif Ekind (T) = E_Class_Wide_Type then
      elsif Ekind (T) = E_Class_Wide_Type then
         return Etype (T) = T2;
         return Etype (T) = T2;
 
 
      --  All other cases
      --  All other cases
 
 
      else
      else
         loop
         loop
            Etyp := Etype (T);
            Etyp := Etype (T);
 
 
            --  Done if we found the type we are looking for
            --  Done if we found the type we are looking for
 
 
            if Etyp = T2 then
            if Etyp = T2 then
               return True;
               return True;
 
 
            --  Done if no more derivations to check
            --  Done if no more derivations to check
 
 
            elsif T = T1
            elsif T = T1
              or else T = Etyp
              or else T = Etyp
            then
            then
               return False;
               return False;
 
 
            --  Following test catches error cases resulting from prev errors
            --  Following test catches error cases resulting from prev errors
 
 
            elsif No (Etyp) then
            elsif No (Etyp) then
               return False;
               return False;
 
 
            elsif Is_Private_Type (T) and then Etyp = Full_View (T) then
            elsif Is_Private_Type (T) and then Etyp = Full_View (T) then
               return False;
               return False;
 
 
            elsif Is_Private_Type (Etyp) and then Full_View (Etyp) = T then
            elsif Is_Private_Type (Etyp) and then Full_View (Etyp) = T then
               return False;
               return False;
            end if;
            end if;
 
 
            T := Base_Type (Etyp);
            T := Base_Type (Etyp);
         end loop;
         end loop;
      end if;
      end if;
   end Is_Descendent_Of;
   end Is_Descendent_Of;
 
 
   --------------
   --------------
   -- Is_False --
   -- Is_False --
   --------------
   --------------
 
 
   function Is_False (U : Uint) return Boolean is
   function Is_False (U : Uint) return Boolean is
   begin
   begin
      return (U = 0);
      return (U = 0);
   end Is_False;
   end Is_False;
 
 
   ---------------------------
   ---------------------------
   -- Is_Fixed_Model_Number --
   -- Is_Fixed_Model_Number --
   ---------------------------
   ---------------------------
 
 
   function Is_Fixed_Model_Number (U : Ureal; T : Entity_Id) return Boolean is
   function Is_Fixed_Model_Number (U : Ureal; T : Entity_Id) return Boolean is
      S : constant Ureal := Small_Value (T);
      S : constant Ureal := Small_Value (T);
      M : Urealp.Save_Mark;
      M : Urealp.Save_Mark;
      R : Boolean;
      R : Boolean;
   begin
   begin
      M := Urealp.Mark;
      M := Urealp.Mark;
      R := (U = UR_Trunc (U / S) * S);
      R := (U = UR_Trunc (U / S) * S);
      Urealp.Release (M);
      Urealp.Release (M);
      return R;
      return R;
   end Is_Fixed_Model_Number;
   end Is_Fixed_Model_Number;
 
 
   -------------------------------
   -------------------------------
   -- Is_Fully_Initialized_Type --
   -- Is_Fully_Initialized_Type --
   -------------------------------
   -------------------------------
 
 
   function Is_Fully_Initialized_Type (Typ : Entity_Id) return Boolean is
   function Is_Fully_Initialized_Type (Typ : Entity_Id) return Boolean is
   begin
   begin
      if Is_Scalar_Type (Typ) then
      if Is_Scalar_Type (Typ) then
         return False;
         return False;
 
 
      elsif Is_Access_Type (Typ) then
      elsif Is_Access_Type (Typ) then
         return True;
         return True;
 
 
      elsif Is_Array_Type (Typ) then
      elsif Is_Array_Type (Typ) then
         if Is_Fully_Initialized_Type (Component_Type (Typ)) then
         if Is_Fully_Initialized_Type (Component_Type (Typ)) then
            return True;
            return True;
         end if;
         end if;
 
 
         --  An interesting case, if we have a constrained type one of whose
         --  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
         --  bounds is known to be null, then there are no elements to be
         --  initialized, so all the elements are initialized!
         --  initialized, so all the elements are initialized!
 
 
         if Is_Constrained (Typ) then
         if Is_Constrained (Typ) then
            declare
            declare
               Indx     : Node_Id;
               Indx     : Node_Id;
               Indx_Typ : Entity_Id;
               Indx_Typ : Entity_Id;
               Lbd, Hbd : Node_Id;
               Lbd, Hbd : Node_Id;
 
 
            begin
            begin
               Indx := First_Index (Typ);
               Indx := First_Index (Typ);
               while Present (Indx) loop
               while Present (Indx) loop
                  if Etype (Indx) = Any_Type then
                  if Etype (Indx) = Any_Type then
                     return False;
                     return False;
 
 
                  --  If index is a range, use directly
                  --  If index is a range, use directly
 
 
                  elsif Nkind (Indx) = N_Range then
                  elsif Nkind (Indx) = N_Range then
                     Lbd := Low_Bound  (Indx);
                     Lbd := Low_Bound  (Indx);
                     Hbd := High_Bound (Indx);
                     Hbd := High_Bound (Indx);
 
 
                  else
                  else
                     Indx_Typ := Etype (Indx);
                     Indx_Typ := Etype (Indx);
 
 
                     if Is_Private_Type (Indx_Typ)  then
                     if Is_Private_Type (Indx_Typ)  then
                        Indx_Typ := Full_View (Indx_Typ);
                        Indx_Typ := Full_View (Indx_Typ);
                     end if;
                     end if;
 
 
                     if No (Indx_Typ) or else Etype (Indx_Typ) = Any_Type then
                     if No (Indx_Typ) or else Etype (Indx_Typ) = Any_Type then
                        return False;
                        return False;
                     else
                     else
                        Lbd := Type_Low_Bound  (Indx_Typ);
                        Lbd := Type_Low_Bound  (Indx_Typ);
                        Hbd := Type_High_Bound (Indx_Typ);
                        Hbd := Type_High_Bound (Indx_Typ);
                     end if;
                     end if;
                  end if;
                  end if;
 
 
                  if Compile_Time_Known_Value (Lbd)
                  if Compile_Time_Known_Value (Lbd)
                    and then Compile_Time_Known_Value (Hbd)
                    and then Compile_Time_Known_Value (Hbd)
                  then
                  then
                     if Expr_Value (Hbd) < Expr_Value (Lbd) then
                     if Expr_Value (Hbd) < Expr_Value (Lbd) then
                        return True;
                        return True;
                     end if;
                     end if;
                  end if;
                  end if;
 
 
                  Next_Index (Indx);
                  Next_Index (Indx);
               end loop;
               end loop;
            end;
            end;
         end if;
         end if;
 
 
         --  If no null indexes, then type is not fully initialized
         --  If no null indexes, then type is not fully initialized
 
 
         return False;
         return False;
 
 
      --  Record types
      --  Record types
 
 
      elsif Is_Record_Type (Typ) then
      elsif Is_Record_Type (Typ) then
         if Has_Discriminants (Typ)
         if Has_Discriminants (Typ)
           and then
           and then
             Present (Discriminant_Default_Value (First_Discriminant (Typ)))
             Present (Discriminant_Default_Value (First_Discriminant (Typ)))
           and then Is_Fully_Initialized_Variant (Typ)
           and then Is_Fully_Initialized_Variant (Typ)
         then
         then
            return True;
            return True;
         end if;
         end if;
 
 
         --  Controlled records are considered to be fully initialized if
         --  Controlled records are considered to be fully initialized if
         --  there is a user defined Initialize routine. This may not be
         --  there is a user defined Initialize routine. This may not be
         --  entirely correct, but as the spec notes, we are guessing here
         --  entirely correct, but as the spec notes, we are guessing here
         --  what is best from the point of view of issuing warnings.
         --  what is best from the point of view of issuing warnings.
 
 
         if Is_Controlled (Typ) then
         if Is_Controlled (Typ) then
            declare
            declare
               Utyp : constant Entity_Id := Underlying_Type (Typ);
               Utyp : constant Entity_Id := Underlying_Type (Typ);
 
 
            begin
            begin
               if Present (Utyp) then
               if Present (Utyp) then
                  declare
                  declare
                     Init : constant Entity_Id :=
                     Init : constant Entity_Id :=
                              (Find_Prim_Op
                              (Find_Prim_Op
                                 (Underlying_Type (Typ), Name_Initialize));
                                 (Underlying_Type (Typ), Name_Initialize));
 
 
                  begin
                  begin
                     if Present (Init)
                     if Present (Init)
                       and then Comes_From_Source (Init)
                       and then Comes_From_Source (Init)
                       and then not
                       and then not
                         Is_Predefined_File_Name
                         Is_Predefined_File_Name
                           (File_Name (Get_Source_File_Index (Sloc (Init))))
                           (File_Name (Get_Source_File_Index (Sloc (Init))))
                     then
                     then
                        return True;
                        return True;
 
 
                     elsif Has_Null_Extension (Typ)
                     elsif Has_Null_Extension (Typ)
                        and then
                        and then
                          Is_Fully_Initialized_Type
                          Is_Fully_Initialized_Type
                            (Etype (Base_Type (Typ)))
                            (Etype (Base_Type (Typ)))
                     then
                     then
                        return True;
                        return True;
                     end if;
                     end if;
                  end;
                  end;
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
         --  Otherwise see if all record components are initialized
         --  Otherwise see if all record components are initialized
 
 
         declare
         declare
            Ent : Entity_Id;
            Ent : Entity_Id;
 
 
         begin
         begin
            Ent := First_Entity (Typ);
            Ent := First_Entity (Typ);
            while Present (Ent) loop
            while Present (Ent) loop
               if Chars (Ent) = Name_uController then
               if Chars (Ent) = Name_uController then
                  null;
                  null;
 
 
               elsif Ekind (Ent) = E_Component
               elsif Ekind (Ent) = E_Component
                 and then (No (Parent (Ent))
                 and then (No (Parent (Ent))
                             or else No (Expression (Parent (Ent))))
                             or else No (Expression (Parent (Ent))))
                 and then not Is_Fully_Initialized_Type (Etype (Ent))
                 and then not Is_Fully_Initialized_Type (Etype (Ent))
 
 
                  --  Special VM case for tag components, which need to be
                  --  Special VM case for tag components, which need to be
                  --  defined in this case, but are never initialized as VMs
                  --  defined in this case, but are never initialized as VMs
                  --  are using other dispatching mechanisms. Ignore this
                  --  are using other dispatching mechanisms. Ignore this
                  --  uninitialized case. Note that this applies both to the
                  --  uninitialized case. Note that this applies both to the
                  --  uTag entry and the main vtable pointer (CPP_Class case).
                  --  uTag entry and the main vtable pointer (CPP_Class case).
 
 
                 and then (Tagged_Type_Expansion or else not Is_Tag (Ent))
                 and then (Tagged_Type_Expansion or else not Is_Tag (Ent))
               then
               then
                  return False;
                  return False;
               end if;
               end if;
 
 
               Next_Entity (Ent);
               Next_Entity (Ent);
            end loop;
            end loop;
         end;
         end;
 
 
         --  No uninitialized components, so type is fully initialized.
         --  No uninitialized components, so type is fully initialized.
         --  Note that this catches the case of no components as well.
         --  Note that this catches the case of no components as well.
 
 
         return True;
         return True;
 
 
      elsif Is_Concurrent_Type (Typ) then
      elsif Is_Concurrent_Type (Typ) then
         return True;
         return True;
 
 
      elsif Is_Private_Type (Typ) then
      elsif Is_Private_Type (Typ) then
         declare
         declare
            U : constant Entity_Id := Underlying_Type (Typ);
            U : constant Entity_Id := Underlying_Type (Typ);
 
 
         begin
         begin
            if No (U) then
            if No (U) then
               return False;
               return False;
            else
            else
               return Is_Fully_Initialized_Type (U);
               return Is_Fully_Initialized_Type (U);
            end if;
            end if;
         end;
         end;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Fully_Initialized_Type;
   end Is_Fully_Initialized_Type;
 
 
   ----------------------------------
   ----------------------------------
   -- Is_Fully_Initialized_Variant --
   -- Is_Fully_Initialized_Variant --
   ----------------------------------
   ----------------------------------
 
 
   function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean is
   function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean is
      Loc           : constant Source_Ptr := Sloc (Typ);
      Loc           : constant Source_Ptr := Sloc (Typ);
      Constraints   : constant List_Id    := New_List;
      Constraints   : constant List_Id    := New_List;
      Components    : constant Elist_Id   := New_Elmt_List;
      Components    : constant Elist_Id   := New_Elmt_List;
      Comp_Elmt     : Elmt_Id;
      Comp_Elmt     : Elmt_Id;
      Comp_Id       : Node_Id;
      Comp_Id       : Node_Id;
      Comp_List     : Node_Id;
      Comp_List     : Node_Id;
      Discr         : Entity_Id;
      Discr         : Entity_Id;
      Discr_Val     : Node_Id;
      Discr_Val     : Node_Id;
 
 
      Report_Errors : Boolean;
      Report_Errors : Boolean;
      pragma Warnings (Off, Report_Errors);
      pragma Warnings (Off, Report_Errors);
 
 
   begin
   begin
      if Serious_Errors_Detected > 0 then
      if Serious_Errors_Detected > 0 then
         return False;
         return False;
      end if;
      end if;
 
 
      if Is_Record_Type (Typ)
      if Is_Record_Type (Typ)
        and then Nkind (Parent (Typ)) = N_Full_Type_Declaration
        and then Nkind (Parent (Typ)) = N_Full_Type_Declaration
        and then Nkind (Type_Definition (Parent (Typ))) = N_Record_Definition
        and then Nkind (Type_Definition (Parent (Typ))) = N_Record_Definition
      then
      then
         Comp_List := Component_List (Type_Definition (Parent (Typ)));
         Comp_List := Component_List (Type_Definition (Parent (Typ)));
 
 
         Discr := First_Discriminant (Typ);
         Discr := First_Discriminant (Typ);
         while Present (Discr) loop
         while Present (Discr) loop
            if Nkind (Parent (Discr)) = N_Discriminant_Specification then
            if Nkind (Parent (Discr)) = N_Discriminant_Specification then
               Discr_Val := Expression (Parent (Discr));
               Discr_Val := Expression (Parent (Discr));
 
 
               if Present (Discr_Val)
               if Present (Discr_Val)
                 and then Is_OK_Static_Expression (Discr_Val)
                 and then Is_OK_Static_Expression (Discr_Val)
               then
               then
                  Append_To (Constraints,
                  Append_To (Constraints,
                    Make_Component_Association (Loc,
                    Make_Component_Association (Loc,
                      Choices    => New_List (New_Occurrence_Of (Discr, Loc)),
                      Choices    => New_List (New_Occurrence_Of (Discr, Loc)),
                      Expression => New_Copy (Discr_Val)));
                      Expression => New_Copy (Discr_Val)));
               else
               else
                  return False;
                  return False;
               end if;
               end if;
            else
            else
               return False;
               return False;
            end if;
            end if;
 
 
            Next_Discriminant (Discr);
            Next_Discriminant (Discr);
         end loop;
         end loop;
 
 
         Gather_Components
         Gather_Components
           (Typ           => Typ,
           (Typ           => Typ,
            Comp_List     => Comp_List,
            Comp_List     => Comp_List,
            Governed_By   => Constraints,
            Governed_By   => Constraints,
            Into          => Components,
            Into          => Components,
            Report_Errors => Report_Errors);
            Report_Errors => Report_Errors);
 
 
         --  Check that each component present is fully initialized
         --  Check that each component present is fully initialized
 
 
         Comp_Elmt := First_Elmt (Components);
         Comp_Elmt := First_Elmt (Components);
         while Present (Comp_Elmt) loop
         while Present (Comp_Elmt) loop
            Comp_Id := Node (Comp_Elmt);
            Comp_Id := Node (Comp_Elmt);
 
 
            if Ekind (Comp_Id) = E_Component
            if Ekind (Comp_Id) = E_Component
              and then (No (Parent (Comp_Id))
              and then (No (Parent (Comp_Id))
                         or else No (Expression (Parent (Comp_Id))))
                         or else No (Expression (Parent (Comp_Id))))
              and then not Is_Fully_Initialized_Type (Etype (Comp_Id))
              and then not Is_Fully_Initialized_Type (Etype (Comp_Id))
            then
            then
               return False;
               return False;
            end if;
            end if;
 
 
            Next_Elmt (Comp_Elmt);
            Next_Elmt (Comp_Elmt);
         end loop;
         end loop;
 
 
         return True;
         return True;
 
 
      elsif Is_Private_Type (Typ) then
      elsif Is_Private_Type (Typ) then
         declare
         declare
            U : constant Entity_Id := Underlying_Type (Typ);
            U : constant Entity_Id := Underlying_Type (Typ);
 
 
         begin
         begin
            if No (U) then
            if No (U) then
               return False;
               return False;
            else
            else
               return Is_Fully_Initialized_Variant (U);
               return Is_Fully_Initialized_Variant (U);
            end if;
            end if;
         end;
         end;
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Fully_Initialized_Variant;
   end Is_Fully_Initialized_Variant;
 
 
   ------------
   ------------
   -- Is_LHS --
   -- Is_LHS --
   ------------
   ------------
 
 
   --  We seem to have a lot of overlapping functions that do similar things
   --  We seem to have a lot of overlapping functions that do similar things
   --  (testing for left hand sides or lvalues???). Anyway, since this one is
   --  (testing for left hand sides or lvalues???). Anyway, since this one is
   --  purely syntactic, it should be in Sem_Aux I would think???
   --  purely syntactic, it should be in Sem_Aux I would think???
 
 
   function Is_LHS (N : Node_Id) return Boolean is
   function Is_LHS (N : Node_Id) return Boolean is
      P : constant Node_Id := Parent (N);
      P : constant Node_Id := Parent (N);
   begin
   begin
      return Nkind (P) = N_Assignment_Statement
      return Nkind (P) = N_Assignment_Statement
        and then Name (P) = N;
        and then Name (P) = N;
   end Is_LHS;
   end Is_LHS;
 
 
   ----------------------------
   ----------------------------
   -- Is_Inherited_Operation --
   -- Is_Inherited_Operation --
   ----------------------------
   ----------------------------
 
 
   function Is_Inherited_Operation (E : Entity_Id) return Boolean is
   function Is_Inherited_Operation (E : Entity_Id) return Boolean is
      Kind : constant Node_Kind := Nkind (Parent (E));
      Kind : constant Node_Kind := Nkind (Parent (E));
   begin
   begin
      pragma Assert (Is_Overloadable (E));
      pragma Assert (Is_Overloadable (E));
      return Kind = N_Full_Type_Declaration
      return Kind = N_Full_Type_Declaration
        or else Kind = N_Private_Extension_Declaration
        or else Kind = N_Private_Extension_Declaration
        or else Kind = N_Subtype_Declaration
        or else Kind = N_Subtype_Declaration
        or else (Ekind (E) = E_Enumeration_Literal
        or else (Ekind (E) = E_Enumeration_Literal
                  and then Is_Derived_Type (Etype (E)));
                  and then Is_Derived_Type (Etype (E)));
   end Is_Inherited_Operation;
   end Is_Inherited_Operation;
 
 
   -----------------------------
   -----------------------------
   -- Is_Library_Level_Entity --
   -- Is_Library_Level_Entity --
   -----------------------------
   -----------------------------
 
 
   function Is_Library_Level_Entity (E : Entity_Id) return Boolean is
   function Is_Library_Level_Entity (E : Entity_Id) return Boolean is
   begin
   begin
      --  The following is a small optimization, and it also properly handles
      --  The following is a small optimization, and it also properly handles
      --  discriminals, which in task bodies might appear in expressions before
      --  discriminals, which in task bodies might appear in expressions before
      --  the corresponding procedure has been created, and which therefore do
      --  the corresponding procedure has been created, and which therefore do
      --  not have an assigned scope.
      --  not have an assigned scope.
 
 
      if Ekind (E) in Formal_Kind then
      if Ekind (E) in Formal_Kind then
         return False;
         return False;
      end if;
      end if;
 
 
      --  Normal test is simply that the enclosing dynamic scope is Standard
      --  Normal test is simply that the enclosing dynamic scope is Standard
 
 
      return Enclosing_Dynamic_Scope (E) = Standard_Standard;
      return Enclosing_Dynamic_Scope (E) = Standard_Standard;
   end Is_Library_Level_Entity;
   end Is_Library_Level_Entity;
 
 
   ---------------------------------
   ---------------------------------
   -- Is_Local_Variable_Reference --
   -- Is_Local_Variable_Reference --
   ---------------------------------
   ---------------------------------
 
 
   function Is_Local_Variable_Reference (Expr : Node_Id) return Boolean is
   function Is_Local_Variable_Reference (Expr : Node_Id) return Boolean is
   begin
   begin
      if not Is_Entity_Name (Expr) then
      if not Is_Entity_Name (Expr) then
         return False;
         return False;
 
 
      else
      else
         declare
         declare
            Ent : constant Entity_Id := Entity (Expr);
            Ent : constant Entity_Id := Entity (Expr);
            Sub : constant Entity_Id := Enclosing_Subprogram (Ent);
            Sub : constant Entity_Id := Enclosing_Subprogram (Ent);
         begin
         begin
            if Ekind (Ent) /= E_Variable
            if Ekind (Ent) /= E_Variable
                 and then
                 and then
               Ekind (Ent) /= E_In_Out_Parameter
               Ekind (Ent) /= E_In_Out_Parameter
            then
            then
               return False;
               return False;
            else
            else
               return Present (Sub) and then Sub = Current_Subprogram;
               return Present (Sub) and then Sub = Current_Subprogram;
            end if;
            end if;
         end;
         end;
      end if;
      end if;
   end Is_Local_Variable_Reference;
   end Is_Local_Variable_Reference;
 
 
   -------------------------
   -------------------------
   -- Is_Object_Reference --
   -- Is_Object_Reference --
   -------------------------
   -------------------------
 
 
   function Is_Object_Reference (N : Node_Id) return Boolean is
   function Is_Object_Reference (N : Node_Id) return Boolean is
   begin
   begin
      if Is_Entity_Name (N) then
      if Is_Entity_Name (N) then
         return Present (Entity (N)) and then Is_Object (Entity (N));
         return Present (Entity (N)) and then Is_Object (Entity (N));
 
 
      else
      else
         case Nkind (N) is
         case Nkind (N) is
            when N_Indexed_Component | N_Slice =>
            when N_Indexed_Component | N_Slice =>
               return
               return
                 Is_Object_Reference (Prefix (N))
                 Is_Object_Reference (Prefix (N))
                   or else Is_Access_Type (Etype (Prefix (N)));
                   or else Is_Access_Type (Etype (Prefix (N)));
 
 
            --  In Ada95, a function call is a constant object; a procedure
            --  In Ada95, a function call is a constant object; a procedure
            --  call is not.
            --  call is not.
 
 
            when N_Function_Call =>
            when N_Function_Call =>
               return Etype (N) /= Standard_Void_Type;
               return Etype (N) /= Standard_Void_Type;
 
 
            --  A reference to the stream attribute Input is a function call
            --  A reference to the stream attribute Input is a function call
 
 
            when N_Attribute_Reference =>
            when N_Attribute_Reference =>
               return Attribute_Name (N) = Name_Input;
               return Attribute_Name (N) = Name_Input;
 
 
            when N_Selected_Component =>
            when N_Selected_Component =>
               return
               return
                 Is_Object_Reference (Selector_Name (N))
                 Is_Object_Reference (Selector_Name (N))
                   and then
                   and then
                     (Is_Object_Reference (Prefix (N))
                     (Is_Object_Reference (Prefix (N))
                        or else Is_Access_Type (Etype (Prefix (N))));
                        or else Is_Access_Type (Etype (Prefix (N))));
 
 
            when N_Explicit_Dereference =>
            when N_Explicit_Dereference =>
               return True;
               return True;
 
 
            --  A view conversion of a tagged object is an object reference
            --  A view conversion of a tagged object is an object reference
 
 
            when N_Type_Conversion =>
            when N_Type_Conversion =>
               return Is_Tagged_Type (Etype (Subtype_Mark (N)))
               return Is_Tagged_Type (Etype (Subtype_Mark (N)))
                 and then Is_Tagged_Type (Etype (Expression (N)))
                 and then Is_Tagged_Type (Etype (Expression (N)))
                 and then Is_Object_Reference (Expression (N));
                 and then Is_Object_Reference (Expression (N));
 
 
            --  An unchecked type conversion is considered to be an object if
            --  An unchecked type conversion is considered to be an object if
            --  the operand is an object (this construction arises only as a
            --  the operand is an object (this construction arises only as a
            --  result of expansion activities).
            --  result of expansion activities).
 
 
            when N_Unchecked_Type_Conversion =>
            when N_Unchecked_Type_Conversion =>
               return True;
               return True;
 
 
            when others =>
            when others =>
               return False;
               return False;
         end case;
         end case;
      end if;
      end if;
   end Is_Object_Reference;
   end Is_Object_Reference;
 
 
   -----------------------------------
   -----------------------------------
   -- Is_OK_Variable_For_Out_Formal --
   -- Is_OK_Variable_For_Out_Formal --
   -----------------------------------
   -----------------------------------
 
 
   function Is_OK_Variable_For_Out_Formal (AV : Node_Id) return Boolean is
   function Is_OK_Variable_For_Out_Formal (AV : Node_Id) return Boolean is
   begin
   begin
      Note_Possible_Modification (AV, Sure => True);
      Note_Possible_Modification (AV, Sure => True);
 
 
      --  We must reject parenthesized variable names. The check for
      --  We must reject parenthesized variable names. The check for
      --  Comes_From_Source is present because there are currently
      --  Comes_From_Source is present because there are currently
      --  cases where the compiler violates this rule (e.g. passing
      --  cases where the compiler violates this rule (e.g. passing
      --  a task object to its controlled Initialize routine).
      --  a task object to its controlled Initialize routine).
 
 
      if Paren_Count (AV) > 0 and then Comes_From_Source (AV) then
      if Paren_Count (AV) > 0 and then Comes_From_Source (AV) then
         return False;
         return False;
 
 
      --  A variable is always allowed
      --  A variable is always allowed
 
 
      elsif Is_Variable (AV) then
      elsif Is_Variable (AV) then
         return True;
         return True;
 
 
      --  Unchecked conversions are allowed only if they come from the
      --  Unchecked conversions are allowed only if they come from the
      --  generated code, which sometimes uses unchecked conversions for out
      --  generated code, which sometimes uses unchecked conversions for out
      --  parameters in cases where code generation is unaffected. We tell
      --  parameters in cases where code generation is unaffected. We tell
      --  source unchecked conversions by seeing if they are rewrites of an
      --  source unchecked conversions by seeing if they are rewrites of an
      --  original Unchecked_Conversion function call, or of an explicit
      --  original Unchecked_Conversion function call, or of an explicit
      --  conversion of a function call.
      --  conversion of a function call.
 
 
      elsif Nkind (AV) = N_Unchecked_Type_Conversion then
      elsif Nkind (AV) = N_Unchecked_Type_Conversion then
         if Nkind (Original_Node (AV)) = N_Function_Call then
         if Nkind (Original_Node (AV)) = N_Function_Call then
            return False;
            return False;
 
 
         elsif Comes_From_Source (AV)
         elsif Comes_From_Source (AV)
           and then Nkind (Original_Node (Expression (AV))) = N_Function_Call
           and then Nkind (Original_Node (Expression (AV))) = N_Function_Call
         then
         then
            return False;
            return False;
 
 
         elsif Nkind (Original_Node (AV)) = N_Type_Conversion then
         elsif Nkind (Original_Node (AV)) = N_Type_Conversion then
            return Is_OK_Variable_For_Out_Formal (Expression (AV));
            return Is_OK_Variable_For_Out_Formal (Expression (AV));
 
 
         else
         else
            return True;
            return True;
         end if;
         end if;
 
 
      --  Normal type conversions are allowed if argument is a variable
      --  Normal type conversions are allowed if argument is a variable
 
 
      elsif Nkind (AV) = N_Type_Conversion then
      elsif Nkind (AV) = N_Type_Conversion then
         if Is_Variable (Expression (AV))
         if Is_Variable (Expression (AV))
           and then Paren_Count (Expression (AV)) = 0
           and then Paren_Count (Expression (AV)) = 0
         then
         then
            Note_Possible_Modification (Expression (AV), Sure => True);
            Note_Possible_Modification (Expression (AV), Sure => True);
            return True;
            return True;
 
 
         --  We also allow a non-parenthesized expression that raises
         --  We also allow a non-parenthesized expression that raises
         --  constraint error if it rewrites what used to be a variable
         --  constraint error if it rewrites what used to be a variable
 
 
         elsif Raises_Constraint_Error (Expression (AV))
         elsif Raises_Constraint_Error (Expression (AV))
            and then Paren_Count (Expression (AV)) = 0
            and then Paren_Count (Expression (AV)) = 0
            and then Is_Variable (Original_Node (Expression (AV)))
            and then Is_Variable (Original_Node (Expression (AV)))
         then
         then
            return True;
            return True;
 
 
         --  Type conversion of something other than a variable
         --  Type conversion of something other than a variable
 
 
         else
         else
            return False;
            return False;
         end if;
         end if;
 
 
      --  If this node is rewritten, then test the original form, if that is
      --  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
      --  OK, then we consider the rewritten node OK (for example, if the
      --  original node is a conversion, then Is_Variable will not be true
      --  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).
      --  but we still want to allow the conversion if it converts a variable).
 
 
      elsif Original_Node (AV) /= AV then
      elsif Original_Node (AV) /= AV then
         return Is_OK_Variable_For_Out_Formal (Original_Node (AV));
         return Is_OK_Variable_For_Out_Formal (Original_Node (AV));
 
 
      --  All other non-variables are rejected
      --  All other non-variables are rejected
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_OK_Variable_For_Out_Formal;
   end Is_OK_Variable_For_Out_Formal;
 
 
   -----------------------------------
   -----------------------------------
   -- Is_Partially_Initialized_Type --
   -- Is_Partially_Initialized_Type --
   -----------------------------------
   -----------------------------------
 
 
   function Is_Partially_Initialized_Type (Typ : Entity_Id) return Boolean is
   function Is_Partially_Initialized_Type (Typ : Entity_Id) return Boolean is
   begin
   begin
      if Is_Scalar_Type (Typ) then
      if Is_Scalar_Type (Typ) then
         return False;
         return False;
 
 
      elsif Is_Access_Type (Typ) then
      elsif Is_Access_Type (Typ) then
         return True;
         return True;
 
 
      elsif Is_Array_Type (Typ) then
      elsif Is_Array_Type (Typ) then
 
 
         --  If component type is partially initialized, so is array type
         --  If component type is partially initialized, so is array type
 
 
         if Is_Partially_Initialized_Type (Component_Type (Typ)) then
         if Is_Partially_Initialized_Type (Component_Type (Typ)) then
            return True;
            return True;
 
 
         --  Otherwise we are only partially initialized if we are fully
         --  Otherwise we are only partially initialized if we are fully
         --  initialized (this is the empty array case, no point in us
         --  initialized (this is the empty array case, no point in us
         --  duplicating that code here).
         --  duplicating that code here).
 
 
         else
         else
            return Is_Fully_Initialized_Type (Typ);
            return Is_Fully_Initialized_Type (Typ);
         end if;
         end if;
 
 
      elsif Is_Record_Type (Typ) then
      elsif Is_Record_Type (Typ) then
 
 
         --  A discriminated type is always partially initialized
         --  A discriminated type is always partially initialized
 
 
         if Has_Discriminants (Typ) then
         if Has_Discriminants (Typ) then
            return True;
            return True;
 
 
         --  A tagged type is always partially initialized
         --  A tagged type is always partially initialized
 
 
         elsif Is_Tagged_Type (Typ) then
         elsif Is_Tagged_Type (Typ) then
            return True;
            return True;
 
 
         --  Case of non-discriminated record
         --  Case of non-discriminated record
 
 
         else
         else
            declare
            declare
               Ent : Entity_Id;
               Ent : Entity_Id;
 
 
               Component_Present : Boolean := False;
               Component_Present : Boolean := False;
               --  Set True if at least one component is present. If no
               --  Set True if at least one component is present. If no
               --  components are present, then record type is fully
               --  components are present, then record type is fully
               --  initialized (another odd case, like the null array).
               --  initialized (another odd case, like the null array).
 
 
            begin
            begin
               --  Loop through components
               --  Loop through components
 
 
               Ent := First_Entity (Typ);
               Ent := First_Entity (Typ);
               while Present (Ent) loop
               while Present (Ent) loop
                  if Ekind (Ent) = E_Component then
                  if Ekind (Ent) = E_Component then
                     Component_Present := True;
                     Component_Present := True;
 
 
                     --  If a component has an initialization expression then
                     --  If a component has an initialization expression then
                     --  the enclosing record type is partially initialized
                     --  the enclosing record type is partially initialized
 
 
                     if Present (Parent (Ent))
                     if Present (Parent (Ent))
                       and then Present (Expression (Parent (Ent)))
                       and then Present (Expression (Parent (Ent)))
                     then
                     then
                        return True;
                        return True;
 
 
                     --  If a component is of a type which is itself partially
                     --  If a component is of a type which is itself partially
                     --  initialized, then the enclosing record type is also.
                     --  initialized, then the enclosing record type is also.
 
 
                     elsif Is_Partially_Initialized_Type (Etype (Ent)) then
                     elsif Is_Partially_Initialized_Type (Etype (Ent)) then
                        return True;
                        return True;
                     end if;
                     end if;
                  end if;
                  end if;
 
 
                  Next_Entity (Ent);
                  Next_Entity (Ent);
               end loop;
               end loop;
 
 
               --  No initialized components found. If we found any components
               --  No initialized components found. If we found any components
               --  they were all uninitialized so the result is false.
               --  they were all uninitialized so the result is false.
 
 
               if Component_Present then
               if Component_Present then
                  return False;
                  return False;
 
 
               --  But if we found no components, then all the components are
               --  But if we found no components, then all the components are
               --  initialized so we consider the type to be initialized.
               --  initialized so we consider the type to be initialized.
 
 
               else
               else
                  return True;
                  return True;
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
      --  Concurrent types are always fully initialized
      --  Concurrent types are always fully initialized
 
 
      elsif Is_Concurrent_Type (Typ) then
      elsif Is_Concurrent_Type (Typ) then
         return True;
         return True;
 
 
      --  For a private type, go to underlying type. If there is no underlying
      --  For a private type, go to underlying type. If there is no underlying
      --  type then just assume this partially initialized. Not clear if this
      --  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.
      --  can happen in a non-error case, but no harm in testing for this.
 
 
      elsif Is_Private_Type (Typ) then
      elsif Is_Private_Type (Typ) then
         declare
         declare
            U : constant Entity_Id := Underlying_Type (Typ);
            U : constant Entity_Id := Underlying_Type (Typ);
         begin
         begin
            if No (U) then
            if No (U) then
               return True;
               return True;
            else
            else
               return Is_Partially_Initialized_Type (U);
               return Is_Partially_Initialized_Type (U);
            end if;
            end if;
         end;
         end;
 
 
      --  For any other type (are there any?) assume partially initialized
      --  For any other type (are there any?) assume partially initialized
 
 
      else
      else
         return True;
         return True;
      end if;
      end if;
   end Is_Partially_Initialized_Type;
   end Is_Partially_Initialized_Type;
 
 
   ------------------------------------
   ------------------------------------
   -- Is_Potentially_Persistent_Type --
   -- Is_Potentially_Persistent_Type --
   ------------------------------------
   ------------------------------------
 
 
   function Is_Potentially_Persistent_Type (T : Entity_Id) return Boolean is
   function Is_Potentially_Persistent_Type (T : Entity_Id) return Boolean is
      Comp : Entity_Id;
      Comp : Entity_Id;
      Indx : Node_Id;
      Indx : Node_Id;
 
 
   begin
   begin
      --  For private type, test corresponding full type
      --  For private type, test corresponding full type
 
 
      if Is_Private_Type (T) then
      if Is_Private_Type (T) then
         return Is_Potentially_Persistent_Type (Full_View (T));
         return Is_Potentially_Persistent_Type (Full_View (T));
 
 
      --  Scalar types are potentially persistent
      --  Scalar types are potentially persistent
 
 
      elsif Is_Scalar_Type (T) then
      elsif Is_Scalar_Type (T) then
         return True;
         return True;
 
 
      --  Record type is potentially persistent if not tagged and the types of
      --  Record type is potentially persistent if not tagged and the types of
      --  all it components are potentially persistent, and no component has
      --  all it components are potentially persistent, and no component has
      --  an initialization expression.
      --  an initialization expression.
 
 
      elsif Is_Record_Type (T)
      elsif Is_Record_Type (T)
        and then not Is_Tagged_Type (T)
        and then not Is_Tagged_Type (T)
        and then not Is_Partially_Initialized_Type (T)
        and then not Is_Partially_Initialized_Type (T)
      then
      then
         Comp := First_Component (T);
         Comp := First_Component (T);
         while Present (Comp) loop
         while Present (Comp) loop
            if not Is_Potentially_Persistent_Type (Etype (Comp)) then
            if not Is_Potentially_Persistent_Type (Etype (Comp)) then
               return False;
               return False;
            else
            else
               Next_Entity (Comp);
               Next_Entity (Comp);
            end if;
            end if;
         end loop;
         end loop;
 
 
         return True;
         return True;
 
 
      --  Array type is potentially persistent if its component type is
      --  Array type is potentially persistent if its component type is
      --  potentially persistent and if all its constraints are static.
      --  potentially persistent and if all its constraints are static.
 
 
      elsif Is_Array_Type (T) then
      elsif Is_Array_Type (T) then
         if not Is_Potentially_Persistent_Type (Component_Type (T)) then
         if not Is_Potentially_Persistent_Type (Component_Type (T)) then
            return False;
            return False;
         end if;
         end if;
 
 
         Indx := First_Index (T);
         Indx := First_Index (T);
         while Present (Indx) loop
         while Present (Indx) loop
            if not Is_OK_Static_Subtype (Etype (Indx)) then
            if not Is_OK_Static_Subtype (Etype (Indx)) then
               return False;
               return False;
            else
            else
               Next_Index (Indx);
               Next_Index (Indx);
            end if;
            end if;
         end loop;
         end loop;
 
 
         return True;
         return True;
 
 
      --  All other types are not potentially persistent
      --  All other types are not potentially persistent
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Potentially_Persistent_Type;
   end Is_Potentially_Persistent_Type;
 
 
   ---------------------------------
   ---------------------------------
   -- Is_Protected_Self_Reference --
   -- Is_Protected_Self_Reference --
   ---------------------------------
   ---------------------------------
 
 
   function Is_Protected_Self_Reference (N : Node_Id) return Boolean is
   function Is_Protected_Self_Reference (N : Node_Id) return Boolean is
 
 
      function In_Access_Definition (N : Node_Id) return Boolean;
      function In_Access_Definition (N : Node_Id) return Boolean;
      --  Returns true if N belongs to an access definition
      --  Returns true if N belongs to an access definition
 
 
      --------------------------
      --------------------------
      -- In_Access_Definition --
      -- In_Access_Definition --
      --------------------------
      --------------------------
 
 
      function In_Access_Definition (N : Node_Id) return Boolean is
      function In_Access_Definition (N : Node_Id) return Boolean is
         P : Node_Id;
         P : Node_Id;
 
 
      begin
      begin
         P := Parent (N);
         P := Parent (N);
         while Present (P) loop
         while Present (P) loop
            if Nkind (P) = N_Access_Definition then
            if Nkind (P) = N_Access_Definition then
               return True;
               return True;
            end if;
            end if;
 
 
            P := Parent (P);
            P := Parent (P);
         end loop;
         end loop;
 
 
         return False;
         return False;
      end In_Access_Definition;
      end In_Access_Definition;
 
 
   --  Start of processing for Is_Protected_Self_Reference
   --  Start of processing for Is_Protected_Self_Reference
 
 
   begin
   begin
      --  Verify that prefix is analyzed and has the proper form. Note that
      --  Verify that prefix is analyzed and has the proper form. Note that
      --  the attributes Elab_Spec, Elab_Body, and UET_Address, which also
      --  the attributes Elab_Spec, Elab_Body, and UET_Address, which also
      --  produce the address of an entity, do not analyze their prefix
      --  produce the address of an entity, do not analyze their prefix
      --  because they denote entities that are not necessarily visible.
      --  because they denote entities that are not necessarily visible.
      --  Neither of them can apply to a protected type.
      --  Neither of them can apply to a protected type.
 
 
      return Ada_Version >= Ada_05
      return Ada_Version >= Ada_05
        and then Is_Entity_Name (N)
        and then Is_Entity_Name (N)
        and then Present (Entity (N))
        and then Present (Entity (N))
        and then Is_Protected_Type (Entity (N))
        and then Is_Protected_Type (Entity (N))
        and then In_Open_Scopes (Entity (N))
        and then In_Open_Scopes (Entity (N))
        and then not In_Access_Definition (N);
        and then not In_Access_Definition (N);
   end Is_Protected_Self_Reference;
   end Is_Protected_Self_Reference;
 
 
   -----------------------------
   -----------------------------
   -- Is_RCI_Pkg_Spec_Or_Body --
   -- Is_RCI_Pkg_Spec_Or_Body --
   -----------------------------
   -----------------------------
 
 
   function Is_RCI_Pkg_Spec_Or_Body (Cunit : Node_Id) return Boolean is
   function Is_RCI_Pkg_Spec_Or_Body (Cunit : Node_Id) return Boolean is
 
 
      function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean;
      function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean;
      --  Return True if the unit of Cunit is an RCI package declaration
      --  Return True if the unit of Cunit is an RCI package declaration
 
 
      ---------------------------
      ---------------------------
      -- Is_RCI_Pkg_Decl_Cunit --
      -- Is_RCI_Pkg_Decl_Cunit --
      ---------------------------
      ---------------------------
 
 
      function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean is
      function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean is
         The_Unit : constant Node_Id := Unit (Cunit);
         The_Unit : constant Node_Id := Unit (Cunit);
 
 
      begin
      begin
         if Nkind (The_Unit) /= N_Package_Declaration then
         if Nkind (The_Unit) /= N_Package_Declaration then
            return False;
            return False;
         end if;
         end if;
 
 
         return Is_Remote_Call_Interface (Defining_Entity (The_Unit));
         return Is_Remote_Call_Interface (Defining_Entity (The_Unit));
      end Is_RCI_Pkg_Decl_Cunit;
      end Is_RCI_Pkg_Decl_Cunit;
 
 
   --  Start of processing for Is_RCI_Pkg_Spec_Or_Body
   --  Start of processing for Is_RCI_Pkg_Spec_Or_Body
 
 
   begin
   begin
      return Is_RCI_Pkg_Decl_Cunit (Cunit)
      return Is_RCI_Pkg_Decl_Cunit (Cunit)
        or else
        or else
         (Nkind (Unit (Cunit)) = N_Package_Body
         (Nkind (Unit (Cunit)) = N_Package_Body
           and then Is_RCI_Pkg_Decl_Cunit (Library_Unit (Cunit)));
           and then Is_RCI_Pkg_Decl_Cunit (Library_Unit (Cunit)));
   end Is_RCI_Pkg_Spec_Or_Body;
   end Is_RCI_Pkg_Spec_Or_Body;
 
 
   -----------------------------------------
   -----------------------------------------
   -- Is_Remote_Access_To_Class_Wide_Type --
   -- Is_Remote_Access_To_Class_Wide_Type --
   -----------------------------------------
   -----------------------------------------
 
 
   function Is_Remote_Access_To_Class_Wide_Type
   function Is_Remote_Access_To_Class_Wide_Type
     (E : Entity_Id) return Boolean
     (E : Entity_Id) return Boolean
   is
   is
   begin
   begin
      --  A remote access to class-wide type is a general access to object type
      --  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_
      --  declared in the visible part of a Remote_Types or Remote_Call_
      --  Interface unit.
      --  Interface unit.
 
 
      return Ekind (E) = E_General_Access_Type
      return Ekind (E) = E_General_Access_Type
        and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E));
        and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E));
   end Is_Remote_Access_To_Class_Wide_Type;
   end Is_Remote_Access_To_Class_Wide_Type;
 
 
   -----------------------------------------
   -----------------------------------------
   -- Is_Remote_Access_To_Subprogram_Type --
   -- Is_Remote_Access_To_Subprogram_Type --
   -----------------------------------------
   -----------------------------------------
 
 
   function Is_Remote_Access_To_Subprogram_Type
   function Is_Remote_Access_To_Subprogram_Type
     (E : Entity_Id) return Boolean
     (E : Entity_Id) return Boolean
   is
   is
   begin
   begin
      return (Ekind (E) = E_Access_Subprogram_Type
      return (Ekind (E) = E_Access_Subprogram_Type
                or else (Ekind (E) = E_Record_Type
                or else (Ekind (E) = E_Record_Type
                           and then Present (Corresponding_Remote_Type (E))))
                           and then Present (Corresponding_Remote_Type (E))))
        and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E));
        and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E));
   end Is_Remote_Access_To_Subprogram_Type;
   end Is_Remote_Access_To_Subprogram_Type;
 
 
   --------------------
   --------------------
   -- Is_Remote_Call --
   -- Is_Remote_Call --
   --------------------
   --------------------
 
 
   function Is_Remote_Call (N : Node_Id) return Boolean is
   function Is_Remote_Call (N : Node_Id) return Boolean is
   begin
   begin
      if Nkind (N) /= N_Procedure_Call_Statement
      if Nkind (N) /= N_Procedure_Call_Statement
        and then Nkind (N) /= N_Function_Call
        and then Nkind (N) /= N_Function_Call
      then
      then
         --  An entry call cannot be remote
         --  An entry call cannot be remote
 
 
         return False;
         return False;
 
 
      elsif Nkind (Name (N)) in N_Has_Entity
      elsif Nkind (Name (N)) in N_Has_Entity
        and then Is_Remote_Call_Interface (Entity (Name (N)))
        and then Is_Remote_Call_Interface (Entity (Name (N)))
      then
      then
         --  A subprogram declared in the spec of a RCI package is remote
         --  A subprogram declared in the spec of a RCI package is remote
 
 
         return True;
         return True;
 
 
      elsif Nkind (Name (N)) = N_Explicit_Dereference
      elsif Nkind (Name (N)) = N_Explicit_Dereference
        and then Is_Remote_Access_To_Subprogram_Type
        and then Is_Remote_Access_To_Subprogram_Type
                   (Etype (Prefix (Name (N))))
                   (Etype (Prefix (Name (N))))
      then
      then
         --  The dereference of a RAS is a remote call
         --  The dereference of a RAS is a remote call
 
 
         return True;
         return True;
 
 
      elsif Present (Controlling_Argument (N))
      elsif Present (Controlling_Argument (N))
        and then Is_Remote_Access_To_Class_Wide_Type
        and then Is_Remote_Access_To_Class_Wide_Type
          (Etype (Controlling_Argument (N)))
          (Etype (Controlling_Argument (N)))
      then
      then
         --  Any primitive operation call with a controlling argument of
         --  Any primitive operation call with a controlling argument of
         --  a RACW type is a remote call.
         --  a RACW type is a remote call.
 
 
         return True;
         return True;
      end if;
      end if;
 
 
      --  All other calls are local calls
      --  All other calls are local calls
 
 
      return False;
      return False;
   end Is_Remote_Call;
   end Is_Remote_Call;
 
 
   ----------------------
   ----------------------
   -- Is_Renamed_Entry --
   -- Is_Renamed_Entry --
   ----------------------
   ----------------------
 
 
   function Is_Renamed_Entry (Proc_Nam : Entity_Id) return Boolean is
   function Is_Renamed_Entry (Proc_Nam : Entity_Id) return Boolean is
      Orig_Node : Node_Id := Empty;
      Orig_Node : Node_Id := Empty;
      Subp_Decl : Node_Id := Parent (Parent (Proc_Nam));
      Subp_Decl : Node_Id := Parent (Parent (Proc_Nam));
 
 
      function Is_Entry (Nam : Node_Id) return Boolean;
      function Is_Entry (Nam : Node_Id) return Boolean;
      --  Determine whether Nam is an entry. Traverse selectors if there are
      --  Determine whether Nam is an entry. Traverse selectors if there are
      --  nested selected components.
      --  nested selected components.
 
 
      --------------
      --------------
      -- Is_Entry --
      -- Is_Entry --
      --------------
      --------------
 
 
      function Is_Entry (Nam : Node_Id) return Boolean is
      function Is_Entry (Nam : Node_Id) return Boolean is
      begin
      begin
         if Nkind (Nam) = N_Selected_Component then
         if Nkind (Nam) = N_Selected_Component then
            return Is_Entry (Selector_Name (Nam));
            return Is_Entry (Selector_Name (Nam));
         end if;
         end if;
 
 
         return Ekind (Entity (Nam)) = E_Entry;
         return Ekind (Entity (Nam)) = E_Entry;
      end Is_Entry;
      end Is_Entry;
 
 
   --  Start of processing for Is_Renamed_Entry
   --  Start of processing for Is_Renamed_Entry
 
 
   begin
   begin
      if Present (Alias (Proc_Nam)) then
      if Present (Alias (Proc_Nam)) then
         Subp_Decl := Parent (Parent (Alias (Proc_Nam)));
         Subp_Decl := Parent (Parent (Alias (Proc_Nam)));
      end if;
      end if;
 
 
      --  Look for a rewritten subprogram renaming declaration
      --  Look for a rewritten subprogram renaming declaration
 
 
      if Nkind (Subp_Decl) = N_Subprogram_Declaration
      if Nkind (Subp_Decl) = N_Subprogram_Declaration
        and then Present (Original_Node (Subp_Decl))
        and then Present (Original_Node (Subp_Decl))
      then
      then
         Orig_Node := Original_Node (Subp_Decl);
         Orig_Node := Original_Node (Subp_Decl);
      end if;
      end if;
 
 
      --  The rewritten subprogram is actually an entry
      --  The rewritten subprogram is actually an entry
 
 
      if Present (Orig_Node)
      if Present (Orig_Node)
        and then Nkind (Orig_Node) = N_Subprogram_Renaming_Declaration
        and then Nkind (Orig_Node) = N_Subprogram_Renaming_Declaration
        and then Is_Entry (Name (Orig_Node))
        and then Is_Entry (Name (Orig_Node))
      then
      then
         return True;
         return True;
      end if;
      end if;
 
 
      return False;
      return False;
   end Is_Renamed_Entry;
   end Is_Renamed_Entry;
 
 
   ----------------------
   ----------------------
   -- Is_Selector_Name --
   -- Is_Selector_Name --
   ----------------------
   ----------------------
 
 
   function Is_Selector_Name (N : Node_Id) return Boolean is
   function Is_Selector_Name (N : Node_Id) return Boolean is
   begin
   begin
      if not Is_List_Member (N) then
      if not Is_List_Member (N) then
         declare
         declare
            P : constant Node_Id   := Parent (N);
            P : constant Node_Id   := Parent (N);
            K : constant Node_Kind := Nkind (P);
            K : constant Node_Kind := Nkind (P);
         begin
         begin
            return
            return
              (K = N_Expanded_Name          or else
              (K = N_Expanded_Name          or else
               K = N_Generic_Association    or else
               K = N_Generic_Association    or else
               K = N_Parameter_Association  or else
               K = N_Parameter_Association  or else
               K = N_Selected_Component)
               K = N_Selected_Component)
              and then Selector_Name (P) = N;
              and then Selector_Name (P) = N;
         end;
         end;
 
 
      else
      else
         declare
         declare
            L : constant List_Id := List_Containing (N);
            L : constant List_Id := List_Containing (N);
            P : constant Node_Id := Parent (L);
            P : constant Node_Id := Parent (L);
         begin
         begin
            return (Nkind (P) = N_Discriminant_Association
            return (Nkind (P) = N_Discriminant_Association
                     and then Selector_Names (P) = L)
                     and then Selector_Names (P) = L)
              or else
              or else
                   (Nkind (P) = N_Component_Association
                   (Nkind (P) = N_Component_Association
                     and then Choices (P) = L);
                     and then Choices (P) = L);
         end;
         end;
      end if;
      end if;
   end Is_Selector_Name;
   end Is_Selector_Name;
 
 
   ------------------
   ------------------
   -- Is_Statement --
   -- Is_Statement --
   ------------------
   ------------------
 
 
   function Is_Statement (N : Node_Id) return Boolean is
   function Is_Statement (N : Node_Id) return Boolean is
   begin
   begin
      return
      return
        Nkind (N) in N_Statement_Other_Than_Procedure_Call
        Nkind (N) in N_Statement_Other_Than_Procedure_Call
          or else Nkind (N) = N_Procedure_Call_Statement;
          or else Nkind (N) = N_Procedure_Call_Statement;
   end Is_Statement;
   end Is_Statement;
 
 
   ---------------------------------
   ---------------------------------
   -- Is_Synchronized_Tagged_Type --
   -- Is_Synchronized_Tagged_Type --
   ---------------------------------
   ---------------------------------
 
 
   function Is_Synchronized_Tagged_Type (E : Entity_Id) return Boolean is
   function Is_Synchronized_Tagged_Type (E : Entity_Id) return Boolean is
      Kind : constant Entity_Kind := Ekind (Base_Type (E));
      Kind : constant Entity_Kind := Ekind (Base_Type (E));
 
 
   begin
   begin
      --  A task or protected type derived from an interface is a tagged type.
      --  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
      --  Such a tagged type is called a synchronized tagged type, as are
      --  synchronized interfaces and private extensions whose declaration
      --  synchronized interfaces and private extensions whose declaration
      --  includes the reserved word synchronized.
      --  includes the reserved word synchronized.
 
 
      return (Is_Tagged_Type (E)
      return (Is_Tagged_Type (E)
                and then (Kind = E_Task_Type
                and then (Kind = E_Task_Type
                           or else Kind = E_Protected_Type))
                           or else Kind = E_Protected_Type))
            or else
            or else
             (Is_Interface (E)
             (Is_Interface (E)
                and then Is_Synchronized_Interface (E))
                and then Is_Synchronized_Interface (E))
            or else
            or else
             (Ekind (E) = E_Record_Type_With_Private
             (Ekind (E) = E_Record_Type_With_Private
                and then (Synchronized_Present (Parent (E))
                and then (Synchronized_Present (Parent (E))
                           or else Is_Synchronized_Interface (Etype (E))));
                           or else Is_Synchronized_Interface (Etype (E))));
   end Is_Synchronized_Tagged_Type;
   end Is_Synchronized_Tagged_Type;
 
 
   -----------------
   -----------------
   -- Is_Transfer --
   -- Is_Transfer --
   -----------------
   -----------------
 
 
   function Is_Transfer (N : Node_Id) return Boolean is
   function Is_Transfer (N : Node_Id) return Boolean is
      Kind : constant Node_Kind := Nkind (N);
      Kind : constant Node_Kind := Nkind (N);
 
 
   begin
   begin
      if Kind = N_Simple_Return_Statement
      if Kind = N_Simple_Return_Statement
           or else
           or else
         Kind = N_Extended_Return_Statement
         Kind = N_Extended_Return_Statement
           or else
           or else
         Kind = N_Goto_Statement
         Kind = N_Goto_Statement
           or else
           or else
         Kind = N_Raise_Statement
         Kind = N_Raise_Statement
           or else
           or else
         Kind = N_Requeue_Statement
         Kind = N_Requeue_Statement
      then
      then
         return True;
         return True;
 
 
      elsif (Kind = N_Exit_Statement or else Kind in N_Raise_xxx_Error)
      elsif (Kind = N_Exit_Statement or else Kind in N_Raise_xxx_Error)
        and then No (Condition (N))
        and then No (Condition (N))
      then
      then
         return True;
         return True;
 
 
      elsif Kind = N_Procedure_Call_Statement
      elsif Kind = N_Procedure_Call_Statement
        and then Is_Entity_Name (Name (N))
        and then Is_Entity_Name (Name (N))
        and then Present (Entity (Name (N)))
        and then Present (Entity (Name (N)))
        and then No_Return (Entity (Name (N)))
        and then No_Return (Entity (Name (N)))
      then
      then
         return True;
         return True;
 
 
      elsif Nkind (Original_Node (N)) = N_Raise_Statement then
      elsif Nkind (Original_Node (N)) = N_Raise_Statement then
         return True;
         return True;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Transfer;
   end Is_Transfer;
 
 
   -------------
   -------------
   -- Is_True --
   -- Is_True --
   -------------
   -------------
 
 
   function Is_True (U : Uint) return Boolean is
   function Is_True (U : Uint) return Boolean is
   begin
   begin
      return (U /= 0);
      return (U /= 0);
   end Is_True;
   end Is_True;
 
 
   -------------------
   -------------------
   -- Is_Value_Type --
   -- Is_Value_Type --
   -------------------
   -------------------
 
 
   function Is_Value_Type (T : Entity_Id) return Boolean is
   function Is_Value_Type (T : Entity_Id) return Boolean is
   begin
   begin
      return VM_Target = CLI_Target
      return VM_Target = CLI_Target
        and then Nkind (T) in N_Has_Chars
        and then Nkind (T) in N_Has_Chars
        and then Chars (T) /= No_Name
        and then Chars (T) /= No_Name
        and then Get_Name_String (Chars (T)) = "valuetype";
        and then Get_Name_String (Chars (T)) = "valuetype";
   end Is_Value_Type;
   end Is_Value_Type;
 
 
   -----------------
   -----------------
   -- Is_Delegate --
   -- Is_Delegate --
   -----------------
   -----------------
 
 
   function Is_Delegate (T : Entity_Id) return Boolean is
   function Is_Delegate (T : Entity_Id) return Boolean is
      Desig_Type : Entity_Id;
      Desig_Type : Entity_Id;
 
 
   begin
   begin
      if VM_Target /= CLI_Target then
      if VM_Target /= CLI_Target then
         return False;
         return False;
      end if;
      end if;
 
 
      --  Access-to-subprograms are delegates in CIL
      --  Access-to-subprograms are delegates in CIL
 
 
      if Ekind (T) = E_Access_Subprogram_Type then
      if Ekind (T) = E_Access_Subprogram_Type then
         return True;
         return True;
      end if;
      end if;
 
 
      if Ekind (T) not in Access_Kind then
      if Ekind (T) not in Access_Kind then
 
 
         --  A delegate is a managed pointer. If no designated type is defined
         --  A delegate is a managed pointer. If no designated type is defined
         --  it means that it's not a delegate.
         --  it means that it's not a delegate.
 
 
         return False;
         return False;
      end if;
      end if;
 
 
      Desig_Type := Etype (Directly_Designated_Type (T));
      Desig_Type := Etype (Directly_Designated_Type (T));
 
 
      if not Is_Tagged_Type (Desig_Type) then
      if not Is_Tagged_Type (Desig_Type) then
         return False;
         return False;
      end if;
      end if;
 
 
      --  Test if the type is inherited from [mscorlib]System.Delegate
      --  Test if the type is inherited from [mscorlib]System.Delegate
 
 
      while Etype (Desig_Type) /= Desig_Type loop
      while Etype (Desig_Type) /= Desig_Type loop
         if Chars (Scope (Desig_Type)) /= No_Name
         if Chars (Scope (Desig_Type)) /= No_Name
           and then Is_Imported (Scope (Desig_Type))
           and then Is_Imported (Scope (Desig_Type))
           and then Get_Name_String (Chars (Scope (Desig_Type))) = "delegate"
           and then Get_Name_String (Chars (Scope (Desig_Type))) = "delegate"
         then
         then
            return True;
            return True;
         end if;
         end if;
 
 
         Desig_Type := Etype (Desig_Type);
         Desig_Type := Etype (Desig_Type);
      end loop;
      end loop;
 
 
      return False;
      return False;
   end Is_Delegate;
   end Is_Delegate;
 
 
   -----------------
   -----------------
   -- Is_Variable --
   -- Is_Variable --
   -----------------
   -----------------
 
 
   function Is_Variable (N : Node_Id) return Boolean is
   function Is_Variable (N : Node_Id) return Boolean is
 
 
      Orig_Node : constant Node_Id := Original_Node (N);
      Orig_Node : constant Node_Id := Original_Node (N);
      --  We do the test on the original node, since this is basically a test
      --  We do the test on the original node, since this is basically a test
      --  of syntactic categories, so it must not be disturbed by whatever
      --  of syntactic categories, so it must not be disturbed by whatever
      --  rewriting might have occurred. For example, an aggregate, which is
      --  rewriting might have occurred. For example, an aggregate, which is
      --  certainly NOT a variable, could be turned into a variable by
      --  certainly NOT a variable, could be turned into a variable by
      --  expansion.
      --  expansion.
 
 
      function In_Protected_Function (E : Entity_Id) return Boolean;
      function In_Protected_Function (E : Entity_Id) return Boolean;
      --  Within a protected function, the private components of the
      --  Within a protected function, the private components of the
      --  enclosing protected type are constants. A function nested within
      --  enclosing protected type are constants. A function nested within
      --  a (protected) procedure is not itself protected.
      --  a (protected) procedure is not itself protected.
 
 
      function Is_Variable_Prefix (P : Node_Id) return Boolean;
      function Is_Variable_Prefix (P : Node_Id) return Boolean;
      --  Prefixes can involve implicit dereferences, in which case we
      --  Prefixes can involve implicit dereferences, in which case we
      --  must test for the case of a reference of a constant access
      --  must test for the case of a reference of a constant access
      --  type, which can never be a variable.
      --  type, which can never be a variable.
 
 
      ---------------------------
      ---------------------------
      -- In_Protected_Function --
      -- In_Protected_Function --
      ---------------------------
      ---------------------------
 
 
      function In_Protected_Function (E : Entity_Id) return Boolean is
      function In_Protected_Function (E : Entity_Id) return Boolean is
         Prot : constant Entity_Id := Scope (E);
         Prot : constant Entity_Id := Scope (E);
         S    : Entity_Id;
         S    : Entity_Id;
 
 
      begin
      begin
         if not Is_Protected_Type (Prot) then
         if not Is_Protected_Type (Prot) then
            return False;
            return False;
         else
         else
            S := Current_Scope;
            S := Current_Scope;
            while Present (S) and then S /= Prot loop
            while Present (S) and then S /= Prot loop
               if Ekind (S) = E_Function
               if Ekind (S) = E_Function
                 and then Scope (S) = Prot
                 and then Scope (S) = Prot
               then
               then
                  return True;
                  return True;
               end if;
               end if;
 
 
               S := Scope (S);
               S := Scope (S);
            end loop;
            end loop;
 
 
            return False;
            return False;
         end if;
         end if;
      end In_Protected_Function;
      end In_Protected_Function;
 
 
      ------------------------
      ------------------------
      -- Is_Variable_Prefix --
      -- Is_Variable_Prefix --
      ------------------------
      ------------------------
 
 
      function Is_Variable_Prefix (P : Node_Id) return Boolean is
      function Is_Variable_Prefix (P : Node_Id) return Boolean is
      begin
      begin
         if Is_Access_Type (Etype (P)) then
         if Is_Access_Type (Etype (P)) then
            return not Is_Access_Constant (Root_Type (Etype (P)));
            return not Is_Access_Constant (Root_Type (Etype (P)));
 
 
         --  For the case of an indexed component whose prefix has a packed
         --  For the case of an indexed component whose prefix has a packed
         --  array type, the prefix has been rewritten into a type conversion.
         --  array type, the prefix has been rewritten into a type conversion.
         --  Determine variable-ness from the converted expression.
         --  Determine variable-ness from the converted expression.
 
 
         elsif Nkind (P) = N_Type_Conversion
         elsif Nkind (P) = N_Type_Conversion
           and then not Comes_From_Source (P)
           and then not Comes_From_Source (P)
           and then Is_Array_Type (Etype (P))
           and then Is_Array_Type (Etype (P))
           and then Is_Packed (Etype (P))
           and then Is_Packed (Etype (P))
         then
         then
            return Is_Variable (Expression (P));
            return Is_Variable (Expression (P));
 
 
         else
         else
            return Is_Variable (P);
            return Is_Variable (P);
         end if;
         end if;
      end Is_Variable_Prefix;
      end Is_Variable_Prefix;
 
 
   --  Start of processing for Is_Variable
   --  Start of processing for Is_Variable
 
 
   begin
   begin
      --  Definitely OK if Assignment_OK is set. Since this is something that
      --  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.
      --  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
      if Nkind (N) in N_Subexpr and then Assignment_OK (N) then
         return True;
         return True;
 
 
      --  Normally we go to the original node, but there is one exception
      --  Normally we go to the original node, but there is one exception
      --  where we use the rewritten node, namely when it is an explicit
      --  where we use the rewritten node, namely when it is an explicit
      --  dereference. The generated code may rewrite a prefix which is an
      --  dereference. The generated code may rewrite a prefix which is an
      --  access type with an explicit dereference. The dereference is a
      --  access type with an explicit dereference. The dereference is a
      --  variable, even though the original node may not be (since it could
      --  variable, even though the original node may not be (since it could
      --  be a constant of the access type).
      --  be a constant of the access type).
 
 
      --  In Ada 2005 we have a further case to consider: the prefix may be
      --  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
      --  a function call given in prefix notation. The original node appears
      --  to be a selected component, but we need to examine the call.
      --  to be a selected component, but we need to examine the call.
 
 
      elsif Nkind (N) = N_Explicit_Dereference
      elsif Nkind (N) = N_Explicit_Dereference
        and then Nkind (Orig_Node) /= N_Explicit_Dereference
        and then Nkind (Orig_Node) /= N_Explicit_Dereference
        and then Present (Etype (Orig_Node))
        and then Present (Etype (Orig_Node))
        and then Is_Access_Type (Etype (Orig_Node))
        and then Is_Access_Type (Etype (Orig_Node))
      then
      then
         --  Note that if the prefix is an explicit dereference that does not
         --  Note that if the prefix is an explicit dereference that does not
         --  come from source, we must check for a rewritten function call in
         --  come from source, we must check for a rewritten function call in
         --  prefixed notation before other forms of rewriting, to prevent a
         --  prefixed notation before other forms of rewriting, to prevent a
         --  compiler crash.
         --  compiler crash.
 
 
         return
         return
           (Nkind (Orig_Node) = N_Function_Call
           (Nkind (Orig_Node) = N_Function_Call
             and then not Is_Access_Constant (Etype (Prefix (N))))
             and then not Is_Access_Constant (Etype (Prefix (N))))
           or else
           or else
             Is_Variable_Prefix (Original_Node (Prefix (N)));
             Is_Variable_Prefix (Original_Node (Prefix (N)));
 
 
      --  A function call is never a variable
      --  A function call is never a variable
 
 
      elsif Nkind (N) = N_Function_Call then
      elsif Nkind (N) = N_Function_Call then
         return False;
         return False;
 
 
      --  All remaining checks use the original node
      --  All remaining checks use the original node
 
 
      elsif Is_Entity_Name (Orig_Node)
      elsif Is_Entity_Name (Orig_Node)
        and then Present (Entity (Orig_Node))
        and then Present (Entity (Orig_Node))
      then
      then
         declare
         declare
            E : constant Entity_Id := Entity (Orig_Node);
            E : constant Entity_Id := Entity (Orig_Node);
            K : constant Entity_Kind := Ekind (E);
            K : constant Entity_Kind := Ekind (E);
 
 
         begin
         begin
            return (K = E_Variable
            return (K = E_Variable
                      and then Nkind (Parent (E)) /= N_Exception_Handler)
                      and then Nkind (Parent (E)) /= N_Exception_Handler)
              or else  (K = E_Component
              or else  (K = E_Component
                          and then not In_Protected_Function (E))
                          and then not In_Protected_Function (E))
              or else  K = E_Out_Parameter
              or else  K = E_Out_Parameter
              or else  K = E_In_Out_Parameter
              or else  K = E_In_Out_Parameter
              or else  K = E_Generic_In_Out_Parameter
              or else  K = E_Generic_In_Out_Parameter
 
 
               --  Current instance of type:
               --  Current instance of type:
 
 
              or else (Is_Type (E) and then In_Open_Scopes (E))
              or else (Is_Type (E) and then In_Open_Scopes (E))
              or else (Is_Incomplete_Or_Private_Type (E)
              or else (Is_Incomplete_Or_Private_Type (E)
                        and then In_Open_Scopes (Full_View (E)));
                        and then In_Open_Scopes (Full_View (E)));
         end;
         end;
 
 
      else
      else
         case Nkind (Orig_Node) is
         case Nkind (Orig_Node) is
            when N_Indexed_Component | N_Slice =>
            when N_Indexed_Component | N_Slice =>
               return Is_Variable_Prefix (Prefix (Orig_Node));
               return Is_Variable_Prefix (Prefix (Orig_Node));
 
 
            when N_Selected_Component =>
            when N_Selected_Component =>
               return Is_Variable_Prefix (Prefix (Orig_Node))
               return Is_Variable_Prefix (Prefix (Orig_Node))
                 and then Is_Variable (Selector_Name (Orig_Node));
                 and then Is_Variable (Selector_Name (Orig_Node));
 
 
            --  For an explicit dereference, the type of the prefix cannot
            --  For an explicit dereference, the type of the prefix cannot
            --  be an access to constant or an access to subprogram.
            --  be an access to constant or an access to subprogram.
 
 
            when N_Explicit_Dereference =>
            when N_Explicit_Dereference =>
               declare
               declare
                  Typ : constant Entity_Id := Etype (Prefix (Orig_Node));
                  Typ : constant Entity_Id := Etype (Prefix (Orig_Node));
               begin
               begin
                  return Is_Access_Type (Typ)
                  return Is_Access_Type (Typ)
                    and then not Is_Access_Constant (Root_Type (Typ))
                    and then not Is_Access_Constant (Root_Type (Typ))
                    and then Ekind (Typ) /= E_Access_Subprogram_Type;
                    and then Ekind (Typ) /= E_Access_Subprogram_Type;
               end;
               end;
 
 
            --  The type conversion is the case where we do not deal with the
            --  The type conversion is the case where we do not deal with the
            --  context dependent special case of an actual parameter. Thus
            --  context dependent special case of an actual parameter. Thus
            --  the type conversion is only considered a variable for the
            --  the type conversion is only considered a variable for the
            --  purposes of this routine if the target type is tagged. However,
            --  purposes of this routine if the target type is tagged. However,
            --  a type conversion is considered to be a variable if it does not
            --  a type conversion is considered to be a variable if it does not
            --  come from source (this deals for example with the conversions
            --  come from source (this deals for example with the conversions
            --  of expressions to their actual subtypes).
            --  of expressions to their actual subtypes).
 
 
            when N_Type_Conversion =>
            when N_Type_Conversion =>
               return Is_Variable (Expression (Orig_Node))
               return Is_Variable (Expression (Orig_Node))
                 and then
                 and then
                   (not Comes_From_Source (Orig_Node)
                   (not Comes_From_Source (Orig_Node)
                      or else
                      or else
                        (Is_Tagged_Type (Etype (Subtype_Mark (Orig_Node)))
                        (Is_Tagged_Type (Etype (Subtype_Mark (Orig_Node)))
                          and then
                          and then
                         Is_Tagged_Type (Etype (Expression (Orig_Node)))));
                         Is_Tagged_Type (Etype (Expression (Orig_Node)))));
 
 
            --  GNAT allows an unchecked type conversion as a variable. This
            --  GNAT allows an unchecked type conversion as a variable. This
            --  only affects the generation of internal expanded code, since
            --  only affects the generation of internal expanded code, since
            --  calls to instantiations of Unchecked_Conversion are never
            --  calls to instantiations of Unchecked_Conversion are never
            --  considered variables (since they are function calls).
            --  considered variables (since they are function calls).
            --  This is also true for expression actions.
            --  This is also true for expression actions.
 
 
            when N_Unchecked_Type_Conversion =>
            when N_Unchecked_Type_Conversion =>
               return Is_Variable (Expression (Orig_Node));
               return Is_Variable (Expression (Orig_Node));
 
 
            when others =>
            when others =>
               return False;
               return False;
         end case;
         end case;
      end if;
      end if;
   end Is_Variable;
   end Is_Variable;
 
 
   ---------------------------
   ---------------------------
   -- Is_Visibly_Controlled --
   -- Is_Visibly_Controlled --
   ---------------------------
   ---------------------------
 
 
   function Is_Visibly_Controlled (T : Entity_Id) return Boolean is
   function Is_Visibly_Controlled (T : Entity_Id) return Boolean is
      Root : constant Entity_Id := Root_Type (T);
      Root : constant Entity_Id := Root_Type (T);
   begin
   begin
      return Chars (Scope (Root)) = Name_Finalization
      return Chars (Scope (Root)) = Name_Finalization
        and then Chars (Scope (Scope (Root))) = Name_Ada
        and then Chars (Scope (Scope (Root))) = Name_Ada
        and then Scope (Scope (Scope (Root))) = Standard_Standard;
        and then Scope (Scope (Scope (Root))) = Standard_Standard;
   end Is_Visibly_Controlled;
   end Is_Visibly_Controlled;
 
 
   ------------------------
   ------------------------
   -- Is_Volatile_Object --
   -- Is_Volatile_Object --
   ------------------------
   ------------------------
 
 
   function Is_Volatile_Object (N : Node_Id) return Boolean is
   function Is_Volatile_Object (N : Node_Id) return Boolean is
 
 
      function Object_Has_Volatile_Components (N : Node_Id) return Boolean;
      function Object_Has_Volatile_Components (N : Node_Id) return Boolean;
      --  Determines if given object has volatile components
      --  Determines if given object has volatile components
 
 
      function Is_Volatile_Prefix (N : Node_Id) return Boolean;
      function Is_Volatile_Prefix (N : Node_Id) return Boolean;
      --  If prefix is an implicit dereference, examine designated type
      --  If prefix is an implicit dereference, examine designated type
 
 
      ------------------------
      ------------------------
      -- Is_Volatile_Prefix --
      -- Is_Volatile_Prefix --
      ------------------------
      ------------------------
 
 
      function Is_Volatile_Prefix (N : Node_Id) return Boolean is
      function Is_Volatile_Prefix (N : Node_Id) return Boolean is
         Typ  : constant Entity_Id := Etype (N);
         Typ  : constant Entity_Id := Etype (N);
 
 
      begin
      begin
         if Is_Access_Type (Typ) then
         if Is_Access_Type (Typ) then
            declare
            declare
               Dtyp : constant Entity_Id := Designated_Type (Typ);
               Dtyp : constant Entity_Id := Designated_Type (Typ);
 
 
            begin
            begin
               return Is_Volatile (Dtyp)
               return Is_Volatile (Dtyp)
                 or else Has_Volatile_Components (Dtyp);
                 or else Has_Volatile_Components (Dtyp);
            end;
            end;
 
 
         else
         else
            return Object_Has_Volatile_Components (N);
            return Object_Has_Volatile_Components (N);
         end if;
         end if;
      end Is_Volatile_Prefix;
      end Is_Volatile_Prefix;
 
 
      ------------------------------------
      ------------------------------------
      -- Object_Has_Volatile_Components --
      -- Object_Has_Volatile_Components --
      ------------------------------------
      ------------------------------------
 
 
      function Object_Has_Volatile_Components (N : Node_Id) return Boolean is
      function Object_Has_Volatile_Components (N : Node_Id) return Boolean is
         Typ : constant Entity_Id := Etype (N);
         Typ : constant Entity_Id := Etype (N);
 
 
      begin
      begin
         if Is_Volatile (Typ)
         if Is_Volatile (Typ)
           or else Has_Volatile_Components (Typ)
           or else Has_Volatile_Components (Typ)
         then
         then
            return True;
            return True;
 
 
         elsif Is_Entity_Name (N)
         elsif Is_Entity_Name (N)
           and then (Has_Volatile_Components (Entity (N))
           and then (Has_Volatile_Components (Entity (N))
                      or else Is_Volatile (Entity (N)))
                      or else Is_Volatile (Entity (N)))
         then
         then
            return True;
            return True;
 
 
         elsif Nkind (N) = N_Indexed_Component
         elsif Nkind (N) = N_Indexed_Component
           or else Nkind (N) = N_Selected_Component
           or else Nkind (N) = N_Selected_Component
         then
         then
            return Is_Volatile_Prefix (Prefix (N));
            return Is_Volatile_Prefix (Prefix (N));
 
 
         else
         else
            return False;
            return False;
         end if;
         end if;
      end Object_Has_Volatile_Components;
      end Object_Has_Volatile_Components;
 
 
   --  Start of processing for Is_Volatile_Object
   --  Start of processing for Is_Volatile_Object
 
 
   begin
   begin
      if Is_Volatile (Etype (N))
      if Is_Volatile (Etype (N))
        or else (Is_Entity_Name (N) and then Is_Volatile (Entity (N)))
        or else (Is_Entity_Name (N) and then Is_Volatile (Entity (N)))
      then
      then
         return True;
         return True;
 
 
      elsif Nkind (N) = N_Indexed_Component
      elsif Nkind (N) = N_Indexed_Component
        or else Nkind (N) = N_Selected_Component
        or else Nkind (N) = N_Selected_Component
      then
      then
         return Is_Volatile_Prefix (Prefix (N));
         return Is_Volatile_Prefix (Prefix (N));
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Is_Volatile_Object;
   end Is_Volatile_Object;
 
 
   -------------------------
   -------------------------
   -- Kill_Current_Values --
   -- Kill_Current_Values --
   -------------------------
   -------------------------
 
 
   procedure Kill_Current_Values
   procedure Kill_Current_Values
     (Ent                  : Entity_Id;
     (Ent                  : Entity_Id;
      Last_Assignment_Only : Boolean := False)
      Last_Assignment_Only : Boolean := False)
   is
   is
   begin
   begin
      --  ??? do we have to worry about clearing cached checks?
      --  ??? do we have to worry about clearing cached checks?
 
 
      if Is_Assignable (Ent) then
      if Is_Assignable (Ent) then
         Set_Last_Assignment (Ent, Empty);
         Set_Last_Assignment (Ent, Empty);
      end if;
      end if;
 
 
      if Is_Object (Ent) then
      if Is_Object (Ent) then
         if not Last_Assignment_Only then
         if not Last_Assignment_Only then
            Kill_Checks (Ent);
            Kill_Checks (Ent);
            Set_Current_Value (Ent, Empty);
            Set_Current_Value (Ent, Empty);
 
 
            if not Can_Never_Be_Null (Ent) then
            if not Can_Never_Be_Null (Ent) then
               Set_Is_Known_Non_Null (Ent, False);
               Set_Is_Known_Non_Null (Ent, False);
            end if;
            end if;
 
 
            Set_Is_Known_Null (Ent, False);
            Set_Is_Known_Null (Ent, False);
 
 
            --  Reset Is_Known_Valid unless type is always valid, or if we have
            --  Reset Is_Known_Valid unless type is always valid, or if we have
            --  a loop parameter (loop parameters are always valid, since their
            --  a loop parameter (loop parameters are always valid, since their
            --  bounds are defined by the bounds given in the loop header).
            --  bounds are defined by the bounds given in the loop header).
 
 
            if not Is_Known_Valid (Etype (Ent))
            if not Is_Known_Valid (Etype (Ent))
              and then Ekind (Ent) /= E_Loop_Parameter
              and then Ekind (Ent) /= E_Loop_Parameter
            then
            then
               Set_Is_Known_Valid (Ent, False);
               Set_Is_Known_Valid (Ent, False);
            end if;
            end if;
         end if;
         end if;
      end if;
      end if;
   end Kill_Current_Values;
   end Kill_Current_Values;
 
 
   procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False) is
   procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False) is
      S : Entity_Id;
      S : Entity_Id;
 
 
      procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id);
      procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id);
      --  Clear current value for entity E and all entities chained to E
      --  Clear current value for entity E and all entities chained to E
 
 
      ------------------------------------------
      ------------------------------------------
      -- Kill_Current_Values_For_Entity_Chain --
      -- Kill_Current_Values_For_Entity_Chain --
      ------------------------------------------
      ------------------------------------------
 
 
      procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id) is
      procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id) is
         Ent : Entity_Id;
         Ent : Entity_Id;
      begin
      begin
         Ent := E;
         Ent := E;
         while Present (Ent) loop
         while Present (Ent) loop
            Kill_Current_Values (Ent, Last_Assignment_Only);
            Kill_Current_Values (Ent, Last_Assignment_Only);
            Next_Entity (Ent);
            Next_Entity (Ent);
         end loop;
         end loop;
      end Kill_Current_Values_For_Entity_Chain;
      end Kill_Current_Values_For_Entity_Chain;
 
 
   --  Start of processing for Kill_Current_Values
   --  Start of processing for Kill_Current_Values
 
 
   begin
   begin
      --  Kill all saved checks, a special case of killing saved values
      --  Kill all saved checks, a special case of killing saved values
 
 
      if not Last_Assignment_Only then
      if not Last_Assignment_Only then
         Kill_All_Checks;
         Kill_All_Checks;
      end if;
      end if;
 
 
      --  Loop through relevant scopes, which includes the current scope and
      --  Loop through relevant scopes, which includes the current scope and
      --  any parent scopes if the current scope is a block or a package.
      --  any parent scopes if the current scope is a block or a package.
 
 
      S := Current_Scope;
      S := Current_Scope;
      Scope_Loop : loop
      Scope_Loop : loop
 
 
         --  Clear current values of all entities in current scope
         --  Clear current values of all entities in current scope
 
 
         Kill_Current_Values_For_Entity_Chain (First_Entity (S));
         Kill_Current_Values_For_Entity_Chain (First_Entity (S));
 
 
         --  If scope is a package, also clear current values of all
         --  If scope is a package, also clear current values of all
         --  private entities in the scope.
         --  private entities in the scope.
 
 
         if Is_Package_Or_Generic_Package (S)
         if Is_Package_Or_Generic_Package (S)
           or else Is_Concurrent_Type (S)
           or else Is_Concurrent_Type (S)
         then
         then
            Kill_Current_Values_For_Entity_Chain (First_Private_Entity (S));
            Kill_Current_Values_For_Entity_Chain (First_Private_Entity (S));
         end if;
         end if;
 
 
         --  If this is a not a subprogram, deal with parents
         --  If this is a not a subprogram, deal with parents
 
 
         if not Is_Subprogram (S) then
         if not Is_Subprogram (S) then
            S := Scope (S);
            S := Scope (S);
            exit Scope_Loop when S = Standard_Standard;
            exit Scope_Loop when S = Standard_Standard;
         else
         else
            exit Scope_Loop;
            exit Scope_Loop;
         end if;
         end if;
      end loop Scope_Loop;
      end loop Scope_Loop;
   end Kill_Current_Values;
   end Kill_Current_Values;
 
 
   --------------------------
   --------------------------
   -- Kill_Size_Check_Code --
   -- Kill_Size_Check_Code --
   --------------------------
   --------------------------
 
 
   procedure Kill_Size_Check_Code (E : Entity_Id) is
   procedure Kill_Size_Check_Code (E : Entity_Id) is
   begin
   begin
      if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable)
      if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable)
        and then Present (Size_Check_Code (E))
        and then Present (Size_Check_Code (E))
      then
      then
         Remove (Size_Check_Code (E));
         Remove (Size_Check_Code (E));
         Set_Size_Check_Code (E, Empty);
         Set_Size_Check_Code (E, Empty);
      end if;
      end if;
   end Kill_Size_Check_Code;
   end Kill_Size_Check_Code;
 
 
   --------------------------
   --------------------------
   -- Known_To_Be_Assigned --
   -- Known_To_Be_Assigned --
   --------------------------
   --------------------------
 
 
   function Known_To_Be_Assigned (N : Node_Id) return Boolean is
   function Known_To_Be_Assigned (N : Node_Id) return Boolean is
      P : constant Node_Id := Parent (N);
      P : constant Node_Id := Parent (N);
 
 
   begin
   begin
      case Nkind (P) is
      case Nkind (P) is
 
 
         --  Test left side of assignment
         --  Test left side of assignment
 
 
         when N_Assignment_Statement =>
         when N_Assignment_Statement =>
            return N = Name (P);
            return N = Name (P);
 
 
            --  Function call arguments are never lvalues
            --  Function call arguments are never lvalues
 
 
         when N_Function_Call =>
         when N_Function_Call =>
            return False;
            return False;
 
 
         --  Positional parameter for procedure or accept call
         --  Positional parameter for procedure or accept call
 
 
         when N_Procedure_Call_Statement |
         when N_Procedure_Call_Statement |
              N_Accept_Statement
              N_Accept_Statement
          =>
          =>
            declare
            declare
               Proc : Entity_Id;
               Proc : Entity_Id;
               Form : Entity_Id;
               Form : Entity_Id;
               Act  : Node_Id;
               Act  : Node_Id;
 
 
            begin
            begin
               Proc := Get_Subprogram_Entity (P);
               Proc := Get_Subprogram_Entity (P);
 
 
               if No (Proc) then
               if No (Proc) then
                  return False;
                  return False;
               end if;
               end if;
 
 
               --  If we are not a list member, something is strange, so
               --  If we are not a list member, something is strange, so
               --  be conservative and return False.
               --  be conservative and return False.
 
 
               if not Is_List_Member (N) then
               if not Is_List_Member (N) then
                  return False;
                  return False;
               end if;
               end if;
 
 
               --  We are going to find the right formal by stepping forward
               --  We are going to find the right formal by stepping forward
               --  through the formals, as we step backwards in the actuals.
               --  through the formals, as we step backwards in the actuals.
 
 
               Form := First_Formal (Proc);
               Form := First_Formal (Proc);
               Act  := N;
               Act  := N;
               loop
               loop
                  --  If no formal, something is weird, so be conservative
                  --  If no formal, something is weird, so be conservative
                  --  and return False.
                  --  and return False.
 
 
                  if No (Form) then
                  if No (Form) then
                     return False;
                     return False;
                  end if;
                  end if;
 
 
                  Prev (Act);
                  Prev (Act);
                  exit when No (Act);
                  exit when No (Act);
                  Next_Formal (Form);
                  Next_Formal (Form);
               end loop;
               end loop;
 
 
               return Ekind (Form) /= E_In_Parameter;
               return Ekind (Form) /= E_In_Parameter;
            end;
            end;
 
 
         --  Named parameter for procedure or accept call
         --  Named parameter for procedure or accept call
 
 
         when N_Parameter_Association =>
         when N_Parameter_Association =>
            declare
            declare
               Proc : Entity_Id;
               Proc : Entity_Id;
               Form : Entity_Id;
               Form : Entity_Id;
 
 
            begin
            begin
               Proc := Get_Subprogram_Entity (Parent (P));
               Proc := Get_Subprogram_Entity (Parent (P));
 
 
               if No (Proc) then
               if No (Proc) then
                  return False;
                  return False;
               end if;
               end if;
 
 
               --  Loop through formals to find the one that matches
               --  Loop through formals to find the one that matches
 
 
               Form := First_Formal (Proc);
               Form := First_Formal (Proc);
               loop
               loop
                  --  If no matching formal, that's peculiar, some kind of
                  --  If no matching formal, that's peculiar, some kind of
                  --  previous error, so return False to be conservative.
                  --  previous error, so return False to be conservative.
 
 
                  if No (Form) then
                  if No (Form) then
                     return False;
                     return False;
                  end if;
                  end if;
 
 
                  --  Else test for match
                  --  Else test for match
 
 
                  if Chars (Form) = Chars (Selector_Name (P)) then
                  if Chars (Form) = Chars (Selector_Name (P)) then
                     return Ekind (Form) /= E_In_Parameter;
                     return Ekind (Form) /= E_In_Parameter;
                  end if;
                  end if;
 
 
                  Next_Formal (Form);
                  Next_Formal (Form);
               end loop;
               end loop;
            end;
            end;
 
 
         --  Test for appearing in a conversion that itself appears
         --  Test for appearing in a conversion that itself appears
         --  in an lvalue context, since this should be an lvalue.
         --  in an lvalue context, since this should be an lvalue.
 
 
         when N_Type_Conversion =>
         when N_Type_Conversion =>
            return Known_To_Be_Assigned (P);
            return Known_To_Be_Assigned (P);
 
 
         --  All other references are definitely not known to be modifications
         --  All other references are definitely not known to be modifications
 
 
         when others =>
         when others =>
            return False;
            return False;
 
 
      end case;
      end case;
   end Known_To_Be_Assigned;
   end Known_To_Be_Assigned;
 
 
   -------------------
   -------------------
   -- May_Be_Lvalue --
   -- May_Be_Lvalue --
   -------------------
   -------------------
 
 
   function May_Be_Lvalue (N : Node_Id) return Boolean is
   function May_Be_Lvalue (N : Node_Id) return Boolean is
      P : constant Node_Id := Parent (N);
      P : constant Node_Id := Parent (N);
 
 
   begin
   begin
      case Nkind (P) is
      case Nkind (P) is
 
 
         --  Test left side of assignment
         --  Test left side of assignment
 
 
         when N_Assignment_Statement =>
         when N_Assignment_Statement =>
            return N = Name (P);
            return N = Name (P);
 
 
         --  Test prefix of component or attribute. Note that the prefix of an
         --  Test prefix of component or attribute. Note that the prefix of an
         --  explicit or implicit dereference cannot be an l-value.
         --  explicit or implicit dereference cannot be an l-value.
 
 
         when N_Attribute_Reference =>
         when N_Attribute_Reference =>
            return N = Prefix (P)
            return N = Prefix (P)
              and then Name_Implies_Lvalue_Prefix (Attribute_Name (P));
              and then Name_Implies_Lvalue_Prefix (Attribute_Name (P));
 
 
         --  For an expanded name, the name is an lvalue if the expanded name
         --  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
         --  is an lvalue, but the prefix is never an lvalue, since it is just
         --  the scope where the name is found.
         --  the scope where the name is found.
 
 
         when N_Expanded_Name        =>
         when N_Expanded_Name        =>
            if N = Prefix (P) then
            if N = Prefix (P) then
               return May_Be_Lvalue (P);
               return May_Be_Lvalue (P);
            else
            else
               return False;
               return False;
            end if;
            end if;
 
 
         --  For a selected component A.B, A is certainly an lvalue if A.B is.
         --  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
         --  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
         --  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
         --  it is. Note however that A is not an lvalue if it is of an access
         --  type since this is an implicit dereference.
         --  type since this is an implicit dereference.
 
 
         when N_Selected_Component   =>
         when N_Selected_Component   =>
            if N = Prefix (P)
            if N = Prefix (P)
              and then Present (Etype (N))
              and then Present (Etype (N))
              and then Is_Access_Type (Etype (N))
              and then Is_Access_Type (Etype (N))
            then
            then
               return False;
               return False;
            else
            else
               return May_Be_Lvalue (P);
               return May_Be_Lvalue (P);
            end if;
            end if;
 
 
         --  For an indexed component or slice, the index or slice bounds is
         --  For an indexed component or slice, the index or slice bounds is
         --  never an lvalue. The prefix is an lvalue if the indexed component
         --  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
         --  or slice is an lvalue, except if it is an access type, where we
         --  have an implicit dereference.
         --  have an implicit dereference.
 
 
         when N_Indexed_Component    =>
         when N_Indexed_Component    =>
            if N /= Prefix (P)
            if N /= Prefix (P)
              or else (Present (Etype (N)) and then Is_Access_Type (Etype (N)))
              or else (Present (Etype (N)) and then Is_Access_Type (Etype (N)))
            then
            then
               return False;
               return False;
            else
            else
               return May_Be_Lvalue (P);
               return May_Be_Lvalue (P);
            end if;
            end if;
 
 
         --  Prefix of a reference is an lvalue if the reference is an lvalue
         --  Prefix of a reference is an lvalue if the reference is an lvalue
 
 
         when N_Reference            =>
         when N_Reference            =>
            return May_Be_Lvalue (P);
            return May_Be_Lvalue (P);
 
 
         --  Prefix of explicit dereference is never an lvalue
         --  Prefix of explicit dereference is never an lvalue
 
 
         when N_Explicit_Dereference =>
         when N_Explicit_Dereference =>
            return False;
            return False;
 
 
         --  Function call arguments are never lvalues
         --  Function call arguments are never lvalues
 
 
         when N_Function_Call =>
         when N_Function_Call =>
            return False;
            return False;
 
 
         --  Positional parameter for procedure, entry,  or accept call
         --  Positional parameter for procedure, entry,  or accept call
 
 
         when N_Procedure_Call_Statement |
         when N_Procedure_Call_Statement |
              N_Entry_Call_Statement     |
              N_Entry_Call_Statement     |
              N_Accept_Statement
              N_Accept_Statement
         =>
         =>
            declare
            declare
               Proc : Entity_Id;
               Proc : Entity_Id;
               Form : Entity_Id;
               Form : Entity_Id;
               Act  : Node_Id;
               Act  : Node_Id;
 
 
            begin
            begin
               Proc := Get_Subprogram_Entity (P);
               Proc := Get_Subprogram_Entity (P);
 
 
               if No (Proc) then
               if No (Proc) then
                  return True;
                  return True;
               end if;
               end if;
 
 
               --  If we are not a list member, something is strange, so
               --  If we are not a list member, something is strange, so
               --  be conservative and return True.
               --  be conservative and return True.
 
 
               if not Is_List_Member (N) then
               if not Is_List_Member (N) then
                  return True;
                  return True;
               end if;
               end if;
 
 
               --  We are going to find the right formal by stepping forward
               --  We are going to find the right formal by stepping forward
               --  through the formals, as we step backwards in the actuals.
               --  through the formals, as we step backwards in the actuals.
 
 
               Form := First_Formal (Proc);
               Form := First_Formal (Proc);
               Act  := N;
               Act  := N;
               loop
               loop
                  --  If no formal, something is weird, so be conservative
                  --  If no formal, something is weird, so be conservative
                  --  and return True.
                  --  and return True.
 
 
                  if No (Form) then
                  if No (Form) then
                     return True;
                     return True;
                  end if;
                  end if;
 
 
                  Prev (Act);
                  Prev (Act);
                  exit when No (Act);
                  exit when No (Act);
                  Next_Formal (Form);
                  Next_Formal (Form);
               end loop;
               end loop;
 
 
               return Ekind (Form) /= E_In_Parameter;
               return Ekind (Form) /= E_In_Parameter;
            end;
            end;
 
 
         --  Named parameter for procedure or accept call
         --  Named parameter for procedure or accept call
 
 
         when N_Parameter_Association =>
         when N_Parameter_Association =>
            declare
            declare
               Proc : Entity_Id;
               Proc : Entity_Id;
               Form : Entity_Id;
               Form : Entity_Id;
 
 
            begin
            begin
               Proc := Get_Subprogram_Entity (Parent (P));
               Proc := Get_Subprogram_Entity (Parent (P));
 
 
               if No (Proc) then
               if No (Proc) then
                  return True;
                  return True;
               end if;
               end if;
 
 
               --  Loop through formals to find the one that matches
               --  Loop through formals to find the one that matches
 
 
               Form := First_Formal (Proc);
               Form := First_Formal (Proc);
               loop
               loop
                  --  If no matching formal, that's peculiar, some kind of
                  --  If no matching formal, that's peculiar, some kind of
                  --  previous error, so return True to be conservative.
                  --  previous error, so return True to be conservative.
 
 
                  if No (Form) then
                  if No (Form) then
                     return True;
                     return True;
                  end if;
                  end if;
 
 
                  --  Else test for match
                  --  Else test for match
 
 
                  if Chars (Form) = Chars (Selector_Name (P)) then
                  if Chars (Form) = Chars (Selector_Name (P)) then
                     return Ekind (Form) /= E_In_Parameter;
                     return Ekind (Form) /= E_In_Parameter;
                  end if;
                  end if;
 
 
                  Next_Formal (Form);
                  Next_Formal (Form);
               end loop;
               end loop;
            end;
            end;
 
 
         --  Test for appearing in a conversion that itself appears in an
         --  Test for appearing in a conversion that itself appears in an
         --  lvalue context, since this should be an lvalue.
         --  lvalue context, since this should be an lvalue.
 
 
         when N_Type_Conversion =>
         when N_Type_Conversion =>
            return May_Be_Lvalue (P);
            return May_Be_Lvalue (P);
 
 
         --  Test for appearance in object renaming declaration
         --  Test for appearance in object renaming declaration
 
 
         when N_Object_Renaming_Declaration =>
         when N_Object_Renaming_Declaration =>
            return True;
            return True;
 
 
         --  All other references are definitely not lvalues
         --  All other references are definitely not lvalues
 
 
         when others =>
         when others =>
            return False;
            return False;
 
 
      end case;
      end case;
   end May_Be_Lvalue;
   end May_Be_Lvalue;
 
 
   -----------------------
   -----------------------
   -- Mark_Coextensions --
   -- Mark_Coextensions --
   -----------------------
   -----------------------
 
 
   procedure Mark_Coextensions (Context_Nod : Node_Id; Root_Nod : Node_Id) is
   procedure Mark_Coextensions (Context_Nod : Node_Id; Root_Nod : Node_Id) is
      Is_Dynamic : Boolean;
      Is_Dynamic : Boolean;
      --  Indicates whether the context causes nested coextensions to be
      --  Indicates whether the context causes nested coextensions to be
      --  dynamic or static
      --  dynamic or static
 
 
      function Mark_Allocator (N : Node_Id) return Traverse_Result;
      function Mark_Allocator (N : Node_Id) return Traverse_Result;
      --  Recognize an allocator node and label it as a dynamic coextension
      --  Recognize an allocator node and label it as a dynamic coextension
 
 
      --------------------
      --------------------
      -- Mark_Allocator --
      -- Mark_Allocator --
      --------------------
      --------------------
 
 
      function Mark_Allocator (N : Node_Id) return Traverse_Result is
      function Mark_Allocator (N : Node_Id) return Traverse_Result is
      begin
      begin
         if Nkind (N) = N_Allocator then
         if Nkind (N) = N_Allocator then
            if Is_Dynamic then
            if Is_Dynamic then
               Set_Is_Dynamic_Coextension (N);
               Set_Is_Dynamic_Coextension (N);
            else
            else
               Set_Is_Static_Coextension (N);
               Set_Is_Static_Coextension (N);
            end if;
            end if;
         end if;
         end if;
 
 
         return OK;
         return OK;
      end Mark_Allocator;
      end Mark_Allocator;
 
 
      procedure Mark_Allocators is new Traverse_Proc (Mark_Allocator);
      procedure Mark_Allocators is new Traverse_Proc (Mark_Allocator);
 
 
   --  Start of processing Mark_Coextensions
   --  Start of processing Mark_Coextensions
 
 
   begin
   begin
      case Nkind (Context_Nod) is
      case Nkind (Context_Nod) is
         when N_Assignment_Statement    |
         when N_Assignment_Statement    |
              N_Simple_Return_Statement =>
              N_Simple_Return_Statement =>
            Is_Dynamic := Nkind (Expression (Context_Nod)) = N_Allocator;
            Is_Dynamic := Nkind (Expression (Context_Nod)) = N_Allocator;
 
 
         when N_Object_Declaration =>
         when N_Object_Declaration =>
            Is_Dynamic := Nkind (Root_Nod) = N_Allocator;
            Is_Dynamic := Nkind (Root_Nod) = N_Allocator;
 
 
         --  This routine should not be called for constructs which may not
         --  This routine should not be called for constructs which may not
         --  contain coextensions.
         --  contain coextensions.
 
 
         when others =>
         when others =>
            raise Program_Error;
            raise Program_Error;
      end case;
      end case;
 
 
      Mark_Allocators (Root_Nod);
      Mark_Allocators (Root_Nod);
   end Mark_Coextensions;
   end Mark_Coextensions;
 
 
   ----------------------
   ----------------------
   -- Needs_One_Actual --
   -- Needs_One_Actual --
   ----------------------
   ----------------------
 
 
   function Needs_One_Actual (E : Entity_Id) return Boolean is
   function Needs_One_Actual (E : Entity_Id) return Boolean is
      Formal : Entity_Id;
      Formal : Entity_Id;
 
 
   begin
   begin
      if Ada_Version >= Ada_05
      if Ada_Version >= Ada_05
        and then Present (First_Formal (E))
        and then Present (First_Formal (E))
      then
      then
         Formal := Next_Formal (First_Formal (E));
         Formal := Next_Formal (First_Formal (E));
         while Present (Formal) loop
         while Present (Formal) loop
            if No (Default_Value (Formal)) then
            if No (Default_Value (Formal)) then
               return False;
               return False;
            end if;
            end if;
 
 
            Next_Formal (Formal);
            Next_Formal (Formal);
         end loop;
         end loop;
 
 
         return True;
         return True;
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Needs_One_Actual;
   end Needs_One_Actual;
 
 
   ------------------------
   ------------------------
   -- New_Copy_List_Tree --
   -- New_Copy_List_Tree --
   ------------------------
   ------------------------
 
 
   function New_Copy_List_Tree (List : List_Id) return List_Id is
   function New_Copy_List_Tree (List : List_Id) return List_Id is
      NL : List_Id;
      NL : List_Id;
      E  : Node_Id;
      E  : Node_Id;
 
 
   begin
   begin
      if List = No_List then
      if List = No_List then
         return No_List;
         return No_List;
 
 
      else
      else
         NL := New_List;
         NL := New_List;
         E := First (List);
         E := First (List);
 
 
         while Present (E) loop
         while Present (E) loop
            Append (New_Copy_Tree (E), NL);
            Append (New_Copy_Tree (E), NL);
            E := Next (E);
            E := Next (E);
         end loop;
         end loop;
 
 
         return NL;
         return NL;
      end if;
      end if;
   end New_Copy_List_Tree;
   end New_Copy_List_Tree;
 
 
   -------------------
   -------------------
   -- New_Copy_Tree --
   -- New_Copy_Tree --
   -------------------
   -------------------
 
 
   use Atree.Unchecked_Access;
   use Atree.Unchecked_Access;
   use Atree_Private_Part;
   use Atree_Private_Part;
 
 
   --  Our approach here requires a two pass traversal of the tree. The
   --  Our approach here requires a two pass traversal of the tree. The
   --  first pass visits all nodes that eventually will be copied looking
   --  first pass visits all nodes that eventually will be copied looking
   --  for defining Itypes. If any defining Itypes are found, then they are
   --  for defining Itypes. If any defining Itypes are found, then they are
   --  copied, and an entry is added to the replacement map. In the second
   --  copied, and an entry is added to the replacement map. In the second
   --  phase, the tree is copied, using the replacement map to replace any
   --  phase, the tree is copied, using the replacement map to replace any
   --  Itype references within the copied tree.
   --  Itype references within the copied tree.
 
 
   --  The following hash tables are used if the Map supplied has more
   --  The following hash tables are used if the Map supplied has more
   --  than hash threshhold entries to speed up access to the map. If
   --  than hash threshhold entries to speed up access to the map. If
   --  there are fewer entries, then the map is searched sequentially
   --  there are fewer entries, then the map is searched sequentially
   --  (because setting up a hash table for only a few entries takes
   --  (because setting up a hash table for only a few entries takes
   --  more time than it saves.
   --  more time than it saves.
 
 
   function New_Copy_Hash (E : Entity_Id) return NCT_Header_Num;
   function New_Copy_Hash (E : Entity_Id) return NCT_Header_Num;
   --  Hash function used for hash operations
   --  Hash function used for hash operations
 
 
   -------------------
   -------------------
   -- New_Copy_Hash --
   -- New_Copy_Hash --
   -------------------
   -------------------
 
 
   function New_Copy_Hash (E : Entity_Id) return NCT_Header_Num is
   function New_Copy_Hash (E : Entity_Id) return NCT_Header_Num is
   begin
   begin
      return Nat (E) mod (NCT_Header_Num'Last + 1);
      return Nat (E) mod (NCT_Header_Num'Last + 1);
   end New_Copy_Hash;
   end New_Copy_Hash;
 
 
   ---------------
   ---------------
   -- NCT_Assoc --
   -- NCT_Assoc --
   ---------------
   ---------------
 
 
   --  The hash table NCT_Assoc associates old entities in the table
   --  The hash table NCT_Assoc associates old entities in the table
   --  with their corresponding new entities (i.e. the pairs of entries
   --  with their corresponding new entities (i.e. the pairs of entries
   --  presented in the original Map argument are Key-Element pairs).
   --  presented in the original Map argument are Key-Element pairs).
 
 
   package NCT_Assoc is new Simple_HTable (
   package NCT_Assoc is new Simple_HTable (
     Header_Num => NCT_Header_Num,
     Header_Num => NCT_Header_Num,
     Element    => Entity_Id,
     Element    => Entity_Id,
     No_Element => Empty,
     No_Element => Empty,
     Key        => Entity_Id,
     Key        => Entity_Id,
     Hash       => New_Copy_Hash,
     Hash       => New_Copy_Hash,
     Equal      => Types."=");
     Equal      => Types."=");
 
 
   ---------------------
   ---------------------
   -- NCT_Itype_Assoc --
   -- NCT_Itype_Assoc --
   ---------------------
   ---------------------
 
 
   --  The hash table NCT_Itype_Assoc contains entries only for those
   --  The hash table NCT_Itype_Assoc contains entries only for those
   --  old nodes which have a non-empty Associated_Node_For_Itype set.
   --  old nodes which have a non-empty Associated_Node_For_Itype set.
   --  The key is the associated node, and the element is the new node
   --  The key is the associated node, and the element is the new node
   --  itself (NOT the associated node for the new node).
   --  itself (NOT the associated node for the new node).
 
 
   package NCT_Itype_Assoc is new Simple_HTable (
   package NCT_Itype_Assoc is new Simple_HTable (
     Header_Num => NCT_Header_Num,
     Header_Num => NCT_Header_Num,
     Element    => Entity_Id,
     Element    => Entity_Id,
     No_Element => Empty,
     No_Element => Empty,
     Key        => Entity_Id,
     Key        => Entity_Id,
     Hash       => New_Copy_Hash,
     Hash       => New_Copy_Hash,
     Equal      => Types."=");
     Equal      => Types."=");
 
 
   --  Start of processing for New_Copy_Tree function
   --  Start of processing for New_Copy_Tree function
 
 
   function New_Copy_Tree
   function New_Copy_Tree
     (Source    : Node_Id;
     (Source    : Node_Id;
      Map       : Elist_Id := No_Elist;
      Map       : Elist_Id := No_Elist;
      New_Sloc  : Source_Ptr := No_Location;
      New_Sloc  : Source_Ptr := No_Location;
      New_Scope : Entity_Id := Empty) return Node_Id
      New_Scope : Entity_Id := Empty) return Node_Id
   is
   is
      Actual_Map : Elist_Id := Map;
      Actual_Map : Elist_Id := Map;
      --  This is the actual map for the copy. It is initialized with the
      --  This is the actual map for the copy. It is initialized with the
      --  given elements, and then enlarged as required for Itypes that are
      --  given elements, and then enlarged as required for Itypes that are
      --  copied during the first phase of the copy operation. The visit
      --  copied during the first phase of the copy operation. The visit
      --  procedures add elements to this map as Itypes are encountered.
      --  procedures add elements to this map as Itypes are encountered.
      --  The reason we cannot use Map directly, is that it may well be
      --  The reason we cannot use Map directly, is that it may well be
      --  (and normally is) initialized to No_Elist, and if we have mapped
      --  (and normally is) initialized to No_Elist, and if we have mapped
      --  entities, we have to reset it to point to a real Elist.
      --  entities, we have to reset it to point to a real Elist.
 
 
      function Assoc (N : Node_Or_Entity_Id) return Node_Id;
      function Assoc (N : Node_Or_Entity_Id) return Node_Id;
      --  Called during second phase to map entities into their corresponding
      --  Called during second phase to map entities into their corresponding
      --  copies using Actual_Map. If the argument is not an entity, or is not
      --  copies using Actual_Map. If the argument is not an entity, or is not
      --  in Actual_Map, then it is returned unchanged.
      --  in Actual_Map, then it is returned unchanged.
 
 
      procedure Build_NCT_Hash_Tables;
      procedure Build_NCT_Hash_Tables;
      --  Builds hash tables (number of elements >= threshold value)
      --  Builds hash tables (number of elements >= threshold value)
 
 
      function Copy_Elist_With_Replacement
      function Copy_Elist_With_Replacement
        (Old_Elist : Elist_Id) return Elist_Id;
        (Old_Elist : Elist_Id) return Elist_Id;
      --  Called during second phase to copy element list doing replacements
      --  Called during second phase to copy element list doing replacements
 
 
      procedure Copy_Itype_With_Replacement (New_Itype : Entity_Id);
      procedure Copy_Itype_With_Replacement (New_Itype : Entity_Id);
      --  Called during the second phase to process a copied Itype. The actual
      --  Called during the second phase to process a copied Itype. The actual
      --  copy happened during the first phase (so that we could make the entry
      --  copy happened during the first phase (so that we could make the entry
      --  in the mapping), but we still have to deal with the descendents of
      --  in the mapping), but we still have to deal with the descendents of
      --  the copied Itype and copy them where necessary.
      --  the copied Itype and copy them where necessary.
 
 
      function Copy_List_With_Replacement (Old_List : List_Id) return List_Id;
      function Copy_List_With_Replacement (Old_List : List_Id) return List_Id;
      --  Called during second phase to copy list doing replacements
      --  Called during second phase to copy list doing replacements
 
 
      function Copy_Node_With_Replacement (Old_Node : Node_Id) return Node_Id;
      function Copy_Node_With_Replacement (Old_Node : Node_Id) return Node_Id;
      --  Called during second phase to copy node doing replacements
      --  Called during second phase to copy node doing replacements
 
 
      procedure Visit_Elist (E : Elist_Id);
      procedure Visit_Elist (E : Elist_Id);
      --  Called during first phase to visit all elements of an Elist
      --  Called during first phase to visit all elements of an Elist
 
 
      procedure Visit_Field (F : Union_Id; N : Node_Id);
      procedure Visit_Field (F : Union_Id; N : Node_Id);
      --  Visit a single field, recursing to call Visit_Node or Visit_List
      --  Visit a single field, recursing to call Visit_Node or Visit_List
      --  if the field is a syntactic descendent of the current node (i.e.
      --  if the field is a syntactic descendent of the current node (i.e.
      --  its parent is Node N).
      --  its parent is Node N).
 
 
      procedure Visit_Itype (Old_Itype : Entity_Id);
      procedure Visit_Itype (Old_Itype : Entity_Id);
      --  Called during first phase to visit subsidiary fields of a defining
      --  Called during first phase to visit subsidiary fields of a defining
      --  Itype, and also create a copy and make an entry in the replacement
      --  Itype, and also create a copy and make an entry in the replacement
      --  map for the new copy.
      --  map for the new copy.
 
 
      procedure Visit_List (L : List_Id);
      procedure Visit_List (L : List_Id);
      --  Called during first phase to visit all elements of a List
      --  Called during first phase to visit all elements of a List
 
 
      procedure Visit_Node (N : Node_Or_Entity_Id);
      procedure Visit_Node (N : Node_Or_Entity_Id);
      --  Called during first phase to visit a node and all its subtrees
      --  Called during first phase to visit a node and all its subtrees
 
 
      -----------
      -----------
      -- Assoc --
      -- Assoc --
      -----------
      -----------
 
 
      function Assoc (N : Node_Or_Entity_Id) return Node_Id is
      function Assoc (N : Node_Or_Entity_Id) return Node_Id is
         E   : Elmt_Id;
         E   : Elmt_Id;
         Ent : Entity_Id;
         Ent : Entity_Id;
 
 
      begin
      begin
         if not Has_Extension (N) or else No (Actual_Map) then
         if not Has_Extension (N) or else No (Actual_Map) then
            return N;
            return N;
 
 
         elsif NCT_Hash_Tables_Used then
         elsif NCT_Hash_Tables_Used then
            Ent := NCT_Assoc.Get (Entity_Id (N));
            Ent := NCT_Assoc.Get (Entity_Id (N));
 
 
            if Present (Ent) then
            if Present (Ent) then
               return Ent;
               return Ent;
            else
            else
               return N;
               return N;
            end if;
            end if;
 
 
         --  No hash table used, do serial search
         --  No hash table used, do serial search
 
 
         else
         else
            E := First_Elmt (Actual_Map);
            E := First_Elmt (Actual_Map);
            while Present (E) loop
            while Present (E) loop
               if Node (E) = N then
               if Node (E) = N then
                  return Node (Next_Elmt (E));
                  return Node (Next_Elmt (E));
               else
               else
                  E := Next_Elmt (Next_Elmt (E));
                  E := Next_Elmt (Next_Elmt (E));
               end if;
               end if;
            end loop;
            end loop;
         end if;
         end if;
 
 
         return N;
         return N;
      end Assoc;
      end Assoc;
 
 
      ---------------------------
      ---------------------------
      -- Build_NCT_Hash_Tables --
      -- Build_NCT_Hash_Tables --
      ---------------------------
      ---------------------------
 
 
      procedure Build_NCT_Hash_Tables is
      procedure Build_NCT_Hash_Tables is
         Elmt : Elmt_Id;
         Elmt : Elmt_Id;
         Ent  : Entity_Id;
         Ent  : Entity_Id;
      begin
      begin
         if NCT_Hash_Table_Setup then
         if NCT_Hash_Table_Setup then
            NCT_Assoc.Reset;
            NCT_Assoc.Reset;
            NCT_Itype_Assoc.Reset;
            NCT_Itype_Assoc.Reset;
         end if;
         end if;
 
 
         Elmt := First_Elmt (Actual_Map);
         Elmt := First_Elmt (Actual_Map);
         while Present (Elmt) loop
         while Present (Elmt) loop
            Ent := Node (Elmt);
            Ent := Node (Elmt);
 
 
            --  Get new entity, and associate old and new
            --  Get new entity, and associate old and new
 
 
            Next_Elmt (Elmt);
            Next_Elmt (Elmt);
            NCT_Assoc.Set (Ent, Node (Elmt));
            NCT_Assoc.Set (Ent, Node (Elmt));
 
 
            if Is_Type (Ent) then
            if Is_Type (Ent) then
               declare
               declare
                  Anode : constant Entity_Id :=
                  Anode : constant Entity_Id :=
                            Associated_Node_For_Itype (Ent);
                            Associated_Node_For_Itype (Ent);
 
 
               begin
               begin
                  if Present (Anode) then
                  if Present (Anode) then
 
 
                     --  Enter a link between the associated node of the
                     --  Enter a link between the associated node of the
                     --  old Itype and the new Itype, for updating later
                     --  old Itype and the new Itype, for updating later
                     --  when node is copied.
                     --  when node is copied.
 
 
                     NCT_Itype_Assoc.Set (Anode, Node (Elmt));
                     NCT_Itype_Assoc.Set (Anode, Node (Elmt));
                  end if;
                  end if;
               end;
               end;
            end if;
            end if;
 
 
            Next_Elmt (Elmt);
            Next_Elmt (Elmt);
         end loop;
         end loop;
 
 
         NCT_Hash_Tables_Used := True;
         NCT_Hash_Tables_Used := True;
         NCT_Hash_Table_Setup := True;
         NCT_Hash_Table_Setup := True;
      end Build_NCT_Hash_Tables;
      end Build_NCT_Hash_Tables;
 
 
      ---------------------------------
      ---------------------------------
      -- Copy_Elist_With_Replacement --
      -- Copy_Elist_With_Replacement --
      ---------------------------------
      ---------------------------------
 
 
      function Copy_Elist_With_Replacement
      function Copy_Elist_With_Replacement
        (Old_Elist : Elist_Id) return Elist_Id
        (Old_Elist : Elist_Id) return Elist_Id
      is
      is
         M         : Elmt_Id;
         M         : Elmt_Id;
         New_Elist : Elist_Id;
         New_Elist : Elist_Id;
 
 
      begin
      begin
         if No (Old_Elist) then
         if No (Old_Elist) then
            return No_Elist;
            return No_Elist;
 
 
         else
         else
            New_Elist := New_Elmt_List;
            New_Elist := New_Elmt_List;
 
 
            M := First_Elmt (Old_Elist);
            M := First_Elmt (Old_Elist);
            while Present (M) loop
            while Present (M) loop
               Append_Elmt (Copy_Node_With_Replacement (Node (M)), New_Elist);
               Append_Elmt (Copy_Node_With_Replacement (Node (M)), New_Elist);
               Next_Elmt (M);
               Next_Elmt (M);
            end loop;
            end loop;
         end if;
         end if;
 
 
         return New_Elist;
         return New_Elist;
      end Copy_Elist_With_Replacement;
      end Copy_Elist_With_Replacement;
 
 
      ---------------------------------
      ---------------------------------
      -- Copy_Itype_With_Replacement --
      -- Copy_Itype_With_Replacement --
      ---------------------------------
      ---------------------------------
 
 
      --  This routine exactly parallels its phase one analog Visit_Itype,
      --  This routine exactly parallels its phase one analog Visit_Itype,
 
 
      procedure Copy_Itype_With_Replacement (New_Itype : Entity_Id) is
      procedure Copy_Itype_With_Replacement (New_Itype : Entity_Id) is
      begin
      begin
         --  Translate Next_Entity, Scope and Etype fields, in case they
         --  Translate Next_Entity, Scope and Etype fields, in case they
         --  reference entities that have been mapped into copies.
         --  reference entities that have been mapped into copies.
 
 
         Set_Next_Entity (New_Itype, Assoc (Next_Entity (New_Itype)));
         Set_Next_Entity (New_Itype, Assoc (Next_Entity (New_Itype)));
         Set_Etype       (New_Itype, Assoc (Etype       (New_Itype)));
         Set_Etype       (New_Itype, Assoc (Etype       (New_Itype)));
 
 
         if Present (New_Scope) then
         if Present (New_Scope) then
            Set_Scope    (New_Itype, New_Scope);
            Set_Scope    (New_Itype, New_Scope);
         else
         else
            Set_Scope    (New_Itype, Assoc (Scope       (New_Itype)));
            Set_Scope    (New_Itype, Assoc (Scope       (New_Itype)));
         end if;
         end if;
 
 
         --  Copy referenced fields
         --  Copy referenced fields
 
 
         if Is_Discrete_Type (New_Itype) then
         if Is_Discrete_Type (New_Itype) then
            Set_Scalar_Range (New_Itype,
            Set_Scalar_Range (New_Itype,
              Copy_Node_With_Replacement (Scalar_Range (New_Itype)));
              Copy_Node_With_Replacement (Scalar_Range (New_Itype)));
 
 
         elsif Has_Discriminants (Base_Type (New_Itype)) then
         elsif Has_Discriminants (Base_Type (New_Itype)) then
            Set_Discriminant_Constraint (New_Itype,
            Set_Discriminant_Constraint (New_Itype,
              Copy_Elist_With_Replacement
              Copy_Elist_With_Replacement
                (Discriminant_Constraint (New_Itype)));
                (Discriminant_Constraint (New_Itype)));
 
 
         elsif Is_Array_Type (New_Itype) then
         elsif Is_Array_Type (New_Itype) then
            if Present (First_Index (New_Itype)) then
            if Present (First_Index (New_Itype)) then
               Set_First_Index (New_Itype,
               Set_First_Index (New_Itype,
                 First (Copy_List_With_Replacement
                 First (Copy_List_With_Replacement
                         (List_Containing (First_Index (New_Itype)))));
                         (List_Containing (First_Index (New_Itype)))));
            end if;
            end if;
 
 
            if Is_Packed (New_Itype) then
            if Is_Packed (New_Itype) then
               Set_Packed_Array_Type (New_Itype,
               Set_Packed_Array_Type (New_Itype,
                 Copy_Node_With_Replacement
                 Copy_Node_With_Replacement
                   (Packed_Array_Type (New_Itype)));
                   (Packed_Array_Type (New_Itype)));
            end if;
            end if;
         end if;
         end if;
      end Copy_Itype_With_Replacement;
      end Copy_Itype_With_Replacement;
 
 
      --------------------------------
      --------------------------------
      -- Copy_List_With_Replacement --
      -- Copy_List_With_Replacement --
      --------------------------------
      --------------------------------
 
 
      function Copy_List_With_Replacement
      function Copy_List_With_Replacement
        (Old_List : List_Id) return List_Id
        (Old_List : List_Id) return List_Id
      is
      is
         New_List : List_Id;
         New_List : List_Id;
         E        : Node_Id;
         E        : Node_Id;
 
 
      begin
      begin
         if Old_List = No_List then
         if Old_List = No_List then
            return No_List;
            return No_List;
 
 
         else
         else
            New_List := Empty_List;
            New_List := Empty_List;
 
 
            E := First (Old_List);
            E := First (Old_List);
            while Present (E) loop
            while Present (E) loop
               Append (Copy_Node_With_Replacement (E), New_List);
               Append (Copy_Node_With_Replacement (E), New_List);
               Next (E);
               Next (E);
            end loop;
            end loop;
 
 
            return New_List;
            return New_List;
         end if;
         end if;
      end Copy_List_With_Replacement;
      end Copy_List_With_Replacement;
 
 
      --------------------------------
      --------------------------------
      -- Copy_Node_With_Replacement --
      -- Copy_Node_With_Replacement --
      --------------------------------
      --------------------------------
 
 
      function Copy_Node_With_Replacement
      function Copy_Node_With_Replacement
        (Old_Node : Node_Id) return Node_Id
        (Old_Node : Node_Id) return Node_Id
      is
      is
         New_Node : Node_Id;
         New_Node : Node_Id;
 
 
         procedure Adjust_Named_Associations
         procedure Adjust_Named_Associations
           (Old_Node : Node_Id;
           (Old_Node : Node_Id;
            New_Node : Node_Id);
            New_Node : Node_Id);
         --  If a call node has named associations, these are chained through
         --  If a call node has named associations, these are chained through
         --  the First_Named_Actual, Next_Named_Actual links. These must be
         --  the First_Named_Actual, Next_Named_Actual links. These must be
         --  propagated separately to the new parameter list, because these
         --  propagated separately to the new parameter list, because these
         --  are not syntactic fields.
         --  are not syntactic fields.
 
 
         function Copy_Field_With_Replacement
         function Copy_Field_With_Replacement
           (Field : Union_Id) return Union_Id;
           (Field : Union_Id) return Union_Id;
         --  Given Field, which is a field of Old_Node, return a copy of it
         --  Given Field, which is a field of Old_Node, return a copy of it
         --  if it is a syntactic field (i.e. its parent is Node), setting
         --  if it is a syntactic field (i.e. its parent is Node), setting
         --  the parent of the copy to poit to New_Node. Otherwise returns
         --  the parent of the copy to poit to New_Node. Otherwise returns
         --  the field (possibly mapped if it is an entity).
         --  the field (possibly mapped if it is an entity).
 
 
         -------------------------------
         -------------------------------
         -- Adjust_Named_Associations --
         -- Adjust_Named_Associations --
         -------------------------------
         -------------------------------
 
 
         procedure Adjust_Named_Associations
         procedure Adjust_Named_Associations
           (Old_Node : Node_Id;
           (Old_Node : Node_Id;
            New_Node : Node_Id)
            New_Node : Node_Id)
         is
         is
            Old_E : Node_Id;
            Old_E : Node_Id;
            New_E : Node_Id;
            New_E : Node_Id;
 
 
            Old_Next : Node_Id;
            Old_Next : Node_Id;
            New_Next : Node_Id;
            New_Next : Node_Id;
 
 
         begin
         begin
            Old_E := First (Parameter_Associations (Old_Node));
            Old_E := First (Parameter_Associations (Old_Node));
            New_E := First (Parameter_Associations (New_Node));
            New_E := First (Parameter_Associations (New_Node));
            while Present (Old_E) loop
            while Present (Old_E) loop
               if Nkind (Old_E) = N_Parameter_Association
               if Nkind (Old_E) = N_Parameter_Association
                 and then Present (Next_Named_Actual (Old_E))
                 and then Present (Next_Named_Actual (Old_E))
               then
               then
                  if First_Named_Actual (Old_Node)
                  if First_Named_Actual (Old_Node)
                    =  Explicit_Actual_Parameter (Old_E)
                    =  Explicit_Actual_Parameter (Old_E)
                  then
                  then
                     Set_First_Named_Actual
                     Set_First_Named_Actual
                       (New_Node, Explicit_Actual_Parameter (New_E));
                       (New_Node, Explicit_Actual_Parameter (New_E));
                  end if;
                  end if;
 
 
                  --  Now scan parameter list from the beginning,to locate
                  --  Now scan parameter list from the beginning,to locate
                  --  next named actual, which can be out of order.
                  --  next named actual, which can be out of order.
 
 
                  Old_Next := First (Parameter_Associations (Old_Node));
                  Old_Next := First (Parameter_Associations (Old_Node));
                  New_Next := First (Parameter_Associations (New_Node));
                  New_Next := First (Parameter_Associations (New_Node));
 
 
                  while Nkind (Old_Next) /= N_Parameter_Association
                  while Nkind (Old_Next) /= N_Parameter_Association
                    or else  Explicit_Actual_Parameter (Old_Next)
                    or else  Explicit_Actual_Parameter (Old_Next)
                      /= Next_Named_Actual (Old_E)
                      /= Next_Named_Actual (Old_E)
                  loop
                  loop
                     Next (Old_Next);
                     Next (Old_Next);
                     Next (New_Next);
                     Next (New_Next);
                  end loop;
                  end loop;
 
 
                  Set_Next_Named_Actual
                  Set_Next_Named_Actual
                    (New_E, Explicit_Actual_Parameter (New_Next));
                    (New_E, Explicit_Actual_Parameter (New_Next));
               end if;
               end if;
 
 
               Next (Old_E);
               Next (Old_E);
               Next (New_E);
               Next (New_E);
            end loop;
            end loop;
         end Adjust_Named_Associations;
         end Adjust_Named_Associations;
 
 
         ---------------------------------
         ---------------------------------
         -- Copy_Field_With_Replacement --
         -- Copy_Field_With_Replacement --
         ---------------------------------
         ---------------------------------
 
 
         function Copy_Field_With_Replacement
         function Copy_Field_With_Replacement
           (Field : Union_Id) return Union_Id
           (Field : Union_Id) return Union_Id
         is
         is
         begin
         begin
            if Field = Union_Id (Empty) then
            if Field = Union_Id (Empty) then
               return Field;
               return Field;
 
 
            elsif Field in Node_Range then
            elsif Field in Node_Range then
               declare
               declare
                  Old_N : constant Node_Id := Node_Id (Field);
                  Old_N : constant Node_Id := Node_Id (Field);
                  New_N : Node_Id;
                  New_N : Node_Id;
 
 
               begin
               begin
                  --  If syntactic field, as indicated by the parent pointer
                  --  If syntactic field, as indicated by the parent pointer
                  --  being set, then copy the referenced node recursively.
                  --  being set, then copy the referenced node recursively.
 
 
                  if Parent (Old_N) = Old_Node then
                  if Parent (Old_N) = Old_Node then
                     New_N := Copy_Node_With_Replacement (Old_N);
                     New_N := Copy_Node_With_Replacement (Old_N);
 
 
                     if New_N /= Old_N then
                     if New_N /= Old_N then
                        Set_Parent (New_N, New_Node);
                        Set_Parent (New_N, New_Node);
                     end if;
                     end if;
 
 
                  --  For semantic fields, update possible entity reference
                  --  For semantic fields, update possible entity reference
                  --  from the replacement map.
                  --  from the replacement map.
 
 
                  else
                  else
                     New_N := Assoc (Old_N);
                     New_N := Assoc (Old_N);
                  end if;
                  end if;
 
 
                  return Union_Id (New_N);
                  return Union_Id (New_N);
               end;
               end;
 
 
            elsif Field in List_Range then
            elsif Field in List_Range then
               declare
               declare
                  Old_L : constant List_Id := List_Id (Field);
                  Old_L : constant List_Id := List_Id (Field);
                  New_L : List_Id;
                  New_L : List_Id;
 
 
               begin
               begin
                  --  If syntactic field, as indicated by the parent pointer,
                  --  If syntactic field, as indicated by the parent pointer,
                  --  then recursively copy the entire referenced list.
                  --  then recursively copy the entire referenced list.
 
 
                  if Parent (Old_L) = Old_Node then
                  if Parent (Old_L) = Old_Node then
                     New_L := Copy_List_With_Replacement (Old_L);
                     New_L := Copy_List_With_Replacement (Old_L);
                     Set_Parent (New_L, New_Node);
                     Set_Parent (New_L, New_Node);
 
 
                  --  For semantic list, just returned unchanged
                  --  For semantic list, just returned unchanged
 
 
                  else
                  else
                     New_L := Old_L;
                     New_L := Old_L;
                  end if;
                  end if;
 
 
                  return Union_Id (New_L);
                  return Union_Id (New_L);
               end;
               end;
 
 
            --  Anything other than a list or a node is returned unchanged
            --  Anything other than a list or a node is returned unchanged
 
 
            else
            else
               return Field;
               return Field;
            end if;
            end if;
         end Copy_Field_With_Replacement;
         end Copy_Field_With_Replacement;
 
 
      --  Start of processing for Copy_Node_With_Replacement
      --  Start of processing for Copy_Node_With_Replacement
 
 
      begin
      begin
         if Old_Node <= Empty_Or_Error then
         if Old_Node <= Empty_Or_Error then
            return Old_Node;
            return Old_Node;
 
 
         elsif Has_Extension (Old_Node) then
         elsif Has_Extension (Old_Node) then
            return Assoc (Old_Node);
            return Assoc (Old_Node);
 
 
         else
         else
            New_Node := New_Copy (Old_Node);
            New_Node := New_Copy (Old_Node);
 
 
            --  If the node we are copying is the associated node of a
            --  If the node we are copying is the associated node of a
            --  previously copied Itype, then adjust the associated node
            --  previously copied Itype, then adjust the associated node
            --  of the copy of that Itype accordingly.
            --  of the copy of that Itype accordingly.
 
 
            if Present (Actual_Map) then
            if Present (Actual_Map) then
               declare
               declare
                  E   : Elmt_Id;
                  E   : Elmt_Id;
                  Ent : Entity_Id;
                  Ent : Entity_Id;
 
 
               begin
               begin
                  --  Case of hash table used
                  --  Case of hash table used
 
 
                  if NCT_Hash_Tables_Used then
                  if NCT_Hash_Tables_Used then
                     Ent := NCT_Itype_Assoc.Get (Old_Node);
                     Ent := NCT_Itype_Assoc.Get (Old_Node);
 
 
                     if Present (Ent) then
                     if Present (Ent) then
                        Set_Associated_Node_For_Itype (Ent, New_Node);
                        Set_Associated_Node_For_Itype (Ent, New_Node);
                     end if;
                     end if;
 
 
                  --  Case of no hash table used
                  --  Case of no hash table used
 
 
                  else
                  else
                     E := First_Elmt (Actual_Map);
                     E := First_Elmt (Actual_Map);
                     while Present (E) loop
                     while Present (E) loop
                        if Is_Itype (Node (E))
                        if Is_Itype (Node (E))
                          and then
                          and then
                            Old_Node = Associated_Node_For_Itype (Node (E))
                            Old_Node = Associated_Node_For_Itype (Node (E))
                        then
                        then
                           Set_Associated_Node_For_Itype
                           Set_Associated_Node_For_Itype
                             (Node (Next_Elmt (E)), New_Node);
                             (Node (Next_Elmt (E)), New_Node);
                        end if;
                        end if;
 
 
                        E := Next_Elmt (Next_Elmt (E));
                        E := Next_Elmt (Next_Elmt (E));
                     end loop;
                     end loop;
                  end if;
                  end if;
               end;
               end;
            end if;
            end if;
 
 
            --  Recursively copy descendents
            --  Recursively copy descendents
 
 
            Set_Field1
            Set_Field1
              (New_Node, Copy_Field_With_Replacement (Field1 (New_Node)));
              (New_Node, Copy_Field_With_Replacement (Field1 (New_Node)));
            Set_Field2
            Set_Field2
              (New_Node, Copy_Field_With_Replacement (Field2 (New_Node)));
              (New_Node, Copy_Field_With_Replacement (Field2 (New_Node)));
            Set_Field3
            Set_Field3
              (New_Node, Copy_Field_With_Replacement (Field3 (New_Node)));
              (New_Node, Copy_Field_With_Replacement (Field3 (New_Node)));
            Set_Field4
            Set_Field4
              (New_Node, Copy_Field_With_Replacement (Field4 (New_Node)));
              (New_Node, Copy_Field_With_Replacement (Field4 (New_Node)));
            Set_Field5
            Set_Field5
              (New_Node, Copy_Field_With_Replacement (Field5 (New_Node)));
              (New_Node, Copy_Field_With_Replacement (Field5 (New_Node)));
 
 
            --  Adjust Sloc of new node if necessary
            --  Adjust Sloc of new node if necessary
 
 
            if New_Sloc /= No_Location then
            if New_Sloc /= No_Location then
               Set_Sloc (New_Node, New_Sloc);
               Set_Sloc (New_Node, New_Sloc);
 
 
               --  If we adjust the Sloc, then we are essentially making
               --  If we adjust the Sloc, then we are essentially making
               --  a completely new node, so the Comes_From_Source flag
               --  a completely new node, so the Comes_From_Source flag
               --  should be reset to the proper default value.
               --  should be reset to the proper default value.
 
 
               Nodes.Table (New_Node).Comes_From_Source :=
               Nodes.Table (New_Node).Comes_From_Source :=
                 Default_Node.Comes_From_Source;
                 Default_Node.Comes_From_Source;
            end if;
            end if;
 
 
            --  If the node is call and has named associations,
            --  If the node is call and has named associations,
            --  set the corresponding links in the copy.
            --  set the corresponding links in the copy.
 
 
            if (Nkind (Old_Node) = N_Function_Call
            if (Nkind (Old_Node) = N_Function_Call
                 or else Nkind (Old_Node) = N_Entry_Call_Statement
                 or else Nkind (Old_Node) = N_Entry_Call_Statement
                 or else
                 or else
                   Nkind (Old_Node) = N_Procedure_Call_Statement)
                   Nkind (Old_Node) = N_Procedure_Call_Statement)
              and then Present (First_Named_Actual (Old_Node))
              and then Present (First_Named_Actual (Old_Node))
            then
            then
               Adjust_Named_Associations (Old_Node, New_Node);
               Adjust_Named_Associations (Old_Node, New_Node);
            end if;
            end if;
 
 
            --  Reset First_Real_Statement for Handled_Sequence_Of_Statements.
            --  Reset First_Real_Statement for Handled_Sequence_Of_Statements.
            --  The replacement mechanism applies to entities, and is not used
            --  The replacement mechanism applies to entities, and is not used
            --  here. Eventually we may need a more general graph-copying
            --  here. Eventually we may need a more general graph-copying
            --  routine. For now, do a sequential search to find desired node.
            --  routine. For now, do a sequential search to find desired node.
 
 
            if Nkind (Old_Node) = N_Handled_Sequence_Of_Statements
            if Nkind (Old_Node) = N_Handled_Sequence_Of_Statements
              and then Present (First_Real_Statement (Old_Node))
              and then Present (First_Real_Statement (Old_Node))
            then
            then
               declare
               declare
                  Old_F  : constant Node_Id := First_Real_Statement (Old_Node);
                  Old_F  : constant Node_Id := First_Real_Statement (Old_Node);
                  N1, N2 : Node_Id;
                  N1, N2 : Node_Id;
 
 
               begin
               begin
                  N1 := First (Statements (Old_Node));
                  N1 := First (Statements (Old_Node));
                  N2 := First (Statements (New_Node));
                  N2 := First (Statements (New_Node));
 
 
                  while N1 /= Old_F loop
                  while N1 /= Old_F loop
                     Next (N1);
                     Next (N1);
                     Next (N2);
                     Next (N2);
                  end loop;
                  end loop;
 
 
                  Set_First_Real_Statement (New_Node, N2);
                  Set_First_Real_Statement (New_Node, N2);
               end;
               end;
            end if;
            end if;
         end if;
         end if;
 
 
         --  All done, return copied node
         --  All done, return copied node
 
 
         return New_Node;
         return New_Node;
      end Copy_Node_With_Replacement;
      end Copy_Node_With_Replacement;
 
 
      -----------------
      -----------------
      -- Visit_Elist --
      -- Visit_Elist --
      -----------------
      -----------------
 
 
      procedure Visit_Elist (E : Elist_Id) is
      procedure Visit_Elist (E : Elist_Id) is
         Elmt : Elmt_Id;
         Elmt : Elmt_Id;
      begin
      begin
         if Present (E) then
         if Present (E) then
            Elmt := First_Elmt (E);
            Elmt := First_Elmt (E);
 
 
            while Elmt /= No_Elmt loop
            while Elmt /= No_Elmt loop
               Visit_Node (Node (Elmt));
               Visit_Node (Node (Elmt));
               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
            end loop;
            end loop;
         end if;
         end if;
      end Visit_Elist;
      end Visit_Elist;
 
 
      -----------------
      -----------------
      -- Visit_Field --
      -- Visit_Field --
      -----------------
      -----------------
 
 
      procedure Visit_Field (F : Union_Id; N : Node_Id) is
      procedure Visit_Field (F : Union_Id; N : Node_Id) is
      begin
      begin
         if F = Union_Id (Empty) then
         if F = Union_Id (Empty) then
            return;
            return;
 
 
         elsif F in Node_Range then
         elsif F in Node_Range then
 
 
            --  Copy node if it is syntactic, i.e. its parent pointer is
            --  Copy node if it is syntactic, i.e. its parent pointer is
            --  set to point to the field that referenced it (certain
            --  set to point to the field that referenced it (certain
            --  Itypes will also meet this criterion, which is fine, since
            --  Itypes will also meet this criterion, which is fine, since
            --  these are clearly Itypes that do need to be copied, since
            --  these are clearly Itypes that do need to be copied, since
            --  we are copying their parent.)
            --  we are copying their parent.)
 
 
            if Parent (Node_Id (F)) = N then
            if Parent (Node_Id (F)) = N then
               Visit_Node (Node_Id (F));
               Visit_Node (Node_Id (F));
               return;
               return;
 
 
            --  Another case, if we are pointing to an Itype, then we want
            --  Another case, if we are pointing to an Itype, then we want
            --  to copy it if its associated node is somewhere in the tree
            --  to copy it if its associated node is somewhere in the tree
            --  being copied.
            --  being copied.
 
 
            --  Note: the exclusion of self-referential copies is just an
            --  Note: the exclusion of self-referential copies is just an
            --  optimization, since the search of the already copied list
            --  optimization, since the search of the already copied list
            --  would catch it, but it is a common case (Etype pointing
            --  would catch it, but it is a common case (Etype pointing
            --  to itself for an Itype that is a base type).
            --  to itself for an Itype that is a base type).
 
 
            elsif Has_Extension (Node_Id (F))
            elsif Has_Extension (Node_Id (F))
              and then Is_Itype (Entity_Id (F))
              and then Is_Itype (Entity_Id (F))
              and then Node_Id (F) /= N
              and then Node_Id (F) /= N
            then
            then
               declare
               declare
                  P : Node_Id;
                  P : Node_Id;
 
 
               begin
               begin
                  P := Associated_Node_For_Itype (Node_Id (F));
                  P := Associated_Node_For_Itype (Node_Id (F));
                  while Present (P) loop
                  while Present (P) loop
                     if P = Source then
                     if P = Source then
                        Visit_Node (Node_Id (F));
                        Visit_Node (Node_Id (F));
                        return;
                        return;
                     else
                     else
                        P := Parent (P);
                        P := Parent (P);
                     end if;
                     end if;
                  end loop;
                  end loop;
 
 
                  --  An Itype whose parent is not being copied definitely
                  --  An Itype whose parent is not being copied definitely
                  --  should NOT be copied, since it does not belong in any
                  --  should NOT be copied, since it does not belong in any
                  --  sense to the copied subtree.
                  --  sense to the copied subtree.
 
 
                  return;
                  return;
               end;
               end;
            end if;
            end if;
 
 
         elsif F in List_Range
         elsif F in List_Range
           and then Parent (List_Id (F)) = N
           and then Parent (List_Id (F)) = N
         then
         then
            Visit_List (List_Id (F));
            Visit_List (List_Id (F));
            return;
            return;
         end if;
         end if;
      end Visit_Field;
      end Visit_Field;
 
 
      -----------------
      -----------------
      -- Visit_Itype --
      -- Visit_Itype --
      -----------------
      -----------------
 
 
      procedure Visit_Itype (Old_Itype : Entity_Id) is
      procedure Visit_Itype (Old_Itype : Entity_Id) is
         New_Itype : Entity_Id;
         New_Itype : Entity_Id;
         E         : Elmt_Id;
         E         : Elmt_Id;
         Ent       : Entity_Id;
         Ent       : Entity_Id;
 
 
      begin
      begin
         --  Itypes that describe the designated type of access to subprograms
         --  Itypes that describe the designated type of access to subprograms
         --  have the structure of subprogram declarations, with signatures,
         --  have the structure of subprogram declarations, with signatures,
         --  etc. Either we duplicate the signatures completely, or choose to
         --  etc. Either we duplicate the signatures completely, or choose to
         --  share such itypes, which is fine because their elaboration will
         --  share such itypes, which is fine because their elaboration will
         --  have no side effects.
         --  have no side effects.
 
 
         if Ekind (Old_Itype) = E_Subprogram_Type then
         if Ekind (Old_Itype) = E_Subprogram_Type then
            return;
            return;
         end if;
         end if;
 
 
         New_Itype := New_Copy (Old_Itype);
         New_Itype := New_Copy (Old_Itype);
 
 
         --  The new Itype has all the attributes of the old one, and
         --  The new Itype has all the attributes of the old one, and
         --  we just copy the contents of the entity. However, the back-end
         --  we just copy the contents of the entity. However, the back-end
         --  needs different names for debugging purposes, so we create a
         --  needs different names for debugging purposes, so we create a
         --  new internal name for it in all cases.
         --  new internal name for it in all cases.
 
 
         Set_Chars (New_Itype, New_Internal_Name ('T'));
         Set_Chars (New_Itype, New_Internal_Name ('T'));
 
 
         --  If our associated node is an entity that has already been copied,
         --  If our associated node is an entity that has already been copied,
         --  then set the associated node of the copy to point to the right
         --  then set the associated node of the copy to point to the right
         --  copy. If we have copied an Itype that is itself the associated
         --  copy. If we have copied an Itype that is itself the associated
         --  node of some previously copied Itype, then we set the right
         --  node of some previously copied Itype, then we set the right
         --  pointer in the other direction.
         --  pointer in the other direction.
 
 
         if Present (Actual_Map) then
         if Present (Actual_Map) then
 
 
            --  Case of hash tables used
            --  Case of hash tables used
 
 
            if NCT_Hash_Tables_Used then
            if NCT_Hash_Tables_Used then
 
 
               Ent := NCT_Assoc.Get (Associated_Node_For_Itype (Old_Itype));
               Ent := NCT_Assoc.Get (Associated_Node_For_Itype (Old_Itype));
 
 
               if Present (Ent) then
               if Present (Ent) then
                  Set_Associated_Node_For_Itype (New_Itype, Ent);
                  Set_Associated_Node_For_Itype (New_Itype, Ent);
               end if;
               end if;
 
 
               Ent := NCT_Itype_Assoc.Get (Old_Itype);
               Ent := NCT_Itype_Assoc.Get (Old_Itype);
               if Present (Ent) then
               if Present (Ent) then
                  Set_Associated_Node_For_Itype (Ent, New_Itype);
                  Set_Associated_Node_For_Itype (Ent, New_Itype);
 
 
               --  If the hash table has no association for this Itype and
               --  If the hash table has no association for this Itype and
               --  its associated node, enter one now.
               --  its associated node, enter one now.
 
 
               else
               else
                  NCT_Itype_Assoc.Set
                  NCT_Itype_Assoc.Set
                    (Associated_Node_For_Itype (Old_Itype), New_Itype);
                    (Associated_Node_For_Itype (Old_Itype), New_Itype);
               end if;
               end if;
 
 
            --  Case of hash tables not used
            --  Case of hash tables not used
 
 
            else
            else
               E := First_Elmt (Actual_Map);
               E := First_Elmt (Actual_Map);
               while Present (E) loop
               while Present (E) loop
                  if Associated_Node_For_Itype (Old_Itype) = Node (E) then
                  if Associated_Node_For_Itype (Old_Itype) = Node (E) then
                     Set_Associated_Node_For_Itype
                     Set_Associated_Node_For_Itype
                       (New_Itype, Node (Next_Elmt (E)));
                       (New_Itype, Node (Next_Elmt (E)));
                  end if;
                  end if;
 
 
                  if Is_Type (Node (E))
                  if Is_Type (Node (E))
                    and then
                    and then
                      Old_Itype = Associated_Node_For_Itype (Node (E))
                      Old_Itype = Associated_Node_For_Itype (Node (E))
                  then
                  then
                     Set_Associated_Node_For_Itype
                     Set_Associated_Node_For_Itype
                       (Node (Next_Elmt (E)), New_Itype);
                       (Node (Next_Elmt (E)), New_Itype);
                  end if;
                  end if;
 
 
                  E := Next_Elmt (Next_Elmt (E));
                  E := Next_Elmt (Next_Elmt (E));
               end loop;
               end loop;
            end if;
            end if;
         end if;
         end if;
 
 
         if Present (Freeze_Node (New_Itype)) then
         if Present (Freeze_Node (New_Itype)) then
            Set_Is_Frozen (New_Itype, False);
            Set_Is_Frozen (New_Itype, False);
            Set_Freeze_Node (New_Itype, Empty);
            Set_Freeze_Node (New_Itype, Empty);
         end if;
         end if;
 
 
         --  Add new association to map
         --  Add new association to map
 
 
         if No (Actual_Map) then
         if No (Actual_Map) then
            Actual_Map := New_Elmt_List;
            Actual_Map := New_Elmt_List;
         end if;
         end if;
 
 
         Append_Elmt (Old_Itype, Actual_Map);
         Append_Elmt (Old_Itype, Actual_Map);
         Append_Elmt (New_Itype, Actual_Map);
         Append_Elmt (New_Itype, Actual_Map);
 
 
         if NCT_Hash_Tables_Used then
         if NCT_Hash_Tables_Used then
            NCT_Assoc.Set (Old_Itype, New_Itype);
            NCT_Assoc.Set (Old_Itype, New_Itype);
 
 
         else
         else
            NCT_Table_Entries := NCT_Table_Entries + 1;
            NCT_Table_Entries := NCT_Table_Entries + 1;
 
 
            if NCT_Table_Entries > NCT_Hash_Threshhold then
            if NCT_Table_Entries > NCT_Hash_Threshhold then
               Build_NCT_Hash_Tables;
               Build_NCT_Hash_Tables;
            end if;
            end if;
         end if;
         end if;
 
 
         --  If a record subtype is simply copied, the entity list will be
         --  If a record subtype is simply copied, the entity list will be
         --  shared. Thus cloned_Subtype must be set to indicate the sharing.
         --  shared. Thus cloned_Subtype must be set to indicate the sharing.
 
 
         if Ekind (Old_Itype) = E_Record_Subtype
         if Ekind (Old_Itype) = E_Record_Subtype
           or else Ekind (Old_Itype) = E_Class_Wide_Subtype
           or else Ekind (Old_Itype) = E_Class_Wide_Subtype
         then
         then
            Set_Cloned_Subtype (New_Itype, Old_Itype);
            Set_Cloned_Subtype (New_Itype, Old_Itype);
         end if;
         end if;
 
 
         --  Visit descendents that eventually get copied
         --  Visit descendents that eventually get copied
 
 
         Visit_Field (Union_Id (Etype (Old_Itype)), Old_Itype);
         Visit_Field (Union_Id (Etype (Old_Itype)), Old_Itype);
 
 
         if Is_Discrete_Type (Old_Itype) then
         if Is_Discrete_Type (Old_Itype) then
            Visit_Field (Union_Id (Scalar_Range (Old_Itype)), Old_Itype);
            Visit_Field (Union_Id (Scalar_Range (Old_Itype)), Old_Itype);
 
 
         elsif Has_Discriminants (Base_Type (Old_Itype)) then
         elsif Has_Discriminants (Base_Type (Old_Itype)) then
            --  ??? This should involve call to Visit_Field
            --  ??? This should involve call to Visit_Field
            Visit_Elist (Discriminant_Constraint (Old_Itype));
            Visit_Elist (Discriminant_Constraint (Old_Itype));
 
 
         elsif Is_Array_Type (Old_Itype) then
         elsif Is_Array_Type (Old_Itype) then
            if Present (First_Index (Old_Itype)) then
            if Present (First_Index (Old_Itype)) then
               Visit_Field (Union_Id (List_Containing
               Visit_Field (Union_Id (List_Containing
                                (First_Index (Old_Itype))),
                                (First_Index (Old_Itype))),
                            Old_Itype);
                            Old_Itype);
            end if;
            end if;
 
 
            if Is_Packed (Old_Itype) then
            if Is_Packed (Old_Itype) then
               Visit_Field (Union_Id (Packed_Array_Type (Old_Itype)),
               Visit_Field (Union_Id (Packed_Array_Type (Old_Itype)),
                            Old_Itype);
                            Old_Itype);
            end if;
            end if;
         end if;
         end if;
      end Visit_Itype;
      end Visit_Itype;
 
 
      ----------------
      ----------------
      -- Visit_List --
      -- Visit_List --
      ----------------
      ----------------
 
 
      procedure Visit_List (L : List_Id) is
      procedure Visit_List (L : List_Id) is
         N : Node_Id;
         N : Node_Id;
      begin
      begin
         if L /= No_List then
         if L /= No_List then
            N := First (L);
            N := First (L);
 
 
            while Present (N) loop
            while Present (N) loop
               Visit_Node (N);
               Visit_Node (N);
               Next (N);
               Next (N);
            end loop;
            end loop;
         end if;
         end if;
      end Visit_List;
      end Visit_List;
 
 
      ----------------
      ----------------
      -- Visit_Node --
      -- Visit_Node --
      ----------------
      ----------------
 
 
      procedure Visit_Node (N : Node_Or_Entity_Id) is
      procedure Visit_Node (N : Node_Or_Entity_Id) is
 
 
      --  Start of processing for Visit_Node
      --  Start of processing for Visit_Node
 
 
      begin
      begin
         --  Handle case of an Itype, which must be copied
         --  Handle case of an Itype, which must be copied
 
 
         if Has_Extension (N)
         if Has_Extension (N)
           and then Is_Itype (N)
           and then Is_Itype (N)
         then
         then
            --  Nothing to do if already in the list. This can happen with an
            --  Nothing to do if already in the list. This can happen with an
            --  Itype entity that appears more than once in the tree.
            --  Itype entity that appears more than once in the tree.
            --  Note that we do not want to visit descendents in this case.
            --  Note that we do not want to visit descendents in this case.
 
 
            --  Test for already in list when hash table is used
            --  Test for already in list when hash table is used
 
 
            if NCT_Hash_Tables_Used then
            if NCT_Hash_Tables_Used then
               if Present (NCT_Assoc.Get (Entity_Id (N))) then
               if Present (NCT_Assoc.Get (Entity_Id (N))) then
                  return;
                  return;
               end if;
               end if;
 
 
            --  Test for already in list when hash table not used
            --  Test for already in list when hash table not used
 
 
            else
            else
               declare
               declare
                  E : Elmt_Id;
                  E : Elmt_Id;
               begin
               begin
                  if Present (Actual_Map) then
                  if Present (Actual_Map) then
                     E := First_Elmt (Actual_Map);
                     E := First_Elmt (Actual_Map);
                     while Present (E) loop
                     while Present (E) loop
                        if Node (E) = N then
                        if Node (E) = N then
                           return;
                           return;
                        else
                        else
                           E := Next_Elmt (Next_Elmt (E));
                           E := Next_Elmt (Next_Elmt (E));
                        end if;
                        end if;
                     end loop;
                     end loop;
                  end if;
                  end if;
               end;
               end;
            end if;
            end if;
 
 
            Visit_Itype (N);
            Visit_Itype (N);
         end if;
         end if;
 
 
         --  Visit descendents
         --  Visit descendents
 
 
         Visit_Field (Field1 (N), N);
         Visit_Field (Field1 (N), N);
         Visit_Field (Field2 (N), N);
         Visit_Field (Field2 (N), N);
         Visit_Field (Field3 (N), N);
         Visit_Field (Field3 (N), N);
         Visit_Field (Field4 (N), N);
         Visit_Field (Field4 (N), N);
         Visit_Field (Field5 (N), N);
         Visit_Field (Field5 (N), N);
      end Visit_Node;
      end Visit_Node;
 
 
   --  Start of processing for New_Copy_Tree
   --  Start of processing for New_Copy_Tree
 
 
   begin
   begin
      Actual_Map := Map;
      Actual_Map := Map;
 
 
      --  See if we should use hash table
      --  See if we should use hash table
 
 
      if No (Actual_Map) then
      if No (Actual_Map) then
         NCT_Hash_Tables_Used := False;
         NCT_Hash_Tables_Used := False;
 
 
      else
      else
         declare
         declare
            Elmt : Elmt_Id;
            Elmt : Elmt_Id;
 
 
         begin
         begin
            NCT_Table_Entries := 0;
            NCT_Table_Entries := 0;
 
 
            Elmt := First_Elmt (Actual_Map);
            Elmt := First_Elmt (Actual_Map);
            while Present (Elmt) loop
            while Present (Elmt) loop
               NCT_Table_Entries := NCT_Table_Entries + 1;
               NCT_Table_Entries := NCT_Table_Entries + 1;
               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
            end loop;
            end loop;
 
 
            if NCT_Table_Entries > NCT_Hash_Threshhold then
            if NCT_Table_Entries > NCT_Hash_Threshhold then
               Build_NCT_Hash_Tables;
               Build_NCT_Hash_Tables;
            else
            else
               NCT_Hash_Tables_Used := False;
               NCT_Hash_Tables_Used := False;
            end if;
            end if;
         end;
         end;
      end if;
      end if;
 
 
      --  Hash table set up if required, now start phase one by visiting
      --  Hash table set up if required, now start phase one by visiting
      --  top node (we will recursively visit the descendents).
      --  top node (we will recursively visit the descendents).
 
 
      Visit_Node (Source);
      Visit_Node (Source);
 
 
      --  Now the second phase of the copy can start. First we process
      --  Now the second phase of the copy can start. First we process
      --  all the mapped entities, copying their descendents.
      --  all the mapped entities, copying their descendents.
 
 
      if Present (Actual_Map) then
      if Present (Actual_Map) then
         declare
         declare
            Elmt      : Elmt_Id;
            Elmt      : Elmt_Id;
            New_Itype : Entity_Id;
            New_Itype : Entity_Id;
         begin
         begin
            Elmt := First_Elmt (Actual_Map);
            Elmt := First_Elmt (Actual_Map);
            while Present (Elmt) loop
            while Present (Elmt) loop
               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
               New_Itype := Node (Elmt);
               New_Itype := Node (Elmt);
               Copy_Itype_With_Replacement (New_Itype);
               Copy_Itype_With_Replacement (New_Itype);
               Next_Elmt (Elmt);
               Next_Elmt (Elmt);
            end loop;
            end loop;
         end;
         end;
      end if;
      end if;
 
 
      --  Now we can copy the actual tree
      --  Now we can copy the actual tree
 
 
      return Copy_Node_With_Replacement (Source);
      return Copy_Node_With_Replacement (Source);
   end New_Copy_Tree;
   end New_Copy_Tree;
 
 
   -------------------------
   -------------------------
   -- New_External_Entity --
   -- New_External_Entity --
   -------------------------
   -------------------------
 
 
   function New_External_Entity
   function New_External_Entity
     (Kind         : Entity_Kind;
     (Kind         : Entity_Kind;
      Scope_Id     : Entity_Id;
      Scope_Id     : Entity_Id;
      Sloc_Value   : Source_Ptr;
      Sloc_Value   : Source_Ptr;
      Related_Id   : Entity_Id;
      Related_Id   : Entity_Id;
      Suffix       : Character;
      Suffix       : Character;
      Suffix_Index : Nat := 0;
      Suffix_Index : Nat := 0;
      Prefix       : Character := ' ') return Entity_Id
      Prefix       : Character := ' ') return Entity_Id
   is
   is
      N : constant Entity_Id :=
      N : constant Entity_Id :=
            Make_Defining_Identifier (Sloc_Value,
            Make_Defining_Identifier (Sloc_Value,
              New_External_Name
              New_External_Name
                (Chars (Related_Id), Suffix, Suffix_Index, Prefix));
                (Chars (Related_Id), Suffix, Suffix_Index, Prefix));
 
 
   begin
   begin
      Set_Ekind          (N, Kind);
      Set_Ekind          (N, Kind);
      Set_Is_Internal    (N, True);
      Set_Is_Internal    (N, True);
      Append_Entity      (N, Scope_Id);
      Append_Entity      (N, Scope_Id);
      Set_Public_Status  (N);
      Set_Public_Status  (N);
 
 
      if Kind in Type_Kind then
      if Kind in Type_Kind then
         Init_Size_Align (N);
         Init_Size_Align (N);
      end if;
      end if;
 
 
      return N;
      return N;
   end New_External_Entity;
   end New_External_Entity;
 
 
   -------------------------
   -------------------------
   -- New_Internal_Entity --
   -- New_Internal_Entity --
   -------------------------
   -------------------------
 
 
   function New_Internal_Entity
   function New_Internal_Entity
     (Kind       : Entity_Kind;
     (Kind       : Entity_Kind;
      Scope_Id   : Entity_Id;
      Scope_Id   : Entity_Id;
      Sloc_Value : Source_Ptr;
      Sloc_Value : Source_Ptr;
      Id_Char    : Character) return Entity_Id
      Id_Char    : Character) return Entity_Id
   is
   is
      N : constant Entity_Id :=
      N : constant Entity_Id :=
            Make_Defining_Identifier (Sloc_Value, New_Internal_Name (Id_Char));
            Make_Defining_Identifier (Sloc_Value, New_Internal_Name (Id_Char));
 
 
   begin
   begin
      Set_Ekind          (N, Kind);
      Set_Ekind          (N, Kind);
      Set_Is_Internal    (N, True);
      Set_Is_Internal    (N, True);
      Append_Entity      (N, Scope_Id);
      Append_Entity      (N, Scope_Id);
 
 
      if Kind in Type_Kind then
      if Kind in Type_Kind then
         Init_Size_Align (N);
         Init_Size_Align (N);
      end if;
      end if;
 
 
      return N;
      return N;
   end New_Internal_Entity;
   end New_Internal_Entity;
 
 
   -----------------
   -----------------
   -- Next_Actual --
   -- Next_Actual --
   -----------------
   -----------------
 
 
   function Next_Actual (Actual_Id : Node_Id) return Node_Id is
   function Next_Actual (Actual_Id : Node_Id) return Node_Id is
      N  : Node_Id;
      N  : Node_Id;
 
 
   begin
   begin
      --  If we are pointing at a positional parameter, it is a member of a
      --  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
      --  node list (the list of parameters), and the next parameter is the
      --  next node on the list, unless we hit a parameter association, then
      --  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
      --  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
      --  the parent, and then is threaded using the Next_Named_Actual of the
      --  Parameter_Association. All this fiddling is because the original node
      --  Parameter_Association. All this fiddling is because the original node
      --  list is in the textual call order, and what we need is the
      --  list is in the textual call order, and what we need is the
      --  declaration order.
      --  declaration order.
 
 
      if Is_List_Member (Actual_Id) then
      if Is_List_Member (Actual_Id) then
         N := Next (Actual_Id);
         N := Next (Actual_Id);
 
 
         if Nkind (N) = N_Parameter_Association then
         if Nkind (N) = N_Parameter_Association then
            return First_Named_Actual (Parent (Actual_Id));
            return First_Named_Actual (Parent (Actual_Id));
         else
         else
            return N;
            return N;
         end if;
         end if;
 
 
      else
      else
         return Next_Named_Actual (Parent (Actual_Id));
         return Next_Named_Actual (Parent (Actual_Id));
      end if;
      end if;
   end Next_Actual;
   end Next_Actual;
 
 
   procedure Next_Actual (Actual_Id : in out Node_Id) is
   procedure Next_Actual (Actual_Id : in out Node_Id) is
   begin
   begin
      Actual_Id := Next_Actual (Actual_Id);
      Actual_Id := Next_Actual (Actual_Id);
   end Next_Actual;
   end Next_Actual;
 
 
   -----------------------
   -----------------------
   -- Normalize_Actuals --
   -- Normalize_Actuals --
   -----------------------
   -----------------------
 
 
   --  Chain actuals according to formals of subprogram. If there are no named
   --  Chain actuals according to formals of subprogram. If there are no named
   --  associations, the chain is simply the list of Parameter Associations,
   --  associations, the chain is simply the list of Parameter Associations,
   --  since the order is the same as the declaration order. If there are named
   --  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
   --  associations, then the First_Named_Actual field in the N_Function_Call
   --  or N_Procedure_Call_Statement node points to the Parameter_Association
   --  or N_Procedure_Call_Statement node points to the Parameter_Association
   --  node for the parameter that comes first in declaration order. The
   --  node for the parameter that comes first in declaration order. The
   --  remaining named parameters are then chained in declaration order using
   --  remaining named parameters are then chained in declaration order using
   --  Next_Named_Actual.
   --  Next_Named_Actual.
 
 
   --  This routine also verifies that the number of actuals is compatible with
   --  This routine also verifies that the number of actuals is compatible with
   --  the number and default values of formals, but performs no type checking
   --  the number and default values of formals, but performs no type checking
   --  (type checking is done by the caller).
   --  (type checking is done by the caller).
 
 
   --  If the matching succeeds, Success is set to True and the caller proceeds
   --  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
   --  with type-checking. If the match is unsuccessful, then Success is set to
   --  False, and the caller attempts a different interpretation, if there is
   --  False, and the caller attempts a different interpretation, if there is
   --  one.
   --  one.
 
 
   --  If the flag Report is on, the call is not overloaded, and a failure to
   --  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.
   --  match can be reported here, rather than in the caller.
 
 
   procedure Normalize_Actuals
   procedure Normalize_Actuals
     (N       : Node_Id;
     (N       : Node_Id;
      S       : Entity_Id;
      S       : Entity_Id;
      Report  : Boolean;
      Report  : Boolean;
      Success : out Boolean)
      Success : out Boolean)
   is
   is
      Actuals     : constant List_Id := Parameter_Associations (N);
      Actuals     : constant List_Id := Parameter_Associations (N);
      Actual      : Node_Id := Empty;
      Actual      : Node_Id := Empty;
      Formal      : Entity_Id;
      Formal      : Entity_Id;
      Last        : Node_Id := Empty;
      Last        : Node_Id := Empty;
      First_Named : Node_Id := Empty;
      First_Named : Node_Id := Empty;
      Found       : Boolean;
      Found       : Boolean;
 
 
      Formals_To_Match : Integer := 0;
      Formals_To_Match : Integer := 0;
      Actuals_To_Match : Integer := 0;
      Actuals_To_Match : Integer := 0;
 
 
      procedure Chain (A : Node_Id);
      procedure Chain (A : Node_Id);
      --  Add named actual at the proper place in the list, using the
      --  Add named actual at the proper place in the list, using the
      --  Next_Named_Actual link.
      --  Next_Named_Actual link.
 
 
      function Reporting return Boolean;
      function Reporting return Boolean;
      --  Determines if an error is to be reported. To report an error, we
      --  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
      --  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
      --  by calls to init procs that occur within other init procs. Such
      --  errors must always be cascaded errors, since if all the types are
      --  errors must always be cascaded errors, since if all the types are
      --  declared correctly, the compiler will certainly build decent calls!
      --  declared correctly, the compiler will certainly build decent calls!
 
 
      -----------
      -----------
      -- Chain --
      -- Chain --
      -----------
      -----------
 
 
      procedure Chain (A : Node_Id) is
      procedure Chain (A : Node_Id) is
      begin
      begin
         if No (Last) then
         if No (Last) then
 
 
            --  Call node points to first actual in list
            --  Call node points to first actual in list
 
 
            Set_First_Named_Actual (N, Explicit_Actual_Parameter (A));
            Set_First_Named_Actual (N, Explicit_Actual_Parameter (A));
 
 
         else
         else
            Set_Next_Named_Actual (Last, Explicit_Actual_Parameter (A));
            Set_Next_Named_Actual (Last, Explicit_Actual_Parameter (A));
         end if;
         end if;
 
 
         Last := A;
         Last := A;
         Set_Next_Named_Actual (Last, Empty);
         Set_Next_Named_Actual (Last, Empty);
      end Chain;
      end Chain;
 
 
      ---------------
      ---------------
      -- Reporting --
      -- Reporting --
      ---------------
      ---------------
 
 
      function Reporting return Boolean is
      function Reporting return Boolean is
      begin
      begin
         if not Report then
         if not Report then
            return False;
            return False;
 
 
         elsif not Within_Init_Proc then
         elsif not Within_Init_Proc then
            return True;
            return True;
 
 
         elsif Is_Init_Proc (Entity (Name (N))) then
         elsif Is_Init_Proc (Entity (Name (N))) then
            return False;
            return False;
 
 
         else
         else
            return True;
            return True;
         end if;
         end if;
      end Reporting;
      end Reporting;
 
 
   --  Start of processing for Normalize_Actuals
   --  Start of processing for Normalize_Actuals
 
 
   begin
   begin
      if Is_Access_Type (S) then
      if Is_Access_Type (S) then
 
 
         --  The name in the call is a function call that returns an access
         --  The name in the call is a function call that returns an access
         --  to subprogram. The designated type has the list of formals.
         --  to subprogram. The designated type has the list of formals.
 
 
         Formal := First_Formal (Designated_Type (S));
         Formal := First_Formal (Designated_Type (S));
      else
      else
         Formal := First_Formal (S);
         Formal := First_Formal (S);
      end if;
      end if;
 
 
      while Present (Formal) loop
      while Present (Formal) loop
         Formals_To_Match := Formals_To_Match + 1;
         Formals_To_Match := Formals_To_Match + 1;
         Next_Formal (Formal);
         Next_Formal (Formal);
      end loop;
      end loop;
 
 
      --  Find if there is a named association, and verify that no positional
      --  Find if there is a named association, and verify that no positional
      --  associations appear after named ones.
      --  associations appear after named ones.
 
 
      if Present (Actuals) then
      if Present (Actuals) then
         Actual := First (Actuals);
         Actual := First (Actuals);
      end if;
      end if;
 
 
      while Present (Actual)
      while Present (Actual)
        and then Nkind (Actual) /= N_Parameter_Association
        and then Nkind (Actual) /= N_Parameter_Association
      loop
      loop
         Actuals_To_Match := Actuals_To_Match + 1;
         Actuals_To_Match := Actuals_To_Match + 1;
         Next (Actual);
         Next (Actual);
      end loop;
      end loop;
 
 
      if No (Actual) and Actuals_To_Match = Formals_To_Match then
      if No (Actual) and Actuals_To_Match = Formals_To_Match then
 
 
         --  Most common case: positional notation, no defaults
         --  Most common case: positional notation, no defaults
 
 
         Success := True;
         Success := True;
         return;
         return;
 
 
      elsif Actuals_To_Match > Formals_To_Match then
      elsif Actuals_To_Match > Formals_To_Match then
 
 
         --  Too many actuals: will not work
         --  Too many actuals: will not work
 
 
         if Reporting then
         if Reporting then
            if Is_Entity_Name (Name (N)) then
            if Is_Entity_Name (Name (N)) then
               Error_Msg_N ("too many arguments in call to&", Name (N));
               Error_Msg_N ("too many arguments in call to&", Name (N));
            else
            else
               Error_Msg_N ("too many arguments in call", N);
               Error_Msg_N ("too many arguments in call", N);
            end if;
            end if;
         end if;
         end if;
 
 
         Success := False;
         Success := False;
         return;
         return;
      end if;
      end if;
 
 
      First_Named := Actual;
      First_Named := Actual;
 
 
      while Present (Actual) loop
      while Present (Actual) loop
         if Nkind (Actual) /= N_Parameter_Association then
         if Nkind (Actual) /= N_Parameter_Association then
            Error_Msg_N
            Error_Msg_N
              ("positional parameters not allowed after named ones", Actual);
              ("positional parameters not allowed after named ones", Actual);
            Success := False;
            Success := False;
            return;
            return;
 
 
         else
         else
            Actuals_To_Match := Actuals_To_Match + 1;
            Actuals_To_Match := Actuals_To_Match + 1;
         end if;
         end if;
 
 
         Next (Actual);
         Next (Actual);
      end loop;
      end loop;
 
 
      if Present (Actuals) then
      if Present (Actuals) then
         Actual := First (Actuals);
         Actual := First (Actuals);
      end if;
      end if;
 
 
      Formal := First_Formal (S);
      Formal := First_Formal (S);
      while Present (Formal) loop
      while Present (Formal) loop
 
 
         --  Match the formals in order. If the corresponding actual is
         --  Match the formals in order. If the corresponding actual is
         --  positional, nothing to do. Else scan the list of named actuals
         --  positional, nothing to do. Else scan the list of named actuals
         --  to find the one with the right name.
         --  to find the one with the right name.
 
 
         if Present (Actual)
         if Present (Actual)
           and then Nkind (Actual) /= N_Parameter_Association
           and then Nkind (Actual) /= N_Parameter_Association
         then
         then
            Next (Actual);
            Next (Actual);
            Actuals_To_Match := Actuals_To_Match - 1;
            Actuals_To_Match := Actuals_To_Match - 1;
            Formals_To_Match := Formals_To_Match - 1;
            Formals_To_Match := Formals_To_Match - 1;
 
 
         else
         else
            --  For named parameters, search the list of actuals to find
            --  For named parameters, search the list of actuals to find
            --  one that matches the next formal name.
            --  one that matches the next formal name.
 
 
            Actual := First_Named;
            Actual := First_Named;
            Found  := False;
            Found  := False;
            while Present (Actual) loop
            while Present (Actual) loop
               if Chars (Selector_Name (Actual)) = Chars (Formal) then
               if Chars (Selector_Name (Actual)) = Chars (Formal) then
                  Found := True;
                  Found := True;
                  Chain (Actual);
                  Chain (Actual);
                  Actuals_To_Match := Actuals_To_Match - 1;
                  Actuals_To_Match := Actuals_To_Match - 1;
                  Formals_To_Match := Formals_To_Match - 1;
                  Formals_To_Match := Formals_To_Match - 1;
                  exit;
                  exit;
               end if;
               end if;
 
 
               Next (Actual);
               Next (Actual);
            end loop;
            end loop;
 
 
            if not Found then
            if not Found then
               if Ekind (Formal) /= E_In_Parameter
               if Ekind (Formal) /= E_In_Parameter
                 or else No (Default_Value (Formal))
                 or else No (Default_Value (Formal))
               then
               then
                  if Reporting then
                  if Reporting then
                     if (Comes_From_Source (S)
                     if (Comes_From_Source (S)
                          or else Sloc (S) = Standard_Location)
                          or else Sloc (S) = Standard_Location)
                       and then Is_Overloadable (S)
                       and then Is_Overloadable (S)
                     then
                     then
                        if No (Actuals)
                        if No (Actuals)
                          and then
                          and then
                           (Nkind (Parent (N)) = N_Procedure_Call_Statement
                           (Nkind (Parent (N)) = N_Procedure_Call_Statement
                             or else
                             or else
                           (Nkind (Parent (N)) = N_Function_Call
                           (Nkind (Parent (N)) = N_Function_Call
                             or else
                             or else
                            Nkind (Parent (N)) = N_Parameter_Association))
                            Nkind (Parent (N)) = N_Parameter_Association))
                          and then Ekind (S) /= E_Function
                          and then Ekind (S) /= E_Function
                        then
                        then
                           Set_Etype (N, Etype (S));
                           Set_Etype (N, Etype (S));
                        else
                        else
                           Error_Msg_Name_1 := Chars (S);
                           Error_Msg_Name_1 := Chars (S);
                           Error_Msg_Sloc := Sloc (S);
                           Error_Msg_Sloc := Sloc (S);
                           Error_Msg_NE
                           Error_Msg_NE
                             ("missing argument for parameter & " &
                             ("missing argument for parameter & " &
                                "in call to % declared #", N, Formal);
                                "in call to % declared #", N, Formal);
                        end if;
                        end if;
 
 
                     elsif Is_Overloadable (S) then
                     elsif Is_Overloadable (S) then
                        Error_Msg_Name_1 := Chars (S);
                        Error_Msg_Name_1 := Chars (S);
 
 
                        --  Point to type derivation that generated the
                        --  Point to type derivation that generated the
                        --  operation.
                        --  operation.
 
 
                        Error_Msg_Sloc := Sloc (Parent (S));
                        Error_Msg_Sloc := Sloc (Parent (S));
 
 
                        Error_Msg_NE
                        Error_Msg_NE
                          ("missing argument for parameter & " &
                          ("missing argument for parameter & " &
                             "in call to % (inherited) #", N, Formal);
                             "in call to % (inherited) #", N, Formal);
 
 
                     else
                     else
                        Error_Msg_NE
                        Error_Msg_NE
                          ("missing argument for parameter &", N, Formal);
                          ("missing argument for parameter &", N, Formal);
                     end if;
                     end if;
                  end if;
                  end if;
 
 
                  Success := False;
                  Success := False;
                  return;
                  return;
 
 
               else
               else
                  Formals_To_Match := Formals_To_Match - 1;
                  Formals_To_Match := Formals_To_Match - 1;
               end if;
               end if;
            end if;
            end if;
         end if;
         end if;
 
 
         Next_Formal (Formal);
         Next_Formal (Formal);
      end loop;
      end loop;
 
 
      if Formals_To_Match = 0 and then Actuals_To_Match = 0 then
      if Formals_To_Match = 0 and then Actuals_To_Match = 0 then
         Success := True;
         Success := True;
         return;
         return;
 
 
      else
      else
         if Reporting then
         if Reporting then
 
 
            --  Find some superfluous named actual that did not get
            --  Find some superfluous named actual that did not get
            --  attached to the list of associations.
            --  attached to the list of associations.
 
 
            Actual := First (Actuals);
            Actual := First (Actuals);
            while Present (Actual) loop
            while Present (Actual) loop
               if Nkind (Actual) = N_Parameter_Association
               if Nkind (Actual) = N_Parameter_Association
                 and then Actual /= Last
                 and then Actual /= Last
                 and then No (Next_Named_Actual (Actual))
                 and then No (Next_Named_Actual (Actual))
               then
               then
                  Error_Msg_N ("unmatched actual & in call",
                  Error_Msg_N ("unmatched actual & in call",
                    Selector_Name (Actual));
                    Selector_Name (Actual));
                  exit;
                  exit;
               end if;
               end if;
 
 
               Next (Actual);
               Next (Actual);
            end loop;
            end loop;
         end if;
         end if;
 
 
         Success := False;
         Success := False;
         return;
         return;
      end if;
      end if;
   end Normalize_Actuals;
   end Normalize_Actuals;
 
 
   --------------------------------
   --------------------------------
   -- Note_Possible_Modification --
   -- Note_Possible_Modification --
   --------------------------------
   --------------------------------
 
 
   procedure Note_Possible_Modification (N : Node_Id; Sure : Boolean) is
   procedure Note_Possible_Modification (N : Node_Id; Sure : Boolean) is
      Modification_Comes_From_Source : constant Boolean :=
      Modification_Comes_From_Source : constant Boolean :=
                                         Comes_From_Source (Parent (N));
                                         Comes_From_Source (Parent (N));
 
 
      Ent : Entity_Id;
      Ent : Entity_Id;
      Exp : Node_Id;
      Exp : Node_Id;
 
 
   begin
   begin
      --  Loop to find referenced entity, if there is one
      --  Loop to find referenced entity, if there is one
 
 
      Exp := N;
      Exp := N;
      loop
      loop
         <<Continue>>
         <<Continue>>
         Ent := Empty;
         Ent := Empty;
 
 
         if Is_Entity_Name (Exp) then
         if Is_Entity_Name (Exp) then
            Ent := Entity (Exp);
            Ent := Entity (Exp);
 
 
            --  If the entity is missing, it is an undeclared identifier,
            --  If the entity is missing, it is an undeclared identifier,
            --  and there is nothing to annotate.
            --  and there is nothing to annotate.
 
 
            if No (Ent) then
            if No (Ent) then
               return;
               return;
            end if;
            end if;
 
 
         elsif Nkind (Exp) = N_Explicit_Dereference then
         elsif Nkind (Exp) = N_Explicit_Dereference then
            declare
            declare
               P : constant Node_Id := Prefix (Exp);
               P : constant Node_Id := Prefix (Exp);
 
 
            begin
            begin
               if Nkind (P) = N_Selected_Component
               if Nkind (P) = N_Selected_Component
                 and then Present (
                 and then Present (
                   Entry_Formal (Entity (Selector_Name (P))))
                   Entry_Formal (Entity (Selector_Name (P))))
               then
               then
                  --  Case of a reference to an entry formal
                  --  Case of a reference to an entry formal
 
 
                  Ent := Entry_Formal (Entity (Selector_Name (P)));
                  Ent := Entry_Formal (Entity (Selector_Name (P)));
 
 
               elsif Nkind (P) = N_Identifier
               elsif Nkind (P) = N_Identifier
                 and then Nkind (Parent (Entity (P))) = N_Object_Declaration
                 and then Nkind (Parent (Entity (P))) = N_Object_Declaration
                 and then Present (Expression (Parent (Entity (P))))
                 and then Present (Expression (Parent (Entity (P))))
                 and then Nkind (Expression (Parent (Entity (P))))
                 and then Nkind (Expression (Parent (Entity (P))))
                   = N_Reference
                   = N_Reference
               then
               then
                  --  Case of a reference to a value on which side effects have
                  --  Case of a reference to a value on which side effects have
                  --  been removed.
                  --  been removed.
 
 
                  Exp := Prefix (Expression (Parent (Entity (P))));
                  Exp := Prefix (Expression (Parent (Entity (P))));
                  goto Continue;
                  goto Continue;
 
 
               else
               else
                  return;
                  return;
 
 
               end if;
               end if;
            end;
            end;
 
 
         elsif     Nkind (Exp) = N_Type_Conversion
         elsif     Nkind (Exp) = N_Type_Conversion
           or else Nkind (Exp) = N_Unchecked_Type_Conversion
           or else Nkind (Exp) = N_Unchecked_Type_Conversion
         then
         then
            Exp := Expression (Exp);
            Exp := Expression (Exp);
            goto Continue;
            goto Continue;
 
 
         elsif     Nkind (Exp) = N_Slice
         elsif     Nkind (Exp) = N_Slice
           or else Nkind (Exp) = N_Indexed_Component
           or else Nkind (Exp) = N_Indexed_Component
           or else Nkind (Exp) = N_Selected_Component
           or else Nkind (Exp) = N_Selected_Component
         then
         then
            Exp := Prefix (Exp);
            Exp := Prefix (Exp);
            goto Continue;
            goto Continue;
 
 
         else
         else
            return;
            return;
         end if;
         end if;
 
 
         --  Now look for entity being referenced
         --  Now look for entity being referenced
 
 
         if Present (Ent) then
         if Present (Ent) then
            if Is_Object (Ent) then
            if Is_Object (Ent) then
               if Comes_From_Source (Exp)
               if Comes_From_Source (Exp)
                 or else Modification_Comes_From_Source
                 or else Modification_Comes_From_Source
               then
               then
                  if Has_Pragma_Unmodified (Ent) then
                  if Has_Pragma_Unmodified (Ent) then
                     Error_Msg_NE ("?pragma Unmodified given for &!", N, Ent);
                     Error_Msg_NE ("?pragma Unmodified given for &!", N, Ent);
                  end if;
                  end if;
 
 
                  Set_Never_Set_In_Source (Ent, False);
                  Set_Never_Set_In_Source (Ent, False);
               end if;
               end if;
 
 
               Set_Is_True_Constant (Ent, False);
               Set_Is_True_Constant (Ent, False);
               Set_Current_Value    (Ent, Empty);
               Set_Current_Value    (Ent, Empty);
               Set_Is_Known_Null    (Ent, False);
               Set_Is_Known_Null    (Ent, False);
 
 
               if not Can_Never_Be_Null (Ent) then
               if not Can_Never_Be_Null (Ent) then
                  Set_Is_Known_Non_Null (Ent, False);
                  Set_Is_Known_Non_Null (Ent, False);
               end if;
               end if;
 
 
               --  Follow renaming chain
               --  Follow renaming chain
 
 
               if (Ekind (Ent) = E_Variable or else Ekind (Ent) = E_Constant)
               if (Ekind (Ent) = E_Variable or else Ekind (Ent) = E_Constant)
                 and then Present (Renamed_Object (Ent))
                 and then Present (Renamed_Object (Ent))
               then
               then
                  Exp := Renamed_Object (Ent);
                  Exp := Renamed_Object (Ent);
                  goto Continue;
                  goto Continue;
               end if;
               end if;
 
 
               --  Generate a reference only if the assignment comes from
               --  Generate a reference only if the assignment comes from
               --  source. This excludes, for example, calls to a dispatching
               --  source. This excludes, for example, calls to a dispatching
               --  assignment operation when the left-hand side is tagged.
               --  assignment operation when the left-hand side is tagged.
 
 
               if Modification_Comes_From_Source then
               if Modification_Comes_From_Source then
                  Generate_Reference (Ent, Exp, 'm');
                  Generate_Reference (Ent, Exp, 'm');
               end if;
               end if;
 
 
               Check_Nested_Access (Ent);
               Check_Nested_Access (Ent);
            end if;
            end if;
 
 
            Kill_Checks (Ent);
            Kill_Checks (Ent);
 
 
            --  If we are sure this is a modification from source, and we know
            --  If we are sure this is a modification from source, and we know
            --  this modifies a constant, then give an appropriate warning.
            --  this modifies a constant, then give an appropriate warning.
 
 
            if Overlays_Constant (Ent)
            if Overlays_Constant (Ent)
              and then Modification_Comes_From_Source
              and then Modification_Comes_From_Source
              and then Sure
              and then Sure
            then
            then
               declare
               declare
                  A : constant Node_Id := Address_Clause (Ent);
                  A : constant Node_Id := Address_Clause (Ent);
               begin
               begin
                  if Present (A) then
                  if Present (A) then
                     declare
                     declare
                        Exp : constant Node_Id := Expression (A);
                        Exp : constant Node_Id := Expression (A);
                     begin
                     begin
                        if Nkind (Exp) = N_Attribute_Reference
                        if Nkind (Exp) = N_Attribute_Reference
                          and then Attribute_Name (Exp) = Name_Address
                          and then Attribute_Name (Exp) = Name_Address
                          and then Is_Entity_Name (Prefix (Exp))
                          and then Is_Entity_Name (Prefix (Exp))
                        then
                        then
                           Error_Msg_Sloc := Sloc (A);
                           Error_Msg_Sloc := Sloc (A);
                           Error_Msg_NE
                           Error_Msg_NE
                             ("constant& may be modified via address clause#?",
                             ("constant& may be modified via address clause#?",
                              N, Entity (Prefix (Exp)));
                              N, Entity (Prefix (Exp)));
                        end if;
                        end if;
                     end;
                     end;
                  end if;
                  end if;
               end;
               end;
            end if;
            end if;
 
 
            return;
            return;
         end if;
         end if;
      end loop;
      end loop;
   end Note_Possible_Modification;
   end Note_Possible_Modification;
 
 
   -------------------------
   -------------------------
   -- Object_Access_Level --
   -- Object_Access_Level --
   -------------------------
   -------------------------
 
 
   function Object_Access_Level (Obj : Node_Id) return Uint is
   function Object_Access_Level (Obj : Node_Id) return Uint is
      E : Entity_Id;
      E : Entity_Id;
 
 
   --  Returns the static accessibility level of the view denoted by Obj. Note
   --  Returns the static accessibility level of the view denoted by Obj. Note
   --  that the value returned is the result of a call to Scope_Depth. Only
   --  that the value returned is the result of a call to Scope_Depth. Only
   --  scope depths associated with dynamic scopes can actually be returned.
   --  scope depths associated with dynamic scopes can actually be returned.
   --  Since only relative levels matter for accessibility checking, the fact
   --  Since only relative levels matter for accessibility checking, the fact
   --  that the distance between successive levels of accessibility is not
   --  that the distance between successive levels of accessibility is not
   --  always one is immaterial (invariant: if level(E2) is deeper than
   --  always one is immaterial (invariant: if level(E2) is deeper than
   --  level(E1), then Scope_Depth(E1) < Scope_Depth(E2)).
   --  level(E1), then Scope_Depth(E1) < Scope_Depth(E2)).
 
 
      function Reference_To (Obj : Node_Id) return Node_Id;
      function Reference_To (Obj : Node_Id) return Node_Id;
      --  An explicit dereference is created when removing side-effects from
      --  An explicit dereference is created when removing side-effects from
      --  expressions for constraint checking purposes. In this case a local
      --  expressions for constraint checking purposes. In this case a local
      --  access type is created for it. The correct access level is that of
      --  access type is created for it. The correct access level is that of
      --  the original source node. We detect this case by noting that the
      --  the original source node. We detect this case by noting that the
      --  prefix of the dereference is created by an object declaration whose
      --  prefix of the dereference is created by an object declaration whose
      --  initial expression is a reference.
      --  initial expression is a reference.
 
 
      ------------------
      ------------------
      -- Reference_To --
      -- Reference_To --
      ------------------
      ------------------
 
 
      function Reference_To (Obj : Node_Id) return Node_Id is
      function Reference_To (Obj : Node_Id) return Node_Id is
         Pref : constant Node_Id := Prefix (Obj);
         Pref : constant Node_Id := Prefix (Obj);
      begin
      begin
         if Is_Entity_Name (Pref)
         if Is_Entity_Name (Pref)
           and then Nkind (Parent (Entity (Pref))) = N_Object_Declaration
           and then Nkind (Parent (Entity (Pref))) = N_Object_Declaration
           and then Present (Expression (Parent (Entity (Pref))))
           and then Present (Expression (Parent (Entity (Pref))))
           and then Nkind (Expression (Parent (Entity (Pref)))) = N_Reference
           and then Nkind (Expression (Parent (Entity (Pref)))) = N_Reference
         then
         then
            return (Prefix (Expression (Parent (Entity (Pref)))));
            return (Prefix (Expression (Parent (Entity (Pref)))));
         else
         else
            return Empty;
            return Empty;
         end if;
         end if;
      end Reference_To;
      end Reference_To;
 
 
   --  Start of processing for Object_Access_Level
   --  Start of processing for Object_Access_Level
 
 
   begin
   begin
      if Is_Entity_Name (Obj) then
      if Is_Entity_Name (Obj) then
         E := Entity (Obj);
         E := Entity (Obj);
 
 
         if Is_Prival (E) then
         if Is_Prival (E) then
            E := Prival_Link (E);
            E := Prival_Link (E);
         end if;
         end if;
 
 
         --  If E is a type then it denotes a current instance. For this case
         --  If E is a type then it denotes a current instance. For this case
         --  we add one to the normal accessibility level of the type to ensure
         --  we add one to the normal accessibility level of the type to ensure
         --  that current instances are treated as always being deeper than
         --  that current instances are treated as always being deeper than
         --  than the level of any visible named access type (see 3.10.2(21)).
         --  than the level of any visible named access type (see 3.10.2(21)).
 
 
         if Is_Type (E) then
         if Is_Type (E) then
            return Type_Access_Level (E) +  1;
            return Type_Access_Level (E) +  1;
 
 
         elsif Present (Renamed_Object (E)) then
         elsif Present (Renamed_Object (E)) then
            return Object_Access_Level (Renamed_Object (E));
            return Object_Access_Level (Renamed_Object (E));
 
 
         --  Similarly, if E is a component of the current instance of a
         --  Similarly, if E is a component of the current instance of a
         --  protected type, any instance of it is assumed to be at a deeper
         --  protected type, any instance of it is assumed to be at a deeper
         --  level than the type. For a protected object (whose type is an
         --  level than the type. For a protected object (whose type is an
         --  anonymous protected type) its components are at the same level
         --  anonymous protected type) its components are at the same level
         --  as the type itself.
         --  as the type itself.
 
 
         elsif not Is_Overloadable (E)
         elsif not Is_Overloadable (E)
           and then Ekind (Scope (E)) = E_Protected_Type
           and then Ekind (Scope (E)) = E_Protected_Type
           and then Comes_From_Source (Scope (E))
           and then Comes_From_Source (Scope (E))
         then
         then
            return Type_Access_Level (Scope (E)) + 1;
            return Type_Access_Level (Scope (E)) + 1;
 
 
         else
         else
            return Scope_Depth (Enclosing_Dynamic_Scope (E));
            return Scope_Depth (Enclosing_Dynamic_Scope (E));
         end if;
         end if;
 
 
      elsif Nkind (Obj) = N_Selected_Component then
      elsif Nkind (Obj) = N_Selected_Component then
         if Is_Access_Type (Etype (Prefix (Obj))) then
         if Is_Access_Type (Etype (Prefix (Obj))) then
            return Type_Access_Level (Etype (Prefix (Obj)));
            return Type_Access_Level (Etype (Prefix (Obj)));
         else
         else
            return Object_Access_Level (Prefix (Obj));
            return Object_Access_Level (Prefix (Obj));
         end if;
         end if;
 
 
      elsif Nkind (Obj) = N_Indexed_Component then
      elsif Nkind (Obj) = N_Indexed_Component then
         if Is_Access_Type (Etype (Prefix (Obj))) then
         if Is_Access_Type (Etype (Prefix (Obj))) then
            return Type_Access_Level (Etype (Prefix (Obj)));
            return Type_Access_Level (Etype (Prefix (Obj)));
         else
         else
            return Object_Access_Level (Prefix (Obj));
            return Object_Access_Level (Prefix (Obj));
         end if;
         end if;
 
 
      elsif Nkind (Obj) = N_Explicit_Dereference then
      elsif Nkind (Obj) = N_Explicit_Dereference then
 
 
         --  If the prefix is a selected access discriminant then we make a
         --  If the prefix is a selected access discriminant then we make a
         --  recursive call on the prefix, which will in turn check the level
         --  recursive call on the prefix, which will in turn check the level
         --  of the prefix object of the selected discriminant.
         --  of the prefix object of the selected discriminant.
 
 
         if Nkind (Prefix (Obj)) = N_Selected_Component
         if Nkind (Prefix (Obj)) = N_Selected_Component
           and then Ekind (Etype (Prefix (Obj))) = E_Anonymous_Access_Type
           and then Ekind (Etype (Prefix (Obj))) = E_Anonymous_Access_Type
           and then
           and then
             Ekind (Entity (Selector_Name (Prefix (Obj)))) = E_Discriminant
             Ekind (Entity (Selector_Name (Prefix (Obj)))) = E_Discriminant
         then
         then
            return Object_Access_Level (Prefix (Obj));
            return Object_Access_Level (Prefix (Obj));
 
 
         elsif not (Comes_From_Source (Obj)) then
         elsif not (Comes_From_Source (Obj)) then
            declare
            declare
               Ref : constant Node_Id := Reference_To (Obj);
               Ref : constant Node_Id := Reference_To (Obj);
            begin
            begin
               if Present (Ref) then
               if Present (Ref) then
                  return Object_Access_Level (Ref);
                  return Object_Access_Level (Ref);
               else
               else
                  return Type_Access_Level (Etype (Prefix (Obj)));
                  return Type_Access_Level (Etype (Prefix (Obj)));
               end if;
               end if;
            end;
            end;
 
 
         else
         else
            return Type_Access_Level (Etype (Prefix (Obj)));
            return Type_Access_Level (Etype (Prefix (Obj)));
         end if;
         end if;
 
 
      elsif Nkind (Obj) = N_Type_Conversion
      elsif Nkind (Obj) = N_Type_Conversion
        or else Nkind (Obj) = N_Unchecked_Type_Conversion
        or else Nkind (Obj) = N_Unchecked_Type_Conversion
      then
      then
         return Object_Access_Level (Expression (Obj));
         return Object_Access_Level (Expression (Obj));
 
 
      --  Function results are objects, so we get either the access level of
      --  Function results are objects, so we get either the access level of
      --  the function or, in the case of an indirect call, the level of the
      --  the function or, in the case of an indirect call, the level of the
      --  access-to-subprogram type.
      --  access-to-subprogram type.
 
 
      elsif Nkind (Obj) = N_Function_Call then
      elsif Nkind (Obj) = N_Function_Call then
         if Is_Entity_Name (Name (Obj)) then
         if Is_Entity_Name (Name (Obj)) then
            return Subprogram_Access_Level (Entity (Name (Obj)));
            return Subprogram_Access_Level (Entity (Name (Obj)));
         else
         else
            return Type_Access_Level (Etype (Prefix (Name (Obj))));
            return Type_Access_Level (Etype (Prefix (Name (Obj))));
         end if;
         end if;
 
 
      --  For convenience we handle qualified expressions, even though
      --  For convenience we handle qualified expressions, even though
      --  they aren't technically object names.
      --  they aren't technically object names.
 
 
      elsif Nkind (Obj) = N_Qualified_Expression then
      elsif Nkind (Obj) = N_Qualified_Expression then
         return Object_Access_Level (Expression (Obj));
         return Object_Access_Level (Expression (Obj));
 
 
      --  Otherwise return the scope level of Standard.
      --  Otherwise return the scope level of Standard.
      --  (If there are cases that fall through
      --  (If there are cases that fall through
      --  to this point they will be treated as
      --  to this point they will be treated as
      --  having global accessibility for now. ???)
      --  having global accessibility for now. ???)
 
 
      else
      else
         return Scope_Depth (Standard_Standard);
         return Scope_Depth (Standard_Standard);
      end if;
      end if;
   end Object_Access_Level;
   end Object_Access_Level;
 
 
   -----------------------
   -----------------------
   -- Private_Component --
   -- Private_Component --
   -----------------------
   -----------------------
 
 
   function Private_Component (Type_Id : Entity_Id) return Entity_Id is
   function Private_Component (Type_Id : Entity_Id) return Entity_Id is
      Ancestor  : constant Entity_Id := Base_Type (Type_Id);
      Ancestor  : constant Entity_Id := Base_Type (Type_Id);
 
 
      function Trace_Components
      function Trace_Components
        (T     : Entity_Id;
        (T     : Entity_Id;
         Check : Boolean) return Entity_Id;
         Check : Boolean) return Entity_Id;
      --  Recursive function that does the work, and checks against circular
      --  Recursive function that does the work, and checks against circular
      --  definition for each subcomponent type.
      --  definition for each subcomponent type.
 
 
      ----------------------
      ----------------------
      -- Trace_Components --
      -- Trace_Components --
      ----------------------
      ----------------------
 
 
      function Trace_Components
      function Trace_Components
         (T     : Entity_Id;
         (T     : Entity_Id;
          Check : Boolean) return Entity_Id
          Check : Boolean) return Entity_Id
       is
       is
         Btype     : constant Entity_Id := Base_Type (T);
         Btype     : constant Entity_Id := Base_Type (T);
         Component : Entity_Id;
         Component : Entity_Id;
         P         : Entity_Id;
         P         : Entity_Id;
         Candidate : Entity_Id := Empty;
         Candidate : Entity_Id := Empty;
 
 
      begin
      begin
         if Check and then Btype = Ancestor then
         if Check and then Btype = Ancestor then
            Error_Msg_N ("circular type definition", Type_Id);
            Error_Msg_N ("circular type definition", Type_Id);
            return Any_Type;
            return Any_Type;
         end if;
         end if;
 
 
         if Is_Private_Type (Btype)
         if Is_Private_Type (Btype)
           and then not Is_Generic_Type (Btype)
           and then not Is_Generic_Type (Btype)
         then
         then
            if Present (Full_View (Btype))
            if Present (Full_View (Btype))
              and then Is_Record_Type (Full_View (Btype))
              and then Is_Record_Type (Full_View (Btype))
              and then not Is_Frozen (Btype)
              and then not Is_Frozen (Btype)
            then
            then
               --  To indicate that the ancestor depends on a private type, the
               --  To indicate that the ancestor depends on a private type, the
               --  current Btype is sufficient. However, to check for circular
               --  current Btype is sufficient. However, to check for circular
               --  definition we must recurse on the full view.
               --  definition we must recurse on the full view.
 
 
               Candidate := Trace_Components (Full_View (Btype), True);
               Candidate := Trace_Components (Full_View (Btype), True);
 
 
               if Candidate = Any_Type then
               if Candidate = Any_Type then
                  return Any_Type;
                  return Any_Type;
               else
               else
                  return Btype;
                  return Btype;
               end if;
               end if;
 
 
            else
            else
               return Btype;
               return Btype;
            end if;
            end if;
 
 
         elsif Is_Array_Type (Btype) then
         elsif Is_Array_Type (Btype) then
            return Trace_Components (Component_Type (Btype), True);
            return Trace_Components (Component_Type (Btype), True);
 
 
         elsif Is_Record_Type (Btype) then
         elsif Is_Record_Type (Btype) then
            Component := First_Entity (Btype);
            Component := First_Entity (Btype);
            while Present (Component) loop
            while Present (Component) loop
 
 
               --  Skip anonymous types generated by constrained components
               --  Skip anonymous types generated by constrained components
 
 
               if not Is_Type (Component) then
               if not Is_Type (Component) then
                  P := Trace_Components (Etype (Component), True);
                  P := Trace_Components (Etype (Component), True);
 
 
                  if Present (P) then
                  if Present (P) then
                     if P = Any_Type then
                     if P = Any_Type then
                        return P;
                        return P;
                     else
                     else
                        Candidate := P;
                        Candidate := P;
                     end if;
                     end if;
                  end if;
                  end if;
               end if;
               end if;
 
 
               Next_Entity (Component);
               Next_Entity (Component);
            end loop;
            end loop;
 
 
            return Candidate;
            return Candidate;
 
 
         else
         else
            return Empty;
            return Empty;
         end if;
         end if;
      end Trace_Components;
      end Trace_Components;
 
 
   --  Start of processing for Private_Component
   --  Start of processing for Private_Component
 
 
   begin
   begin
      return Trace_Components (Type_Id, False);
      return Trace_Components (Type_Id, False);
   end Private_Component;
   end Private_Component;
 
 
   ---------------------------
   ---------------------------
   -- Primitive_Names_Match --
   -- Primitive_Names_Match --
   ---------------------------
   ---------------------------
 
 
   function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean is
   function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean is
 
 
      function Non_Internal_Name (E : Entity_Id) return Name_Id;
      function Non_Internal_Name (E : Entity_Id) return Name_Id;
      --  Given an internal name, returns the corresponding non-internal name
      --  Given an internal name, returns the corresponding non-internal name
 
 
      ------------------------
      ------------------------
      --  Non_Internal_Name --
      --  Non_Internal_Name --
      ------------------------
      ------------------------
 
 
      function Non_Internal_Name (E : Entity_Id) return Name_Id is
      function Non_Internal_Name (E : Entity_Id) return Name_Id is
      begin
      begin
         Get_Name_String (Chars (E));
         Get_Name_String (Chars (E));
         Name_Len := Name_Len - 1;
         Name_Len := Name_Len - 1;
         return Name_Find;
         return Name_Find;
      end Non_Internal_Name;
      end Non_Internal_Name;
 
 
   --  Start of processing for Primitive_Names_Match
   --  Start of processing for Primitive_Names_Match
 
 
   begin
   begin
      pragma Assert (Present (E1) and then Present (E2));
      pragma Assert (Present (E1) and then Present (E2));
 
 
      return Chars (E1) = Chars (E2)
      return Chars (E1) = Chars (E2)
        or else
        or else
           (not Is_Internal_Name (Chars (E1))
           (not Is_Internal_Name (Chars (E1))
              and then Is_Internal_Name (Chars (E2))
              and then Is_Internal_Name (Chars (E2))
              and then Non_Internal_Name (E2) = Chars (E1))
              and then Non_Internal_Name (E2) = Chars (E1))
        or else
        or else
           (not Is_Internal_Name (Chars (E2))
           (not Is_Internal_Name (Chars (E2))
              and then Is_Internal_Name (Chars (E1))
              and then Is_Internal_Name (Chars (E1))
              and then Non_Internal_Name (E1) = Chars (E2))
              and then Non_Internal_Name (E1) = Chars (E2))
        or else
        or else
           (Is_Predefined_Dispatching_Operation (E1)
           (Is_Predefined_Dispatching_Operation (E1)
              and then Is_Predefined_Dispatching_Operation (E2)
              and then Is_Predefined_Dispatching_Operation (E2)
              and then Same_TSS (E1, E2))
              and then Same_TSS (E1, E2))
        or else
        or else
           (Is_Init_Proc (E1) and then Is_Init_Proc (E2));
           (Is_Init_Proc (E1) and then Is_Init_Proc (E2));
   end Primitive_Names_Match;
   end Primitive_Names_Match;
 
 
   -----------------------
   -----------------------
   -- Process_End_Label --
   -- Process_End_Label --
   -----------------------
   -----------------------
 
 
   procedure Process_End_Label
   procedure Process_End_Label
     (N   : Node_Id;
     (N   : Node_Id;
      Typ : Character;
      Typ : Character;
      Ent  : Entity_Id)
      Ent  : Entity_Id)
   is
   is
      Loc  : Source_Ptr;
      Loc  : Source_Ptr;
      Nam  : Node_Id;
      Nam  : Node_Id;
      Scop : Entity_Id;
      Scop : Entity_Id;
 
 
      Label_Ref : Boolean;
      Label_Ref : Boolean;
      --  Set True if reference to end label itself is required
      --  Set True if reference to end label itself is required
 
 
      Endl : Node_Id;
      Endl : Node_Id;
      --  Gets set to the operator symbol or identifier that references the
      --  Gets set to the operator symbol or identifier that references the
      --  entity Ent. For the child unit case, this is the identifier from the
      --  entity Ent. For the child unit case, this is the identifier from the
      --  designator. For other cases, this is simply Endl.
      --  designator. For other cases, this is simply Endl.
 
 
      procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id);
      procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id);
      --  N is an identifier node that appears as a parent unit reference in
      --  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
      --  the case where Ent is a child unit. This procedure generates an
      --  appropriate cross-reference entry. E is the corresponding entity.
      --  appropriate cross-reference entry. E is the corresponding entity.
 
 
      -------------------------
      -------------------------
      -- Generate_Parent_Ref --
      -- Generate_Parent_Ref --
      -------------------------
      -------------------------
 
 
      procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id) is
      procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id) is
      begin
      begin
         --  If names do not match, something weird, skip reference
         --  If names do not match, something weird, skip reference
 
 
         if Chars (E) = Chars (N) then
         if Chars (E) = Chars (N) then
 
 
            --  Generate the reference. We do NOT consider this as a reference
            --  Generate the reference. We do NOT consider this as a reference
            --  for unreferenced symbol purposes.
            --  for unreferenced symbol purposes.
 
 
            Generate_Reference (E, N, 'r', Set_Ref => False, Force => True);
            Generate_Reference (E, N, 'r', Set_Ref => False, Force => True);
 
 
            if Style_Check then
            if Style_Check then
               Style.Check_Identifier (N, E);
               Style.Check_Identifier (N, E);
            end if;
            end if;
         end if;
         end if;
      end Generate_Parent_Ref;
      end Generate_Parent_Ref;
 
 
   --  Start of processing for Process_End_Label
   --  Start of processing for Process_End_Label
 
 
   begin
   begin
      --  If no node, ignore. This happens in some error situations, and
      --  If no node, ignore. This happens in some error situations, and
      --  also for some internally generated structures where no end label
      --  also for some internally generated structures where no end label
      --  references are required in any case.
      --  references are required in any case.
 
 
      if No (N) then
      if No (N) then
         return;
         return;
      end if;
      end if;
 
 
      --  Nothing to do if no End_Label, happens for internally generated
      --  Nothing to do if no End_Label, happens for internally generated
      --  constructs where we don't want an end label reference anyway. Also
      --  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
      --  nothing to do if Endl is a string literal, which means there was
      --  some prior error (bad operator symbol)
      --  some prior error (bad operator symbol)
 
 
      Endl := End_Label (N);
      Endl := End_Label (N);
 
 
      if No (Endl) or else Nkind (Endl) = N_String_Literal then
      if No (Endl) or else Nkind (Endl) = N_String_Literal then
         return;
         return;
      end if;
      end if;
 
 
      --  Reference node is not in extended main source unit
      --  Reference node is not in extended main source unit
 
 
      if not In_Extended_Main_Source_Unit (N) then
      if not In_Extended_Main_Source_Unit (N) then
 
 
         --  Generally we do not collect references except for the extended
         --  Generally we do not collect references except for the extended
         --  main source unit. The one exception is the 'e' entry for a
         --  main source unit. The one exception is the 'e' entry for a
         --  package spec, where it is useful for a client to have the
         --  package spec, where it is useful for a client to have the
         --  ending information to define scopes.
         --  ending information to define scopes.
 
 
         if Typ /= 'e' then
         if Typ /= 'e' then
            return;
            return;
 
 
         else
         else
            Label_Ref := False;
            Label_Ref := False;
 
 
            --  For this case, we can ignore any parent references, but we
            --  For this case, we can ignore any parent references, but we
            --  need the package name itself for the 'e' entry.
            --  need the package name itself for the 'e' entry.
 
 
            if Nkind (Endl) = N_Designator then
            if Nkind (Endl) = N_Designator then
               Endl := Identifier (Endl);
               Endl := Identifier (Endl);
            end if;
            end if;
         end if;
         end if;
 
 
      --  Reference is in extended main source unit
      --  Reference is in extended main source unit
 
 
      else
      else
         Label_Ref := True;
         Label_Ref := True;
 
 
         --  For designator, generate references for the parent entries
         --  For designator, generate references for the parent entries
 
 
         if Nkind (Endl) = N_Designator then
         if Nkind (Endl) = N_Designator then
 
 
            --  Generate references for the prefix if the END line comes from
            --  Generate references for the prefix if the END line comes from
            --  source (otherwise we do not need these references) We climb the
            --  source (otherwise we do not need these references) We climb the
            --  scope stack to find the expected entities.
            --  scope stack to find the expected entities.
 
 
            if Comes_From_Source (Endl) then
            if Comes_From_Source (Endl) then
               Nam  := Name (Endl);
               Nam  := Name (Endl);
               Scop := Current_Scope;
               Scop := Current_Scope;
               while Nkind (Nam) = N_Selected_Component loop
               while Nkind (Nam) = N_Selected_Component loop
                  Scop := Scope (Scop);
                  Scop := Scope (Scop);
                  exit when No (Scop);
                  exit when No (Scop);
                  Generate_Parent_Ref (Selector_Name (Nam), Scop);
                  Generate_Parent_Ref (Selector_Name (Nam), Scop);
                  Nam := Prefix (Nam);
                  Nam := Prefix (Nam);
               end loop;
               end loop;
 
 
               if Present (Scop) then
               if Present (Scop) then
                  Generate_Parent_Ref (Nam, Scope (Scop));
                  Generate_Parent_Ref (Nam, Scope (Scop));
               end if;
               end if;
            end if;
            end if;
 
 
            Endl := Identifier (Endl);
            Endl := Identifier (Endl);
         end if;
         end if;
      end if;
      end if;
 
 
      --  If the end label is not for the given entity, then either we have
      --  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
      --  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
      --  we do not need to make a cross-reference in this case anyway. In
      --  either case we simply ignore the call.
      --  either case we simply ignore the call.
 
 
      if Chars (Ent) /= Chars (Endl) then
      if Chars (Ent) /= Chars (Endl) then
         return;
         return;
      end if;
      end if;
 
 
      --  If label was really there, then generate a normal reference and then
      --  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
      --  adjust the location in the end label to point past the name (which
      --  should almost always be the semicolon).
      --  should almost always be the semicolon).
 
 
      Loc := Sloc (Endl);
      Loc := Sloc (Endl);
 
 
      if Comes_From_Source (Endl) then
      if Comes_From_Source (Endl) then
 
 
         --  If a label reference is required, then do the style check and
         --  If a label reference is required, then do the style check and
         --  generate an l-type cross-reference entry for the label
         --  generate an l-type cross-reference entry for the label
 
 
         if Label_Ref then
         if Label_Ref then
            if Style_Check then
            if Style_Check then
               Style.Check_Identifier (Endl, Ent);
               Style.Check_Identifier (Endl, Ent);
            end if;
            end if;
 
 
            Generate_Reference (Ent, Endl, 'l', Set_Ref => False);
            Generate_Reference (Ent, Endl, 'l', Set_Ref => False);
         end if;
         end if;
 
 
         --  Set the location to point past the label (normally this will
         --  Set the location to point past the label (normally this will
         --  mean the semicolon immediately following the label). This is
         --  mean the semicolon immediately following the label). This is
         --  done for the sake of the 'e' or 't' entry generated below.
         --  done for the sake of the 'e' or 't' entry generated below.
 
 
         Get_Decoded_Name_String (Chars (Endl));
         Get_Decoded_Name_String (Chars (Endl));
         Set_Sloc (Endl, Sloc (Endl) + Source_Ptr (Name_Len));
         Set_Sloc (Endl, Sloc (Endl) + Source_Ptr (Name_Len));
      end if;
      end if;
 
 
      --  Now generate the e/t reference
      --  Now generate the e/t reference
 
 
      Generate_Reference (Ent, Endl, Typ, Set_Ref => False, Force => True);
      Generate_Reference (Ent, Endl, Typ, Set_Ref => False, Force => True);
 
 
      --  Restore Sloc, in case modified above, since we have an identifier
      --  Restore Sloc, in case modified above, since we have an identifier
      --  and the normal Sloc should be left set in the tree.
      --  and the normal Sloc should be left set in the tree.
 
 
      Set_Sloc (Endl, Loc);
      Set_Sloc (Endl, Loc);
   end Process_End_Label;
   end Process_End_Label;
 
 
   ------------------
   ------------------
   -- Real_Convert --
   -- Real_Convert --
   ------------------
   ------------------
 
 
   --  We do the conversion to get the value of the real string by using
   --  We do the conversion to get the value of the real string by using
   --  the scanner, see Sinput for details on use of the internal source
   --  the scanner, see Sinput for details on use of the internal source
   --  buffer for scanning internal strings.
   --  buffer for scanning internal strings.
 
 
   function Real_Convert (S : String) return Node_Id is
   function Real_Convert (S : String) return Node_Id is
      Save_Src : constant Source_Buffer_Ptr := Source;
      Save_Src : constant Source_Buffer_Ptr := Source;
      Negative : Boolean;
      Negative : Boolean;
 
 
   begin
   begin
      Source := Internal_Source_Ptr;
      Source := Internal_Source_Ptr;
      Scan_Ptr := 1;
      Scan_Ptr := 1;
 
 
      for J in S'Range loop
      for J in S'Range loop
         Source (Source_Ptr (J)) := S (J);
         Source (Source_Ptr (J)) := S (J);
      end loop;
      end loop;
 
 
      Source (S'Length + 1) := EOF;
      Source (S'Length + 1) := EOF;
 
 
      if Source (Scan_Ptr) = '-' then
      if Source (Scan_Ptr) = '-' then
         Negative := True;
         Negative := True;
         Scan_Ptr := Scan_Ptr + 1;
         Scan_Ptr := Scan_Ptr + 1;
      else
      else
         Negative := False;
         Negative := False;
      end if;
      end if;
 
 
      Scan;
      Scan;
 
 
      if Negative then
      if Negative then
         Set_Realval (Token_Node, UR_Negate (Realval (Token_Node)));
         Set_Realval (Token_Node, UR_Negate (Realval (Token_Node)));
      end if;
      end if;
 
 
      Source := Save_Src;
      Source := Save_Src;
      return Token_Node;
      return Token_Node;
   end Real_Convert;
   end Real_Convert;
 
 
   ------------------------------------
   ------------------------------------
   -- References_Generic_Formal_Type --
   -- References_Generic_Formal_Type --
   ------------------------------------
   ------------------------------------
 
 
   function References_Generic_Formal_Type (N : Node_Id) return Boolean is
   function References_Generic_Formal_Type (N : Node_Id) return Boolean is
 
 
      function Process (N : Node_Id) return Traverse_Result;
      function Process (N : Node_Id) return Traverse_Result;
      --  Process one node in search for generic formal type
      --  Process one node in search for generic formal type
 
 
      -------------
      -------------
      -- Process --
      -- Process --
      -------------
      -------------
 
 
      function Process (N : Node_Id) return Traverse_Result is
      function Process (N : Node_Id) return Traverse_Result is
      begin
      begin
         if Nkind (N) in N_Has_Entity then
         if Nkind (N) in N_Has_Entity then
            declare
            declare
               E : constant Entity_Id := Entity (N);
               E : constant Entity_Id := Entity (N);
            begin
            begin
               if Present (E) then
               if Present (E) then
                  if Is_Generic_Type (E) then
                  if Is_Generic_Type (E) then
                     return Abandon;
                     return Abandon;
                  elsif Present (Etype (E))
                  elsif Present (Etype (E))
                    and then Is_Generic_Type (Etype (E))
                    and then Is_Generic_Type (Etype (E))
                  then
                  then
                     return Abandon;
                     return Abandon;
                  end if;
                  end if;
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
         return Atree.OK;
         return Atree.OK;
      end Process;
      end Process;
 
 
      function Traverse is new Traverse_Func (Process);
      function Traverse is new Traverse_Func (Process);
      --  Traverse tree to look for generic type
      --  Traverse tree to look for generic type
 
 
   begin
   begin
      if Inside_A_Generic then
      if Inside_A_Generic then
         return Traverse (N) = Abandon;
         return Traverse (N) = Abandon;
      else
      else
         return False;
         return False;
      end if;
      end if;
   end References_Generic_Formal_Type;
   end References_Generic_Formal_Type;
 
 
   --------------------
   --------------------
   -- Remove_Homonym --
   -- Remove_Homonym --
   --------------------
   --------------------
 
 
   procedure Remove_Homonym (E : Entity_Id) is
   procedure Remove_Homonym (E : Entity_Id) is
      Prev  : Entity_Id := Empty;
      Prev  : Entity_Id := Empty;
      H     : Entity_Id;
      H     : Entity_Id;
 
 
   begin
   begin
      if E = Current_Entity (E) then
      if E = Current_Entity (E) then
         if Present (Homonym (E)) then
         if Present (Homonym (E)) then
            Set_Current_Entity (Homonym (E));
            Set_Current_Entity (Homonym (E));
         else
         else
            Set_Name_Entity_Id (Chars (E), Empty);
            Set_Name_Entity_Id (Chars (E), Empty);
         end if;
         end if;
      else
      else
         H := Current_Entity (E);
         H := Current_Entity (E);
         while Present (H) and then H /= E loop
         while Present (H) and then H /= E loop
            Prev := H;
            Prev := H;
            H    := Homonym (H);
            H    := Homonym (H);
         end loop;
         end loop;
 
 
         Set_Homonym (Prev, Homonym (E));
         Set_Homonym (Prev, Homonym (E));
      end if;
      end if;
   end Remove_Homonym;
   end Remove_Homonym;
 
 
   ---------------------
   ---------------------
   -- Rep_To_Pos_Flag --
   -- Rep_To_Pos_Flag --
   ---------------------
   ---------------------
 
 
   function Rep_To_Pos_Flag (E : Entity_Id; Loc : Source_Ptr) return Node_Id is
   function Rep_To_Pos_Flag (E : Entity_Id; Loc : Source_Ptr) return Node_Id is
   begin
   begin
      return New_Occurrence_Of
      return New_Occurrence_Of
               (Boolean_Literals (not Range_Checks_Suppressed (E)), Loc);
               (Boolean_Literals (not Range_Checks_Suppressed (E)), Loc);
   end Rep_To_Pos_Flag;
   end Rep_To_Pos_Flag;
 
 
   --------------------
   --------------------
   -- Require_Entity --
   -- Require_Entity --
   --------------------
   --------------------
 
 
   procedure Require_Entity (N : Node_Id) is
   procedure Require_Entity (N : Node_Id) is
   begin
   begin
      if Is_Entity_Name (N) and then No (Entity (N)) then
      if Is_Entity_Name (N) and then No (Entity (N)) then
         if Total_Errors_Detected /= 0 then
         if Total_Errors_Detected /= 0 then
            Set_Entity (N, Any_Id);
            Set_Entity (N, Any_Id);
         else
         else
            raise Program_Error;
            raise Program_Error;
         end if;
         end if;
      end if;
      end if;
   end Require_Entity;
   end Require_Entity;
 
 
   ------------------------------
   ------------------------------
   -- Requires_Transient_Scope --
   -- Requires_Transient_Scope --
   ------------------------------
   ------------------------------
 
 
   --  A transient scope is required when variable-sized temporaries are
   --  A transient scope is required when variable-sized temporaries are
   --  allocated in the primary or secondary stack, or when finalization
   --  allocated in the primary or secondary stack, or when finalization
   --  actions must be generated before the next instruction.
   --  actions must be generated before the next instruction.
 
 
   function Requires_Transient_Scope (Id : Entity_Id) return Boolean is
   function Requires_Transient_Scope (Id : Entity_Id) return Boolean is
      Typ : constant Entity_Id := Underlying_Type (Id);
      Typ : constant Entity_Id := Underlying_Type (Id);
 
 
   --  Start of processing for Requires_Transient_Scope
   --  Start of processing for Requires_Transient_Scope
 
 
   begin
   begin
      --  This is a private type which is not completed yet. This can only
      --  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
      --  happen in a default expression (of a formal parameter or of a
      --  record component). Do not expand transient scope in this case
      --  record component). Do not expand transient scope in this case
 
 
      if No (Typ) then
      if No (Typ) then
         return False;
         return False;
 
 
      --  Do not expand transient scope for non-existent procedure return
      --  Do not expand transient scope for non-existent procedure return
 
 
      elsif Typ = Standard_Void_Type then
      elsif Typ = Standard_Void_Type then
         return False;
         return False;
 
 
      --  Elementary types do not require a transient scope
      --  Elementary types do not require a transient scope
 
 
      elsif Is_Elementary_Type (Typ) then
      elsif Is_Elementary_Type (Typ) then
         return False;
         return False;
 
 
      --  Generally, indefinite subtypes require a transient scope, since the
      --  Generally, indefinite subtypes require a transient scope, since the
      --  back end cannot generate temporaries, since this is not a valid type
      --  back end cannot generate temporaries, since this is not a valid type
      --  for declaring an object. It might be possible to relax this in the
      --  for declaring an object. It might be possible to relax this in the
      --  future, e.g. by declaring the maximum possible space for the type.
      --  future, e.g. by declaring the maximum possible space for the type.
 
 
      elsif Is_Indefinite_Subtype (Typ) then
      elsif Is_Indefinite_Subtype (Typ) then
         return True;
         return True;
 
 
      --  Functions returning tagged types may dispatch on result so their
      --  Functions returning tagged types may dispatch on result so their
      --  returned value is allocated on the secondary stack. Controlled
      --  returned value is allocated on the secondary stack. Controlled
      --  type temporaries need finalization.
      --  type temporaries need finalization.
 
 
      elsif Is_Tagged_Type (Typ)
      elsif Is_Tagged_Type (Typ)
        or else Has_Controlled_Component (Typ)
        or else Has_Controlled_Component (Typ)
      then
      then
         return not Is_Value_Type (Typ);
         return not Is_Value_Type (Typ);
 
 
      --  Record type
      --  Record type
 
 
      elsif Is_Record_Type (Typ) then
      elsif Is_Record_Type (Typ) then
         declare
         declare
            Comp : Entity_Id;
            Comp : Entity_Id;
         begin
         begin
            Comp := First_Entity (Typ);
            Comp := First_Entity (Typ);
            while Present (Comp) loop
            while Present (Comp) loop
               if Ekind (Comp) = E_Component
               if Ekind (Comp) = E_Component
                  and then Requires_Transient_Scope (Etype (Comp))
                  and then Requires_Transient_Scope (Etype (Comp))
               then
               then
                  return True;
                  return True;
               else
               else
                  Next_Entity (Comp);
                  Next_Entity (Comp);
               end if;
               end if;
            end loop;
            end loop;
         end;
         end;
 
 
         return False;
         return False;
 
 
      --  String literal types never require transient scope
      --  String literal types never require transient scope
 
 
      elsif Ekind (Typ) = E_String_Literal_Subtype then
      elsif Ekind (Typ) = E_String_Literal_Subtype then
         return False;
         return False;
 
 
      --  Array type. Note that we already know that this is a constrained
      --  Array type. Note that we already know that this is a constrained
      --  array, since unconstrained arrays will fail the indefinite test.
      --  array, since unconstrained arrays will fail the indefinite test.
 
 
      elsif Is_Array_Type (Typ) then
      elsif Is_Array_Type (Typ) then
 
 
         --  If component type requires a transient scope, the array does too
         --  If component type requires a transient scope, the array does too
 
 
         if Requires_Transient_Scope (Component_Type (Typ)) then
         if Requires_Transient_Scope (Component_Type (Typ)) then
            return True;
            return True;
 
 
         --  Otherwise, we only need a transient scope if the size is not
         --  Otherwise, we only need a transient scope if the size is not
         --  known at compile time.
         --  known at compile time.
 
 
         else
         else
            return not Size_Known_At_Compile_Time (Typ);
            return not Size_Known_At_Compile_Time (Typ);
         end if;
         end if;
 
 
      --  All other cases do not require a transient scope
      --  All other cases do not require a transient scope
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Requires_Transient_Scope;
   end Requires_Transient_Scope;
 
 
   --------------------------
   --------------------------
   -- Reset_Analyzed_Flags --
   -- Reset_Analyzed_Flags --
   --------------------------
   --------------------------
 
 
   procedure Reset_Analyzed_Flags (N : Node_Id) is
   procedure Reset_Analyzed_Flags (N : Node_Id) is
 
 
      function Clear_Analyzed (N : Node_Id) return Traverse_Result;
      function Clear_Analyzed (N : Node_Id) return Traverse_Result;
      --  Function used to reset Analyzed flags in tree. Note that we do
      --  Function used to reset Analyzed flags in tree. Note that we do
      --  not reset Analyzed flags in entities, since there is no need to
      --  not reset Analyzed flags in entities, since there is no need to
      --  reanalyze entities, and indeed, it is wrong to do so, since it
      --  reanalyze entities, and indeed, it is wrong to do so, since it
      --  can result in generating auxiliary stuff more than once.
      --  can result in generating auxiliary stuff more than once.
 
 
      --------------------
      --------------------
      -- Clear_Analyzed --
      -- Clear_Analyzed --
      --------------------
      --------------------
 
 
      function Clear_Analyzed (N : Node_Id) return Traverse_Result is
      function Clear_Analyzed (N : Node_Id) return Traverse_Result is
      begin
      begin
         if not Has_Extension (N) then
         if not Has_Extension (N) then
            Set_Analyzed (N, False);
            Set_Analyzed (N, False);
         end if;
         end if;
 
 
         return OK;
         return OK;
      end Clear_Analyzed;
      end Clear_Analyzed;
 
 
      procedure Reset_Analyzed is new Traverse_Proc (Clear_Analyzed);
      procedure Reset_Analyzed is new Traverse_Proc (Clear_Analyzed);
 
 
   --  Start of processing for Reset_Analyzed_Flags
   --  Start of processing for Reset_Analyzed_Flags
 
 
   begin
   begin
      Reset_Analyzed (N);
      Reset_Analyzed (N);
   end Reset_Analyzed_Flags;
   end Reset_Analyzed_Flags;
 
 
   ---------------------------
   ---------------------------
   -- Safe_To_Capture_Value --
   -- Safe_To_Capture_Value --
   ---------------------------
   ---------------------------
 
 
   function Safe_To_Capture_Value
   function Safe_To_Capture_Value
     (N    : Node_Id;
     (N    : Node_Id;
      Ent  : Entity_Id;
      Ent  : Entity_Id;
      Cond : Boolean := False) return Boolean
      Cond : Boolean := False) return Boolean
   is
   is
   begin
   begin
      --  The only entities for which we track constant values are variables
      --  The only entities for which we track constant values are variables
      --  which are not renamings, constants, out parameters, and in out
      --  which are not renamings, constants, out parameters, and in out
      --  parameters, so check if we have this case.
      --  parameters, so check if we have this case.
 
 
      --  Note: it may seem odd to track constant values for constants, but in
      --  Note: it may seem odd to track constant values for constants, but in
      --  fact this routine is used for other purposes than simply capturing
      --  fact this routine is used for other purposes than simply capturing
      --  the value. In particular, the setting of Known[_Non]_Null.
      --  the value. In particular, the setting of Known[_Non]_Null.
 
 
      if (Ekind (Ent) = E_Variable and then No (Renamed_Object (Ent)))
      if (Ekind (Ent) = E_Variable and then No (Renamed_Object (Ent)))
            or else
            or else
          Ekind (Ent) = E_Constant
          Ekind (Ent) = E_Constant
            or else
            or else
          Ekind (Ent) = E_Out_Parameter
          Ekind (Ent) = E_Out_Parameter
            or else
            or else
          Ekind (Ent) = E_In_Out_Parameter
          Ekind (Ent) = E_In_Out_Parameter
      then
      then
         null;
         null;
 
 
      --  For conditionals, we also allow loop parameters and all formals,
      --  For conditionals, we also allow loop parameters and all formals,
      --  including in parameters.
      --  including in parameters.
 
 
      elsif Cond
      elsif Cond
        and then
        and then
          (Ekind (Ent) = E_Loop_Parameter
          (Ekind (Ent) = E_Loop_Parameter
             or else
             or else
           Ekind (Ent) = E_In_Parameter)
           Ekind (Ent) = E_In_Parameter)
      then
      then
         null;
         null;
 
 
      --  For all other cases, not just unsafe, but impossible to capture
      --  For all other cases, not just unsafe, but impossible to capture
      --  Current_Value, since the above are the only entities which have
      --  Current_Value, since the above are the only entities which have
      --  Current_Value fields.
      --  Current_Value fields.
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
 
 
      --  Skip if volatile or aliased, since funny things might be going on in
      --  Skip if volatile or aliased, since funny things might be going on in
      --  these cases which we cannot necessarily track. Also skip any variable
      --  these cases which we cannot necessarily track. Also skip any variable
      --  for which an address clause is given, or whose address is taken. Also
      --  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
      --  never capture value of library level variables (an attempt to do so
      --  can occur in the case of package elaboration code).
      --  can occur in the case of package elaboration code).
 
 
      if Treat_As_Volatile (Ent)
      if Treat_As_Volatile (Ent)
        or else Is_Aliased (Ent)
        or else Is_Aliased (Ent)
        or else Present (Address_Clause (Ent))
        or else Present (Address_Clause (Ent))
        or else Address_Taken (Ent)
        or else Address_Taken (Ent)
        or else (Is_Library_Level_Entity (Ent)
        or else (Is_Library_Level_Entity (Ent)
                   and then Ekind (Ent) = E_Variable)
                   and then Ekind (Ent) = E_Variable)
      then
      then
         return False;
         return False;
      end if;
      end if;
 
 
      --  OK, all above conditions are met. We also require that the scope of
      --  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
      --  the reference be the same as the scope of the entity, not counting
      --  packages and blocks and loops.
      --  packages and blocks and loops.
 
 
      declare
      declare
         E_Scope : constant Entity_Id := Scope (Ent);
         E_Scope : constant Entity_Id := Scope (Ent);
         R_Scope : Entity_Id;
         R_Scope : Entity_Id;
 
 
      begin
      begin
         R_Scope := Current_Scope;
         R_Scope := Current_Scope;
         while R_Scope /= Standard_Standard loop
         while R_Scope /= Standard_Standard loop
            exit when R_Scope = E_Scope;
            exit when R_Scope = E_Scope;
 
 
            if Ekind (R_Scope) /= E_Package
            if Ekind (R_Scope) /= E_Package
                  and then
                  and then
                Ekind (R_Scope) /= E_Block
                Ekind (R_Scope) /= E_Block
                  and then
                  and then
                Ekind (R_Scope) /= E_Loop
                Ekind (R_Scope) /= E_Loop
            then
            then
               return False;
               return False;
            else
            else
               R_Scope := Scope (R_Scope);
               R_Scope := Scope (R_Scope);
            end if;
            end if;
         end loop;
         end loop;
      end;
      end;
 
 
      --  We also require that the reference does not appear in a context
      --  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
      --  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
      --  or an exception handler). We skip this if Cond is True, since the
      --  capturing of values from conditional tests handles this ok.
      --  capturing of values from conditional tests handles this ok.
 
 
      if Cond then
      if Cond then
         return True;
         return True;
      end if;
      end if;
 
 
      declare
      declare
         Desc : Node_Id;
         Desc : Node_Id;
         P    : Node_Id;
         P    : Node_Id;
 
 
      begin
      begin
         Desc := N;
         Desc := N;
 
 
         P := Parent (N);
         P := Parent (N);
         while Present (P) loop
         while Present (P) loop
            if         Nkind (P) = N_If_Statement
            if         Nkind (P) = N_If_Statement
              or else  Nkind (P) = N_Case_Statement
              or else  Nkind (P) = N_Case_Statement
              or else (Nkind (P) in N_Short_Circuit
              or else (Nkind (P) in N_Short_Circuit
                         and then Desc = Right_Opnd (P))
                         and then Desc = Right_Opnd (P))
              or else (Nkind (P) = N_Conditional_Expression
              or else (Nkind (P) = N_Conditional_Expression
                         and then Desc /= First (Expressions (P)))
                         and then Desc /= First (Expressions (P)))
              or else  Nkind (P) = N_Exception_Handler
              or else  Nkind (P) = N_Exception_Handler
              or else  Nkind (P) = N_Selective_Accept
              or else  Nkind (P) = N_Selective_Accept
              or else  Nkind (P) = N_Conditional_Entry_Call
              or else  Nkind (P) = N_Conditional_Entry_Call
              or else  Nkind (P) = N_Timed_Entry_Call
              or else  Nkind (P) = N_Timed_Entry_Call
              or else  Nkind (P) = N_Asynchronous_Select
              or else  Nkind (P) = N_Asynchronous_Select
            then
            then
               return False;
               return False;
            else
            else
               Desc := P;
               Desc := P;
               P    := Parent (P);
               P    := Parent (P);
            end if;
            end if;
         end loop;
         end loop;
      end;
      end;
 
 
      --  OK, looks safe to set value
      --  OK, looks safe to set value
 
 
      return True;
      return True;
   end Safe_To_Capture_Value;
   end Safe_To_Capture_Value;
 
 
   ---------------
   ---------------
   -- Same_Name --
   -- Same_Name --
   ---------------
   ---------------
 
 
   function Same_Name (N1, N2 : Node_Id) return Boolean is
   function Same_Name (N1, N2 : Node_Id) return Boolean is
      K1 : constant Node_Kind := Nkind (N1);
      K1 : constant Node_Kind := Nkind (N1);
      K2 : constant Node_Kind := Nkind (N2);
      K2 : constant Node_Kind := Nkind (N2);
 
 
   begin
   begin
      if (K1 = N_Identifier or else K1 = N_Defining_Identifier)
      if (K1 = N_Identifier or else K1 = N_Defining_Identifier)
        and then (K2 = N_Identifier or else K2 = N_Defining_Identifier)
        and then (K2 = N_Identifier or else K2 = N_Defining_Identifier)
      then
      then
         return Chars (N1) = Chars (N2);
         return Chars (N1) = Chars (N2);
 
 
      elsif (K1 = N_Selected_Component or else K1 = N_Expanded_Name)
      elsif (K1 = N_Selected_Component or else K1 = N_Expanded_Name)
        and then (K2 = N_Selected_Component or else K2 = N_Expanded_Name)
        and then (K2 = N_Selected_Component or else K2 = N_Expanded_Name)
      then
      then
         return Same_Name (Selector_Name (N1), Selector_Name (N2))
         return Same_Name (Selector_Name (N1), Selector_Name (N2))
           and then Same_Name (Prefix (N1), Prefix (N2));
           and then Same_Name (Prefix (N1), Prefix (N2));
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Same_Name;
   end Same_Name;
 
 
   -----------------
   -----------------
   -- Same_Object --
   -- Same_Object --
   -----------------
   -----------------
 
 
   function Same_Object (Node1, Node2 : Node_Id) return Boolean is
   function Same_Object (Node1, Node2 : Node_Id) return Boolean is
      N1 : constant Node_Id := Original_Node (Node1);
      N1 : constant Node_Id := Original_Node (Node1);
      N2 : constant Node_Id := Original_Node (Node2);
      N2 : constant Node_Id := Original_Node (Node2);
      --  We do the tests on original nodes, since we are most interested
      --  We do the tests on original nodes, since we are most interested
      --  in the original source, not any expansion that got in the way.
      --  in the original source, not any expansion that got in the way.
 
 
      K1 : constant Node_Kind := Nkind (N1);
      K1 : constant Node_Kind := Nkind (N1);
      K2 : constant Node_Kind := Nkind (N2);
      K2 : constant Node_Kind := Nkind (N2);
 
 
   begin
   begin
      --  First case, both are entities with same entity
      --  First case, both are entities with same entity
 
 
      if K1 in N_Has_Entity
      if K1 in N_Has_Entity
        and then K2 in N_Has_Entity
        and then K2 in N_Has_Entity
        and then Present (Entity (N1))
        and then Present (Entity (N1))
        and then Present (Entity (N2))
        and then Present (Entity (N2))
        and then (Ekind (Entity (N1)) = E_Variable
        and then (Ekind (Entity (N1)) = E_Variable
                    or else
                    or else
                  Ekind (Entity (N1)) = E_Constant)
                  Ekind (Entity (N1)) = E_Constant)
        and then Entity (N1) = Entity (N2)
        and then Entity (N1) = Entity (N2)
      then
      then
         return True;
         return True;
 
 
      --  Second case, selected component with same selector, same record
      --  Second case, selected component with same selector, same record
 
 
      elsif K1 = N_Selected_Component
      elsif K1 = N_Selected_Component
        and then K2 = N_Selected_Component
        and then K2 = N_Selected_Component
        and then Chars (Selector_Name (N1)) = Chars (Selector_Name (N2))
        and then Chars (Selector_Name (N1)) = Chars (Selector_Name (N2))
      then
      then
         return Same_Object (Prefix (N1), Prefix (N2));
         return Same_Object (Prefix (N1), Prefix (N2));
 
 
      --  Third case, indexed component with same subscripts, same array
      --  Third case, indexed component with same subscripts, same array
 
 
      elsif K1 = N_Indexed_Component
      elsif K1 = N_Indexed_Component
        and then K2 = N_Indexed_Component
        and then K2 = N_Indexed_Component
        and then Same_Object (Prefix (N1), Prefix (N2))
        and then Same_Object (Prefix (N1), Prefix (N2))
      then
      then
         declare
         declare
            E1, E2 : Node_Id;
            E1, E2 : Node_Id;
         begin
         begin
            E1 := First (Expressions (N1));
            E1 := First (Expressions (N1));
            E2 := First (Expressions (N2));
            E2 := First (Expressions (N2));
            while Present (E1) loop
            while Present (E1) loop
               if not Same_Value (E1, E2) then
               if not Same_Value (E1, E2) then
                  return False;
                  return False;
               else
               else
                  Next (E1);
                  Next (E1);
                  Next (E2);
                  Next (E2);
               end if;
               end if;
            end loop;
            end loop;
 
 
            return True;
            return True;
         end;
         end;
 
 
      --  Fourth case, slice of same array with same bounds
      --  Fourth case, slice of same array with same bounds
 
 
      elsif K1 = N_Slice
      elsif K1 = N_Slice
        and then K2 = N_Slice
        and then K2 = N_Slice
        and then Nkind (Discrete_Range (N1)) = N_Range
        and then Nkind (Discrete_Range (N1)) = N_Range
        and then Nkind (Discrete_Range (N2)) = N_Range
        and then Nkind (Discrete_Range (N2)) = N_Range
        and then Same_Value (Low_Bound (Discrete_Range (N1)),
        and then Same_Value (Low_Bound (Discrete_Range (N1)),
                             Low_Bound (Discrete_Range (N2)))
                             Low_Bound (Discrete_Range (N2)))
        and then Same_Value (High_Bound (Discrete_Range (N1)),
        and then Same_Value (High_Bound (Discrete_Range (N1)),
                             High_Bound (Discrete_Range (N2)))
                             High_Bound (Discrete_Range (N2)))
      then
      then
         return Same_Name (Prefix (N1), Prefix (N2));
         return Same_Name (Prefix (N1), Prefix (N2));
 
 
      --  All other cases, not clearly the same object
      --  All other cases, not clearly the same object
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Same_Object;
   end Same_Object;
 
 
   ---------------
   ---------------
   -- Same_Type --
   -- Same_Type --
   ---------------
   ---------------
 
 
   function Same_Type (T1, T2 : Entity_Id) return Boolean is
   function Same_Type (T1, T2 : Entity_Id) return Boolean is
   begin
   begin
      if T1 = T2 then
      if T1 = T2 then
         return True;
         return True;
 
 
      elsif not Is_Constrained (T1)
      elsif not Is_Constrained (T1)
        and then not Is_Constrained (T2)
        and then not Is_Constrained (T2)
        and then Base_Type (T1) = Base_Type (T2)
        and then Base_Type (T1) = Base_Type (T2)
      then
      then
         return True;
         return True;
 
 
      --  For now don't bother with case of identical constraints, to be
      --  For now don't bother with case of identical constraints, to be
      --  fiddled with later on perhaps (this is only used for optimization
      --  fiddled with later on perhaps (this is only used for optimization
      --  purposes, so it is not critical to do a best possible job)
      --  purposes, so it is not critical to do a best possible job)
 
 
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Same_Type;
   end Same_Type;
 
 
   ----------------
   ----------------
   -- Same_Value --
   -- Same_Value --
   ----------------
   ----------------
 
 
   function Same_Value (Node1, Node2 : Node_Id) return Boolean is
   function Same_Value (Node1, Node2 : Node_Id) return Boolean is
   begin
   begin
      if Compile_Time_Known_Value (Node1)
      if Compile_Time_Known_Value (Node1)
        and then Compile_Time_Known_Value (Node2)
        and then Compile_Time_Known_Value (Node2)
        and then Expr_Value (Node1) = Expr_Value (Node2)
        and then Expr_Value (Node1) = Expr_Value (Node2)
      then
      then
         return True;
         return True;
      elsif Same_Object (Node1, Node2) then
      elsif Same_Object (Node1, Node2) then
         return True;
         return True;
      else
      else
         return False;
         return False;
      end if;
      end if;
   end Same_Value;
   end Same_Value;
 
 
   ------------------------
   ------------------------
   -- Scope_Is_Transient --
   -- Scope_Is_Transient --
   ------------------------
   ------------------------
 
 
   function Scope_Is_Transient return Boolean is
   function Scope_Is_Transient return Boolean is
   begin
   begin
      return Scope_Stack.Table (Scope_Stack.Last).Is_Transient;
      return Scope_Stack.Table (Scope_Stack.Last).Is_Transient;
   end Scope_Is_Transient;
   end Scope_Is_Transient;
 
 
   ------------------
   ------------------
   -- Scope_Within --
   -- Scope_Within --
   ------------------
   ------------------
 
 
   function Scope_Within (Scope1, Scope2 : Entity_Id) return Boolean is
   function Scope_Within (Scope1, Scope2 : Entity_Id) return Boolean is
      Scop : Entity_Id;
      Scop : Entity_Id;
 
 
   begin
   begin
      Scop := Scope1;
      Scop := Scope1;
      while Scop /= Standard_Standard loop
      while Scop /= Standard_Standard loop
         Scop := Scope (Scop);
         Scop := Scope (Scop);
 
 
         if Scop = Scope2 then
         if Scop = Scope2 then
            return True;
            return True;
         end if;
         end if;
      end loop;
      end loop;
 
 
      return False;
      return False;
   end Scope_Within;
   end Scope_Within;
 
 
   --------------------------
   --------------------------
   -- Scope_Within_Or_Same --
   -- Scope_Within_Or_Same --
   --------------------------
   --------------------------
 
 
   function Scope_Within_Or_Same (Scope1, Scope2 : Entity_Id) return Boolean is
   function Scope_Within_Or_Same (Scope1, Scope2 : Entity_Id) return Boolean is
      Scop : Entity_Id;
      Scop : Entity_Id;
 
 
   begin
   begin
      Scop := Scope1;
      Scop := Scope1;
      while Scop /= Standard_Standard loop
      while Scop /= Standard_Standard loop
         if Scop = Scope2 then
         if Scop = Scope2 then
            return True;
            return True;
         else
         else
            Scop := Scope (Scop);
            Scop := Scope (Scop);
         end if;
         end if;
      end loop;
      end loop;
 
 
      return False;
      return False;
   end Scope_Within_Or_Same;
   end Scope_Within_Or_Same;
 
 
   --------------------
   --------------------
   -- Set_Convention --
   -- Set_Convention --
   --------------------
   --------------------
 
 
   procedure Set_Convention (E : Entity_Id; Val : Snames.Convention_Id) is
   procedure Set_Convention (E : Entity_Id; Val : Snames.Convention_Id) is
   begin
   begin
      Basic_Set_Convention (E, Val);
      Basic_Set_Convention (E, Val);
 
 
      if Is_Type (E)
      if Is_Type (E)
        and then Is_Access_Subprogram_Type (Base_Type (E))
        and then Is_Access_Subprogram_Type (Base_Type (E))
        and then Has_Foreign_Convention (E)
        and then Has_Foreign_Convention (E)
      then
      then
         Set_Can_Use_Internal_Rep (E, False);
         Set_Can_Use_Internal_Rep (E, False);
      end if;
      end if;
   end Set_Convention;
   end Set_Convention;
 
 
   ------------------------
   ------------------------
   -- Set_Current_Entity --
   -- Set_Current_Entity --
   ------------------------
   ------------------------
 
 
   --  The given entity is to be set as the currently visible definition
   --  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).
   --  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
   --  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.
   --  then set the associated Node_Id to point to the given entity.
 
 
   procedure Set_Current_Entity (E : Entity_Id) is
   procedure Set_Current_Entity (E : Entity_Id) is
   begin
   begin
      Set_Name_Entity_Id (Chars (E), E);
      Set_Name_Entity_Id (Chars (E), E);
   end Set_Current_Entity;
   end Set_Current_Entity;
 
 
   ---------------------------
   ---------------------------
   -- Set_Debug_Info_Needed --
   -- Set_Debug_Info_Needed --
   ---------------------------
   ---------------------------
 
 
   procedure Set_Debug_Info_Needed (T : Entity_Id) is
   procedure Set_Debug_Info_Needed (T : Entity_Id) is
 
 
      procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id);
      procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id);
      pragma Inline (Set_Debug_Info_Needed_If_Not_Set);
      pragma Inline (Set_Debug_Info_Needed_If_Not_Set);
      --  Used to set debug info in a related node if not set already
      --  Used to set debug info in a related node if not set already
 
 
      --------------------------------------
      --------------------------------------
      -- Set_Debug_Info_Needed_If_Not_Set --
      -- Set_Debug_Info_Needed_If_Not_Set --
      --------------------------------------
      --------------------------------------
 
 
      procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id) is
      procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id) is
      begin
      begin
         if Present (E)
         if Present (E)
           and then not Needs_Debug_Info (E)
           and then not Needs_Debug_Info (E)
         then
         then
            Set_Debug_Info_Needed (E);
            Set_Debug_Info_Needed (E);
 
 
            --  For a private type, indicate that the full view also needs
            --  For a private type, indicate that the full view also needs
            --  debug information.
            --  debug information.
 
 
            if Is_Type (E)
            if Is_Type (E)
              and then Is_Private_Type (E)
              and then Is_Private_Type (E)
              and then Present (Full_View (E))
              and then Present (Full_View (E))
            then
            then
               Set_Debug_Info_Needed (Full_View (E));
               Set_Debug_Info_Needed (Full_View (E));
            end if;
            end if;
         end if;
         end if;
      end Set_Debug_Info_Needed_If_Not_Set;
      end Set_Debug_Info_Needed_If_Not_Set;
 
 
   --  Start of processing for Set_Debug_Info_Needed
   --  Start of processing for Set_Debug_Info_Needed
 
 
   begin
   begin
      --  Nothing to do if argument is Empty or has Debug_Info_Off set, which
      --  Nothing to do if argument is Empty or has Debug_Info_Off set, which
      --  indicates that Debug_Info_Needed is never required for the entity.
      --  indicates that Debug_Info_Needed is never required for the entity.
 
 
      if No (T)
      if No (T)
        or else Debug_Info_Off (T)
        or else Debug_Info_Off (T)
      then
      then
         return;
         return;
      end if;
      end if;
 
 
      --  Set flag in entity itself. Note that we will go through the following
      --  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,
      --  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.
      --  it makes sure that the flag will be set in subsidiary entities.
 
 
      Set_Needs_Debug_Info (T);
      Set_Needs_Debug_Info (T);
 
 
      --  Set flag on subsidiary entities if not set already
      --  Set flag on subsidiary entities if not set already
 
 
      if Is_Object (T) then
      if Is_Object (T) then
         Set_Debug_Info_Needed_If_Not_Set (Etype (T));
         Set_Debug_Info_Needed_If_Not_Set (Etype (T));
 
 
      elsif Is_Type (T) then
      elsif Is_Type (T) then
         Set_Debug_Info_Needed_If_Not_Set (Etype (T));
         Set_Debug_Info_Needed_If_Not_Set (Etype (T));
 
 
         if Is_Record_Type (T) then
         if Is_Record_Type (T) then
            declare
            declare
               Ent : Entity_Id := First_Entity (T);
               Ent : Entity_Id := First_Entity (T);
            begin
            begin
               while Present (Ent) loop
               while Present (Ent) loop
                  Set_Debug_Info_Needed_If_Not_Set (Ent);
                  Set_Debug_Info_Needed_If_Not_Set (Ent);
                  Next_Entity (Ent);
                  Next_Entity (Ent);
               end loop;
               end loop;
            end;
            end;
 
 
            if Ekind (T) = E_Class_Wide_Subtype then
            if Ekind (T) = E_Class_Wide_Subtype then
               Set_Debug_Info_Needed_If_Not_Set (Equivalent_Type (T));
               Set_Debug_Info_Needed_If_Not_Set (Equivalent_Type (T));
            end if;
            end if;
 
 
         elsif Is_Array_Type (T) then
         elsif Is_Array_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Component_Type (T));
            Set_Debug_Info_Needed_If_Not_Set (Component_Type (T));
 
 
            declare
            declare
               Indx : Node_Id := First_Index (T);
               Indx : Node_Id := First_Index (T);
            begin
            begin
               while Present (Indx) loop
               while Present (Indx) loop
                  Set_Debug_Info_Needed_If_Not_Set (Etype (Indx));
                  Set_Debug_Info_Needed_If_Not_Set (Etype (Indx));
                  Indx := Next_Index (Indx);
                  Indx := Next_Index (Indx);
               end loop;
               end loop;
            end;
            end;
 
 
            if Is_Packed (T) then
            if Is_Packed (T) then
               Set_Debug_Info_Needed_If_Not_Set (Packed_Array_Type (T));
               Set_Debug_Info_Needed_If_Not_Set (Packed_Array_Type (T));
            end if;
            end if;
 
 
         elsif Is_Access_Type (T) then
         elsif Is_Access_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Directly_Designated_Type (T));
            Set_Debug_Info_Needed_If_Not_Set (Directly_Designated_Type (T));
 
 
         elsif Is_Private_Type (T) then
         elsif Is_Private_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Full_View (T));
            Set_Debug_Info_Needed_If_Not_Set (Full_View (T));
 
 
         elsif Is_Protected_Type (T) then
         elsif Is_Protected_Type (T) then
            Set_Debug_Info_Needed_If_Not_Set (Corresponding_Record_Type (T));
            Set_Debug_Info_Needed_If_Not_Set (Corresponding_Record_Type (T));
         end if;
         end if;
      end if;
      end if;
   end Set_Debug_Info_Needed;
   end Set_Debug_Info_Needed;
 
 
   ---------------------------------
   ---------------------------------
   -- Set_Entity_With_Style_Check --
   -- Set_Entity_With_Style_Check --
   ---------------------------------
   ---------------------------------
 
 
   procedure Set_Entity_With_Style_Check (N : Node_Id; Val : Entity_Id) is
   procedure Set_Entity_With_Style_Check (N : Node_Id; Val : Entity_Id) is
      Val_Actual : Entity_Id;
      Val_Actual : Entity_Id;
      Nod        : Node_Id;
      Nod        : Node_Id;
 
 
   begin
   begin
      Set_Entity (N, Val);
      Set_Entity (N, Val);
 
 
      if Style_Check
      if Style_Check
        and then not Suppress_Style_Checks (Val)
        and then not Suppress_Style_Checks (Val)
        and then not In_Instance
        and then not In_Instance
      then
      then
         if Nkind (N) = N_Identifier then
         if Nkind (N) = N_Identifier then
            Nod := N;
            Nod := N;
         elsif Nkind (N) = N_Expanded_Name then
         elsif Nkind (N) = N_Expanded_Name then
            Nod := Selector_Name (N);
            Nod := Selector_Name (N);
         else
         else
            return;
            return;
         end if;
         end if;
 
 
         --  A special situation arises for derived operations, where we want
         --  A special situation arises for derived operations, where we want
         --  to do the check against the parent (since the Sloc of the derived
         --  to do the check against the parent (since the Sloc of the derived
         --  operation points to the derived type declaration itself).
         --  operation points to the derived type declaration itself).
 
 
         Val_Actual := Val;
         Val_Actual := Val;
         while not Comes_From_Source (Val_Actual)
         while not Comes_From_Source (Val_Actual)
           and then Nkind (Val_Actual) in N_Entity
           and then Nkind (Val_Actual) in N_Entity
           and then (Ekind (Val_Actual) = E_Enumeration_Literal
           and then (Ekind (Val_Actual) = E_Enumeration_Literal
                      or else Is_Subprogram (Val_Actual)
                      or else Is_Subprogram (Val_Actual)
                      or else Is_Generic_Subprogram (Val_Actual))
                      or else Is_Generic_Subprogram (Val_Actual))
           and then Present (Alias (Val_Actual))
           and then Present (Alias (Val_Actual))
         loop
         loop
            Val_Actual := Alias (Val_Actual);
            Val_Actual := Alias (Val_Actual);
         end loop;
         end loop;
 
 
         --  Renaming declarations for generic actuals do not come from source,
         --  Renaming declarations for generic actuals do not come from source,
         --  and have a different name from that of the entity they rename, so
         --  and have a different name from that of the entity they rename, so
         --  there is no style check to perform here.
         --  there is no style check to perform here.
 
 
         if Chars (Nod) = Chars (Val_Actual) then
         if Chars (Nod) = Chars (Val_Actual) then
            Style.Check_Identifier (Nod, Val_Actual);
            Style.Check_Identifier (Nod, Val_Actual);
         end if;
         end if;
      end if;
      end if;
 
 
      Set_Entity (N, Val);
      Set_Entity (N, Val);
   end Set_Entity_With_Style_Check;
   end Set_Entity_With_Style_Check;
 
 
   ------------------------
   ------------------------
   -- Set_Name_Entity_Id --
   -- Set_Name_Entity_Id --
   ------------------------
   ------------------------
 
 
   procedure Set_Name_Entity_Id (Id : Name_Id; Val : Entity_Id) is
   procedure Set_Name_Entity_Id (Id : Name_Id; Val : Entity_Id) is
   begin
   begin
      Set_Name_Table_Info (Id, Int (Val));
      Set_Name_Table_Info (Id, Int (Val));
   end Set_Name_Entity_Id;
   end Set_Name_Entity_Id;
 
 
   ---------------------
   ---------------------
   -- Set_Next_Actual --
   -- Set_Next_Actual --
   ---------------------
   ---------------------
 
 
   procedure Set_Next_Actual (Ass1_Id : Node_Id; Ass2_Id : Node_Id) is
   procedure Set_Next_Actual (Ass1_Id : Node_Id; Ass2_Id : Node_Id) is
   begin
   begin
      if Nkind (Parent (Ass1_Id)) = N_Parameter_Association then
      if Nkind (Parent (Ass1_Id)) = N_Parameter_Association then
         Set_First_Named_Actual (Parent (Ass1_Id), Ass2_Id);
         Set_First_Named_Actual (Parent (Ass1_Id), Ass2_Id);
      end if;
      end if;
   end Set_Next_Actual;
   end Set_Next_Actual;
 
 
   ----------------------------------
   ----------------------------------
   -- Set_Optimize_Alignment_Flags --
   -- Set_Optimize_Alignment_Flags --
   ----------------------------------
   ----------------------------------
 
 
   procedure Set_Optimize_Alignment_Flags (E : Entity_Id) is
   procedure Set_Optimize_Alignment_Flags (E : Entity_Id) is
   begin
   begin
      if Optimize_Alignment = 'S' then
      if Optimize_Alignment = 'S' then
         Set_Optimize_Alignment_Space (E);
         Set_Optimize_Alignment_Space (E);
      elsif Optimize_Alignment = 'T' then
      elsif Optimize_Alignment = 'T' then
         Set_Optimize_Alignment_Time (E);
         Set_Optimize_Alignment_Time (E);
      end if;
      end if;
   end Set_Optimize_Alignment_Flags;
   end Set_Optimize_Alignment_Flags;
 
 
   -----------------------
   -----------------------
   -- Set_Public_Status --
   -- Set_Public_Status --
   -----------------------
   -----------------------
 
 
   procedure Set_Public_Status (Id : Entity_Id) is
   procedure Set_Public_Status (Id : Entity_Id) is
      S : constant Entity_Id := Current_Scope;
      S : constant Entity_Id := Current_Scope;
 
 
      function Within_HSS_Or_If (E : Entity_Id) return Boolean;
      function Within_HSS_Or_If (E : Entity_Id) return Boolean;
      --  Determines if E is defined within handled statement sequence or
      --  Determines if E is defined within handled statement sequence or
      --  an if statement, returns True if so, False otherwise.
      --  an if statement, returns True if so, False otherwise.
 
 
      ----------------------
      ----------------------
      -- Within_HSS_Or_If --
      -- Within_HSS_Or_If --
      ----------------------
      ----------------------
 
 
      function Within_HSS_Or_If (E : Entity_Id) return Boolean is
      function Within_HSS_Or_If (E : Entity_Id) return Boolean is
         N : Node_Id;
         N : Node_Id;
      begin
      begin
         N := Declaration_Node (E);
         N := Declaration_Node (E);
         loop
         loop
            N := Parent (N);
            N := Parent (N);
 
 
            if No (N) then
            if No (N) then
               return False;
               return False;
 
 
            elsif Nkind_In (N, N_Handled_Sequence_Of_Statements,
            elsif Nkind_In (N, N_Handled_Sequence_Of_Statements,
                               N_If_Statement)
                               N_If_Statement)
            then
            then
               return True;
               return True;
            end if;
            end if;
         end loop;
         end loop;
      end Within_HSS_Or_If;
      end Within_HSS_Or_If;
 
 
   --  Start of processing for Set_Public_Status
   --  Start of processing for Set_Public_Status
 
 
   begin
   begin
      --  Everything in the scope of Standard is public
      --  Everything in the scope of Standard is public
 
 
      if S = Standard_Standard then
      if S = Standard_Standard then
         Set_Is_Public (Id);
         Set_Is_Public (Id);
 
 
      --  Entity is definitely not public if enclosing scope is not public
      --  Entity is definitely not public if enclosing scope is not public
 
 
      elsif not Is_Public (S) then
      elsif not Is_Public (S) then
         return;
         return;
 
 
      --  An object or function declaration that occurs in a handled sequence
      --  An object or function declaration that occurs in a handled sequence
      --  of statements or within an if statement is the declaration for a
      --  of statements or within an if statement is the declaration for a
      --  temporary object or local subprogram generated by the expander. It
      --  temporary object or local subprogram generated by the expander. It
      --  never needs to be made public and furthermore, making it public can
      --  never needs to be made public and furthermore, making it public can
      --  cause back end problems.
      --  cause back end problems.
 
 
      elsif Nkind_In (Parent (Id), N_Object_Declaration,
      elsif Nkind_In (Parent (Id), N_Object_Declaration,
                                   N_Function_Specification)
                                   N_Function_Specification)
        and then Within_HSS_Or_If (Id)
        and then Within_HSS_Or_If (Id)
      then
      then
         return;
         return;
 
 
      --  Entities in public packages or records are public
      --  Entities in public packages or records are public
 
 
      elsif Ekind (S) = E_Package or Is_Record_Type (S) then
      elsif Ekind (S) = E_Package or Is_Record_Type (S) then
         Set_Is_Public (Id);
         Set_Is_Public (Id);
 
 
      --  The bounds of an entry family declaration can generate object
      --  The bounds of an entry family declaration can generate object
      --  declarations that are visible to the back-end, e.g. in the
      --  declarations that are visible to the back-end, e.g. in the
      --  the declaration of a composite type that contains tasks.
      --  the declaration of a composite type that contains tasks.
 
 
      elsif Is_Concurrent_Type (S)
      elsif Is_Concurrent_Type (S)
        and then not Has_Completion (S)
        and then not Has_Completion (S)
        and then Nkind (Parent (Id)) = N_Object_Declaration
        and then Nkind (Parent (Id)) = N_Object_Declaration
      then
      then
         Set_Is_Public (Id);
         Set_Is_Public (Id);
      end if;
      end if;
   end Set_Public_Status;
   end Set_Public_Status;
 
 
   -----------------------------
   -----------------------------
   -- Set_Referenced_Modified --
   -- Set_Referenced_Modified --
   -----------------------------
   -----------------------------
 
 
   procedure Set_Referenced_Modified (N : Node_Id; Out_Param : Boolean) is
   procedure Set_Referenced_Modified (N : Node_Id; Out_Param : Boolean) is
      Pref : Node_Id;
      Pref : Node_Id;
 
 
   begin
   begin
      --  Deal with indexed or selected component where prefix is modified
      --  Deal with indexed or selected component where prefix is modified
 
 
      if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
      if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
         Pref := Prefix (N);
         Pref := Prefix (N);
 
 
         --  If prefix is access type, then it is the designated object that is
         --  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.
         --  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
         if No (Etype (Pref)) or else Is_Access_Type (Etype (Pref)) then
            return;
            return;
 
 
            --  Otherwise chase the prefix
            --  Otherwise chase the prefix
 
 
         else
         else
            Set_Referenced_Modified (Pref, Out_Param);
            Set_Referenced_Modified (Pref, Out_Param);
         end if;
         end if;
 
 
      --  Otherwise see if we have an entity name (only other case to process)
      --  Otherwise see if we have an entity name (only other case to process)
 
 
      elsif Is_Entity_Name (N) and then Present (Entity (N)) then
      elsif Is_Entity_Name (N) and then Present (Entity (N)) then
         Set_Referenced_As_LHS           (Entity (N), not Out_Param);
         Set_Referenced_As_LHS           (Entity (N), not Out_Param);
         Set_Referenced_As_Out_Parameter (Entity (N), Out_Param);
         Set_Referenced_As_Out_Parameter (Entity (N), Out_Param);
      end if;
      end if;
   end Set_Referenced_Modified;
   end Set_Referenced_Modified;
 
 
   ----------------------------
   ----------------------------
   -- Set_Scope_Is_Transient --
   -- Set_Scope_Is_Transient --
   ----------------------------
   ----------------------------
 
 
   procedure Set_Scope_Is_Transient (V : Boolean := True) is
   procedure Set_Scope_Is_Transient (V : Boolean := True) is
   begin
   begin
      Scope_Stack.Table (Scope_Stack.Last).Is_Transient := V;
      Scope_Stack.Table (Scope_Stack.Last).Is_Transient := V;
   end Set_Scope_Is_Transient;
   end Set_Scope_Is_Transient;
 
 
   -------------------
   -------------------
   -- Set_Size_Info --
   -- Set_Size_Info --
   -------------------
   -------------------
 
 
   procedure Set_Size_Info (T1, T2 : Entity_Id) is
   procedure Set_Size_Info (T1, T2 : Entity_Id) is
   begin
   begin
      --  We copy Esize, but not RM_Size, since in general RM_Size is
      --  We copy Esize, but not RM_Size, since in general RM_Size is
      --  subtype specific and does not get inherited by all subtypes.
      --  subtype specific and does not get inherited by all subtypes.
 
 
      Set_Esize                     (T1, Esize                     (T2));
      Set_Esize                     (T1, Esize                     (T2));
      Set_Has_Biased_Representation (T1, Has_Biased_Representation (T2));
      Set_Has_Biased_Representation (T1, Has_Biased_Representation (T2));
 
 
      if Is_Discrete_Or_Fixed_Point_Type (T1)
      if Is_Discrete_Or_Fixed_Point_Type (T1)
           and then
           and then
         Is_Discrete_Or_Fixed_Point_Type (T2)
         Is_Discrete_Or_Fixed_Point_Type (T2)
      then
      then
         Set_Is_Unsigned_Type       (T1, Is_Unsigned_Type          (T2));
         Set_Is_Unsigned_Type       (T1, Is_Unsigned_Type          (T2));
      end if;
      end if;
 
 
      Set_Alignment                 (T1, Alignment                 (T2));
      Set_Alignment                 (T1, Alignment                 (T2));
   end Set_Size_Info;
   end Set_Size_Info;
 
 
   --------------------
   --------------------
   -- Static_Integer --
   -- Static_Integer --
   --------------------
   --------------------
 
 
   function Static_Integer (N : Node_Id) return Uint is
   function Static_Integer (N : Node_Id) return Uint is
   begin
   begin
      Analyze_And_Resolve (N, Any_Integer);
      Analyze_And_Resolve (N, Any_Integer);
 
 
      if N = Error
      if N = Error
        or else Error_Posted (N)
        or else Error_Posted (N)
        or else Etype (N) = Any_Type
        or else Etype (N) = Any_Type
      then
      then
         return No_Uint;
         return No_Uint;
      end if;
      end if;
 
 
      if Is_Static_Expression (N) then
      if Is_Static_Expression (N) then
         if not Raises_Constraint_Error (N) then
         if not Raises_Constraint_Error (N) then
            return Expr_Value (N);
            return Expr_Value (N);
         else
         else
            return No_Uint;
            return No_Uint;
         end if;
         end if;
 
 
      elsif Etype (N) = Any_Type then
      elsif Etype (N) = Any_Type then
         return No_Uint;
         return No_Uint;
 
 
      else
      else
         Flag_Non_Static_Expr
         Flag_Non_Static_Expr
           ("static integer expression required here", N);
           ("static integer expression required here", N);
         return No_Uint;
         return No_Uint;
      end if;
      end if;
   end Static_Integer;
   end Static_Integer;
 
 
   --------------------------
   --------------------------
   -- Statically_Different --
   -- Statically_Different --
   --------------------------
   --------------------------
 
 
   function Statically_Different (E1, E2 : Node_Id) return Boolean is
   function Statically_Different (E1, E2 : Node_Id) return Boolean is
      R1 : constant Node_Id := Get_Referenced_Object (E1);
      R1 : constant Node_Id := Get_Referenced_Object (E1);
      R2 : constant Node_Id := Get_Referenced_Object (E2);
      R2 : constant Node_Id := Get_Referenced_Object (E2);
   begin
   begin
      return     Is_Entity_Name (R1)
      return     Is_Entity_Name (R1)
        and then Is_Entity_Name (R2)
        and then Is_Entity_Name (R2)
        and then Entity (R1) /= Entity (R2)
        and then Entity (R1) /= Entity (R2)
        and then not Is_Formal (Entity (R1))
        and then not Is_Formal (Entity (R1))
        and then not Is_Formal (Entity (R2));
        and then not Is_Formal (Entity (R2));
   end Statically_Different;
   end Statically_Different;
 
 
   -----------------------------
   -----------------------------
   -- Subprogram_Access_Level --
   -- Subprogram_Access_Level --
   -----------------------------
   -----------------------------
 
 
   function Subprogram_Access_Level (Subp : Entity_Id) return Uint is
   function Subprogram_Access_Level (Subp : Entity_Id) return Uint is
   begin
   begin
      if Present (Alias (Subp)) then
      if Present (Alias (Subp)) then
         return Subprogram_Access_Level (Alias (Subp));
         return Subprogram_Access_Level (Alias (Subp));
      else
      else
         return Scope_Depth (Enclosing_Dynamic_Scope (Subp));
         return Scope_Depth (Enclosing_Dynamic_Scope (Subp));
      end if;
      end if;
   end Subprogram_Access_Level;
   end Subprogram_Access_Level;
 
 
   -----------------
   -----------------
   -- Trace_Scope --
   -- Trace_Scope --
   -----------------
   -----------------
 
 
   procedure Trace_Scope (N : Node_Id; E : Entity_Id; Msg : String) is
   procedure Trace_Scope (N : Node_Id; E : Entity_Id; Msg : String) is
   begin
   begin
      if Debug_Flag_W then
      if Debug_Flag_W then
         for J in 0 .. Scope_Stack.Last loop
         for J in 0 .. Scope_Stack.Last loop
            Write_Str ("  ");
            Write_Str ("  ");
         end loop;
         end loop;
 
 
         Write_Str (Msg);
         Write_Str (Msg);
         Write_Name (Chars (E));
         Write_Name (Chars (E));
         Write_Str (" from ");
         Write_Str (" from ");
         Write_Location (Sloc (N));
         Write_Location (Sloc (N));
         Write_Eol;
         Write_Eol;
      end if;
      end if;
   end Trace_Scope;
   end Trace_Scope;
 
 
   -----------------------
   -----------------------
   -- Transfer_Entities --
   -- Transfer_Entities --
   -----------------------
   -----------------------
 
 
   procedure Transfer_Entities (From : Entity_Id; To : Entity_Id) is
   procedure Transfer_Entities (From : Entity_Id; To : Entity_Id) is
      Ent : Entity_Id := First_Entity (From);
      Ent : Entity_Id := First_Entity (From);
 
 
   begin
   begin
      if No (Ent) then
      if No (Ent) then
         return;
         return;
      end if;
      end if;
 
 
      if (Last_Entity (To)) = Empty then
      if (Last_Entity (To)) = Empty then
         Set_First_Entity (To, Ent);
         Set_First_Entity (To, Ent);
      else
      else
         Set_Next_Entity (Last_Entity (To), Ent);
         Set_Next_Entity (Last_Entity (To), Ent);
      end if;
      end if;
 
 
      Set_Last_Entity (To, Last_Entity (From));
      Set_Last_Entity (To, Last_Entity (From));
 
 
      while Present (Ent) loop
      while Present (Ent) loop
         Set_Scope (Ent, To);
         Set_Scope (Ent, To);
 
 
         if not Is_Public (Ent) then
         if not Is_Public (Ent) then
            Set_Public_Status (Ent);
            Set_Public_Status (Ent);
 
 
            if Is_Public (Ent)
            if Is_Public (Ent)
              and then Ekind (Ent) = E_Record_Subtype
              and then Ekind (Ent) = E_Record_Subtype
 
 
            then
            then
               --  The components of the propagated Itype must be public
               --  The components of the propagated Itype must be public
               --  as well.
               --  as well.
 
 
               declare
               declare
                  Comp : Entity_Id;
                  Comp : Entity_Id;
               begin
               begin
                  Comp := First_Entity (Ent);
                  Comp := First_Entity (Ent);
                  while Present (Comp) loop
                  while Present (Comp) loop
                     Set_Is_Public (Comp);
                     Set_Is_Public (Comp);
                     Next_Entity (Comp);
                     Next_Entity (Comp);
                  end loop;
                  end loop;
               end;
               end;
            end if;
            end if;
         end if;
         end if;
 
 
         Next_Entity (Ent);
         Next_Entity (Ent);
      end loop;
      end loop;
 
 
      Set_First_Entity (From, Empty);
      Set_First_Entity (From, Empty);
      Set_Last_Entity (From, Empty);
      Set_Last_Entity (From, Empty);
   end Transfer_Entities;
   end Transfer_Entities;
 
 
   -----------------------
   -----------------------
   -- Type_Access_Level --
   -- Type_Access_Level --
   -----------------------
   -----------------------
 
 
   function Type_Access_Level (Typ : Entity_Id) return Uint is
   function Type_Access_Level (Typ : Entity_Id) return Uint is
      Btyp : Entity_Id;
      Btyp : Entity_Id;
 
 
   begin
   begin
      Btyp := Base_Type (Typ);
      Btyp := Base_Type (Typ);
 
 
      --  Ada 2005 (AI-230): For most cases of anonymous access types, we
      --  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
      --  simply use the level where the type is declared. This is true for
      --  stand-alone object declarations, and for anonymous access types
      --  stand-alone object declarations, and for anonymous access types
      --  associated with components the level is the same as that of the
      --  associated with components the level is the same as that of the
      --  enclosing composite type. However, special treatment is needed for
      --  enclosing composite type. However, special treatment is needed for
      --  the cases of access parameters, return objects of an anonymous access
      --  the cases of access parameters, return objects of an anonymous access
      --  type, and, in Ada 95, access discriminants of limited types.
      --  type, and, in Ada 95, access discriminants of limited types.
 
 
      if Ekind (Btyp) in Access_Kind then
      if Ekind (Btyp) in Access_Kind then
         if Ekind (Btyp) = E_Anonymous_Access_Type then
         if Ekind (Btyp) = E_Anonymous_Access_Type then
 
 
            --  If the type is a nonlocal anonymous access type (such as for
            --  If the type is a nonlocal anonymous access type (such as for
            --  an access parameter) we treat it as being declared at the
            --  an access parameter) we treat it as being declared at the
            --  library level to ensure that names such as X.all'access don't
            --  library level to ensure that names such as X.all'access don't
            --  fail static accessibility checks.
            --  fail static accessibility checks.
 
 
            if not Is_Local_Anonymous_Access (Typ) then
            if not Is_Local_Anonymous_Access (Typ) then
               return Scope_Depth (Standard_Standard);
               return Scope_Depth (Standard_Standard);
 
 
            --  If this is a return object, the accessibility level is that of
            --  If this is a return object, the accessibility level is that of
            --  the result subtype of the enclosing function. The test here is
            --  the result subtype of the enclosing function. The test here is
            --  little complicated, because we have to account for extended
            --  little complicated, because we have to account for extended
            --  return statements that have been rewritten as blocks, in which
            --  return statements that have been rewritten as blocks, in which
            --  case we have to find and the Is_Return_Object attribute of the
            --  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
            --  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
            --  simplify this test, but it doesn't seem worthwhile to add a new
            --  flag just for purposes of this test. ???
            --  flag just for purposes of this test. ???
 
 
            elsif Ekind (Scope (Btyp)) = E_Return_Statement
            elsif Ekind (Scope (Btyp)) = E_Return_Statement
              or else
              or else
                (Is_Itype (Btyp)
                (Is_Itype (Btyp)
                  and then Nkind (Associated_Node_For_Itype (Btyp)) =
                  and then Nkind (Associated_Node_For_Itype (Btyp)) =
                             N_Object_Declaration
                             N_Object_Declaration
                  and then Is_Return_Object
                  and then Is_Return_Object
                             (Defining_Identifier
                             (Defining_Identifier
                                (Associated_Node_For_Itype (Btyp))))
                                (Associated_Node_For_Itype (Btyp))))
            then
            then
               declare
               declare
                  Scop : Entity_Id;
                  Scop : Entity_Id;
 
 
               begin
               begin
                  Scop := Scope (Scope (Btyp));
                  Scop := Scope (Scope (Btyp));
                  while Present (Scop) loop
                  while Present (Scop) loop
                     exit when Ekind (Scop) = E_Function;
                     exit when Ekind (Scop) = E_Function;
                     Scop := Scope (Scop);
                     Scop := Scope (Scop);
                  end loop;
                  end loop;
 
 
                  --  Treat the return object's type as having the level of the
                  --  Treat the return object's type as having the level of the
                  --  function's result subtype (as per RM05-6.5(5.3/2)).
                  --  function's result subtype (as per RM05-6.5(5.3/2)).
 
 
                  return Type_Access_Level (Etype (Scop));
                  return Type_Access_Level (Etype (Scop));
               end;
               end;
            end if;
            end if;
         end if;
         end if;
 
 
         Btyp := Root_Type (Btyp);
         Btyp := Root_Type (Btyp);
 
 
         --  The accessibility level of anonymous access types associated with
         --  The accessibility level of anonymous access types associated with
         --  discriminants is that of the current instance of the type, and
         --  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)).
         --  that's deeper than the type itself (AARM 3.10.2 (12.3.21)).
 
 
         --  AI-402: access discriminants have accessibility based on the
         --  AI-402: access discriminants have accessibility based on the
         --  object rather than the type in Ada 2005, so the above paragraph
         --  object rather than the type in Ada 2005, so the above paragraph
         --  doesn't apply.
         --  doesn't apply.
 
 
         --  ??? Needs completion with rules from AI-416
         --  ??? Needs completion with rules from AI-416
 
 
         if Ada_Version <= Ada_95
         if Ada_Version <= Ada_95
           and then Ekind (Typ) = E_Anonymous_Access_Type
           and then Ekind (Typ) = E_Anonymous_Access_Type
           and then Present (Associated_Node_For_Itype (Typ))
           and then Present (Associated_Node_For_Itype (Typ))
           and then Nkind (Associated_Node_For_Itype (Typ)) =
           and then Nkind (Associated_Node_For_Itype (Typ)) =
                                                 N_Discriminant_Specification
                                                 N_Discriminant_Specification
         then
         then
            return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1;
            return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1;
         end if;
         end if;
      end if;
      end if;
 
 
      return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
      return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
   end Type_Access_Level;
   end Type_Access_Level;
 
 
   --------------------
   --------------------
   -- Ultimate_Alias --
   -- Ultimate_Alias --
   --------------------
   --------------------
   --  To do: add occurrences calling this new subprogram
   --  To do: add occurrences calling this new subprogram
 
 
   function Ultimate_Alias (Prim : Entity_Id) return Entity_Id is
   function Ultimate_Alias (Prim : Entity_Id) return Entity_Id is
      E : Entity_Id := Prim;
      E : Entity_Id := Prim;
 
 
   begin
   begin
      while Present (Alias (E)) loop
      while Present (Alias (E)) loop
         E := Alias (E);
         E := Alias (E);
      end loop;
      end loop;
 
 
      return E;
      return E;
   end Ultimate_Alias;
   end Ultimate_Alias;
 
 
   --------------------------
   --------------------------
   -- Unit_Declaration_Node --
   -- Unit_Declaration_Node --
   --------------------------
   --------------------------
 
 
   function Unit_Declaration_Node (Unit_Id : Entity_Id) return Node_Id is
   function Unit_Declaration_Node (Unit_Id : Entity_Id) return Node_Id is
      N : Node_Id := Parent (Unit_Id);
      N : Node_Id := Parent (Unit_Id);
 
 
   begin
   begin
      --  Predefined operators do not have a full function declaration
      --  Predefined operators do not have a full function declaration
 
 
      if Ekind (Unit_Id) = E_Operator then
      if Ekind (Unit_Id) = E_Operator then
         return N;
         return N;
      end if;
      end if;
 
 
      --  Isn't there some better way to express the following ???
      --  Isn't there some better way to express the following ???
 
 
      while Nkind (N) /= N_Abstract_Subprogram_Declaration
      while Nkind (N) /= N_Abstract_Subprogram_Declaration
        and then Nkind (N) /= N_Formal_Package_Declaration
        and then Nkind (N) /= N_Formal_Package_Declaration
        and then Nkind (N) /= N_Function_Instantiation
        and then Nkind (N) /= N_Function_Instantiation
        and then Nkind (N) /= N_Generic_Package_Declaration
        and then Nkind (N) /= N_Generic_Package_Declaration
        and then Nkind (N) /= N_Generic_Subprogram_Declaration
        and then Nkind (N) /= N_Generic_Subprogram_Declaration
        and then Nkind (N) /= N_Package_Declaration
        and then Nkind (N) /= N_Package_Declaration
        and then Nkind (N) /= N_Package_Body
        and then Nkind (N) /= N_Package_Body
        and then Nkind (N) /= N_Package_Instantiation
        and then Nkind (N) /= N_Package_Instantiation
        and then Nkind (N) /= N_Package_Renaming_Declaration
        and then Nkind (N) /= N_Package_Renaming_Declaration
        and then Nkind (N) /= N_Procedure_Instantiation
        and then Nkind (N) /= N_Procedure_Instantiation
        and then Nkind (N) /= N_Protected_Body
        and then Nkind (N) /= N_Protected_Body
        and then Nkind (N) /= N_Subprogram_Declaration
        and then Nkind (N) /= N_Subprogram_Declaration
        and then Nkind (N) /= N_Subprogram_Body
        and then Nkind (N) /= N_Subprogram_Body
        and then Nkind (N) /= N_Subprogram_Body_Stub
        and then Nkind (N) /= N_Subprogram_Body_Stub
        and then Nkind (N) /= N_Subprogram_Renaming_Declaration
        and then Nkind (N) /= N_Subprogram_Renaming_Declaration
        and then Nkind (N) /= N_Task_Body
        and then Nkind (N) /= N_Task_Body
        and then Nkind (N) /= N_Task_Type_Declaration
        and then Nkind (N) /= N_Task_Type_Declaration
        and then Nkind (N) not in N_Formal_Subprogram_Declaration
        and then Nkind (N) not in N_Formal_Subprogram_Declaration
        and then Nkind (N) not in N_Generic_Renaming_Declaration
        and then Nkind (N) not in N_Generic_Renaming_Declaration
      loop
      loop
         N := Parent (N);
         N := Parent (N);
         pragma Assert (Present (N));
         pragma Assert (Present (N));
      end loop;
      end loop;
 
 
      return N;
      return N;
   end Unit_Declaration_Node;
   end Unit_Declaration_Node;
 
 
   ------------------------------
   ------------------------------
   -- Universal_Interpretation --
   -- Universal_Interpretation --
   ------------------------------
   ------------------------------
 
 
   function Universal_Interpretation (Opnd : Node_Id) return Entity_Id is
   function Universal_Interpretation (Opnd : Node_Id) return Entity_Id is
      Index : Interp_Index;
      Index : Interp_Index;
      It    : Interp;
      It    : Interp;
 
 
   begin
   begin
      --  The argument may be a formal parameter of an operator or subprogram
      --  The argument may be a formal parameter of an operator or subprogram
      --  with multiple interpretations, or else an expression for an actual.
      --  with multiple interpretations, or else an expression for an actual.
 
 
      if Nkind (Opnd) = N_Defining_Identifier
      if Nkind (Opnd) = N_Defining_Identifier
        or else not Is_Overloaded (Opnd)
        or else not Is_Overloaded (Opnd)
      then
      then
         if Etype (Opnd) = Universal_Integer
         if Etype (Opnd) = Universal_Integer
           or else Etype (Opnd) = Universal_Real
           or else Etype (Opnd) = Universal_Real
         then
         then
            return Etype (Opnd);
            return Etype (Opnd);
         else
         else
            return Empty;
            return Empty;
         end if;
         end if;
 
 
      else
      else
         Get_First_Interp (Opnd, Index, It);
         Get_First_Interp (Opnd, Index, It);
         while Present (It.Typ) loop
         while Present (It.Typ) loop
            if It.Typ = Universal_Integer
            if It.Typ = Universal_Integer
              or else It.Typ = Universal_Real
              or else It.Typ = Universal_Real
            then
            then
               return It.Typ;
               return It.Typ;
            end if;
            end if;
 
 
            Get_Next_Interp (Index, It);
            Get_Next_Interp (Index, It);
         end loop;
         end loop;
 
 
         return Empty;
         return Empty;
      end if;
      end if;
   end Universal_Interpretation;
   end Universal_Interpretation;
 
 
   ---------------
   ---------------
   -- Unqualify --
   -- Unqualify --
   ---------------
   ---------------
 
 
   function Unqualify (Expr : Node_Id) return Node_Id is
   function Unqualify (Expr : Node_Id) return Node_Id is
   begin
   begin
      --  Recurse to handle unlikely case of multiple levels of qualification
      --  Recurse to handle unlikely case of multiple levels of qualification
 
 
      if Nkind (Expr) = N_Qualified_Expression then
      if Nkind (Expr) = N_Qualified_Expression then
         return Unqualify (Expression (Expr));
         return Unqualify (Expression (Expr));
 
 
      --  Normal case, not a qualified expression
      --  Normal case, not a qualified expression
 
 
      else
      else
         return Expr;
         return Expr;
      end if;
      end if;
   end Unqualify;
   end Unqualify;
 
 
   ----------------------
   ----------------------
   -- Within_Init_Proc --
   -- Within_Init_Proc --
   ----------------------
   ----------------------
 
 
   function Within_Init_Proc return Boolean is
   function Within_Init_Proc return Boolean is
      S : Entity_Id;
      S : Entity_Id;
 
 
   begin
   begin
      S := Current_Scope;
      S := Current_Scope;
      while not Is_Overloadable (S) loop
      while not Is_Overloadable (S) loop
         if S = Standard_Standard then
         if S = Standard_Standard then
            return False;
            return False;
         else
         else
            S := Scope (S);
            S := Scope (S);
         end if;
         end if;
      end loop;
      end loop;
 
 
      return Is_Init_Proc (S);
      return Is_Init_Proc (S);
   end Within_Init_Proc;
   end Within_Init_Proc;
 
 
   ----------------
   ----------------
   -- Wrong_Type --
   -- Wrong_Type --
   ----------------
   ----------------
 
 
   procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id) is
   procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id) is
      Found_Type : constant Entity_Id := First_Subtype (Etype (Expr));
      Found_Type : constant Entity_Id := First_Subtype (Etype (Expr));
      Expec_Type : constant Entity_Id := First_Subtype (Expected_Type);
      Expec_Type : constant Entity_Id := First_Subtype (Expected_Type);
 
 
      function Has_One_Matching_Field return Boolean;
      function Has_One_Matching_Field return Boolean;
      --  Determines if Expec_Type is a record type with a single component or
      --  Determines if Expec_Type is a record type with a single component or
      --  discriminant whose type matches the found type or is one dimensional
      --  discriminant whose type matches the found type or is one dimensional
      --  array whose component type matches the found type.
      --  array whose component type matches the found type.
 
 
      ----------------------------
      ----------------------------
      -- Has_One_Matching_Field --
      -- Has_One_Matching_Field --
      ----------------------------
      ----------------------------
 
 
      function Has_One_Matching_Field return Boolean is
      function Has_One_Matching_Field return Boolean is
         E : Entity_Id;
         E : Entity_Id;
 
 
      begin
      begin
         if Is_Array_Type (Expec_Type)
         if Is_Array_Type (Expec_Type)
           and then Number_Dimensions (Expec_Type) = 1
           and then Number_Dimensions (Expec_Type) = 1
           and then
           and then
             Covers (Etype (Component_Type (Expec_Type)), Found_Type)
             Covers (Etype (Component_Type (Expec_Type)), Found_Type)
         then
         then
            return True;
            return True;
 
 
         elsif not Is_Record_Type (Expec_Type) then
         elsif not Is_Record_Type (Expec_Type) then
            return False;
            return False;
 
 
         else
         else
            E := First_Entity (Expec_Type);
            E := First_Entity (Expec_Type);
            loop
            loop
               if No (E) then
               if No (E) then
                  return False;
                  return False;
 
 
               elsif (Ekind (E) /= E_Discriminant
               elsif (Ekind (E) /= E_Discriminant
                       and then Ekind (E) /= E_Component)
                       and then Ekind (E) /= E_Component)
                 or else (Chars (E) = Name_uTag
                 or else (Chars (E) = Name_uTag
                           or else Chars (E) = Name_uParent)
                           or else Chars (E) = Name_uParent)
               then
               then
                  Next_Entity (E);
                  Next_Entity (E);
 
 
               else
               else
                  exit;
                  exit;
               end if;
               end if;
            end loop;
            end loop;
 
 
            if not Covers (Etype (E), Found_Type) then
            if not Covers (Etype (E), Found_Type) then
               return False;
               return False;
 
 
            elsif Present (Next_Entity (E)) then
            elsif Present (Next_Entity (E)) then
               return False;
               return False;
 
 
            else
            else
               return True;
               return True;
            end if;
            end if;
         end if;
         end if;
      end Has_One_Matching_Field;
      end Has_One_Matching_Field;
 
 
   --  Start of processing for Wrong_Type
   --  Start of processing for Wrong_Type
 
 
   begin
   begin
      --  Don't output message if either type is Any_Type, or if a message
      --  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
      --  has already been posted for this node. We need to do the latter
      --  check explicitly (it is ordinarily done in Errout), because we
      --  check explicitly (it is ordinarily done in Errout), because we
      --  are using ! to force the output of the error messages.
      --  are using ! to force the output of the error messages.
 
 
      if Expec_Type = Any_Type
      if Expec_Type = Any_Type
        or else Found_Type = Any_Type
        or else Found_Type = Any_Type
        or else Error_Posted (Expr)
        or else Error_Posted (Expr)
      then
      then
         return;
         return;
 
 
      --  In  an instance, there is an ongoing problem with completion of
      --  In  an instance, there is an ongoing problem with completion of
      --  type derived from private types. Their structure is what Gigi
      --  type derived from private types. Their structure is what Gigi
      --  expects, but the  Etype is the parent type rather than the
      --  expects, but the  Etype is the parent type rather than the
      --  derived private type itself. Do not flag error in this case. The
      --  derived private type itself. Do not flag error in this case. The
      --  private completion is an entity without a parent, like an Itype.
      --  private completion is an entity without a parent, like an Itype.
      --  Similarly, full and partial views may be incorrect in the instance.
      --  Similarly, full and partial views may be incorrect in the instance.
      --  There is no simple way to insure that it is consistent ???
      --  There is no simple way to insure that it is consistent ???
 
 
      elsif In_Instance then
      elsif In_Instance then
         if Etype (Etype (Expr)) = Etype (Expected_Type)
         if Etype (Etype (Expr)) = Etype (Expected_Type)
           and then
           and then
             (Has_Private_Declaration (Expected_Type)
             (Has_Private_Declaration (Expected_Type)
               or else Has_Private_Declaration (Etype (Expr)))
               or else Has_Private_Declaration (Etype (Expr)))
           and then No (Parent (Expected_Type))
           and then No (Parent (Expected_Type))
         then
         then
            return;
            return;
         end if;
         end if;
      end if;
      end if;
 
 
      --  An interesting special check. If the expression is parenthesized
      --  An interesting special check. If the expression is parenthesized
      --  and its type corresponds to the type of the sole component of the
      --  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
      --  expected record type, or to the component type of the expected one
      --  dimensional array type, then assume we have a bad aggregate attempt.
      --  dimensional array type, then assume we have a bad aggregate attempt.
 
 
      if Nkind (Expr) in N_Subexpr
      if Nkind (Expr) in N_Subexpr
        and then Paren_Count (Expr) /= 0
        and then Paren_Count (Expr) /= 0
        and then Has_One_Matching_Field
        and then Has_One_Matching_Field
      then
      then
         Error_Msg_N ("positional aggregate cannot have one component", Expr);
         Error_Msg_N ("positional aggregate cannot have one component", Expr);
 
 
      --  Another special check, if we are looking for a pool-specific access
      --  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
      --  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-
      --  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
      --  specific type, which is never allowed. The one extra check we make
      --  is that the expected designated type covers the Found_Type.
      --  is that the expected designated type covers the Found_Type.
 
 
      elsif Is_Access_Type (Expec_Type)
      elsif Is_Access_Type (Expec_Type)
        and then Ekind (Found_Type) = E_Access_Attribute_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_General_Access_Type
        and then Ekind (Base_Type (Expec_Type)) /= E_Anonymous_Access_Type
        and then Ekind (Base_Type (Expec_Type)) /= E_Anonymous_Access_Type
        and then Covers
        and then Covers
          (Designated_Type (Expec_Type), Designated_Type (Found_Type))
          (Designated_Type (Expec_Type), Designated_Type (Found_Type))
      then
      then
         Error_Msg_N ("result must be general access type!", Expr);
         Error_Msg_N ("result must be general access type!", Expr);
         Error_Msg_NE ("add ALL to }!", Expr, Expec_Type);
         Error_Msg_NE ("add ALL to }!", Expr, Expec_Type);
 
 
      --  Another special check, if the expected type is an integer type,
      --  Another special check, if the expected type is an integer type,
      --  but the expression is of type System.Address, and the parent is
      --  but the expression is of type System.Address, and the parent is
      --  an addition or subtraction operation whose left operand is the
      --  an addition or subtraction operation whose left operand is the
      --  expression in question and whose right operand is of an integral
      --  expression in question and whose right operand is of an integral
      --  type, then this is an attempt at address arithmetic, so give
      --  type, then this is an attempt at address arithmetic, so give
      --  appropriate message.
      --  appropriate message.
 
 
      elsif Is_Integer_Type (Expec_Type)
      elsif Is_Integer_Type (Expec_Type)
        and then Is_RTE (Found_Type, RE_Address)
        and then Is_RTE (Found_Type, RE_Address)
        and then (Nkind (Parent (Expr)) = N_Op_Add
        and then (Nkind (Parent (Expr)) = N_Op_Add
                    or else
                    or else
                  Nkind (Parent (Expr)) = N_Op_Subtract)
                  Nkind (Parent (Expr)) = N_Op_Subtract)
        and then Expr = Left_Opnd (Parent (Expr))
        and then Expr = Left_Opnd (Parent (Expr))
        and then Is_Integer_Type (Etype (Right_Opnd (Parent (Expr))))
        and then Is_Integer_Type (Etype (Right_Opnd (Parent (Expr))))
      then
      then
         Error_Msg_N
         Error_Msg_N
           ("address arithmetic not predefined in package System",
           ("address arithmetic not predefined in package System",
            Parent (Expr));
            Parent (Expr));
         Error_Msg_N
         Error_Msg_N
           ("\possible missing with/use of System.Storage_Elements",
           ("\possible missing with/use of System.Storage_Elements",
            Parent (Expr));
            Parent (Expr));
         return;
         return;
 
 
      --  If the expected type is an anonymous access type, as for access
      --  If the expected type is an anonymous access type, as for access
      --  parameters and discriminants, the error is on the designated types.
      --  parameters and discriminants, the error is on the designated types.
 
 
      elsif Ekind (Expec_Type) = E_Anonymous_Access_Type then
      elsif Ekind (Expec_Type) = E_Anonymous_Access_Type then
         if Comes_From_Source (Expec_Type) then
         if Comes_From_Source (Expec_Type) then
            Error_Msg_NE ("expected}!", Expr, Expec_Type);
            Error_Msg_NE ("expected}!", Expr, Expec_Type);
         else
         else
            Error_Msg_NE
            Error_Msg_NE
              ("expected an access type with designated}",
              ("expected an access type with designated}",
                 Expr, Designated_Type (Expec_Type));
                 Expr, Designated_Type (Expec_Type));
         end if;
         end if;
 
 
         if Is_Access_Type (Found_Type)
         if Is_Access_Type (Found_Type)
           and then not Comes_From_Source (Found_Type)
           and then not Comes_From_Source (Found_Type)
         then
         then
            Error_Msg_NE
            Error_Msg_NE
              ("\\found an access type with designated}!",
              ("\\found an access type with designated}!",
                Expr, Designated_Type (Found_Type));
                Expr, Designated_Type (Found_Type));
         else
         else
            if From_With_Type (Found_Type) then
            if From_With_Type (Found_Type) then
               Error_Msg_NE ("\\found incomplete}!", Expr, Found_Type);
               Error_Msg_NE ("\\found incomplete}!", Expr, Found_Type);
               Error_Msg_Qual_Level := 99;
               Error_Msg_Qual_Level := 99;
               Error_Msg_NE ("\\missing `WITH &;", Expr, Scope (Found_Type));
               Error_Msg_NE ("\\missing `WITH &;", Expr, Scope (Found_Type));
               Error_Msg_Qual_Level := 0;
               Error_Msg_Qual_Level := 0;
            else
            else
               Error_Msg_NE ("found}!", Expr, Found_Type);
               Error_Msg_NE ("found}!", Expr, Found_Type);
            end if;
            end if;
         end if;
         end if;
 
 
      --  Normal case of one type found, some other type expected
      --  Normal case of one type found, some other type expected
 
 
      else
      else
         --  If the names of the two types are the same, see if some number
         --  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
         --  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
         --  levels, and if we get to standard, it's no use (and probably
         --  represents an error in the compiler) Also do not bother with
         --  represents an error in the compiler) Also do not bother with
         --  internal scope names.
         --  internal scope names.
 
 
         declare
         declare
            Expec_Scope : Entity_Id;
            Expec_Scope : Entity_Id;
            Found_Scope : Entity_Id;
            Found_Scope : Entity_Id;
 
 
         begin
         begin
            Expec_Scope := Expec_Type;
            Expec_Scope := Expec_Type;
            Found_Scope := Found_Type;
            Found_Scope := Found_Type;
 
 
            for Levels in Int range 0 .. 3 loop
            for Levels in Int range 0 .. 3 loop
               if Chars (Expec_Scope) /= Chars (Found_Scope) then
               if Chars (Expec_Scope) /= Chars (Found_Scope) then
                  Error_Msg_Qual_Level := Levels;
                  Error_Msg_Qual_Level := Levels;
                  exit;
                  exit;
               end if;
               end if;
 
 
               Expec_Scope := Scope (Expec_Scope);
               Expec_Scope := Scope (Expec_Scope);
               Found_Scope := Scope (Found_Scope);
               Found_Scope := Scope (Found_Scope);
 
 
               exit when Expec_Scope = Standard_Standard
               exit when Expec_Scope = Standard_Standard
                 or else Found_Scope = Standard_Standard
                 or else Found_Scope = Standard_Standard
                 or else not Comes_From_Source (Expec_Scope)
                 or else not Comes_From_Source (Expec_Scope)
                 or else not Comes_From_Source (Found_Scope);
                 or else not Comes_From_Source (Found_Scope);
            end loop;
            end loop;
         end;
         end;
 
 
         if Is_Record_Type (Expec_Type)
         if Is_Record_Type (Expec_Type)
           and then Present (Corresponding_Remote_Type (Expec_Type))
           and then Present (Corresponding_Remote_Type (Expec_Type))
         then
         then
            Error_Msg_NE ("expected}!", Expr,
            Error_Msg_NE ("expected}!", Expr,
                          Corresponding_Remote_Type (Expec_Type));
                          Corresponding_Remote_Type (Expec_Type));
         else
         else
            Error_Msg_NE ("expected}!", Expr, Expec_Type);
            Error_Msg_NE ("expected}!", Expr, Expec_Type);
         end if;
         end if;
 
 
         if Is_Entity_Name (Expr)
         if Is_Entity_Name (Expr)
           and then Is_Package_Or_Generic_Package (Entity (Expr))
           and then Is_Package_Or_Generic_Package (Entity (Expr))
         then
         then
            Error_Msg_N ("\\found package name!", Expr);
            Error_Msg_N ("\\found package name!", Expr);
 
 
         elsif Is_Entity_Name (Expr)
         elsif Is_Entity_Name (Expr)
           and then
           and then
             (Ekind (Entity (Expr)) = E_Procedure
             (Ekind (Entity (Expr)) = E_Procedure
                or else
                or else
              Ekind (Entity (Expr)) = E_Generic_Procedure)
              Ekind (Entity (Expr)) = E_Generic_Procedure)
         then
         then
            if Ekind (Expec_Type) = E_Access_Subprogram_Type then
            if Ekind (Expec_Type) = E_Access_Subprogram_Type then
               Error_Msg_N
               Error_Msg_N
                 ("found procedure name, possibly missing Access attribute!",
                 ("found procedure name, possibly missing Access attribute!",
                   Expr);
                   Expr);
            else
            else
               Error_Msg_N
               Error_Msg_N
                 ("\\found procedure name instead of function!", Expr);
                 ("\\found procedure name instead of function!", Expr);
            end if;
            end if;
 
 
         elsif Nkind (Expr) = N_Function_Call
         elsif Nkind (Expr) = N_Function_Call
           and then Ekind (Expec_Type) = E_Access_Subprogram_Type
           and then Ekind (Expec_Type) = E_Access_Subprogram_Type
           and then Etype (Designated_Type (Expec_Type)) = Etype (Expr)
           and then Etype (Designated_Type (Expec_Type)) = Etype (Expr)
           and then No (Parameter_Associations (Expr))
           and then No (Parameter_Associations (Expr))
         then
         then
            Error_Msg_N
            Error_Msg_N
              ("found function name, possibly missing Access attribute!",
              ("found function name, possibly missing Access attribute!",
               Expr);
               Expr);
 
 
         --  Catch common error: a prefix or infix operator which is not
         --  Catch common error: a prefix or infix operator which is not
         --  directly visible because the type isn't.
         --  directly visible because the type isn't.
 
 
         elsif Nkind (Expr) in N_Op
         elsif Nkind (Expr) in N_Op
            and then Is_Overloaded (Expr)
            and then Is_Overloaded (Expr)
            and then not Is_Immediately_Visible (Expec_Type)
            and then not Is_Immediately_Visible (Expec_Type)
            and then not Is_Potentially_Use_Visible (Expec_Type)
            and then not Is_Potentially_Use_Visible (Expec_Type)
            and then not In_Use (Expec_Type)
            and then not In_Use (Expec_Type)
            and then Has_Compatible_Type (Right_Opnd (Expr), Expec_Type)
            and then Has_Compatible_Type (Right_Opnd (Expr), Expec_Type)
         then
         then
            Error_Msg_N
            Error_Msg_N
              ("operator of the type is not directly visible!", Expr);
              ("operator of the type is not directly visible!", Expr);
 
 
         elsif Ekind (Found_Type) = E_Void
         elsif Ekind (Found_Type) = E_Void
           and then Present (Parent (Found_Type))
           and then Present (Parent (Found_Type))
           and then Nkind (Parent (Found_Type)) = N_Full_Type_Declaration
           and then Nkind (Parent (Found_Type)) = N_Full_Type_Declaration
         then
         then
            Error_Msg_NE ("\\found premature usage of}!", Expr, Found_Type);
            Error_Msg_NE ("\\found premature usage of}!", Expr, Found_Type);
 
 
         else
         else
            Error_Msg_NE ("\\found}!", Expr, Found_Type);
            Error_Msg_NE ("\\found}!", Expr, Found_Type);
         end if;
         end if;
 
 
         --  A special check for cases like M1 and M2 = 0 where M1 and M2 are
         --  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.
         --  of the same modular type, and (M1 and M2) = 0 was intended.
 
 
         if Expec_Type = Standard_Boolean
         if Expec_Type = Standard_Boolean
           and then Is_Modular_Integer_Type (Found_Type)
           and then Is_Modular_Integer_Type (Found_Type)
           and then Nkind_In (Parent (Expr), N_Op_And, N_Op_Or, N_Op_Xor)
           and then Nkind_In (Parent (Expr), N_Op_And, N_Op_Or, N_Op_Xor)
           and then Nkind (Right_Opnd (Parent (Expr))) in N_Op_Compare
           and then Nkind (Right_Opnd (Parent (Expr))) in N_Op_Compare
         then
         then
            declare
            declare
               Op : constant Node_Id := Right_Opnd (Parent (Expr));
               Op : constant Node_Id := Right_Opnd (Parent (Expr));
               L  : constant Node_Id := Left_Opnd (Op);
               L  : constant Node_Id := Left_Opnd (Op);
               R  : constant Node_Id := Right_Opnd (Op);
               R  : constant Node_Id := Right_Opnd (Op);
            begin
            begin
               --  The case for the message is when the left operand of the
               --  The case for the message is when the left operand of the
               --  comparison is the same modular type, or when it is an
               --  comparison is the same modular type, or when it is an
               --  integer literal (or other universal integer expression),
               --  integer literal (or other universal integer expression),
               --  which would have been typed as the modular type if the
               --  which would have been typed as the modular type if the
               --  parens had been there.
               --  parens had been there.
 
 
               if (Etype (L) = Found_Type
               if (Etype (L) = Found_Type
                     or else
                     or else
                   Etype (L) = Universal_Integer)
                   Etype (L) = Universal_Integer)
                 and then Is_Integer_Type (Etype (R))
                 and then Is_Integer_Type (Etype (R))
               then
               then
                  Error_Msg_N
                  Error_Msg_N
                    ("\\possible missing parens for modular operation", Expr);
                    ("\\possible missing parens for modular operation", Expr);
               end if;
               end if;
            end;
            end;
         end if;
         end if;
 
 
         --  Reset error message qualification indication
         --  Reset error message qualification indication
 
 
         Error_Msg_Qual_Level := 0;
         Error_Msg_Qual_Level := 0;
      end if;
      end if;
   end Wrong_Type;
   end Wrong_Type;
 
 
end Sem_Util;
end Sem_Util;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.