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

with Aspects;        use Aspects;
with Atree;          use Atree;
with Alloc;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Nlists;         use Nlists;
with Errout;         use Errout;
with Lib;            use Lib;
with Namet;          use Namet;
with Opt;            use Opt;
with Output;         use Output;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch12;       use Sem_Ch12;
with Sem_Disp;       use Sem_Disp;
with Sem_Dist;       use Sem_Dist;
with Sem_Util;       use Sem_Util;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Snames;         use Snames;
with Table;
with Treepr;         use Treepr;
with Uintp;          use Uintp;

with GNAT.HTable;    use GNAT.HTable;

package body Sem_Type is

   ---------------------
   -- Data Structures --
   ---------------------

   --  The following data structures establish a mapping between nodes and
   --  their interpretations. An overloaded node has an entry in Interp_Map,
   --  which in turn contains a pointer into the All_Interp array. The
   --  interpretations of a given node are contiguous in All_Interp. Each set
   --  of interpretations is terminated with the marker No_Interp.

   --     Interp_Map           All_Interp

   --      +-----+             +--------+
   --      |     |         --->|interp1 |
   --      |_____|         |   |interp2 |
   --      |index|---------|   |nointerp|
   --      |-----|             |        |
   --      |     |             |        |
   --      +-----+             +--------+

   --  This scheme does not currently reclaim interpretations. In principle,
   --  after a unit is compiled, all overloadings have been resolved, and the
   --  candidate interpretations should be deleted. This should be easier
   --  now than with the previous scheme???

   package All_Interp is new Table.Table (
     Table_Component_Type => Interp,
     Table_Index_Type     => Interp_Index,
     Table_Low_Bound      => 0,
     Table_Initial        => Alloc.All_Interp_Initial,
     Table_Increment      => Alloc.All_Interp_Increment,
     Table_Name           => "All_Interp");

   Header_Max : constant := 3079;
   --  The number of hash buckets; an arbitrary prime number

   subtype Header_Num is Integer range 0 .. Header_Max - 1;

   function Hash (N : Node_Id) return Header_Num;
   --  A trivial hashing function for nodes, used to insert an overloaded
   --  node into the Interp_Map table.

   package Interp_Map is new Simple_HTable
     (Header_Num => Header_Num,
      Element    => Interp_Index,
      No_Element => -1,
      Key        => Node_Id,
      Hash       => Hash,
      Equal      => "=");

   Last_Overloaded : Node_Id := Empty;
   --  Overloaded node after initializing a new collection of intepretation

   -------------------------------------
   -- Handling of Overload Resolution --
   -------------------------------------

   --  Overload resolution uses two passes over the syntax tree of a complete
   --  context. In the first, bottom-up pass, the types of actuals in calls
   --  are used to resolve possibly overloaded subprogram and operator names.
   --  In the second top-down pass, the type of the context (for example the
   --  condition in a while statement) is used to resolve a possibly ambiguous
   --  call, and the unique subprogram name in turn imposes a specific context
   --  on each of its actuals.

   --  Most expressions are in fact unambiguous, and the bottom-up pass is
   --  sufficient  to resolve most everything. To simplify the common case,
   --  names and expressions carry a flag Is_Overloaded to indicate whether
   --  they have more than one interpretation. If the flag is off, then each
   --  name has already a unique meaning and type, and the bottom-up pass is
   --  sufficient (and much simpler).

   --------------------------
   -- Operator Overloading --
   --------------------------

   --  The visibility of operators is handled differently from that of other
   --  entities. We do not introduce explicit versions of primitive operators
   --  for each type definition. As a result, there is only one entity
   --  corresponding to predefined addition on all numeric types, etc. The
   --  back end resolves predefined operators according to their type. The
   --  visibility of primitive operations then reduces to the visibility of the
   --  resulting type: (a + b) is a legal interpretation of some primitive
   --  operator + if the type of the result (which must also be the type of a
   --  and b) is directly visible (either immediately visible or use-visible).

   --  User-defined operators are treated like other functions, but the
   --  visibility of these user-defined operations must be special-cased
   --  to determine whether they hide or are hidden by predefined operators.
   --  The form P."+" (x, y) requires additional handling.

   --  Concatenation is treated more conventionally: for every one-dimensional
   --  array type we introduce a explicit concatenation operator. This is
   --  necessary to handle the case of (element & element => array) which
   --  cannot be handled conveniently if there is no explicit instance of
   --  resulting type of the operation.

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

   procedure All_Overloads;
   pragma Warnings (Off, All_Overloads);
   --  Debugging procedure: list full contents of Overloads table

   function Binary_Op_Interp_Has_Abstract_Op
     (N : Node_Id;
      E : Entity_Id) return Entity_Id;
   --  Given the node and entity of a binary operator, determine whether the
   --  actuals of E contain an abstract interpretation with regards to the
   --  types of their corresponding formals. Return the abstract operation or
   --  Empty.

   function Function_Interp_Has_Abstract_Op
     (N : Node_Id;
      E : Entity_Id) return Entity_Id;
   --  Given the node and entity of a function call, determine whether the
   --  actuals of E contain an abstract interpretation with regards to the
   --  types of their corresponding formals. Return the abstract operation or
   --  Empty.

   function Has_Abstract_Op
     (N   : Node_Id;
      Typ : Entity_Id) return Entity_Id;
   --  Subsidiary routine to Binary_Op_Interp_Has_Abstract_Op and Function_
   --  Interp_Has_Abstract_Op. Determine whether an overloaded node has an
   --  abstract interpretation which yields type Typ.

   procedure New_Interps (N : Node_Id);
   --  Initialize collection of interpretations for the given node, which is
   --  either an overloaded entity, or an operation whose arguments have
   --  multiple interpretations. Interpretations can be added to only one
   --  node at a time.

   function Specific_Type (Typ_1, Typ_2 : Entity_Id) return Entity_Id;
   --  If Typ_1 and Typ_2 are compatible, return the one that is not universal
   --  or is not a "class" type (any_character, etc).

   --------------------
   -- Add_One_Interp --
   --------------------

   procedure Add_One_Interp
     (N         : Node_Id;
      E         : Entity_Id;
      T         : Entity_Id;
      Opnd_Type : Entity_Id := Empty)
   is
      Vis_Type : Entity_Id;

      procedure Add_Entry (Name : Entity_Id; Typ : Entity_Id);
      --  Add one interpretation to an overloaded node. Add a new entry if
      --  not hidden by previous one, and remove previous one if hidden by
      --  new one.

      function Is_Universal_Operation (Op : Entity_Id) return Boolean;
      --  True if the entity is a predefined operator and the operands have
      --  a universal Interpretation.

      ---------------
      -- Add_Entry --
      ---------------

      procedure Add_Entry (Name : Entity_Id; Typ : Entity_Id) is
         Abstr_Op : Entity_Id := Empty;
         I        : Interp_Index;
         It       : Interp;

      --  Start of processing for Add_Entry

      begin
         --  Find out whether the new entry references interpretations that
         --  are abstract or disabled by abstract operators.

         if Ada_Version >= Ada_2005 then
            if Nkind (N) in N_Binary_Op then
               Abstr_Op := Binary_Op_Interp_Has_Abstract_Op (N, Name);
            elsif Nkind (N) = N_Function_Call then
               Abstr_Op := Function_Interp_Has_Abstract_Op (N, Name);
            end if;
         end if;

         Get_First_Interp (N, I, It);
         while Present (It.Nam) loop

            --  Avoid making duplicate entries in overloads

            if Name = It.Nam
              and then Base_Type (It.Typ) = Base_Type (T)
            then
               return;

            --  A user-defined subprogram hides another declared at an outer
            --  level, or one that is use-visible. So return if previous
            --  definition hides new one (which is either in an outer
            --  scope, or use-visible). Note that for functions use-visible
            --  is the same as potentially use-visible. If new one hides
            --  previous one, replace entry in table of interpretations.
            --  If this is a universal operation, retain the operator in case
            --  preference rule applies.

            elsif ((Ekind (Name) in E_Function | E_Procedure
                   and then Ekind (Name) = Ekind (It.Nam))
                 or else (Ekind (Name) = E_Operator
                           and then Ekind (It.Nam) = E_Function))
              and then Is_Immediately_Visible (It.Nam)
              and then Type_Conformant (Name, It.Nam)
              and then Base_Type (It.Typ) = Base_Type (T)
            then
               if Is_Universal_Operation (Name) then
                  exit;

               --  If node is an operator symbol, we have no actuals with
               --  which to check hiding, and this is done in full in the
               --  caller (Analyze_Subprogram_Renaming) so we include the
               --  predefined operator in any case.

               elsif Nkind (N) = N_Operator_Symbol
                 or else
                   (Nkind (N) = N_Expanded_Name
                     and then Nkind (Selector_Name (N)) = N_Operator_Symbol)
               then
                  exit;

               elsif not In_Open_Scopes (Scope (Name))
                 or else Scope_Depth (Scope (Name)) <=
                         Scope_Depth (Scope (It.Nam))
               then
                  --  If ambiguity within instance, and entity is not an
                  --  implicit operation, save for later disambiguation.

                  if Scope (Name) = Scope (It.Nam)
                    and then not Is_Inherited_Operation (Name)
                    and then In_Instance
                  then
                     exit;
                  else
                     return;
                  end if;

               else
                  All_Interp.Table (I).Nam := Name;
                  return;
               end if;

            --  Otherwise keep going

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

         All_Interp.Table (All_Interp.Last) := (Name, Typ, Abstr_Op);
         All_Interp.Append (No_Interp);
      end Add_Entry;

      ----------------------------
      -- Is_Universal_Operation --
      ----------------------------

      function Is_Universal_Operation (Op : Entity_Id) return Boolean is
         Arg : Node_Id;

      begin
         if Ekind (Op) /= E_Operator then
            return False;

         elsif Nkind (N) in N_Binary_Op then
            if Present (Universal_Interpretation (Left_Opnd (N)))
              and then Present (Universal_Interpretation (Right_Opnd (N)))
            then
               return True;
            elsif Nkind (N) in N_Op_Eq | N_Op_Ne
              and then
                (Is_Anonymous_Access_Type (Etype (Left_Opnd (N)))
                  or else Is_Anonymous_Access_Type (Etype (Right_Opnd (N))))
            then
               return True;
            else
               return False;
            end if;

         elsif Nkind (N) in N_Unary_Op then
            return Present (Universal_Interpretation (Right_Opnd (N)));

         elsif Nkind (N) = N_Function_Call then
            Arg := First_Actual (N);
            while Present (Arg) loop
               if No (Universal_Interpretation (Arg)) then
                  return False;
               end if;

               Next_Actual (Arg);
            end loop;

            return True;

         else
            return False;
         end if;
      end Is_Universal_Operation;

   --  Start of processing for Add_One_Interp

   begin
      --  If the interpretation is a predefined operator, verify that the
      --  result type is visible, or that the entity has already been
      --  resolved (case of an instantiation node that refers to a predefined
      --  operation, or an internally generated operator node, or an operator
      --  given as an expanded name). If the operator is a comparison or
      --  equality, it is the type of the operand that matters to determine
      --  whether the operator is visible. In an instance, the check is not
      --  performed, given that the operator was visible in the generic.

      if Ekind (E) = E_Operator then
         if Present (Opnd_Type) then
            Vis_Type := Opnd_Type;
         else
            Vis_Type := Base_Type (T);
         end if;

         if In_Open_Scopes (Scope (Vis_Type))
           or else Is_Potentially_Use_Visible (Vis_Type)
           or else In_Use (Vis_Type)
           or else (In_Use (Scope (Vis_Type))
                     and then not Is_Hidden (Vis_Type))
           or else Nkind (N) = N_Expanded_Name
           or else (Nkind (N) in N_Op and then E = Entity (N))
           or else (In_Instance or else In_Inlined_Body)
           or else Is_Anonymous_Access_Type (Vis_Type)
         then
            null;

         --  If the node is given in functional notation and the prefix
         --  is an expanded name, then the operator is visible if the
         --  prefix is the scope of the result type as well. If the
         --  operator is (implicitly) defined in an extension of system,
         --  it is know to be valid (see Defined_In_Scope, sem_ch4.adb).

         elsif Nkind (N) = N_Function_Call
           and then Nkind (Name (N)) = N_Expanded_Name
           and then (Entity (Prefix (Name (N))) = Scope (Base_Type (T))
                      or else Entity (Prefix (Name (N))) = Scope (Vis_Type)
                      or else Scope (Vis_Type) = System_Aux_Id)
         then
            null;

         --  Save type for subsequent error message, in case no other
         --  interpretation is found.

         else
            Candidate_Type := Vis_Type;
            return;
         end if;

      --  In an instance, an abstract non-dispatching operation cannot be a
      --  candidate interpretation, because it could not have been one in the
      --  generic (it may be a spurious overloading in the instance).

      elsif In_Instance
        and then Is_Overloadable (E)
        and then Is_Abstract_Subprogram (E)
        and then not Is_Dispatching_Operation (E)
      then
         return;

      --  An inherited interface operation that is implemented by some derived
      --  type does not participate in overload resolution, only the
      --  implementation operation does.

      elsif Is_Hidden (E)
        and then Is_Subprogram (E)
        and then Present (Interface_Alias (E))
      then
         --  Ada 2005 (AI-251): If this primitive operation corresponds with
         --  an immediate ancestor interface there is no need to add it to the
         --  list of interpretations. The corresponding aliased primitive is
         --  also in this list of primitive operations and will be used instead
         --  because otherwise we have a dummy ambiguity between the two
         --  subprograms which are in fact the same.

         if not Is_Ancestor
                  (Find_Dispatching_Type (Interface_Alias (E)),
                   Find_Dispatching_Type (E))
         then
            Add_One_Interp (N, Interface_Alias (E), T);
         end if;

         return;

      --  Calling stubs for an RACW operation never participate in resolution,
      --  they are executed only through dispatching calls.

      elsif Is_RACW_Stub_Type_Operation (E) then
         return;
      end if;

      --  If this is the first interpretation of N, N has type Any_Type.
      --  In that case place the new type on the node. If one interpretation
      --  already exists, indicate that the node is overloaded, and store
      --  both the previous and the new interpretation in All_Interp. If
      --  this is a later interpretation, just add it to the set.

      if Etype (N) = Any_Type then
         if Is_Type (E) then
            Set_Etype (N, T);

         else
            --  Record both the operator or subprogram name, and its type

            if Nkind (N) in N_Op or else Is_Entity_Name (N) then
               Set_Entity (N, E);
            end if;

            Set_Etype (N, T);
         end if;

      --  Either there is no current interpretation in the table for any
      --  node or the interpretation that is present is for a different
      --  node. In both cases add a new interpretation to the table.

      elsif No (Last_Overloaded)
        or else
          (Last_Overloaded /= N
            and then not Is_Overloaded (N))
      then
         New_Interps (N);

         if (Nkind (N) in N_Op or else Is_Entity_Name (N))
           and then Present (Entity (N))
         then
            Add_Entry (Entity (N), Etype (N));

         elsif Nkind (N) in N_Subprogram_Call
           and then Is_Entity_Name (Name (N))
         then
            Add_Entry (Entity (Name (N)), Etype (N));

         --  If this is an indirect call there will be no name associated
         --  with the previous entry. To make diagnostics clearer, save
         --  Subprogram_Type of first interpretation, so that the error will
         --  point to the anonymous access to subprogram, not to the result
         --  type of the call itself.

         elsif (Nkind (N)) = N_Function_Call
           and then Nkind (Name (N)) = N_Explicit_Dereference
           and then Is_Overloaded (Name (N))
         then
            declare
               It : Interp;

               Itn : Interp_Index;
               pragma Warnings (Off, Itn);

            begin
               Get_First_Interp (Name (N), Itn, It);
               Add_Entry (It.Nam, Etype (N));
            end;

         else
            --  Overloaded prefix in indexed or selected component, or call
            --  whose name is an expression or another call.

            Add_Entry (Etype (N), Etype (N));
         end if;

         Add_Entry (E, T);

      else
         Add_Entry (E, T);
      end if;
   end Add_One_Interp;

   -------------------
   -- All_Overloads --
   -------------------

   procedure All_Overloads is
   begin
      for J in All_Interp.First .. All_Interp.Last loop

         if Present (All_Interp.Table (J).Nam) then
            Write_Entity_Info (All_Interp.Table (J). Nam, " ");
         else
            Write_Str ("No Interp");
            Write_Eol;
         end if;

         Write_Str ("=================");
         Write_Eol;
      end loop;
   end All_Overloads;

   --------------------------------------
   -- Binary_Op_Interp_Has_Abstract_Op --
   --------------------------------------

   function Binary_Op_Interp_Has_Abstract_Op
     (N : Node_Id;
      E : Entity_Id) return Entity_Id
   is
      Abstr_Op : Entity_Id;
      E_Left   : constant Node_Id := First_Formal (E);
      E_Right  : constant Node_Id := Next_Formal (E_Left);

   begin
      Abstr_Op := Has_Abstract_Op (Left_Opnd (N), Etype (E_Left));
      if Present (Abstr_Op) then
         return Abstr_Op;
      end if;

      return Has_Abstract_Op (Right_Opnd (N), Etype (E_Right));
   end Binary_Op_Interp_Has_Abstract_Op;

   ---------------------
   -- Collect_Interps --
   ---------------------

   procedure Collect_Interps (N : Node_Id) is
      Ent          : constant Entity_Id := Entity (N);
      H            : Entity_Id;
      First_Interp : Interp_Index;

      function Within_Instance (E : Entity_Id) return Boolean;
      --  Within an instance there can be spurious ambiguities between a local
      --  entity and one declared outside of the instance. This can only happen
      --  for subprograms, because otherwise the local entity hides the outer
      --  one. For an overloadable entity, this predicate determines whether it
      --  is a candidate within the instance, or must be ignored.

      ---------------------
      -- Within_Instance --
      ---------------------

      function Within_Instance (E : Entity_Id) return Boolean is
         Inst : Entity_Id;
         Scop : Entity_Id;

      begin
         if not In_Instance then
            return False;
         end if;

         Inst := Current_Scope;
         while Present (Inst) and then not Is_Generic_Instance (Inst) loop
            Inst := Scope (Inst);
         end loop;

         Scop := Scope (E);
         while Present (Scop) and then Scop /= Standard_Standard loop
            if Scop = Inst then
               return True;
            end if;

            Scop := Scope (Scop);
         end loop;

         return False;
      end Within_Instance;

   --  Start of processing for Collect_Interps

   begin
      New_Interps (N);

      --  Unconditionally add the entity that was initially matched

      First_Interp := All_Interp.Last;
      Add_One_Interp (N, Ent, Etype (N));

      --  For expanded name, pick up all additional entities from the
      --  same scope, since these are obviously also visible. Note that
      --  these are not necessarily contiguous on the homonym chain.

      if Nkind (N) = N_Expanded_Name then
         H := Homonym (Ent);
         while Present (H) loop
            if Scope (H) = Scope (Entity (N)) then
               Add_One_Interp (N, H, Etype (H));
            end if;

            H := Homonym (H);
         end loop;

      --  Case of direct name

      else
         --  First, search the homonym chain for directly visible entities

         H := Current_Entity (Ent);
         while Present (H) loop
            exit when
              not Is_Overloadable (H)
                and then Is_Immediately_Visible (H);

            if Is_Immediately_Visible (H) and then H /= Ent then

               --  Only add interpretation if not hidden by an inner
               --  immediately visible one.

               for J in First_Interp .. All_Interp.Last - 1 loop

                  --  Current homograph is not hidden. Add to overloads

                  if not Is_Immediately_Visible (All_Interp.Table (J).Nam) then
                     exit;

                  --  Homograph is hidden, unless it is a predefined operator

                  elsif Type_Conformant (H, All_Interp.Table (J).Nam) then

                     --  A homograph in the same scope can occur within an
                     --  instantiation, the resulting ambiguity has to be
                     --  resolved later. The homographs may both be local
                     --  functions or actuals, or may be declared at different
                     --  levels within the instance. The renaming of an actual
                     --  within the instance must not be included.

                     if Within_Instance (H)
                       and then H /= Renamed_Entity (Ent)
                       and then not Is_Inherited_Operation (H)
                     then
                        All_Interp.Table (All_Interp.Last) :=
                          (H, Etype (H), Empty);
                        All_Interp.Append (No_Interp);
                        goto Next_Homograph;

                     elsif Scope (H) /= Standard_Standard then
                        goto Next_Homograph;
                     end if;
                  end if;
               end loop;

               --  On exit, we know that current homograph is not hidden

               Add_One_Interp (N, H, Etype (H));

               if Debug_Flag_E then
                  Write_Str ("Add overloaded interpretation ");
                  Write_Int (Int (H));
                  Write_Eol;
               end if;
            end if;

            <<Next_Homograph>>
               H := Homonym (H);
         end loop;

         --  Scan list of homographs for use-visible entities only

         H := Current_Entity (Ent);

         while Present (H) loop
            if Is_Potentially_Use_Visible (H)
              and then H /= Ent
              and then Is_Overloadable (H)
            then
               for J in First_Interp .. All_Interp.Last - 1 loop

                  if not Is_Immediately_Visible (All_Interp.Table (J).Nam) then
                     exit;

                  elsif Type_Conformant (H, All_Interp.Table (J).Nam) then
                     goto Next_Use_Homograph;
                  end if;
               end loop;

               Add_One_Interp (N, H, Etype (H));
            end if;

            <<Next_Use_Homograph>>
               H := Homonym (H);
         end loop;
      end if;

      if All_Interp.Last = First_Interp + 1 then

         --  The final interpretation is in fact not overloaded. Note that the
         --  unique legal interpretation may or may not be the original one,
         --  so we need to update N's entity and etype now, because once N
         --  is marked as not overloaded it is also expected to carry the
         --  proper interpretation.

         Set_Is_Overloaded (N, False);
         Set_Entity (N, All_Interp.Table (First_Interp).Nam);
         Set_Etype  (N, All_Interp.Table (First_Interp).Typ);
      end if;
   end Collect_Interps;

   ------------
   -- Covers --
   ------------

   function Covers (T1, T2 : Entity_Id) return Boolean is
      BT1 : Entity_Id;
      BT2 : Entity_Id;

      function Full_View_Covers (Typ1, Typ2 : Entity_Id) return Boolean;
      --  In an instance the proper view may not always be correct for
      --  private types, but private and full view are compatible. This
      --  removes spurious errors from nested instantiations that involve,
      --  among other things, types derived from private types.

      function Real_Actual (T : Entity_Id) return Entity_Id;
      --  If an actual in an inner instance is the formal of an enclosing
      --  generic, the actual in the enclosing instance is the one that can
      --  create an accidental ambiguity, and the check on compatibily of
      --  generic actual types must use this enclosing actual.

      ----------------------
      -- Full_View_Covers --
      ----------------------

      function Full_View_Covers (Typ1, Typ2 : Entity_Id) return Boolean is
      begin
         if Present (Full_View (Typ1))
           and then Covers (Full_View (Typ1), Typ2)
         then
            return True;

         elsif Present (Underlying_Full_View (Typ1))
           and then Covers (Underlying_Full_View (Typ1), Typ2)
         then
            return True;

         else
            return False;
         end if;
      end Full_View_Covers;

      -----------------
      -- Real_Actual --
      -----------------

      function Real_Actual (T : Entity_Id) return Entity_Id is
         Par : constant Node_Id := Parent (T);
         RA  : Entity_Id;

      begin
         --  Retrieve parent subtype from subtype declaration for actual

         if Nkind (Par) = N_Subtype_Declaration
           and then not Comes_From_Source (Par)
           and then Is_Entity_Name (Subtype_Indication (Par))
         then
            RA := Entity (Subtype_Indication (Par));

            if Is_Generic_Actual_Type (RA) then
               return RA;
            end if;
         end if;

         --  Otherwise actual is not the actual of an enclosing instance

         return T;
      end Real_Actual;

   --  Start of processing for Covers

   begin
      --  If either operand is missing, then this is an error, but ignore it
      --  and pretend we have a cover if errors already detected since this may
      --  simply mean we have malformed trees or a semantic error upstream.

      if No (T1) or else No (T2) then
         if Total_Errors_Detected /= 0 then
            return True;
         else
            raise Program_Error;
         end if;
      end if;

      --  Trivial case: same types are always compatible

      if T1 = T2 then
         return True;
      end if;

      --  First check for Standard_Void_Type, which is special. Subsequent
      --  processing in this routine assumes T1 and T2 are bona fide types;
      --  Standard_Void_Type is a special entity that has some, but not all,
      --  properties of types.

      if T1 = Standard_Void_Type or else T2 = Standard_Void_Type then
         return False;
      end if;

      BT1 := Base_Type (T1);
      BT2 := Base_Type (T2);

      --  Handle underlying view of records with unknown discriminants
      --  using the original entity that motivated the construction of
      --  this underlying record view (see Build_Derived_Private_Type).

      if Is_Underlying_Record_View (BT1) then
         BT1 := Underlying_Record_View (BT1);
      end if;

      if Is_Underlying_Record_View (BT2) then
         BT2 := Underlying_Record_View (BT2);
      end if;

      --  Simplest case: types that have the same base type and are not generic
      --  actuals are compatible. Generic actuals belong to their class but are
      --  not compatible with other types of their class, and in particular
      --  with other generic actuals. They are however compatible with their
      --  own subtypes, and itypes with the same base are compatible as well.
      --  Similarly, constrained subtypes obtained from expressions of an
      --  unconstrained nominal type are compatible with the base type (may
      --  lead to spurious ambiguities in obscure cases ???)

      --  Generic actuals require special treatment to avoid spurious ambi-
      --  guities in an instance, when two formal types are instantiated with
      --  the same actual, so that different subprograms end up with the same
      --  signature in the instance. If a generic actual is the actual of an
      --  enclosing instance, it is that actual that we must compare: generic
      --  actuals are only incompatible if they appear in the same instance.

      if BT1 = BT2
        or else BT1 = T2
        or else BT2 = T1
      then
         if not Is_Generic_Actual_Type (T1)
              or else
            not Is_Generic_Actual_Type (T2)
         then
            return True;

         --  Both T1 and T2 are generic actual types

         else
            declare
               RT1 : constant Entity_Id := Real_Actual (T1);
               RT2 : constant Entity_Id := Real_Actual (T2);
            begin
               return RT1 = RT2
                  or else Is_Itype (T1)
                  or else Is_Itype (T2)
                  or else Is_Constr_Subt_For_U_Nominal (T1)
                  or else Is_Constr_Subt_For_U_Nominal (T2)
                  or else Scope (RT1) /= Scope (RT2);
            end;
         end if;

      --  Literals are compatible with types in a given "class"

      elsif     (T2 = Universal_Integer and then Is_Integer_Type (T1))
        or else (T2 = Universal_Real    and then Is_Real_Type (T1))
        or else (T2 = Universal_Fixed   and then Is_Fixed_Point_Type (T1))
        or else (T2 = Any_Fixed         and then Is_Fixed_Point_Type (T1))
        or else (T2 = Any_Character     and then Is_Character_Type (T1))
        or else (T2 = Any_String        and then Is_String_Type (T1))
        or else (T2 = Any_Access        and then Is_Access_Type (T1))
      then
         return True;

      --  The context may be class wide, and a class-wide type is compatible
      --  with any member of the class.

      elsif Is_Class_Wide_Type (T1)
        and then Is_Ancestor (Root_Type (T1), T2)
      then
         return True;

      elsif Is_Class_Wide_Type (T1)
        and then Is_Class_Wide_Type (T2)
        and then Base_Type (Etype (T1)) = Base_Type (Etype (T2))
      then
         return True;

      --  Ada 2005 (AI-345): A class-wide abstract interface type covers a
      --  task_type or protected_type that implements the interface.

      elsif Ada_Version >= Ada_2005
        and then Is_Concurrent_Type (T2)
        and then Is_Class_Wide_Type (T1)
        and then Is_Interface (Etype (T1))
        and then Interface_Present_In_Ancestor
                   (Typ => BT2, Iface => Etype (T1))
      then
         return True;

      --  Ada 2005 (AI-251): A class-wide abstract interface type T1 covers an
      --  object T2 implementing T1.

      elsif Ada_Version >= Ada_2005
        and then Is_Tagged_Type (T2)
        and then Is_Class_Wide_Type (T1)
        and then Is_Interface (Etype (T1))
      then
         if Interface_Present_In_Ancestor (Typ   => T2,
                                           Iface => Etype (T1))
         then
            return True;
         end if;

         declare
            E    : Entity_Id;
            Elmt : Elmt_Id;

         begin
            if Is_Concurrent_Type (BT2) then
               E := Corresponding_Record_Type (BT2);
            else
               E := BT2;
            end if;

            --  Ada 2005 (AI-251): A class-wide abstract interface type T1
            --  covers an object T2 that implements a direct derivation of T1.
            --  Note: test for presence of E is defense against previous error.

            if No (E) then
               Check_Error_Detected;

            --  Here we have a corresponding record type

            elsif Present (Interfaces (E)) then
               Elmt := First_Elmt (Interfaces (E));
               while Present (Elmt) loop
                  if Is_Ancestor (Etype (T1), Node (Elmt)) then
                     return True;
                  else
                     Next_Elmt (Elmt);
                  end if;
               end loop;
            end if;

            --  We should also check the case in which T1 is an ancestor of
            --  some implemented interface???

            return False;
         end;

      --  In a dispatching call, the formal is of some specific type, and the
      --  actual is of the corresponding class-wide type, including a subtype
      --  of the class-wide type.

      elsif Is_Class_Wide_Type (T2)
        and then
          (Class_Wide_Type (T1) = Class_Wide_Type (T2)
            or else Base_Type (Root_Type (T2)) = BT1)
      then
         return True;

      --  Some contexts require a class of types rather than a specific type.
      --  For example, conditions require any boolean type, fixed point
      --  attributes require some real type, etc. The built-in types Any_XXX
      --  represent these classes.

      elsif     (T1 = Any_Integer  and then Is_Integer_Type     (T2))
        or else (T1 = Any_Boolean  and then Is_Boolean_Type     (T2))
        or else (T1 = Any_Real     and then Is_Real_Type        (T2))
        or else (T1 = Any_Fixed    and then Is_Fixed_Point_Type (T2))
        or else (T1 = Any_Discrete and then Is_Discrete_Type    (T2))
      then
         return True;

      --  An aggregate is compatible with an array or record type

      elsif T2 = Any_Composite and then Is_Aggregate_Type (T1) then
         return True;

      --  In Ada_2022, an aggregate is compatible with the type that
      --  as the corresponding aspect.

      elsif Ada_Version >= Ada_2022
        and then T2 = Any_Composite
        and then Present (Find_Aspect (T1, Aspect_Aggregate))
      then
         return True;

      --  If the expected type is an anonymous access, the designated type must
      --  cover that of the expression. Use the base type for this check: even
      --  though access subtypes are rare in sources, they are generated for
      --  actuals in instantiations.

      elsif Ekind (BT1) = E_Anonymous_Access_Type
        and then Is_Access_Type (T2)
        and then Covers (Designated_Type (T1), Designated_Type (T2))
      then
         return True;

      --  Ada 2012 (AI05-0149): Allow an anonymous access type in the context
      --  of a named general access type. An implicit conversion will be
      --  applied. For the resolution, the designated types must match if
      --  untagged; further, if the designated type is tagged, the designated
      --  type of the anonymous access type shall be covered by the designated
      --  type of the named access type.

      elsif Ada_Version >= Ada_2012
        and then Ekind (BT1) = E_General_Access_Type
        and then Ekind (BT2) = E_Anonymous_Access_Type
        and then Covers (Designated_Type (T1), Designated_Type (T2))
        and then (Is_Class_Wide_Type (Designated_Type (T1)) >=
                  Is_Class_Wide_Type (Designated_Type (T2)))
      then
         return True;

      --  An Access_To_Subprogram is compatible with itself, or with an
      --  anonymous type created for an attribute reference Access.

      elsif Ekind (BT1) in E_Access_Subprogram_Type
                         | E_Access_Protected_Subprogram_Type
        and then Is_Access_Type (T2)
        and then (not Comes_From_Source (T1)
                   or else not Comes_From_Source (T2))
        and then (Is_Overloadable (Designated_Type (T2))
                   or else Ekind (Designated_Type (T2)) = E_Subprogram_Type)
        and then Type_Conformant (Designated_Type (T1), Designated_Type (T2))
        and then Mode_Conformant (Designated_Type (T1), Designated_Type (T2))
      then
         return True;

      --  Ada 2005 (AI-254): An Anonymous_Access_To_Subprogram is compatible
      --  with itself, or with an anonymous type created for an attribute
      --  reference Access.

      elsif Ekind (BT1) in E_Anonymous_Access_Subprogram_Type
                         | E_Anonymous_Access_Protected_Subprogram_Type
        and then Is_Access_Type (T2)
        and then (not Comes_From_Source (T1)
                   or else not Comes_From_Source (T2))
        and then (Is_Overloadable (Designated_Type (T2))
                   or else Ekind (Designated_Type (T2)) = E_Subprogram_Type)
        and then Type_Conformant (Designated_Type (T1), Designated_Type (T2))
        and then Mode_Conformant (Designated_Type (T1), Designated_Type (T2))
      then
         return True;

      --  The context can be a remote access type, and the expression the
      --  corresponding source type declared in a categorized package, or
      --  vice versa.

      elsif Is_Record_Type (T1)
        and then (Is_Remote_Call_Interface (T1) or else Is_Remote_Types (T1))
        and then Present (Corresponding_Remote_Type (T1))
      then
         return Covers (Corresponding_Remote_Type (T1), T2);

      --  and conversely.

      elsif Is_Record_Type (T2)
        and then (Is_Remote_Call_Interface (T2) or else Is_Remote_Types (T2))
        and then Present (Corresponding_Remote_Type (T2))
      then
         return Covers (Corresponding_Remote_Type (T2), T1);

      --  Synchronized types are represented at run time by their corresponding
      --  record type. During expansion one is replaced with the other, but
      --  they are compatible views of the same type.

      elsif Is_Record_Type (T1)
        and then Is_Concurrent_Type (T2)
        and then Present (Corresponding_Record_Type (T2))
      then
         return Covers (T1, Corresponding_Record_Type (T2));

      elsif Is_Concurrent_Type (T1)
        and then Present (Corresponding_Record_Type (T1))
        and then Is_Record_Type (T2)
      then
         return Covers (Corresponding_Record_Type (T1), T2);

      --  During analysis, an attribute reference 'Access has a special type
      --  kind: Access_Attribute_Type, to be replaced eventually with the type
      --  imposed by context.

      elsif Ekind (T2) = E_Access_Attribute_Type
        and then Ekind (BT1) in E_General_Access_Type | E_Access_Type
        and then Covers (Designated_Type (T1), Designated_Type (T2))
      then
         --  If the target type is a RACW type while the source is an access
         --  attribute type, we are building a RACW that may be exported.

         if Is_Remote_Access_To_Class_Wide_Type (BT1) then
            Set_Has_RACW (Current_Sem_Unit);
         end if;

         return True;

      --  Ditto for allocators, which eventually resolve to the context type

      elsif Ekind (T2) = E_Allocator_Type and then Is_Access_Type (T1) then
         return Covers (Designated_Type (T1), Designated_Type (T2))
           or else
             (From_Limited_With (Designated_Type (T1))
               and then Covers (Designated_Type (T2), Designated_Type (T1)));

      --  A boolean operation on integer literals is compatible with modular
      --  context.

      elsif T2 = Any_Modular and then Is_Modular_Integer_Type (T1) then
         return True;

      --  The actual type may be the result of a previous error

      elsif BT2 = Any_Type then
         return True;

      --  A Raise_Expressions is legal in any expression context

      elsif BT2 = Raise_Type then
         return True;

      --  A packed array type covers its corresponding non-packed type. This is
      --  not legitimate Ada, but allows the omission of a number of otherwise
      --  useless unchecked conversions, and since this can only arise in
      --  (known correct) expanded code, no harm is done.

      elsif Is_Packed_Array (T2)
        and then T1 = Packed_Array_Impl_Type (T2)
      then
         return True;

      --  Similarly an array type covers its corresponding packed array type

      elsif Is_Packed_Array (T1)
        and then T2 = Packed_Array_Impl_Type (T1)
      then
         return True;

      --  In instances, or with types exported from instantiations, check
      --  whether a partial and a full view match. Verify that types are
      --  legal, to prevent cascaded errors.

      elsif Is_Private_Type (T1)
        and then (In_Instance
                   or else (Is_Type (T2) and then Is_Generic_Actual_Type (T2)))
        and then Full_View_Covers (T1, T2)
      then
         return True;

      elsif Is_Private_Type (T2)
        and then (In_Instance
                   or else (Is_Type (T1) and then Is_Generic_Actual_Type (T1)))
        and then Full_View_Covers (T2, T1)
      then
         return True;

      --  In the expansion of inlined bodies, types are compatible if they
      --  are structurally equivalent.

      elsif In_Inlined_Body
        and then (Underlying_Type (T1) = Underlying_Type (T2)
                   or else
                     (Is_Access_Type (T1)
                       and then Is_Access_Type (T2)
                       and then Designated_Type (T1) = Designated_Type (T2))
                   or else
                     (T1 = Any_Access
                       and then Is_Access_Type (Underlying_Type (T2)))
                   or else
                     (T2 = Any_Composite
                       and then Is_Composite_Type (Underlying_Type (T1))))
      then
         return True;

      --  Ada 2005 (AI-50217): Additional branches to make the shadow entity
      --  obtained through a limited_with compatible with its real entity.

      elsif From_Limited_With (T1) then

         --  If the expected type is the nonlimited view of a type, the
         --  expression may have the limited view. If that one in turn is
         --  incomplete, get full view if available.

         return Has_Non_Limited_View (T1)
           and then Covers (Get_Full_View (Non_Limited_View (T1)), T2);

      elsif From_Limited_With (T2) then

         --  If units in the context have Limited_With clauses on each other,
         --  either type might have a limited view. Checks performed elsewhere
         --  verify that the context type is the nonlimited view.

         return Has_Non_Limited_View (T2)
           and then Covers (T1, Get_Full_View (Non_Limited_View (T2)));

      --  Ada 2005 (AI-412): Coverage for regular incomplete subtypes

      elsif Ekind (T1) = E_Incomplete_Subtype then
         return Covers (Full_View (Etype (T1)), T2);

      elsif Ekind (T2) = E_Incomplete_Subtype then
         return Covers (T1, Full_View (Etype (T2)));

      --  Ada 2005 (AI-423): Coverage of formal anonymous access types
      --  and actual anonymous access types in the context of generic
      --  instantiations. We have the following situation:

      --     generic
      --        type Formal is private;
      --        Formal_Obj : access Formal;  --  T1
      --     package G is ...

      --     package P is
      --        type Actual is ...
      --        Actual_Obj : access Actual;  --  T2
      --        package Instance is new G (Formal     => Actual,
      --                                   Formal_Obj => Actual_Obj);

      elsif Ada_Version >= Ada_2005
        and then Is_Anonymous_Access_Type (T1)
        and then Is_Anonymous_Access_Type (T2)
        and then Is_Generic_Type (Directly_Designated_Type (T1))
        and then Get_Instance_Of (Directly_Designated_Type (T1)) =
                                               Directly_Designated_Type (T2)
      then
         return True;

      --  Otherwise, types are not compatible

      else
         return False;
      end if;
   end Covers;

   ------------------
   -- Disambiguate --
   ------------------

   function Disambiguate
     (N      : Node_Id;
      I1, I2 : Interp_Index;
      Typ    : Entity_Id) return Interp
   is
      I           : Interp_Index;
      It          : Interp;
      It1, It2    : Interp;
      Nam1, Nam2  : Entity_Id;
      Predef_Subp : Entity_Id;
      User_Subp   : Entity_Id;

      function Inherited_From_Actual (S : Entity_Id) return Boolean;
      --  Determine whether one of the candidates is an operation inherited by
      --  a type that is derived from an actual in an instantiation.

      function In_Same_Declaration_List
        (Typ     : Entity_Id;
         Op_Decl : Entity_Id) return Boolean;
      --  AI05-0020: a spurious ambiguity may arise when equality on anonymous
      --  access types is declared on the partial view of a designated type, so
      --  that the type declaration and equality are not in the same list of
      --  declarations. This AI gives a preference rule for the user-defined
      --  operation. Same rule applies for arithmetic operations on private
      --  types completed with fixed-point types: the predefined operation is
      --  hidden;  this is already handled properly in GNAT.

      function Is_Actual_Subprogram (S : Entity_Id) return Boolean;
      --  Determine whether a subprogram is an actual in an enclosing instance.
      --  An overloading between such a subprogram and one declared outside the
      --  instance is resolved in favor of the first, because it resolved in
      --  the generic. Within the instance the actual is represented by a
      --  constructed subprogram renaming.

      function Matches (Op : Node_Id; Func_Id : Entity_Id) return Boolean;
      --  Determine whether function Func_Id is an exact match for binary or
      --  unary operator Op.

      function Operand_Type return Entity_Id;
      --  Determine type of operand for an equality operation, to apply Ada
      --  2005 rules to equality on anonymous access types.

      function Standard_Operator return Boolean;
      --  Check whether subprogram is predefined operator declared in Standard.
      --  It may given by an operator name, or by an expanded name whose prefix
      --  is Standard.

      function Remove_Conversions return Interp;
      --  Last chance for pathological cases involving comparisons on literals,
      --  and user overloadings of the same operator. Such pathologies have
      --  been removed from the ACVC, but still appear in two DEC tests, with
      --  the following notable quote from Ben Brosgol:
      --
      --  [Note: I disclaim all credit/responsibility/blame for coming up with
      --  this example; Robert Dewar brought it to our attention, since it is
      --  apparently found in the ACVC 1.5. I did not attempt to find the
      --  reason in the Reference Manual that makes the example legal, since I
      --  was too nauseated by it to want to pursue it further.]
      --
      --  Accordingly, this is not a fully recursive solution, but it handles
      --  DEC tests c460vsa, c460vsb. It also handles ai00136a, which pushes
      --  pathology in the other direction with calls whose multiple overloaded
      --  actuals make them truly unresolvable.

      --  The new rules concerning abstract operations create additional need
      --  for special handling of expressions with universal operands, see
      --  comments to Has_Abstract_Interpretation below.

      function Is_User_Defined_Anonymous_Access_Equality
        (User_Subp, Predef_Subp : Entity_Id) return Boolean;
      --  Check for Ada 2005, AI-020: If the context involves an anonymous
      --  access operand, recognize a user-defined equality (User_Subp) with
      --  the proper signature, declared in the same declarative list as the
      --  type and not hiding a predefined equality Predef_Subp.

      ---------------------------
      -- Inherited_From_Actual --
      ---------------------------

      function Inherited_From_Actual (S : Entity_Id) return Boolean is
         Par : constant Node_Id := Parent (S);
      begin
         if Nkind (Par) /= N_Full_Type_Declaration
           or else Nkind (Type_Definition (Par)) /= N_Derived_Type_Definition
         then
            return False;
         else
            return Is_Entity_Name (Subtype_Indication (Type_Definition (Par)))
              and then
                Is_Generic_Actual_Type (
                  Entity (Subtype_Indication (Type_Definition (Par))));
         end if;
      end Inherited_From_Actual;

      ------------------------------
      -- In_Same_Declaration_List --
      ------------------------------

      function In_Same_Declaration_List
        (Typ     : Entity_Id;
         Op_Decl : Entity_Id) return Boolean
      is
         Scop : constant Entity_Id := Scope (Typ);

      begin
         return In_Same_List (Parent (Typ), Op_Decl)
           or else
             (Is_Package_Or_Generic_Package (Scop)
               and then List_Containing (Op_Decl) =
                              Visible_Declarations (Parent (Scop))
               and then List_Containing (Parent (Typ)) =
                              Private_Declarations (Parent (Scop)));
      end In_Same_Declaration_List;

      --------------------------
      -- Is_Actual_Subprogram --
      --------------------------

      function Is_Actual_Subprogram (S : Entity_Id) return Boolean is
      begin
         return In_Open_Scopes (Scope (S))
           and then Nkind (Unit_Declaration_Node (S)) =
                                         N_Subprogram_Renaming_Declaration

           --  Why the Comes_From_Source test here???

           and then not Comes_From_Source (Unit_Declaration_Node (S))

           and then
             (Is_Generic_Instance (Scope (S))
               or else Is_Wrapper_Package (Scope (S)));
      end Is_Actual_Subprogram;

      -------------
      -- Matches --
      -------------

      function Matches (Op : Node_Id; Func_Id : Entity_Id) return Boolean is
         function Matching_Types
           (Opnd_Typ   : Entity_Id;
            Formal_Typ : Entity_Id) return Boolean;
         --  Determine whether operand type Opnd_Typ and formal parameter type
         --  Formal_Typ are either the same or compatible.

         --------------------
         -- Matching_Types --
         --------------------

         function Matching_Types
           (Opnd_Typ   : Entity_Id;
            Formal_Typ : Entity_Id) return Boolean
         is
         begin
            --  A direct match

            if Opnd_Typ = Formal_Typ then
               return True;

            --  Any integer type matches universal integer

            elsif Opnd_Typ = Universal_Integer
              and then Is_Integer_Type (Formal_Typ)
            then
               return True;

            --  Any floating point type matches universal real

            elsif Opnd_Typ = Universal_Real
              and then Is_Floating_Point_Type (Formal_Typ)
            then
               return True;

            --  The type of the formal parameter maps a generic actual type to
            --  a generic formal type. If the operand type is the type being
            --  mapped in an instance, then this is a match.

            elsif Is_Generic_Actual_Type (Formal_Typ)
              and then Etype (Formal_Typ) = Opnd_Typ
            then
               return True;

            --  ??? There are possibly other cases to consider

            else
               return False;
            end if;
         end Matching_Types;

         --  Local variables

         F1      : constant Entity_Id := First_Formal (Func_Id);
         F1_Typ  : constant Entity_Id := Etype (F1);
         F2      : constant Entity_Id := Next_Formal (F1);
         F2_Typ  : constant Entity_Id := Etype (F2);
         Lop_Typ : constant Entity_Id := Etype (Left_Opnd  (Op));
         Rop_Typ : constant Entity_Id := Etype (Right_Opnd (Op));

      --  Start of processing for Matches

      begin
         if Lop_Typ = F1_Typ then
            return Matching_Types (Rop_Typ, F2_Typ);

         elsif Rop_Typ = F2_Typ then
            return Matching_Types (Lop_Typ, F1_Typ);

         --  Otherwise this is not a good match because each operand-formal
         --  pair is compatible only on base-type basis, which is not specific
         --  enough.

         else
            return False;
         end if;
      end Matches;

      ------------------
      -- Operand_Type --
      ------------------

      function Operand_Type return Entity_Id is
         Opnd : Node_Id;

      begin
         if Nkind (N) = N_Function_Call then
            Opnd := First_Actual (N);
         else
            Opnd := Left_Opnd (N);
         end if;

         return Etype (Opnd);
      end Operand_Type;

      ------------------------
      -- Remove_Conversions --
      ------------------------

      function Remove_Conversions return Interp is
         I    : Interp_Index;
         It   : Interp;
         It1  : Interp;
         F1   : Entity_Id;
         Act1 : Node_Id;
         Act2 : Node_Id;

         function Has_Abstract_Interpretation (N : Node_Id) return Boolean;
         --  If an operation has universal operands the universal operation
         --  is present among its interpretations. If there is an abstract
         --  interpretation for the operator, with a numeric result, this
         --  interpretation was already removed in sem_ch4, but the universal
         --  one is still visible. We must rescan the list of operators and
         --  remove the universal interpretation to resolve the ambiguity.

         ---------------------------------
         -- Has_Abstract_Interpretation --
         ---------------------------------

         function Has_Abstract_Interpretation (N : Node_Id) return Boolean is
            E : Entity_Id;

         begin
            if Nkind (N) not in N_Op
              or else Ada_Version < Ada_2005
              or else not Is_Overloaded (N)
              or else No (Universal_Interpretation (N))
            then
               return False;

            else
               E := Get_Name_Entity_Id (Chars (N));
               while Present (E) loop
                  if Is_Overloadable (E)
                    and then Is_Abstract_Subprogram (E)
                    and then Is_Numeric_Type (Etype (E))
                  then
                     return True;
                  else
                     E := Homonym (E);
                  end if;
               end loop;

               --  Finally, if an operand of the binary operator is itself
               --  an operator, recurse to see whether its own abstract
               --  interpretation is responsible for the spurious ambiguity.

               if Nkind (N) in N_Binary_Op then
                  return Has_Abstract_Interpretation (Left_Opnd (N))
                    or else Has_Abstract_Interpretation (Right_Opnd (N));

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

               else
                  return False;
               end if;
            end if;
         end Has_Abstract_Interpretation;

      --  Start of processing for Remove_Conversions

      begin
         It1 := No_Interp;

         Get_First_Interp (N, I, It);
         while Present (It.Typ) loop
            if not Is_Overloadable (It.Nam) then
               return No_Interp;
            end if;

            F1 := First_Formal (It.Nam);

            if No (F1) then
               return It1;

            else
               if Nkind (N) in N_Subprogram_Call then
                  Act1 := First_Actual (N);

                  if Present (Act1) then
                     Act2 := Next_Actual (Act1);
                  else
                     Act2 := Empty;
                  end if;

               elsif Nkind (N) in N_Unary_Op then
                  Act1 := Right_Opnd (N);
                  Act2 := Empty;

               elsif Nkind (N) in N_Binary_Op then
                  Act1 := Left_Opnd (N);
                  Act2 := Right_Opnd (N);

                  --  Use the type of the second formal, so as to include
                  --  exponentiation, where the exponent may be ambiguous and
                  --  the result non-universal.

                  Next_Formal (F1);

               else
                  return It1;
               end if;

               if Nkind (Act1) in N_Op
                 and then Is_Overloaded (Act1)
                 and then
                   (Nkind (Act1) in N_Unary_Op
                     or else Nkind (Left_Opnd (Act1)) in
                               N_Integer_Literal | N_Real_Literal)
                 and then Nkind (Right_Opnd (Act1)) in
                            N_Integer_Literal | N_Real_Literal
                 and then Has_Compatible_Type (Act1, Standard_Boolean)
                 and then Etype (F1) = Standard_Boolean
               then
                  --  If the two candidates are the original ones, the
                  --  ambiguity is real. Otherwise keep the original, further
                  --  calls to Disambiguate will take care of others in the
                  --  list of candidates.

                  if It1 /= No_Interp then
                     if It = Disambiguate.It1
                       or else It = Disambiguate.It2
                     then
                        if It1 = Disambiguate.It1
                          or else It1 = Disambiguate.It2
                        then
                           return No_Interp;
                        else
                           It1 := It;
                        end if;
                     end if;

                  elsif Present (Act2)
                    and then Nkind (Act2) in N_Op
                    and then Is_Overloaded (Act2)
                    and then Nkind (Right_Opnd (Act2)) in
                               N_Integer_Literal | N_Real_Literal
                    and then Has_Compatible_Type (Act2, Standard_Boolean)
                  then
                     --  The preference rule on the first actual is not
                     --  sufficient to disambiguate.

                     goto Next_Interp;

                  else
                     It1 := It;
                  end if;

               elsif Is_Numeric_Type (Etype (F1))
                 and then Has_Abstract_Interpretation (Act1)
               then
                  --  Current interpretation is not the right one because it
                  --  expects a numeric operand. Examine all the other ones.

                  declare
                     I  : Interp_Index;
                     It : Interp;

                  begin
                     Get_First_Interp (N, I, It);
                     while Present (It.Typ) loop
                        if
                          not Is_Numeric_Type (Etype (First_Formal (It.Nam)))
                        then
                           if No (Act2)
                             or else not Has_Abstract_Interpretation (Act2)
                             or else not
                               Is_Numeric_Type
                                 (Etype (Next_Formal (First_Formal (It.Nam))))
                           then
                              return It;
                           end if;
                        end if;

                        Get_Next_Interp (I, It);
                     end loop;

                     return No_Interp;
                  end;
               end if;
            end if;

            <<Next_Interp>>
               Get_Next_Interp (I, It);
         end loop;

         --  After some error, a formal may have Any_Type and yield a spurious
         --  match. To avoid cascaded errors if possible, check for such a
         --  formal in either candidate.

         if Serious_Errors_Detected > 0 then
            declare
               Formal : Entity_Id;

            begin
               Formal := First_Formal (Nam1);
               while Present (Formal) loop
                  if Etype (Formal) = Any_Type then
                     return Disambiguate.It2;
                  end if;

                  Next_Formal (Formal);
               end loop;

               Formal := First_Formal (Nam2);
               while Present (Formal) loop
                  if Etype (Formal) = Any_Type then
                     return Disambiguate.It1;
                  end if;

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

         return It1;
      end Remove_Conversions;

      -----------------------
      -- Standard_Operator --
      -----------------------

      function Standard_Operator return Boolean is
         Nam : Node_Id;

      begin
         if Nkind (N) in N_Op then
            return True;

         elsif Nkind (N) = N_Function_Call then
            Nam := Name (N);

            if Nkind (Nam) /= N_Expanded_Name then
               return True;
            else
               return Entity (Prefix (Nam)) = Standard_Standard;
            end if;
         else
            return False;
         end if;
      end Standard_Operator;

      -----------------------------------------------
      -- Is_User_Defined_Anonymous_Access_Equality --
      -----------------------------------------------

      function Is_User_Defined_Anonymous_Access_Equality
        (User_Subp, Predef_Subp : Entity_Id) return Boolean is
      begin
         return Present (User_Subp)

         --  Check for Ada 2005 and use of anonymous access

           and then Ada_Version >= Ada_2005
           and then Etype (User_Subp) = Standard_Boolean
           and then Is_Anonymous_Access_Type (Operand_Type)

         --  This check is only relevant if User_Subp is visible and not in
         --  an instance

           and then (In_Open_Scopes (Scope (User_Subp))
                      or else Is_Potentially_Use_Visible (User_Subp))
           and then not In_Instance
           and then not Hides_Op (User_Subp, Predef_Subp)

         --  Is User_Subp declared in the same declarative list as the type?

           and then
             In_Same_Declaration_List
               (Designated_Type (Operand_Type),
                Unit_Declaration_Node (User_Subp));
      end Is_User_Defined_Anonymous_Access_Equality;

   --  Start of processing for Disambiguate

   begin
      --  Recover the two legal interpretations

      Get_First_Interp (N, I, It);
      while I /= I1 loop
         Get_Next_Interp (I, It);
      end loop;

      It1  := It;
      Nam1 := It.Nam;

      while I /= I2 loop
         Get_Next_Interp (I, It);
      end loop;

      It2  := It;
      Nam2 := It.Nam;

      --  Check whether one of the entities is an Ada 2005/2012/2022 and we
      --  are operating in an earlier mode, in which case we discard the Ada
      --  2005/2012/2022 entity, so that we get proper Ada 95 overload
      --  resolution.

      if Ada_Version < Ada_2005 then
         if Is_Ada_2005_Only (Nam1)
           or else Is_Ada_2012_Only (Nam1)
           or else Is_Ada_2022_Only (Nam1)
         then
            return It2;

         elsif Is_Ada_2005_Only (Nam2)
           or else Is_Ada_2012_Only (Nam2)
           or else Is_Ada_2022_Only (Nam2)
         then
            return It1;
         end if;

      --  Check whether one of the entities is an Ada 2012/2022 entity and we
      --  are operating in Ada 2005 mode, in which case we discard the Ada 2012
      --  Ada 2022 entity, so that we get proper Ada 2005 overload resolution.

      elsif Ada_Version = Ada_2005 then
         if Is_Ada_2012_Only (Nam1) or else Is_Ada_2022_Only (Nam1) then
            return It2;
         elsif Is_Ada_2012_Only (Nam2) or else Is_Ada_2022_Only (Nam2) then
            return It1;
         end if;

      --  Ditto for Ada 2012 vs Ada 2022.

      elsif Ada_Version = Ada_2012 then
         if Is_Ada_2022_Only (Nam1) then
            return It2;
         elsif Is_Ada_2022_Only (Nam2) then
            return It1;
         end if;
      end if;

      --  If the context is universal, the predefined operator is preferred.
      --  This includes bounds in numeric type declarations, and expressions
      --  in type conversions. If no interpretation yields a universal type,
      --  then we must check whether the user-defined entity hides the prede-
      --  fined one.

      if Chars (Nam1) in Any_Operator_Name and then Standard_Operator then
         if        Typ = Universal_Integer
           or else Typ = Universal_Real
           or else Typ = Any_Integer
           or else Typ = Any_Discrete
           or else Typ = Any_Real
           or else Typ = Any_Type
         then
            --  Find an interpretation that yields the universal type, or else
            --  a predefined operator that yields a predefined numeric type.

            declare
               Candidate : Interp := No_Interp;

            begin
               Get_First_Interp (N, I, It);
               while Present (It.Typ) loop
                  if Is_Universal_Numeric_Type (It.Typ)
                    and then (Typ = Any_Type or else Covers (Typ, It.Typ))
                  then
                     return It;

                  elsif Is_Numeric_Type (It.Typ)
                    and then Scope (It.Typ) = Standard_Standard
                    and then Scope (It.Nam) = Standard_Standard
                    and then Covers (Typ, It.Typ)
                  then
                     Candidate := It;
                  end if;

                  Get_Next_Interp (I, It);
               end loop;

               if Candidate /= No_Interp then
                  return Candidate;
               end if;
            end;

         elsif Chars (Nam1) /= Name_Op_Not
           and then (Typ = Standard_Boolean or else Typ = Any_Boolean)
         then
            --  Equality or comparison operation. Choose predefined operator if
            --  arguments are universal. The node may be an operator, name, or
            --  a function call, so unpack arguments accordingly.

            declare
               Arg1, Arg2 : Node_Id;

            begin
               if Nkind (N) in N_Op then
                  Arg1 := Left_Opnd  (N);
                  Arg2 := Right_Opnd (N);

               elsif Is_Entity_Name (N) then
                  Arg1 := First_Entity (Entity (N));
                  Arg2 := Next_Entity (Arg1);

               else
                  Arg1 := First_Actual (N);
                  Arg2 := Next_Actual (Arg1);
               end if;

               if Present (Arg2) then
                  if Ekind (Nam1) = E_Operator then
                     Predef_Subp := Nam1;
                     User_Subp   := Nam2;
                  elsif Ekind (Nam2) = E_Operator then
                     Predef_Subp := Nam2;
                     User_Subp   := Nam1;
                  else
                     Predef_Subp := Empty;
                     User_Subp   := Empty;
                  end if;

                  --  Take into account universal interpretation as well as
                  --  universal_access equality, as long as AI05-0020 does not
                  --  trigger.

                  if (Present (Universal_Interpretation (Arg1))
                       and then Universal_Interpretation (Arg2) =
                                Universal_Interpretation (Arg1))
                    or else
                      (Nkind (N) in N_Op_Eq | N_Op_Ne
                        and then (Is_Anonymous_Access_Type (Etype (Arg1))
                                    or else
                                  Is_Anonymous_Access_Type (Etype (Arg2)))
                        and then not
                          Is_User_Defined_Anonymous_Access_Equality
                            (User_Subp, Predef_Subp))
                  then
                     Get_First_Interp (N, I, It);
                     while Scope (It.Nam) /= Standard_Standard loop
                        Get_Next_Interp (I, It);
                     end loop;

                     return It;
                  end if;
               end if;
            end;
         end if;
      end if;

      --  If no universal interpretation, check whether user-defined operator
      --  hides predefined one, as well as other special cases. If the node
      --  is a range, then one or both bounds are ambiguous. Each will have
      --  to be disambiguated w.r.t. the context type. The type of the range
      --  itself is imposed by the context, so we can return either legal
      --  interpretation.

      if Ekind (Nam1) = E_Operator then
         Predef_Subp := Nam1;
         User_Subp   := Nam2;

      elsif Ekind (Nam2) = E_Operator then
         Predef_Subp := Nam2;
         User_Subp   := Nam1;

      elsif Nkind (N) = N_Range then
         return It1;

      --  Implement AI05-105: A renaming declaration with an access
      --  definition must resolve to an anonymous access type. This
      --  is a resolution rule and can be used to disambiguate.

      elsif Nkind (Parent (N)) = N_Object_Renaming_Declaration
        and then Present (Access_Definition (Parent (N)))
      then
         if Is_Anonymous_Access_Type (It1.Typ) then
            if Ekind (It2.Typ) = Ekind (It1.Typ) then

               --  True ambiguity

               return No_Interp;

            else
               return It1;
            end if;

         elsif Is_Anonymous_Access_Type (It2.Typ) then
            return It2;

         --  No legal interpretation

         else
            return No_Interp;
         end if;

      --  Two access attribute types may have been created for an expression
      --  with an implicit dereference, which is automatically overloaded.
      --  If both access attribute types designate the same object type,
      --  disambiguation if any will take place elsewhere, so keep any one of
      --  the interpretations.

      elsif Ekind (It1.Typ) = E_Access_Attribute_Type
        and then Ekind (It2.Typ) = E_Access_Attribute_Type
        and then Designated_Type (It1.Typ) = Designated_Type (It2.Typ)
      then
         return It1;

      --  If two user defined-subprograms are visible, it is a true ambiguity,
      --  unless one of them is an entry and the context is a conditional or
      --  timed entry call, or unless we are within an instance and this is
      --  results from two formals types with the same actual.

      else
         if Nkind (N) = N_Procedure_Call_Statement
           and then Nkind (Parent (N)) = N_Entry_Call_Alternative
           and then N = Entry_Call_Statement (Parent (N))
         then
            if Ekind (Nam2) = E_Entry then
               return It2;
            elsif Ekind (Nam1) = E_Entry then
               return It1;
            else
               return No_Interp;
            end if;

         --  If the ambiguity occurs within an instance, it is due to several
         --  formal types with the same actual. Look for an exact match between
         --  the types of the formals of the overloadable entities, and the
         --  actuals in the call, to recover the unambiguous match in the
         --  original generic.

         --  The ambiguity can also be due to an overloading between a formal
         --  subprogram and a subprogram declared outside the generic. If the
         --  node is overloaded, it did not resolve to the global entity in
         --  the generic, and we choose the formal subprogram.

         --  Finally, the ambiguity can be between an explicit subprogram and
         --  one inherited (with different defaults) from an actual. In this
         --  case the resolution was to the explicit declaration in the
         --  generic, and remains so in the instance.

         --  The same sort of disambiguation needed for calls is also required
         --  for the name given in a subprogram renaming, and that case is
         --  handled here as well. We test Comes_From_Source to exclude this
         --  treatment for implicit renamings created for formal subprograms.

         elsif In_Instance and then not In_Generic_Actual (N) then
            if Nkind (N) in N_Subprogram_Call
              or else
                (Nkind (N) in N_Has_Entity
                  and then
                    Nkind (Parent (N)) = N_Subprogram_Renaming_Declaration
                  and then Comes_From_Source (Parent (N)))
            then
               declare
                  Actual  : Node_Id;
                  Formal  : Entity_Id;
                  Renam   : Entity_Id        := Empty;
                  Is_Act1 : constant Boolean := Is_Actual_Subprogram (Nam1);
                  Is_Act2 : constant Boolean := Is_Actual_Subprogram (Nam2);

               begin
                  if Is_Act1 and then not Is_Act2 then
                     return It1;

                  elsif Is_Act2 and then not Is_Act1 then
                     return It2;

                  elsif Inherited_From_Actual (Nam1)
                    and then Comes_From_Source (Nam2)
                  then
                     return It2;

                  elsif Inherited_From_Actual (Nam2)
                    and then Comes_From_Source (Nam1)
                  then
                     return It1;
                  end if;

                  --  In the case of a renamed subprogram, pick up the entity
                  --  of the renaming declaration so we can traverse its
                  --  formal parameters.

                  if Nkind (N) in N_Has_Entity then
                     Renam := Defining_Unit_Name (Specification (Parent (N)));
                  end if;

                  if Present (Renam) then
                     Actual := First_Formal (Renam);
                  else
                     Actual := First_Actual (N);
                  end if;

                  Formal := First_Formal (Nam1);
                  while Present (Actual) loop
                     if Etype (Actual) /= Etype (Formal) then
                        return It2;
                     end if;

                     if Present (Renam) then
                        Next_Formal (Actual);
                     else
                        Next_Actual (Actual);
                     end if;

                     Next_Formal (Formal);
                  end loop;

                  return It1;
               end;

            elsif Nkind (N) in N_Binary_Op then
               if Matches (N, Nam1) then
                  return It1;
               else
                  return It2;
               end if;

            elsif Nkind (N) in N_Unary_Op then
               if Etype (Right_Opnd (N)) = Etype (First_Formal (Nam1)) then
                  return It1;
               else
                  return It2;
               end if;

            else
               return Remove_Conversions;
            end if;
         else
            return Remove_Conversions;
         end if;
      end if;

      --  An implicit concatenation operator on a string type cannot be
      --  disambiguated from the predefined concatenation. This can only
      --  happen with concatenation of string literals.

      if Chars (User_Subp) = Name_Op_Concat
        and then Ekind (User_Subp) = E_Operator
        and then Is_String_Type (Etype (First_Formal (User_Subp)))
      then
         return No_Interp;

      --  If the user-defined operator is in an open scope, or in the scope
      --  of the resulting type, or given by an expanded name that names its
      --  scope, it hides the predefined operator for the type. Exponentiation
      --  has to be special-cased because the implicit operator does not have
      --  a symmetric signature, and may not be hidden by the explicit one.

      elsif (Nkind (N) = N_Function_Call
              and then Nkind (Name (N)) = N_Expanded_Name
              and then (Chars (Predef_Subp) /= Name_Op_Expon
                         or else Hides_Op (User_Subp, Predef_Subp))
              and then Scope (User_Subp) = Entity (Prefix (Name (N))))
        or else Hides_Op (User_Subp, Predef_Subp)
      then
         if It1.Nam = User_Subp then
            return It1;
         else
            return It2;
         end if;

      --  Otherwise, the predefined operator has precedence, or if the user-
      --  defined operation is directly visible we have a true ambiguity.

      --  If this is a fixed-point multiplication and division in Ada 83 mode,
      --  exclude the universal_fixed operator, which often causes ambiguities
      --  in legacy code.

      --  Ditto in Ada 2012, where an ambiguity may arise for an operation
      --  on a partial view that is completed with a fixed point type. See
      --  AI05-0020 and AI05-0209. The ambiguity is resolved in favor of the
      --  user-defined type and subprogram, so that a client of the package
      --  has the same resolution as the body of the package.

      else
         if (In_Open_Scopes (Scope (User_Subp))
              or else Is_Potentially_Use_Visible (User_Subp))
           and then not In_Instance
         then
            if Is_Fixed_Point_Type (Typ)
              and then Chars (Nam1) in Name_Op_Multiply | Name_Op_Divide
              and then
                (Ada_Version = Ada_83
                  or else (Ada_Version >= Ada_2012
                            and then In_Same_Declaration_List
                                       (First_Subtype (Typ),
                                          Unit_Declaration_Node (User_Subp))))
            then
               if It2.Nam = Predef_Subp then
                  return It1;
               else
                  return It2;
               end if;

            --  Check for AI05-020

            elsif Chars (Nam1) in Name_Op_Eq | Name_Op_Ne
              and then Is_User_Defined_Anonymous_Access_Equality
                         (User_Subp, Predef_Subp)
            then
               if It2.Nam = Predef_Subp then
                  return It1;
               else
                  return It2;
               end if;

            --  An immediately visible operator hides a use-visible user-
            --  defined operation. This disambiguation cannot take place
            --  earlier because the visibility of the predefined operator
            --  can only be established when operand types are known.

            elsif Ekind (User_Subp) = E_Function
              and then Ekind (Predef_Subp) = E_Operator
              and then Nkind (N) in N_Op
              and then not Is_Overloaded (Right_Opnd (N))
              and then
                Is_Immediately_Visible (Base_Type (Etype (Right_Opnd (N))))
              and then Is_Potentially_Use_Visible (User_Subp)
            then
               if It2.Nam = Predef_Subp then
                  return It1;
               else
                  return It2;
               end if;

            else
               return No_Interp;
            end if;

         elsif It1.Nam = Predef_Subp then
            return It1;

         else
            return It2;
         end if;
      end if;
   end Disambiguate;

   -------------------------
   -- Entity_Matches_Spec --
   -------------------------

   function Entity_Matches_Spec (Old_S, New_S : Entity_Id) return Boolean is
   begin
      --  Simple case: same entity kinds, type conformance is required. A
      --  parameterless function can also rename a literal.

      if Ekind (Old_S) = Ekind (New_S)
        or else (Ekind (New_S) = E_Function
                  and then Ekind (Old_S) = E_Enumeration_Literal)
      then
         return Type_Conformant (New_S, Old_S);

      elsif Ekind (New_S) = E_Function and then Ekind (Old_S) = E_Operator then
         return Operator_Matches_Spec (Old_S, New_S);

      elsif Ekind (New_S) = E_Procedure and then Is_Entry (Old_S) then
         return Type_Conformant (New_S, Old_S);

      else
         return False;
      end if;
   end Entity_Matches_Spec;

   ----------------------
   -- Find_Unique_Type --
   ----------------------

   function Find_Unique_Type (L : Node_Id; R : Node_Id) return Entity_Id is
      T  : constant Entity_Id := Etype (L);
      I  : Interp_Index;
      It : Interp;
      TR : Entity_Id := Any_Type;

   begin
      if Is_Overloaded (R) then
         Get_First_Interp (R, I, It);
         while Present (It.Typ) loop
            if Covers (T, It.Typ) or else Covers (It.Typ, T) then

               --  If several interpretations are possible and L is universal,
               --  apply preference rule.

               if TR /= Any_Type then
                  if Is_Universal_Numeric_Type (T)
                    and then It.Typ = T
                  then
                     TR := It.Typ;
                  end if;

               else
                  TR := It.Typ;
               end if;
            end if;

            Get_Next_Interp (I, It);
         end loop;

         Set_Etype (R, TR);

      --  In the non-overloaded case, the Etype of R is already set correctly

      else
         null;
      end if;

      --  If one of the operands is Universal_Fixed, the type of the other
      --  operand provides the context.

      if Etype (R) = Universal_Fixed then
         return T;

      elsif T = Universal_Fixed then
         return Etype (R);

      --  If one operand is a raise_expression, use type of other operand

      elsif Nkind (L) = N_Raise_Expression then
         return Etype (R);

      else
         return Specific_Type (T, Etype (R));
      end if;
   end Find_Unique_Type;

   -------------------------------------
   -- Function_Interp_Has_Abstract_Op --
   -------------------------------------

   function Function_Interp_Has_Abstract_Op
     (N : Node_Id;
      E : Entity_Id) return Entity_Id
   is
      Abstr_Op  : Entity_Id;
      Act       : Node_Id;
      Act_Parm  : Node_Id;
      Form_Parm : Node_Id;

   begin
      --  Why is check on E needed below ???
      --  In any case this para needs comments ???

      if Is_Overloaded (N) and then Is_Overloadable (E) then
         Act_Parm  := First_Actual (N);
         Form_Parm := First_Formal (E);
         while Present (Act_Parm) and then Present (Form_Parm) loop
            Act := Act_Parm;

            if Nkind (Act) = N_Parameter_Association then
               Act := Explicit_Actual_Parameter (Act);
            end if;

            Abstr_Op := Has_Abstract_Op (Act, Etype (Form_Parm));

            if Present (Abstr_Op) then
               return Abstr_Op;
            end if;

            Next_Actual (Act_Parm);
            Next_Formal (Form_Parm);
         end loop;
      end if;

      return Empty;
   end Function_Interp_Has_Abstract_Op;

   ----------------------
   -- Get_First_Interp --
   ----------------------

   procedure Get_First_Interp
     (N  : Node_Id;
      I  : out Interp_Index;
      It : out Interp)
   is
      Int_Ind : Interp_Index;
      O_N     : Node_Id;

   begin
      --  If a selected component is overloaded because the selector has
      --  multiple interpretations, the node is a call to a protected
      --  operation or an indirect call. Retrieve the interpretation from
      --  the selector name. The selected component may be overloaded as well
      --  if the prefix is overloaded. That case is unchanged.

      if Nkind (N) = N_Selected_Component
        and then Is_Overloaded (Selector_Name (N))
      then
         O_N := Selector_Name (N);
      else
         O_N := N;
      end if;

      Int_Ind := Interp_Map.Get (O_N);

      --  Procedure should never be called if the node has no interpretations

      if Int_Ind < 0 then
         raise Program_Error;
      end if;

      I  := Int_Ind;
      It := All_Interp.Table (Int_Ind);
   end Get_First_Interp;

   ---------------------
   -- Get_Next_Interp --
   ---------------------

   procedure Get_Next_Interp (I : in out Interp_Index; It : out Interp) is
   begin
      I  := I + 1;
      It := All_Interp.Table (I);
   end Get_Next_Interp;

   -------------------------
   -- Has_Compatible_Type --
   -------------------------

   function Has_Compatible_Type
     (N   : Node_Id;
      Typ : Entity_Id) return Boolean
   is
      I  : Interp_Index;
      It : Interp;

   begin
      if N = Error then
         return False;
      end if;

      if Nkind (N) = N_Subtype_Indication
        or else not Is_Overloaded (N)
      then
         return
           Covers (Typ, Etype (N))

            --  Ada 2005 (AI-345): The context may be a synchronized interface.
            --  If the type is already frozen use the corresponding_record
            --  to check whether it is a proper descendant.

           or else
             (Is_Record_Type (Typ)
               and then Is_Concurrent_Type (Etype (N))
               and then Present (Corresponding_Record_Type (Etype (N)))
               and then Covers (Typ, Corresponding_Record_Type (Etype (N))))

           or else
             (Is_Concurrent_Type (Typ)
               and then Is_Record_Type (Etype (N))
               and then Present (Corresponding_Record_Type (Typ))
               and then Covers (Corresponding_Record_Type (Typ), Etype (N)))

           or else
             (not Is_Tagged_Type (Typ)
               and then Ekind (Typ) /= E_Anonymous_Access_Type
               and then Covers (Etype (N), Typ))

           or else
             (Nkind (N) = N_Integer_Literal
               and then Present (Find_Aspect (Typ, Aspect_Integer_Literal)))

           or else
             (Nkind (N) = N_Real_Literal
               and then Present (Find_Aspect (Typ, Aspect_Real_Literal)))

           or else
             (Nkind (N) = N_String_Literal
               and then Present (Find_Aspect (Typ, Aspect_String_Literal)));

      --  Overloaded case

      else
         Get_First_Interp (N, I, It);
         while Present (It.Typ) loop
            if (Covers (Typ, It.Typ)
                 and then
                   (Scope (It.Nam) /= Standard_Standard
                     or else not Is_Invisible_Operator (N, Base_Type (Typ))))

               --  Ada 2005 (AI-345)

              or else
                (Is_Concurrent_Type (It.Typ)
                  and then Present (Corresponding_Record_Type
                                                             (Etype (It.Typ)))
                  and then Covers (Typ, Corresponding_Record_Type
                                                             (Etype (It.Typ))))

              or else (not Is_Tagged_Type (Typ)
                         and then Ekind (Typ) /= E_Anonymous_Access_Type
                         and then Covers (It.Typ, Typ))
            then
               return True;
            end if;

            Get_Next_Interp (I, It);
         end loop;

         return False;
      end if;
   end Has_Compatible_Type;

   ---------------------
   -- Has_Abstract_Op --
   ---------------------

   function Has_Abstract_Op
     (N   : Node_Id;
      Typ : Entity_Id) return Entity_Id
   is
      I  : Interp_Index;
      It : Interp;

   begin
      if Is_Overloaded (N) then
         Get_First_Interp (N, I, It);
         while Present (It.Nam) loop
            if Present (It.Abstract_Op)
              and then Etype (It.Abstract_Op) = Typ
            then
               return It.Abstract_Op;
            end if;

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

      return Empty;
   end Has_Abstract_Op;

   ----------
   -- Hash --
   ----------

   function Hash (N : Node_Id) return Header_Num is
   begin
      return Header_Num (N mod Header_Max);
   end Hash;

   --------------
   -- Hides_Op --
   --------------

   function Hides_Op (F : Entity_Id; Op : Entity_Id) return Boolean is
      Btyp : constant Entity_Id := Base_Type (Etype (First_Formal (F)));
   begin
      return Operator_Matches_Spec (Op, F)
        and then (In_Open_Scopes (Scope (F))
                   or else Scope (F) = Scope (Btyp)
                   or else (not In_Open_Scopes (Scope (Btyp))
                             and then not In_Use (Btyp)
                             and then not In_Use (Scope (Btyp))));
   end Hides_Op;

   ------------------------
   -- Init_Interp_Tables --
   ------------------------

   procedure Init_Interp_Tables is
   begin
      All_Interp.Init;
      Interp_Map.Reset;
   end Init_Interp_Tables;

   -----------------------------------
   -- Interface_Present_In_Ancestor --
   -----------------------------------

   function Interface_Present_In_Ancestor
     (Typ   : Entity_Id;
      Iface : Entity_Id) return Boolean
   is
      Target_Typ : Entity_Id;
      Iface_Typ  : Entity_Id;

      function Iface_Present_In_Ancestor (Typ : Entity_Id) return Boolean;
      --  Returns True if Typ or some ancestor of Typ implements Iface

      -------------------------------
      -- Iface_Present_In_Ancestor --
      -------------------------------

      function Iface_Present_In_Ancestor (Typ : Entity_Id) return Boolean is
         E    : Entity_Id;
         AI   : Entity_Id;
         Elmt : Elmt_Id;

      begin
         if Typ = Iface_Typ then
            return True;
         end if;

         --  Handle private types

         if Present (Full_View (Typ))
           and then not Is_Concurrent_Type (Full_View (Typ))
         then
            E := Full_View (Typ);
         else
            E := Typ;
         end if;

         loop
            if Present (Interfaces (E))
              and then not Is_Empty_Elmt_List (Interfaces (E))
            then
               Elmt := First_Elmt (Interfaces (E));
               while Present (Elmt) loop
                  AI := Node (Elmt);

                  if AI = Iface_Typ or else Is_Ancestor (Iface_Typ, AI) then
                     return True;
                  end if;

                  Next_Elmt (Elmt);
               end loop;
            end if;

            exit when Etype (E) = E

               --  Handle private types

               or else (Present (Full_View (Etype (E)))
                         and then Full_View (Etype (E)) = E);

            --  Check if the current type is a direct derivation of the
            --  interface

            if Etype (E) = Iface_Typ then
               return True;
            end if;

            --  Climb to the immediate ancestor handling private types

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

         return False;
      end Iface_Present_In_Ancestor;

   --  Start of processing for Interface_Present_In_Ancestor

   begin
      --  Iface might be a class-wide subtype, so we have to apply Base_Type

      if Is_Class_Wide_Type (Iface) then
         Iface_Typ := Etype (Base_Type (Iface));
      else
         Iface_Typ := Iface;
      end if;

      --  Handle subtypes

      Iface_Typ := Base_Type (Iface_Typ);

      if Is_Access_Type (Typ) then
         Target_Typ := Etype (Directly_Designated_Type (Typ));
      else
         Target_Typ := Typ;
      end if;

      if Is_Concurrent_Record_Type (Target_Typ) then
         Target_Typ := Corresponding_Concurrent_Type (Target_Typ);
      end if;

      Target_Typ := Base_Type (Target_Typ);

      --  In case of concurrent types we can't use the Corresponding Record_Typ
      --  to look for the interface because it is built by the expander (and
      --  hence it is not always available). For this reason we traverse the
      --  list of interfaces (available in the parent of the concurrent type)

      if Is_Concurrent_Type (Target_Typ) then
         if Present (Interface_List (Parent (Target_Typ))) then
            declare
               AI : Node_Id;

            begin
               AI := First (Interface_List (Parent (Target_Typ)));

               --  The progenitor itself may be a subtype of an interface type.

               while Present (AI) loop
                  if Etype (AI) = Iface_Typ
                    or else Base_Type (Etype (AI)) = Iface_Typ
                  then
                     return True;

                  elsif Present (Interfaces (Etype (AI)))
                    and then Iface_Present_In_Ancestor (Etype (AI))
                  then
                     return True;
                  end if;

                  Next (AI);
               end loop;
            end;
         end if;

         return False;
      end if;

      if Is_Class_Wide_Type (Target_Typ) then
         Target_Typ := Etype (Target_Typ);
      end if;

      if Ekind (Target_Typ) = E_Incomplete_Type then

         --  We must have either a full view or a nonlimited view of the type
         --  to locate the list of ancestors.

         if Present (Full_View (Target_Typ)) then
            Target_Typ := Full_View (Target_Typ);
         else
            --  In a spec expression or in an expression function, the use of
            --  an incomplete type is legal; legality of the conversion will be
            --  checked at freeze point of related entity.

            if In_Spec_Expression then
               return True;

            else
               pragma Assert (Present (Non_Limited_View (Target_Typ)));
               Target_Typ := Non_Limited_View (Target_Typ);
            end if;
         end if;

         --  Protect the front end against previously detected errors

         if Ekind (Target_Typ) = E_Incomplete_Type then
            return False;
         end if;
      end if;

      return Iface_Present_In_Ancestor (Target_Typ);
   end Interface_Present_In_Ancestor;

   ---------------------
   -- Intersect_Types --
   ---------------------

   function Intersect_Types (L, R : Node_Id) return Entity_Id is
      Index : Interp_Index;
      It    : Interp;
      Typ   : Entity_Id;

      function Check_Right_Argument (T : Entity_Id) return Entity_Id;
      --  Find interpretation of right arg that has type compatible with T

      --------------------------
      -- Check_Right_Argument --
      --------------------------

      function Check_Right_Argument (T : Entity_Id) return Entity_Id is
         Index : Interp_Index;
         It    : Interp;
         T2    : Entity_Id;

      begin
         if not Is_Overloaded (R) then
            return Specific_Type (T, Etype (R));

         else
            Get_First_Interp (R, Index, It);
            loop
               T2 := Specific_Type (T, It.Typ);

               if T2 /= Any_Type then
                  return T2;
               end if;

               Get_Next_Interp (Index, It);
               exit when No (It.Typ);
            end loop;

            return Any_Type;
         end if;
      end Check_Right_Argument;

   --  Start of processing for Intersect_Types

   begin
      if Etype (L) = Any_Type or else Etype (R) = Any_Type then
         return Any_Type;
      end if;

      if not Is_Overloaded (L) then
         Typ := Check_Right_Argument (Etype (L));

      else
         Typ := Any_Type;
         Get_First_Interp (L, Index, It);
         while Present (It.Typ) loop
            Typ := Check_Right_Argument (It.Typ);
            exit when Typ /= Any_Type;
            Get_Next_Interp (Index, It);
         end loop;

      end if;

      --  If Typ is Any_Type, it means no compatible pair of types was found

      if Typ = Any_Type then
         if Nkind (Parent (L)) in N_Op then
            Error_Msg_N ("incompatible types for operator", Parent (L));

         elsif Nkind (Parent (L)) = N_Range then
            Error_Msg_N ("incompatible types given in constraint", Parent (L));

         --  Ada 2005 (AI-251): Complete the error notification

         elsif Is_Class_Wide_Type (Etype (R))
           and then Is_Interface (Etype (Class_Wide_Type (Etype (R))))
         then
            Error_Msg_NE ("(Ada 2005) does not implement interface }",
                          L, Etype (Class_Wide_Type (Etype (R))));

         --  Specialize message if one operand is a limited view, a priori
         --  unrelated to all other types.

         elsif From_Limited_With (Etype (R)) then
            Error_Msg_NE ("limited view of& not compatible with context",
                           R, Etype (R));

         elsif From_Limited_With (Etype (L)) then
            Error_Msg_NE ("limited view of& not compatible with context",
                           L, Etype (L));
         else
            Error_Msg_N ("incompatible types", Parent (L));
         end if;
      end if;

      return Typ;
   end Intersect_Types;

   -----------------------
   -- In_Generic_Actual --
   -----------------------

   function In_Generic_Actual (Exp : Node_Id) return Boolean is
      Par : constant Node_Id := Parent (Exp);

   begin
      if No (Par) then
         return False;

      elsif Nkind (Par) in N_Declaration then
         return
           Nkind (Par) = N_Object_Declaration
             and then Present (Corresponding_Generic_Association (Par));

      elsif Nkind (Par) = N_Object_Renaming_Declaration then
         return Present (Corresponding_Generic_Association (Par));

      elsif Nkind (Par) in N_Statement_Other_Than_Procedure_Call then
         return False;

      else
         return In_Generic_Actual (Par);
      end if;
   end In_Generic_Actual;

   -----------------
   -- Is_Ancestor --
   -----------------

   function Is_Ancestor
     (T1            : Entity_Id;
      T2            : Entity_Id;
      Use_Full_View : Boolean := False) return Boolean
   is
      BT1 : Entity_Id;
      BT2 : Entity_Id;
      Par : Entity_Id;

   begin
      BT1 := Base_Type (T1);
      BT2 := Base_Type (T2);

      --  Handle underlying view of records with unknown discriminants using
      --  the original entity that motivated the construction of this
      --  underlying record view (see Build_Derived_Private_Type).

      if Is_Underlying_Record_View (BT1) then
         BT1 := Underlying_Record_View (BT1);
      end if;

      if Is_Underlying_Record_View (BT2) then
         BT2 := Underlying_Record_View (BT2);
      end if;

      if BT1 = BT2 then
         return True;

      --  The predicate must look past privacy

      elsif Is_Private_Type (T1)
        and then Present (Full_View (T1))
        and then BT2 = Base_Type (Full_View (T1))
      then
         return True;

      elsif Is_Private_Type (T2)
        and then Present (Full_View (T2))
        and then BT1 = Base_Type (Full_View (T2))
      then
         return True;

      else
         --  Obtain the parent of the base type of T2 (use the full view if
         --  allowed).

         if Use_Full_View
           and then Is_Private_Type (BT2)
           and then Present (Full_View (BT2))
         then
            --  No climbing needed if its full view is the root type

            if Full_View (BT2) = Root_Type (Full_View (BT2)) then
               return False;
            end if;

            Par := Etype (Full_View (BT2));

         else
            Par := Etype (BT2);
         end if;

         loop
            --  If there was a error on the type declaration, do not recurse

            if Error_Posted (Par) then
               return False;

            elsif BT1 = Base_Type (Par)
              or else (Is_Private_Type (T1)
                        and then Present (Full_View (T1))
                        and then Base_Type (Par) = Base_Type (Full_View (T1)))
            then
               return True;

            elsif Is_Private_Type (Par)
              and then Present (Full_View (Par))
              and then Full_View (Par) = BT1
            then
               return True;

            --  Root type found

            elsif Par = Root_Type (Par) then
               return False;

            --  Continue climbing

            else
               --  Use the full-view of private types (if allowed). Guard
               --  against infinite loops when full view has same type as
               --  parent, as can happen with interface extensions.

               if Use_Full_View
                 and then Is_Private_Type (Par)
                 and then Present (Full_View (Par))
                 and then Par /= Etype (Full_View (Par))
               then
                  Par := Etype (Full_View (Par));
               else
                  Par := Etype (Par);
               end if;
            end if;
         end loop;
      end if;
   end Is_Ancestor;

   ---------------------------
   -- Is_Invisible_Operator --
   ---------------------------

   function Is_Invisible_Operator
     (N : Node_Id;
      T : Entity_Id) return Boolean
   is
      Orig_Node : constant Node_Id := Original_Node (N);

   begin
      if Nkind (N) not in N_Op then
         return False;

      elsif not Comes_From_Source (N) then
         return False;

      elsif No (Universal_Interpretation (Right_Opnd (N))) then
         return False;

      elsif Nkind (N) in N_Binary_Op
        and then No (Universal_Interpretation (Left_Opnd (N)))
      then
         return False;

      else
         return Is_Numeric_Type (T)
           and then not In_Open_Scopes (Scope (T))
           and then not Is_Potentially_Use_Visible (T)
           and then not In_Use (T)
           and then not In_Use (Scope (T))
           and then
            (Nkind (Orig_Node) /= N_Function_Call
              or else Nkind (Name (Orig_Node)) /= N_Expanded_Name
              or else Entity (Prefix (Name (Orig_Node))) /= Scope (T))
           and then not In_Instance;
      end if;
   end Is_Invisible_Operator;

   --------------------
   --  Is_Progenitor --
   --------------------

   function Is_Progenitor
     (Iface : Entity_Id;
      Typ   : Entity_Id) return Boolean
   is
   begin
      return Implements_Interface (Typ, Iface, Exclude_Parents => True);
   end Is_Progenitor;

   -------------------
   -- Is_Subtype_Of --
   -------------------

   function Is_Subtype_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean is
      S : Entity_Id;

   begin
      S := Ancestor_Subtype (T1);
      while Present (S) loop
         if S = T2 then
            return True;
         else
            S := Ancestor_Subtype (S);
         end if;
      end loop;

      return False;
   end Is_Subtype_Of;

   ------------------
   -- List_Interps --
   ------------------

   procedure List_Interps (Nam : Node_Id; Err : Node_Id) is
      Index : Interp_Index;
      It    : Interp;

   begin
      Get_First_Interp (Nam, Index, It);
      while Present (It.Nam) loop
         if Scope (It.Nam) = Standard_Standard
           and then Scope (It.Typ) /= Standard_Standard
         then
            Error_Msg_Sloc := Sloc (Parent (It.Typ));
            Error_Msg_NE ("\\& (inherited) declared#!", Err, It.Nam);

         else
            Error_Msg_Sloc := Sloc (It.Nam);
            Error_Msg_NE ("\\& declared#!", Err, It.Nam);
         end if;

         Get_Next_Interp (Index, It);
      end loop;
   end List_Interps;

   -----------------
   -- New_Interps --
   -----------------

   procedure New_Interps (N : Node_Id) is
   begin
      All_Interp.Append (No_Interp);

      --  Add or rewrite the existing node
      Last_Overloaded := N;
      Interp_Map.Set (N, All_Interp.Last);
      Set_Is_Overloaded (N, True);
   end New_Interps;

   ---------------------------
   -- Operator_Matches_Spec --
   ---------------------------

   function Operator_Matches_Spec (Op, New_S : Entity_Id) return Boolean is
      New_First_F : constant Entity_Id := First_Formal (New_S);
      Op_Name     : constant Name_Id   := Chars (Op);
      T           : constant Entity_Id := Etype (New_S);
      New_F       : Entity_Id;
      Num         : Nat;
      Old_F       : Entity_Id;
      T1          : Entity_Id;
      T2          : Entity_Id;

   begin
      --  To verify that a predefined operator matches a given signature, do a
      --  case analysis of the operator classes. Function can have one or two
      --  formals and must have the proper result type.

      New_F := New_First_F;
      Old_F := First_Formal (Op);
      Num := 0;
      while Present (New_F) and then Present (Old_F) loop
         Num := Num + 1;
         Next_Formal (New_F);
         Next_Formal (Old_F);
      end loop;

      --  Definite mismatch if different number of parameters

      if Present (Old_F) or else Present (New_F) then
         return False;

      --  Unary operators

      elsif Num = 1 then
         T1 := Etype (New_First_F);

         if Op_Name in Name_Op_Subtract | Name_Op_Add | Name_Op_Abs then
            return Base_Type (T1) = Base_Type (T)
              and then Is_Numeric_Type (T);

         elsif Op_Name = Name_Op_Not then
            return Base_Type (T1) = Base_Type (T)
              and then Valid_Boolean_Arg (Base_Type (T));

         else
            return False;
         end if;

      --  Binary operators

      else
         T1 := Etype (New_First_F);
         T2 := Etype (Next_Formal (New_First_F));

         if Op_Name in Name_Op_And | Name_Op_Or | Name_Op_Xor then
            return Base_Type (T1) = Base_Type (T2)
              and then Base_Type (T1) = Base_Type (T)
              and then Valid_Boolean_Arg (Base_Type (T));

         elsif Op_Name in Name_Op_Eq | Name_Op_Ne then
            return Base_Type (T1) = Base_Type (T2)
              and then not Is_Limited_Type (T1)
              and then Is_Boolean_Type (T);

         elsif Op_Name in Name_Op_Lt | Name_Op_Le | Name_Op_Gt | Name_Op_Ge
         then
            return Base_Type (T1) = Base_Type (T2)
              and then Valid_Comparison_Arg (T1)
              and then Is_Boolean_Type (T);

         elsif Op_Name in Name_Op_Add | Name_Op_Subtract then
            return Base_Type (T1) = Base_Type (T2)
              and then Base_Type (T1) = Base_Type (T)
              and then Is_Numeric_Type (T);

         --  For division and multiplication, a user-defined function does not
         --  match the predefined universal_fixed operation, except in Ada 83.

         elsif Op_Name = Name_Op_Divide then
            return (Base_Type (T1) = Base_Type (T2)
              and then Base_Type (T1) = Base_Type (T)
              and then Is_Numeric_Type (T)
              and then (not Is_Fixed_Point_Type (T)
                         or else Ada_Version = Ada_83))

            --  Mixed_Mode operations on fixed-point types

              or else (Base_Type (T1) = Base_Type (T)
                        and then Base_Type (T2) = Base_Type (Standard_Integer)
                        and then Is_Fixed_Point_Type (T))

            --  A user defined operator can also match (and hide) a mixed
            --  operation on universal literals.

              or else (Is_Integer_Type (T2)
                        and then Is_Floating_Point_Type (T1)
                        and then Base_Type (T1) = Base_Type (T));

         elsif Op_Name = Name_Op_Multiply then
            return (Base_Type (T1) = Base_Type (T2)
              and then Base_Type (T1) = Base_Type (T)
              and then Is_Numeric_Type (T)
              and then (not Is_Fixed_Point_Type (T)
                         or else Ada_Version = Ada_83))

            --  Mixed_Mode operations on fixed-point types

              or else (Base_Type (T1) = Base_Type (T)
                        and then Base_Type (T2) = Base_Type (Standard_Integer)
                        and then Is_Fixed_Point_Type (T))

              or else (Base_Type (T2) = Base_Type (T)
                        and then Base_Type (T1) = Base_Type (Standard_Integer)
                        and then Is_Fixed_Point_Type (T))

              or else (Is_Integer_Type (T2)
                        and then Is_Floating_Point_Type (T1)
                        and then Base_Type (T1) = Base_Type (T))

              or else (Is_Integer_Type (T1)
                        and then Is_Floating_Point_Type (T2)
                        and then Base_Type (T2) = Base_Type (T));

         elsif Op_Name in Name_Op_Mod | Name_Op_Rem then
            return Base_Type (T1) = Base_Type (T2)
              and then Base_Type (T1) = Base_Type (T)
              and then Is_Integer_Type (T);

         elsif Op_Name = Name_Op_Expon then
            return Base_Type (T1) = Base_Type (T)
              and then Is_Numeric_Type (T)
              and then Base_Type (T2) = Base_Type (Standard_Integer);

         elsif Op_Name = Name_Op_Concat then
            return Is_Array_Type (T)
              and then (Base_Type (T) = Base_Type (Etype (Op)))
              and then (Base_Type (T1) = Base_Type (T)
                          or else
                        Base_Type (T1) = Base_Type (Component_Type (T)))
              and then (Base_Type (T2) = Base_Type (T)
                          or else
                        Base_Type (T2) = Base_Type (Component_Type (T)));

         else
            return False;
         end if;
      end if;
   end Operator_Matches_Spec;

   -------------------
   -- Remove_Interp --
   -------------------

   procedure Remove_Interp (I : in out Interp_Index) is
      II : Interp_Index;

   begin
      --  Find end of interp list and copy downward to erase the discarded one

      II := I + 1;
      while Present (All_Interp.Table (II).Typ) loop
         II := II + 1;
      end loop;

      for J in I + 1 .. II loop
         All_Interp.Table (J - 1) := All_Interp.Table (J);
      end loop;

      --  Back up interp index to insure that iterator will pick up next
      --  available interpretation.

      I := I - 1;
   end Remove_Interp;

   ------------------
   -- Save_Interps --
   ------------------

   procedure Save_Interps (Old_N : Node_Id; New_N : Node_Id) is
      Old_Ind : Interp_Index;
      O_N     : Node_Id;

   begin
      if Is_Overloaded (Old_N) then
         Set_Is_Overloaded (New_N);

         if Nkind (Old_N) = N_Selected_Component
           and then Is_Overloaded (Selector_Name (Old_N))
         then
            O_N := Selector_Name (Old_N);
         else
            O_N := Old_N;
         end if;

         Old_Ind := Interp_Map.Get (O_N);
         pragma Assert (Old_Ind >= 0);

         New_Interps (New_N);
         Interp_Map.Set (New_N, Old_Ind);
      end if;
   end Save_Interps;

   -------------------
   -- Specific_Type --
   -------------------

   function Specific_Type (Typ_1, Typ_2 : Entity_Id) return Entity_Id is
      T1 : constant Entity_Id := Available_View (Typ_1);
      T2 : constant Entity_Id := Available_View (Typ_2);
      B1 : constant Entity_Id := Base_Type (T1);
      B2 : constant Entity_Id := Base_Type (T2);

      function Is_Remote_Access (T : Entity_Id) return Boolean;
      --  Check whether T is the equivalent type of a remote access type.
      --  If distribution is enabled, T is a legal context for Null.

      ----------------------
      -- Is_Remote_Access --
      ----------------------

      function Is_Remote_Access (T : Entity_Id) return Boolean is
      begin
         return Is_Record_Type (T)
           and then (Is_Remote_Call_Interface (T)
                      or else Is_Remote_Types (T))
           and then Present (Corresponding_Remote_Type (T))
           and then Is_Access_Type (Corresponding_Remote_Type (T));
      end Is_Remote_Access;

   --  Start of processing for Specific_Type

   begin
      if T1 = Any_Type or else T2 = Any_Type then
         return Any_Type;
      end if;

      if B1 = B2 then
         return B1;

      elsif     (T1 = Universal_Integer and then Is_Integer_Type (T2))
        or else (T1 = Universal_Real    and then Is_Real_Type (T2))
        or else (T1 = Universal_Fixed   and then Is_Fixed_Point_Type (T2))
        or else (T1 = Any_Fixed         and then Is_Fixed_Point_Type (T2))
      then
         return B2;

      elsif     (T2 = Universal_Integer and then Is_Integer_Type (T1))
        or else (T2 = Universal_Real    and then Is_Real_Type (T1))
        or else (T2 = Universal_Fixed   and then Is_Fixed_Point_Type (T1))
        or else (T2 = Any_Fixed         and then Is_Fixed_Point_Type (T1))
      then
         return B1;

      elsif T2 = Any_String and then Is_String_Type (T1) then
         return B1;

      elsif T1 = Any_String and then Is_String_Type (T2) then
         return B2;

      elsif T2 = Any_Character and then Is_Character_Type (T1) then
         return B1;

      elsif T1 = Any_Character and then Is_Character_Type (T2) then
         return B2;

      elsif T1 = Any_Access
        and then (Is_Access_Type (T2) or else Is_Remote_Access (T2))
      then
         return T2;

      elsif T2 = Any_Access
        and then (Is_Access_Type (T1) or else Is_Remote_Access (T1))
      then
         return T1;

      --  In an instance, the specific type may have a private view. Use full
      --  view to check legality.

      elsif T2 = Any_Access
        and then Is_Private_Type (T1)
        and then Present (Full_View (T1))
        and then Is_Access_Type (Full_View (T1))
        and then In_Instance
      then
         return T1;

      elsif T2 = Any_Composite and then Is_Aggregate_Type (T1) then
         return T1;

      elsif T1 = Any_Composite and then Is_Aggregate_Type (T2) then
         return T2;

      elsif T1 = Any_Modular and then Is_Modular_Integer_Type (T2) then
         return T2;

      elsif T2 = Any_Modular and then Is_Modular_Integer_Type (T1) then
         return T1;

      --  ----------------------------------------------------------
      --  Special cases for equality operators (all other predefined
      --  operators can never apply to tagged types)
      --  ----------------------------------------------------------

      --  Ada 2005 (AI-251): T1 and T2 are class-wide types, and T2 is an
      --  interface

      elsif Is_Class_Wide_Type (T1)
        and then Is_Class_Wide_Type (T2)
        and then Is_Interface (Etype (T2))
      then
         return T1;

      --  Ada 2005 (AI-251): T1 is a concrete type that implements the
      --  class-wide interface T2

      elsif Is_Class_Wide_Type (T2)
        and then Is_Interface (Etype (T2))
        and then Interface_Present_In_Ancestor (Typ   => T1,
                                                Iface => Etype (T2))
      then
         return T1;

      elsif Is_Class_Wide_Type (T1)
        and then Is_Ancestor (Root_Type (T1), T2)
      then
         return T1;

      elsif Is_Class_Wide_Type (T2)
        and then Is_Ancestor (Root_Type (T2), T1)
      then
         return T2;

      elsif Is_Access_Type (T1)
        and then Is_Access_Type (T2)
        and then Is_Class_Wide_Type (Designated_Type (T1))
        and then not Is_Class_Wide_Type (Designated_Type (T2))
        and then
          Is_Ancestor (Root_Type (Designated_Type (T1)), Designated_Type (T2))
      then
         return T1;

      elsif Is_Access_Type (T1)
        and then Is_Access_Type (T2)
        and then Is_Class_Wide_Type (Designated_Type (T2))
        and then not Is_Class_Wide_Type (Designated_Type (T1))
        and then
          Is_Ancestor (Root_Type (Designated_Type (T2)), Designated_Type (T1))
      then
         return T2;

      elsif Ekind (B1) in E_Access_Subprogram_Type
                        | E_Access_Protected_Subprogram_Type
        and then Ekind (Designated_Type (B1)) /= E_Subprogram_Type
        and then Is_Access_Type (T2)
      then
         return T2;

      elsif Ekind (B2) in E_Access_Subprogram_Type
                        | E_Access_Protected_Subprogram_Type
        and then Ekind (Designated_Type (B2)) /= E_Subprogram_Type
        and then Is_Access_Type (T1)
      then
         return T1;

      elsif Ekind (T1) in E_Allocator_Type | E_Access_Attribute_Type
        and then Is_Access_Type (T2)
      then
         return T2;

      elsif Ekind (T2) in E_Allocator_Type | E_Access_Attribute_Type
        and then Is_Access_Type (T1)
      then
         return T1;

      --  Ada 2005 (AI-230): Support the following operators:

      --    function "="  (L, R : universal_access) return Boolean;
      --    function "/=" (L, R : universal_access) return Boolean;

      --  Pool-specific access types (E_Access_Type) are not covered by these
      --  operators because of the legality rule of 4.5.2(9.2): "The operands
      --  of the equality operators for universal_access shall be convertible
      --  to one another (see 4.6)". For example, considering the type decla-
      --  ration "type P is access Integer" and an anonymous access to Integer,
      --  P is convertible to "access Integer" by 4.6 (24.11-24.15), but there
      --  is no rule in 4.6 that allows "access Integer" to be converted to P.
      --  Note that this does not preclude one operand to be a pool-specific
      --  access type, as a previous version of this code enforced.

      elsif Ada_Version >= Ada_2005 then
         if Is_Anonymous_Access_Type (T1)
           and then Is_Access_Type (T2)
         then
            return T1;

         elsif Is_Anonymous_Access_Type (T2)
           and then Is_Access_Type (T1)
         then
            return T2;
         end if;
      end if;

      --  If none of the above cases applies, types are not compatible

      return Any_Type;
   end Specific_Type;

   ---------------------
   -- Set_Abstract_Op --
   ---------------------

   procedure Set_Abstract_Op (I : Interp_Index; V : Entity_Id) is
   begin
      All_Interp.Table (I).Abstract_Op := V;
   end Set_Abstract_Op;

   -----------------------
   -- Valid_Boolean_Arg --
   -----------------------

   --  In addition to booleans and arrays of booleans, we must include
   --  aggregates as valid boolean arguments, because in the first pass of
   --  resolution their components are not examined. If it turns out not to be
   --  an aggregate of booleans, this will be diagnosed in Resolve.
   --  Any_Composite must be checked for prior to the array type checks because
   --  Any_Composite does not have any associated indexes.

   function Valid_Boolean_Arg (T : Entity_Id) return Boolean is
   begin
      if Is_Boolean_Type (T)
        or else Is_Modular_Integer_Type (T)
        or else T = Universal_Integer
        or else T = Any_Composite
      then
         return True;

      elsif Is_Array_Type (T)
        and then T /= Any_String
        and then Number_Dimensions (T) = 1
        and then Is_Boolean_Type (Component_Type (T))
        and then
         ((not Is_Private_Composite (T) and then not Is_Limited_Composite (T))
           or else In_Instance
           or else Available_Full_View_Of_Component (T))
      then
         return True;

      else
         return False;
      end if;
   end Valid_Boolean_Arg;

   --------------------------
   -- Valid_Comparison_Arg --
   --------------------------

   function Valid_Comparison_Arg (T : Entity_Id) return Boolean is
   begin

      if T = Any_Composite then
         return False;

      elsif Is_Discrete_Type (T)
        or else Is_Real_Type (T)
      then
         return True;

      elsif Is_Array_Type (T)
          and then Number_Dimensions (T) = 1
          and then Is_Discrete_Type (Component_Type (T))
          and then (not Is_Private_Composite (T) or else In_Instance)
          and then (not Is_Limited_Composite (T) or else In_Instance)
      then
         return True;

      elsif Is_Array_Type (T)
        and then Number_Dimensions (T) = 1
        and then Is_Discrete_Type (Component_Type (T))
        and then Available_Full_View_Of_Component (T)
      then
         return True;

      elsif Is_String_Type (T) then
         return True;
      else
         return False;
      end if;
   end Valid_Comparison_Arg;

   ------------------
   -- Write_Interp --
   ------------------

   procedure Write_Interp (It : Interp) is
   begin
      Write_Str ("Nam: ");
      Print_Tree_Node (It.Nam);
      Write_Str ("Typ: ");
      Print_Tree_Node (It.Typ);
      Write_Str ("Abstract_Op: ");
      Print_Tree_Node (It.Abstract_Op);
   end Write_Interp;

   ---------------------
   -- Write_Overloads --
   ---------------------

   procedure Write_Overloads (N : Node_Id) is
      I   : Interp_Index;
      It  : Interp;
      Nam : Entity_Id;

   begin
      Write_Str ("Overloads: ");
      Print_Node_Briefly (N);

      if not Is_Overloaded (N) then
         if Is_Entity_Name (N) then
            Write_Line ("Non-overloaded entity ");
            Write_Entity_Info (Entity (N), " ");
         end if;

      elsif Nkind (N) not in N_Has_Entity then
         Get_First_Interp (N, I, It);
         while Present (It.Nam) loop
            Write_Int (Int (It.Typ));
            Write_Str ("   ");
            Write_Name (Chars (It.Typ));
            Write_Eol;
            Get_Next_Interp (I, It);
         end loop;

      else
         Get_First_Interp (N, I, It);
         Write_Line ("Overloaded entity ");
         Write_Line ("      Name           Type           Abstract Op");
         Write_Line ("===============================================");
         Nam := It.Nam;

         while Present (Nam) loop
            Write_Int (Int (Nam));
            Write_Str ("   ");
            Write_Name (Chars (Nam));
            Write_Str ("   ");
            Write_Int (Int (It.Typ));
            Write_Str ("   ");
            Write_Name (Chars (It.Typ));

            if Present (It.Abstract_Op) then
               Write_Str ("   ");
               Write_Int (Int (It.Abstract_Op));
               Write_Str ("   ");
               Write_Name (Chars (It.Abstract_Op));
            end if;

            Write_Eol;
            Get_Next_Interp (I, It);
            Nam := It.Nam;
         end loop;
      end if;
   end Write_Overloads;

end Sem_Type;
