------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              S E M _ C H 8                               --
--                                                                          --
--                                 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 Atree;          use Atree;
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 Errout;         use Errout;
with Exp_Disp;       use Exp_Disp;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Ghost;          use Ghost;
with Impunit;        use Impunit;
with Lib;            use Lib;
with Lib.Load;       use Lib.Load;
with Lib.Xref;       use Lib.Xref;
with Namet;          use Namet;
with Namet.Sp;       use Namet.Sp;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Output;         use Output;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch4;        use Sem_Ch4;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch10;       use Sem_Ch10;
with Sem_Ch12;       use Sem_Ch12;
with Sem_Ch13;       use Sem_Ch13;
with Sem_Dim;        use Sem_Dim;
with Sem_Disp;       use Sem_Disp;
with Sem_Dist;       use Sem_Dist;
with Sem_Elab;       use Sem_Elab;
with Sem_Eval;       use Sem_Eval;
with Sem_Prag;       use Sem_Prag;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sem_Type;       use Sem_Type;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinfo.CN;       use Sinfo.CN;
with Snames;         use Snames;
with Style;
with Table;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;

package body Sem_Ch8 is

   ------------------------------------
   -- Visibility and Name Resolution --
   ------------------------------------

   --  This package handles name resolution and the collection of possible
   --  interpretations for overloaded names, prior to overload resolution.

   --  Name resolution is the process that establishes a mapping between source
   --  identifiers and the entities they denote at each point in the program.
   --  Each entity is represented by a defining occurrence. Each identifier
   --  that denotes an entity points to the corresponding defining occurrence.
   --  This is the entity of the applied occurrence. Each occurrence holds
   --  an index into the names table, where source identifiers are stored.

   --  Each entry in the names table for an identifier or designator uses the
   --  Info pointer to hold a link to the currently visible entity that has
   --  this name (see subprograms Get_Name_Entity_Id and Set_Name_Entity_Id
   --  in package Sem_Util). The visibility is initialized at the beginning of
   --  semantic processing to make entities in package Standard immediately
   --  visible. The visibility table is used in a more subtle way when
   --  compiling subunits (see below).

   --  Entities that have the same name (i.e. homonyms) are chained. In the
   --  case of overloaded entities, this chain holds all the possible meanings
   --  of a given identifier. The process of overload resolution uses type
   --  information to select from this chain the unique meaning of a given
   --  identifier.

   --  Entities are also chained in their scope, through the Next_Entity link.
   --  As a consequence, the name space is organized as a sparse matrix, where
   --  each row corresponds to a scope, and each column to a source identifier.
   --  Open scopes, that is to say scopes currently being compiled, have their
   --  corresponding rows of entities in order, innermost scope first.

   --  The scopes of packages that are mentioned in context clauses appear in
   --  no particular order, interspersed among open scopes. This is because
   --  in the course of analyzing the context of a compilation, a package
   --  declaration is first an open scope, and subsequently an element of the
   --  context. If subunits or child units are present, a parent unit may
   --  appear under various guises at various times in the compilation.

   --  When the compilation of the innermost scope is complete, the entities
   --  defined therein are no longer visible. If the scope is not a package
   --  declaration, these entities are never visible subsequently, and can be
   --  removed from visibility chains. If the scope is a package declaration,
   --  its visible declarations may still be accessible. Therefore the entities
   --  defined in such a scope are left on the visibility chains, and only
   --  their visibility (immediately visibility or potential use-visibility)
   --  is affected.

   --  The ordering of homonyms on their chain does not necessarily follow
   --  the order of their corresponding scopes on the scope stack. For
   --  example, if package P and the enclosing scope both contain entities
   --  named E, then when compiling the package body the chain for E will
   --  hold the global entity first,  and the local one (corresponding to
   --  the current inner scope) next. As a result, name resolution routines
   --  do not assume any relative ordering of the homonym chains, either
   --  for scope nesting or to order of appearance of context clauses.

   --  When compiling a child unit, entities in the parent scope are always
   --  immediately visible. When compiling the body of a child unit, private
   --  entities in the parent must also be made immediately visible. There
   --  are separate routines to make the visible and private declarations
   --  visible at various times (see package Sem_Ch7).

   --              +--------+         +-----+
   --              | In use |-------->| EU1 |-------------------------->
   --              +--------+         +-----+
   --                                    |                      |
   --      +--------+                 +-----+                +-----+
   --      | Stand. |---------------->| ES1 |--------------->| ES2 |--->
   --      +--------+                 +-----+                +-----+
   --                                    |                      |
   --              +---------+           |                   +-----+
   --              | with'ed |------------------------------>| EW2 |--->
   --              +---------+           |                   +-----+
   --                                    |                      |
   --      +--------+                 +-----+                +-----+
   --      | Scope2 |---------------->| E12 |--------------->| E22 |--->
   --      +--------+                 +-----+                +-----+
   --                                    |                      |
   --      +--------+                 +-----+                +-----+
   --      | Scope1 |---------------->| E11 |--------------->| E12 |--->
   --      +--------+                 +-----+                +-----+
   --          ^                         |                      |
   --          |                         |                      |
   --          |   +---------+           |                      |
   --          |   | with'ed |----------------------------------------->
   --          |   +---------+           |                      |
   --          |                         |                      |
   --      Scope stack                   |                      |
   --      (innermost first)             |                      |
   --                                 +----------------------------+
   --      Names  table =>            | Id1 |     |    |     | Id2 |
   --                                 +----------------------------+

   --  Name resolution must deal with several syntactic forms: simple names,
   --  qualified names, indexed names, and various forms of calls.

   --  Each identifier points to an entry in the names table. The resolution
   --  of a simple name consists in traversing the homonym chain, starting
   --  from the names table. If an entry is immediately visible, it is the one
   --  designated by the identifier. If only potentially use-visible entities
   --  are on the chain, we must verify that they do not hide each other. If
   --  the entity we find is overloadable, we collect all other overloadable
   --  entities on the chain as long as they are not hidden.
   --
   --  To resolve expanded names, we must find the entity at the intersection
   --  of the entity chain for the scope (the prefix) and the homonym chain
   --  for the selector. In general, homonym chains will be much shorter than
   --  entity chains, so it is preferable to start from the names table as
   --  well. If the entity found is overloadable, we must collect all other
   --  interpretations that are defined in the scope denoted by the prefix.

   --  For records, protected types, and tasks, their local entities are
   --  removed from visibility chains on exit from the corresponding scope.
   --  From the outside, these entities are always accessed by selected
   --  notation, and the entity chain for the record type, protected type,
   --  etc. is traversed sequentially in order to find the designated entity.

   --  The discriminants of a type and the operations of a protected type or
   --  task are unchained on  exit from the first view of the type, (such as
   --  a private or incomplete type declaration, or a protected type speci-
   --  fication) and re-chained when compiling the second view.

   --  In the case of operators,  we do not make operators on derived types
   --  explicit. As a result, the notation P."+" may denote either a user-
   --  defined function with name "+", or else an implicit declaration of the
   --  operator "+" in package P. The resolution of expanded names always
   --  tries to resolve an operator name as such an implicitly defined entity,
   --  in addition to looking for explicit declarations.

   --  All forms of names that denote entities (simple names, expanded names,
   --  character literals in some cases) have a Entity attribute, which
   --  identifies the entity denoted by the name.

   ---------------------
   -- The Scope Stack --
   ---------------------

   --  The Scope stack keeps track of the scopes currently been compiled.
   --  Every entity that contains declarations (including records) is placed
   --  on the scope stack while it is being processed, and removed at the end.
   --  Whenever a non-package scope is exited, the entities defined therein
   --  are removed from the visibility table, so that entities in outer scopes
   --  become visible (see previous description). On entry to Sem, the scope
   --  stack only contains the package Standard. As usual, subunits complicate
   --  this picture ever so slightly.

   --  The Rtsfind mechanism can force a call to Semantics while another
   --  compilation is in progress. The unit retrieved by Rtsfind must be
   --  compiled in its own context, and has no access to the visibility of
   --  the unit currently being compiled. The procedures Save_Scope_Stack and
   --  Restore_Scope_Stack make entities in current open scopes invisible
   --  before compiling the retrieved unit, and restore the compilation
   --  environment afterwards.

   ------------------------
   -- Compiling subunits --
   ------------------------

   --  Subunits must be compiled in the environment of the corresponding stub,
   --  that is to say with the same visibility into the parent (and its
   --  context) that is available at the point of the stub declaration, but
   --  with the additional visibility provided by the context clause of the
   --  subunit itself. As a result, compilation of a subunit forces compilation
   --  of the parent (see description in lib-). At the point of the stub
   --  declaration, Analyze is called recursively to compile the proper body of
   --  the subunit, but without reinitializing the names table, nor the scope
   --  stack (i.e. standard is not pushed on the stack). In this fashion the
   --  context of the subunit is added to the context of the parent, and the
   --  subunit is compiled in the correct environment. Note that in the course
   --  of processing the context of a subunit, Standard will appear twice on
   --  the scope stack: once for the parent of the subunit, and once for the
   --  unit in the context clause being compiled. However, the two sets of
   --  entities are not linked by homonym chains, so that the compilation of
   --  any context unit happens in a fresh visibility environment.

   -------------------------------
   -- Processing of USE Clauses --
   -------------------------------

   --  Every defining occurrence has a flag indicating if it is potentially use
   --  visible. Resolution of simple names examines this flag. The processing
   --  of use clauses consists in setting this flag on all visible entities
   --  defined in the corresponding package. On exit from the scope of the use
   --  clause, the corresponding flag must be reset. However, a package may
   --  appear in several nested use clauses (pathological but legal, alas)
   --  which forces us to use a slightly more involved scheme:

   --    a) The defining occurrence for a package holds a flag -In_Use- to
   --    indicate that it is currently in the scope of a use clause. If a
   --    redundant use clause is encountered, then the corresponding occurrence
   --    of the package name is flagged -Redundant_Use-.

   --    b) On exit from a scope, the use clauses in its declarative part are
   --    scanned. The visibility flag is reset in all entities declared in
   --    package named in a use clause, as long as the package is not flagged
   --    as being in a redundant use clause (in which case the outer use
   --    clause is still in effect, and the direct visibility of its entities
   --    must be retained).

   --  Note that entities are not removed from their homonym chains on exit
   --  from the package specification. A subsequent use clause does not need
   --  to rechain the visible entities, but only to establish their direct
   --  visibility.

   -----------------------------------
   -- Handling private declarations --
   -----------------------------------

   --  The principle that each entity has a single defining occurrence clashes
   --  with the presence of two separate definitions for private types: the
   --  first is the private type declaration, and second is the full type
   --  declaration. It is important that all references to the type point to
   --  the same defining occurrence, namely the first one. To enforce the two
   --  separate views of the entity, the corresponding information is swapped
   --  between the two declarations. Outside of the package, the defining
   --  occurrence only contains the private declaration information, while in
   --  the private part and the body of the package the defining occurrence
   --  contains the full declaration. To simplify the swap, the defining
   --  occurrence that currently holds the private declaration points to the
   --  full declaration. During semantic processing the defining occurrence
   --  also points to a list of private dependents, that is to say access types
   --  or composite types whose designated types or component types are
   --  subtypes or derived types of the private type in question. After the
   --  full declaration has been seen, the private dependents are updated to
   --  indicate that they have full definitions.

   ------------------------------------
   -- Handling of Undefined Messages --
   ------------------------------------

   --  In normal mode, only the first use of an undefined identifier generates
   --  a message. The table Urefs is used to record error messages that have
   --  been issued so that second and subsequent ones do not generate further
   --  messages. However, the second reference causes text to be added to the
   --  original undefined message noting "(more references follow)". The
   --  full error list option (-gnatf) forces messages to be generated for
   --  every reference and disconnects the use of this table.

   type Uref_Entry is record
      Node : Node_Id;
      --  Node for identifier for which original message was posted. The
      --  Chars field of this identifier is used to detect later references
      --  to the same identifier.

      Err : Error_Msg_Id;
      --  Records error message Id of original undefined message. Reset to
      --  No_Error_Msg after the second occurrence, where it is used to add
      --  text to the original message as described above.

      Nvis : Boolean;
      --  Set if the message is not visible rather than undefined

      Loc : Source_Ptr;
      --  Records location of error message. Used to make sure that we do
      --  not consider a, b : undefined as two separate instances, which
      --  would otherwise happen, since the parser converts this sequence
      --  to a : undefined; b : undefined.

   end record;

   package Urefs is new Table.Table (
     Table_Component_Type => Uref_Entry,
     Table_Index_Type     => Nat,
     Table_Low_Bound      => 1,
     Table_Initial        => 10,
     Table_Increment      => 100,
     Table_Name           => "Urefs");

   Candidate_Renaming : Entity_Id;
   --  Holds a candidate interpretation that appears in a subprogram renaming
   --  declaration and does not match the given specification, but matches at
   --  least on the first formal. Allows better error message when given
   --  specification omits defaulted parameters, a common error.

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

   procedure Analyze_Generic_Renaming
     (N : Node_Id;
      K : Entity_Kind);
   --  Common processing for all three kinds of generic renaming declarations.
   --  Enter new name and indicate that it renames the generic unit.

   procedure Analyze_Renamed_Character
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean);
   --  Renamed entity is given by a character literal, which must belong
   --  to the return type of the new entity. Is_Body indicates whether the
   --  declaration is a renaming_as_body. If the original declaration has
   --  already been frozen (because of an intervening body, e.g.) the body of
   --  the function must be built now. The same applies to the following
   --  various renaming procedures.

   procedure Analyze_Renamed_Dereference
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean);
   --  Renamed entity is given by an explicit dereference. Prefix must be a
   --  conformant access_to_subprogram type.

   procedure Analyze_Renamed_Entry
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean);
   --  If the renamed entity in a subprogram renaming is an entry or protected
   --  subprogram, build a body for the new entity whose only statement is a
   --  call to the renamed entity.

   procedure Analyze_Renamed_Family_Member
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean);
   --  Used when the renamed entity is an indexed component. The prefix must
   --  denote an entry family.

   procedure Analyze_Renamed_Primitive_Operation
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean);
   --  If the renamed entity in a subprogram renaming is a primitive operation
   --  or a class-wide operation in prefix form, save the target object,
   --  which must be added to the list of actuals in any subsequent call.
   --  The renaming operation is intrinsic because the compiler must in
   --  fact generate a wrapper for it (6.3.1 (10 1/2)).

   procedure Attribute_Renaming (N : Node_Id);
   --  Analyze renaming of attribute as subprogram. The renaming declaration N
   --  is rewritten as a subprogram body that returns the attribute reference
   --  applied to the formals of the function.

   procedure Set_Entity_Or_Discriminal (N : Node_Id; E : Entity_Id);
   --  Set Entity, with style check if need be. For a discriminant reference,
   --  replace by the corresponding discriminal, i.e. the parameter of the
   --  initialization procedure that corresponds to the discriminant.

   procedure Check_Frozen_Renaming (N : Node_Id; Subp : Entity_Id);
   --  A renaming_as_body may occur after the entity of the original decla-
   --  ration has been frozen. In that case, the body of the new entity must
   --  be built now, because the usual mechanism of building the renamed
   --  body at the point of freezing will not work. Subp is the subprogram
   --  for which N provides the Renaming_As_Body.

   procedure Check_In_Previous_With_Clause
     (N   : Node_Id;
      Nam : Node_Id);
   --  N is a use_package clause and Nam the package name, or N is a use_type
   --  clause and Nam is the prefix of the type name. In either case, verify
   --  that the package is visible at that point in the context: either  it
   --  appears in a previous with_clause, or because it is a fully qualified
   --  name and the root ancestor appears in a previous with_clause.

   procedure Check_Library_Unit_Renaming (N : Node_Id; Old_E : Entity_Id);
   --  Verify that the entity in a renaming declaration that is a library unit
   --  is itself a library unit and not a nested unit or subunit. Also check
   --  that if the renaming is a child unit of a generic parent, then the
   --  renamed unit must also be a child unit of that parent. Finally, verify
   --  that a renamed generic unit is not an implicit child declared within
   --  an instance of the parent.

   procedure Chain_Use_Clause (N : Node_Id);
   --  Chain use clause onto list of uses clauses headed by First_Use_Clause in
   --  the proper scope table entry. This is usually the current scope, but it
   --  will be an inner scope when installing the use clauses of the private
   --  declarations of a parent unit prior to compiling the private part of a
   --  child unit. This chain is traversed when installing/removing use clauses
   --  when compiling a subunit or instantiating a generic body on the fly,
   --  when it is necessary to save and restore full environments.

   function Enclosing_Instance return Entity_Id;
   --  In an instance nested within another one, several semantic checks are
   --  unnecessary because the legality of the nested instance has been checked
   --  in the enclosing generic unit. This applies in particular to legality
   --  checks on actuals for formal subprograms of the inner instance, which
   --  are checked as subprogram renamings, and may be complicated by confusion
   --  in private/full views. This function returns the instance enclosing the
   --  current one if there is such, else it returns Empty.
   --
   --  If the renaming determines the entity for the default of a formal
   --  subprogram nested within another instance, choose the innermost
   --  candidate. This is because if the formal has a box, and we are within
   --  an enclosing instance where some candidate interpretations are local
   --  to this enclosing instance, we know that the default was properly
   --  resolved when analyzing the generic, so we prefer the local
   --  candidates to those that are external. This is not always the case
   --  but is a reasonable heuristic on the use of nested generics. The
   --  proper solution requires a full renaming model.

   function Entity_Of_Unit (U : Node_Id) return Entity_Id;
   --  Return the appropriate entity for determining which unit has a deeper
   --  scope: the defining entity for U, unless U is a package instance, in
   --  which case we retrieve the entity of the instance spec.

   procedure Find_Expanded_Name (N : Node_Id);
   --  The input is a selected component known to be an expanded name. Verify
   --  legality of selector given the scope denoted by prefix, and change node
   --  N into a expanded name with a properly set Entity field.

   function Find_First_Use (Use_Clause : Node_Id) return Node_Id;
   --  Find the most previous use clause (that is, the first one to appear in
   --  the source) by traversing the previous clause chain that exists in both
   --  N_Use_Package_Clause nodes and N_Use_Type_Clause nodes.

   function Find_Renamed_Entity
     (N         : Node_Id;
      Nam       : Node_Id;
      New_S     : Entity_Id;
      Is_Actual : Boolean := False) return Entity_Id;
   --  Find the renamed entity that corresponds to the given parameter profile
   --  in a subprogram renaming declaration. The renamed entity may be an
   --  operator, a subprogram, an entry, or a protected operation. Is_Actual
   --  indicates that the renaming is the one generated for an actual subpro-
   --  gram in an instance, for which special visibility checks apply.

   function Has_Implicit_Character_Literal (N : Node_Id) return Boolean;
   --  Find a type derived from Character or Wide_Character in the prefix of N.
   --  Used to resolved qualified names whose selector is a character literal.

   function Has_Private_With (E : Entity_Id) return Boolean;
   --  Ada 2005 (AI-262): Determines if the current compilation unit has a
   --  private with on E.

   function Has_Components (Typ : Entity_Id) return Boolean;
   --  Determine if given type has components, i.e. is either a record type or
   --  type or a type that has discriminants.

   function Has_Implicit_Operator (N : Node_Id) return Boolean;
   --  N is an expanded name whose selector is an operator name (e.g. P."+").
   --  declarative part contains an implicit declaration of an operator if it
   --  has a declaration of a type to which one of the predefined operators
   --  apply. The existence of this routine is an implementation artifact. A
   --  more straightforward but more space-consuming choice would be to make
   --  all inherited operators explicit in the symbol table.

   procedure Inherit_Renamed_Profile (New_S : Entity_Id; Old_S : Entity_Id);
   --  A subprogram defined by a renaming declaration inherits the parameter
   --  profile of the renamed entity. The subtypes given in the subprogram
   --  specification are discarded and replaced with those of the renamed
   --  subprogram, which are then used to recheck the default values.

   function Most_Descendant_Use_Clause
     (Clause1 : Entity_Id;
      Clause2 : Entity_Id) return Entity_Id;
   --  Determine which use clause parameter is the most descendant in terms of
   --  scope.

   procedure Premature_Usage (N : Node_Id);
   --  Diagnose usage of an entity before it is visible

   procedure Use_One_Package
     (N         : Node_Id;
      Pack_Name : Entity_Id := Empty;
      Force     : Boolean   := False);
   --  Make visible entities declared in package P potentially use-visible
   --  in the current context. Also used in the analysis of subunits, when
   --  re-installing use clauses of parent units. N is the use_clause that
   --  names P (and possibly other packages).

   procedure Use_One_Type
     (Id        : Node_Id;
      Installed : Boolean := False;
      Force     : Boolean := False);
   --  Id is the subtype mark from a use_type_clause. This procedure makes
   --  the primitive operators of the type potentially use-visible. The
   --  boolean flag Installed indicates that the clause is being reinstalled
   --  after previous analysis, and primitive operations are already chained
   --  on the Used_Operations list of the clause.

   procedure Write_Info;
   --  Write debugging information on entities declared in current scope

   --------------------------------
   -- Analyze_Exception_Renaming --
   --------------------------------

   --  The language only allows a single identifier, but the tree holds an
   --  identifier list. The parser has already issued an error message if
   --  there is more than one element in the list.

   procedure Analyze_Exception_Renaming (N : Node_Id) is
      Id  : constant Entity_Id := Defining_Entity (N);
      Nam : constant Node_Id   := Name (N);

   begin
      Enter_Name (Id);
      Analyze (Nam);

      Mutate_Ekind   (Id, E_Exception);
      Set_Etype   (Id, Standard_Exception_Type);
      Set_Is_Pure (Id, Is_Pure (Current_Scope));

      if Is_Entity_Name (Nam)
        and then Present (Entity (Nam))
        and then Ekind (Entity (Nam)) = E_Exception
      then
         if Present (Renamed_Object (Entity (Nam))) then
            Set_Renamed_Object (Id, Renamed_Object (Entity (Nam)));
         else
            Set_Renamed_Object (Id, Entity (Nam));
         end if;

         --  The exception renaming declaration may become Ghost if it renames
         --  a Ghost entity.

         Mark_Ghost_Renaming (N, Entity (Nam));
      else
         Error_Msg_N ("invalid exception name in renaming", Nam);
      end if;

      --  Implementation-defined aspect specifications can appear in a renaming
      --  declaration, but not language-defined ones. The call to procedure
      --  Analyze_Aspect_Specifications will take care of this error check.

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, Id);
      end if;
   end Analyze_Exception_Renaming;

   ---------------------------
   -- Analyze_Expanded_Name --
   ---------------------------

   procedure Analyze_Expanded_Name (N : Node_Id) is
   begin
      --  If the entity pointer is already set, this is an internal node, or a
      --  node that is analyzed more than once, after a tree modification. In
      --  such a case there is no resolution to perform, just set the type. In
      --  either case, start by analyzing the prefix.

      Analyze (Prefix (N));

      if Present (Entity (N)) then
         if Is_Type (Entity (N)) then
            Set_Etype (N, Entity (N));
         else
            Set_Etype (N, Etype (Entity (N)));
         end if;

      else
         Find_Expanded_Name (N);
      end if;

      --  In either case, propagate dimension of entity to expanded name

      Analyze_Dimension (N);
   end Analyze_Expanded_Name;

   ---------------------------------------
   -- Analyze_Generic_Function_Renaming --
   ---------------------------------------

   procedure Analyze_Generic_Function_Renaming  (N : Node_Id) is
   begin
      Analyze_Generic_Renaming (N, E_Generic_Function);
   end Analyze_Generic_Function_Renaming;

   --------------------------------------
   -- Analyze_Generic_Package_Renaming --
   --------------------------------------

   procedure Analyze_Generic_Package_Renaming   (N : Node_Id) is
   begin
      --  Test for the Text_IO special unit case here, since we may be renaming
      --  one of the subpackages of Text_IO, then join common routine.

      Check_Text_IO_Special_Unit (Name (N));

      Analyze_Generic_Renaming (N, E_Generic_Package);
   end Analyze_Generic_Package_Renaming;

   ----------------------------------------
   -- Analyze_Generic_Procedure_Renaming --
   ----------------------------------------

   procedure Analyze_Generic_Procedure_Renaming (N : Node_Id) is
   begin
      Analyze_Generic_Renaming (N, E_Generic_Procedure);
   end Analyze_Generic_Procedure_Renaming;

   ------------------------------
   -- Analyze_Generic_Renaming --
   ------------------------------

   procedure Analyze_Generic_Renaming
     (N : Node_Id;
      K : Entity_Kind)
   is
      New_P : constant Entity_Id := Defining_Entity (N);
      Inst  : Boolean := False;
      Old_P : Entity_Id;

   begin
      if Name (N) = Error then
         return;
      end if;

      Generate_Definition (New_P);

      if Current_Scope /= Standard_Standard then
         Set_Is_Pure (New_P, Is_Pure (Current_Scope));
      end if;

      if Nkind (Name (N)) = N_Selected_Component then
         Check_Generic_Child_Unit (Name (N), Inst);
      else
         Analyze (Name (N));
      end if;

      if not Is_Entity_Name (Name (N)) then
         Error_Msg_N ("expect entity name in renaming declaration", Name (N));
         Old_P := Any_Id;
      else
         Old_P := Entity (Name (N));
      end if;

      Enter_Name (New_P);
      Mutate_Ekind (New_P, K);

      if Etype (Old_P) = Any_Type then
         null;

      elsif Ekind (Old_P) /= K then
         Error_Msg_N ("invalid generic unit name", Name (N));

      else
         if Present (Renamed_Object (Old_P)) then
            Set_Renamed_Object (New_P, Renamed_Object (Old_P));
         else
            Set_Renamed_Object (New_P, Old_P);
         end if;

         --  The generic renaming declaration may become Ghost if it renames a
         --  Ghost entity.

         Mark_Ghost_Renaming (N, Old_P);

         Set_Is_Pure          (New_P, Is_Pure          (Old_P));
         Set_Is_Preelaborated (New_P, Is_Preelaborated (Old_P));

         Set_Etype (New_P, Etype (Old_P));
         Set_Has_Completion (New_P);

         if In_Open_Scopes (Old_P) then
            Error_Msg_N ("within its scope, generic denotes its instance", N);
         end if;

         --  For subprograms, propagate the Intrinsic flag, to allow, e.g.
         --  renamings and subsequent instantiations of Unchecked_Conversion.

         if Is_Generic_Subprogram (Old_P) then
            Set_Is_Intrinsic_Subprogram
              (New_P, Is_Intrinsic_Subprogram (Old_P));
         end if;

         Check_Library_Unit_Renaming (N, Old_P);
      end if;

      --  Implementation-defined aspect specifications can appear in a renaming
      --  declaration, but not language-defined ones. The call to procedure
      --  Analyze_Aspect_Specifications will take care of this error check.

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, New_P);
      end if;
   end Analyze_Generic_Renaming;

   -----------------------------
   -- Analyze_Object_Renaming --
   -----------------------------

   procedure Analyze_Object_Renaming (N : Node_Id) is
      Id            : constant Entity_Id  := Defining_Identifier (N);
      Loc           : constant Source_Ptr := Sloc (N);
      Nam           : constant Node_Id    := Name (N);
      Is_Object_Ref : Boolean;
      Dec           : Node_Id;
      T             : Entity_Id;
      T2            : Entity_Id;
      Q             : Node_Id;

      procedure Check_Constrained_Object;
      --  If the nominal type is unconstrained but the renamed object is
      --  constrained, as can happen with renaming an explicit dereference or
      --  a function return, build a constrained subtype from the object. If
      --  the renaming is for a formal in an accept statement, the analysis
      --  has already established its actual subtype. This is only relevant
      --  if the renamed object is an explicit dereference.

      function Get_Object_Name (Nod : Node_Id) return Node_Id;
      --  Obtain the name of the object from node Nod which is being renamed by
      --  the object renaming declaration N.

      function Find_Raise_Node (N : Node_Id) return Traverse_Result;
      --  Process one node in search for N_Raise_xxx_Error nodes.
      --  Return Abandon if found, OK otherwise.

      ---------------------
      -- Find_Raise_Node --
      ---------------------

      function Find_Raise_Node (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) in N_Raise_xxx_Error then
            return Abandon;
         else
            return OK;
         end if;
      end Find_Raise_Node;

      ------------------------
      -- No_Raise_xxx_Error --
      ------------------------

      function No_Raise_xxx_Error is new Traverse_Func (Find_Raise_Node);
      --  Traverse tree to look for a N_Raise_xxx_Error node and returns
      --  Abandon if so and OK if none found.

      ------------------------------
      -- Check_Constrained_Object --
      ------------------------------

      procedure Check_Constrained_Object is
         Typ         : constant Entity_Id := Etype (Nam);
         Subt        : Entity_Id;
         Loop_Scheme : Node_Id;

      begin
         if Nkind (Nam) in N_Function_Call | N_Explicit_Dereference
           and then Is_Composite_Type (Typ)
           and then not Is_Constrained (Typ)
           and then not Has_Unknown_Discriminants (Typ)
           and then Expander_Active
         then
            --  If Actual_Subtype is already set, nothing to do

            if Ekind (Id) in E_Variable | E_Constant
              and then Present (Actual_Subtype (Id))
            then
               null;

            --  A renaming of an unchecked union has no actual subtype

            elsif Is_Unchecked_Union (Typ) then
               null;

            --  If a record is limited its size is invariant. This is the case
            --  in particular with record types with an access discriminant
            --  that are used in iterators. This is an optimization, but it
            --  also prevents typing anomalies when the prefix is further
            --  expanded.

            --  Note that we cannot just use the Is_Limited_Record flag because
            --  it does not apply to records with limited components, for which
            --  this syntactic flag is not set, but whose size is also fixed.

            --  Note also that we need to build the constrained subtype for an
            --  array in order to make the bounds explicit in most cases, but
            --  not if the object comes from an extended return statement, as
            --  this would create dangling references to them later on.

            elsif Is_Limited_Type (Typ)
              and then (not Is_Array_Type (Typ) or else Is_Return_Object (Id))
            then
               null;

            else
               Subt := Make_Temporary (Loc, 'T');
               Remove_Side_Effects (Nam);
               Insert_Action (N,
                 Make_Subtype_Declaration (Loc,
                   Defining_Identifier => Subt,
                   Subtype_Indication  =>
                     Make_Subtype_From_Expr (Nam, Typ)));
               Rewrite (Subtype_Mark (N), New_Occurrence_Of (Subt, Loc));
               Set_Etype (Nam, Subt);

               --  Suppress discriminant checks on this subtype if the original
               --  type has defaulted discriminants and Id is a "for of" loop
               --  iterator.

               if Has_Defaulted_Discriminants (Typ)
                 and then Nkind (Original_Node (Parent (N))) = N_Loop_Statement
               then
                  Loop_Scheme := Iteration_Scheme (Original_Node (Parent (N)));

                  if Present (Loop_Scheme)
                    and then Present (Iterator_Specification (Loop_Scheme))
                    and then
                      Defining_Identifier
                        (Iterator_Specification (Loop_Scheme)) = Id
                  then
                     Set_Checks_May_Be_Suppressed (Subt);
                     Push_Local_Suppress_Stack_Entry
                       (Entity   => Subt,
                        Check    => Discriminant_Check,
                        Suppress => True);
                  end if;
               end if;

               --  Freeze subtype at once, to prevent order of elaboration
               --  issues in the backend. The renamed object exists, so its
               --  type is already frozen in any case.

               Freeze_Before (N, Subt);
            end if;
         end if;
      end Check_Constrained_Object;

      ---------------------
      -- Get_Object_Name --
      ---------------------

      function Get_Object_Name (Nod : Node_Id) return Node_Id is
         Obj_Nam : Node_Id;

      begin
         Obj_Nam := Nod;
         while Present (Obj_Nam) loop
            case Nkind (Obj_Nam) is
               when N_Attribute_Reference
                  | N_Explicit_Dereference
                  | N_Indexed_Component
                  | N_Slice
               =>
                  Obj_Nam := Prefix (Obj_Nam);

               when N_Selected_Component =>
                  Obj_Nam := Selector_Name (Obj_Nam);

               when N_Qualified_Expression | N_Type_Conversion =>
                  Obj_Nam := Expression (Obj_Nam);

               when others =>
                  exit;
            end case;
         end loop;

         return Obj_Nam;
      end Get_Object_Name;

   --  Start of processing for Analyze_Object_Renaming

   begin
      if Nam = Error then
         return;
      end if;

      Set_Is_Pure (Id, Is_Pure (Current_Scope));
      Enter_Name (Id);

      --  The renaming of a component that depends on a discriminant requires
      --  an actual subtype, because in subsequent use of the object Gigi will
      --  be unable to locate the actual bounds. This explicit step is required
      --  when the renaming is generated in removing side effects of an
      --  already-analyzed expression.

      if Nkind (Nam) = N_Selected_Component and then Analyzed (Nam) then

         --  The object renaming declaration may become Ghost if it renames a
         --  Ghost entity.

         if Is_Entity_Name (Nam) then
            Mark_Ghost_Renaming (N, Entity (Nam));
         end if;

         T   := Etype (Nam);
         Dec := Build_Actual_Subtype_Of_Component (Etype (Nam), Nam);

         if Present (Dec) then
            Insert_Action (N, Dec);
            T := Defining_Identifier (Dec);
            Set_Etype (Nam, T);
         end if;
      elsif Present (Subtype_Mark (N))
        or else not Present (Access_Definition (N))
      then
         if Present (Subtype_Mark (N)) then
            Find_Type (Subtype_Mark (N));
            T := Entity (Subtype_Mark (N));
            Analyze (Nam);

         --  AI12-0275: Case of object renaming without a subtype_mark

         else
            Analyze (Nam);

            --  Normal case of no overloading in object name

            if not Is_Overloaded (Nam) then

               --  Catch error cases (such as attempting to rename a procedure
               --  or package) using the shorthand form.

               if No (Etype (Nam))
                 or else Etype (Nam) = Standard_Void_Type
               then
                  Error_Msg_N
                    ("object name or value expected in renaming", Nam);

                  Mutate_Ekind (Id, E_Variable);
                  Set_Etype (Id, Any_Type);

                  return;

               else
                  T := Etype (Nam);
               end if;

            --  Case of overloaded name, which will be illegal if there's more
            --  than one acceptable interpretation (such as overloaded function
            --  calls).

            else
               declare
                  I    : Interp_Index;
                  I1   : Interp_Index;
                  It   : Interp;
                  It1  : Interp;
                  Nam1 : Entity_Id;

               begin
                  --  More than one candidate interpretation is available

                  --  Remove procedure calls, which syntactically cannot appear
                  --  in this context, but which cannot be removed by type
                  --  checking, because the context does not impose a type.

                  Get_First_Interp (Nam, I, It);
                  while Present (It.Typ) loop
                     if It.Typ = Standard_Void_Type then
                        Remove_Interp (I);
                     end if;

                     Get_Next_Interp (I, It);
                  end loop;

                  Get_First_Interp (Nam, I, It);
                  I1  := I;
                  It1 := It;

                  --  If there's no type present, we have an error case (such
                  --  as overloaded procedures named in the object renaming).

                  if No (It.Typ) then
                     Error_Msg_N
                       ("object name or value expected in renaming", Nam);

                     Mutate_Ekind (Id, E_Variable);
                     Set_Etype (Id, Any_Type);

                     return;
                  end if;

                  Get_Next_Interp (I, It);

                  if Present (It.Typ) then
                     Nam1  := It1.Nam;
                     It1 := Disambiguate (Nam, I1, I, Any_Type);

                     if It1 = No_Interp then
                        Error_Msg_N ("ambiguous name in object renaming", Nam);

                        Error_Msg_Sloc := Sloc (It.Nam);
                        Error_Msg_N ("\\possible interpretation#!", Nam);

                        Error_Msg_Sloc := Sloc (Nam1);
                        Error_Msg_N ("\\possible interpretation#!", Nam);

                        return;
                     end if;
                  end if;

                  Set_Etype (Nam, It1.Typ);
                  T := It1.Typ;
               end;
            end if;

            if Etype (Nam) = Standard_Exception_Type then
               Error_Msg_N
                 ("exception requires a subtype mark in renaming", Nam);
               return;
            end if;
         end if;

         --  The object renaming declaration may become Ghost if it renames a
         --  Ghost entity.

         if Is_Entity_Name (Nam) then
            Mark_Ghost_Renaming (N, Entity (Nam));
         end if;

         --  Check against AI12-0401 here before Resolve may rewrite Nam and
         --  potentially generate spurious warnings.

         --   In the case where the object_name is a qualified_expression with
         --   a nominal subtype T and whose expression is a name that denotes
         --   an object Q:
         --    * if T is an elementary subtype, then:
         --      * Q shall be a constant other than a dereference of an access
         --        type; or
         --      * the nominal subtype of Q shall be statically compatible with
         --        T; or
         --      * T shall statically match the base subtype of its type if
         --        scalar, or the first subtype of its type if an access type.
         --    * if T is a composite subtype, then Q shall be known to be
         --      constrained or T shall statically match the first subtype of
         --      its type.

         if Nkind (Nam) = N_Qualified_Expression
           and then Is_Object_Reference (Expression (Nam))
         then
            Q := Expression (Nam);

            if (Is_Elementary_Type (T)
                  and then
                not ((not Is_Variable (Q)
                       and then Nkind (Q) /= N_Explicit_Dereference)
                      or else Subtypes_Statically_Compatible (Etype (Q), T)
                      or else (Is_Scalar_Type (T)
                                and then Subtypes_Statically_Match
                                           (T, Base_Type (T)))
                      or else (Is_Access_Type (T)
                                and then Subtypes_Statically_Match
                                           (T, First_Subtype (T)))))
              or else (Is_Composite_Type (T)
                         and then

                       --  If Q is an aggregate, Is_Constrained may not be set
                       --  yet and its type may not be resolved yet.
                       --  This doesn't quite correspond to the complex notion
                       --  of "known to be constrained" but this is good enough
                       --  for a rule which is in any case too complex.

                       not (Is_Constrained (Etype (Q))
                             or else Nkind (Q) = N_Aggregate
                             or else Subtypes_Statically_Match
                                       (T, First_Subtype (T))))
            then
               Error_Msg_N
                 ("subtype of renamed qualified expression does not " &
                  "statically match", N);
               return;
            end if;
         end if;

         Resolve (Nam, T);

         --  If the renamed object is a function call of a limited type,
         --  the expansion of the renaming is complicated by the presence
         --  of various temporaries and subtypes that capture constraints
         --  of the renamed object. Rewrite node as an object declaration,
         --  whose expansion is simpler. Given that the object is limited
         --  there is no copy involved and no performance hit.

         if Nkind (Nam) = N_Function_Call
           and then Is_Limited_View (Etype (Nam))
           and then not Is_Constrained (Etype (Nam))
           and then Comes_From_Source (N)
         then
            Set_Etype (Id, T);
            Mutate_Ekind (Id, E_Constant);
            Rewrite (N,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Id,
                Constant_Present    => True,
                Object_Definition   => New_Occurrence_Of (Etype (Nam), Loc),
                Expression          => Relocate_Node (Nam)));
            return;
         end if;

         --  Ada 2012 (AI05-149): Reject renaming of an anonymous access object
         --  when renaming declaration has a named access type. The Ada 2012
         --  coverage rules allow an anonymous access type in the context of
         --  an expected named general access type, but the renaming rules
         --  require the types to be the same. (An exception is when the type
         --  of the renaming is also an anonymous access type, which can only
         --  happen due to a renaming created by the expander.)

         if Nkind (Nam) = N_Type_Conversion
           and then not Comes_From_Source (Nam)
           and then Is_Anonymous_Access_Type (Etype (Expression (Nam)))
           and then not Is_Anonymous_Access_Type (T)
         then
            Error_Msg_NE
              ("cannot rename anonymous access object "
                & "as a named access type", Expression (Nam), T);
         end if;

         --  Check that a class-wide object is not being renamed as an object
         --  of a specific type. The test for access types is needed to exclude
         --  cases where the renamed object is a dynamically tagged access
         --  result, such as occurs in certain expansions.

         if Is_Tagged_Type (T) then
            Check_Dynamically_Tagged_Expression
              (Expr        => Nam,
               Typ         => T,
               Related_Nod => N);
         end if;

      --  Ada 2005 (AI-230/AI-254): Access renaming

      else pragma Assert (Present (Access_Definition (N)));
         T :=
           Access_Definition
             (Related_Nod => N,
              N           => Access_Definition (N));

         Analyze (Nam);

         --  The object renaming declaration may become Ghost if it renames a
         --  Ghost entity.

         if Is_Entity_Name (Nam) then
            Mark_Ghost_Renaming (N, Entity (Nam));
         end if;

         --  Ada 2005 AI05-105: if the declaration has an anonymous access
         --  type, the renamed object must also have an anonymous type, and
         --  this is a name resolution rule. This was implicit in the last part
         --  of the first sentence in 8.5.1(3/2), and is made explicit by this
         --  recent AI.

         if not Is_Overloaded (Nam) then
            if Ekind (Etype (Nam)) /= Ekind (T) then
               Error_Msg_N
                 ("expect anonymous access type in object renaming", N);
            end if;

         else
            declare
               I    : Interp_Index;
               It   : Interp;
               Typ  : Entity_Id := Empty;
               Seen : Boolean   := False;

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

                  --  Renaming is ambiguous if more than one candidate
                  --  interpretation is type-conformant with the context.

                  if Ekind (It.Typ) = Ekind (T) then
                     if Ekind (T) = E_Anonymous_Access_Subprogram_Type
                       and then
                         Type_Conformant
                           (Designated_Type (T), Designated_Type (It.Typ))
                     then
                        if not Seen then
                           Seen := True;
                        else
                           Error_Msg_N
                             ("ambiguous expression in renaming", Nam);
                        end if;

                     elsif Ekind (T) = E_Anonymous_Access_Type
                       and then
                         Covers (Designated_Type (T), Designated_Type (It.Typ))
                     then
                        if not Seen then
                           Seen := True;
                        else
                           Error_Msg_N
                             ("ambiguous expression in renaming", Nam);
                        end if;
                     end if;

                     if Covers (T, It.Typ) then
                        Typ := It.Typ;
                        Set_Etype (Nam, Typ);
                        Set_Is_Overloaded (Nam, False);
                     end if;
                  end if;

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

         Resolve (Nam, T);

         --  Do not perform the legality checks below when the resolution of
         --  the renaming name failed because the associated type is Any_Type.

         if Etype (Nam) = Any_Type then
            null;

         --  Ada 2005 (AI-231): In the case where the type is defined by an
         --  access_definition, the renamed entity shall be of an access-to-
         --  constant type if and only if the access_definition defines an
         --  access-to-constant type. ARM 8.5.1(4)

         elsif Constant_Present (Access_Definition (N))
           and then not Is_Access_Constant (Etype (Nam))
         then
            Error_Msg_N
              ("(Ada 2005): the renamed object is not access-to-constant "
               & "(RM 8.5.1(6))", N);

         elsif not Constant_Present (Access_Definition (N))
           and then Is_Access_Constant (Etype (Nam))
         then
            Error_Msg_N
              ("(Ada 2005): the renamed object is not access-to-variable "
               & "(RM 8.5.1(6))", N);
         end if;

         if Is_Access_Subprogram_Type (Etype (Nam)) then
            Check_Subtype_Conformant
              (Designated_Type (T), Designated_Type (Etype (Nam)));

         elsif not Subtypes_Statically_Match
                     (Designated_Type (T),
                      Available_View (Designated_Type (Etype (Nam))))
         then
            Error_Msg_N
              ("subtype of renamed object does not statically match", N);
         end if;
      end if;

      --  Special processing for renaming function return object. Some errors
      --  and warnings are produced only for calls that come from source.

      if Nkind (Nam) = N_Function_Call then
         case Ada_Version is

            --  Usage is illegal in Ada 83, but renamings are also introduced
            --  during expansion, and error does not apply to those.

            when Ada_83 =>
               if Comes_From_Source (N) then
                  Error_Msg_N
                    ("(Ada 83) cannot rename function return object", Nam);
               end if;

            --  In Ada 95, warn for odd case of renaming parameterless function
            --  call if this is not a limited type (where this is useful).

            when others =>
               if Warn_On_Object_Renames_Function
                 and then No (Parameter_Associations (Nam))
                 and then not Is_Limited_Type (Etype (Nam))
                 and then Comes_From_Source (Nam)
               then
                  Error_Msg_N
                    ("renaming function result object is suspicious?R?", Nam);
                  Error_Msg_NE
                    ("\function & will be called only once?R?", Nam,
                     Entity (Name (Nam)));
                  Error_Msg_N -- CODEFIX
                    ("\suggest using an initialized constant object "
                     & "instead?R?", Nam);
               end if;
         end case;
      end if;

      Check_Constrained_Object;

      --  An object renaming requires an exact match of the type. Class-wide
      --  matching is not allowed.

      if Is_Class_Wide_Type (T)
        and then Base_Type (Etype (Nam)) /= Base_Type (T)
      then
         Wrong_Type (Nam, T);
      end if;

      --  We must search for an actual subtype here so that the bounds of
      --  objects of unconstrained types don't get dropped on the floor - such
      --  as with renamings of formal parameters.

      T2 := Get_Actual_Subtype_If_Available (Nam);

      --  Ada 2005 (AI-326): Handle wrong use of incomplete type

      if Nkind (Nam) = N_Explicit_Dereference
        and then Ekind (Etype (T2)) = E_Incomplete_Type
      then
         Error_Msg_NE ("invalid use of incomplete type&", Id, T2);
         return;

      elsif Ekind (Etype (T)) = E_Incomplete_Type then
         Error_Msg_NE ("invalid use of incomplete type&", Id, T);
         return;
      end if;

      if Ada_Version >= Ada_2005 and then Nkind (Nam) in N_Has_Entity then
         declare
            Nam_Ent  : constant Entity_Id := Entity (Get_Object_Name (Nam));
            Nam_Decl : constant Node_Id   := Declaration_Node (Nam_Ent);

         begin
            if Has_Null_Exclusion (N)
              and then not Has_Null_Exclusion (Nam_Decl)
            then
               --  Ada 2005 (AI-423): If the object name denotes a generic
               --  formal object of a generic unit G, and the object renaming
               --  declaration occurs within the body of G or within the body
               --  of a generic unit declared within the declarative region
               --  of G, then the declaration of the formal object of G must
               --  have a null exclusion or a null-excluding subtype.

               if Is_Formal_Object (Nam_Ent)
                 and then In_Generic_Scope (Id)
               then
                  if not Can_Never_Be_Null (Etype (Nam_Ent)) then
                     Error_Msg_N
                       ("object does not exclude `NULL` "
                        & "(RM 8.5.1(4.6/2))", N);

                  elsif In_Package_Body (Scope (Id)) then
                     Error_Msg_N
                       ("formal object does not have a null exclusion"
                        & "(RM 8.5.1(4.6/2))", N);
                  end if;

               --  Ada 2005 (AI-423): Otherwise, the subtype of the object name
               --  shall exclude null.

               elsif not Can_Never_Be_Null (Etype (Nam_Ent)) then
                  Error_Msg_N
                    ("object does not exclude `NULL` "
                     & "(RM 8.5.1(4.6/2))", N);

               --  An instance is illegal if it contains a renaming that
               --  excludes null, and the actual does not. The renaming
               --  declaration has already indicated that the declaration
               --  of the renamed actual in the instance will raise
               --  constraint_error.

               elsif Nkind (Nam_Decl) = N_Object_Declaration
                 and then In_Instance
                 and then
                   Present (Corresponding_Generic_Association (Nam_Decl))
                 and then Nkind (Expression (Nam_Decl)) =
                                            N_Raise_Constraint_Error
               then
                  Error_Msg_N
                    ("actual does not exclude `NULL` (RM 8.5.1(4.6/2))", N);

               --  Finally, if there is a null exclusion, the subtype mark
               --  must not be null-excluding.

               elsif No (Access_Definition (N))
                 and then Can_Never_Be_Null (T)
               then
                  Error_Msg_NE
                    ("`NOT NULL` not allowed (& already excludes null)",
                      N, T);

               end if;

            elsif Can_Never_Be_Null (T)
              and then not Can_Never_Be_Null (Etype (Nam_Ent))
            then
               Error_Msg_N
                 ("object does not exclude `NULL` (RM 8.5.1(4.6/2))", N);

            elsif Has_Null_Exclusion (N)
              and then No (Access_Definition (N))
              and then Can_Never_Be_Null (T)
            then
               Error_Msg_NE
                 ("`NOT NULL` not allowed (& already excludes null)", N, T);
            end if;
         end;
      end if;

      --  Set the Ekind of the entity, unless it has been set already, as is
      --  the case for the iteration object over a container with no variable
      --  indexing. In that case it's been marked as a constant, and we do not
      --  want to change it to a variable.

      if Ekind (Id) /= E_Constant then
         Mutate_Ekind (Id, E_Variable);
      end if;

      Init_Object_Size_Align (Id);

      --  If N comes from source then check that the original node is an
      --  object reference since there may have been several rewritting and
      --  folding. Do not do this for N_Function_Call or N_Explicit_Dereference
      --  which might correspond to rewrites of e.g. N_Selected_Component
      --  (for example Object.Method rewriting).
      --  If N does not come from source then assume the tree is properly
      --  formed and accept any object reference. In such cases we do support
      --  more cases of renamings anyway, so the actual check on which renaming
      --  is valid is better left to the code generator as a last sanity
      --  check.

      if Comes_From_Source (N) then
         if Nkind (Nam) in N_Function_Call | N_Explicit_Dereference then
            Is_Object_Ref := Is_Object_Reference (Nam);
         else
            Is_Object_Ref := Is_Object_Reference (Original_Node (Nam));
         end if;
      else
         Is_Object_Ref := True;
      end if;

      if T = Any_Type or else Etype (Nam) = Any_Type then
         return;

      --  Verify that the renamed entity is an object or function call

      elsif Is_Object_Ref then
         if Comes_From_Source (N) then
            if Is_Dependent_Component_Of_Mutable_Object (Nam) then
               Error_Msg_N
                 ("illegal renaming of discriminant-dependent component", Nam);
            end if;

            --  If the renaming comes from source and the renamed object is a
            --  dereference, then mark the prefix as needing debug information,
            --  since it might have been rewritten hence internally generated
            --  and Debug_Renaming_Declaration will link the renaming to it.

            if Nkind (Nam) = N_Explicit_Dereference
              and then Is_Entity_Name (Prefix (Nam))
            then
               Set_Debug_Info_Needed (Entity (Prefix (Nam)));
            end if;
         end if;

      --  Weird but legal, equivalent to renaming a function call. Illegal
      --  if the literal is the result of constant-folding an attribute
      --  reference that is not a function.

      elsif Is_Entity_Name (Nam)
        and then Ekind (Entity (Nam)) = E_Enumeration_Literal
        and then Nkind (Original_Node (Nam)) /= N_Attribute_Reference
      then
         null;

      --  A named number can only be renamed without a subtype mark

      elsif Nkind (Nam) in N_Real_Literal | N_Integer_Literal
        and then Present (Subtype_Mark (N))
        and then Present (Original_Entity (Nam))
      then
         Error_Msg_N ("incompatible types in renaming", Nam);

      --  AI12-0383: Names that denote values can be renamed.
      --  Ignore (accept) N_Raise_xxx_Error nodes in this context.

      elsif No_Raise_xxx_Error (Nam) = OK then
         Error_Msg_Ada_2022_Feature ("value in renaming", Sloc (Nam));
      end if;

      Set_Etype (Id, T2);

      if not Is_Variable (Nam) then
         Mutate_Ekind            (Id, E_Constant);
         Set_Never_Set_In_Source (Id, True);
         Set_Is_True_Constant    (Id, True);
      end if;

      --  The entity of the renaming declaration needs to reflect whether the
      --  renamed object is atomic, independent, volatile or VFA. These flags
      --  are set on the renamed object in the RM legality sense.

      Set_Is_Atomic (Id, Is_Atomic_Object (Nam));
      Set_Is_Independent (Id, Is_Independent_Object (Nam));
      Set_Is_Volatile (Id, Is_Volatile_Object_Ref (Nam));
      Set_Is_Volatile_Full_Access
        (Id, Is_Volatile_Full_Access_Object_Ref (Nam));

      --  Treat as volatile if we just set the Volatile flag

      if Is_Volatile (Id)

        --  Or if we are renaming an entity which was marked this way

        --  Are there more cases, e.g. X(J) where X is Treat_As_Volatile ???

        or else (Is_Entity_Name (Nam)
                  and then Treat_As_Volatile (Entity (Nam)))
      then
         Set_Treat_As_Volatile (Id, True);
      end if;

      --  Now make the link to the renamed object

      Set_Renamed_Object (Id, Nam);

      --  Implementation-defined aspect specifications can appear in a renaming
      --  declaration, but not language-defined ones. The call to procedure
      --  Analyze_Aspect_Specifications will take care of this error check.

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, Id);
      end if;

      --  Deal with dimensions

      Analyze_Dimension (N);
   end Analyze_Object_Renaming;

   ------------------------------
   -- Analyze_Package_Renaming --
   ------------------------------

   procedure Analyze_Package_Renaming (N : Node_Id) is
      New_P : constant Entity_Id := Defining_Entity (N);
      Old_P : Entity_Id;
      Spec  : Node_Id;

   begin
      if Name (N) = Error then
         return;
      end if;

      --  Check for Text_IO special unit (we may be renaming a Text_IO child)

      Check_Text_IO_Special_Unit (Name (N));

      if Current_Scope /= Standard_Standard then
         Set_Is_Pure (New_P, Is_Pure (Current_Scope));
      end if;

      Enter_Name (New_P);
      Analyze (Name (N));

      if Is_Entity_Name (Name (N)) then
         Old_P := Entity (Name (N));
      else
         Old_P := Any_Id;
      end if;

      if Etype (Old_P) = Any_Type then
         Error_Msg_N ("expect package name in renaming", Name (N));

      elsif Ekind (Old_P) /= E_Package
        and then not (Ekind (Old_P) = E_Generic_Package
                       and then In_Open_Scopes (Old_P))
      then
         if Ekind (Old_P) = E_Generic_Package then
            Error_Msg_N
               ("generic package cannot be renamed as a package", Name (N));
         else
            Error_Msg_Sloc := Sloc (Old_P);
            Error_Msg_NE
              ("expect package name in renaming, found& declared#",
               Name (N), Old_P);
         end if;

         --  Set basic attributes to minimize cascaded errors

         Mutate_Ekind (New_P, E_Package);
         Set_Etype (New_P, Standard_Void_Type);

      elsif Present (Renamed_Entity (Old_P))
        and then (From_Limited_With (Renamed_Entity (Old_P))
                    or else Has_Limited_View (Renamed_Entity (Old_P)))
        and then not
          Unit_Is_Visible (Cunit (Get_Source_Unit (Renamed_Entity (Old_P))))
      then
         Error_Msg_NE
           ("renaming of limited view of package & not usable in this context"
            & " (RM 8.5.3(3.1/2))", Name (N), Renamed_Entity (Old_P));

         --  Set basic attributes to minimize cascaded errors

         Mutate_Ekind (New_P, E_Package);
         Set_Etype (New_P, Standard_Void_Type);

      --  Here for OK package renaming

      else
         --  Entities in the old package are accessible through the renaming
         --  entity. The simplest implementation is to have both packages share
         --  the entity list.

         Mutate_Ekind (New_P, E_Package);
         Set_Etype (New_P, Standard_Void_Type);

         if Present (Renamed_Object (Old_P)) then
            Set_Renamed_Object (New_P, Renamed_Object (Old_P));
         else
            Set_Renamed_Object (New_P, Old_P);
         end if;

         --  The package renaming declaration may become Ghost if it renames a
         --  Ghost entity.

         Mark_Ghost_Renaming (N, Old_P);

         Set_Has_Completion (New_P);
         Set_First_Entity   (New_P, First_Entity (Old_P));
         Set_Last_Entity    (New_P, Last_Entity  (Old_P));
         Set_First_Private_Entity (New_P, First_Private_Entity (Old_P));
         Check_Library_Unit_Renaming (N, Old_P);
         Generate_Reference (Old_P, Name (N));

         --  If the renaming is in the visible part of a package, then we set
         --  Renamed_In_Spec for the renamed package, to prevent giving
         --  warnings about no entities referenced. Such a warning would be
         --  overenthusiastic, since clients can see entities in the renamed
         --  package via the visible package renaming.

         declare
            Ent : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
         begin
            if Ekind (Ent) = E_Package
              and then not In_Private_Part (Ent)
              and then In_Extended_Main_Source_Unit (N)
              and then Ekind (Old_P) = E_Package
            then
               Set_Renamed_In_Spec (Old_P);
            end if;
         end;

         --  If this is the renaming declaration of a package instantiation
         --  within itself, it is the declaration that ends the list of actuals
         --  for the instantiation. At this point, the subtypes that rename
         --  the actuals are flagged as generic, to avoid spurious ambiguities
         --  if the actuals for two distinct formals happen to coincide. If
         --  the actual is a private type, the subtype has a private completion
         --  that is flagged in the same fashion.

         --  Resolution is identical to what is was in the original generic.
         --  On exit from the generic instance, these are turned into regular
         --  subtypes again, so they are compatible with types in their class.

         if not Is_Generic_Instance (Old_P) then
            return;
         else
            Spec := Specification (Unit_Declaration_Node (Old_P));
         end if;

         if Nkind (Spec) = N_Package_Specification
           and then Present (Generic_Parent (Spec))
           and then Old_P = Current_Scope
           and then Chars (New_P) = Chars (Generic_Parent (Spec))
         then
            declare
               E : Entity_Id;

            begin
               E := First_Entity (Old_P);
               while Present (E) and then E /= New_P loop
                  if Is_Type (E)
                    and then Nkind (Parent (E)) = N_Subtype_Declaration
                  then
                     Set_Is_Generic_Actual_Type (E);

                     if Is_Private_Type (E)
                       and then Present (Full_View (E))
                     then
                        Set_Is_Generic_Actual_Type (Full_View (E));
                     end if;
                  end if;

                  Next_Entity (E);
               end loop;
            end;
         end if;
      end if;

      --  Implementation-defined aspect specifications can appear in a renaming
      --  declaration, but not language-defined ones. The call to procedure
      --  Analyze_Aspect_Specifications will take care of this error check.

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, New_P);
      end if;
   end Analyze_Package_Renaming;

   -------------------------------
   -- Analyze_Renamed_Character --
   -------------------------------

   procedure Analyze_Renamed_Character
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean)
   is
      C : constant Node_Id := Name (N);

   begin
      if Ekind (New_S) = E_Function then
         Resolve (C, Etype (New_S));

         if Is_Body then
            Check_Frozen_Renaming (N, New_S);
         end if;

      else
         Error_Msg_N ("character literal can only be renamed as function", N);
      end if;
   end Analyze_Renamed_Character;

   ---------------------------------
   -- Analyze_Renamed_Dereference --
   ---------------------------------

   procedure Analyze_Renamed_Dereference
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean)
   is
      Nam : constant Node_Id := Name (N);
      P   : constant Node_Id := Prefix (Nam);
      Typ : Entity_Id;
      Ind : Interp_Index;
      It  : Interp;

   begin
      if not Is_Overloaded (P) then
         if Ekind (Etype (Nam)) /= E_Subprogram_Type
           or else not Type_Conformant (Etype (Nam), New_S)
         then
            Error_Msg_N ("designated type does not match specification", P);
         else
            Resolve (P);
         end if;

         return;

      else
         Typ := Any_Type;
         Get_First_Interp (Nam, Ind, It);

         while Present (It.Nam) loop

            if Ekind (It.Nam) = E_Subprogram_Type
              and then Type_Conformant (It.Nam, New_S)
            then
               if Typ /= Any_Id then
                  Error_Msg_N ("ambiguous renaming", P);
                  return;
               else
                  Typ := It.Nam;
               end if;
            end if;

            Get_Next_Interp (Ind, It);
         end loop;

         if Typ = Any_Type then
            Error_Msg_N ("designated type does not match specification", P);
         else
            Resolve (N, Typ);

            if Is_Body then
               Check_Frozen_Renaming (N, New_S);
            end if;
         end if;
      end if;
   end Analyze_Renamed_Dereference;

   ---------------------------
   -- Analyze_Renamed_Entry --
   ---------------------------

   procedure Analyze_Renamed_Entry
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean)
   is
      Nam       : constant Node_Id := Name (N);
      Sel       : constant Node_Id := Selector_Name (Nam);
      Is_Actual : constant Boolean := Present (Corresponding_Formal_Spec (N));
      Old_S     : Entity_Id;

   begin
      if Entity (Sel) = Any_Id then

         --  Selector is undefined on prefix. Error emitted already

         Set_Has_Completion (New_S);
         return;
      end if;

      --  Otherwise find renamed entity and build body of New_S as a call to it

      Old_S := Find_Renamed_Entity (N, Selector_Name (Nam), New_S);

      if Old_S = Any_Id then
         Error_Msg_N ("no subprogram or entry matches specification",  N);
      else
         if Is_Body then
            Check_Subtype_Conformant (New_S, Old_S, N);
            Generate_Reference (New_S, Defining_Entity (N), 'b');
            Style.Check_Identifier (Defining_Entity (N), New_S);

         else
            --  Only mode conformance required for a renaming_as_declaration

            Check_Mode_Conformant (New_S, Old_S, N);
         end if;

         Inherit_Renamed_Profile (New_S, Old_S);

         --  The prefix can be an arbitrary expression that yields a task or
         --  protected object, so it must be resolved.

         if Is_Access_Type (Etype (Prefix (Nam))) then
            Insert_Explicit_Dereference (Prefix (Nam));
         end if;
         Resolve (Prefix (Nam), Scope (Old_S));
      end if;

      Set_Convention (New_S, Convention (Old_S));
      Set_Has_Completion (New_S, Inside_A_Generic);

      --  AI05-0225: If the renamed entity is a procedure or entry of a
      --  protected object, the target object must be a variable.

      if Is_Protected_Type (Scope (Old_S))
        and then Ekind (New_S) = E_Procedure
        and then not Is_Variable (Prefix (Nam))
      then
         if Is_Actual then
            Error_Msg_N
              ("target object of protected operation used as actual for "
               & "formal procedure must be a variable", Nam);
         else
            Error_Msg_N
              ("target object of protected operation renamed as procedure, "
               & "must be a variable", Nam);
         end if;
      end if;

      if Is_Body then
         Check_Frozen_Renaming (N, New_S);
      end if;
   end Analyze_Renamed_Entry;

   -----------------------------------
   -- Analyze_Renamed_Family_Member --
   -----------------------------------

   procedure Analyze_Renamed_Family_Member
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean)
   is
      Nam   : constant Node_Id := Name (N);
      P     : constant Node_Id := Prefix (Nam);
      Old_S : Entity_Id;

   begin
      if (Is_Entity_Name (P) and then Ekind (Entity (P)) = E_Entry_Family)
        or else (Nkind (P) = N_Selected_Component
                  and then Ekind (Entity (Selector_Name (P))) = E_Entry_Family)
      then
         if Is_Entity_Name (P) then
            Old_S := Entity (P);
         else
            Old_S := Entity (Selector_Name (P));
         end if;

         if not Entity_Matches_Spec (Old_S, New_S) then
            Error_Msg_N ("entry family does not match specification", N);

         elsif Is_Body then
            Check_Subtype_Conformant (New_S, Old_S, N);
            Generate_Reference (New_S, Defining_Entity (N), 'b');
            Style.Check_Identifier (Defining_Entity (N), New_S);
         end if;

      else
         Error_Msg_N ("no entry family matches specification", N);
      end if;

      Set_Has_Completion (New_S, Inside_A_Generic);

      if Is_Body then
         Check_Frozen_Renaming (N, New_S);
      end if;
   end Analyze_Renamed_Family_Member;

   -----------------------------------------
   -- Analyze_Renamed_Primitive_Operation --
   -----------------------------------------

   procedure Analyze_Renamed_Primitive_Operation
     (N       : Node_Id;
      New_S   : Entity_Id;
      Is_Body : Boolean)
   is
      Old_S : Entity_Id;
      Nam   : Entity_Id;

      function Conforms
        (Subp : Entity_Id;
         Ctyp : Conformance_Type) return Boolean;
      --  Verify that the signatures of the renamed entity and the new entity
      --  match. The first formal of the renamed entity is skipped because it
      --  is the target object in any subsequent call.

      --------------
      -- Conforms --
      --------------

      function Conforms
        (Subp : Entity_Id;
         Ctyp : Conformance_Type) return Boolean
      is
         Old_F : Entity_Id;
         New_F : Entity_Id;

      begin
         if Ekind (Subp) /= Ekind (New_S) then
            return False;
         end if;

         Old_F := Next_Formal (First_Formal (Subp));
         New_F := First_Formal (New_S);
         while Present (Old_F) and then Present (New_F) loop
            if not Conforming_Types (Etype (Old_F), Etype (New_F), Ctyp) then
               return False;
            end if;

            if Ctyp >= Mode_Conformant
              and then Ekind (Old_F) /= Ekind (New_F)
            then
               return False;
            end if;

            Next_Formal (New_F);
            Next_Formal (Old_F);
         end loop;

         return True;
      end Conforms;

   --  Start of processing for Analyze_Renamed_Primitive_Operation

   begin
      if not Is_Overloaded (Selector_Name (Name (N))) then
         Old_S := Entity (Selector_Name (Name (N)));

         if not Conforms (Old_S, Type_Conformant) then
            Old_S := Any_Id;
         end if;

      else
         --  Find the operation that matches the given signature

         declare
            It  : Interp;
            Ind : Interp_Index;

         begin
            Old_S := Any_Id;
            Get_First_Interp (Selector_Name (Name (N)), Ind, It);

            while Present (It.Nam) loop
               if Conforms (It.Nam, Type_Conformant) then
                  Old_S := It.Nam;
               end if;

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

      if Old_S = Any_Id then
         Error_Msg_N ("no subprogram or entry matches specification",  N);

      else
         if Is_Body then
            if not Conforms (Old_S, Subtype_Conformant) then
               Error_Msg_N ("subtype conformance error in renaming", N);
            end if;

            Generate_Reference (New_S, Defining_Entity (N), 'b');
            Style.Check_Identifier (Defining_Entity (N), New_S);

         else
            --  Only mode conformance required for a renaming_as_declaration

            if not Conforms (Old_S, Mode_Conformant) then
               Error_Msg_N ("mode conformance error in renaming", N);
            end if;

            --  AI12-0204: The prefix of a prefixed view that is renamed or
            --  passed as a formal subprogram must be renamable as an object.

            Nam := Prefix (Name (N));

            if Is_Object_Reference (Nam) then
               if Is_Dependent_Component_Of_Mutable_Object (Nam) then
                  Error_Msg_N
                    ("illegal renaming of discriminant-dependent component",
                     Nam);
               end if;
            else
               Error_Msg_N ("expect object name in renaming", Nam);
            end if;

            --  Enforce the rule given in (RM 6.3.1 (10.1/2)): a prefixed
            --  view of a subprogram is intrinsic, because the compiler has
            --  to generate a wrapper for any call to it. If the name in a
            --  subprogram renaming is a prefixed view, the entity is thus
            --  intrinsic, and 'Access cannot be applied to it.

            Set_Convention (New_S, Convention_Intrinsic);
         end if;

         --  Inherit_Renamed_Profile (New_S, Old_S);

         --  The prefix can be an arbitrary expression that yields an
         --  object, so it must be resolved.

         Resolve (Prefix (Name (N)));
      end if;
   end Analyze_Renamed_Primitive_Operation;

   ---------------------------------
   -- Analyze_Subprogram_Renaming --
   ---------------------------------

   procedure Analyze_Subprogram_Renaming (N : Node_Id) is
      Formal_Spec : constant Entity_Id        := Corresponding_Formal_Spec (N);
      Is_Actual   : constant Boolean          := Present (Formal_Spec);
      Nam         : constant Node_Id          := Name (N);
      Save_AV     : constant Ada_Version_Type := Ada_Version;
      Save_AVP    : constant Node_Id          := Ada_Version_Pragma;
      Save_AV_Exp : constant Ada_Version_Type := Ada_Version_Explicit;
      Spec        : constant Node_Id          := Specification (N);

      Old_S       : Entity_Id := Empty;
      Rename_Spec : Entity_Id;

      procedure Build_Class_Wide_Wrapper
        (Ren_Id  : out Entity_Id;
         Wrap_Id : out Entity_Id);
      --  Ada 2012 (AI05-0071): A generic/instance scenario involving a formal
      --  type with unknown discriminants and a generic primitive operation of
      --  the said type with a box require special processing when the actual
      --  is a class-wide type:
      --
      --    generic
      --       type Formal_Typ (<>) is private;
      --       with procedure Prim_Op (Param : Formal_Typ) is <>;
      --    package Gen is ...
      --
      --    package Inst is new Gen (Actual_Typ'Class);
      --
      --  In this case the general renaming mechanism used in the prologue of
      --  an instance no longer applies:
      --
      --    procedure Prim_Op (Param : Formal_Typ) renames Prim_Op;
      --
      --  The above is replaced the following wrapper/renaming combination:
      --
      --    procedure Wrapper (Param : Formal_Typ) is  --  wrapper
      --    begin
      --       Prim_Op (Param);                        --  primitive
      --    end Wrapper;
      --
      --    procedure Prim_Op (Param : Formal_Typ) renames Wrapper;
      --
      --  This transformation applies only if there is no explicit visible
      --  class-wide operation at the point of the instantiation. Ren_Id is
      --  the entity of the renaming declaration. When the transformation
      --  applies, Wrap_Id is the entity of the generated class-wide wrapper
      --  (or Any_Id). Otherwise, Wrap_Id is the entity of the class-wide
      --  operation.

      procedure Check_Null_Exclusion
        (Ren : Entity_Id;
         Sub : Entity_Id);
      --  Ada 2005 (AI-423): Given renaming Ren of subprogram Sub, check the
      --  following AI rules:
      --
      --    If Ren denotes a generic formal object of a generic unit G, and the
      --    renaming (or instantiation containing the actual) occurs within the
      --    body of G or within the body of a generic unit declared within the
      --    declarative region of G, then the corresponding parameter of G
      --    shall have a null_exclusion; Otherwise the subtype of the Sub's
      --    formal parameter shall exclude null.
      --
      --    Similarly for its return profile.

      procedure Check_SPARK_Primitive_Operation (Subp_Id : Entity_Id);
      --  Ensure that a SPARK renaming denoted by its entity Subp_Id does not
      --  declare a primitive operation of a tagged type (SPARK RM 6.1.1(3)).

      procedure Freeze_Actual_Profile;
      --  In Ada 2012, enforce the freezing rule concerning formal incomplete
      --  types: a callable entity freezes its profile, unless it has an
      --  incomplete untagged formal (RM 13.14(10.2/3)).

      function Has_Class_Wide_Actual return Boolean;
      --  Ada 2012 (AI05-071, AI05-0131): True if N is the renaming for a
      --  defaulted formal subprogram where the actual for the controlling
      --  formal type is class-wide.

      function Original_Subprogram (Subp : Entity_Id) return Entity_Id;
      --  Find renamed entity when the declaration is a renaming_as_body and
      --  the renamed entity may itself be a renaming_as_body. Used to enforce
      --  rule that a renaming_as_body is illegal if the declaration occurs
      --  before the subprogram it completes is frozen, and renaming indirectly
      --  renames the subprogram itself.(Defect Report 8652/0027).

      ------------------------------
      -- Build_Class_Wide_Wrapper --
      ------------------------------

      procedure Build_Class_Wide_Wrapper
        (Ren_Id  : out Entity_Id;
         Wrap_Id : out Entity_Id)
      is
         Loc : constant Source_Ptr := Sloc (N);

         function Build_Call
           (Subp_Id : Entity_Id;
            Params  : List_Id) return Node_Id;
         --  Create a dispatching call to invoke routine Subp_Id with actuals
         --  built from the parameter specifications of list Params.

         function Build_Expr_Fun_Call
           (Subp_Id : Entity_Id;
            Params  : List_Id) return Node_Id;
         --  Create a dispatching call to invoke function Subp_Id with actuals
         --  built from the parameter specifications of list Params. Return
         --  directly the call, so that it can be used inside an expression
         --  function. This is a specificity of the GNATprove mode.

         function Build_Spec (Subp_Id : Entity_Id) return Node_Id;
         --  Create a subprogram specification based on the subprogram profile
         --  of Subp_Id.

         function Find_Primitive (Typ : Entity_Id) return Entity_Id;
         --  Find a primitive subprogram of type Typ which matches the profile
         --  of the renaming declaration.

         procedure Interpretation_Error (Subp_Id : Entity_Id);
         --  Emit a continuation error message suggesting subprogram Subp_Id as
         --  a possible interpretation.

         function Is_Intrinsic_Equality (Subp_Id : Entity_Id) return Boolean;
         --  Determine whether subprogram Subp_Id denotes the intrinsic "="
         --  operator.

         function Is_Suitable_Candidate (Subp_Id : Entity_Id) return Boolean;
         --  Determine whether subprogram Subp_Id is a suitable candidate for
         --  the role of a wrapped subprogram.

         ----------------
         -- Build_Call --
         ----------------

         function Build_Call
           (Subp_Id : Entity_Id;
            Params  : List_Id) return Node_Id
         is
            Actuals  : constant List_Id := New_List;
            Call_Ref : constant Node_Id := New_Occurrence_Of (Subp_Id, Loc);
            Formal   : Node_Id;

         begin
            --  Build the actual parameters of the call

            Formal := First (Params);
            while Present (Formal) loop
               Append_To (Actuals,
                 Make_Identifier (Loc, Chars (Defining_Identifier (Formal))));
               Next (Formal);
            end loop;

            --  Generate:
            --    return Subp_Id (Actuals);

            if Ekind (Subp_Id) in E_Function | E_Operator then
               return
                 Make_Simple_Return_Statement (Loc,
                   Expression =>
                     Make_Function_Call (Loc,
                       Name                   => Call_Ref,
                       Parameter_Associations => Actuals));

            --  Generate:
            --    Subp_Id (Actuals);

            else
               return
                 Make_Procedure_Call_Statement (Loc,
                   Name                   => Call_Ref,
                   Parameter_Associations => Actuals);
            end if;
         end Build_Call;

         -------------------------
         -- Build_Expr_Fun_Call --
         -------------------------

         function Build_Expr_Fun_Call
           (Subp_Id : Entity_Id;
            Params  : List_Id) return Node_Id
         is
            Actuals  : constant List_Id := New_List;
            Call_Ref : constant Node_Id := New_Occurrence_Of (Subp_Id, Loc);
            Formal   : Node_Id;

         begin
            pragma Assert (Ekind (Subp_Id) in E_Function | E_Operator);

            --  Build the actual parameters of the call

            Formal := First (Params);
            while Present (Formal) loop
               Append_To (Actuals,
                 Make_Identifier (Loc, Chars (Defining_Identifier (Formal))));
               Next (Formal);
            end loop;

            --  Generate:
            --    Subp_Id (Actuals);

            return
              Make_Function_Call (Loc,
                Name                   => Call_Ref,
                Parameter_Associations => Actuals);
         end Build_Expr_Fun_Call;

         ----------------
         -- Build_Spec --
         ----------------

         function Build_Spec (Subp_Id : Entity_Id) return Node_Id is
            Params  : constant List_Id   := Copy_Parameter_List (Subp_Id);
            Spec_Id : constant Entity_Id :=
                        Make_Defining_Identifier (Loc,
                          Chars => New_External_Name (Chars (Subp_Id), 'R'));

         begin
            if Ekind (Formal_Spec) = E_Procedure then
               return
                 Make_Procedure_Specification (Loc,
                   Defining_Unit_Name       => Spec_Id,
                   Parameter_Specifications => Params);
            else
               return
                 Make_Function_Specification (Loc,
                   Defining_Unit_Name       => Spec_Id,
                   Parameter_Specifications => Params,
                   Result_Definition =>
                     New_Copy_Tree (Result_Definition (Spec)));
            end if;
         end Build_Spec;

         --------------------
         -- Find_Primitive --
         --------------------

         function Find_Primitive (Typ : Entity_Id) return Entity_Id is
            procedure Replace_Parameter_Types (Spec : Node_Id);
            --  Given a specification Spec, replace all class-wide parameter
            --  types with reference to type Typ.

            -----------------------------
            -- Replace_Parameter_Types --
            -----------------------------

            procedure Replace_Parameter_Types (Spec : Node_Id) is
               Formal     : Node_Id;
               Formal_Id  : Entity_Id;
               Formal_Typ : Node_Id;

            begin
               Formal := First (Parameter_Specifications (Spec));
               while Present (Formal) loop
                  Formal_Id  := Defining_Identifier (Formal);
                  Formal_Typ := Parameter_Type (Formal);

                  --  Create a new entity for each class-wide formal to prevent
                  --  aliasing with the original renaming. Replace the type of
                  --  such a parameter with the candidate type.

                  if Nkind (Formal_Typ) = N_Identifier
                    and then Is_Class_Wide_Type (Etype (Formal_Typ))
                  then
                     Set_Defining_Identifier (Formal,
                       Make_Defining_Identifier (Loc, Chars (Formal_Id)));

                     Set_Parameter_Type (Formal, New_Occurrence_Of (Typ, Loc));
                  end if;

                  Next (Formal);
               end loop;
            end Replace_Parameter_Types;

            --  Local variables

            Alt_Ren  : constant Node_Id := New_Copy_Tree (N);
            Alt_Nam  : constant Node_Id := Name (Alt_Ren);
            Alt_Spec : constant Node_Id := Specification (Alt_Ren);
            Subp_Id  : Entity_Id;

         --  Start of processing for Find_Primitive

         begin
            --  Each attempt to find a suitable primitive of a particular type
            --  operates on its own copy of the original renaming. As a result
            --  the original renaming is kept decoration and side-effect free.

            --  Inherit the overloaded status of the renamed subprogram name

            if Is_Overloaded (Nam) then
               Set_Is_Overloaded (Alt_Nam);
               Save_Interps (Nam, Alt_Nam);
            end if;

            --  The copied renaming is hidden from visibility to prevent the
            --  pollution of the enclosing context.

            Set_Defining_Unit_Name (Alt_Spec, Make_Temporary (Loc, 'R'));

            --  The types of all class-wide parameters must be changed to the
            --  candidate type.

            Replace_Parameter_Types (Alt_Spec);

            --  Try to find a suitable primitive which matches the altered
            --  profile of the renaming specification.

            Subp_Id :=
              Find_Renamed_Entity
                (N         => Alt_Ren,
                 Nam       => Name (Alt_Ren),
                 New_S     => Analyze_Subprogram_Specification (Alt_Spec),
                 Is_Actual => Is_Actual);

            --  Do not return Any_Id if the resolion of the altered profile
            --  failed as this complicates further checks on the caller side,
            --  return Empty instead.

            if Subp_Id = Any_Id then
               return Empty;
            else
               return Subp_Id;
            end if;
         end Find_Primitive;

         --------------------------
         -- Interpretation_Error --
         --------------------------

         procedure Interpretation_Error (Subp_Id : Entity_Id) is
         begin
            Error_Msg_Sloc := Sloc (Subp_Id);

            if Is_Internal (Subp_Id) then
               Error_Msg_NE
                 ("\\possible interpretation: predefined & #",
                  Spec, Formal_Spec);
            else
               Error_Msg_NE
                 ("\\possible interpretation: & defined #", Spec, Formal_Spec);
            end if;
         end Interpretation_Error;

         ---------------------------
         -- Is_Intrinsic_Equality --
         ---------------------------

         function Is_Intrinsic_Equality (Subp_Id : Entity_Id) return Boolean is
         begin
            return
              Ekind (Subp_Id) = E_Operator
                and then Chars (Subp_Id) = Name_Op_Eq
                and then Is_Intrinsic_Subprogram (Subp_Id);
         end Is_Intrinsic_Equality;

         ---------------------------
         -- Is_Suitable_Candidate --
         ---------------------------

         function Is_Suitable_Candidate (Subp_Id : Entity_Id) return Boolean is
         begin
            if No (Subp_Id) then
               return False;

            --  An intrinsic subprogram is never a good candidate. This is an
            --  indication of a missing primitive, either defined directly or
            --  inherited from a parent tagged type.

            elsif Is_Intrinsic_Subprogram (Subp_Id) then
               return False;

            else
               return True;
            end if;
         end Is_Suitable_Candidate;

         --  Local variables

         Actual_Typ : Entity_Id := Empty;
         --  The actual class-wide type for Formal_Typ

         CW_Prim_OK : Boolean;
         CW_Prim_Op : Entity_Id;
         --  The class-wide subprogram (if available) which corresponds to the
         --  renamed generic formal subprogram.

         Formal_Typ : Entity_Id := Empty;
         --  The generic formal type with unknown discriminants

         Root_Prim_OK : Boolean;
         Root_Prim_Op : Entity_Id;
         --  The root type primitive (if available) which corresponds to the
         --  renamed generic formal subprogram.

         Root_Typ : Entity_Id := Empty;
         --  The root type of Actual_Typ

         Body_Decl : Node_Id;
         Formal    : Node_Id;
         Prim_Op   : Entity_Id;
         Spec_Decl : Node_Id;
         New_Spec  : Node_Id;

      --  Start of processing for Build_Class_Wide_Wrapper

      begin
         --  Analyze the specification of the renaming in case the generation
         --  of the class-wide wrapper fails.

         Ren_Id  := Analyze_Subprogram_Specification (Spec);
         Wrap_Id := Any_Id;

         --  Do not attempt to build a wrapper if the renaming is in error

         if Error_Posted (Nam) then
            return;
         end if;

         --  Analyze the renamed name, but do not resolve it. The resolution is
         --  completed once a suitable subprogram is found.

         Analyze (Nam);

         --  When the renamed name denotes the intrinsic operator equals, the
         --  name must be treated as overloaded. This allows for a potential
         --  match against the root type's predefined equality function.

         if Is_Intrinsic_Equality (Entity (Nam)) then
            Set_Is_Overloaded (Nam);
            Collect_Interps   (Nam);
         end if;

         --  Step 1: Find the generic formal type with unknown discriminants
         --  and its corresponding class-wide actual type from the renamed
         --  generic formal subprogram.

         Formal := First_Formal (Formal_Spec);
         while Present (Formal) loop
            if Has_Unknown_Discriminants (Etype (Formal))
              and then not Is_Class_Wide_Type (Etype (Formal))
              and then Is_Class_Wide_Type (Get_Instance_Of (Etype (Formal)))
            then
               Formal_Typ := Etype (Formal);
               Actual_Typ := Get_Instance_Of (Formal_Typ);
               Root_Typ   := Etype (Actual_Typ);
               exit;
            end if;

            Next_Formal (Formal);
         end loop;

         --  The specification of the generic formal subprogram should always
         --  contain a formal type with unknown discriminants whose actual is
         --  a class-wide type, otherwise this indicates a failure in routine
         --  Has_Class_Wide_Actual.

         pragma Assert (Present (Formal_Typ));

         --  Step 2: Find the proper class-wide subprogram or primitive which
         --  corresponds to the renamed generic formal subprogram.

         CW_Prim_Op   := Find_Primitive (Actual_Typ);
         CW_Prim_OK   := Is_Suitable_Candidate (CW_Prim_Op);
         Root_Prim_Op := Find_Primitive (Root_Typ);
         Root_Prim_OK := Is_Suitable_Candidate (Root_Prim_Op);

         --  The class-wide actual type has two subprograms which correspond to
         --  the renamed generic formal subprogram:

         --    with procedure Prim_Op (Param : Formal_Typ);

         --    procedure Prim_Op (Param : Actual_Typ);  --  may be inherited
         --    procedure Prim_Op (Param : Actual_Typ'Class);

         --  Even though the declaration of the two subprograms is legal, a
         --  call to either one is ambiguous and therefore illegal.

         if CW_Prim_OK and Root_Prim_OK then

            --  A user-defined primitive has precedence over a predefined one

            if Is_Internal (CW_Prim_Op)
              and then not Is_Internal (Root_Prim_Op)
            then
               Prim_Op := Root_Prim_Op;

            elsif Is_Internal (Root_Prim_Op)
              and then not Is_Internal (CW_Prim_Op)
            then
               Prim_Op := CW_Prim_Op;

            elsif CW_Prim_Op = Root_Prim_Op then
               Prim_Op := Root_Prim_Op;

            --  Otherwise both candidate subprograms are user-defined and
            --  ambiguous.

            else
               Error_Msg_NE
                 ("ambiguous actual for generic subprogram &",
                  Spec, Formal_Spec);
               Interpretation_Error (Root_Prim_Op);
               Interpretation_Error (CW_Prim_Op);
               return;
            end if;

         elsif CW_Prim_OK and not Root_Prim_OK then
            Prim_Op := CW_Prim_Op;

         elsif not CW_Prim_OK and Root_Prim_OK then
            Prim_Op := Root_Prim_Op;

         --  An intrinsic equality may act as a suitable candidate in the case
         --  of a null type extension where the parent's equality is hidden. A
         --  call to an intrinsic equality is expanded as dispatching.

         elsif Present (Root_Prim_Op)
           and then Is_Intrinsic_Equality (Root_Prim_Op)
         then
            Prim_Op := Root_Prim_Op;

         --  Otherwise there are no candidate subprograms. Let the caller
         --  diagnose the error.

         else
            return;
         end if;

         --  At this point resolution has taken place and the name is no longer
         --  overloaded. Mark the primitive as referenced.

         Set_Is_Overloaded (Name (N), False);
         Set_Referenced    (Prim_Op);

         --  Do not generate a wrapper when the only candidate is a class-wide
         --  subprogram. Instead modify the renaming to directly map the actual
         --  to the generic formal.

         if CW_Prim_OK and then Prim_Op = CW_Prim_Op then
            Wrap_Id := Prim_Op;
            Rewrite (Nam, New_Occurrence_Of (Prim_Op, Loc));
            return;
         end if;

         --  Step 3: Create the declaration and the body of the wrapper, insert
         --  all the pieces into the tree.

         --  In GNATprove mode, create a function wrapper in the form of an
         --  expression function, so that an implicit postcondition relating
         --  the result of calling the wrapper function and the result of the
         --  dispatching call to the wrapped function is known during proof.

         if GNATprove_Mode
           and then Ekind (Ren_Id) in E_Function | E_Operator
         then
            New_Spec := Build_Spec (Ren_Id);
            Body_Decl :=
              Make_Expression_Function (Loc,
                Specification => New_Spec,
                Expression    =>
                  Build_Expr_Fun_Call
                    (Subp_Id => Prim_Op,
                     Params  => Parameter_Specifications (New_Spec)));

            Wrap_Id := Defining_Entity (Body_Decl);

         --  Otherwise, create separate spec and body for the subprogram

         else
            Spec_Decl :=
              Make_Subprogram_Declaration (Loc,
                Specification => Build_Spec (Ren_Id));
            Insert_Before_And_Analyze (N, Spec_Decl);

            Wrap_Id := Defining_Entity (Spec_Decl);

            Body_Decl :=
              Make_Subprogram_Body (Loc,
                Specification              => Build_Spec (Ren_Id),
                Declarations               => New_List,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => New_List (
                      Build_Call
                        (Subp_Id => Prim_Op,
                         Params  =>
                           Parameter_Specifications
                             (Specification (Spec_Decl))))));

            Set_Corresponding_Body (Spec_Decl, Defining_Entity (Body_Decl));
         end if;

         --  If the operator carries an Eliminated pragma, indicate that the
         --  wrapper is also to be eliminated, to prevent spurious error when
         --  using gnatelim on programs that include box-initialization of
         --  equality operators.

         Set_Is_Eliminated (Wrap_Id, Is_Eliminated (Prim_Op));

         --  In GNATprove mode, insert the body in the tree for analysis

         if GNATprove_Mode then
            Insert_Before_And_Analyze (N, Body_Decl);
         end if;

         --  The generated body does not freeze and must be analyzed when the
         --  class-wide wrapper is frozen. The body is only needed if expansion
         --  is enabled.

         if Expander_Active then
            Append_Freeze_Action (Wrap_Id, Body_Decl);
         end if;

         --  Step 4: The subprogram renaming aliases the wrapper

         Rewrite (Nam, New_Occurrence_Of (Wrap_Id, Loc));
      end Build_Class_Wide_Wrapper;

      --------------------------
      -- Check_Null_Exclusion --
      --------------------------

      procedure Check_Null_Exclusion
        (Ren : Entity_Id;
         Sub : Entity_Id)
      is
         Ren_Formal : Entity_Id;
         Sub_Formal : Entity_Id;

         function Null_Exclusion_Mismatch
           (Renaming : Entity_Id; Renamed : Entity_Id) return Boolean;
         --  Return True if there is a null exclusion mismatch between
         --  Renaming and Renamed, False otherwise.

         -----------------------------
         -- Null_Exclusion_Mismatch --
         -----------------------------

         function Null_Exclusion_Mismatch
           (Renaming : Entity_Id; Renamed : Entity_Id) return Boolean is
         begin
            return Has_Null_Exclusion (Parent (Renaming))
              and then
                not (Has_Null_Exclusion (Parent (Renamed))
                      or else (Can_Never_Be_Null (Etype (Renamed))
                                and then not
                                  (Is_Formal_Subprogram (Sub)
                                   and then In_Generic_Body (Current_Scope))));
         end Null_Exclusion_Mismatch;

      begin
         --  Parameter check

         Ren_Formal := First_Formal (Ren);
         Sub_Formal := First_Formal (Sub);
         while Present (Ren_Formal) and then Present (Sub_Formal) loop
            if Null_Exclusion_Mismatch (Ren_Formal, Sub_Formal) then
               Error_Msg_Sloc := Sloc (Sub_Formal);
               Error_Msg_NE
                 ("`NOT NULL` required for parameter &#",
                  Ren_Formal, Sub_Formal);
            end if;

            Next_Formal (Ren_Formal);
            Next_Formal (Sub_Formal);
         end loop;

         --  Return profile check

         if Nkind (Parent (Ren)) = N_Function_Specification
           and then Nkind (Parent (Sub)) = N_Function_Specification
           and then Null_Exclusion_Mismatch (Ren, Sub)
         then
            Error_Msg_Sloc := Sloc (Sub);
            Error_Msg_N ("return must specify `NOT NULL`#", Ren);
         end if;
      end Check_Null_Exclusion;

      -------------------------------------
      -- Check_SPARK_Primitive_Operation --
      -------------------------------------

      procedure Check_SPARK_Primitive_Operation (Subp_Id : Entity_Id) is
         Prag : constant Node_Id := SPARK_Pragma (Subp_Id);
         Typ  : Entity_Id;

      begin
         --  Nothing to do when the subprogram is not subject to SPARK_Mode On
         --  because this check applies to SPARK code only.

         if not (Present (Prag)
                  and then Get_SPARK_Mode_From_Annotation (Prag) = On)
         then
            return;

         --  Nothing to do when the subprogram is not a primitive operation

         elsif not Is_Primitive (Subp_Id) then
            return;
         end if;

         Typ := Find_Dispatching_Type (Subp_Id);

         --  Nothing to do when the subprogram is a primitive operation of an
         --  untagged type.

         if No (Typ) then
            return;
         end if;

         --  At this point a renaming declaration introduces a new primitive
         --  operation for a tagged type.

         Error_Msg_Node_2 := Typ;
         Error_Msg_NE
           ("subprogram renaming & cannot declare primitive for type & "
            & "(SPARK RM 6.1.1(3))", N, Subp_Id);
      end Check_SPARK_Primitive_Operation;

      ---------------------------
      -- Freeze_Actual_Profile --
      ---------------------------

      procedure Freeze_Actual_Profile is
         F                  : Entity_Id;
         Has_Untagged_Inc   : Boolean;
         Instantiation_Node : constant Node_Id := Parent (N);

      begin
         if Ada_Version >= Ada_2012 then
            F := First_Formal (Formal_Spec);
            Has_Untagged_Inc := False;
            while Present (F) loop
               if Ekind (Etype (F)) = E_Incomplete_Type
                 and then not Is_Tagged_Type (Etype (F))
               then
                  Has_Untagged_Inc := True;
                  exit;
               end if;

               Next_Formal (F);
            end loop;

            if Ekind (Formal_Spec) = E_Function
              and then not Is_Tagged_Type (Etype (Formal_Spec))
            then
               Has_Untagged_Inc := True;
            end if;

            if not Has_Untagged_Inc then
               F := First_Formal (Old_S);
               while Present (F) loop
                  Freeze_Before (Instantiation_Node, Etype (F));

                  if Is_Incomplete_Or_Private_Type (Etype (F))
                    and then No (Underlying_Type (Etype (F)))
                  then
                     --  Exclude generic types, or types derived  from them.
                     --  They will be frozen in the enclosing instance.

                     if Is_Generic_Type (Etype (F))
                       or else Is_Generic_Type (Root_Type (Etype (F)))
                     then
                        null;

                     --  A limited view of a type declared elsewhere needs no
                     --  freezing actions.

                     elsif From_Limited_With (Etype (F)) then
                        null;

                     else
                        Error_Msg_NE
                          ("type& must be frozen before this point",
                           Instantiation_Node, Etype (F));
                     end if;
                  end if;

                  Next_Formal (F);
               end loop;
            end if;
         end if;
      end Freeze_Actual_Profile;

      ---------------------------
      -- Has_Class_Wide_Actual --
      ---------------------------

      function Has_Class_Wide_Actual return Boolean is
         Formal     : Entity_Id;
         Formal_Typ : Entity_Id;

      begin
         if Is_Actual then
            Formal := First_Formal (Formal_Spec);
            while Present (Formal) loop
               Formal_Typ := Etype (Formal);

               if Has_Unknown_Discriminants (Formal_Typ)
                 and then not Is_Class_Wide_Type (Formal_Typ)
                 and then Is_Class_Wide_Type (Get_Instance_Of (Formal_Typ))
               then
                  return True;
               end if;

               Next_Formal (Formal);
            end loop;
         end if;

         return False;
      end Has_Class_Wide_Actual;

      -------------------------
      -- Original_Subprogram --
      -------------------------

      function Original_Subprogram (Subp : Entity_Id) return Entity_Id is
         Orig_Decl : Node_Id;
         Orig_Subp : Entity_Id;

      begin
         --  First case: renamed entity is itself a renaming

         if Present (Alias (Subp)) then
            return Alias (Subp);

         elsif Nkind (Unit_Declaration_Node (Subp)) = N_Subprogram_Declaration
           and then Present (Corresponding_Body (Unit_Declaration_Node (Subp)))
         then
            --  Check if renamed entity is a renaming_as_body

            Orig_Decl :=
              Unit_Declaration_Node
                (Corresponding_Body (Unit_Declaration_Node (Subp)));

            if Nkind (Orig_Decl) = N_Subprogram_Renaming_Declaration then
               Orig_Subp := Entity (Name (Orig_Decl));

               if Orig_Subp = Rename_Spec then

                  --  Circularity detected

                  return Orig_Subp;

               else
                  return (Original_Subprogram (Orig_Subp));
               end if;
            else
               return Subp;
            end if;
         else
            return Subp;
         end if;
      end Original_Subprogram;

      --  Local variables

      CW_Actual : constant Boolean := Has_Class_Wide_Actual;
      --  Ada 2012 (AI05-071, AI05-0131): True if the renaming is for a
      --  defaulted formal subprogram when the actual for a related formal
      --  type is class-wide.

      Inst_Node : Node_Id := Empty;
      New_S     : Entity_Id;

   --  Start of processing for Analyze_Subprogram_Renaming

   begin
      --  We must test for the attribute renaming case before the Analyze
      --  call because otherwise Sem_Attr will complain that the attribute
      --  is missing an argument when it is analyzed.

      if Nkind (Nam) = N_Attribute_Reference then

         --  In the case of an abstract formal subprogram association, rewrite
         --  an actual given by a stream or Put_Image attribute as the name of
         --  the corresponding stream or Put_Image primitive of the type.

         --  In a generic context the stream and Put_Image operations are not
         --  generated, and this must be treated as a normal attribute
         --  reference, to be expanded in subsequent instantiations.

         if Is_Actual
           and then Is_Abstract_Subprogram (Formal_Spec)
           and then Expander_Active
         then
            declare
               Prefix_Type : constant Entity_Id := Entity (Prefix (Nam));
               Prim : Entity_Id;

            begin
               --  The class-wide forms of the stream and Put_Image attributes
               --  are not primitive dispatching operations (even though they
               --  internally dispatch).

               if Is_Class_Wide_Type (Prefix_Type) then
                  Error_Msg_N
                    ("attribute must be a primitive dispatching operation",
                     Nam);
                  return;
               end if;

               --  Retrieve the primitive subprogram associated with the
               --  attribute. This can only be a stream attribute, since those
               --  are the only ones that are dispatching (and the actual for
               --  an abstract formal subprogram must be dispatching
               --  operation).

               case Attribute_Name (Nam) is
                  when Name_Input =>
                     Prim :=
                       Find_Optional_Prim_Op (Prefix_Type, TSS_Stream_Input);

                  when Name_Output =>
                     Prim :=
                       Find_Optional_Prim_Op (Prefix_Type, TSS_Stream_Output);

                  when Name_Read =>
                     Prim :=
                       Find_Optional_Prim_Op (Prefix_Type, TSS_Stream_Read);

                  when Name_Write =>
                     Prim :=
                       Find_Optional_Prim_Op (Prefix_Type, TSS_Stream_Write);

                  when Name_Put_Image =>
                     Prim :=
                       Find_Optional_Prim_Op (Prefix_Type, TSS_Put_Image);

                  when others =>
                     Error_Msg_N
                       ("attribute must be a primitive dispatching operation",
                        Nam);
                     return;
               end case;

               --  If no stream operation was found, and the type is limited,
               --  the user should have defined one. This rule does not apply
               --  to Put_Image.

               if No (Prim)
                 and then Attribute_Name (Nam) /= Name_Put_Image
               then
                  if Is_Limited_Type (Prefix_Type) then
                     Error_Msg_NE
                      ("stream operation not defined for type&",
                        N, Prefix_Type);
                     return;

                  --  Otherwise, compiler should have generated default

                  else
                     raise Program_Error;
                  end if;
               end if;

               --  Rewrite the attribute into the name of its corresponding
               --  primitive dispatching subprogram. We can then proceed with
               --  the usual processing for subprogram renamings.

               declare
                  Prim_Name : constant Node_Id :=
                                Make_Identifier (Sloc (Nam),
                                  Chars => Chars (Prim));
               begin
                  Set_Entity (Prim_Name, Prim);
                  Rewrite (Nam, Prim_Name);
                  Analyze (Nam);
               end;
            end;

         --  Normal processing for a renaming of an attribute

         else
            Attribute_Renaming (N);
            return;
         end if;
      end if;

      --  Check whether this declaration corresponds to the instantiation of a
      --  formal subprogram.

      --  If this is an instantiation, the corresponding actual is frozen and
      --  error messages can be made more precise. If this is a default
      --  subprogram, the entity is already established in the generic, and is
      --  not retrieved by visibility. If it is a default with a box, the
      --  candidate interpretations, if any, have been collected when building
      --  the renaming declaration. If overloaded, the proper interpretation is
      --  determined in Find_Renamed_Entity. If the entity is an operator,
      --  Find_Renamed_Entity applies additional visibility checks.

      if Is_Actual then
         Inst_Node := Unit_Declaration_Node (Formal_Spec);

         --  Check whether the renaming is for a defaulted actual subprogram
         --  with a class-wide actual.

         if CW_Actual and then Box_Present (Inst_Node) then
            Build_Class_Wide_Wrapper (New_S, Old_S);

         elsif Is_Entity_Name (Nam)
           and then Present (Entity (Nam))
           and then not Comes_From_Source (Nam)
           and then not Is_Overloaded (Nam)
         then
            Old_S := Entity (Nam);

            --  The subprogram renaming declaration may become Ghost if it
            --  renames a Ghost entity.

            Mark_Ghost_Renaming (N, Old_S);

            New_S := Analyze_Subprogram_Specification (Spec);

            --  Operator case

            if Ekind (Old_S) = E_Operator then

               --  Box present

               if Box_Present (Inst_Node) then
                  Old_S := Find_Renamed_Entity (N, Name (N), New_S, Is_Actual);

               --  If there is an immediately visible homonym of the operator
               --  and the declaration has a default, this is worth a warning
               --  because the user probably did not intend to get the pre-
               --  defined operator, visible in the generic declaration. To
               --  find if there is an intended candidate, analyze the renaming
               --  again in the current context.

               elsif Scope (Old_S) = Standard_Standard
                 and then Present (Default_Name (Inst_Node))
               then
                  declare
                     Decl   : constant Node_Id := New_Copy_Tree (N);
                     Hidden : Entity_Id;

                  begin
                     Set_Entity (Name (Decl), Empty);
                     Analyze (Name (Decl));
                     Hidden :=
                       Find_Renamed_Entity (Decl, Name (Decl), New_S, True);

                     if Present (Hidden)
                       and then In_Open_Scopes (Scope (Hidden))
                       and then Is_Immediately_Visible (Hidden)
                       and then Comes_From_Source (Hidden)
                       and then Hidden /= Old_S
                     then
                        Error_Msg_Sloc := Sloc (Hidden);
                        Error_Msg_N
                          ("default subprogram is resolved in the generic "
                           & "declaration (RM 12.6(17))??", N);
                        Error_Msg_NE ("\and will not use & #??", N, Hidden);
                     end if;
                  end;
               end if;
            end if;

         else
            Analyze (Nam);

            --  The subprogram renaming declaration may become Ghost if it
            --  renames a Ghost entity.

            if Is_Entity_Name (Nam) then
               Mark_Ghost_Renaming (N, Entity (Nam));
            end if;

            New_S := Analyze_Subprogram_Specification (Spec);
         end if;

      else
         --  Renamed entity must be analyzed first, to avoid being hidden by
         --  new name (which might be the same in a generic instance).

         Analyze (Nam);

         --  The subprogram renaming declaration may become Ghost if it renames
         --  a Ghost entity.

         if Is_Entity_Name (Nam) then
            Mark_Ghost_Renaming (N, Entity (Nam));
         end if;

         --  The renaming defines a new overloaded entity, which is analyzed
         --  like a subprogram declaration.

         New_S := Analyze_Subprogram_Specification (Spec);
      end if;

      if Current_Scope /= Standard_Standard then
         Set_Is_Pure (New_S, Is_Pure (Current_Scope));
      end if;

      --  Set SPARK mode from current context

      Set_SPARK_Pragma           (New_S, SPARK_Mode_Pragma);
      Set_SPARK_Pragma_Inherited (New_S);

      Rename_Spec := Find_Corresponding_Spec (N);

      --  Case of Renaming_As_Body

      if Present (Rename_Spec) then
         Check_Previous_Null_Procedure (N, Rename_Spec);

         --  Renaming declaration is the completion of the declaration of
         --  Rename_Spec. We build an actual body for it at the freezing point.

         Set_Corresponding_Spec (N, Rename_Spec);

         --  Deal with special case of stream functions of abstract types
         --  and interfaces.

         if Nkind (Unit_Declaration_Node (Rename_Spec)) =
                                     N_Abstract_Subprogram_Declaration
         then
            --  Input stream functions are abstract if the object type is
            --  abstract. Similarly, all default stream functions for an
            --  interface type are abstract. However, these subprograms may
            --  receive explicit declarations in representation clauses, making
            --  the attribute subprograms usable as defaults in subsequent
            --  type extensions.
            --  In this case we rewrite the declaration to make the subprogram
            --  non-abstract. We remove the previous declaration, and insert
            --  the new one at the point of the renaming, to prevent premature
            --  access to unfrozen types. The new declaration reuses the
            --  specification of the previous one, and must not be analyzed.

            pragma Assert
              (Is_Primitive (Entity (Nam))
                and then
                  Is_Abstract_Type (Find_Dispatching_Type (Entity (Nam))));
            declare
               Old_Decl : constant Node_Id :=
                            Unit_Declaration_Node (Rename_Spec);
               New_Decl : constant Node_Id :=
                            Make_Subprogram_Declaration (Sloc (N),
                              Specification =>
                                Relocate_Node (Specification (Old_Decl)));
            begin
               Remove (Old_Decl);
               Insert_After (N, New_Decl);
               Set_Is_Abstract_Subprogram (Rename_Spec, False);
               Set_Analyzed (New_Decl);
            end;
         end if;

         Set_Corresponding_Body (Unit_Declaration_Node (Rename_Spec), New_S);

         if Ada_Version = Ada_83 and then Comes_From_Source (N) then
            Error_Msg_N ("(Ada 83) renaming cannot serve as a body", N);
         end if;

         Set_Convention (New_S, Convention (Rename_Spec));
         Check_Fully_Conformant (New_S, Rename_Spec);
         Set_Public_Status (New_S);

         if No_Return (Rename_Spec)
           and then not No_Return (Entity (Nam))
         then
            Error_Msg_NE
              ("renamed subprogram & must be No_Return", N, Entity (Nam));
            Error_Msg_N
              ("\since renaming subprogram is No_Return (RM 6.5.1(7/2))", N);
         end if;

         --  The specification does not introduce new formals, but only
         --  repeats the formals of the original subprogram declaration.
         --  For cross-reference purposes, and for refactoring tools, we
         --  treat the formals of the renaming declaration as body formals.

         Reference_Body_Formals (Rename_Spec, New_S);

         --  Indicate that the entity in the declaration functions like the
         --  corresponding body, and is not a new entity. The body will be
         --  constructed later at the freeze point, so indicate that the
         --  completion has not been seen yet.

         Reinit_Field_To_Zero (New_S, F_Has_Out_Or_In_Out_Parameter);
         Reinit_Field_To_Zero (New_S, F_Needs_No_Actuals,
           Old_Ekind => (E_Function | E_Procedure => True, others => False));
         Mutate_Ekind (New_S, E_Subprogram_Body);
         New_S := Rename_Spec;
         Set_Has_Completion (Rename_Spec, False);

         --  Ada 2005: check overriding indicator

         if Present (Overridden_Operation (Rename_Spec)) then
            if Must_Not_Override (Specification (N)) then
               Error_Msg_NE
                 ("subprogram& overrides inherited operation",
                    N, Rename_Spec);

            elsif Style_Check
              and then not Must_Override (Specification (N))
            then
               Style.Missing_Overriding (N, Rename_Spec);
            end if;

         elsif Must_Override (Specification (N))
           and then not Can_Override_Operator (Rename_Spec)
         then
            Error_Msg_NE ("subprogram& is not overriding", N, Rename_Spec);
         end if;

         --  AI12-0132: a renames-as-body freezes the expression of any
         --  expression function that it renames.

         if Is_Entity_Name (Nam)
           and then Is_Expression_Function (Entity (Nam))
           and then not Inside_A_Generic
         then
            Freeze_Expr_Types
              (Def_Id => Entity (Nam),
               Typ    => Etype (Entity (Nam)),
               Expr   =>
                 Expression
                   (Original_Node (Unit_Declaration_Node (Entity (Nam)))),
               N      => N);
         end if;

      --  Normal subprogram renaming (not renaming as body)

      else
         Generate_Definition (New_S);
         New_Overloaded_Entity (New_S);

         if not (Is_Entity_Name (Nam)
                  and then Is_Intrinsic_Subprogram (Entity (Nam)))
         then
            Check_Delayed_Subprogram (New_S);
         end if;

         --  Verify that a SPARK renaming does not declare a primitive
         --  operation of a tagged type.

         Check_SPARK_Primitive_Operation (New_S);
      end if;

      --  There is no need for elaboration checks on the new entity, which may
      --  be called before the next freezing point where the body will appear.
      --  Elaboration checks refer to the real entity, not the one created by
      --  the renaming declaration.

      Set_Kill_Elaboration_Checks (New_S, True);

      --  If we had a previous error, indicate a completion is present to stop
      --  junk cascaded messages, but don't take any further action.

      if Etype (Nam) = Any_Type then
         Set_Has_Completion (New_S);
         return;

      --  Case where name has the form of a selected component

      elsif Nkind (Nam) = N_Selected_Component then

         --  A name which has the form A.B can designate an entry of task A, a
         --  protected operation of protected object A, or finally a primitive
         --  operation of object A. In the later case, A is an object of some
         --  tagged type, or an access type that denotes one such. To further
         --  distinguish these cases, note that the scope of a task entry or
         --  protected operation is type of the prefix.

         --  The prefix could be an overloaded function call that returns both
         --  kinds of operations. This overloading pathology is left to the
         --  dedicated reader ???

         declare
            T : constant Entity_Id := Etype (Prefix (Nam));

         begin
            if Present (T)
              and then
                (Is_Tagged_Type (T)
                  or else
                    (Is_Access_Type (T)
                      and then Is_Tagged_Type (Designated_Type (T))))
              and then Scope (Entity (Selector_Name (Nam))) /= T
            then
               Analyze_Renamed_Primitive_Operation
                 (N, New_S, Present (Rename_Spec));
               return;

            else
               --  Renamed entity is an entry or protected operation. For those
               --  cases an explicit body is built (at the point of freezing of
               --  this entity) that contains a call to the renamed entity.

               --  This is not allowed for renaming as body if the renamed
               --  spec is already frozen (see RM 8.5.4(5) for details).

               if Present (Rename_Spec) and then Is_Frozen (Rename_Spec) then
                  Error_Msg_N
                    ("renaming-as-body cannot rename entry as subprogram", N);
                  Error_Msg_NE
                    ("\since & is already frozen (RM 8.5.4(5))",
                     N, Rename_Spec);
               else
                  Analyze_Renamed_Entry (N, New_S, Present (Rename_Spec));
               end if;

               return;
            end if;
         end;

      --  Case where name is an explicit dereference X.all

      elsif Nkind (Nam) = N_Explicit_Dereference then

         --  Renamed entity is designated by access_to_subprogram expression.
         --  Must build body to encapsulate call, as in the entry case.

         Analyze_Renamed_Dereference (N, New_S, Present (Rename_Spec));
         return;

      --  Indexed component

      elsif Nkind (Nam) = N_Indexed_Component then
         Analyze_Renamed_Family_Member (N, New_S, Present (Rename_Spec));
         return;

      --  Character literal

      elsif Nkind (Nam) = N_Character_Literal then
         Analyze_Renamed_Character (N, New_S, Present (Rename_Spec));
         return;

      --  Only remaining case is where we have a non-entity name, or a renaming
      --  of some other non-overloadable entity.

      elsif not Is_Entity_Name (Nam)
        or else not Is_Overloadable (Entity (Nam))
      then
         --  Do not mention the renaming if it comes from an instance

         if not Is_Actual then
            Error_Msg_N ("expect valid subprogram name in renaming", N);
         else
            Error_Msg_NE ("no visible subprogram for formal&", N, Nam);
         end if;

         return;
      end if;

      --  Find the renamed entity that matches the given specification. Disable
      --  Ada_83 because there is no requirement of full conformance between
      --  renamed entity and new entity, even though the same circuit is used.

      --  This is a bit of an odd case, which introduces a really irregular use
      --  of Ada_Version[_Explicit]. Would be nice to find cleaner way to do
      --  this. ???

      Ada_Version := Ada_Version_Type'Max (Ada_Version, Ada_95);
      Ada_Version_Pragma := Empty;
      Ada_Version_Explicit := Ada_Version;

      if No (Old_S) then
         Old_S := Find_Renamed_Entity (N, Name (N), New_S, Is_Actual);

         --  The visible operation may be an inherited abstract operation that
         --  was overridden in the private part, in which case a call will
         --  dispatch to the overriding operation. Use the overriding one in
         --  the renaming declaration, to prevent spurious errors below.

         if Is_Overloadable (Old_S)
           and then Is_Abstract_Subprogram (Old_S)
           and then No (DTC_Entity (Old_S))
           and then Present (Alias (Old_S))
           and then not Is_Abstract_Subprogram (Alias (Old_S))
           and then Present (Overridden_Operation (Alias (Old_S)))
         then
            Old_S := Alias (Old_S);
         end if;

         --  When the renamed subprogram is overloaded and used as an actual
         --  of a generic, its entity is set to the first available homonym.
         --  We must first disambiguate the name, then set the proper entity.

         if Is_Actual and then Is_Overloaded (Nam) then
            Set_Entity (Nam, Old_S);
         end if;
      end if;

      --  Most common case: subprogram renames subprogram. No body is generated
      --  in this case, so we must indicate the declaration is complete as is.
      --  and inherit various attributes of the renamed subprogram.

      if No (Rename_Spec) then
         Set_Has_Completion   (New_S);
         Set_Is_Imported      (New_S, Is_Imported      (Entity (Nam)));
         Set_Is_Pure          (New_S, Is_Pure          (Entity (Nam)));
         Set_Is_Preelaborated (New_S, Is_Preelaborated (Entity (Nam)));

         --  Ada 2005 (AI-423): Check the consistency of null exclusions
         --  between a subprogram and its correct renaming.

         --  Note: the Any_Id check is a guard that prevents compiler crashes
         --  when performing a null exclusion check between a renaming and a
         --  renamed subprogram that has been found to be illegal.

         if Ada_Version >= Ada_2005 and then Entity (Nam) /= Any_Id then
            Check_Null_Exclusion
              (Ren => New_S,
               Sub => Entity (Nam));
         end if;

         --  Enforce the Ada 2005 rule that the renamed entity cannot require
         --  overriding. The flag Requires_Overriding is set very selectively
         --  and misses some other illegal cases. The additional conditions
         --  checked below are sufficient but not necessary ???

         --  The rule does not apply to the renaming generated for an actual
         --  subprogram in an instance.

         if Is_Actual then
            null;

         --  Guard against previous errors, and omit renamings of predefined
         --  operators.

         elsif Ekind (Old_S) not in E_Function | E_Procedure then
            null;

         elsif Requires_Overriding (Old_S)
           or else
             (Is_Abstract_Subprogram (Old_S)
               and then Present (Find_Dispatching_Type (Old_S))
               and then not Is_Abstract_Type (Find_Dispatching_Type (Old_S)))
         then
            Error_Msg_N
              ("renamed entity cannot be subprogram that requires overriding "
               & "(RM 8.5.4 (5.1))", N);
         end if;

         declare
            Prev : constant Entity_Id := Overridden_Operation (New_S);
         begin
            if Present (Prev)
              and then
                (Has_Non_Trivial_Precondition (Prev)
                  or else Has_Non_Trivial_Precondition (Old_S))
            then
               Error_Msg_NE
                 ("conflicting inherited classwide preconditions in renaming "
                  & "of& (RM 6.1.1 (17)", N, Old_S);
            end if;
         end;
      end if;

      if Old_S /= Any_Id then
         if Is_Actual and then From_Default (N) then

            --  This is an implicit reference to the default actual

            Generate_Reference (Old_S, Nam, Typ => 'i', Force => True);

         else
            Generate_Reference (Old_S, Nam);
         end if;

         Check_Internal_Protected_Use (N, Old_S);

         --  For a renaming-as-body, require subtype conformance, but if the
         --  declaration being completed has not been frozen, then inherit the
         --  convention of the renamed subprogram prior to checking conformance
         --  (unless the renaming has an explicit convention established; the
         --  rule stated in the RM doesn't seem to address this ???).

         if Present (Rename_Spec) then
            Generate_Reference (Rename_Spec, Defining_Entity (Spec), 'b');
            Style.Check_Identifier (Defining_Entity (Spec), Rename_Spec);

            if not Is_Frozen (Rename_Spec) then
               if not Has_Convention_Pragma (Rename_Spec) then
                  Set_Convention (New_S, Convention (Old_S));
               end if;

               if Ekind (Old_S) /= E_Operator then
                  Check_Mode_Conformant (New_S, Old_S, Spec);
               end if;

               if Original_Subprogram (Old_S) = Rename_Spec then
                  Error_Msg_N ("unfrozen subprogram cannot rename itself", N);
               else
                  Check_Formal_Subprogram_Conformance (New_S, Old_S, Spec);
               end if;
            else
               Check_Subtype_Conformant (New_S, Old_S, Spec);
            end if;

            Check_Frozen_Renaming (N, Rename_Spec);

            --  Check explicitly that renamed entity is not intrinsic, because
            --  in a generic the renamed body is not built. In this case,
            --  the renaming_as_body is a completion.

            if Inside_A_Generic then
               if Is_Frozen (Rename_Spec)
                 and then Is_Intrinsic_Subprogram (Old_S)
               then
                  Error_Msg_N
                    ("subprogram in renaming_as_body cannot be intrinsic",
                     Name (N));
               end if;

               Set_Has_Completion (Rename_Spec);
            end if;

         elsif Ekind (Old_S) /= E_Operator then

            --  If this a defaulted subprogram for a class-wide actual there is
            --  no check for mode conformance,  given that the signatures don't
            --  match (the source mentions T but the actual mentions T'Class).

            if CW_Actual then
               null;

            --  No need for a redundant error message if this is a nested
            --  instance, unless the current instantiation (of a child unit)
            --  is a compilation unit, which is not analyzed when the parent
            --  generic is analyzed.

            elsif not Is_Actual
               or else No (Enclosing_Instance)
               or else Is_Compilation_Unit (Current_Scope)
            then
               Check_Mode_Conformant (New_S, Old_S);
            end if;
         end if;

         if No (Rename_Spec) then

            --  The parameter profile of the new entity is that of the renamed
            --  entity: the subtypes given in the specification are irrelevant.

            Inherit_Renamed_Profile (New_S, Old_S);

            --  A call to the subprogram is transformed into a call to the
            --  renamed entity. This is transitive if the renamed entity is
            --  itself a renaming.

            if Present (Alias (Old_S)) then
               Set_Alias (New_S, Alias (Old_S));
            else
               Set_Alias (New_S, Old_S);
            end if;

            --  Note that we do not set Is_Intrinsic_Subprogram if we have a
            --  renaming as body, since the entity in this case is not an
            --  intrinsic (it calls an intrinsic, but we have a real body for
            --  this call, and it is in this body that the required intrinsic
            --  processing will take place).

            --  Also, if this is a renaming of inequality, the renamed operator
            --  is intrinsic, but what matters is the corresponding equality
            --  operator, which may be user-defined.

            Set_Is_Intrinsic_Subprogram
              (New_S,
               Is_Intrinsic_Subprogram (Old_S)
                 and then
                   (Chars (Old_S) /= Name_Op_Ne
                     or else Ekind (Old_S) = E_Operator
                     or else Is_Intrinsic_Subprogram
                               (Corresponding_Equality (Old_S))));

            if Ekind (Alias (New_S)) = E_Operator then
               Set_Has_Delayed_Freeze (New_S, False);
            end if;

            --  If the renaming corresponds to an association for an abstract
            --  formal subprogram, then various attributes must be set to
            --  indicate that the renaming is an abstract dispatching operation
            --  with a controlling type.

            if Is_Actual and then Is_Abstract_Subprogram (Formal_Spec) then

               --  Mark the renaming as abstract here, so Find_Dispatching_Type
               --  see it as corresponding to a generic association for a
               --  formal abstract subprogram

               Set_Is_Abstract_Subprogram (New_S);

               declare
                  New_S_Ctrl_Type : constant Entity_Id :=
                                      Find_Dispatching_Type (New_S);
                  Old_S_Ctrl_Type : constant Entity_Id :=
                                      Find_Dispatching_Type (Old_S);

               begin

                  --  The actual must match the (instance of the) formal,
                  --  and must be a controlling type.

                  if Old_S_Ctrl_Type /= New_S_Ctrl_Type
                    or else No (New_S_Ctrl_Type)
                  then
                     if No (New_S_Ctrl_Type) then
                        Error_Msg_N
                          ("actual must be dispatching subprogram", Nam);
                     else
                        Error_Msg_NE
                          ("actual must be dispatching subprogram for type&",
                           Nam, New_S_Ctrl_Type);
                     end if;

                  else
                     Set_Is_Dispatching_Operation (New_S);
                     Check_Controlling_Formals (New_S_Ctrl_Type, New_S);

                     --  If the actual in the formal subprogram is itself a
                     --  formal abstract subprogram association, there's no
                     --  dispatch table component or position to inherit.

                     if Present (DTC_Entity (Old_S)) then
                        Set_DTC_Entity  (New_S, DTC_Entity (Old_S));
                        Set_DT_Position_Value (New_S, DT_Position (Old_S));
                     end if;
                  end if;
               end;
            end if;
         end if;

         if Is_Actual then
            null;

         --  The following is illegal, because F hides whatever other F may
         --  be around:
         --     function F (...) renames F;

         elsif Old_S = New_S
           or else (Nkind (Nam) /= N_Expanded_Name
                     and then Chars (Old_S) = Chars (New_S))
         then
            Error_Msg_N ("subprogram cannot rename itself", N);

         --  This is illegal even if we use a selector:
         --     function F (...) renames Pkg.F;
         --  because F is still hidden.

         elsif Nkind (Nam) = N_Expanded_Name
           and then Entity (Prefix (Nam)) = Current_Scope
           and then Chars (Selector_Name (Nam)) = Chars (New_S)
         then
            --  This is an error, but we overlook the error and accept the
            --  renaming if the special Overriding_Renamings mode is in effect.

            if not Overriding_Renamings then
               Error_Msg_NE
                 ("implicit operation& is not visible (RM 8.3 (15))",
                  Nam, Old_S);
            end if;
         end if;

         Set_Convention (New_S, Convention (Old_S));

         if Is_Abstract_Subprogram (Old_S) then
            if Present (Rename_Spec) then
               Error_Msg_N
                 ("a renaming-as-body cannot rename an abstract subprogram",
                  N);
               Set_Has_Completion (Rename_Spec);
            else
               Set_Is_Abstract_Subprogram (New_S);
            end if;
         end if;

         Check_Library_Unit_Renaming (N, Old_S);

         --  Pathological case: procedure renames entry in the scope of its
         --  task. Entry is given by simple name, but body must be built for
         --  procedure. Of course if called it will deadlock.

         if Ekind (Old_S) = E_Entry then
            Set_Has_Completion (New_S, False);
            Set_Alias (New_S, Empty);
         end if;

         --  Do not freeze the renaming nor the renamed entity when the context
         --  is an enclosing generic. Freezing is an expansion activity, and in
         --  addition the renamed entity may depend on the generic formals of
         --  the enclosing generic.

         if Is_Actual and not Inside_A_Generic then
            Freeze_Before (N, Old_S);
            Freeze_Actual_Profile;
            Set_Has_Delayed_Freeze (New_S, False);
            Freeze_Before (N, New_S);

            if (Ekind (Old_S) = E_Procedure or else Ekind (Old_S) = E_Function)
              and then not Is_Abstract_Subprogram (Formal_Spec)
            then
               --  An abstract subprogram is only allowed as an actual in the
               --  case where the formal subprogram is also abstract.

               if Is_Abstract_Subprogram (Old_S) then
                  Error_Msg_N
                    ("abstract subprogram not allowed as generic actual", Nam);
               end if;

               --  AI12-0412: A primitive of an abstract type with Pre'Class
               --  or Post'Class aspects specified with nonstatic expressions
               --  is not allowed as actual for a nonabstract formal subprogram
               --  (see RM 6.1.1(18.2/5).

               if Is_Dispatching_Operation (Old_S)
                 and then
                   Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post (Old_S)
               then
                  Error_Msg_N
                    ("primitive of abstract type with nonstatic class-wide "
                      & "pre/postconditions not allowed as actual",
                     Nam);
               end if;
            end if;
         end if;

      else
         --  A common error is to assume that implicit operators for types are
         --  defined in Standard, or in the scope of a subtype. In those cases
         --  where the renamed entity is given with an expanded name, it is
         --  worth mentioning that operators for the type are not declared in
         --  the scope given by the prefix.

         if Nkind (Nam) = N_Expanded_Name
           and then Nkind (Selector_Name (Nam)) = N_Operator_Symbol
           and then Scope (Entity (Nam)) = Standard_Standard
         then
            declare
               T : constant Entity_Id :=
                     Base_Type (Etype (First_Formal (New_S)));
            begin
               Error_Msg_Node_2 := Prefix (Nam);
               Error_Msg_NE
                 ("operator for type& is not declared in&", Prefix (Nam), T);
            end;

         else
            Error_Msg_NE
              ("no visible subprogram matches the specification for&",
                Spec, New_S);
         end if;

         if Present (Candidate_Renaming) then
            declare
               F1 : Entity_Id;
               F2 : Entity_Id;
               T1 : Entity_Id;

            begin
               F1 := First_Formal (Candidate_Renaming);
               F2 := First_Formal (New_S);
               T1 := First_Subtype (Etype (F1));
               while Present (F1) and then Present (F2) loop
                  Next_Formal (F1);
                  Next_Formal (F2);
               end loop;

               if Present (F1) and then Present (Default_Value (F1)) then
                  if Present (Next_Formal (F1)) then
                     Error_Msg_NE
                       ("\missing specification for & and other formals with "
                        & "defaults", Spec, F1);
                  else
                     Error_Msg_NE ("\missing specification for &", Spec, F1);
                  end if;
               end if;

               if Nkind (Nam) = N_Operator_Symbol
                 and then From_Default (N)
               then
                  Error_Msg_Node_2 := T1;
                  Error_Msg_NE
                    ("default & on & is not directly visible", Nam, Nam);
               end if;
            end;
         end if;
      end if;

      --  Ada 2005 AI 404: if the new subprogram is dispatching, verify that
      --  controlling access parameters are known non-null for the renamed
      --  subprogram. Test also applies to a subprogram instantiation that
      --  is dispatching. Test is skipped if some previous error was detected
      --  that set Old_S to Any_Id.

      if Ada_Version >= Ada_2005
        and then Old_S /= Any_Id
        and then not Is_Dispatching_Operation (Old_S)
        and then Is_Dispatching_Operation (New_S)
      then
         declare
            Old_F : Entity_Id;
            New_F : Entity_Id;

         begin
            Old_F := First_Formal (Old_S);
            New_F := First_Formal (New_S);
            while Present (Old_F) loop
               if Ekind (Etype (Old_F)) = E_Anonymous_Access_Type
                 and then Is_Controlling_Formal (New_F)
                 and then not Can_Never_Be_Null (Old_F)
               then
                  Error_Msg_N ("access parameter is controlling,", New_F);
                  Error_Msg_NE
                    ("\corresponding parameter of& must be explicitly null "
                     & "excluding", New_F, Old_S);
               end if;

               Next_Formal (Old_F);
               Next_Formal (New_F);
            end loop;
         end;
      end if;

      --  A useful warning, suggested by Ada Bug Finder (Ada-Europe 2005)
      --  is to warn if an operator is being renamed as a different operator.
      --  If the operator is predefined, examine the kind of the entity, not
      --  the abbreviated declaration in Standard.

      if Comes_From_Source (N)
        and then Present (Old_S)
        and then (Nkind (Old_S) = N_Defining_Operator_Symbol
                   or else Ekind (Old_S) = E_Operator)
        and then Nkind (New_S) = N_Defining_Operator_Symbol
        and then Chars (Old_S) /= Chars (New_S)
      then
         Error_Msg_NE
           ("& is being renamed as a different operator??", N, Old_S);
      end if;

      --  Check for renaming of obsolescent subprogram

      Check_Obsolescent_2005_Entity (Entity (Nam), Nam);

      --  Another warning or some utility: if the new subprogram as the same
      --  name as the old one, the old one is not hidden by an outer homograph,
      --  the new one is not a public symbol, and the old one is otherwise
      --  directly visible, the renaming is superfluous.

      if Chars (Old_S) = Chars (New_S)
        and then Comes_From_Source (N)
        and then Scope (Old_S) /= Standard_Standard
        and then Warn_On_Redundant_Constructs
        and then (Is_Immediately_Visible (Old_S)
                   or else Is_Potentially_Use_Visible (Old_S))
        and then Is_Overloadable (Current_Scope)
        and then Chars (Current_Scope) /= Chars (Old_S)
      then
         Error_Msg_N
           ("redundant renaming, entity is directly visible?r?", Name (N));
      end if;

      --  Implementation-defined aspect specifications can appear in a renaming
      --  declaration, but not language-defined ones. The call to procedure
      --  Analyze_Aspect_Specifications will take care of this error check.

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, New_S);
      end if;

      --  AI12-0279

      if Is_Actual
        and then Has_Yield_Aspect (Formal_Spec)
        and then not Has_Yield_Aspect (Old_S)
      then
         Error_Msg_Name_1 := Name_Yield;
         Error_Msg_N
           ("actual subprogram& must have aspect% to match formal", Name (N));
      end if;

      Ada_Version := Save_AV;
      Ada_Version_Pragma := Save_AVP;
      Ada_Version_Explicit := Save_AV_Exp;

      --  Check if we are looking at an Ada 2012 defaulted formal subprogram
      --  and mark any use_package_clauses that affect the visibility of the
      --  implicit generic actual.

      --  Also, we may be looking at an internal renaming of a user-defined
      --  subprogram created for a generic formal subprogram association,
      --  which will also have to be marked here. This can occur when the
      --  corresponding formal subprogram contains references to other generic
      --  formals.

      if Is_Generic_Actual_Subprogram (New_S)
        and then (Is_Intrinsic_Subprogram (New_S)
                   or else From_Default (N)
                   or else Nkind (N) = N_Subprogram_Renaming_Declaration)
      then
         Mark_Use_Clauses (New_S);

         --  Handle overloaded subprograms

         if Present (Alias (New_S)) then
            Mark_Use_Clauses (Alias (New_S));
         end if;
      end if;
   end Analyze_Subprogram_Renaming;

   -------------------------
   -- Analyze_Use_Package --
   -------------------------

   --  Resolve the package names in the use clause, and make all the visible
   --  entities defined in the package potentially use-visible. If the package
   --  is already in use from a previous use clause, its visible entities are
   --  already use-visible. In that case, mark the occurrence as a redundant
   --  use. If the package is an open scope, i.e. if the use clause occurs
   --  within the package itself, ignore it.

   procedure Analyze_Use_Package (N : Node_Id; Chain : Boolean := True) is
      procedure Analyze_Package_Name (Clause : Node_Id);
      --  Perform analysis on a package name from a use_package_clause

      procedure Analyze_Package_Name_List (Head_Clause : Node_Id);
      --  Similar to Analyze_Package_Name but iterates over all the names
      --  in a use clause.

      --------------------------
      -- Analyze_Package_Name --
      --------------------------

      procedure Analyze_Package_Name (Clause : Node_Id) is
         Pack : constant Node_Id := Name (Clause);
         Pref : Node_Id;

      begin
         pragma Assert (Nkind (Clause) = N_Use_Package_Clause);
         Analyze (Pack);

         --  Verify that the package standard is not directly named in a
         --  use_package_clause.

         if Nkind (Parent (Clause)) = N_Compilation_Unit
           and then Nkind (Pack) = N_Expanded_Name
         then
            Pref := Prefix (Pack);

            while Nkind (Pref) = N_Expanded_Name loop
               Pref := Prefix (Pref);
            end loop;

            if Entity (Pref) = Standard_Standard then
               Error_Msg_N
                 ("predefined package Standard cannot appear in a context "
                  & "clause", Pref);
            end if;
         end if;
      end Analyze_Package_Name;

      -------------------------------
      -- Analyze_Package_Name_List --
      -------------------------------

      procedure Analyze_Package_Name_List (Head_Clause : Node_Id) is
         Curr : Node_Id;

      begin
         --  Due to the way source use clauses are split during parsing we are
         --  forced to simply iterate through all entities in scope until the
         --  clause representing the last name in the list is found.

         Curr := Head_Clause;
         while Present (Curr) loop
            Analyze_Package_Name (Curr);

            --  Stop iterating over the names in the use clause when we are at
            --  the last one.

            exit when not More_Ids (Curr) and then Prev_Ids (Curr);
            Next (Curr);
         end loop;
      end Analyze_Package_Name_List;

      --  Local variables

      Pack : Entity_Id;

   --  Start of processing for Analyze_Use_Package

   begin
      Set_Hidden_By_Use_Clause (N, No_Elist);

      --  Use clause not allowed in a spec of a predefined package declaration
      --  except that packages whose file name starts a-n are OK (these are
      --  children of Ada.Numerics, which are never loaded by Rtsfind).

      if Is_Predefined_Unit (Current_Sem_Unit)
        and then Get_Name_String
                   (Unit_File_Name (Current_Sem_Unit)) (1 .. 3) /= "a-n"
        and then Nkind (Unit (Cunit (Current_Sem_Unit))) =
                   N_Package_Declaration
      then
         Error_Msg_N ("use clause not allowed in predefined spec", N);
      end if;

      --  Loop through all package names from the original use clause in
      --  order to analyze referenced packages. A use_package_clause with only
      --  one name does not have More_Ids or Prev_Ids set, while a clause with
      --  More_Ids only starts the chain produced by the parser.

      if not More_Ids (N) and then not Prev_Ids (N) then
         Analyze_Package_Name (N);

      elsif More_Ids (N) and then not Prev_Ids (N) then
         Analyze_Package_Name_List (N);
      end if;

      if not Is_Entity_Name (Name (N)) then
         Error_Msg_N ("& is not a package", Name (N));

         return;
      end if;

      if Chain then
         Chain_Use_Clause (N);
      end if;

      Pack := Entity (Name (N));

      --  There are many cases where scopes are manipulated during analysis, so
      --  check that Pack's current use clause has not already been chained
      --  before setting its previous use clause.

      if Ekind (Pack) = E_Package
        and then Present (Current_Use_Clause (Pack))
        and then Current_Use_Clause (Pack) /= N
        and then No (Prev_Use_Clause (N))
        and then Prev_Use_Clause (Current_Use_Clause (Pack)) /= N
      then
         Set_Prev_Use_Clause (N, Current_Use_Clause (Pack));
      end if;

      --  Mark all entities as potentially use visible

      if Ekind (Pack) /= E_Package and then Etype (Pack) /= Any_Type then
         if Ekind (Pack) = E_Generic_Package then
            Error_Msg_N  -- CODEFIX
              ("a generic package is not allowed in a use clause", Name (N));

         elsif Is_Generic_Subprogram (Pack) then
            Error_Msg_N  -- CODEFIX
              ("a generic subprogram is not allowed in a use clause",
               Name (N));

         elsif Is_Subprogram (Pack) then
            Error_Msg_N  -- CODEFIX
              ("a subprogram is not allowed in a use clause", Name (N));

         else
            Error_Msg_N ("& is not allowed in a use clause", Name (N));
         end if;

      else
         if Nkind (Parent (N)) = N_Compilation_Unit then
            Check_In_Previous_With_Clause (N, Name (N));
         end if;

         Use_One_Package (N, Name (N));
      end if;

      Mark_Ghost_Clause (N);
   end Analyze_Use_Package;

   ----------------------
   -- Analyze_Use_Type --
   ----------------------

   procedure Analyze_Use_Type (N : Node_Id; Chain : Boolean := True) is
      E  : Entity_Id;
      Id : Node_Id;

   begin
      Set_Hidden_By_Use_Clause (N, No_Elist);

      --  Chain clause to list of use clauses in current scope when flagged

      if Chain then
         Chain_Use_Clause (N);
      end if;

      --  Obtain the base type of the type denoted within the use_type_clause's
      --  subtype mark.

      Id := Subtype_Mark (N);
      Find_Type (Id);
      E := Base_Type (Entity (Id));

      --  There are many cases where a use_type_clause may be reanalyzed due to
      --  manipulation of the scope stack so we much guard against those cases
      --  here, otherwise, we must add the new use_type_clause to the previous
      --  use_type_clause chain in order to mark redundant use_type_clauses as
      --  used. When the redundant use-type clauses appear in a parent unit and
      --  a child unit we must prevent a circularity in the chain that would
      --  otherwise result from the separate steps of analysis and installation
      --  of the parent context.

      if Present (Current_Use_Clause (E))
        and then Current_Use_Clause (E) /= N
        and then Prev_Use_Clause (Current_Use_Clause (E)) /= N
        and then No (Prev_Use_Clause (N))
      then
         Set_Prev_Use_Clause (N, Current_Use_Clause (E));
      end if;

      --  If the Used_Operations list is already initialized, the clause has
      --  been analyzed previously, and it is being reinstalled, for example
      --  when the clause appears in a package spec and we are compiling the
      --  corresponding package body. In that case, make the entities on the
      --  existing list use_visible, and mark the corresponding types In_Use.

      if Present (Used_Operations (N)) then
         declare
            Elmt : Elmt_Id;

         begin
            Use_One_Type (Subtype_Mark (N), Installed => True);

            Elmt := First_Elmt (Used_Operations (N));
            while Present (Elmt) loop
               Set_Is_Potentially_Use_Visible (Node (Elmt));
               Next_Elmt (Elmt);
            end loop;
         end;

         return;
      end if;

      --  Otherwise, create new list and attach to it the operations that are
      --  made use-visible by the clause.

      Set_Used_Operations (N, New_Elmt_List);
      E := Entity (Id);

      if E /= Any_Type then
         Use_One_Type (Id);

         if Nkind (Parent (N)) = N_Compilation_Unit then
            if Nkind (Id) = N_Identifier then
               Error_Msg_N ("type is not directly visible", Id);

            elsif Is_Child_Unit (Scope (E))
              and then Scope (E) /= System_Aux_Id
            then
               Check_In_Previous_With_Clause (N, Prefix (Id));
            end if;
         end if;

      else
         --  If the use_type_clause appears in a compilation unit context,
         --  check whether it comes from a unit that may appear in a
         --  limited_with_clause, for a better error message.

         if Nkind (Parent (N)) = N_Compilation_Unit
           and then Nkind (Id) /= N_Identifier
         then
            declare
               Item : Node_Id;
               Pref : Node_Id;

               function Mentioned (Nam : Node_Id) return Boolean;
               --  Check whether the prefix of expanded name for the type
               --  appears in the prefix of some limited_with_clause.

               ---------------
               -- Mentioned --
               ---------------

               function Mentioned (Nam : Node_Id) return Boolean is
               begin
                  return Nkind (Name (Item)) = N_Selected_Component
                    and then Chars (Prefix (Name (Item))) = Chars (Nam);
               end Mentioned;

            begin
               Pref := Prefix (Id);
               Item := First (Context_Items (Parent (N)));
               while Present (Item) and then Item /= N loop
                  if Nkind (Item) = N_With_Clause
                    and then Limited_Present (Item)
                    and then Mentioned (Pref)
                  then
                     Change_Error_Text
                       (Get_Msg_Id, "premature usage of incomplete type");
                  end if;

                  Next (Item);
               end loop;
            end;
         end if;
      end if;

      Mark_Ghost_Clause (N);
   end Analyze_Use_Type;

   ------------------------
   -- Attribute_Renaming --
   ------------------------

   procedure Attribute_Renaming (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Nam   : constant Node_Id    := Name (N);
      Spec  : constant Node_Id    := Specification (N);
      New_S : constant Entity_Id  := Defining_Unit_Name (Spec);
      Aname : constant Name_Id    := Attribute_Name (Nam);

      Form_Num  : Nat      := 0;
      Expr_List : List_Id  := No_List;

      Attr_Node  : Node_Id;
      Body_Node  : Node_Id;
      Param_Spec : Node_Id;

   begin
      Generate_Definition (New_S);

      --  This procedure is called in the context of subprogram renaming, and
      --  thus the attribute must be one that is a subprogram. All of those
      --  have at least one formal parameter, with the exceptions of the GNAT
      --  attribute 'Img, which GNAT treats as renameable.

      if not Is_Non_Empty_List (Parameter_Specifications (Spec)) then
         if Aname /= Name_Img then
            Error_Msg_N
              ("subprogram renaming an attribute must have formals", N);
            return;
         end if;

      else
         Param_Spec := First (Parameter_Specifications (Spec));
         while Present (Param_Spec) loop
            Form_Num := Form_Num + 1;

            if Nkind (Parameter_Type (Param_Spec)) /= N_Access_Definition then
               Find_Type (Parameter_Type (Param_Spec));

               --  The profile of the new entity denotes the base type (s) of
               --  the types given in the specification. For access parameters
               --  there are no subtypes involved.

               Rewrite (Parameter_Type (Param_Spec),
                 New_Occurrence_Of
                   (Base_Type (Entity (Parameter_Type (Param_Spec))), Loc));
            end if;

            if No (Expr_List) then
               Expr_List := New_List;
            end if;

            Append_To (Expr_List,
              Make_Identifier (Loc,
                Chars => Chars (Defining_Identifier (Param_Spec))));

            --  The expressions in the attribute reference are not freeze
            --  points. Neither is the attribute as a whole, see below.

            Set_Must_Not_Freeze (Last (Expr_List));
            Next (Param_Spec);
         end loop;
      end if;

      --  Immediate error if too many formals. Other mismatches in number or
      --  types of parameters are detected when we analyze the body of the
      --  subprogram that we construct.

      if Form_Num > 2 then
         Error_Msg_N ("too many formals for attribute", N);

      --  Error if the attribute reference has expressions that look like
      --  formal parameters.

      elsif Present (Expressions (Nam)) then
         Error_Msg_N ("illegal expressions in attribute reference", Nam);

      elsif Aname in Name_Compose | Name_Exponent | Name_Leading_Part |
                     Name_Pos     | Name_Round    | Name_Scaling      |
                     Name_Val
      then
         if Nkind (N) = N_Subprogram_Renaming_Declaration
           and then Present (Corresponding_Formal_Spec (N))
         then
            Error_Msg_N
              ("generic actual cannot be attribute involving universal type",
               Nam);
         else
            Error_Msg_N
              ("attribute involving a universal type cannot be renamed",
               Nam);
         end if;
      end if;

      --  Rewrite attribute node to have a list of expressions corresponding to
      --  the subprogram formals. A renaming declaration is not a freeze point,
      --  and the analysis of the attribute reference should not freeze the
      --  type of the prefix. We use the original node in the renaming so that
      --  its source location is preserved, and checks on stream attributes are
      --  properly applied.

      Attr_Node := Relocate_Node (Nam);
      Set_Expressions (Attr_Node, Expr_List);

      Set_Must_Not_Freeze (Attr_Node);
      Set_Must_Not_Freeze (Prefix (Nam));

      --  Case of renaming a function

      if Nkind (Spec) = N_Function_Specification then
         if Is_Procedure_Attribute_Name (Aname) then
            Error_Msg_N ("attribute can only be renamed as procedure", Nam);
            return;
         end if;

         Find_Type (Result_Definition (Spec));
         Rewrite (Result_Definition (Spec),
           New_Occurrence_Of
             (Base_Type (Entity (Result_Definition (Spec))), Loc));

         Body_Node :=
           Make_Subprogram_Body (Loc,
             Specification => Spec,
             Declarations => New_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                   Statements => New_List (
                     Make_Simple_Return_Statement (Loc,
                       Expression => Attr_Node))));

      --  Case of renaming a procedure

      else
         if not Is_Procedure_Attribute_Name (Aname) then
            Error_Msg_N ("attribute can only be renamed as function", Nam);
            return;
         end if;

         Body_Node :=
           Make_Subprogram_Body (Loc,
             Specification => Spec,
             Declarations => New_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                   Statements => New_List (Attr_Node)));
      end if;

      --  Signal the ABE mechanism that the generated subprogram body has not
      --  ABE ramifications.

      Set_Was_Attribute_Reference (Body_Node);

      --  In case of tagged types we add the body of the generated function to
      --  the freezing actions of the type (because in the general case such
      --  type is still not frozen). We exclude from this processing generic
      --  formal subprograms found in instantiations.

      --  We must exclude restricted run-time libraries because
      --  entity AST_Handler is defined in package System.Aux_Dec which is not
      --  available in those platforms. Note that we cannot use the function
      --  Restricted_Profile (instead of Configurable_Run_Time_Mode) because
      --  the ZFP run-time library is not defined as a profile, and we do not
      --  want to deal with AST_Handler in ZFP mode.

      if not Configurable_Run_Time_Mode
        and then not Present (Corresponding_Formal_Spec (N))
        and then not Is_RTE (Etype (Nam), RE_AST_Handler)
      then
         declare
            P : constant Node_Id := Prefix (Nam);

         begin
            --  The prefix of 'Img is an object that is evaluated for each call
            --  of the function that renames it.

            if Aname = Name_Img then
               Preanalyze_And_Resolve (P);

            --  For all other attribute renamings, the prefix is a subtype

            else
               Find_Type (P);
            end if;

            --  If the target type is not yet frozen, add the body to the
            --  actions to be elaborated at freeze time.

            if Is_Tagged_Type (Etype (P))
              and then In_Open_Scopes (Scope (Etype (P)))
            then
               Ensure_Freeze_Node (Etype (P));
               Append_Freeze_Action (Etype (P), Body_Node);
            else
               Rewrite (N, Body_Node);
               Analyze (N);
               Set_Etype (New_S, Base_Type (Etype (New_S)));
            end if;
         end;

      --  Generic formal subprograms or AST_Handler renaming

      else
         Rewrite (N, Body_Node);
         Analyze (N);
         Set_Etype (New_S, Base_Type (Etype (New_S)));
      end if;

      if Is_Compilation_Unit (New_S) then
         Error_Msg_N
           ("a library unit can only rename another library unit", N);
      end if;

      --  We suppress elaboration warnings for the resulting entity, since
      --  clearly they are not needed, and more particularly, in the case
      --  of a generic formal subprogram, the resulting entity can appear
      --  after the instantiation itself, and thus look like a bogus case
      --  of access before elaboration.

      if Legacy_Elaboration_Checks then
         Set_Suppress_Elaboration_Warnings (New_S);
      end if;
   end Attribute_Renaming;

   ----------------------
   -- Chain_Use_Clause --
   ----------------------

   procedure Chain_Use_Clause (N : Node_Id) is
      Level : Int := Scope_Stack.Last;
      Pack  : Entity_Id;

   begin
      --  Common case

      if not Is_Compilation_Unit (Current_Scope)
        or else not Is_Child_Unit (Current_Scope)
      then
         null;

      --  Common case for compilation unit

      elsif Defining_Entity (Parent (N)) = Current_Scope then
         null;

      else
         --  If declaration appears in some other scope, it must be in some
         --  parent unit when compiling a child.

         Pack := Defining_Entity (Parent (N));

         if not In_Open_Scopes (Pack) then
            null;

         --  If the use clause appears in an ancestor and we are in the
         --  private part of the immediate parent, the use clauses are
         --  already installed.

         elsif Pack /= Scope (Current_Scope)
           and then In_Private_Part (Scope (Current_Scope))
         then
            null;

         else
            --  Find entry for parent unit in scope stack

            while Scope_Stack.Table (Level).Entity /= Pack loop
               Level := Level - 1;
            end loop;
         end if;
      end if;

      Set_Next_Use_Clause (N,
        Scope_Stack.Table (Level).First_Use_Clause);
      Scope_Stack.Table (Level).First_Use_Clause := N;
   end Chain_Use_Clause;

   ---------------------------
   -- Check_Frozen_Renaming --
   ---------------------------

   procedure Check_Frozen_Renaming (N : Node_Id; Subp : Entity_Id) is
      B_Node : Node_Id;
      Old_S  : Entity_Id;

   begin
      if Is_Frozen (Subp) and then not Has_Completion (Subp) then
         B_Node :=
           Build_Renamed_Body
             (Parent (Declaration_Node (Subp)), Defining_Entity (N));

         if Is_Entity_Name (Name (N)) then
            Old_S := Entity (Name (N));

            if not Is_Frozen (Old_S)
              and then Operating_Mode /= Check_Semantics
            then
               Append_Freeze_Action (Old_S, B_Node);
            else
               Insert_After (N, B_Node);
               Analyze (B_Node);
            end if;

            if Is_Intrinsic_Subprogram (Old_S)
              and then not In_Instance
              and then not Relaxed_RM_Semantics
            then
               Error_Msg_N
                 ("subprogram used in renaming_as_body cannot be intrinsic",
                  Name (N));
            end if;

         else
            Insert_After (N, B_Node);
            Analyze (B_Node);
         end if;
      end if;
   end Check_Frozen_Renaming;

   -------------------------------
   -- Set_Entity_Or_Discriminal --
   -------------------------------

   procedure Set_Entity_Or_Discriminal (N : Node_Id; E : Entity_Id) is
      P : Node_Id;

   begin
      --  If the entity is not a discriminant, or else expansion is disabled,
      --  simply set the entity.

      if not In_Spec_Expression
        or else Ekind (E) /= E_Discriminant
        or else Inside_A_Generic
      then
         Set_Entity_With_Checks (N, E);

      --  The replacement of a discriminant by the corresponding discriminal
      --  is not done for a task discriminant that appears in a default
      --  expression of an entry parameter. See Exp_Ch2.Expand_Discriminant
      --  for details on their handling.

      elsif Is_Concurrent_Type (Scope (E)) then
         P := Parent (N);
         while Present (P)
           and then Nkind (P) not in
             N_Parameter_Specification | N_Component_Declaration
         loop
            P := Parent (P);
         end loop;

         if Present (P)
           and then Nkind (P) = N_Parameter_Specification
         then
            null;

         else
            Set_Entity (N, Discriminal (E));
         end if;

         --  Otherwise, this is a discriminant in a context in which
         --  it is a reference to the corresponding parameter of the
         --  init proc for the enclosing type.

      else
         Set_Entity (N, Discriminal (E));
      end if;
   end Set_Entity_Or_Discriminal;

   -----------------------------------
   -- Check_In_Previous_With_Clause --
   -----------------------------------

   procedure Check_In_Previous_With_Clause
     (N   : Node_Id;
      Nam : Entity_Id)
   is
      Pack : constant Entity_Id := Entity (Original_Node (Nam));
      Item : Node_Id;
      Par  : Node_Id;

   begin
      Item := First (Context_Items (Parent (N)));
      while Present (Item) and then Item /= N loop
         if Nkind (Item) = N_With_Clause

           --  Protect the frontend against previous critical errors

           and then Nkind (Name (Item)) /= N_Selected_Component
           and then Entity (Name (Item)) = Pack
         then
            Par := Nam;

            --  Find root library unit in with_clause

            while Nkind (Par) = N_Expanded_Name loop
               Par := Prefix (Par);
            end loop;

            if Is_Child_Unit (Entity (Original_Node (Par))) then
               Error_Msg_NE ("& is not directly visible", Par, Entity (Par));
            else
               return;
            end if;
         end if;

         Next (Item);
      end loop;

      --  On exit, package is not mentioned in a previous with_clause.
      --  Check if its prefix is.

      if Nkind (Nam) = N_Expanded_Name then
         Check_In_Previous_With_Clause (N, Prefix (Nam));

      elsif Pack /= Any_Id then
         Error_Msg_NE ("& is not visible", Nam, Pack);
      end if;
   end Check_In_Previous_With_Clause;

   ---------------------------------
   -- Check_Library_Unit_Renaming --
   ---------------------------------

   procedure Check_Library_Unit_Renaming (N : Node_Id; Old_E : Entity_Id) is
      New_E : Entity_Id;

   begin
      if Nkind (Parent (N)) /= N_Compilation_Unit then
         return;

      --  Check for library unit. Note that we used to check for the scope
      --  being Standard here, but that was wrong for Standard itself.

      elsif not Is_Compilation_Unit (Old_E)
        and then not Is_Child_Unit (Old_E)
      then
         Error_Msg_N ("renamed unit must be a library unit", Name (N));

      --  Entities defined in Standard (operators and boolean literals) cannot
      --  be renamed as library units.

      elsif Scope (Old_E) = Standard_Standard
        and then Sloc (Old_E) = Standard_Location
      then
         Error_Msg_N ("renamed unit must be a library unit", Name (N));

      elsif Present (Parent_Spec (N))
        and then Nkind (Unit (Parent_Spec (N))) = N_Generic_Package_Declaration
        and then not Is_Child_Unit (Old_E)
      then
         Error_Msg_N
           ("renamed unit must be a child unit of generic parent", Name (N));

      elsif Nkind (N) in N_Generic_Renaming_Declaration
        and then  Nkind (Name (N)) = N_Expanded_Name
        and then Is_Generic_Instance (Entity (Prefix (Name (N))))
        and then Is_Generic_Unit (Old_E)
      then
         Error_Msg_N
           ("renamed generic unit must be a library unit", Name (N));

      elsif Is_Package_Or_Generic_Package (Old_E) then

         --  Inherit categorization flags

         New_E := Defining_Entity (N);
         Set_Is_Pure                  (New_E, Is_Pure           (Old_E));
         Set_Is_Preelaborated         (New_E, Is_Preelaborated  (Old_E));
         Set_Is_Remote_Call_Interface (New_E,
                                       Is_Remote_Call_Interface (Old_E));
         Set_Is_Remote_Types          (New_E, Is_Remote_Types   (Old_E));
         Set_Is_Shared_Passive        (New_E, Is_Shared_Passive (Old_E));
      end if;
   end Check_Library_Unit_Renaming;

   ------------------------
   -- Enclosing_Instance --
   ------------------------

   function Enclosing_Instance return Entity_Id is
      S : Entity_Id;

   begin
      if not Is_Generic_Instance (Current_Scope) then
         return Empty;
      end if;

      S := Scope (Current_Scope);
      while S /= Standard_Standard loop
         if Is_Generic_Instance (S) then
            return S;
         end if;

         S := Scope (S);
      end loop;

      return Empty;
   end Enclosing_Instance;

   ---------------
   -- End_Scope --
   ---------------

   procedure End_Scope is
      Id    : Entity_Id;
      Prev  : Entity_Id;
      Outer : Entity_Id;

   begin
      Id := First_Entity (Current_Scope);
      while Present (Id) loop
         --  An entity in the current scope is not necessarily the first one
         --  on its homonym chain. Find its predecessor if any,
         --  If it is an internal entity, it will not be in the visibility
         --  chain altogether,  and there is nothing to unchain.

         if Id /= Current_Entity (Id) then
            Prev := Current_Entity (Id);
            while Present (Prev)
              and then Present (Homonym (Prev))
              and then Homonym (Prev) /= Id
            loop
               Prev := Homonym (Prev);
            end loop;

            --  Skip to end of loop if Id is not in the visibility chain

            if No (Prev) or else Homonym (Prev) /= Id then
               goto Next_Ent;
            end if;

         else
            Prev := Empty;
         end if;

         Set_Is_Immediately_Visible (Id, False);

         Outer := Homonym (Id);
         while Present (Outer) and then Scope (Outer) = Current_Scope loop
            Outer := Homonym (Outer);
         end loop;

         --  Reset homonym link of other entities, but do not modify link
         --  between entities in current scope, so that the back-end can have
         --  a proper count of local overloadings.

         if No (Prev) then
            Set_Name_Entity_Id (Chars (Id), Outer);

         elsif Scope (Prev) /= Scope (Id) then
            Set_Homonym (Prev,  Outer);
         end if;

         <<Next_Ent>>
            Next_Entity (Id);
      end loop;

      --  If the scope generated freeze actions, place them before the
      --  current declaration and analyze them. Type declarations and
      --  the bodies of initialization procedures can generate such nodes.
      --  We follow the parent chain until we reach a list node, which is
      --  the enclosing list of declarations. If the list appears within
      --  a protected definition, move freeze nodes outside the protected
      --  type altogether.

      if Present
         (Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions)
      then
         declare
            Decl : Node_Id;
            L    : constant List_Id := Scope_Stack.Table
                    (Scope_Stack.Last).Pending_Freeze_Actions;

         begin
            if Is_Itype (Current_Scope) then
               Decl := Associated_Node_For_Itype (Current_Scope);
            else
               Decl := Parent (Current_Scope);
            end if;

            Pop_Scope;

            while not Is_List_Member (Decl)
              or else Nkind (Parent (Decl)) in N_Protected_Definition
                                             | N_Task_Definition
            loop
               Decl := Parent (Decl);
            end loop;

            Insert_List_Before_And_Analyze (Decl, L);
         end;

      else
         Pop_Scope;
      end if;
   end End_Scope;

   ---------------------
   -- End_Use_Clauses --
   ---------------------

   procedure End_Use_Clauses (Clause : Node_Id) is
      U : Node_Id;

   begin
      --  Remove use_type_clauses first, because they affect the visibility of
      --  operators in subsequent used packages.

      U := Clause;
      while Present (U) loop
         if Nkind (U) = N_Use_Type_Clause then
            End_Use_Type (U);
         end if;

         Next_Use_Clause (U);
      end loop;

      U := Clause;
      while Present (U) loop
         if Nkind (U) = N_Use_Package_Clause then
            End_Use_Package (U);
         end if;

         Next_Use_Clause (U);
      end loop;
   end End_Use_Clauses;

   ---------------------
   -- End_Use_Package --
   ---------------------

   procedure End_Use_Package (N : Node_Id) is
      Pack      : Entity_Id;
      Pack_Name : Node_Id;
      Id        : Entity_Id;
      Elmt      : Elmt_Id;

      function Is_Primitive_Operator_In_Use
        (Op : Entity_Id;
         F  : Entity_Id) return Boolean;
      --  Check whether Op is a primitive operator of a use-visible type

      ----------------------------------
      -- Is_Primitive_Operator_In_Use --
      ----------------------------------

      function Is_Primitive_Operator_In_Use
        (Op : Entity_Id;
         F  : Entity_Id) return Boolean
      is
         T : constant Entity_Id := Base_Type (Etype (F));
      begin
         return In_Use (T) and then Scope (T) = Scope (Op);
      end Is_Primitive_Operator_In_Use;

   --  Start of processing for End_Use_Package

   begin
      Pack_Name := Name (N);

      --  Test that Pack_Name actually denotes a package before processing

      if Is_Entity_Name (Pack_Name)
        and then Ekind (Entity (Pack_Name)) = E_Package
      then
         Pack := Entity (Pack_Name);

         if In_Open_Scopes (Pack) then
            null;

         elsif not Redundant_Use (Pack_Name) then
            Set_In_Use (Pack, False);
            Set_Current_Use_Clause (Pack, Empty);

            Id := First_Entity (Pack);
            while Present (Id) loop

               --  Preserve use-visibility of operators that are primitive
               --  operators of a type that is use-visible through an active
               --  use_type_clause.

               if Nkind (Id) = N_Defining_Operator_Symbol
                 and then
                   (Is_Primitive_Operator_In_Use (Id, First_Formal (Id))
                     or else
                       (Present (Next_Formal (First_Formal (Id)))
                         and then
                           Is_Primitive_Operator_In_Use
                             (Id, Next_Formal (First_Formal (Id)))))
               then
                  null;
               else
                  Set_Is_Potentially_Use_Visible (Id, False);
               end if;

               if Is_Private_Type (Id)
                 and then Present (Full_View (Id))
               then
                  Set_Is_Potentially_Use_Visible (Full_View (Id), False);
               end if;

               Next_Entity (Id);
            end loop;

            if Present (Renamed_Object (Pack)) then
               Set_In_Use (Renamed_Object (Pack), False);
               Set_Current_Use_Clause (Renamed_Object (Pack), Empty);
            end if;

            if Chars (Pack) = Name_System
              and then Scope (Pack) = Standard_Standard
              and then Present_System_Aux
            then
               Id := First_Entity (System_Aux_Id);
               while Present (Id) loop
                  Set_Is_Potentially_Use_Visible (Id, False);

                  if Is_Private_Type (Id)
                    and then Present (Full_View (Id))
                  then
                     Set_Is_Potentially_Use_Visible (Full_View (Id), False);
                  end if;

                  Next_Entity (Id);
               end loop;

               Set_In_Use (System_Aux_Id, False);
            end if;
         else
            Set_Redundant_Use (Pack_Name, False);
         end if;
      end if;

      if Present (Hidden_By_Use_Clause (N)) then
         Elmt := First_Elmt (Hidden_By_Use_Clause (N));
         while Present (Elmt) loop
            declare
               E : constant Entity_Id := Node (Elmt);

            begin
               --  Reset either Use_Visibility or Direct_Visibility, depending
               --  on how the entity was hidden by the use clause.

               if In_Use (Scope (E))
                 and then Used_As_Generic_Actual (Scope (E))
               then
                  Set_Is_Potentially_Use_Visible (Node (Elmt));
               else
                  Set_Is_Immediately_Visible (Node (Elmt));
               end if;

               Next_Elmt (Elmt);
            end;
         end loop;

         Set_Hidden_By_Use_Clause (N, No_Elist);
      end if;
   end End_Use_Package;

   ------------------
   -- End_Use_Type --
   ------------------

   procedure End_Use_Type (N : Node_Id) is
      Elmt : Elmt_Id;
      Id   : Entity_Id;
      T    : Entity_Id;

   --  Start of processing for End_Use_Type

   begin
      Id := Subtype_Mark (N);

      --  A call to Rtsfind may occur while analyzing a use_type_clause, in
      --  which case the type marks are not resolved yet, so guard against that
      --  here.

      if Is_Entity_Name (Id) and then Present (Entity (Id)) then
         T := Entity (Id);

         if T = Any_Type or else From_Limited_With (T) then
            null;

         --  Note that the use_type_clause may mention a subtype of the type
         --  whose primitive operations have been made visible. Here as
         --  elsewhere, it is the base type that matters for visibility.

         elsif In_Open_Scopes (Scope (Base_Type (T))) then
            null;

         elsif not Redundant_Use (Id) then
            Set_In_Use (T, False);
            Set_In_Use (Base_Type (T), False);
            Set_Current_Use_Clause (T, Empty);
            Set_Current_Use_Clause (Base_Type (T), Empty);

            --  See Use_One_Type for the rationale. This is a bit on the naive
            --  side, but should be good enough in practice.

            if Is_Tagged_Type (T) then
               Set_In_Use (Class_Wide_Type (T), False);
            end if;
         end if;
      end if;

      if Is_Empty_Elmt_List (Used_Operations (N)) then
         return;

      else
         Elmt := First_Elmt (Used_Operations (N));
         while Present (Elmt) loop
            Set_Is_Potentially_Use_Visible (Node (Elmt), False);
            Next_Elmt (Elmt);
         end loop;
      end if;
   end End_Use_Type;

   --------------------
   -- Entity_Of_Unit --
   --------------------

   function Entity_Of_Unit (U : Node_Id) return Entity_Id is
   begin
      if Nkind (U) = N_Package_Instantiation and then Analyzed (U) then
         return Defining_Entity (Instance_Spec (U));
      else
         return Defining_Entity (U);
      end if;
   end Entity_Of_Unit;

   ----------------------
   -- Find_Direct_Name --
   ----------------------

   procedure Find_Direct_Name (N : Node_Id) is
      E   : Entity_Id;
      E2  : Entity_Id;
      Msg : Boolean;

      Homonyms : Entity_Id;
      --  Saves start of homonym chain

      Inst : Entity_Id := Empty;
      --  Enclosing instance, if any

      Nvis_Entity : Boolean;
      --  Set True to indicate that there is at least one entity on the homonym
      --  chain which, while not visible, is visible enough from the user point
      --  of view to warrant an error message of "not visible" rather than
      --  undefined.

      Nvis_Is_Private_Subprg : Boolean := False;
      --  Ada 2005 (AI-262): Set True to indicate that a form of Beaujolais
      --  effect concerning library subprograms has been detected. Used to
      --  generate the precise error message.

      function From_Actual_Package (E : Entity_Id) return Boolean;
      --  Returns true if the entity is an actual for a package that is itself
      --  an actual for a formal package of the current instance. Such an
      --  entity requires special handling because it may be use-visible but
      --  hides directly visible entities defined outside the instance, because
      --  the corresponding formal did so in the generic.

      function Is_Actual_Parameter return Boolean;
      --  This function checks if the node N is an identifier that is an actual
      --  parameter of a procedure call. If so it returns True, otherwise it
      --  return False. The reason for this check is that at this stage we do
      --  not know what procedure is being called if the procedure might be
      --  overloaded, so it is premature to go setting referenced flags or
      --  making calls to Generate_Reference. We will wait till Resolve_Actuals
      --  for that processing.
      --  Note: there is a similar routine Sem_Util.Is_Actual_Parameter, but
      --  it works for both function and procedure calls, while here we are
      --  only concerned with procedure calls (and with entry calls as well,
      --  but they are parsed as procedure calls and only later rewritten to
      --  entry calls).

      function Known_But_Invisible (E : Entity_Id) return Boolean;
      --  This function determines whether a reference to the entity E, which
      --  is not visible, can reasonably be considered to be known to the
      --  writer of the reference. This is a heuristic test, used only for
      --  the purposes of figuring out whether we prefer to complain that an
      --  entity is undefined or invisible (and identify the declaration of
      --  the invisible entity in the latter case). The point here is that we
      --  don't want to complain that something is invisible and then point to
      --  something entirely mysterious to the writer.

      procedure Nvis_Messages;
      --  Called if there are no visible entries for N, but there is at least
      --  one non-directly visible, or hidden declaration. This procedure
      --  outputs an appropriate set of error messages.

      procedure Undefined (Nvis : Boolean);
      --  This function is called if the current node has no corresponding
      --  visible entity or entities. The value set in Msg indicates whether
      --  an error message was generated (multiple error messages for the
      --  same variable are generally suppressed, see body for details).
      --  Msg is True if an error message was generated, False if not. This
      --  value is used by the caller to determine whether or not to output
      --  additional messages where appropriate. The parameter is set False
      --  to get the message "X is undefined", and True to get the message
      --  "X is not visible".

      -------------------------
      -- From_Actual_Package --
      -------------------------

      function From_Actual_Package (E : Entity_Id) return Boolean is
         Scop : constant Entity_Id := Scope (E);
         --  Declared scope of candidate entity

         function Declared_In_Actual (Pack : Entity_Id) return Boolean;
         --  Recursive function that does the work and examines actuals of
         --  actual packages of current instance.

         ------------------------
         -- Declared_In_Actual --
         ------------------------

         function Declared_In_Actual (Pack : Entity_Id) return Boolean is
            Act : Entity_Id;

         begin
            if No (Associated_Formal_Package (Pack)) then
               return False;

            else
               Act := First_Entity (Pack);
               while Present (Act) loop
                  if Renamed_Object (Pack) = Scop then
                     return True;

                  --  Check for end of list of actuals

                  elsif Ekind (Act) = E_Package
                    and then Renamed_Object (Act) = Pack
                  then
                     return False;

                  elsif Ekind (Act) = E_Package
                    and then Declared_In_Actual (Act)
                  then
                     return True;
                  end if;

                  Next_Entity (Act);
               end loop;

               return False;
            end if;
         end Declared_In_Actual;

         --  Local variables

         Act : Entity_Id;

      --  Start of processing for From_Actual_Package

      begin
         if not In_Instance then
            return False;

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

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

            Act := First_Entity (Inst);
            while Present (Act) loop
               if Ekind (Act) = E_Package
                 and then Declared_In_Actual (Act)
               then
                  return True;
               end if;

               Next_Entity (Act);
            end loop;

            return False;
         end if;
      end From_Actual_Package;

      -------------------------
      -- Is_Actual_Parameter --
      -------------------------

      function Is_Actual_Parameter return Boolean is
      begin
         if Nkind (N) = N_Identifier then
            case Nkind (Parent (N)) is
               when N_Procedure_Call_Statement =>
                  return Is_List_Member (N)
                    and then List_Containing (N) =
                      Parameter_Associations (Parent (N));

               when N_Parameter_Association =>
                  return N = Explicit_Actual_Parameter (Parent (N))
                    and then Nkind (Parent (Parent (N))) =
                               N_Procedure_Call_Statement;

               when others =>
                  return False;
            end case;
         else
            return False;
         end if;
      end Is_Actual_Parameter;

      -------------------------
      -- Known_But_Invisible --
      -------------------------

      function Known_But_Invisible (E : Entity_Id) return Boolean is
         Fname : File_Name_Type;

      begin
         --  Entities in Standard are always considered to be known

         if Sloc (E) <= Standard_Location then
            return True;

         --  An entity that does not come from source is always considered
         --  to be unknown, since it is an artifact of code expansion.

         elsif not Comes_From_Source (E) then
            return False;
         end if;

         --  Here we have an entity that is not from package Standard, and
         --  which comes from Source. See if it comes from an internal file.

         Fname := Unit_File_Name (Get_Source_Unit (E));

         --  Case of from internal file

         if In_Internal_Unit (E) then

            --  Private part entities in internal files are never considered
            --  to be known to the writer of normal application code.

            if Is_Hidden (E) then
               return False;
            end if;

            --  Entities from System packages other than System and
            --  System.Storage_Elements are not considered to be known.
            --  System.Auxxxx files are also considered known to the user.

            --  Should refine this at some point to generally distinguish
            --  between known and unknown internal files ???

            Get_Name_String (Fname);

            return
              Name_Len < 2
                or else
              Name_Buffer (1 .. 2) /= "s-"
                or else
              Name_Buffer (3 .. 8) = "stoele"
                or else
              Name_Buffer (3 .. 5) = "aux";

         --  If not an internal file, then entity is definitely known, even if
         --  it is in a private part (the message generated will note that it
         --  is in a private part).

         else
            return True;
         end if;
      end Known_But_Invisible;

      -------------------
      -- Nvis_Messages --
      -------------------

      procedure Nvis_Messages is
         Comp_Unit : Node_Id;
         Ent       : Entity_Id;
         Found     : Boolean := False;
         Hidden    : Boolean := False;
         Item      : Node_Id;

      begin
         --  Ada 2005 (AI-262): Generate a precise error concerning the
         --  Beaujolais effect that was previously detected

         if Nvis_Is_Private_Subprg then

            pragma Assert (Nkind (E2) = N_Defining_Identifier
                            and then Ekind (E2) = E_Function
                            and then Scope (E2) = Standard_Standard
                            and then Has_Private_With (E2));

            --  Find the sloc corresponding to the private with'ed unit

            Comp_Unit := Cunit (Current_Sem_Unit);
            Error_Msg_Sloc := No_Location;

            Item := First (Context_Items (Comp_Unit));
            while Present (Item) loop
               if Nkind (Item) = N_With_Clause
                 and then Private_Present (Item)
                 and then Entity (Name (Item)) = E2
               then
                  Error_Msg_Sloc := Sloc (Item);
                  exit;
               end if;

               Next (Item);
            end loop;

            pragma Assert (Error_Msg_Sloc /= No_Location);

            Error_Msg_N ("(Ada 2005): hidden by private with clause #", N);
            return;
         end if;

         Undefined (Nvis => True);

         if Msg then

            --  First loop does hidden declarations

            Ent := Homonyms;
            while Present (Ent) loop
               if Is_Potentially_Use_Visible (Ent) then
                  if not Hidden then
                     Error_Msg_N -- CODEFIX
                       ("multiple use clauses cause hiding!", N);
                     Hidden := True;
                  end if;

                  Error_Msg_Sloc := Sloc (Ent);
                  Error_Msg_N -- CODEFIX
                    ("hidden declaration#!", N);
               end if;

               Ent := Homonym (Ent);
            end loop;

            --  If we found hidden declarations, then that's enough, don't
            --  bother looking for non-visible declarations as well.

            if Hidden then
               return;
            end if;

            --  Second loop does non-directly visible declarations

            Ent := Homonyms;
            while Present (Ent) loop
               if not Is_Potentially_Use_Visible (Ent) then

                  --  Do not bother the user with unknown entities

                  if not Known_But_Invisible (Ent) then
                     goto Continue;
                  end if;

                  Error_Msg_Sloc := Sloc (Ent);

                  --  Output message noting that there is a non-visible
                  --  declaration, distinguishing the private part case.

                  if Is_Hidden (Ent) then
                     Error_Msg_N ("non-visible (private) declaration#!", N);

                  --  If the entity is declared in a generic package, it
                  --  cannot be visible, so there is no point in adding it
                  --  to the list of candidates if another homograph from a
                  --  non-generic package has been seen.

                  elsif Ekind (Scope (Ent)) = E_Generic_Package
                    and then Found
                  then
                     null;

                  else
                     Error_Msg_N -- CODEFIX
                       ("non-visible declaration#!", N);

                     if Ekind (Scope (Ent)) /= E_Generic_Package then
                        Found := True;
                     end if;

                     if Is_Compilation_Unit (Ent)
                       and then
                         Nkind (Parent (Parent (N))) = N_Use_Package_Clause
                     then
                        Error_Msg_Qual_Level := 99;
                        Error_Msg_NE -- CODEFIX
                          ("\\missing `WITH &;`", N, Ent);
                        Error_Msg_Qual_Level := 0;
                     end if;

                     if Ekind (Ent) = E_Discriminant
                       and then Present (Corresponding_Discriminant (Ent))
                       and then Scope (Corresponding_Discriminant (Ent)) =
                                                        Etype (Scope (Ent))
                     then
                        Error_Msg_N
                          ("inherited discriminant not allowed here" &
                            " (RM 3.8 (12), 3.8.1 (6))!", N);
                     end if;
                  end if;

                  --  Set entity and its containing package as referenced. We
                  --  can't be sure of this, but this seems a better choice
                  --  to avoid unused entity messages.

                  if Comes_From_Source (Ent) then
                     Set_Referenced (Ent);
                     Set_Referenced (Cunit_Entity (Get_Source_Unit (Ent)));
                  end if;
               end if;

               <<Continue>>
               Ent := Homonym (Ent);
            end loop;
         end if;
      end Nvis_Messages;

      ---------------
      -- Undefined --
      ---------------

      procedure Undefined (Nvis : Boolean) is
         Emsg : Error_Msg_Id;

      begin
         --  We should never find an undefined internal name. If we do, then
         --  see if we have previous errors. If so, ignore on the grounds that
         --  it is probably a cascaded message (e.g. a block label from a badly
         --  formed block). If no previous errors, then we have a real internal
         --  error of some kind so raise an exception.

         if Is_Internal_Name (Chars (N)) then
            if Total_Errors_Detected /= 0 then
               return;
            else
               raise Program_Error;
            end if;
         end if;

         --  A very specialized error check, if the undefined variable is
         --  a case tag, and the case type is an enumeration type, check
         --  for a possible misspelling, and if so, modify the identifier

         --  Named aggregate should also be handled similarly ???

         if Nkind (N) = N_Identifier
           and then Nkind (Parent (N)) = N_Case_Statement_Alternative
         then
            declare
               Case_Stm : constant Node_Id   := Parent (Parent (N));
               Case_Typ : constant Entity_Id := Etype (Expression (Case_Stm));

               Lit : Node_Id;

            begin
               if Is_Enumeration_Type (Case_Typ)
                 and then not Is_Standard_Character_Type (Case_Typ)
               then
                  Lit := First_Literal (Case_Typ);
                  Get_Name_String (Chars (Lit));

                  if Chars (Lit) /= Chars (N)
                    and then Is_Bad_Spelling_Of (Chars (N), Chars (Lit))
                  then
                     Error_Msg_Node_2 := Lit;
                     Error_Msg_N -- CODEFIX
                       ("& is undefined, assume misspelling of &", N);
                     Rewrite (N, New_Occurrence_Of (Lit, Sloc (N)));
                     return;
                  end if;

                  Next_Literal (Lit);
               end if;
            end;
         end if;

         --  Normal processing

         Set_Entity (N, Any_Id);
         Set_Etype  (N, Any_Type);

         --  We use the table Urefs to keep track of entities for which we
         --  have issued errors for undefined references. Multiple errors
         --  for a single name are normally suppressed, however we modify
         --  the error message to alert the programmer to this effect.

         for J in Urefs.First .. Urefs.Last loop
            if Chars (N) = Chars (Urefs.Table (J).Node) then
               if Urefs.Table (J).Err /= No_Error_Msg
                 and then Sloc (N) /= Urefs.Table (J).Loc
               then
                  Error_Msg_Node_1 := Urefs.Table (J).Node;

                  if Urefs.Table (J).Nvis then
                     Change_Error_Text (Urefs.Table (J).Err,
                       "& is not visible (more references follow)");
                  else
                     Change_Error_Text (Urefs.Table (J).Err,
                       "& is undefined (more references follow)");
                  end if;

                  Urefs.Table (J).Err := No_Error_Msg;
               end if;

               --  Although we will set Msg False, and thus suppress the
               --  message, we also set Error_Posted True, to avoid any
               --  cascaded messages resulting from the undefined reference.

               Msg := False;
               Set_Error_Posted (N);
               return;
            end if;
         end loop;

         --  If entry not found, this is first undefined occurrence

         if Nvis then
            Error_Msg_N ("& is not visible!", N);
            Emsg := Get_Msg_Id;

         else
            Error_Msg_N ("& is undefined!", N);
            Emsg := Get_Msg_Id;

            --  A very bizarre special check, if the undefined identifier
            --  is Put or Put_Line, then add a special error message (since
            --  this is a very common error for beginners to make).

            if Chars (N) in Name_Put | Name_Put_Line then
               Error_Msg_N -- CODEFIX
                 ("\\possible missing `WITH Ada.Text_'I'O; " &
                  "USE Ada.Text_'I'O`!", N);

            --  Another special check if N is the prefix of a selected
            --  component which is a known unit: add message complaining
            --  about missing with for this unit.

            elsif Nkind (Parent (N)) = N_Selected_Component
              and then N = Prefix (Parent (N))
              and then Is_Known_Unit (Parent (N))
            then
               declare
                  P : Node_Id := Parent (N);
               begin
                  Error_Msg_Name_1 := Chars (N);
                  Error_Msg_Name_2 := Chars (Selector_Name (P));

                  if Nkind (Parent (P)) = N_Selected_Component
                    and then Is_Known_Unit (Parent (P))
                  then
                     P := Parent (P);
                     Error_Msg_Name_3 := Chars (Selector_Name (P));
                     Error_Msg_N -- CODEFIX
                       ("\\missing `WITH %.%.%;`", N);

                  else
                     Error_Msg_N -- CODEFIX
                       ("\\missing `WITH %.%;`", N);
                  end if;
               end;
            end if;

            --  Now check for possible misspellings

            declare
               E      : Entity_Id;
               Ematch : Entity_Id := Empty;
            begin
               for Nam in First_Name_Id .. Last_Name_Id loop
                  E := Get_Name_Entity_Id (Nam);

                  if Present (E)
                     and then (Is_Immediately_Visible (E)
                                 or else
                               Is_Potentially_Use_Visible (E))
                  then
                     if Is_Bad_Spelling_Of (Chars (N), Nam) then
                        Ematch := E;
                        exit;
                     end if;
                  end if;
               end loop;

               if Present (Ematch) then
                  Error_Msg_NE -- CODEFIX
                    ("\possible misspelling of&", N, Ematch);
               end if;
            end;
         end if;

         --  Make entry in undefined references table unless the full errors
         --  switch is set, in which case by refraining from generating the
         --  table entry we guarantee that we get an error message for every
         --  undefined reference. The entry is not added if we are ignoring
         --  errors.

         if not All_Errors_Mode
           and then Ignore_Errors_Enable = 0
           and then not Get_Ignore_Errors
         then
            Urefs.Append (
              (Node => N,
               Err  => Emsg,
               Nvis => Nvis,
               Loc  => Sloc (N)));
         end if;

         Msg := True;
      end Undefined;

      --  Local variables

      Nested_Inst : Entity_Id := Empty;
      --  The entity of a nested instance which appears within Inst (if any)

   --  Start of processing for Find_Direct_Name

   begin
      --  If the entity pointer is already set, this is an internal node, or
      --  a node that is analyzed more than once, after a tree modification.
      --  In such a case there is no resolution to perform, just set the type.

      if Present (Entity (N)) then
         if Is_Type (Entity (N)) then
            Set_Etype (N, Entity (N));

         --  The exception to this general rule are constants associated with
         --  discriminals of protected types because for each protected op
         --  a new set of discriminals is internally created by the frontend
         --  (see Exp_Ch9.Set_Discriminals), and the current decoration of the
         --  entity pointer may have been set as part of a preanalysis, where
         --  discriminals still reference the first subprogram or entry to be
         --  expanded (see Expand_Protected_Body_Declarations).

         elsif Full_Analysis
           and then Ekind (Entity (N)) = E_Constant
           and then Present (Discriminal_Link (Entity (N)))
           and then Is_Protected_Type (Scope (Discriminal_Link (Entity (N))))
         then
            goto Find_Name;

         else
            declare
               Entyp : constant Entity_Id := Etype (Entity (N));

            begin
               --  One special case here. If the Etype field is already set,
               --  and references the packed array type corresponding to the
               --  etype of the referenced entity, then leave it alone. This
               --  happens for trees generated from Exp_Pakd, where expressions
               --  can be deliberately "mis-typed" to the packed array type.

               if Is_Packed_Array (Entyp)
                 and then Present (Etype (N))
                 and then Etype (N) = Packed_Array_Impl_Type (Entyp)
               then
                  null;

               --  If not that special case, then just reset the Etype

               else
                  Set_Etype (N, Etype (Entity (N)));
               end if;
            end;
         end if;

         --  Although the marking of use clauses happens at the end of
         --  Find_Direct_Name, a certain case where a generic actual satisfies
         --  a use clause must be checked here due to how the generic machinery
         --  handles the analysis of said actuals.

         if In_Instance
           and then Nkind (Parent (N)) = N_Generic_Association
         then
            Mark_Use_Clauses (Entity (N));
         end if;

         return;
      end if;

      <<Find_Name>>

      --  Preserve relevant elaboration-related attributes of the context which
      --  are no longer available or very expensive to recompute once analysis,
      --  resolution, and expansion are over.

      if Nkind (N) = N_Identifier then
         Mark_Elaboration_Attributes
           (N_Id     => N,
            Checks   => True,
            Modes    => True,
            Warnings => True);
      end if;

      --  Here if Entity pointer was not set, we need full visibility analysis
      --  First we generate debugging output if the debug E flag is set.

      if Debug_Flag_E then
         Write_Str ("Looking for ");
         Write_Name (Chars (N));
         Write_Eol;
      end if;

      Homonyms := Current_Entity (N);
      Nvis_Entity := False;

      E := Homonyms;
      while Present (E) loop

         --  If entity is immediately visible or potentially use visible, then
         --  process the entity and we are done.

         if Is_Immediately_Visible (E) then
            goto Immediately_Visible_Entity;

         elsif Is_Potentially_Use_Visible (E) then
            goto Potentially_Use_Visible_Entity;

         --  Note if a known but invisible entity encountered

         elsif Known_But_Invisible (E) then
            Nvis_Entity := True;
         end if;

         --  Move to next entity in chain and continue search

         E := Homonym (E);
      end loop;

      --  If no entries on homonym chain that were potentially visible,
      --  and no entities reasonably considered as non-visible, then
      --  we have a plain undefined reference, with no additional
      --  explanation required.

      if not Nvis_Entity then
         Undefined (Nvis => False);

      --  Otherwise there is at least one entry on the homonym chain that
      --  is reasonably considered as being known and non-visible.

      else
         Nvis_Messages;
      end if;

      goto Done;

      --  Processing for a potentially use visible entry found. We must search
      --  the rest of the homonym chain for two reasons. First, if there is a
      --  directly visible entry, then none of the potentially use-visible
      --  entities are directly visible (RM 8.4(10)). Second, we need to check
      --  for the case of multiple potentially use-visible entries hiding one
      --  another and as a result being non-directly visible (RM 8.4(11)).

      <<Potentially_Use_Visible_Entity>> declare
         Only_One_Visible : Boolean := True;
         All_Overloadable : Boolean := Is_Overloadable (E);

      begin
         E2 := Homonym (E);
         while Present (E2) loop
            if Is_Immediately_Visible (E2) then

               --  If the use-visible entity comes from the actual for a
               --  formal package, it hides a directly visible entity from
               --  outside the instance.

               if From_Actual_Package (E)
                 and then Scope_Depth (Scope (E2)) < Scope_Depth (Inst)
               then
                  goto Found;
               else
                  E := E2;
                  goto Immediately_Visible_Entity;
               end if;

            elsif Is_Potentially_Use_Visible (E2) then
               Only_One_Visible := False;
               All_Overloadable := All_Overloadable and Is_Overloadable (E2);

            --  Ada 2005 (AI-262): Protect against a form of Beaujolais effect
            --  that can occur in private_with clauses. Example:

            --    with A;
            --    private with B;              package A is
            --    package C is                   function B return Integer;
            --      use A;                     end A;
            --      V1 : Integer := B;
            --    private                      function B return Integer;
            --      V2 : Integer := B;
            --    end C;

            --  V1 resolves to A.B, but V2 resolves to library unit B

            elsif Ekind (E2) = E_Function
              and then Scope (E2) = Standard_Standard
              and then Has_Private_With (E2)
            then
               Only_One_Visible       := False;
               All_Overloadable       := False;
               Nvis_Is_Private_Subprg := True;
               exit;
            end if;

            E2 := Homonym (E2);
         end loop;

         --  On falling through this loop, we have checked that there are no
         --  immediately visible entities. Only_One_Visible is set if exactly
         --  one potentially use visible entity exists. All_Overloadable is
         --  set if all the potentially use visible entities are overloadable.
         --  The condition for legality is that either there is one potentially
         --  use visible entity, or if there is more than one, then all of them
         --  are overloadable.

         if Only_One_Visible or All_Overloadable then
            goto Found;

         --  If there is more than one potentially use-visible entity and at
         --  least one of them non-overloadable, we have an error (RM 8.4(11)).
         --  Note that E points to the first such entity on the homonym list.

         else
            --  If one of the entities is declared in an actual package, it
            --  was visible in the generic, and takes precedence over other
            --  entities that are potentially use-visible. The same applies
            --  if the entity is declared in a local instantiation of the
            --  current instance.

            if In_Instance then

               --  Find the current instance

               Inst := Current_Scope;
               while Present (Inst) and then Inst /= Standard_Standard loop
                  if Is_Generic_Instance (Inst) then
                     exit;
                  end if;

                  Inst := Scope (Inst);
               end loop;

               --  Reexamine the candidate entities, giving priority to those
               --  that were visible within the generic.

               E2 := E;
               while Present (E2) loop
                  Nested_Inst := Nearest_Enclosing_Instance (E2);

                  --  The entity is declared within an actual package, or in a
                  --  nested instance. The ">=" accounts for the case where the
                  --  current instance and the nested instance are the same.

                  if From_Actual_Package (E2)
                    or else (Present (Nested_Inst)
                              and then Scope_Depth (Nested_Inst) >=
                                       Scope_Depth (Inst))
                  then
                     E := E2;
                     goto Found;
                  end if;

                  E2 := Homonym (E2);
               end loop;

               Nvis_Messages;
               goto Done;

            elsif Is_Predefined_Unit (Current_Sem_Unit) then
               --  A use clause in the body of a system file creates conflict
               --  with some entity in a user scope, while rtsfind is active.
               --  Keep only the entity coming from another predefined unit.

               E2 := E;
               while Present (E2) loop
                  if In_Predefined_Unit (E2) then
                     E := E2;
                     goto Found;
                  end if;

                  E2 := Homonym (E2);
               end loop;

               --  Entity must exist because predefined unit is correct

               raise Program_Error;

            else
               Nvis_Messages;
               goto Done;
            end if;
         end if;
      end;

      --  Come here with E set to the first immediately visible entity on
      --  the homonym chain. This is the one we want unless there is another
      --  immediately visible entity further on in the chain for an inner
      --  scope (RM 8.3(8)).

      <<Immediately_Visible_Entity>> declare
         Level : Int;
         Scop  : Entity_Id;

      begin
         --  Find scope level of initial entity. When compiling through
         --  Rtsfind, the previous context is not completely invisible, and
         --  an outer entity may appear on the chain, whose scope is below
         --  the entry for Standard that delimits the current scope stack.
         --  Indicate that the level for this spurious entry is outside of
         --  the current scope stack.

         Level := Scope_Stack.Last;
         loop
            Scop := Scope_Stack.Table (Level).Entity;
            exit when Scop = Scope (E);
            Level := Level - 1;
            exit when Scop = Standard_Standard;
         end loop;

         --  Now search remainder of homonym chain for more inner entry
         --  If the entity is Standard itself, it has no scope, and we
         --  compare it with the stack entry directly.

         E2 := Homonym (E);
         while Present (E2) loop
            if Is_Immediately_Visible (E2) then

               --  If a generic package contains a local declaration that
               --  has the same name as the generic, there may be a visibility
               --  conflict in an instance, where the local declaration must
               --  also hide the name of the corresponding package renaming.
               --  We check explicitly for a package declared by a renaming,
               --  whose renamed entity is an instance that is on the scope
               --  stack, and that contains a homonym in the same scope. Once
               --  we have found it, we know that the package renaming is not
               --  immediately visible, and that the identifier denotes the
               --  other entity (and its homonyms if overloaded).

               if Scope (E) = Scope (E2)
                 and then Ekind (E) = E_Package
                 and then Present (Renamed_Object (E))
                 and then Is_Generic_Instance (Renamed_Object (E))
                 and then In_Open_Scopes (Renamed_Object (E))
                 and then Comes_From_Source (N)
               then
                  Set_Is_Immediately_Visible (E, False);
                  E := E2;

               else
                  for J in Level + 1 .. Scope_Stack.Last loop
                     if Scope_Stack.Table (J).Entity = Scope (E2)
                       or else Scope_Stack.Table (J).Entity = E2
                     then
                        Level := J;
                        E := E2;
                        exit;
                     end if;
                  end loop;
               end if;
            end if;

            E2 := Homonym (E2);
         end loop;

         --  At the end of that loop, E is the innermost immediately
         --  visible entity, so we are all set.
      end;

      --  Come here with entity found, and stored in E

      <<Found>> begin

         --  Check violation of No_Wide_Characters restriction

         Check_Wide_Character_Restriction (E, N);

         --  When distribution features are available (Get_PCS_Name /=
         --  Name_No_DSA), a remote access-to-subprogram type is converted
         --  into a record type holding whatever information is needed to
         --  perform a remote call on an RCI subprogram. In that case we
         --  rewrite any occurrence of the RAS type into the equivalent record
         --  type here. 'Access attribute references and RAS dereferences are
         --  then implemented using specific TSSs. However when distribution is
         --  not available (case of Get_PCS_Name = Name_No_DSA), we bypass the
         --  generation of these TSSs, and we must keep the RAS type in its
         --  original access-to-subprogram form (since all calls through a
         --  value of such type will be local anyway in the absence of a PCS).

         if Comes_From_Source (N)
           and then Is_Remote_Access_To_Subprogram_Type (E)
           and then Ekind (E) = E_Access_Subprogram_Type
           and then Expander_Active
           and then Get_PCS_Name /= Name_No_DSA
         then
            Rewrite (N, New_Occurrence_Of (Equivalent_Type (E), Sloc (N)));
            goto Done;
         end if;

         --  Set the entity. Note that the reason we call Set_Entity for the
         --  overloadable case, as opposed to Set_Entity_With_Checks is
         --  that in the overloaded case, the initial call can set the wrong
         --  homonym. The call that sets the right homonym is in Sem_Res and
         --  that call does use Set_Entity_With_Checks, so we don't miss
         --  a style check.

         if Is_Overloadable (E) then
            Set_Entity (N, E);
         else
            Set_Entity_With_Checks (N, E);
         end if;

         if Is_Type (E) then
            Set_Etype (N, E);
         else
            Set_Etype (N, Get_Full_View (Etype (E)));
         end if;

         if Debug_Flag_E then
            Write_Str (" found  ");
            Write_Entity_Info (E, "      ");
         end if;

         --  If the Ekind of the entity is Void, it means that all homonyms
         --  are hidden from all visibility (RM 8.3(5,14-20)). However, this
         --  test is skipped if the current scope is a record and the name is
         --  a pragma argument expression (case of Atomic and Volatile pragmas
         --  and possibly other similar pragmas added later, which are allowed
         --  to reference components in the current record).

         if Ekind (E) = E_Void
           and then
             (not Is_Record_Type (Current_Scope)
               or else Nkind (Parent (N)) /= N_Pragma_Argument_Association)
         then
            Premature_Usage (N);

         --  If the entity is overloadable, collect all interpretations of the
         --  name for subsequent overload resolution. We optimize a bit here to
         --  do this only if we have an overloadable entity that is not on its
         --  own on the homonym chain.

         elsif Is_Overloadable (E)
           and then (Present (Homonym (E)) or else Current_Entity (N) /= E)
         then
            Collect_Interps (N);

            --  If no homonyms were visible, the entity is unambiguous

            if not Is_Overloaded (N) then
               if not Is_Actual_Parameter then
                  Generate_Reference (E, N);
               end if;
            end if;

         --  Case of non-overloadable entity, set the entity providing that
         --  we do not have the case of a discriminant reference within a
         --  default expression. Such references are replaced with the
         --  corresponding discriminal, which is the formal corresponding to
         --  to the discriminant in the initialization procedure.

         else
            --  Entity is unambiguous, indicate that it is referenced here

            --  For a renaming of an object, always generate simple reference,
            --  we don't try to keep track of assignments in this case, except
            --  in SPARK mode where renamings are traversed for generating
            --  local effects of subprograms.

            if Is_Object (E)
              and then Present (Renamed_Object (E))
              and then not GNATprove_Mode
            then
               Generate_Reference (E, N);

               --  If the renamed entity is a private protected component,
               --  reference the original component as well. This needs to be
               --  done because the private renamings are installed before any
               --  analysis has occurred. Reference to a private component will
               --  resolve to the renaming and the original component will be
               --  left unreferenced, hence the following.

               if Is_Prival (E) then
                  Generate_Reference (Prival_Link (E), N);
               end if;

            --  One odd case is that we do not want to set the Referenced flag
            --  if the entity is a label, and the identifier is the label in
            --  the source, since this is not a reference from the point of
            --  view of the user.

            elsif Nkind (Parent (N)) = N_Label then
               declare
                  R : constant Boolean := Referenced (E);

               begin
                  --  Generate reference unless this is an actual parameter
                  --  (see comment below).

                  if not Is_Actual_Parameter then
                     Generate_Reference (E, N);
                     Set_Referenced (E, R);
                  end if;
               end;

            --  Normal case, not a label: generate reference

            else
               if not Is_Actual_Parameter then

                  --  Package or generic package is always a simple reference

                  if Is_Package_Or_Generic_Package (E) then
                     Generate_Reference (E, N, 'r');

                  --  Else see if we have a left hand side

                  else
                     case Is_LHS (N) is
                        when Yes =>
                           Generate_Reference (E, N, 'm');

                        when No =>
                           Generate_Reference (E, N, 'r');

                        --  If we don't know now, generate reference later

                        when Unknown =>
                           Defer_Reference ((E, N));
                     end case;
                  end if;
               end if;
            end if;

            Set_Entity_Or_Discriminal (N, E);

            --  The name may designate a generalized reference, in which case
            --  the dereference interpretation will be included. Context is
            --  one in which a name is legal.

            if Ada_Version >= Ada_2012
              and then
                (Nkind (Parent (N)) in N_Subexpr
                  or else Nkind (Parent (N)) in N_Assignment_Statement
                                              | N_Object_Declaration
                                              | N_Parameter_Association)
            then
               Check_Implicit_Dereference (N, Etype (E));
            end if;
         end if;
      end;

      --  Mark relevant use-type and use-package clauses as effective if the
      --  node in question is not overloaded and therefore does not require
      --  resolution.
      --
      --  Note: Generic actual subprograms do not follow the normal resolution
      --  path, so ignore the fact that they are overloaded and mark them
      --  anyway.

      if Nkind (N) not in N_Subexpr or else not Is_Overloaded (N) then
         Mark_Use_Clauses (N);
      end if;

   --  Come here with entity set

   <<Done>>
      Check_Restriction_No_Use_Of_Entity (N);

      --  Annotate the tree by creating a variable reference marker in case the
      --  original variable reference is folded or optimized away. The variable
      --  reference marker is automatically saved for later examination by the
      --  ABE Processing phase. Variable references which act as actuals in a
      --  call require special processing and are left to Resolve_Actuals. The
      --  reference is a write when it appears on the left hand side of an
      --  assignment.

      if Needs_Variable_Reference_Marker (N => N, Calls_OK => False) then
         declare
            Is_Assignment_LHS : constant Boolean := Is_LHS (N) = Yes;

         begin
            Build_Variable_Reference_Marker
              (N     => N,
               Read  => not Is_Assignment_LHS,
               Write => Is_Assignment_LHS);
         end;
      end if;
   end Find_Direct_Name;

   ------------------------
   -- Find_Expanded_Name --
   ------------------------

   --  This routine searches the homonym chain of the entity until it finds
   --  an entity declared in the scope denoted by the prefix. If the entity
   --  is private, it may nevertheless be immediately visible, if we are in
   --  the scope of its declaration.

   procedure Find_Expanded_Name (N : Node_Id) is
      function In_Abstract_View_Pragma (Nod : Node_Id) return Boolean;
      --  Determine whether expanded name Nod appears within a pragma which is
      --  a suitable context for an abstract view of a state or variable. The
      --  following pragmas fall in this category:
      --    Depends
      --    Global
      --    Initializes
      --    Refined_Depends
      --    Refined_Global
      --
      --  In addition, pragma Abstract_State is also considered suitable even
      --  though it is an illegal context for an abstract view as this allows
      --  for proper resolution of abstract views of variables. This illegal
      --  context is later flagged in the analysis of indicator Part_Of.

      -----------------------------
      -- In_Abstract_View_Pragma --
      -----------------------------

      function In_Abstract_View_Pragma (Nod : Node_Id) return Boolean is
         Par : Node_Id;

      begin
         --  Climb the parent chain looking for a pragma

         Par := Nod;
         while Present (Par) loop
            if Nkind (Par) = N_Pragma then
               if Pragma_Name_Unmapped (Par)
                    in Name_Abstract_State
                     | Name_Depends
                     | Name_Global
                     | Name_Initializes
                     | Name_Refined_Depends
                     | Name_Refined_Global
               then
                  return True;

               --  Otherwise the pragma is not a legal context for an abstract
               --  view.

               else
                  exit;
               end if;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);
         end loop;

         return False;
      end In_Abstract_View_Pragma;

      --  Local variables

      Selector : constant Node_Id := Selector_Name (N);

      Candidate : Entity_Id := Empty;
      P_Name    : Entity_Id;
      Id        : Entity_Id;

   --  Start of processing for Find_Expanded_Name

   begin
      P_Name := Entity (Prefix (N));

      --  If the prefix is a renamed package, look for the entity in the
      --  original package.

      if Ekind (P_Name) = E_Package
        and then Present (Renamed_Object (P_Name))
      then
         P_Name := Renamed_Object (P_Name);

         if From_Limited_With (P_Name)
           and then not Unit_Is_Visible (Cunit (Get_Source_Unit (P_Name)))
         then
            Error_Msg_NE
              ("renaming of limited view of package & not usable in this"
               & " context (RM 8.5.3(3.1/2))", Prefix (N), P_Name);

         elsif Has_Limited_View (P_Name)
           and then not Unit_Is_Visible (Cunit (Get_Source_Unit (P_Name)))
           and then not Is_Visible_Through_Renamings (P_Name)
         then
            Error_Msg_NE
              ("renaming of limited view of package & not usable in this"
               & " context (RM 8.5.3(3.1/2))", Prefix (N), P_Name);
         end if;

         --  Rewrite node with entity field pointing to renamed object

         Rewrite (Prefix (N), New_Copy (Prefix (N)));
         Set_Entity (Prefix (N), P_Name);

      --  If the prefix is an object of a concurrent type, look for
      --  the entity in the associated task or protected type.

      elsif Is_Concurrent_Type (Etype (P_Name)) then
         P_Name := Etype (P_Name);
      end if;

      Id := Current_Entity (Selector);

      declare
         Is_New_Candidate : Boolean;

      begin
         while Present (Id) loop
            if Scope (Id) = P_Name then
               Candidate        := Id;
               Is_New_Candidate := True;

               --  Handle abstract views of states and variables. These are
               --  acceptable candidates only when the reference to the view
               --  appears in certain pragmas.

               if Ekind (Id) = E_Abstract_State
                 and then From_Limited_With (Id)
                 and then Present (Non_Limited_View (Id))
               then
                  if In_Abstract_View_Pragma (N) then
                     Candidate        := Non_Limited_View (Id);
                     Is_New_Candidate := True;

                  --  Hide the candidate because it is not used in a proper
                  --  context.

                  else
                     Candidate        := Empty;
                     Is_New_Candidate := False;
                  end if;
               end if;

            --  Ada 2005 (AI-217): Handle shadow entities associated with
            --  types declared in limited-withed nested packages. We don't need
            --  to handle E_Incomplete_Subtype entities because the entities
            --  in the limited view are always E_Incomplete_Type and
            --  E_Class_Wide_Type entities (see Build_Limited_Views).

            --  Regarding the expression used to evaluate the scope, it
            --  is important to note that the limited view also has shadow
            --  entities associated nested packages. For this reason the
            --  correct scope of the entity is the scope of the real entity.
            --  The non-limited view may itself be incomplete, in which case
            --  get the full view if available.

            elsif Ekind (Id) in E_Incomplete_Type | E_Class_Wide_Type
              and then From_Limited_With (Id)
              and then Present (Non_Limited_View (Id))
              and then Scope (Non_Limited_View (Id)) = P_Name
            then
               Candidate        := Get_Full_View (Non_Limited_View (Id));
               Is_New_Candidate := True;

            --  Handle special case where the prefix is a renaming of a shadow
            --  package which is visible. Required to avoid reporting spurious
            --  errors.

            elsif Ekind (P_Name) = E_Package
              and then From_Limited_With (P_Name)
              and then not From_Limited_With (Id)
              and then Sloc (Scope (Id)) = Sloc (P_Name)
              and then Unit_Is_Visible (Cunit (Get_Source_Unit (P_Name)))
            then
               Candidate        := Get_Full_View (Id);
               Is_New_Candidate := True;

            --  An unusual case arises with a fully qualified name for an
            --  entity local to a generic child unit package, within an
            --  instantiation of that package. The name of the unit now
            --  denotes the renaming created within the instance. This is
            --  only relevant in an instance body, see below.

            elsif Is_Generic_Instance (Scope (Id))
              and then In_Open_Scopes (Scope (Id))
              and then In_Instance_Body
              and then Ekind (Scope (Id)) = E_Package
              and then Ekind (Id) = E_Package
              and then Renamed_Entity (Id) = Scope (Id)
              and then Is_Immediately_Visible (P_Name)
            then
               Is_New_Candidate := True;

            else
               Is_New_Candidate := False;
            end if;

            if Is_New_Candidate then

               --  If entity is a child unit, either it is a visible child of
               --  the prefix, or we are in the body of a generic prefix, as
               --  will happen when a child unit is instantiated in the body
               --  of a generic parent. This is because the instance body does
               --  not restore the full compilation context, given that all
               --  non-local references have been captured.

               if Is_Child_Unit (Id) or else P_Name = Standard_Standard then
                  exit when Is_Visible_Lib_Unit (Id)
                    or else (Is_Child_Unit (Id)
                              and then In_Open_Scopes (Scope (Id))
                              and then In_Instance_Body);
               else
                  exit when not Is_Hidden (Id);
               end if;

               exit when Is_Immediately_Visible (Id);
            end if;

            Id := Homonym (Id);
         end loop;
      end;

      if No (Id)
        and then Ekind (P_Name) in E_Procedure | E_Function
        and then Is_Generic_Instance (P_Name)
      then
         --  Expanded name denotes entity in (instance of) generic subprogram.
         --  The entity may be in the subprogram instance, or may denote one of
         --  the formals, which is declared in the enclosing wrapper package.

         P_Name := Scope (P_Name);

         Id := Current_Entity (Selector);
         while Present (Id) loop
            exit when Scope (Id) = P_Name;
            Id := Homonym (Id);
         end loop;
      end if;

      if No (Id) or else Chars (Id) /= Chars (Selector) then
         Set_Etype (N, Any_Type);

         --  If we are looking for an entity defined in System, try to find it
         --  in the child package that may have been provided as an extension
         --  to System. The Extend_System pragma will have supplied the name of
         --  the extension, which may have to be loaded.

         if Chars (P_Name) = Name_System
           and then Scope (P_Name) = Standard_Standard
           and then Present (System_Extend_Unit)
           and then Present_System_Aux (N)
         then
            Set_Entity (Prefix (N), System_Aux_Id);
            Find_Expanded_Name (N);
            return;

         --  There is an implicit instance of the predefined operator in
         --  the given scope. The operator entity is defined in Standard.
         --  Has_Implicit_Operator makes the node into an Expanded_Name.

         elsif Nkind (Selector) = N_Operator_Symbol
           and then Has_Implicit_Operator (N)
         then
            return;

         --  If there is no literal defined in the scope denoted by the
         --  prefix, the literal may belong to (a type derived from)
         --  Standard_Character, for which we have no explicit literals.

         elsif Nkind (Selector) = N_Character_Literal
           and then Has_Implicit_Character_Literal (N)
         then
            return;

         else
            --  If the prefix is a single concurrent object, use its name in
            --  the error message, rather than that of the anonymous type.

            if Is_Concurrent_Type (P_Name)
              and then Is_Internal_Name (Chars (P_Name))
            then
               Error_Msg_Node_2 := Entity (Prefix (N));
            else
               Error_Msg_Node_2 := P_Name;
            end if;

            if P_Name = System_Aux_Id then
               P_Name := Scope (P_Name);
               Set_Entity (Prefix (N), P_Name);
            end if;

            if Present (Candidate) then

               --  If we know that the unit is a child unit we can give a more
               --  accurate error message.

               if Is_Child_Unit (Candidate) then

                  --  If the candidate is a private child unit and we are in
                  --  the visible part of a public unit, specialize the error
                  --  message. There might be a private with_clause for it,
                  --  but it is not currently active.

                  if Is_Private_Descendant (Candidate)
                    and then Ekind (Current_Scope) = E_Package
                    and then not In_Private_Part (Current_Scope)
                    and then not Is_Private_Descendant (Current_Scope)
                  then
                     Error_Msg_N
                       ("private child unit& is not visible here", Selector);

                  --  Normal case where we have a missing with for a child unit

                  else
                     Error_Msg_Qual_Level := 99;
                     Error_Msg_NE -- CODEFIX
                       ("missing `WITH &;`", Selector, Candidate);
                     Error_Msg_Qual_Level := 0;
                  end if;

                  --  Here we don't know that this is a child unit

               else
                  Error_Msg_NE ("& is not a visible entity of&", N, Selector);
               end if;

            else
               --  Within the instantiation of a child unit, the prefix may
               --  denote the parent instance, but the selector has the name
               --  of the original child. That is to say, when A.B appears
               --  within an instantiation of generic child unit B, the scope
               --  stack includes an instance of A (P_Name) and an instance
               --  of B under some other name. We scan the scope to find this
               --  child instance, which is the desired entity.
               --  Note that the parent may itself be a child instance, if
               --  the reference is of the form A.B.C, in which case A.B has
               --  already been rewritten with the proper entity.

               if In_Open_Scopes (P_Name)
                 and then Is_Generic_Instance (P_Name)
               then
                  declare
                     Gen_Par : constant Entity_Id :=
                                 Generic_Parent (Specification
                                   (Unit_Declaration_Node (P_Name)));
                     S : Entity_Id := Current_Scope;
                     P : Entity_Id;

                  begin
                     for J in reverse 0 .. Scope_Stack.Last loop
                        S := Scope_Stack.Table (J).Entity;

                        exit when S = Standard_Standard;

                        if Ekind (S) in E_Function | E_Package | E_Procedure
                        then
                           P :=
                             Generic_Parent (Specification
                               (Unit_Declaration_Node (S)));

                           --  Check that P is a generic child of the generic
                           --  parent of the prefix.

                           if Present (P)
                             and then Chars (P) = Chars (Selector)
                             and then Scope (P) = Gen_Par
                           then
                              Id := S;
                              goto Found;
                           end if;
                        end if;

                     end loop;
                  end;
               end if;

               --  If this is a selection from Ada, System or Interfaces, then
               --  we assume a missing with for the corresponding package.

               if Is_Known_Unit (N)
                 and then not (Present (Entity (Prefix (N)))
                                and then Scope (Entity (Prefix (N))) /=
                                           Standard_Standard)
               then
                  if not Error_Posted (N) then
                     Error_Msg_Node_2 := Selector;
                     Error_Msg_N -- CODEFIX
                       ("missing `WITH &.&;`", Prefix (N));
                  end if;

               --  If this is a selection from a dummy package, then suppress
               --  the error message, of course the entity is missing if the
               --  package is missing.

               elsif Sloc (Error_Msg_Node_2) = No_Location then
                  null;

               --  Here we have the case of an undefined component

               else
                  --  The prefix may hide a homonym in the context that
                  --  declares the desired entity. This error can use a
                  --  specialized message.

                  if In_Open_Scopes (P_Name) then
                     declare
                        H : constant Entity_Id := Homonym (P_Name);

                     begin
                        if Present (H)
                          and then Is_Compilation_Unit (H)
                          and then
                            (Is_Immediately_Visible (H)
                              or else Is_Visible_Lib_Unit (H))
                        then
                           Id := First_Entity (H);
                           while Present (Id) loop
                              if Chars (Id) = Chars (Selector) then
                                 Error_Msg_Qual_Level := 99;
                                 Error_Msg_Name_1 := Chars (Selector);
                                 Error_Msg_NE
                                   ("% not declared in&", N, P_Name);
                                 Error_Msg_NE
                                   ("\use fully qualified name starting with "
                                    & "Standard to make& visible", N, H);
                                 Error_Msg_Qual_Level := 0;
                                 goto Done;
                              end if;

                              Next_Entity (Id);
                           end loop;
                        end if;

                        --  If not found, standard error message

                        Error_Msg_NE ("& not declared in&", N, Selector);

                        <<Done>> null;
                     end;

                  else
                     --  Might be worth specializing the case when the prefix
                     --  is a limited view.
                     --  ... not declared in limited view of...

                     Error_Msg_NE ("& not declared in&", N, Selector);
                  end if;

                  --  Check for misspelling of some entity in prefix

                  Id := First_Entity (P_Name);
                  while Present (Id) loop
                     if Is_Bad_Spelling_Of (Chars (Id), Chars (Selector))
                       and then not Is_Internal_Name (Chars (Id))
                     then
                        Error_Msg_NE -- CODEFIX
                          ("possible misspelling of&", Selector, Id);
                        exit;
                     end if;

                     Next_Entity (Id);
                  end loop;

                  --  Specialize the message if this may be an instantiation
                  --  of a child unit that was not mentioned in the context.

                  if Nkind (Parent (N)) = N_Package_Instantiation
                    and then Is_Generic_Instance (Entity (Prefix (N)))
                    and then Is_Compilation_Unit
                               (Generic_Parent (Parent (Entity (Prefix (N)))))
                  then
                     Error_Msg_Node_2 := Selector;
                     Error_Msg_N -- CODEFIX
                       ("\missing `WITH &.&;`", Prefix (N));
                  end if;
               end if;
            end if;

            Id := Any_Id;
         end if;
      end if;

      <<Found>>
      if Comes_From_Source (N)
        and then Is_Remote_Access_To_Subprogram_Type (Id)
        and then Ekind (Id) = E_Access_Subprogram_Type
        and then Present (Equivalent_Type (Id))
      then
         --  If we are not actually generating distribution code (i.e. the
         --  current PCS is the dummy non-distributed version), then the
         --  Equivalent_Type will be missing, and Id should be treated as
         --  a regular access-to-subprogram type.

         Id := Equivalent_Type (Id);
         Set_Chars (Selector, Chars (Id));
      end if;

      --  Ada 2005 (AI-50217): Check usage of entities in limited withed units

      if Ekind (P_Name) = E_Package and then From_Limited_With (P_Name) then
         if From_Limited_With (Id)
           or else Is_Type (Id)
           or else Ekind (Id) = E_Package
         then
            null;
         else
            Error_Msg_N
              ("limited withed package can only be used to access incomplete "
               & "types", N);
         end if;
      end if;

      if Is_Task_Type (P_Name)
        and then ((Ekind (Id) = E_Entry
                    and then Nkind (Parent (N)) /= N_Attribute_Reference)
                   or else
                     (Ekind (Id) = E_Entry_Family
                       and then
                         Nkind (Parent (Parent (N))) /= N_Attribute_Reference))
      then
         --  If both the task type and the entry are in scope, this may still
         --  be the expanded name of an entry formal.

         if In_Open_Scopes (Id)
           and then Nkind (Parent (N)) = N_Selected_Component
         then
            null;

         else
            --  It is an entry call after all, either to the current task
            --  (which will deadlock) or to an enclosing task.

            Analyze_Selected_Component (N);
            return;
         end if;
      end if;

      case Nkind (N) is
         when N_Selected_Component =>
            Reinit_Field_To_Zero (N, F_Is_Prefixed_Call);
            Change_Selected_Component_To_Expanded_Name (N);

         when N_Expanded_Name =>
            null;

         when others =>
            pragma Assert (False);
      end case;

      --  Preserve relevant elaboration-related attributes of the context which
      --  are no longer available or very expensive to recompute once analysis,
      --  resolution, and expansion are over.

      Mark_Elaboration_Attributes
        (N_Id     => N,
         Checks   => True,
         Modes    => True,
         Warnings => True);

      --  Set appropriate type

      if Is_Type (Id) then
         Set_Etype (N, Id);
      else
         Set_Etype (N, Get_Full_View (Etype (Id)));
      end if;

      --  Do style check and generate reference, but skip both steps if this
      --  entity has homonyms, since we may not have the right homonym set yet.
      --  The proper homonym will be set during the resolve phase.

      if Has_Homonym (Id) then
         Set_Entity (N, Id);

      else
         Set_Entity_Or_Discriminal (N, Id);

         case Is_LHS (N) is
            when Yes =>
               Generate_Reference (Id, N, 'm');

            when No =>
               Generate_Reference (Id, N, 'r');

            when Unknown =>
               Defer_Reference ((Id, N));
         end case;
      end if;

      --  Check for violation of No_Wide_Characters

      Check_Wide_Character_Restriction (Id, N);

      --  If the Ekind of the entity is Void, it means that all homonyms are
      --  hidden from all visibility (RM 8.3(5,14-20)).

      if Ekind (Id) = E_Void then
         Premature_Usage (N);

      elsif Is_Overloadable (Id) and then Present (Homonym (Id)) then
         declare
            H : Entity_Id := Homonym (Id);

         begin
            while Present (H) loop
               if Scope (H) = Scope (Id)
                 and then (not Is_Hidden (H)
                            or else Is_Immediately_Visible (H))
               then
                  Collect_Interps (N);
                  exit;
               end if;

               H := Homonym (H);
            end loop;

            --  If an extension of System is present, collect possible explicit
            --  overloadings declared in the extension.

            if Chars (P_Name) = Name_System
              and then Scope (P_Name) = Standard_Standard
              and then Present (System_Extend_Unit)
              and then Present_System_Aux (N)
            then
               H := Current_Entity (Id);

               while Present (H) loop
                  if Scope (H) = System_Aux_Id then
                     Add_One_Interp (N, H, Etype (H));
                  end if;

                  H := Homonym (H);
               end loop;
            end if;
         end;
      end if;

      if Nkind (Selector_Name (N)) = N_Operator_Symbol
        and then Scope (Id) /= Standard_Standard
      then
         --  In addition to user-defined operators in the given scope, there
         --  may be an implicit instance of the predefined operator. The
         --  operator (defined in Standard) is found in Has_Implicit_Operator,
         --  and added to the interpretations. Procedure Add_One_Interp will
         --  determine which hides which.

         if Has_Implicit_Operator (N) then
            null;
         end if;
      end if;

      --  If there is a single interpretation for N we can generate a
      --  reference to the unique entity found.

      if Is_Overloadable (Id) and then not Is_Overloaded (N) then
         Generate_Reference (Id, N);
      end if;

      --  Mark relevant use-type and use-package clauses as effective if the
      --  node in question is not overloaded and therefore does not require
      --  resolution.

      if Nkind (N) not in N_Subexpr or else not Is_Overloaded (N) then
         Mark_Use_Clauses (N);
      end if;

      Check_Restriction_No_Use_Of_Entity (N);

      --  Annotate the tree by creating a variable reference marker in case the
      --  original variable reference is folded or optimized away. The variable
      --  reference marker is automatically saved for later examination by the
      --  ABE Processing phase. Variable references which act as actuals in a
      --  call require special processing and are left to Resolve_Actuals. The
      --  reference is a write when it appears on the left hand side of an
      --  assignment.

      if Needs_Variable_Reference_Marker
           (N        => N,
            Calls_OK => False)
      then
         declare
            Is_Assignment_LHS : constant Boolean := Is_LHS (N) = Yes;

         begin
            Build_Variable_Reference_Marker
              (N     => N,
               Read  => not Is_Assignment_LHS,
               Write => Is_Assignment_LHS);
         end;
      end if;
   end Find_Expanded_Name;

   --------------------
   -- Find_First_Use --
   --------------------

   function Find_First_Use (Use_Clause : Node_Id) return Node_Id is
      Curr : Node_Id;

   begin
      --  Loop through the Prev_Use_Clause chain

      Curr := Use_Clause;
      while Present (Prev_Use_Clause (Curr)) loop
         Curr := Prev_Use_Clause (Curr);
      end loop;

      return Curr;
   end Find_First_Use;

   -------------------------
   -- Find_Renamed_Entity --
   -------------------------

   function Find_Renamed_Entity
     (N         : Node_Id;
      Nam       : Node_Id;
      New_S     : Entity_Id;
      Is_Actual : Boolean := False) return Entity_Id
   is
      Ind   : Interp_Index;
      I1    : Interp_Index := 0; -- Suppress junk warnings
      It    : Interp;
      It1   : Interp;
      Old_S : Entity_Id;
      Inst  : Entity_Id;

      function Find_Nearer_Entity
        (New_S  : Entity_Id;
         Old1_S : Entity_Id;
         Old2_S : Entity_Id) return Entity_Id;
      --  Determine whether one of Old_S1 and Old_S2 is nearer to New_S than
      --  the other, and return it if so. Return Empty otherwise. We use this
      --  in conjunction with Inherit_Renamed_Profile to simplify later type
      --  disambiguation for actual subprograms in instances.

      function Is_Visible_Operation (Op : Entity_Id) return Boolean;
      --  If the renamed entity is an implicit operator, check whether it is
      --  visible because its operand type is properly visible. This check
      --  applies to explicit renamed entities that appear in the source in a
      --  renaming declaration or a formal subprogram instance, but not to
      --  default generic actuals with a name.

      function Report_Overload return Entity_Id;
      --  List possible interpretations, and specialize message in the
      --  case of a generic actual.

      function Within (Inner, Outer : Entity_Id) return Boolean;
      --  Determine whether a candidate subprogram is defined within the
      --  enclosing instance. If yes, it has precedence over outer candidates.

      --------------------------
      --  Find_Nearer_Entity  --
      --------------------------

      function Find_Nearer_Entity
        (New_S  : Entity_Id;
         Old1_S : Entity_Id;
         Old2_S : Entity_Id) return Entity_Id
      is
         New_F  : Entity_Id;
         Old1_F : Entity_Id;
         Old2_F : Entity_Id;
         Anc_T  : Entity_Id;

      begin
         New_F  := First_Formal (New_S);
         Old1_F := First_Formal (Old1_S);
         Old2_F := First_Formal (Old2_S);

         --  The criterion is whether the type of the formals of one of Old1_S
         --  and Old2_S is an ancestor subtype of the type of the corresponding
         --  formals of New_S while the other is not (we already know that they
         --  are all subtypes of the same base type).

         --  This makes it possible to find the more correct renamed entity in
         --  the case of a generic instantiation nested in an enclosing one for
         --  which different formal types get the same actual type, which will
         --  in turn make it possible for Inherit_Renamed_Profile to preserve
         --  types on formal parameters and ultimately simplify disambiguation.

         --  Consider the follow package G:

         --    generic
         --       type Item_T is private;
         --       with function Compare (L, R: Item_T) return Boolean is <>;

         --       type Bound_T is private;
         --       with function Compare (L, R : Bound_T) return Boolean is <>;
         --    package G is
         --       ...
         --    end G;

         --    package body G is
         --       package My_Inner is Inner_G (Bound_T);
         --       ...
         --    end G;

         --    with the following package Inner_G:

         --    generic
         --       type T is private;
         --       with function Compare (L, R: T) return Boolean is <>;
         --    package Inner_G is
         --       function "<" (L, R: T) return Boolean is (Compare (L, R));
         --    end Inner_G;

         --  If G is instantiated on the same actual type with a single Compare
         --  function:

         --    type T is ...
         --    function Compare (L, R : T) return Boolean;
         --    package My_G is new (T, T);

         --  then the renaming generated for Compare in the inner instantiation
         --  is ambiguous: it can rename either of the renamings generated for
         --  the outer instantiation. Now if the first one is picked up, then
         --  the subtypes of the formal parameters of the renaming will not be
         --  preserved in Inherit_Renamed_Profile because they are subtypes of
         --  the Bound_T formal type and not of the Item_T formal type, so we
         --  need to arrange for the second one to be picked up instead.

         while Present (New_F) loop
            if Etype (Old1_F) /= Etype (Old2_F) then
               Anc_T := Ancestor_Subtype (Etype (New_F));

               if Etype (Old1_F) = Anc_T then
                  return Old1_S;
               elsif Etype (Old2_F) = Anc_T then
                  return Old2_S;
               end if;
            end if;

            Next_Formal (New_F);
            Next_Formal (Old1_F);
            Next_Formal (Old2_F);
         end loop;

         pragma Assert (No (Old1_F));
         pragma Assert (No (Old2_F));

         return Empty;
      end Find_Nearer_Entity;

      --------------------------
      -- Is_Visible_Operation --
      --------------------------

      function Is_Visible_Operation (Op : Entity_Id) return Boolean is
         Scop : Entity_Id;
         Typ  : Entity_Id;
         Btyp : Entity_Id;

      begin
         if Ekind (Op) /= E_Operator
           or else Scope (Op) /= Standard_Standard
           or else (In_Instance
                     and then (not Is_Actual
                                or else Present (Enclosing_Instance)))
         then
            return True;

         else
            --  For a fixed point type operator, check the resulting type,
            --  because it may be a mixed mode integer * fixed operation.

            if Present (Next_Formal (First_Formal (New_S)))
              and then Is_Fixed_Point_Type (Etype (New_S))
            then
               Typ := Etype (New_S);
            else
               Typ := Etype (First_Formal (New_S));
            end if;

            Btyp := Base_Type (Typ);

            if Nkind (Nam) /= N_Expanded_Name then
               return (In_Open_Scopes (Scope (Btyp))
                        or else Is_Potentially_Use_Visible (Btyp)
                        or else In_Use (Btyp)
                        or else In_Use (Scope (Btyp)));

            else
               Scop := Entity (Prefix (Nam));

               if Ekind (Scop) = E_Package
                 and then Present (Renamed_Object (Scop))
               then
                  Scop := Renamed_Object (Scop);
               end if;

               --  Operator is visible if prefix of expanded name denotes
               --  scope of type, or else type is defined in System_Aux
               --  and the prefix denotes System.

               return Scope (Btyp) = Scop
                 or else (Scope (Btyp) = System_Aux_Id
                           and then Scope (Scope (Btyp)) = Scop);
            end if;
         end if;
      end Is_Visible_Operation;

      ------------
      -- Within --
      ------------

      function Within (Inner, Outer : Entity_Id) return Boolean is
         Sc : Entity_Id;

      begin
         Sc := Scope (Inner);
         while Sc /= Standard_Standard loop
            if Sc = Outer then
               return True;
            else
               Sc := Scope (Sc);
            end if;
         end loop;

         return False;
      end Within;

      ---------------------
      -- Report_Overload --
      ---------------------

      function Report_Overload return Entity_Id is
      begin
         if Is_Actual then
            Error_Msg_NE -- CODEFIX
              ("ambiguous actual subprogram&, " &
                 "possible interpretations:", N, Nam);
         else
            Error_Msg_N -- CODEFIX
              ("ambiguous subprogram, " &
                 "possible interpretations:", N);
         end if;

         List_Interps (Nam, N);
         return Old_S;
      end Report_Overload;

   --  Start of processing for Find_Renamed_Entity

   begin
      Old_S := Any_Id;
      Candidate_Renaming := Empty;

      if Is_Overloaded (Nam) then
         Get_First_Interp (Nam, Ind, It);
         while Present (It.Nam) loop
            if Entity_Matches_Spec (It.Nam, New_S)
              and then Is_Visible_Operation (It.Nam)
            then
               if Old_S /= Any_Id then

                  --  Note: The call to Disambiguate only happens if a
                  --  previous interpretation was found, in which case I1
                  --  has received a value.

                  It1 := Disambiguate (Nam, I1, Ind, Etype (Old_S));

                  if It1 = No_Interp then
                     Inst := Enclosing_Instance;

                     if Present (Inst) then
                        if Within (It.Nam, Inst) then
                           if Within (Old_S, Inst) then
                              declare
                                 It_D  : constant Uint := Scope_Depth (It.Nam);
                                 Old_D : constant Uint := Scope_Depth (Old_S);
                                 N_Ent : Entity_Id;
                              begin
                                 --  Choose the innermost subprogram, which
                                 --  would hide the outer one in the generic.

                                 if Old_D > It_D then
                                    return Old_S;
                                 elsif It_D > Old_D then
                                    return It.Nam;
                                 end if;

                                 --  Otherwise, if we can determine that one
                                 --  of the entities is nearer to the renaming
                                 --  than the other, choose it. If not, then
                                 --  return the newer one as done historically.

                                 N_Ent :=
                                     Find_Nearer_Entity (New_S, Old_S, It.Nam);
                                 if Present (N_Ent) then
                                    return N_Ent;
                                 else
                                    return It.Nam;
                                 end if;
                              end;
                           end if;

                        elsif Within (Old_S, Inst) then
                           return Old_S;

                        else
                           return Report_Overload;
                        end if;

                     --  If not within an instance, ambiguity is real

                     else
                        return Report_Overload;
                     end if;

                  else
                     Old_S := It1.Nam;
                     exit;
                  end if;

               else
                  I1 := Ind;
                  Old_S := It.Nam;
               end if;

            elsif
              Present (First_Formal (It.Nam))
                and then Present (First_Formal (New_S))
                and then (Base_Type (Etype (First_Formal (It.Nam))) =
                          Base_Type (Etype (First_Formal (New_S))))
            then
               Candidate_Renaming := It.Nam;
            end if;

            Get_Next_Interp (Ind, It);
         end loop;

         Set_Entity (Nam, Old_S);

         if Old_S /= Any_Id then
            Set_Is_Overloaded (Nam, False);
         end if;

      --  Non-overloaded case

      else
         if Is_Actual
           and then Present (Enclosing_Instance)
           and then Entity_Matches_Spec (Entity (Nam), New_S)
         then
            Old_S := Entity (Nam);

         elsif Entity_Matches_Spec (Entity (Nam), New_S) then
            Candidate_Renaming := New_S;

            if Is_Visible_Operation (Entity (Nam)) then
               Old_S := Entity (Nam);
            end if;

         elsif Present (First_Formal (Entity (Nam)))
           and then Present (First_Formal (New_S))
           and then (Base_Type (Etype (First_Formal (Entity (Nam)))) =
                     Base_Type (Etype (First_Formal (New_S))))
         then
            Candidate_Renaming := Entity (Nam);
         end if;
      end if;

      return Old_S;
   end Find_Renamed_Entity;

   -----------------------------
   -- Find_Selected_Component --
   -----------------------------

   procedure Find_Selected_Component (N : Node_Id) is
      P : constant Node_Id := Prefix (N);

      P_Name : Entity_Id;
      --  Entity denoted by prefix

      P_Type : Entity_Id;
      --  and its type

      Nam : Node_Id;

      function Available_Subtype return Boolean;
      --  A small optimization: if the prefix is constrained and the component
      --  is an array type we may already have a usable subtype for it, so we
      --  can use it rather than generating a new one, because the bounds
      --  will be the values of the discriminants and not discriminant refs.
      --  This simplifies value tracing in GNATprove. For consistency, both
      --  the entity name and the subtype come from the constrained component.

      --  This is only used in GNATprove mode: when generating code it may be
      --  necessary to create an itype in the scope of use of the selected
      --  component, e.g. in the context of a expanded record equality.

      function Is_Reference_In_Subunit return Boolean;
      --  In a subunit, the scope depth is not a proper measure of hiding,
      --  because the context of the proper body may itself hide entities in
      --  parent units. This rare case requires inspecting the tree directly
      --  because the proper body is inserted in the main unit and its context
      --  is simply added to that of the parent.

      -----------------------
      -- Available_Subtype --
      -----------------------

      function Available_Subtype return Boolean is
         Comp : Entity_Id;

      begin
         if GNATprove_Mode then
            Comp := First_Entity (Etype (P));
            while Present (Comp) loop
               if Chars (Comp) = Chars (Selector_Name (N)) then
                  Set_Etype  (N, Etype (Comp));
                  Set_Entity (Selector_Name (N), Comp);
                  Set_Etype  (Selector_Name (N), Etype (Comp));
                  return True;
               end if;

               Next_Component (Comp);
            end loop;
         end if;

         return False;
      end Available_Subtype;

      -----------------------------
      -- Is_Reference_In_Subunit --
      -----------------------------

      function Is_Reference_In_Subunit return Boolean is
         Clause    : Node_Id;
         Comp_Unit : Node_Id;

      begin
         Comp_Unit := N;
         while Present (Comp_Unit)
           and then Nkind (Comp_Unit) /= N_Compilation_Unit
         loop
            Comp_Unit := Parent (Comp_Unit);
         end loop;

         if No (Comp_Unit) or else Nkind (Unit (Comp_Unit)) /= N_Subunit then
            return False;
         end if;

         --  Now check whether the package is in the context of the subunit

         Clause := First (Context_Items (Comp_Unit));
         while Present (Clause) loop
            if Nkind (Clause) = N_With_Clause
              and then Entity (Name (Clause)) = P_Name
            then
               return True;
            end if;

            Next (Clause);
         end loop;

         return False;
      end Is_Reference_In_Subunit;

   --  Start of processing for Find_Selected_Component

   begin
      Analyze (P);

      if Nkind (P) = N_Error then
         return;
      end if;

      --  If the selector already has an entity, the node has been constructed
      --  in the course of expansion, and is known to be valid. Do not verify
      --  that it is defined for the type (it may be a private component used
      --  in the expansion of record equality).

      if Present (Entity (Selector_Name (N))) then
         if No (Etype (N)) or else Etype (N) = Any_Type then
            declare
               Sel_Name : constant Node_Id   := Selector_Name (N);
               Selector : constant Entity_Id := Entity (Sel_Name);
               C_Etype  : Node_Id;

            begin
               Set_Etype (Sel_Name, Etype (Selector));

               if not Is_Entity_Name (P) then
                  Resolve (P);
               end if;

               --  Build an actual subtype except for the first parameter
               --  of an init proc, where this actual subtype is by
               --  definition incorrect, since the object is uninitialized
               --  (and does not even have defined discriminants etc.)

               if Is_Entity_Name (P)
                 and then Ekind (Entity (P)) = E_Function
               then
                  Nam := New_Copy (P);

                  if Is_Overloaded (P) then
                     Save_Interps (P, Nam);
                  end if;

                  Rewrite (P, Make_Function_Call (Sloc (P), Name => Nam));
                  Analyze_Call (P);
                  Analyze_Selected_Component (N);
                  return;

               elsif Ekind (Selector) = E_Component
                 and then (not Is_Entity_Name (P)
                            or else Chars (Entity (P)) /= Name_uInit)
               then
                  --  Check if we already have an available subtype we can use

                  if Ekind (Etype (P)) = E_Record_Subtype
                    and then Nkind (Parent (Etype (P))) = N_Subtype_Declaration
                    and then Is_Array_Type (Etype (Selector))
                    and then not Is_Packed (Etype (Selector))
                    and then Available_Subtype
                  then
                     return;

                  --  Do not build the subtype when referencing components of
                  --  dispatch table wrappers. Required to avoid generating
                  --  elaboration code with HI runtimes.

                  elsif Is_RTE (Scope (Selector), RE_Dispatch_Table_Wrapper)
                    or else
                      Is_RTE (Scope (Selector), RE_No_Dispatch_Table_Wrapper)
                  then
                     C_Etype := Empty;
                  else
                     C_Etype :=
                       Build_Actual_Subtype_Of_Component
                         (Etype (Selector), N);
                  end if;

               else
                  C_Etype := Empty;
               end if;

               if No (C_Etype) then
                  C_Etype := Etype (Selector);
               else
                  Insert_Action (N, C_Etype);
                  C_Etype := Defining_Identifier (C_Etype);
               end if;

               Set_Etype (N, C_Etype);
            end;

         --  If the selected component appears within a default expression
         --  and it has an actual subtype, the preanalysis has not yet
         --  completed its analysis, because Insert_Actions is disabled in
         --  that context. Within the init proc of the enclosing type we
         --  must complete this analysis, if an actual subtype was created.

         elsif Inside_Init_Proc then
            declare
               Typ  : constant Entity_Id := Etype (N);
               Decl : constant Node_Id   := Declaration_Node (Typ);
            begin
               if Nkind (Decl) = N_Subtype_Declaration
                 and then not Analyzed (Decl)
                 and then Is_List_Member (Decl)
                 and then No (Parent (Decl))
               then
                  Remove (Decl);
                  Insert_Action (N, Decl);
               end if;
            end;
         end if;

         return;

      elsif Is_Entity_Name (P) then
         P_Name := Entity (P);

         --  The prefix may denote an enclosing type which is the completion
         --  of an incomplete type declaration.

         if Is_Type (P_Name) then
            Set_Entity (P, Get_Full_View (P_Name));
            Set_Etype  (P, Entity (P));
            P_Name := Entity (P);
         end if;

         P_Type := Base_Type (Etype (P));

         if Debug_Flag_E then
            Write_Str ("Found prefix type to be ");
            Write_Entity_Info (P_Type, "      "); Write_Eol;
         end if;

         --  If the prefix's type is an access type, get to the record type

         if Is_Access_Type (P_Type) then
            P_Type := Implicitly_Designated_Type (P_Type);
         end if;

         --  First check for components of a record object (not the result of
         --  a call, which is handled below). This also covers the case where
         --  where the extension feature that supports the prefixed form of
         --  calls for primitives of untagged types is enabled (excluding
         --  concurrent cases, which are handled further below).

         if Is_Type (P_Type)
           and then (Has_Components (P_Type)
                      or else (Extensions_Allowed
                                and then not Is_Concurrent_Type (P_Type)))
           and then not Is_Overloadable (P_Name)
           and then not Is_Type (P_Name)
         then
            --  Selected component of record. Type checking will validate
            --  name of selector.

            --  ??? Could we rewrite an implicit dereference into an explicit
            --  one here?

            Analyze_Selected_Component (N);

         --  Reference to type name in predicate/invariant expression

         elsif Is_Concurrent_Type (P_Type)
           and then not In_Open_Scopes (P_Name)
           and then (not Is_Concurrent_Type (Etype (P_Name))
                      or else not In_Open_Scopes (Etype (P_Name)))
         then
            --  Call to protected operation or entry. Type checking is
            --  needed on the prefix.

            Analyze_Selected_Component (N);

         elsif (In_Open_Scopes (P_Name)
                 and then Ekind (P_Name) /= E_Void
                 and then not Is_Overloadable (P_Name))
           or else (Is_Concurrent_Type (Etype (P_Name))
                     and then In_Open_Scopes (Etype (P_Name)))
         then
            --  Prefix denotes an enclosing loop, block, or task, i.e. an
            --  enclosing construct that is not a subprogram or accept.

            --  A special case: a protected body may call an operation
            --  on an external object of the same type, in which case it
            --  is not an expanded name. If the prefix is the type itself,
            --  or the context is a single synchronized object it can only
            --  be interpreted as an expanded name.

            if Is_Concurrent_Type (Etype (P_Name)) then
               if Is_Type (P_Name)
                  or else Present (Anonymous_Object (Etype (P_Name)))
               then
                  Find_Expanded_Name (N);

               else
                  Analyze_Selected_Component (N);
                  return;
               end if;

            else
               Find_Expanded_Name (N);
            end if;

         elsif Ekind (P_Name) = E_Package then
            Find_Expanded_Name (N);

         elsif Is_Overloadable (P_Name) then

            --  The subprogram may be a renaming (of an enclosing scope) as
            --  in the case of the name of the generic within an instantiation.

            if Ekind (P_Name) in E_Procedure | E_Function
              and then Present (Alias (P_Name))
              and then Is_Generic_Instance (Alias (P_Name))
            then
               P_Name := Alias (P_Name);
            end if;

            if Is_Overloaded (P) then

               --  The prefix must resolve to a unique enclosing construct

               declare
                  Found : Boolean := False;
                  Ind   : Interp_Index;
                  It    : Interp;

               begin
                  Get_First_Interp (P, Ind, It);
                  while Present (It.Nam) loop
                     if In_Open_Scopes (It.Nam) then
                        if Found then
                           Error_Msg_N (
                              "prefix must be unique enclosing scope", N);
                           Set_Entity (N, Any_Id);
                           Set_Etype  (N, Any_Type);
                           return;

                        else
                           Found := True;
                           P_Name := It.Nam;
                        end if;
                     end if;

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

            if In_Open_Scopes (P_Name) then
               Set_Entity (P, P_Name);
               Set_Is_Overloaded (P, False);
               Find_Expanded_Name (N);

            else
               --  If no interpretation as an expanded name is possible, it
               --  must be a selected component of a record returned by a
               --  function call. Reformat prefix as a function call, the rest
               --  is done by type resolution.

               --  Error if the prefix is procedure or entry, as is P.X

               if Ekind (P_Name) /= E_Function
                 and then
                   (not Is_Overloaded (P)
                     or else Nkind (Parent (N)) = N_Procedure_Call_Statement)
               then
                  --  Prefix may mention a package that is hidden by a local
                  --  declaration: let the user know. Scan the full homonym
                  --  chain, the candidate package may be anywhere on it.

                  if Present (Homonym (Current_Entity (P_Name))) then
                     P_Name := Current_Entity (P_Name);

                     while Present (P_Name) loop
                        exit when Ekind (P_Name) = E_Package;
                        P_Name := Homonym (P_Name);
                     end loop;

                     if Present (P_Name) then
                        if not Is_Reference_In_Subunit then
                           Error_Msg_Sloc := Sloc (Entity (Prefix (N)));
                           Error_Msg_NE
                             ("package& is hidden by declaration#", N, P_Name);
                        end if;

                        Set_Entity (Prefix (N), P_Name);
                        Find_Expanded_Name (N);
                        return;

                     else
                        P_Name := Entity (Prefix (N));
                     end if;
                  end if;

                  Error_Msg_NE
                    ("invalid prefix in selected component&", N, P_Name);
                  Change_Selected_Component_To_Expanded_Name (N);
                  Set_Entity (N, Any_Id);
                  Set_Etype (N, Any_Type);

               --  Here we have a function call, so do the reformatting

               else
                  Nam := New_Copy (P);
                  Save_Interps (P, Nam);

                  --  We use Replace here because this is one of those cases
                  --  where the parser has missclassified the node, and we fix
                  --  things up and then do the semantic analysis on the fixed
                  --  up node. Normally we do this using one of the Sinfo.CN
                  --  routines, but this is too tricky for that.

                  --  Note that using Rewrite would be wrong, because we would
                  --  have a tree where the original node is unanalyzed.

                  Replace (P,
                    Make_Function_Call (Sloc (P), Name => Nam));

                  --  Now analyze the reformatted node

                  Analyze_Call (P);

                  --  If the prefix is illegal after this transformation, there
                  --  may be visibility errors on the prefix. The safest is to
                  --  treat the selected component as an error.

                  if Error_Posted (P) then
                     Set_Etype (N, Any_Type);
                     return;

                  else
                     Analyze_Selected_Component (N);
                  end if;
               end if;
            end if;

         --  Remaining cases generate various error messages

         else
            --  Format node as expanded name, to avoid cascaded errors

            Change_Selected_Component_To_Expanded_Name (N);
            Set_Entity (N, Any_Id);
            Set_Etype  (N, Any_Type);

            --  Issue error message, but avoid this if error issued already.
            --  Use identifier of prefix if one is available.

            if P_Name = Any_Id then
               null;

            --  It is not an error if the prefix is the current instance of
            --  type name, e.g. the expression of a type aspect, when it is
            --  analyzed within a generic unit. We still have to verify that a
            --  component of that name exists, and decorate the node
            --  accordingly.

            elsif Is_Entity_Name (P) and then Is_Current_Instance (P) then
               declare
                  Comp : Entity_Id;

               begin
                  Comp := First_Entity (Entity (P));
                  while Present (Comp) loop
                     if Chars (Comp) = Chars (Selector_Name (N)) then
                        Set_Entity (N, Comp);
                        Set_Etype  (N, Etype (Comp));
                        Set_Entity (Selector_Name (N), Comp);
                        Set_Etype  (Selector_Name (N), Etype (Comp));
                        return;
                     end if;

                     Next_Entity (Comp);
                  end loop;
               end;

            elsif Ekind (P_Name) = E_Void then
               Premature_Usage (P);

            elsif Nkind (P) /= N_Attribute_Reference then

               --  This may have been meant as a prefixed call to a primitive
               --  of an untagged type. If it is a function call check type of
               --  its first formal and add explanation.

               declare
                  F : constant Entity_Id :=
                        Current_Entity (Selector_Name (N));
               begin
                  if Present (F)
                    and then Is_Overloadable (F)
                    and then Present (First_Entity (F))
                    and then not Is_Tagged_Type (Etype (First_Entity (F)))
                  then
                     Error_Msg_N
                       ("prefixed call is only allowed for objects of a "
                        & "tagged type", N);
                  end if;
               end;

               Error_Msg_N ("invalid prefix in selected component&", P);

               if Is_Incomplete_Type (P_Type)
                 and then Is_Access_Type (Etype (P))
               then
                  Error_Msg_N
                    ("\dereference must not be of an incomplete type "
                     & "(RM 3.10.1)", P);
               end if;

            else
               Error_Msg_N ("invalid prefix in selected component", P);
            end if;
         end if;
      else
         --  If prefix is not the name of an entity, it must be an expression,
         --  whose type is appropriate for a record. This is determined by
         --  type resolution.

         Analyze_Selected_Component (N);
      end if;

      Analyze_Dimension (N);
   end Find_Selected_Component;

   ---------------
   -- Find_Type --
   ---------------

   procedure Find_Type (N : Node_Id) is
      C      : Entity_Id;
      Typ    : Entity_Id;
      T      : Entity_Id;
      T_Name : Entity_Id;

   begin
      if N = Error then
         return;

      elsif Nkind (N) = N_Attribute_Reference then

         --  Class attribute. This is not valid in Ada 83 mode, but we do not
         --  need to enforce that at this point, since the declaration of the
         --  tagged type in the prefix would have been flagged already.

         if Attribute_Name (N) = Name_Class then
            Check_Restriction (No_Dispatch, N);
            Find_Type (Prefix (N));

            --  Propagate error from bad prefix

            if Etype (Prefix (N)) = Any_Type then
               Set_Entity (N, Any_Type);
               Set_Etype  (N, Any_Type);
               return;
            end if;

            T := Base_Type (Entity (Prefix (N)));

            --  Case where type is not known to be tagged. Its appearance in
            --  the prefix of the 'Class attribute indicates that the full view
            --  will be tagged.

            if not Is_Tagged_Type (T) then
               if Ekind (T) = E_Incomplete_Type then

                  --  It is legal to denote the class type of an incomplete
                  --  type. The full type will have to be tagged, of course.
                  --  In Ada 2005 this usage is declared obsolescent, so we
                  --  warn accordingly. This usage is only legal if the type
                  --  is completed in the current scope, and not for a limited
                  --  view of a type.

                  if Ada_Version >= Ada_2005 then

                     --  Test whether the Available_View of a limited type view
                     --  is tagged, since the limited view may not be marked as
                     --  tagged if the type itself has an untagged incomplete
                     --  type view in its package.

                     if From_Limited_With (T)
                       and then not Is_Tagged_Type (Available_View (T))
                     then
                        Error_Msg_N
                          ("prefix of Class attribute must be tagged", N);
                        Set_Etype (N, Any_Type);
                        Set_Entity (N, Any_Type);
                        return;

                     else
                        if Restriction_Check_Required (No_Obsolescent_Features)
                        then
                           Check_Restriction
                             (No_Obsolescent_Features, Prefix (N));
                        end if;

                        if Warn_On_Obsolescent_Feature then
                           Error_Msg_N
                             ("applying ''Class to an untagged incomplete type"
                              & " is an obsolescent feature (RM J.11)?r?", N);
                        end if;
                     end if;
                  end if;

                  Set_Is_Tagged_Type (T);
                  Set_Direct_Primitive_Operations (T, New_Elmt_List);
                  Make_Class_Wide_Type (T);
                  Set_Entity (N, Class_Wide_Type (T));
                  Set_Etype  (N, Class_Wide_Type (T));

               elsif Ekind (T) = E_Private_Type
                 and then not Is_Generic_Type (T)
                 and then In_Private_Part (Scope (T))
               then
                  --  The Class attribute can be applied to an untagged private
                  --  type fulfilled by a tagged type prior to the full type
                  --  declaration (but only within the parent package's private
                  --  part). Create the class-wide type now and check that the
                  --  full type is tagged later during its analysis. Note that
                  --  we do not mark the private type as tagged, unlike the
                  --  case of incomplete types, because the type must still
                  --  appear untagged to outside units.

                  if No (Class_Wide_Type (T)) then
                     Make_Class_Wide_Type (T);
                  end if;

                  Set_Entity (N, Class_Wide_Type (T));
                  Set_Etype  (N, Class_Wide_Type (T));

               else
                  --  Should we introduce a type Any_Tagged and use Wrong_Type
                  --  here, it would be a bit more consistent???

                  Error_Msg_NE
                    ("tagged type required, found}",
                     Prefix (N), First_Subtype (T));
                  Set_Entity (N, Any_Type);
                  return;
               end if;

            --  Case of tagged type

            else
               if Is_Concurrent_Type (T) then
                  if No (Corresponding_Record_Type (Entity (Prefix (N)))) then

                     --  Previous error. Create a class-wide type for the
                     --  synchronized type itself, with minimal semantic
                     --  attributes, to catch other errors in some ACATS tests.

                     pragma Assert (Serious_Errors_Detected /= 0);
                     Make_Class_Wide_Type (T);
                     C := Class_Wide_Type (T);
                     Set_First_Entity (C, First_Entity (T));

                  else
                     C := Class_Wide_Type
                            (Corresponding_Record_Type (Entity (Prefix (N))));
                  end if;

               else
                  C := Class_Wide_Type (Entity (Prefix (N)));
               end if;

               Set_Entity_With_Checks (N, C);
               Generate_Reference (C, N);
               Set_Etype (N, C);
            end if;

         --  Base attribute, not allowed in Ada 83

         elsif Attribute_Name (N) = Name_Base then
            if Ada_Version = Ada_83 and then Comes_From_Source (N) then
               Error_Msg_N
                 ("(Ada 83) Base attribute not allowed in subtype mark", N);

            else
               Find_Type (Prefix (N));
               Typ := Entity (Prefix (N));

               if Ada_Version >= Ada_95
                 and then not Is_Scalar_Type (Typ)
                 and then not Is_Generic_Type (Typ)
               then
                  Error_Msg_N
                    ("prefix of Base attribute must be scalar type",
                      Prefix (N));

               elsif Warn_On_Redundant_Constructs
                 and then Base_Type (Typ) = Typ
               then
                  Error_Msg_NE -- CODEFIX
                    ("redundant attribute, & is its own base type?r?", N, Typ);
               end if;

               T := Base_Type (Typ);

               --  Rewrite attribute reference with type itself (see similar
               --  processing in Analyze_Attribute, case Base). Preserve prefix
               --  if present, for other legality checks.

               if Nkind (Prefix (N)) = N_Expanded_Name then
                  Rewrite (N,
                     Make_Expanded_Name (Sloc (N),
                       Chars         => Chars (T),
                       Prefix        => New_Copy (Prefix (Prefix (N))),
                       Selector_Name => New_Occurrence_Of (T, Sloc (N))));

               else
                  Rewrite (N, New_Occurrence_Of (T, Sloc (N)));
               end if;

               Set_Entity (N, T);
               Set_Etype (N, T);
            end if;

         elsif Attribute_Name (N) = Name_Stub_Type then

            --  This is handled in Analyze_Attribute

            Analyze (N);

         --  All other attributes are invalid in a subtype mark

         else
            Error_Msg_N ("invalid attribute in subtype mark", N);
         end if;

      else
         Analyze (N);

         if Is_Entity_Name (N) then
            T_Name := Entity (N);
         else
            Error_Msg_N ("subtype mark required in this context", N);
            Set_Etype (N, Any_Type);
            return;
         end if;

         if T_Name  = Any_Id or else Etype (N) = Any_Type then

            --  Undefined id. Make it into a valid type

            Set_Entity (N, Any_Type);

         elsif not Is_Type (T_Name)
           and then T_Name /= Standard_Void_Type
         then
            Error_Msg_Sloc := Sloc (T_Name);
            Error_Msg_N ("subtype mark required in this context", N);
            Error_Msg_NE ("\\found & declared#", N, T_Name);
            Set_Entity (N, Any_Type);

         else
            --  If the type is an incomplete type created to handle
            --  anonymous access components of a record type, then the
            --  incomplete type is the visible entity and subsequent
            --  references will point to it. Mark the original full
            --  type as referenced, to prevent spurious warnings.

            if Is_Incomplete_Type (T_Name)
              and then Present (Full_View (T_Name))
              and then not Comes_From_Source (T_Name)
            then
               Set_Referenced (Full_View (T_Name));
            end if;

            T_Name := Get_Full_View (T_Name);

            --  Ada 2005 (AI-251, AI-50217): Handle interfaces visible through
            --  limited-with clauses

            if From_Limited_With (T_Name)
              and then Is_Incomplete_Type (T_Name)
              and then Present (Non_Limited_View (T_Name))
              and then Is_Interface (Non_Limited_View (T_Name))
            then
               T_Name := Non_Limited_View (T_Name);
            end if;

            if In_Open_Scopes (T_Name) then
               if Ekind (Base_Type (T_Name)) = E_Task_Type then

                  --  In Ada 2005, a task name can be used in an access
                  --  definition within its own body.

                  if Ada_Version >= Ada_2005
                    and then Nkind (Parent (N)) = N_Access_Definition
                  then
                     Set_Entity (N, T_Name);
                     Set_Etype  (N, T_Name);
                     return;

                  else
                     Error_Msg_N
                       ("task type cannot be used as type mark " &
                        "within its own spec or body", N);
                  end if;

               elsif Ekind (Base_Type (T_Name)) = E_Protected_Type then

                  --  In Ada 2005, a protected name can be used in an access
                  --  definition within its own body.

                  if Ada_Version >= Ada_2005
                    and then Nkind (Parent (N)) = N_Access_Definition
                  then
                     Set_Entity (N, T_Name);
                     Set_Etype  (N, T_Name);
                     return;

                  else
                     Error_Msg_N
                       ("protected type cannot be used as type mark " &
                        "within its own spec or body", N);
                  end if;

               else
                  Error_Msg_N ("type declaration cannot refer to itself", N);
               end if;

               Set_Etype (N, Any_Type);
               Set_Entity (N, Any_Type);
               Set_Error_Posted (T_Name);
               return;
            end if;

            Set_Entity (N, T_Name);
            Set_Etype  (N, T_Name);
         end if;
      end if;

      if Present (Etype (N)) and then Comes_From_Source (N) then
         if Is_Fixed_Point_Type (Etype (N)) then
            Check_Restriction (No_Fixed_Point, N);
         elsif Is_Floating_Point_Type (Etype (N)) then
            Check_Restriction (No_Floating_Point, N);
         end if;

         --  A Ghost type must appear in a specific context

         if Is_Ghost_Entity (Etype (N)) then
            Check_Ghost_Context (Etype (N), N);
         end if;
      end if;
   end Find_Type;

   --------------------
   -- Has_Components --
   --------------------

   function Has_Components (Typ : Entity_Id) return Boolean is
   begin
      return Is_Record_Type (Typ)
        or else (Is_Private_Type (Typ) and then Has_Discriminants (Typ))
        or else (Is_Task_Type (Typ) and then Has_Discriminants (Typ))
        or else (Is_Incomplete_Type (Typ)
                  and then From_Limited_With (Typ)
                  and then Is_Record_Type (Available_View (Typ)));
   end Has_Components;

   ------------------------------------
   -- Has_Implicit_Character_Literal --
   ------------------------------------

   function Has_Implicit_Character_Literal (N : Node_Id) return Boolean is
      Id      : Entity_Id;
      Found   : Boolean := False;
      P       : constant Entity_Id := Entity (Prefix (N));
      Priv_Id : Entity_Id := Empty;

   begin
      if Ekind (P) = E_Package and then not In_Open_Scopes (P) then
         Priv_Id := First_Private_Entity (P);
      end if;

      if P = Standard_Standard then
         Change_Selected_Component_To_Expanded_Name (N);
         Rewrite (N, Selector_Name (N));
         Analyze (N);
         Set_Etype (Original_Node (N), Standard_Character);
         return True;
      end if;

      Id := First_Entity (P);
      while Present (Id) and then Id /= Priv_Id loop
         if Is_Standard_Character_Type (Id) and then Is_Base_Type (Id) then

            --  We replace the node with the literal itself, resolve as a
            --  character, and set the type correctly.

            if not Found then
               Change_Selected_Component_To_Expanded_Name (N);
               Rewrite (N, Selector_Name (N));
               Analyze (N);
               Set_Etype (N, Id);
               Set_Etype (Original_Node (N), Id);
               Found := True;

            else
               --  More than one type derived from Character in given scope.
               --  Collect all possible interpretations.

               Add_One_Interp (N, Id, Id);
            end if;
         end if;

         Next_Entity (Id);
      end loop;

      return Found;
   end Has_Implicit_Character_Literal;

   ----------------------
   -- Has_Private_With --
   ----------------------

   function Has_Private_With (E : Entity_Id) return Boolean is
      Comp_Unit : constant Node_Id := Cunit (Current_Sem_Unit);
      Item      : Node_Id;

   begin
      Item := First (Context_Items (Comp_Unit));
      while Present (Item) loop
         if Nkind (Item) = N_With_Clause
           and then Private_Present (Item)
           and then Entity (Name (Item)) = E
         then
            return True;
         end if;

         Next (Item);
      end loop;

      return False;
   end Has_Private_With;

   ---------------------------
   -- Has_Implicit_Operator --
   ---------------------------

   function Has_Implicit_Operator (N : Node_Id) return Boolean is
      Op_Id   : constant Name_Id   := Chars (Selector_Name (N));
      P       : constant Entity_Id := Entity (Prefix (N));
      Id      : Entity_Id;
      Priv_Id : Entity_Id := Empty;

      procedure Add_Implicit_Operator
        (T       : Entity_Id;
         Op_Type : Entity_Id := Empty);
      --  Add implicit interpretation to node N, using the type for which a
      --  predefined operator exists. If the operator yields a boolean type,
      --  the Operand_Type is implicitly referenced by the operator, and a
      --  reference to it must be generated.

      ---------------------------
      -- Add_Implicit_Operator --
      ---------------------------

      procedure Add_Implicit_Operator
        (T       : Entity_Id;
         Op_Type : Entity_Id := Empty)
      is
         Predef_Op : Entity_Id;

      begin
         Predef_Op := Current_Entity (Selector_Name (N));
         while Present (Predef_Op)
           and then Scope (Predef_Op) /= Standard_Standard
         loop
            Predef_Op := Homonym (Predef_Op);
         end loop;

         if Nkind (N) = N_Selected_Component then
            Change_Selected_Component_To_Expanded_Name (N);
         end if;

         --  If the context is an unanalyzed function call, determine whether
         --  a binary or unary interpretation is required.

         if Nkind (Parent (N)) = N_Indexed_Component then
            declare
               Is_Binary_Call : constant Boolean :=
                                  Present
                                    (Next (First (Expressions (Parent (N)))));
               Is_Binary_Op   : constant Boolean :=
                                  First_Entity
                                    (Predef_Op) /= Last_Entity (Predef_Op);
               Predef_Op2     : constant Entity_Id := Homonym (Predef_Op);

            begin
               if Is_Binary_Call then
                  if Is_Binary_Op then
                     Add_One_Interp (N, Predef_Op, T);
                  else
                     Add_One_Interp (N, Predef_Op2, T);
                  end if;
               else
                  if not Is_Binary_Op then
                     Add_One_Interp (N, Predef_Op, T);

                  --  Predef_Op2 may be empty in case of previous errors

                  elsif Present (Predef_Op2) then
                     Add_One_Interp (N, Predef_Op2, T);
                  end if;
               end if;
            end;

         else
            Add_One_Interp (N, Predef_Op, T);

            --  For operators with unary and binary interpretations, if
            --  context is not a call, add both

            if Present (Homonym (Predef_Op)) then
               Add_One_Interp (N, Homonym (Predef_Op), T);
            end if;
         end if;

         --  The node is a reference to a predefined operator, and
         --  an implicit reference to the type of its operands.

         if Present (Op_Type) then
            Generate_Operator_Reference (N, Op_Type);
         else
            Generate_Operator_Reference (N, T);
         end if;
      end Add_Implicit_Operator;

   --  Start of processing for Has_Implicit_Operator

   begin
      if Ekind (P) = E_Package and then not In_Open_Scopes (P) then
         Priv_Id := First_Private_Entity (P);
      end if;

      Id := First_Entity (P);

      case Op_Id is

         --  Boolean operators: an implicit declaration exists if the scope
         --  contains a declaration for a derived Boolean type, or for an
         --  array of Boolean type.

         when Name_Op_And
            | Name_Op_Not
            | Name_Op_Or
            | Name_Op_Xor
         =>
            while Id /= Priv_Id loop
               if Valid_Boolean_Arg (Id) and then Is_Base_Type (Id) then
                  Add_Implicit_Operator (Id);
                  return True;
               end if;

               Next_Entity (Id);
            end loop;

         --  Equality: look for any non-limited type (result is Boolean)

         when Name_Op_Eq
            | Name_Op_Ne
         =>
            while Id /= Priv_Id loop
               if Is_Type (Id)
                 and then not Is_Limited_Type (Id)
                 and then Is_Base_Type (Id)
               then
                  Add_Implicit_Operator (Standard_Boolean, Id);
                  return True;
               end if;

               Next_Entity (Id);
            end loop;

         --  Comparison operators: scalar type, or array of scalar

         when Name_Op_Ge
            | Name_Op_Gt
            | Name_Op_Le
            | Name_Op_Lt
         =>
            while Id /= Priv_Id loop
               if (Is_Scalar_Type (Id)
                    or else (Is_Array_Type (Id)
                              and then Is_Scalar_Type (Component_Type (Id))))
                 and then Is_Base_Type (Id)
               then
                  Add_Implicit_Operator (Standard_Boolean, Id);
                  return True;
               end if;

               Next_Entity (Id);
            end loop;

         --  Arithmetic operators: any numeric type

         when Name_Op_Abs
            | Name_Op_Add
            | Name_Op_Divide
            | Name_Op_Expon
            | Name_Op_Mod
            | Name_Op_Multiply
            | Name_Op_Rem
            | Name_Op_Subtract
         =>
            while Id /= Priv_Id loop
               if Is_Numeric_Type (Id) and then Is_Base_Type (Id) then
                  Add_Implicit_Operator (Id);
                  return True;
               end if;

               Next_Entity (Id);
            end loop;

         --  Concatenation: any one-dimensional array type

         when Name_Op_Concat =>
            while Id /= Priv_Id loop
               if Is_Array_Type (Id)
                 and then Number_Dimensions (Id) = 1
                 and then Is_Base_Type (Id)
               then
                  Add_Implicit_Operator (Id);
                  return True;
               end if;

               Next_Entity (Id);
            end loop;

         --  What is the others condition here? Should we be using a
         --  subtype of Name_Id that would restrict to operators ???

         when others =>
            null;
      end case;

      --  If we fall through, then we do not have an implicit operator

      return False;
   end Has_Implicit_Operator;

   -----------------------------------
   -- Has_Loop_In_Inner_Open_Scopes --
   -----------------------------------

   function Has_Loop_In_Inner_Open_Scopes (S : Entity_Id) return Boolean is
   begin
      --  Several scope stacks are maintained by Scope_Stack. The base of the
      --  currently active scope stack is denoted by the Is_Active_Stack_Base
      --  flag in the scope stack entry. Note that the scope stacks used to
      --  simply be delimited implicitly by the presence of Standard_Standard
      --  at their base, but there now are cases where this is not sufficient
      --  because Standard_Standard actually may appear in the middle of the
      --  active set of scopes.

      for J in reverse 0 .. Scope_Stack.Last loop

         --  S was reached without seing a loop scope first

         if Scope_Stack.Table (J).Entity = S then
            return False;

         --  S was not yet reached, so it contains at least one inner loop

         elsif Ekind (Scope_Stack.Table (J).Entity) = E_Loop then
            return True;
         end if;

         --  Check Is_Active_Stack_Base to tell us when to stop, as there are
         --  cases where Standard_Standard appears in the middle of the active
         --  set of scopes. This affects the declaration and overriding of
         --  private inherited operations in instantiations of generic child
         --  units.

         pragma Assert (not Scope_Stack.Table (J).Is_Active_Stack_Base);
      end loop;

      raise Program_Error;    --  unreachable
   end Has_Loop_In_Inner_Open_Scopes;

   --------------------
   -- In_Open_Scopes --
   --------------------

   function In_Open_Scopes (S : Entity_Id) return Boolean is
   begin
      --  Several scope stacks are maintained by Scope_Stack. The base of the
      --  currently active scope stack is denoted by the Is_Active_Stack_Base
      --  flag in the scope stack entry. Note that the scope stacks used to
      --  simply be delimited implicitly by the presence of Standard_Standard
      --  at their base, but there now are cases where this is not sufficient
      --  because Standard_Standard actually may appear in the middle of the
      --  active set of scopes.

      for J in reverse 0 .. Scope_Stack.Last loop
         if Scope_Stack.Table (J).Entity = S then
            return True;
         end if;

         --  Check Is_Active_Stack_Base to tell us when to stop, as there are
         --  cases where Standard_Standard appears in the middle of the active
         --  set of scopes. This affects the declaration and overriding of
         --  private inherited operations in instantiations of generic child
         --  units.

         exit when Scope_Stack.Table (J).Is_Active_Stack_Base;
      end loop;

      return False;
   end In_Open_Scopes;

   -----------------------------
   -- Inherit_Renamed_Profile --
   -----------------------------

   procedure Inherit_Renamed_Profile (New_S : Entity_Id; Old_S : Entity_Id) is
      New_F : Entity_Id;
      Old_F : Entity_Id;
      Old_T : Entity_Id;
      New_T : Entity_Id;

   begin
      if Ekind (Old_S) = E_Operator then
         New_F := First_Formal (New_S);

         while Present (New_F) loop
            Set_Etype (New_F, Base_Type (Etype (New_F)));
            Next_Formal (New_F);
         end loop;

         Set_Etype (New_S, Base_Type (Etype (New_S)));

      else
         New_F := First_Formal (New_S);
         Old_F := First_Formal (Old_S);

         while Present (New_F) loop
            New_T := Etype (New_F);
            Old_T := Etype (Old_F);

            --  If the new type is a renaming of the old one, as is the case
            --  for actuals in instances, retain its name, to simplify later
            --  disambiguation.

            if Nkind (Parent (New_T)) = N_Subtype_Declaration
              and then Is_Entity_Name (Subtype_Indication (Parent (New_T)))
              and then Entity (Subtype_Indication (Parent (New_T))) = Old_T
            then
               null;
            else
               Set_Etype (New_F, Old_T);
            end if;

            Next_Formal (New_F);
            Next_Formal (Old_F);
         end loop;

         pragma Assert (No (Old_F));

         if Ekind (Old_S) in E_Function | E_Enumeration_Literal then
            Set_Etype (New_S, Etype (Old_S));
         end if;
      end if;
   end Inherit_Renamed_Profile;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      Urefs.Init;
   end Initialize;

   -------------------------
   -- Install_Use_Clauses --
   -------------------------

   procedure Install_Use_Clauses
     (Clause             : Node_Id;
      Force_Installation : Boolean := False)
   is
      U : Node_Id;

   begin
      U := Clause;
      while Present (U) loop

         --  Case of USE package

         if Nkind (U) = N_Use_Package_Clause then
            Use_One_Package (U, Name (U), True);

         --  Case of USE TYPE

         else
            Use_One_Type (Subtype_Mark (U), Force => Force_Installation);

         end if;

         Next_Use_Clause (U);
      end loop;
   end Install_Use_Clauses;

   ----------------------
   -- Mark_Use_Clauses --
   ----------------------

   procedure Mark_Use_Clauses (Id : Node_Or_Entity_Id) is
      procedure Mark_Parameters (Call : Entity_Id);
      --  Perform use_type_clause marking for all parameters in a subprogram
      --  or operator call.

      procedure Mark_Use_Package (Pak : Entity_Id);
      --  Move up the Prev_Use_Clause chain for packages denoted by Pak -
      --  marking each clause in the chain as effective in the process.

      procedure Mark_Use_Type (E : Entity_Id);
      --  Similar to Do_Use_Package_Marking except we move up the
      --  Prev_Use_Clause chain for the type denoted by E.

      ---------------------
      -- Mark_Parameters --
      ---------------------

      procedure Mark_Parameters (Call : Entity_Id) is
         Curr : Node_Id;

      begin
         --  Move through all of the formals

         Curr := First_Formal (Call);
         while Present (Curr) loop
            Mark_Use_Type (Curr);

            Next_Formal (Curr);
         end loop;

         --  Handle the return type

         Mark_Use_Type (Call);
      end Mark_Parameters;

      ----------------------
      -- Mark_Use_Package --
      ----------------------

      procedure Mark_Use_Package (Pak : Entity_Id) is
         Curr : Node_Id;

      begin
         --  Ignore cases where the scope of the type is not a package (e.g.
         --  Standard_Standard).

         if Ekind (Pak) /= E_Package then
            return;
         end if;

         Curr := Current_Use_Clause (Pak);
         while Present (Curr)
           and then not Is_Effective_Use_Clause (Curr)
         loop
            --  We need to mark the previous use clauses as effective, but
            --  each use clause may in turn render other use_package_clauses
            --  effective. Additionally, it is possible to have a parent
            --  package renamed as a child of itself so we must check the
            --  prefix entity is not the same as the package we are marking.

            if Nkind (Name (Curr)) /= N_Identifier
              and then Present (Prefix (Name (Curr)))
              and then Entity (Prefix (Name (Curr))) /= Pak
            then
               Mark_Use_Package (Entity (Prefix (Name (Curr))));

            --  It is also possible to have a child package without a prefix
            --  that relies on a previous use_package_clause.

            elsif Nkind (Name (Curr)) = N_Identifier
              and then Is_Child_Unit (Entity (Name (Curr)))
            then
               Mark_Use_Package (Scope (Entity (Name (Curr))));
            end if;

            --  Mark the use_package_clause as effective and move up the chain

            Set_Is_Effective_Use_Clause (Curr);

            Curr := Prev_Use_Clause (Curr);
         end loop;
      end Mark_Use_Package;

      -------------------
      -- Mark_Use_Type --
      -------------------

      procedure Mark_Use_Type (E : Entity_Id) is
         Curr : Node_Id;
         Base : Entity_Id;

      begin
         --  Ignore void types and unresolved string literals and primitives

         if Nkind (E) = N_String_Literal
           or else Nkind (Etype (E)) not in N_Entity
           or else not Is_Type (Etype (E))
         then
            return;
         end if;

         --  Primitives with class-wide operands might additionally render
         --  their base type's use_clauses effective - so do a recursive check
         --  here.

         Base := Base_Type (Etype (E));

         if Ekind (Base) = E_Class_Wide_Type then
            Mark_Use_Type (Base);
         end if;

         --  The package containing the type or operator function being used
         --  may be in use as well, so mark any use_package_clauses for it as
         --  effective. There are also additional sanity checks performed here
         --  for ignoring previous errors.

         Mark_Use_Package (Scope (Base));

         if Nkind (E) in N_Op
           and then Present (Entity (E))
           and then Present (Scope (Entity (E)))
         then
            Mark_Use_Package (Scope (Entity (E)));
         end if;

         Curr := Current_Use_Clause (Base);
         while Present (Curr)
            and then not Is_Effective_Use_Clause (Curr)
         loop
            --  Current use_type_clause may render other use_package_clauses
            --  effective.

            if Nkind (Subtype_Mark (Curr)) /= N_Identifier
              and then Present (Prefix (Subtype_Mark (Curr)))
            then
               Mark_Use_Package (Entity (Prefix (Subtype_Mark (Curr))));
            end if;

            --  Mark the use_type_clause as effective and move up the chain

            Set_Is_Effective_Use_Clause (Curr);

            Curr := Prev_Use_Clause (Curr);
         end loop;
      end Mark_Use_Type;

   --  Start of processing for Mark_Use_Clauses

   begin
      --  Use clauses in and of themselves do not count as a "use" of a
      --  package.

      if Nkind (Parent (Id)) in N_Use_Package_Clause | N_Use_Type_Clause then
         return;
      end if;

      --  Handle entities

      if Nkind (Id) in N_Entity then

         --  Mark the entity's package

         if Is_Potentially_Use_Visible (Id) then
            Mark_Use_Package (Scope (Id));
         end if;

         --  Mark enumeration literals

         if Ekind (Id) = E_Enumeration_Literal then
            Mark_Use_Type (Id);

         --  Mark primitives

         elsif (Is_Overloadable (Id)
                 or else Is_Generic_Subprogram (Id))
           and then (Is_Potentially_Use_Visible (Id)
                      or else Is_Intrinsic_Subprogram (Id)
                      or else (Ekind (Id) in E_Function | E_Procedure
                                and then Is_Generic_Actual_Subprogram (Id)))
         then
            Mark_Parameters (Id);
         end if;

      --  Handle nodes

      else
         --  Mark operators

         if Nkind (Id) in N_Op then

            --  At this point the left operand may not be resolved if we are
            --  encountering multiple operators next to eachother in an
            --  expression.

            if Nkind (Id) in N_Binary_Op
              and then not (Nkind (Left_Opnd (Id)) in N_Op)
            then
               Mark_Use_Type (Left_Opnd (Id));
            end if;

            Mark_Use_Type (Right_Opnd (Id));
            Mark_Use_Type (Id);

         --  Mark entity identifiers

         elsif Nkind (Id) in N_Has_Entity
           and then (Is_Potentially_Use_Visible (Entity (Id))
                      or else (Is_Generic_Instance (Entity (Id))
                                and then Is_Immediately_Visible (Entity (Id))))
         then
            --  Ignore fully qualified names as they do not count as a "use" of
            --  a package.

            if Nkind (Id) in N_Identifier | N_Operator_Symbol
              or else (Present (Prefix (Id))
                         and then Scope (Entity (Id)) /= Entity (Prefix (Id)))
            then
               Mark_Use_Clauses (Entity (Id));
            end if;
         end if;
      end if;
   end Mark_Use_Clauses;

   --------------------------------
   -- Most_Descendant_Use_Clause --
   --------------------------------

   function Most_Descendant_Use_Clause
     (Clause1 : Entity_Id;
      Clause2 : Entity_Id) return Entity_Id
   is
      Scope1 : Entity_Id;
      Scope2 : Entity_Id;

   begin
      if Clause1 = Clause2 then
         return Clause1;
      end if;

      --  We determine which one is the most descendant by the scope distance
      --  to the ultimate parent unit.

      Scope1 := Entity_Of_Unit (Unit (Parent (Clause1)));
      Scope2 := Entity_Of_Unit (Unit (Parent (Clause2)));
      while Scope1 /= Standard_Standard
        and then Scope2 /= Standard_Standard
      loop
         Scope1 := Scope (Scope1);
         Scope2 := Scope (Scope2);

         if not Present (Scope1) then
            return Clause1;
         elsif not Present (Scope2) then
            return Clause2;
         end if;
      end loop;

      if Scope1 = Standard_Standard then
         return Clause1;
      end if;

      return Clause2;
   end Most_Descendant_Use_Clause;

   ---------------
   -- Pop_Scope --
   ---------------

   procedure Pop_Scope is
      SST : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);
      S   : constant Entity_Id := SST.Entity;

   begin
      if Debug_Flag_E then
         Write_Info;
      end if;

      --  Set Default_Storage_Pool field of the library unit if necessary

      if Is_Package_Or_Generic_Package (S)
        and then
          Nkind (Parent (Unit_Declaration_Node (S))) = N_Compilation_Unit
      then
         declare
            Aux : constant Node_Id :=
                    Aux_Decls_Node (Parent (Unit_Declaration_Node (S)));
         begin
            if No (Default_Storage_Pool (Aux)) then
               Set_Default_Storage_Pool (Aux, Default_Pool);
            end if;
         end;
      end if;

      Scope_Suppress           := SST.Save_Scope_Suppress;
      Local_Suppress_Stack_Top := SST.Save_Local_Suppress_Stack_Top;
      Check_Policy_List        := SST.Save_Check_Policy_List;
      Default_Pool             := SST.Save_Default_Storage_Pool;
      No_Tagged_Streams        := SST.Save_No_Tagged_Streams;
      SPARK_Mode               := SST.Save_SPARK_Mode;
      SPARK_Mode_Pragma        := SST.Save_SPARK_Mode_Pragma;
      Default_SSO              := SST.Save_Default_SSO;
      Uneval_Old               := SST.Save_Uneval_Old;

      if Debug_Flag_W then
         Write_Str ("<-- exiting scope: ");
         Write_Name (Chars (Current_Scope));
         Write_Str (", Depth=");
         Write_Int (Int (Scope_Stack.Last));
         Write_Eol;
      end if;

      End_Use_Clauses (SST.First_Use_Clause);

      --  If the actions to be wrapped are still there they will get lost
      --  causing incomplete code to be generated. It is better to abort in
      --  this case (and we do the abort even with assertions off since the
      --  penalty is incorrect code generation).

      if SST.Actions_To_Be_Wrapped /= Scope_Actions'(others => No_List) then
         raise Program_Error;
      end if;

      --  Free last subprogram name if allocated, and pop scope

      Free (SST.Last_Subprogram_Name);
      Scope_Stack.Decrement_Last;
   end Pop_Scope;

   ----------------
   -- Push_Scope --
   ----------------

   procedure Push_Scope (S : Entity_Id) is
      E : constant Entity_Id := Scope (S);

      function Component_Alignment_Default return Component_Alignment_Kind;
      --  Return Component_Alignment_Kind for the newly-pushed scope.

      function Component_Alignment_Default return Component_Alignment_Kind is
      begin
         --  Each new scope pushed onto the scope stack inherits the component
         --  alignment of the previous scope. This emulates the "visibility"
         --  semantics of pragma Component_Alignment.

         if Scope_Stack.Last > Scope_Stack.First then
            return Scope_Stack.Table
              (Scope_Stack.Last - 1).Component_Alignment_Default;

         --  Otherwise, this is the first scope being pushed on the scope
         --  stack. Inherit the component alignment from the configuration
         --  form of pragma Component_Alignment (if any).

         else
            return Configuration_Component_Alignment;
         end if;
      end Component_Alignment_Default;

   begin
      if Ekind (S) = E_Void then
         null;

      --  Set scope depth if not a non-concurrent type, and we have not yet set
      --  the scope depth. This means that we have the first occurrence of the
      --  scope, and this is where the depth is set.

      elsif (not Is_Type (S) or else Is_Concurrent_Type (S))
        and then not Scope_Depth_Set (S)
      then
         if S = Standard_Standard then
            Set_Scope_Depth_Value (S, Uint_0);

         elsif Is_Child_Unit (S) then
            Set_Scope_Depth_Value (S, Uint_1);

         elsif not Is_Record_Type (Current_Scope) then
            if Ekind (S) = E_Loop then
               Set_Scope_Depth_Value (S, Scope_Depth (Current_Scope));
            else
               Set_Scope_Depth_Value (S, Scope_Depth (Current_Scope) + 1);
            end if;
         end if;
      end if;

      Scope_Stack.Increment_Last;

      Scope_Stack.Table (Scope_Stack.Last) :=
        (Entity                        => S,
         Save_Scope_Suppress           => Scope_Suppress,
         Save_Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
         Save_Check_Policy_List        => Check_Policy_List,
         Save_Default_Storage_Pool     => Default_Pool,
         Save_No_Tagged_Streams        => No_Tagged_Streams,
         Save_SPARK_Mode               => SPARK_Mode,
         Save_SPARK_Mode_Pragma        => SPARK_Mode_Pragma,
         Save_Default_SSO              => Default_SSO,
         Save_Uneval_Old               => Uneval_Old,
         Component_Alignment_Default   => Component_Alignment_Default,
         Last_Subprogram_Name          => null,
         Is_Transient                  => False,
         Node_To_Be_Wrapped            => Empty,
         Pending_Freeze_Actions        => No_List,
         Actions_To_Be_Wrapped         => (others => No_List),
         First_Use_Clause              => Empty,
         Is_Active_Stack_Base          => False,
         Previous_Visibility           => False,
         Locked_Shared_Objects         => No_Elist);

      if Debug_Flag_W then
         Write_Str ("--> new scope: ");
         Write_Name (Chars (Current_Scope));
         Write_Str (", Id=");
         Write_Int (Int (Current_Scope));
         Write_Str (", Depth=");
         Write_Int (Int (Scope_Stack.Last));
         Write_Eol;
      end if;

      --  Deal with copying flags from the previous scope to this one. This is
      --  not necessary if either scope is standard, or if the new scope is a
      --  child unit.

      if S /= Standard_Standard
        and then Scope (S) /= Standard_Standard
        and then not Is_Child_Unit (S)
      then
         if Nkind (E) not in N_Entity then
            return;
         end if;

         --  Copy categorization flags from Scope (S) to S, this is not done
         --  when Scope (S) is Standard_Standard since propagation is from
         --  library unit entity inwards. Copy other relevant attributes as
         --  well (Discard_Names in particular).

         --  We only propagate inwards for library level entities,
         --  inner level subprograms do not inherit the categorization.

         if Is_Library_Level_Entity (S) then
            Set_Is_Preelaborated  (S, Is_Preelaborated (E));
            Set_Is_Shared_Passive (S, Is_Shared_Passive (E));
            Set_Discard_Names     (S, Discard_Names (E));
            Set_Suppress_Value_Tracking_On_Call
                                  (S, Suppress_Value_Tracking_On_Call (E));
            Set_Categorization_From_Scope (E => S, Scop => E);
         end if;
      end if;

      if Is_Child_Unit (S)
        and then Present (E)
        and then Is_Package_Or_Generic_Package (E)
        and then
          Nkind (Parent (Unit_Declaration_Node (E))) = N_Compilation_Unit
      then
         declare
            Aux : constant Node_Id :=
                    Aux_Decls_Node (Parent (Unit_Declaration_Node (E)));
         begin
            if Present (Default_Storage_Pool (Aux)) then
               Default_Pool := Default_Storage_Pool (Aux);
            end if;
         end;
      end if;
   end Push_Scope;

   ---------------------
   -- Premature_Usage --
   ---------------------

   procedure Premature_Usage (N : Node_Id) is
      Kind : constant Node_Kind := Nkind (Parent (Entity (N)));
      E    : Entity_Id := Entity (N);

   begin
      --  Within an instance, the analysis of the actual for a formal object
      --  does not see the name of the object itself. This is significant only
      --  if the object is an aggregate, where its analysis does not do any
      --  name resolution on component associations. (see 4717-008). In such a
      --  case, look for the visible homonym on the chain.

      if In_Instance and then Present (Homonym (E)) then
         E := Homonym (E);
         while Present (E) and then not In_Open_Scopes (Scope (E)) loop
            E := Homonym (E);
         end loop;

         if Present (E) then
            Set_Entity (N, E);
            Set_Etype (N, Etype (E));
            return;
         end if;
      end if;

      case Kind is
         when N_Component_Declaration =>
            Error_Msg_N
              ("component&! cannot be used before end of record declaration",
               N);

         when N_Parameter_Specification =>
            Error_Msg_N
              ("formal parameter&! cannot be used before end of specification",
               N);

         when N_Discriminant_Specification =>
            Error_Msg_N
              ("discriminant&! cannot be used before end of discriminant part",
               N);

         when N_Procedure_Specification | N_Function_Specification =>
            Error_Msg_N
              ("subprogram&! cannot be used before end of its declaration",
               N);

         when N_Full_Type_Declaration | N_Subtype_Declaration =>
            Error_Msg_N
              ("type& cannot be used before end of its declaration!", N);

         when others =>
            Error_Msg_N
              ("object& cannot be used before end of its declaration!", N);

            --  If the premature reference appears as the expression in its own
            --  declaration, rewrite it to prevent compiler loops in subsequent
            --  uses of this mangled declaration in address clauses.

            if Nkind (Parent (N)) = N_Object_Declaration then
               Set_Entity (N, Any_Id);
            end if;
      end case;
   end Premature_Usage;

   ------------------------
   -- Present_System_Aux --
   ------------------------

   function Present_System_Aux (N : Node_Id := Empty) return Boolean is
      Loc      : Source_Ptr;
      Aux_Name : Unit_Name_Type;
      Unum     : Unit_Number_Type;
      Withn    : Node_Id;
      With_Sys : Node_Id;
      The_Unit : Node_Id;

      function Find_System (C_Unit : Node_Id) return Entity_Id;
      --  Scan context clause of compilation unit to find with_clause
      --  for System.

      -----------------
      -- Find_System --
      -----------------

      function Find_System (C_Unit : Node_Id) return Entity_Id is
         With_Clause : Node_Id;

      begin
         With_Clause := First (Context_Items (C_Unit));
         while Present (With_Clause) loop
            if (Nkind (With_Clause) = N_With_Clause
              and then Chars (Name (With_Clause)) = Name_System)
              and then Comes_From_Source (With_Clause)
            then
               return With_Clause;
            end if;

            Next (With_Clause);
         end loop;

         return Empty;
      end Find_System;

   --  Start of processing for Present_System_Aux

   begin
      --  The child unit may have been loaded and analyzed already

      if Present (System_Aux_Id) then
         return True;

      --  If no previous pragma for System.Aux, nothing to load

      elsif No (System_Extend_Unit) then
         return False;

      --  Use the unit name given in the pragma to retrieve the unit.
      --  Verify that System itself appears in the context clause of the
      --  current compilation. If System is not present, an error will
      --  have been reported already.

      else
         With_Sys := Find_System (Cunit (Current_Sem_Unit));

         The_Unit := Unit (Cunit (Current_Sem_Unit));

         if No (With_Sys)
           and then
             (Nkind (The_Unit) = N_Package_Body
               or else (Nkind (The_Unit) = N_Subprogram_Body
                         and then not Acts_As_Spec (Cunit (Current_Sem_Unit))))
         then
            With_Sys := Find_System (Library_Unit (Cunit (Current_Sem_Unit)));
         end if;

         if No (With_Sys) and then Present (N) then

            --  If we are compiling a subunit, we need to examine its
            --  context as well (Current_Sem_Unit is the parent unit);

            The_Unit := Parent (N);
            while Nkind (The_Unit) /= N_Compilation_Unit loop
               The_Unit := Parent (The_Unit);
            end loop;

            if Nkind (Unit (The_Unit)) = N_Subunit then
               With_Sys := Find_System (The_Unit);
            end if;
         end if;

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

         Loc := Sloc (With_Sys);
         Get_Name_String (Chars (Expression (System_Extend_Unit)));
         Name_Buffer (8 .. Name_Len + 7) := Name_Buffer (1 .. Name_Len);
         Name_Buffer (1 .. 7) := "system.";
         Name_Buffer (Name_Len + 8) := '%';
         Name_Buffer (Name_Len + 9) := 's';
         Name_Len := Name_Len + 9;
         Aux_Name := Name_Find;

         Unum :=
           Load_Unit
             (Load_Name  => Aux_Name,
              Required   => False,
              Subunit    => False,
              Error_Node => With_Sys);

         if Unum /= No_Unit then
            Semantics (Cunit (Unum));
            System_Aux_Id :=
              Defining_Entity (Specification (Unit (Cunit (Unum))));

            Withn :=
              Make_With_Clause (Loc,
                Name =>
                  Make_Expanded_Name (Loc,
                    Chars         => Chars (System_Aux_Id),
                    Prefix        =>
                      New_Occurrence_Of (Scope (System_Aux_Id), Loc),
                    Selector_Name => New_Occurrence_Of (System_Aux_Id, Loc)));

            Set_Entity (Name (Withn), System_Aux_Id);

            Set_Corresponding_Spec (Withn, System_Aux_Id);
            Set_First_Name         (Withn);
            Set_Implicit_With      (Withn);
            Set_Library_Unit       (Withn, Cunit (Unum));

            Insert_After (With_Sys, Withn);
            Mark_Rewrite_Insertion (Withn);
            Set_Context_Installed (Withn);

            return True;

         --  Here if unit load failed

         else
            Error_Msg_Name_1 := Name_System;
            Error_Msg_Name_2 := Chars (Expression (System_Extend_Unit));
            Error_Msg_N
              ("extension package `%.%` does not exist",
               Opt.System_Extend_Unit);
            return False;
         end if;
      end if;
   end Present_System_Aux;

   -------------------------
   -- Restore_Scope_Stack --
   -------------------------

   procedure Restore_Scope_Stack
     (List       : Elist_Id;
      Handle_Use : Boolean := True)
   is
      SS_Last : constant Int := Scope_Stack.Last;
      Elmt    : Elmt_Id;

   begin
      --  Restore visibility of previous scope stack, if any, using the list
      --  we saved (we use Remove, since this list will not be used again).

      loop
         Elmt := Last_Elmt (List);
         exit when Elmt = No_Elmt;
         Set_Is_Immediately_Visible (Node (Elmt));
         Remove_Last_Elmt (List);
      end loop;

      --  Restore use clauses

      if SS_Last >= Scope_Stack.First
        and then Scope_Stack.Table (SS_Last).Entity /= Standard_Standard
        and then Handle_Use
      then
         Install_Use_Clauses
           (Scope_Stack.Table (SS_Last).First_Use_Clause,
            Force_Installation => True);
      end if;
   end Restore_Scope_Stack;

   ----------------------
   -- Save_Scope_Stack --
   ----------------------

   --  Save_Scope_Stack/Restore_Scope_Stack were originally designed to avoid
   --  consuming any memory. That is, Save_Scope_Stack took care of removing
   --  from immediate visibility entities and Restore_Scope_Stack took care
   --  of restoring their visibility analyzing the context of each entity. The
   --  problem of such approach is that it was fragile and caused unexpected
   --  visibility problems, and indeed one test was found where there was a
   --  real problem.

   --  Furthermore, the following experiment was carried out:

   --    - Save_Scope_Stack was modified to store in an Elist1 all those
   --      entities whose attribute Is_Immediately_Visible is modified
   --      from True to False.

   --    - Restore_Scope_Stack was modified to store in another Elist2
   --      all the entities whose attribute Is_Immediately_Visible is
   --      modified from False to True.

   --    - Extra code was added to verify that all the elements of Elist1
   --      are found in Elist2

   --  This test shows that there may be more occurrences of this problem which
   --  have not yet been detected. As a result, we replaced that approach by
   --  the current one in which Save_Scope_Stack returns the list of entities
   --  whose visibility is changed, and that list is passed to Restore_Scope_
   --  Stack to undo that change. This approach is simpler and safer, although
   --  it consumes more memory.

   function Save_Scope_Stack (Handle_Use : Boolean := True) return Elist_Id is
      Result  : constant Elist_Id := New_Elmt_List;
      E       : Entity_Id;
      S       : Entity_Id;
      SS_Last : constant Int := Scope_Stack.Last;

      procedure Remove_From_Visibility (E : Entity_Id);
      --  If E is immediately visible then append it to the result and remove
      --  it temporarily from visibility.

      ----------------------------
      -- Remove_From_Visibility --
      ----------------------------

      procedure Remove_From_Visibility (E : Entity_Id) is
      begin
         if Is_Immediately_Visible (E) then
            Append_Elmt (E, Result);
            Set_Is_Immediately_Visible (E, False);
         end if;
      end Remove_From_Visibility;

   --  Start of processing for Save_Scope_Stack

   begin
      if SS_Last >= Scope_Stack.First
        and then Scope_Stack.Table (SS_Last).Entity /= Standard_Standard
      then
         if Handle_Use then
            End_Use_Clauses (Scope_Stack.Table (SS_Last).First_Use_Clause);
         end if;

         --  If the call is from within a compilation unit, as when called from
         --  Rtsfind, make current entries in scope stack invisible while we
         --  analyze the new unit.

         for J in reverse 0 .. SS_Last loop
            exit when  Scope_Stack.Table (J).Entity = Standard_Standard
               or else No (Scope_Stack.Table (J).Entity);

            S := Scope_Stack.Table (J).Entity;

            Remove_From_Visibility (S);

            E := First_Entity (S);
            while Present (E) loop
               Remove_From_Visibility (E);
               Next_Entity (E);
            end loop;
         end loop;

      end if;

      return Result;
   end Save_Scope_Stack;

   -------------
   -- Set_Use --
   -------------

   procedure Set_Use (L : List_Id) is
      Decl : Node_Id;

   begin
      if Present (L) then
         Decl := First (L);
         while Present (Decl) loop
            if Nkind (Decl) = N_Use_Package_Clause then
               Chain_Use_Clause (Decl);
               Use_One_Package (Decl, Name (Decl));

            elsif Nkind (Decl) = N_Use_Type_Clause then
               Chain_Use_Clause (Decl);
               Use_One_Type (Subtype_Mark (Decl));

            end if;

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

   -----------------------------
   -- Update_Use_Clause_Chain --
   -----------------------------

   procedure Update_Use_Clause_Chain is

      procedure Update_Chain_In_Scope (Level : Int);
      --  Iterate through one level in the scope stack verifying each use-type
      --  clause within said level is used then reset the Current_Use_Clause
      --  to a redundant use clause outside of the current ending scope if such
      --  a clause exists.

      ---------------------------
      -- Update_Chain_In_Scope --
      ---------------------------

      procedure Update_Chain_In_Scope (Level : Int) is
         Curr : Node_Id;
         N    : Node_Id;

      begin
         --  Loop through all use clauses within the scope dictated by Level

         Curr := Scope_Stack.Table (Level).First_Use_Clause;
         while Present (Curr) loop

            --  Retrieve the subtype mark or name within the current current
            --  use clause.

            if Nkind (Curr) = N_Use_Type_Clause then
               N := Subtype_Mark (Curr);
            else
               N := Name (Curr);
            end if;

            --  If warnings for unreferenced entities are enabled and the
            --  current use clause has not been marked effective.

            if Check_Unreferenced
              and then Comes_From_Source (Curr)
              and then not Is_Effective_Use_Clause (Curr)
              and then not In_Instance
              and then not In_Inlined_Body
            then
               --  We are dealing with a potentially unused use_package_clause

               if Nkind (Curr) = N_Use_Package_Clause then

                  --  Renamings and formal subprograms may cause the associated
                  --  node to be marked as effective instead of the original.

                  if not (Present (Associated_Node (N))
                           and then Present
                                      (Current_Use_Clause
                                        (Associated_Node (N)))
                           and then Is_Effective_Use_Clause
                                      (Current_Use_Clause
                                        (Associated_Node (N))))
                  then
                     Error_Msg_Node_1 := Entity (N);
                     Error_Msg_NE
                       ("use clause for package & has no effect?u?",
                        Curr, Entity (N));
                  end if;

               --  We are dealing with an unused use_type_clause

               else
                  Error_Msg_Node_1 := Etype (N);
                  Error_Msg_NE
                    ("use clause for } has no effect?u?", Curr, Etype (N));
               end if;
            end if;

            --  Verify that we haven't already processed a redundant
            --  use_type_clause within the same scope before we move the
            --  current use clause up to a previous one for type T.

            if Present (Prev_Use_Clause (Curr)) then
               Set_Current_Use_Clause (Entity (N), Prev_Use_Clause (Curr));
            end if;

            Next_Use_Clause (Curr);
         end loop;
      end Update_Chain_In_Scope;

   --  Start of processing for Update_Use_Clause_Chain

   begin
      Update_Chain_In_Scope (Scope_Stack.Last);

      --  Deal with use clauses within the context area if the current
      --  scope is a compilation unit.

      if Is_Compilation_Unit (Current_Scope)
        and then Sloc (Scope_Stack.Table
                        (Scope_Stack.Last - 1).Entity) = Standard_Location
      then
         Update_Chain_In_Scope (Scope_Stack.Last - 1);
      end if;
   end Update_Use_Clause_Chain;

   ---------------------
   -- Use_One_Package --
   ---------------------

   procedure Use_One_Package
     (N         : Node_Id;
      Pack_Name : Entity_Id := Empty;
      Force     : Boolean   := False)
   is
      procedure Note_Redundant_Use (Clause : Node_Id);
      --  Mark the name in a use clause as redundant if the corresponding
      --  entity is already use-visible. Emit a warning if the use clause comes
      --  from source and the proper warnings are enabled.

      ------------------------
      -- Note_Redundant_Use --
      ------------------------

      procedure Note_Redundant_Use (Clause : Node_Id) is
         Decl      : constant Node_Id   := Parent (Clause);
         Pack_Name : constant Entity_Id := Entity (Clause);

         Cur_Use    : Node_Id := Current_Use_Clause (Pack_Name);
         Prev_Use   : Node_Id := Empty;
         Redundant  : Node_Id := Empty;
         --  The Use_Clause which is actually redundant. In the simplest case
         --  it is Pack itself, but when we compile a body we install its
         --  context before that of its spec, in which case it is the
         --  use_clause in the spec that will appear to be redundant, and we
         --  want the warning to be placed on the body. Similar complications
         --  appear when the redundancy is between a child unit and one of its
         --  ancestors.

      begin
         --  Could be renamed...

         if No (Cur_Use) then
            Cur_Use := Current_Use_Clause (Renamed_Entity (Pack_Name));
         end if;

         Set_Redundant_Use (Clause, True);

         --  Do not check for redundant use if clause is generated, or in an
         --  instance, or in a predefined unit to avoid misleading warnings
         --  that may occur as part of a rtsfind load.

         if not Comes_From_Source (Clause)
           or else In_Instance
           or else not Warn_On_Redundant_Constructs
           or else Is_Predefined_Unit (Current_Sem_Unit)
         then
            return;
         end if;

         if not Is_Compilation_Unit (Current_Scope) then

            --  If the use_clause is in an inner scope, it is made redundant by
            --  some clause in the current context, with one exception: If we
            --  are compiling a nested package body, and the use_clause comes
            --  from then corresponding spec, the clause is not necessarily
            --  fully redundant, so we should not warn. If a warning was
            --  warranted, it would have been given when the spec was
            --  processed.

            if Nkind (Parent (Decl)) = N_Package_Specification then
               declare
                  Package_Spec_Entity : constant Entity_Id :=
                                          Defining_Unit_Name (Parent (Decl));
               begin
                  if In_Package_Body (Package_Spec_Entity) then
                     return;
                  end if;
               end;
            end if;

            Redundant := Clause;
            Prev_Use  := Cur_Use;

         elsif Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Body then
            declare
               Cur_Unit : constant Unit_Number_Type :=
                            Get_Source_Unit (Cur_Use);
               New_Unit : constant Unit_Number_Type :=
                            Get_Source_Unit (Clause);

               Scop : Entity_Id;

            begin
               if Cur_Unit = New_Unit then

                  --  Redundant clause in same body

                  Redundant := Clause;
                  Prev_Use  := Cur_Use;

               elsif Cur_Unit = Current_Sem_Unit then

                  --  If the new clause is not in the current unit it has been
                  --  analyzed first, and it makes the other one redundant.
                  --  However, if the new clause appears in a subunit, Cur_Unit
                  --  is still the parent, and in that case the redundant one
                  --  is the one appearing in the subunit.

                  if Nkind (Unit (Cunit (New_Unit))) = N_Subunit then
                     Redundant := Clause;
                     Prev_Use  := Cur_Use;

                  --  Most common case: redundant clause in body, original
                  --  clause in spec. Current scope is spec entity.

                  elsif Current_Scope = Cunit_Entity (Current_Sem_Unit) then
                     Redundant := Cur_Use;
                     Prev_Use  := Clause;

                  else
                     --  The new clause may appear in an unrelated unit, when
                     --  the parents of a generic are being installed prior to
                     --  instantiation. In this case there must be no warning.
                     --  We detect this case by checking whether the current
                     --  top of the stack is related to the current
                     --  compilation.

                     Scop := Current_Scope;
                     while Present (Scop)
                       and then Scop /= Standard_Standard
                     loop
                        if Is_Compilation_Unit (Scop)
                          and then not Is_Child_Unit (Scop)
                        then
                           return;

                        elsif Scop = Cunit_Entity (Current_Sem_Unit) then
                           exit;
                        end if;

                        Scop := Scope (Scop);
                     end loop;

                     Redundant := Cur_Use;
                     Prev_Use  := Clause;
                  end if;

               elsif New_Unit = Current_Sem_Unit then
                  Redundant := Clause;
                  Prev_Use  := Cur_Use;

               else
                  --  Neither is the current unit, so they appear in parent or
                  --  sibling units. Warning will be emitted elsewhere.

                  return;
               end if;
            end;

         elsif Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Declaration
           and then Present (Parent_Spec (Unit (Cunit (Current_Sem_Unit))))
         then
            --  Use_clause is in child unit of current unit, and the child unit
            --  appears in the context of the body of the parent, so it has
            --  been installed first, even though it is the redundant one.
            --  Depending on their placement in the context, the visible or the
            --  private parts of the two units, either might appear as
            --  redundant, but the message has to be on the current unit.

            if Get_Source_Unit (Cur_Use) = Current_Sem_Unit then
               Redundant := Cur_Use;
               Prev_Use  := Clause;
            else
               Redundant := Clause;
               Prev_Use  := Cur_Use;
            end if;

            --  If the new use clause appears in the private part of a parent
            --  unit it may appear to be redundant w.r.t. a use clause in a
            --  child unit, but the previous use clause was needed in the
            --  visible part of the child, and no warning should be emitted.

            if Nkind (Parent (Decl)) = N_Package_Specification
              and then List_Containing (Decl) =
                         Private_Declarations (Parent (Decl))
            then
               declare
                  Par      : constant Entity_Id :=
                    Defining_Entity (Parent (Decl));
                  Spec     : constant Node_Id  :=
                    Specification (Unit (Cunit (Current_Sem_Unit)));
                  Cur_List : constant List_Id := List_Containing (Cur_Use);

               begin
                  if Is_Compilation_Unit (Par)
                    and then Par /= Cunit_Entity (Current_Sem_Unit)
                  then
                     if Cur_List = Context_Items (Cunit (Current_Sem_Unit))
                       or else Cur_List = Visible_Declarations (Spec)
                     then
                        return;
                     end if;
                  end if;
               end;
            end if;

         --  Finally, if the current use clause is in the context then the
         --  clause is redundant when it is nested within the unit.

         elsif Nkind (Parent (Cur_Use)) = N_Compilation_Unit
           and then Nkind (Parent (Parent (Clause))) /= N_Compilation_Unit
           and then Get_Source_Unit (Cur_Use) = Get_Source_Unit (Clause)
         then
            Redundant := Clause;
            Prev_Use  := Cur_Use;
         end if;

         if Present (Redundant) and then Parent (Redundant) /= Prev_Use then

            --  Make sure we are looking at most-descendant use_package_clause
            --  by traversing the chain with Find_First_Use and then verifying
            --  there is no scope manipulation via Most_Descendant_Use_Clause.

            if Nkind (Prev_Use) = N_Use_Package_Clause
              and then
                (Nkind (Parent (Prev_Use)) /= N_Compilation_Unit
                  or else Most_Descendant_Use_Clause
                            (Prev_Use, Find_First_Use (Prev_Use)) /= Prev_Use)
            then
               Prev_Use := Find_First_Use (Prev_Use);
            end if;

            Error_Msg_Sloc := Sloc (Prev_Use);
            Error_Msg_NE -- CODEFIX
              ("& is already use-visible through previous use_clause #?r?",
               Redundant, Pack_Name);
         end if;
      end Note_Redundant_Use;

      --  Local variables

      Current_Instance : Entity_Id := Empty;
      Id               : Entity_Id;
      P                : Entity_Id;
      Prev             : Entity_Id;
      Private_With_OK  : Boolean   := False;
      Real_P           : Entity_Id;

   --  Start of processing for Use_One_Package

   begin
      --  Use_One_Package may have been called recursively to handle an
      --  implicit use for a auxiliary system package, so set P accordingly
      --  and skip redundancy checks.

      if No (Pack_Name) and then Present_System_Aux (N) then
         P := System_Aux_Id;

      --  Check for redundant use_package_clauses

      else
         --  Ignore cases where we are dealing with a non user defined package
         --  like Standard_Standard or something other than a valid package.

         if not Is_Entity_Name (Pack_Name)
           or else No (Entity (Pack_Name))
           or else Ekind (Entity (Pack_Name)) /= E_Package
         then
            return;
         end if;

         --  When a renaming exists we must check it for redundancy. The
         --  original package would have already been seen at this point.

         if Present (Renamed_Object (Entity (Pack_Name))) then
            P := Renamed_Object (Entity (Pack_Name));
         else
            P := Entity (Pack_Name);
         end if;

         --  Check for redundant clauses then set the current use clause for
         --  P if were are not "forcing" an installation from a scope
         --  reinstallation that is done throughout analysis for various
         --  reasons.

         if In_Use (P) then
            Note_Redundant_Use (Pack_Name);

            if not Force then
               Set_Current_Use_Clause (P, N);
            end if;

            return;

         --  Warn about detected redundant clauses

         elsif not Force
           and then In_Open_Scopes (P)
           and then not Is_Hidden_Open_Scope (P)
         then
            if Warn_On_Redundant_Constructs and then P = Current_Scope then
               Error_Msg_NE -- CODEFIX
                 ("& is already use-visible within itself?r?",
                   Pack_Name, P);
            end if;

            return;
         end if;

         --  Set P back to the non-renamed package so that visiblilty of the
         --  entities within the package can be properly set below.

         P := Entity (Pack_Name);
      end if;

      Set_In_Use (P);
      Set_Current_Use_Clause (P, N);

      --  Ada 2005 (AI-50217): Check restriction

      if From_Limited_With (P) then
         Error_Msg_N ("limited withed package cannot appear in use clause", N);
      end if;

      --  Find enclosing instance, if any

      if In_Instance then
         Current_Instance := Current_Scope;
         while not Is_Generic_Instance (Current_Instance) loop
            Current_Instance := Scope (Current_Instance);
         end loop;

         if No (Hidden_By_Use_Clause (N)) then
            Set_Hidden_By_Use_Clause (N, New_Elmt_List);
         end if;
      end if;

      --  If unit is a package renaming, indicate that the renamed package is
      --  also in use (the flags on both entities must remain consistent, and a
      --  subsequent use of either of them should be recognized as redundant).

      if Present (Renamed_Object (P)) then
         Set_In_Use (Renamed_Object (P));
         Set_Current_Use_Clause (Renamed_Object (P), N);
         Real_P := Renamed_Object (P);
      else
         Real_P := P;
      end if;

      --  Ada 2005 (AI-262): Check the use_clause of a private withed package
      --  found in the private part of a package specification

      if In_Private_Part (Current_Scope)
        and then Has_Private_With (P)
        and then Is_Child_Unit (Current_Scope)
        and then Is_Child_Unit (P)
        and then Is_Ancestor_Package (Scope (Current_Scope), P)
      then
         Private_With_OK := True;
      end if;

      --  Loop through entities in one package making them potentially
      --  use-visible.

      Id := First_Entity (P);
      while Present (Id)
        and then (Id /= First_Private_Entity (P)
                   or else Private_With_OK) -- Ada 2005 (AI-262)
      loop
         Prev := Current_Entity (Id);
         while Present (Prev) loop
            if Is_Immediately_Visible (Prev)
              and then (not Is_Overloadable (Prev)
                         or else not Is_Overloadable (Id)
                         or else (Type_Conformant (Id, Prev)))
            then
               if No (Current_Instance) then

                  --  Potentially use-visible entity remains hidden

                  goto Next_Usable_Entity;

               --  A use clause within an instance hides outer global entities,
               --  which are not used to resolve local entities in the
               --  instance. Note that the predefined entities in Standard
               --  could not have been hidden in the generic by a use clause,
               --  and therefore remain visible. Other compilation units whose
               --  entities appear in Standard must be hidden in an instance.

               --  To determine whether an entity is external to the instance
               --  we compare the scope depth of its scope with that of the
               --  current instance. However, a generic actual of a subprogram
               --  instance is declared in the wrapper package but will not be
               --  hidden by a use-visible entity. similarly, an entity that is
               --  declared in an enclosing instance will not be hidden by an
               --  an entity declared in a generic actual, which can only have
               --  been use-visible in the generic and will not have hidden the
               --  entity in the generic parent.

               --  If Id is called Standard, the predefined package with the
               --  same name is in the homonym chain. It has to be ignored
               --  because it has no defined scope (being the only entity in
               --  the system with this mandated behavior).

               elsif not Is_Hidden (Id)
                 and then Present (Scope (Prev))
                 and then not Is_Wrapper_Package (Scope (Prev))
                 and then Scope_Depth (Scope (Prev)) <
                          Scope_Depth (Current_Instance)
                 and then (Scope (Prev) /= Standard_Standard
                            or else Sloc (Prev) > Standard_Location)
               then
                  if In_Open_Scopes (Scope (Prev))
                    and then Is_Generic_Instance (Scope (Prev))
                    and then Present (Associated_Formal_Package (P))
                  then
                     null;

                  else
                     Set_Is_Potentially_Use_Visible (Id);
                     Set_Is_Immediately_Visible (Prev, False);
                     Append_Elmt (Prev, Hidden_By_Use_Clause (N));
                  end if;
               end if;

            --  A user-defined operator is not use-visible if the predefined
            --  operator for the type is immediately visible, which is the case
            --  if the type of the operand is in an open scope. This does not
            --  apply to user-defined operators that have operands of different
            --  types, because the predefined mixed mode operations (multiply
            --  and divide) apply to universal types and do not hide anything.

            elsif Ekind (Prev) = E_Operator
              and then Operator_Matches_Spec (Prev, Id)
              and then In_Open_Scopes
                         (Scope (Base_Type (Etype (First_Formal (Id)))))
              and then (No (Next_Formal (First_Formal (Id)))
                         or else Etype (First_Formal (Id)) =
                                 Etype (Next_Formal (First_Formal (Id)))
                         or else Chars (Prev) = Name_Op_Expon)
            then
               goto Next_Usable_Entity;

            --  In an instance, two homonyms may become use_visible through the
            --  actuals of distinct formal packages. In the generic, only the
            --  current one would have been visible, so make the other one
            --  not use_visible.

            --  In certain pathological cases it is possible that unrelated
            --  homonyms from distinct formal packages may exist in an
            --  uninstalled scope. We must test for that here.

            elsif Present (Current_Instance)
              and then Is_Potentially_Use_Visible (Prev)
              and then not Is_Overloadable (Prev)
              and then Scope (Id) /= Scope (Prev)
              and then Used_As_Generic_Actual (Scope (Prev))
              and then Used_As_Generic_Actual (Scope (Id))
              and then Is_List_Member (Scope (Prev))
              and then not In_Same_List (Current_Use_Clause (Scope (Prev)),
                                         Current_Use_Clause (Scope (Id)))
            then
               Set_Is_Potentially_Use_Visible (Prev, False);
               Append_Elmt (Prev, Hidden_By_Use_Clause (N));
            end if;

            Prev := Homonym (Prev);
         end loop;

         --  On exit, we know entity is not hidden, unless it is private

         if not Is_Hidden (Id)
           and then ((not Is_Child_Unit (Id)) or else Is_Visible_Lib_Unit (Id))
         then
            Set_Is_Potentially_Use_Visible (Id);

            if Is_Private_Type (Id) and then Present (Full_View (Id)) then
               Set_Is_Potentially_Use_Visible (Full_View (Id));
            end if;
         end if;

         <<Next_Usable_Entity>>
            Next_Entity (Id);
      end loop;

      --  Child units are also made use-visible by a use clause, but they may
      --  appear after all visible declarations in the parent entity list.

      while Present (Id) loop
         if Is_Child_Unit (Id) and then Is_Visible_Lib_Unit (Id) then
            Set_Is_Potentially_Use_Visible (Id);
         end if;

         Next_Entity (Id);
      end loop;

      if Chars (Real_P) = Name_System
        and then Scope (Real_P) = Standard_Standard
        and then Present_System_Aux (N)
      then
         Use_One_Package (N);
      end if;
   end Use_One_Package;

   ------------------
   -- Use_One_Type --
   ------------------

   procedure Use_One_Type
     (Id        : Node_Id;
      Installed : Boolean := False;
      Force     : Boolean := False)
   is
      function Spec_Reloaded_For_Body return Boolean;
      --  Determine whether the compilation unit is a package body and the use
      --  type clause is in the spec of the same package. Even though the spec
      --  was analyzed first, its context is reloaded when analysing the body.

      procedure Use_Class_Wide_Operations (Typ : Entity_Id);
      --  AI05-150: if the use_type_clause carries the "all" qualifier,
      --  class-wide operations of ancestor types are use-visible if the
      --  ancestor type is visible.

      ----------------------------
      -- Spec_Reloaded_For_Body --
      ----------------------------

      function Spec_Reloaded_For_Body return Boolean is
      begin
         if Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Body then
            declare
               Spec : constant Node_Id :=
                        Parent (List_Containing (Parent (Id)));

            begin
               --  Check whether type is declared in a package specification,
               --  and current unit is the corresponding package body. The
               --  use clauses themselves may be within a nested package.

               return
                 Nkind (Spec) = N_Package_Specification
                   and then In_Same_Source_Unit
                              (Corresponding_Body (Parent (Spec)),
                               Cunit_Entity (Current_Sem_Unit));
            end;
         end if;

         return False;
      end Spec_Reloaded_For_Body;

      -------------------------------
      -- Use_Class_Wide_Operations --
      -------------------------------

      procedure Use_Class_Wide_Operations (Typ : Entity_Id) is
         function Is_Class_Wide_Operation_Of
           (Op : Entity_Id;
            T  : Entity_Id) return Boolean;
         --  Determine whether a subprogram has a class-wide parameter or
         --  result that is T'Class.

         ---------------------------------
         --  Is_Class_Wide_Operation_Of --
         ---------------------------------

         function Is_Class_Wide_Operation_Of
           (Op : Entity_Id;
            T  : Entity_Id) return Boolean
         is
            Formal : Entity_Id;

         begin
            Formal := First_Formal (Op);
            while Present (Formal) loop
               if Etype (Formal) = Class_Wide_Type (T) then
                  return True;
               end if;

               Next_Formal (Formal);
            end loop;

            if Etype (Op) = Class_Wide_Type (T) then
               return True;
            end if;

            return False;
         end Is_Class_Wide_Operation_Of;

         --  Local variables

         Ent  : Entity_Id;
         Scop : Entity_Id;

      --  Start of processing for Use_Class_Wide_Operations

      begin
         Scop := Scope (Typ);
         if not Is_Hidden (Scop) then
            Ent := First_Entity (Scop);
            while Present (Ent) loop
               if Is_Overloadable (Ent)
                 and then Is_Class_Wide_Operation_Of (Ent, Typ)
                 and then not Is_Potentially_Use_Visible (Ent)
               then
                  Set_Is_Potentially_Use_Visible (Ent);
                  Append_Elmt (Ent, Used_Operations (Parent (Id)));
               end if;

               Next_Entity (Ent);
            end loop;
         end if;

         if Is_Derived_Type (Typ) then
            Use_Class_Wide_Operations (Etype (Base_Type (Typ)));
         end if;
      end Use_Class_Wide_Operations;

      --  Local variables

      Elmt          : Elmt_Id;
      Is_Known_Used : Boolean;
      Op_List       : Elist_Id;
      T             : Entity_Id;

   --  Start of processing for Use_One_Type

   begin
      if Entity (Id) = Any_Type then
         return;
      end if;

      --  It is the type determined by the subtype mark (8.4(8)) whose
      --  operations become potentially use-visible.

      T := Base_Type (Entity (Id));

      --  Either the type itself is used, the package where it is declared is
      --  in use or the entity is declared in the current package, thus
      --  use-visible.

      Is_Known_Used :=
          (In_Use (T)
            and then ((Present (Current_Use_Clause (T))
                        and then All_Present (Current_Use_Clause (T)))
                      or else not All_Present (Parent (Id))))
        or else In_Use (Scope (T))
        or else Scope (T) = Current_Scope;

      Set_Redundant_Use (Id,
        Is_Known_Used or else Is_Potentially_Use_Visible (T));

      if Ekind (T) = E_Incomplete_Type then
         Error_Msg_N ("premature usage of incomplete type", Id);

      elsif In_Open_Scopes (Scope (T)) then
         null;

      --  A limited view cannot appear in a use_type_clause. However, an access
      --  type whose designated type is limited has the flag but is not itself
      --  a limited view unless we only have a limited view of its enclosing
      --  package.

      elsif From_Limited_With (T) and then From_Limited_With (Scope (T)) then
         Error_Msg_N
           ("incomplete type from limited view cannot appear in use clause",
            Id);

      --  If the use clause is redundant, Used_Operations will usually be
      --  empty, but we need to set it to empty here in one case: If we are
      --  instantiating a generic library unit, then we install the ancestors
      --  of that unit in the scope stack, which involves reprocessing use
      --  clauses in those ancestors. Such a use clause will typically have a
      --  nonempty Used_Operations unless it was redundant in the generic unit,
      --  even if it is redundant at the place of the instantiation.

      elsif Redundant_Use (Id) then

         --  We must avoid incorrectly setting the Current_Use_Clause when we
         --  are working with a redundant clause that has already been linked
         --  in the Prev_Use_Clause chain, otherwise the chain will break.

         if Present (Current_Use_Clause (T))
           and then Present (Prev_Use_Clause (Current_Use_Clause (T)))
           and then Parent (Id) = Prev_Use_Clause (Current_Use_Clause (T))
         then
            null;
         else
            Set_Current_Use_Clause (T, Parent (Id));
         end if;

         Set_Used_Operations (Parent (Id), New_Elmt_List);

      --  If the subtype mark designates a subtype in a different package,
      --  we have to check that the parent type is visible, otherwise the
      --  use_type_clause is a no-op. Not clear how to do that???

      else
         Set_Current_Use_Clause (T, Parent (Id));
         Set_In_Use (T);

         --  If T is tagged, primitive operators on class-wide operands are
         --  also deemed available. Note that this is really necessary only
         --  in semantics-only mode, because the primitive operators are not
         --  fully constructed in this mode, but we do it in all modes for the
         --  sake of uniformity, as this should not matter in practice.

         if Is_Tagged_Type (T) then
            Set_In_Use (Class_Wide_Type (T));
         end if;

         --  Iterate over primitive operations of the type. If an operation is
         --  already use_visible, it is the result of a previous use_clause,
         --  and already appears on the corresponding entity chain. If the
         --  clause is being reinstalled, operations are already use-visible.

         if Installed then
            null;

         else
            Op_List := Collect_Primitive_Operations (T);
            Elmt := First_Elmt (Op_List);
            while Present (Elmt) loop
               if (Nkind (Node (Elmt)) = N_Defining_Operator_Symbol
                    or else Chars (Node (Elmt)) in Any_Operator_Name)
                 and then not Is_Hidden (Node (Elmt))
                 and then not Is_Potentially_Use_Visible (Node (Elmt))
               then
                  Set_Is_Potentially_Use_Visible (Node (Elmt));
                  Append_Elmt (Node (Elmt), Used_Operations (Parent (Id)));

               elsif Ada_Version >= Ada_2012
                 and then All_Present (Parent (Id))
                 and then not Is_Hidden (Node (Elmt))
                 and then not Is_Potentially_Use_Visible (Node (Elmt))
               then
                  Set_Is_Potentially_Use_Visible (Node (Elmt));
                  Append_Elmt (Node (Elmt), Used_Operations (Parent (Id)));
               end if;

               Next_Elmt (Elmt);
            end loop;
         end if;

         if Ada_Version >= Ada_2012
           and then All_Present (Parent (Id))
           and then Is_Tagged_Type (T)
         then
            Use_Class_Wide_Operations (T);
         end if;
      end if;

      --  If warning on redundant constructs, check for unnecessary WITH

      if not Force
        and then Warn_On_Redundant_Constructs
        and then Is_Known_Used

        --                     with P;         with P; use P;
        --    package P is     package X is    package body X is
        --       type T ...       use P.T;

        --  The compilation unit is the body of X. GNAT first compiles the
        --  spec of X, then proceeds to the body. At that point P is marked
        --  as use visible. The analysis then reinstalls the spec along with
        --  its context. The use clause P.T is now recognized as redundant,
        --  but in the wrong context. Do not emit a warning in such cases.
        --  Do not emit a warning either if we are in an instance, there is
        --  no redundancy between an outer use_clause and one that appears
        --  within the generic.

        and then not Spec_Reloaded_For_Body
        and then not In_Instance
        and then not In_Inlined_Body
      then
         --  The type already has a use clause

         if In_Use (T) then

            --  Case where we know the current use clause for the type

            if Present (Current_Use_Clause (T)) then
               Use_Clause_Known : declare
                  Clause1 : constant Node_Id :=
                              Find_First_Use (Current_Use_Clause (T));
                  Clause2 : constant Node_Id := Parent (Id);
                  Ent1    : Entity_Id;
                  Ent2    : Entity_Id;
                  Err_No  : Node_Id;
                  Unit1   : Node_Id;
                  Unit2   : Node_Id;

               --  Start of processing for Use_Clause_Known

               begin
                  --  If both current use_type_clause and the use_type_clause
                  --  for the type are at the compilation unit level, one of
                  --  the units must be an ancestor of the other, and the
                  --  warning belongs on the descendant.

                  if Nkind (Parent (Clause1)) = N_Compilation_Unit
                       and then
                     Nkind (Parent (Clause2)) = N_Compilation_Unit
                  then
                     --  If the unit is a subprogram body that acts as spec,
                     --  the context clause is shared with the constructed
                     --  subprogram spec. Clearly there is no redundancy.

                     if Clause1 = Clause2 then
                        return;
                     end if;

                     Unit1 := Unit (Parent (Clause1));
                     Unit2 := Unit (Parent (Clause2));

                     --  If both clauses are on same unit, or one is the body
                     --  of the other, or one of them is in a subunit, report
                     --  redundancy on the later one.

                     if Unit1 = Unit2 or else Nkind (Unit1) = N_Subunit then
                        Error_Msg_Sloc := Sloc (Current_Use_Clause (T));
                        Error_Msg_NE -- CODEFIX
                          ("& is already use-visible through previous "
                           & "use_type_clause #??", Clause1, T);
                        return;

                     elsif Nkind (Unit2) in N_Package_Body | N_Subprogram_Body
                       and then Nkind (Unit1) /= Nkind (Unit2)
                       and then Nkind (Unit1) /= N_Subunit
                     then
                        Error_Msg_Sloc := Sloc (Clause1);
                        Error_Msg_NE -- CODEFIX
                          ("& is already use-visible through previous "
                           & "use_type_clause #??", Current_Use_Clause (T), T);
                        return;
                     end if;

                     --  There is a redundant use_type_clause in a child unit.
                     --  Determine which of the units is more deeply nested.
                     --  If a unit is a package instance, retrieve the entity
                     --  and its scope from the instance spec.

                     Ent1 := Entity_Of_Unit (Unit1);
                     Ent2 := Entity_Of_Unit (Unit2);

                     if Scope (Ent2) = Standard_Standard then
                        Error_Msg_Sloc := Sloc (Current_Use_Clause (T));
                        Err_No := Clause1;

                     elsif Scope (Ent1) = Standard_Standard then
                        Error_Msg_Sloc := Sloc (Id);
                        Err_No := Clause2;

                     --  If both units are child units, we determine which one
                     --  is the descendant by the scope distance to the
                     --  ultimate parent unit.

                     else
                        declare
                           S1 : Entity_Id;
                           S2 : Entity_Id;

                        begin
                           S1 := Scope (Ent1);
                           S2 := Scope (Ent2);
                           while Present (S1)
                             and then Present (S2)
                             and then S1 /= Standard_Standard
                             and then S2 /= Standard_Standard
                           loop
                              S1 := Scope (S1);
                              S2 := Scope (S2);
                           end loop;

                           if S1 = Standard_Standard then
                              Error_Msg_Sloc := Sloc (Id);
                              Err_No := Clause2;
                           else
                              Error_Msg_Sloc := Sloc (Current_Use_Clause (T));
                              Err_No := Clause1;
                           end if;
                        end;
                     end if;

                     if Parent (Id) /= Err_No then
                        if Most_Descendant_Use_Clause
                             (Err_No, Parent (Id)) = Parent (Id)
                        then
                           Error_Msg_Sloc := Sloc (Err_No);
                           Err_No := Parent (Id);
                        end if;

                        Error_Msg_NE -- CODEFIX
                          ("& is already use-visible through previous "
                           & "use_type_clause #??", Err_No, Id);
                     end if;

                  --  Case where current use_type_clause and use_type_clause
                  --  for the type are not both at the compilation unit level.
                  --  In this case we don't have location information.

                  else
                     Error_Msg_NE -- CODEFIX
                       ("& is already use-visible through previous "
                        & "use_type_clause??", Id, T);
                  end if;
               end Use_Clause_Known;

            --  Here if Current_Use_Clause is not set for T, another case where
            --  we do not have the location information available.

            else
               Error_Msg_NE -- CODEFIX
                 ("& is already use-visible through previous "
                  & "use_type_clause??", Id, T);
            end if;

         --  The package where T is declared is already used

         elsif In_Use (Scope (T)) then
            --  Due to expansion of contracts we could be attempting to issue
            --  a spurious warning - so verify there is a previous use clause.

            if Current_Use_Clause (Scope (T)) /=
                 Find_First_Use (Current_Use_Clause (Scope (T)))
            then
               Error_Msg_Sloc :=
                 Sloc (Find_First_Use (Current_Use_Clause (Scope (T))));
               Error_Msg_NE -- CODEFIX
                 ("& is already use-visible through package use clause #??",
                  Id, T);
            end if;

         --  The current scope is the package where T is declared

         else
            Error_Msg_Node_2 := Scope (T);
            Error_Msg_NE -- CODEFIX
              ("& is already use-visible inside package &??", Id, T);
         end if;
      end if;
   end Use_One_Type;

   ----------------
   -- Write_Info --
   ----------------

   procedure Write_Info is
      Id : Entity_Id := First_Entity (Current_Scope);

   begin
      --  No point in dumping standard entities

      if Current_Scope = Standard_Standard then
         return;
      end if;

      Write_Str ("========================================================");
      Write_Eol;
      Write_Str ("        Defined Entities in ");
      Write_Name (Chars (Current_Scope));
      Write_Eol;
      Write_Str ("========================================================");
      Write_Eol;

      if No (Id) then
         Write_Str ("-- none --");
         Write_Eol;

      else
         while Present (Id) loop
            Write_Entity_Info (Id, " ");
            Next_Entity (Id);
         end loop;
      end if;

      if Scope (Current_Scope) = Standard_Standard then

         --  Print information on the current unit itself

         Write_Entity_Info (Current_Scope, " ");
      end if;

      Write_Eol;
   end Write_Info;

   --------
   -- ws --
   --------

   procedure ws is
      S : Entity_Id;
   begin
      for J in reverse 1 .. Scope_Stack.Last loop
         S := Scope_Stack.Table (J).Entity;
         Write_Int (Int (S));
         Write_Str (" === ");
         Write_Name (Chars (S));
         Write_Eol;
      end loop;
   end ws;

   --------
   -- we --
   --------

   procedure we (S : Entity_Id) is
      E : Entity_Id;
   begin
      E := First_Entity (S);
      while Present (E) loop
         Write_Int (Int (E));
         Write_Str (" === ");
         Write_Name (Chars (E));
         Write_Eol;
         Next_Entity (E);
      end loop;
   end we;
end Sem_Ch8;
