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

with Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
with Contracts;      use Contracts;
with Debug;          use Debug;
with Elists;         use Elists;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Eval_Fat;       use Eval_Fat;
with Exp_Ch3;        use Exp_Ch3;
with Exp_Ch9;        use Exp_Ch9;
with Exp_Disp;       use Exp_Disp;
with Exp_Dist;       use Exp_Dist;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Ghost;          use Ghost;
with Itypes;         use Itypes;
with Layout;         use Layout;
with Lib;            use Lib;
with Lib.Xref;       use Lib.Xref;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Case;       use Sem_Case;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch7;        use Sem_Ch7;
with Sem_Ch8;        use Sem_Ch8;
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_Elim;       use Sem_Elim;
with Sem_Eval;       use Sem_Eval;
with Sem_Mech;       use Sem_Mech;
with Sem_Res;        use Sem_Res;
with Sem_Smem;       use Sem_Smem;
with Sem_Type;       use Sem_Type;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Targparm;       use Targparm;
with Tbuild;         use Tbuild;
with Ttypes;         use Ttypes;
with Uintp;          use Uintp;
with Urealp;         use Urealp;

package body Sem_Ch3 is

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

   procedure Add_Interface_Tag_Components (N : Node_Id; Typ : Entity_Id);
   --  Ada 2005 (AI-251): Add the tag components corresponding to all the
   --  abstract interface types implemented by a record type or a derived
   --  record type.

   procedure Build_Access_Subprogram_Wrapper (Decl : Node_Id);
   --  When an access-to-subprogram type has pre/postconditions, we build a
   --  subprogram that includes these contracts and is invoked by an indirect
   --  call through the corresponding access type.

   procedure Build_Derived_Type
     (N             : Node_Id;
      Parent_Type   : Entity_Id;
      Derived_Type  : Entity_Id;
      Is_Completion : Boolean;
      Derive_Subps  : Boolean := True);
   --  Create and decorate a Derived_Type given the Parent_Type entity. N is
   --  the N_Full_Type_Declaration node containing the derived type definition.
   --  Parent_Type is the entity for the parent type in the derived type
   --  definition and Derived_Type the actual derived type. Is_Completion must
   --  be set to False if Derived_Type is the N_Defining_Identifier node in N
   --  (i.e. Derived_Type = Defining_Identifier (N)). In this case N is not the
   --  completion of a private type declaration. If Is_Completion is set to
   --  True, N is the completion of a private type declaration and Derived_Type
   --  is different from the defining identifier inside N (i.e. Derived_Type /=
   --  Defining_Identifier (N)). Derive_Subps indicates whether the parent
   --  subprograms should be derived. The only case where this parameter is
   --  False is when Build_Derived_Type is recursively called to process an
   --  implicit derived full type for a type derived from a private type (in
   --  that case the subprograms must only be derived for the private view of
   --  the type).
   --
   --  ??? These flags need a bit of re-examination and re-documentation:
   --  ???  are they both necessary (both seem related to the recursion)?

   procedure Build_Derived_Access_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id);
   --  Subsidiary procedure to Build_Derived_Type. For a derived access type,
   --  create an implicit base if the parent type is constrained or if the
   --  subtype indication has a constraint.

   procedure Build_Derived_Array_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id);
   --  Subsidiary procedure to Build_Derived_Type. For a derived array type,
   --  create an implicit base if the parent type is constrained or if the
   --  subtype indication has a constraint.

   procedure Build_Derived_Concurrent_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id);
   --  Subsidiary procedure to Build_Derived_Type. For a derived task or
   --  protected type, inherit entries and protected subprograms, check
   --  legality of discriminant constraints if any.

   procedure Build_Derived_Enumeration_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id);
   --  Subsidiary procedure to Build_Derived_Type. For a derived enumeration
   --  type, we must create a new list of literals. Types derived from
   --  Character and [Wide_]Wide_Character are special-cased.

   procedure Build_Derived_Numeric_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id);
   --  Subsidiary procedure to Build_Derived_Type. For numeric types, create
   --  an anonymous base type, and propagate constraint to subtype if needed.

   procedure Build_Derived_Private_Type
     (N             : Node_Id;
      Parent_Type   : Entity_Id;
      Derived_Type  : Entity_Id;
      Is_Completion : Boolean;
      Derive_Subps  : Boolean := True);
   --  Subsidiary procedure to Build_Derived_Type. This procedure is complex
   --  because the parent may or may not have a completion, and the derivation
   --  may itself be a completion.

   procedure Build_Derived_Record_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id;
      Derive_Subps : Boolean := True);
   --  Subsidiary procedure used for tagged and untagged record types
   --  by Build_Derived_Type and Analyze_Private_Extension_Declaration.
   --  All parameters are as in Build_Derived_Type except that N, in
   --  addition to being an N_Full_Type_Declaration node, can also be an
   --  N_Private_Extension_Declaration node. See the definition of this routine
   --  for much more info. Derive_Subps indicates whether subprograms should be
   --  derived from the parent type. The only case where Derive_Subps is False
   --  is for an implicit derived full type for a type derived from a private
   --  type (see Build_Derived_Type).

   procedure Build_Discriminal (Discrim : Entity_Id);
   --  Create the discriminal corresponding to discriminant Discrim, that is
   --  the parameter corresponding to Discrim to be used in initialization
   --  procedures for the type where Discrim is a discriminant. Discriminals
   --  are not used during semantic analysis, and are not fully defined
   --  entities until expansion. Thus they are not given a scope until
   --  initialization procedures are built.

   function Build_Discriminant_Constraints
     (T           : Entity_Id;
      Def         : Node_Id;
      Derived_Def : Boolean := False) return Elist_Id;
   --  Validate discriminant constraints and return the list of the constraints
   --  in order of discriminant declarations, where T is the discriminated
   --  unconstrained type. Def is the N_Subtype_Indication node where the
   --  discriminants constraints for T are specified. Derived_Def is True
   --  when building the discriminant constraints in a derived type definition
   --  of the form "type D (...) is new T (xxx)". In this case T is the parent
   --  type and Def is the constraint "(xxx)" on T and this routine sets the
   --  Corresponding_Discriminant field of the discriminants in the derived
   --  type D to point to the corresponding discriminants in the parent type T.

   procedure Build_Discriminated_Subtype
     (T           : Entity_Id;
      Def_Id      : Entity_Id;
      Elist       : Elist_Id;
      Related_Nod : Node_Id;
      For_Access  : Boolean := False);
   --  Subsidiary procedure to Constrain_Discriminated_Type and to
   --  Process_Incomplete_Dependents. Given
   --
   --     T (a possibly discriminated base type)
   --     Def_Id (a very partially built subtype for T),
   --
   --  the call completes Def_Id to be the appropriate E_*_Subtype.
   --
   --  The Elist is the list of discriminant constraints if any (it is set
   --  to No_Elist if T is not a discriminated type, and to an empty list if
   --  T has discriminants but there are no discriminant constraints). The
   --  Related_Nod is the same as Decl_Node in Create_Constrained_Components.
   --  The For_Access says whether or not this subtype is really constraining
   --  an access type.

   function Build_Scalar_Bound
     (Bound : Node_Id;
      Par_T : Entity_Id;
      Der_T : Entity_Id) return Node_Id;
   --  The bounds of a derived scalar type are conversions of the bounds of
   --  the parent type. Optimize the representation if the bounds are literals.
   --  Needs a more complete spec--what are the parameters exactly, and what
   --  exactly is the returned value, and how is Bound affected???

   procedure Check_Access_Discriminant_Requires_Limited
     (D   : Node_Id;
      Loc : Node_Id);
   --  Check the restriction that the type to which an access discriminant
   --  belongs must be a concurrent type or a descendant of a type with
   --  the reserved word 'limited' in its declaration.

   procedure Check_Anonymous_Access_Component
     (Typ_Decl   : Node_Id;
      Typ        : Entity_Id;
      Prev       : Entity_Id;
      Comp_Def   : Node_Id;
      Access_Def : Node_Id);
   --  Ada 2005 AI-382: an access component in a record definition can refer to
   --  the enclosing record, in which case it denotes the type itself, and not
   --  the current instance of the type. We create an anonymous access type for
   --  the component, and flag it as an access to a component, so accessibility
   --  checks are properly performed on it. The declaration of the access type
   --  is placed ahead of that of the record to prevent order-of-elaboration
   --  circularity issues in Gigi. We create an incomplete type for the record
   --  declaration, which is the designated type of the anonymous access.

   procedure Check_Anonymous_Access_Components
     (Typ_Decl  : Node_Id;
      Typ       : Entity_Id;
      Prev      : Entity_Id;
      Comp_List : Node_Id);
   --  Call Check_Anonymous_Access_Component on Comp_List

   procedure Check_Constraining_Discriminant (New_Disc, Old_Disc : Entity_Id);
   --  Check that, if a new discriminant is used in a constraint defining the
   --  parent subtype of a derivation, its subtype is statically compatible
   --  with the subtype of the corresponding parent discriminant (RM 3.7(15)).

   procedure Check_Delta_Expression (E : Node_Id);
   --  Check that the expression represented by E is suitable for use as a
   --  delta expression, i.e. it is of real type and is static.

   procedure Check_Digits_Expression (E : Node_Id);
   --  Check that the expression represented by E is suitable for use as a
   --  digits expression, i.e. it is of integer type, positive and static.

   procedure Check_Initialization (T : Entity_Id; Exp : Node_Id);
   --  Validate the initialization of an object declaration. T is the required
   --  type, and Exp is the initialization expression.

   procedure Check_Interfaces (N : Node_Id; Def : Node_Id);
   --  Check ARM rules 3.9.4 (15/2), 9.1 (9.d/2) and 9.4 (11.d/2)

   procedure Check_Or_Process_Discriminants
     (N    : Node_Id;
      T    : Entity_Id;
      Prev : Entity_Id := Empty);
   --  If N is the full declaration of the completion T of an incomplete or
   --  private type, check its discriminants (which are already known to be
   --  conformant with those of the partial view, see Find_Type_Name),
   --  otherwise process them. Prev is the entity of the partial declaration,
   --  if any.

   procedure Check_Real_Bound (Bound : Node_Id);
   --  Check given bound for being of real type and static. If not, post an
   --  appropriate message, and rewrite the bound with the real literal zero.

   procedure Constant_Redeclaration
     (Id : Entity_Id;
      N  : Node_Id;
      T  : out Entity_Id);
   --  Various checks on legality of full declaration of deferred constant.
   --  Id is the entity for the redeclaration, N is the N_Object_Declaration,
   --  node. The caller has not yet set any attributes of this entity.

   function Contain_Interface
     (Iface  : Entity_Id;
      Ifaces : Elist_Id) return Boolean;
   --  Ada 2005: Determine whether Iface is present in the list Ifaces

   procedure Convert_Scalar_Bounds
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id;
      Loc          : Source_Ptr);
   --  For derived scalar types, convert the bounds in the type definition to
   --  the derived type, and complete their analysis. Given a constraint of the
   --  form ".. new T range Lo .. Hi", Lo and Hi are analyzed and resolved with
   --  T'Base, the parent_type. The bounds of the derived type (the anonymous
   --  base) are copies of Lo and Hi. Finally, the bounds of the derived
   --  subtype are conversions of those bounds to the derived_type, so that
   --  their typing is consistent.

   procedure Copy_Array_Base_Type_Attributes (T1, T2 : Entity_Id);
   --  Copies attributes from array base type T2 to array base type T1. Copies
   --  only attributes that apply to base types, but not subtypes.

   procedure Copy_Array_Subtype_Attributes (T1, T2 : Entity_Id);
   --  Copies attributes from array subtype T2 to array subtype T1. Copies
   --  attributes that apply to both subtypes and base types.

   procedure Create_Constrained_Components
     (Subt        : Entity_Id;
      Decl_Node   : Node_Id;
      Typ         : Entity_Id;
      Constraints : Elist_Id);
   --  Build the list of entities for a constrained discriminated record
   --  subtype. If a component depends on a discriminant, replace its subtype
   --  using the discriminant values in the discriminant constraint. Subt
   --  is the defining identifier for the subtype whose list of constrained
   --  entities we will create. Decl_Node is the type declaration node where
   --  we will attach all the itypes created. Typ is the base discriminated
   --  type for the subtype Subt. Constraints is the list of discriminant
   --  constraints for Typ.

   function Constrain_Component_Type
     (Comp            : Entity_Id;
      Constrained_Typ : Entity_Id;
      Related_Node    : Node_Id;
      Typ             : Entity_Id;
      Constraints     : Elist_Id) return Entity_Id;
   --  Given a discriminated base type Typ, a list of discriminant constraints,
   --  Constraints, for Typ and a component Comp of Typ, create and return the
   --  type corresponding to Etype (Comp) where all discriminant references
   --  are replaced with the corresponding constraint. If Etype (Comp) contains
   --  no discriminant references then it is returned as-is. Constrained_Typ
   --  is the final constrained subtype to which the constrained component
   --  belongs. Related_Node is the node where we attach all created itypes.

   procedure Constrain_Access
     (Def_Id      : in out Entity_Id;
      S           : Node_Id;
      Related_Nod : Node_Id);
   --  Apply a list of constraints to an access type. If Def_Id is empty, it is
   --  an anonymous type created for a subtype indication. In that case it is
   --  created in the procedure and attached to Related_Nod.

   procedure Constrain_Array
     (Def_Id      : in out Entity_Id;
      SI          : Node_Id;
      Related_Nod : Node_Id;
      Related_Id  : Entity_Id;
      Suffix      : Character);
   --  Apply a list of index constraints to an unconstrained array type. The
   --  first parameter is the entity for the resulting subtype. A value of
   --  Empty for Def_Id indicates that an implicit type must be created, but
   --  creation is delayed (and must be done by this procedure) because other
   --  subsidiary implicit types must be created first (which is why Def_Id
   --  is an in/out parameter). The second parameter is a subtype indication
   --  node for the constrained array to be created (e.g. something of the
   --  form string (1 .. 10)). Related_Nod gives the place where this type
   --  has to be inserted in the tree. The Related_Id and Suffix parameters
   --  are used to build the associated Implicit type name.

   procedure Constrain_Concurrent
     (Def_Id      : in out Entity_Id;
      SI          : Node_Id;
      Related_Nod : Node_Id;
      Related_Id  : Entity_Id;
      Suffix      : Character);
   --  Apply list of discriminant constraints to an unconstrained concurrent
   --  type.
   --
   --    SI is the N_Subtype_Indication node containing the constraint and
   --    the unconstrained type to constrain.
   --
   --    Def_Id is the entity for the resulting constrained subtype. A value
   --    of Empty for Def_Id indicates that an implicit type must be created,
   --    but creation is delayed (and must be done by this procedure) because
   --    other subsidiary implicit types must be created first (which is why
   --    Def_Id is an in/out parameter).
   --
   --    Related_Nod gives the place where this type has to be inserted
   --    in the tree.
   --
   --  The last two arguments are used to create its external name if needed.

   function Constrain_Corresponding_Record
     (Prot_Subt   : Entity_Id;
      Corr_Rec    : Entity_Id;
      Related_Nod : Node_Id) return Entity_Id;
   --  When constraining a protected type or task type with discriminants,
   --  constrain the corresponding record with the same discriminant values.

   procedure Constrain_Decimal (Def_Id : Entity_Id; S : Node_Id);
   --  Constrain a decimal fixed point type with a digits constraint and/or a
   --  range constraint, and build E_Decimal_Fixed_Point_Subtype entity.

   procedure Constrain_Discriminated_Type
     (Def_Id      : Entity_Id;
      S           : Node_Id;
      Related_Nod : Node_Id;
      For_Access  : Boolean := False);
   --  Process discriminant constraints of composite type. Verify that values
   --  have been provided for all discriminants, that the original type is
   --  unconstrained, and that the types of the supplied expressions match
   --  the discriminant types. The first three parameters are like in routine
   --  Constrain_Concurrent. See Build_Discriminated_Subtype for an explanation
   --  of For_Access.

   procedure Constrain_Enumeration (Def_Id : Entity_Id; S : Node_Id);
   --  Constrain an enumeration type with a range constraint. This is identical
   --  to Constrain_Integer, but for the Ekind of the resulting subtype.

   procedure Constrain_Float (Def_Id : Entity_Id; S : Node_Id);
   --  Constrain a floating point type with either a digits constraint
   --  and/or a range constraint, building a E_Floating_Point_Subtype.

   procedure Constrain_Index
     (Index        : Node_Id;
      S            : Node_Id;
      Related_Nod  : Node_Id;
      Related_Id   : Entity_Id;
      Suffix       : Character;
      Suffix_Index : Pos);
   --  Process an index constraint S in a constrained array declaration. The
   --  constraint can be a subtype name, or a range with or without an explicit
   --  subtype mark. The index is the corresponding index of the unconstrained
   --  array. The Related_Id and Suffix parameters are used to build the
   --  associated Implicit type name.

   procedure Constrain_Integer (Def_Id : Entity_Id; S : Node_Id);
   --  Build subtype of a signed or modular integer type

   procedure Constrain_Ordinary_Fixed (Def_Id : Entity_Id; S : Node_Id);
   --  Constrain an ordinary fixed point type with a range constraint, and
   --  build an E_Ordinary_Fixed_Point_Subtype entity.

   procedure Copy_And_Swap (Priv, Full : Entity_Id);
   --  Copy the Priv entity into the entity of its full declaration then swap
   --  the two entities in such a manner that the former private type is now
   --  seen as a full type.

   procedure Decimal_Fixed_Point_Type_Declaration
     (T   : Entity_Id;
      Def : Node_Id);
   --  Create a new decimal fixed point type, and apply the constraint to
   --  obtain a subtype of this new type.

   procedure Complete_Private_Subtype
     (Priv        : Entity_Id;
      Full        : Entity_Id;
      Full_Base   : Entity_Id;
      Related_Nod : Node_Id);
   --  Complete the implicit full view of a private subtype by setting the
   --  appropriate semantic fields. If the full view of the parent is a record
   --  type, build constrained components of subtype.

   procedure Derive_Progenitor_Subprograms
     (Parent_Type : Entity_Id;
      Tagged_Type : Entity_Id);
   --  Ada 2005 (AI-251): To complete type derivation, collect the primitive
   --  operations of progenitors of Tagged_Type, and replace the subsidiary
   --  subtypes with Tagged_Type, to build the specs of the inherited interface
   --  primitives. The derived primitives are aliased to those of the
   --  interface. This routine takes care also of transferring to the full view
   --  subprograms associated with the partial view of Tagged_Type that cover
   --  interface primitives.

   procedure Derived_Standard_Character
     (N             : Node_Id;
      Parent_Type   : Entity_Id;
      Derived_Type  : Entity_Id);
   --  Subsidiary procedure to Build_Derived_Enumeration_Type which handles
   --  derivations from types Standard.Character and Standard.Wide_Character.

   procedure Derived_Type_Declaration
     (T             : Entity_Id;
      N             : Node_Id;
      Is_Completion : Boolean);
   --  Process a derived type declaration. Build_Derived_Type is invoked
   --  to process the actual derived type definition. Parameters N and
   --  Is_Completion have the same meaning as in Build_Derived_Type.
   --  T is the N_Defining_Identifier for the entity defined in the
   --  N_Full_Type_Declaration node N, that is T is the derived type.

   procedure Enumeration_Type_Declaration (T : Entity_Id; Def : Node_Id);
   --  Insert each literal in symbol table, as an overloadable identifier. Each
   --  enumeration type is mapped into a sequence of integers, and each literal
   --  is defined as a constant with integer value. If any of the literals are
   --  character literals, the type is a character type, which means that
   --  strings are legal aggregates for arrays of components of the type.

   function Expand_To_Stored_Constraint
     (Typ        : Entity_Id;
      Constraint : Elist_Id) return Elist_Id;
   --  Given a constraint (i.e. a list of expressions) on the discriminants of
   --  Typ, expand it into a constraint on the stored discriminants and return
   --  the new list of expressions constraining the stored discriminants.

   function Find_Type_Of_Object
     (Obj_Def     : Node_Id;
      Related_Nod : Node_Id) return Entity_Id;
   --  Get type entity for object referenced by Obj_Def, attaching the implicit
   --  types generated to Related_Nod.

   procedure Floating_Point_Type_Declaration (T : Entity_Id; Def : Node_Id);
   --  Create a new float and apply the constraint to obtain subtype of it

   function Has_Range_Constraint (N : Node_Id) return Boolean;
   --  Given an N_Subtype_Indication node N, return True if a range constraint
   --  is present, either directly, or as part of a digits or delta constraint.
   --  In addition, a digits constraint in the decimal case returns True, since
   --  it establishes a default range if no explicit range is present.

   function Inherit_Components
     (N             : Node_Id;
      Parent_Base   : Entity_Id;
      Derived_Base  : Entity_Id;
      Is_Tagged     : Boolean;
      Inherit_Discr : Boolean;
      Discs         : Elist_Id) return Elist_Id;
   --  Called from Build_Derived_Record_Type to inherit the components of
   --  Parent_Base (a base type) into the Derived_Base (the derived base type).
   --  For more information on derived types and component inheritance please
   --  consult the comment above the body of Build_Derived_Record_Type.
   --
   --    N is the original derived type declaration
   --
   --    Is_Tagged is set if we are dealing with tagged types
   --
   --    If Inherit_Discr is set, Derived_Base inherits its discriminants from
   --    Parent_Base, otherwise no discriminants are inherited.
   --
   --    Discs gives the list of constraints that apply to Parent_Base in the
   --    derived type declaration. If Discs is set to No_Elist, then we have
   --    the following situation:
   --
   --      type Parent (D1..Dn : ..) is [tagged] record ...;
   --      type Derived is new Parent [with ...];
   --
   --    which gets treated as
   --
   --      type Derived (D1..Dn : ..) is new Parent (D1,..,Dn) [with ...];
   --
   --  For untagged types the returned value is an association list. The list
   --  starts from the association (Parent_Base => Derived_Base), and then it
   --  contains a sequence of the associations of the form
   --
   --    (Old_Component => New_Component),
   --
   --  where Old_Component is the Entity_Id of a component in Parent_Base and
   --  New_Component is the Entity_Id of the corresponding component in
   --  Derived_Base. For untagged records, this association list is needed when
   --  copying the record declaration for the derived base. In the tagged case
   --  the value returned is irrelevant.

   function Is_EVF_Procedure (Subp : Entity_Id) return Boolean;
   --  Subsidiary to Check_Abstract_Overriding and Derive_Subprogram.
   --  Determine whether subprogram Subp is a procedure subject to pragma
   --  Extensions_Visible with value False and has at least one controlling
   --  parameter of mode OUT.

   function Is_Private_Primitive (Prim : Entity_Id) return Boolean;
   --  Subsidiary to Check_Abstract_Overriding and Derive_Subprogram.
   --  When applied to a primitive subprogram Prim, returns True if Prim is
   --  declared as a private operation within a package or generic package,
   --  and returns False otherwise.

   function Is_Valid_Constraint_Kind
     (T_Kind          : Type_Kind;
      Constraint_Kind : Node_Kind) return Boolean;
   --  Returns True if it is legal to apply the given kind of constraint to the
   --  given kind of type (index constraint to an array type, for example).

   procedure Modular_Type_Declaration (T : Entity_Id; Def : Node_Id);
   --  Create new modular type. Verify that modulus is in bounds

   procedure New_Concatenation_Op (Typ : Entity_Id);
   --  Create an abbreviated declaration for an operator in order to
   --  materialize concatenation on array types.

   procedure Ordinary_Fixed_Point_Type_Declaration
     (T   : Entity_Id;
      Def : Node_Id);
   --  Create a new ordinary fixed point type, and apply the constraint to
   --  obtain subtype of it.

   procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id);
   --  Wrapper on Preanalyze_Spec_Expression for default expressions, so that
   --  In_Default_Expr can be properly adjusted.

   procedure Prepare_Private_Subtype_Completion
     (Id          : Entity_Id;
      Related_Nod : Node_Id);
   --  Id is a subtype of some private type. Creates the full declaration
   --  associated with Id whenever possible, i.e. when the full declaration
   --  of the base type is already known. Records each subtype into
   --  Private_Dependents of the base type.

   procedure Process_Incomplete_Dependents
     (N      : Node_Id;
      Full_T : Entity_Id;
      Inc_T  : Entity_Id);
   --  Process all entities that depend on an incomplete type. There include
   --  subtypes, subprogram types that mention the incomplete type in their
   --  profiles, and subprogram with access parameters that designate the
   --  incomplete type.

   --  Inc_T is the defining identifier of an incomplete type declaration, its
   --  Ekind is E_Incomplete_Type.
   --
   --    N is the corresponding N_Full_Type_Declaration for Inc_T.
   --
   --    Full_T is N's defining identifier.
   --
   --  Subtypes of incomplete types with discriminants are completed when the
   --  parent type is. This is simpler than private subtypes, because they can
   --  only appear in the same scope, and there is no need to exchange views.
   --  Similarly, access_to_subprogram types may have a parameter or a return
   --  type that is an incomplete type, and that must be replaced with the
   --  full type.
   --
   --  If the full type is tagged, subprogram with access parameters that
   --  designated the incomplete may be primitive operations of the full type,
   --  and have to be processed accordingly.

   procedure Process_Real_Range_Specification (Def : Node_Id);
   --  Given the type definition for a real type, this procedure processes and
   --  checks the real range specification of this type definition if one is
   --  present. If errors are found, error messages are posted, and the
   --  Real_Range_Specification of Def is reset to Empty.

   procedure Record_Type_Declaration
     (T    : Entity_Id;
      N    : Node_Id;
      Prev : Entity_Id);
   --  Process a record type declaration (for both untagged and tagged
   --  records). Parameters T and N are exactly like in procedure
   --  Derived_Type_Declaration, except that no flag Is_Completion is needed
   --  for this routine. If this is the completion of an incomplete type
   --  declaration, Prev is the entity of the incomplete declaration, used for
   --  cross-referencing. Otherwise Prev = T.

   procedure Record_Type_Definition (Def : Node_Id; Prev_T : Entity_Id);
   --  This routine is used to process the actual record type definition (both
   --  for untagged and tagged records). Def is a record type definition node.
   --  This procedure analyzes the components in this record type definition.
   --  Prev_T is the entity for the enclosing record type. It is provided so
   --  that its Has_Task flag can be set if any of the component have Has_Task
   --  set. If the declaration is the completion of an incomplete type
   --  declaration, Prev_T is the original incomplete type, whose full view is
   --  the record type.

   procedure Replace_Discriminants (Typ : Entity_Id; Decl : Node_Id);
   --  Subsidiary to Build_Derived_Record_Type. For untagged record types, we
   --  first create the list of components for the derived type from that of
   --  the parent by means of Inherit_Components and then build a copy of the
   --  declaration tree of the parent with the help of the mapping returned by
   --  Inherit_Components, which will for example be used to validate record
   --  representation clauses given for the derived type. If the parent type
   --  is private and has discriminants, the ancestor discriminants used in the
   --  inheritance are that of the private declaration, whereas the ancestor
   --  discriminants present in the declaration tree of the parent are that of
   --  the full declaration; as a consequence, the remapping done during the
   --  copy will leave the references to the ancestor discriminants unchanged
   --  in the declaration tree and they need to be fixed up. If the derived
   --  type has a known discriminant part, then the remapping done during the
   --  copy will only create references to the stored discriminants and they
   --  need to be replaced with references to the non-stored discriminants.

   procedure Set_Fixed_Range
     (E   : Entity_Id;
      Loc : Source_Ptr;
      Lo  : Ureal;
      Hi  : Ureal);
   --  Build a range node with the given bounds and set it as the Scalar_Range
   --  of the given fixed-point type entity. Loc is the source location used
   --  for the constructed range. See body for further details.

   procedure Set_Scalar_Range_For_Subtype
     (Def_Id : Entity_Id;
      R      : Node_Id;
      Subt   : Entity_Id);
   --  This routine is used to set the scalar range field for a subtype given
   --  Def_Id, the entity for the subtype, and R, the range expression for the
   --  scalar range. Subt provides the parent subtype to be used to analyze,
   --  resolve, and check the given range.

   procedure Set_Default_SSO (T : Entity_Id);
   --  T is the entity for an array or record being declared. This procedure
   --  sets the flags SSO_Set_Low_By_Default/SSO_Set_High_By_Default according
   --  to the setting of Opt.Default_SSO.

   procedure Signed_Integer_Type_Declaration (T : Entity_Id; Def : Node_Id);
   --  Create a new signed integer entity, and apply the constraint to obtain
   --  the required first named subtype of this type.

   procedure Set_Stored_Constraint_From_Discriminant_Constraint
     (E : Entity_Id);
   --  E is some record type. This routine computes E's Stored_Constraint
   --  from its Discriminant_Constraint.

   procedure Diagnose_Interface (N : Node_Id;  E : Entity_Id);
   --  Check that an entity in a list of progenitors is an interface,
   --  emit error otherwise.

   -----------------------
   -- Access_Definition --
   -----------------------

   function Access_Definition
     (Related_Nod : Node_Id;
      N           : Node_Id) return Entity_Id
   is
      Anon_Type           : Entity_Id;
      Anon_Scope          : Entity_Id;
      Desig_Type          : Entity_Id;
      Enclosing_Prot_Type : Entity_Id := Empty;

   begin
      if Is_Entry (Current_Scope)
        and then Is_Task_Type (Etype (Scope (Current_Scope)))
      then
         Error_Msg_N ("task entries cannot have access parameters", N);
         return Empty;
      end if;

      --  Ada 2005: For an object declaration the corresponding anonymous
      --  type is declared in the current scope.

      --  If the access definition is the return type of another access to
      --  function, scope is the current one, because it is the one of the
      --  current type declaration, except for the pathological case below.

      if Nkind (Related_Nod) in
           N_Object_Declaration | N_Access_Function_Definition
      then
         Anon_Scope := Current_Scope;

         --  A pathological case: function returning access functions that
         --  return access functions, etc. Each anonymous access type created
         --  is in the enclosing scope of the outermost function.

         declare
            Par : Node_Id;

         begin
            Par := Related_Nod;
            while Nkind (Par) in
                    N_Access_Function_Definition | N_Access_Definition
            loop
               Par := Parent (Par);
            end loop;

            if Nkind (Par) = N_Function_Specification then
               Anon_Scope := Scope (Defining_Entity (Par));
            end if;
         end;

      --  For the anonymous function result case, retrieve the scope of the
      --  function specification's associated entity rather than using the
      --  current scope. The current scope will be the function itself if the
      --  formal part is currently being analyzed, but will be the parent scope
      --  in the case of a parameterless function, and we always want to use
      --  the function's parent scope. Finally, if the function is a child
      --  unit, we must traverse the tree to retrieve the proper entity.

      elsif Nkind (Related_Nod) = N_Function_Specification
        and then Nkind (Parent (N)) /= N_Parameter_Specification
      then
         --  If the current scope is a protected type, the anonymous access
         --  is associated with one of the protected operations, and must
         --  be available in the scope that encloses the protected declaration.
         --  Otherwise the type is in the scope enclosing the subprogram.

         --  If the function has formals, the return type of a subprogram
         --  declaration is analyzed in the scope of the subprogram (see
         --  Process_Formals) and thus the protected type, if present, is
         --  the scope of the current function scope.

         if Ekind (Current_Scope) = E_Protected_Type then
            Enclosing_Prot_Type := Current_Scope;

         elsif Ekind (Current_Scope) = E_Function
           and then Ekind (Scope (Current_Scope)) = E_Protected_Type
         then
            Enclosing_Prot_Type := Scope (Current_Scope);
         end if;

         if Present (Enclosing_Prot_Type) then
            Anon_Scope := Scope (Enclosing_Prot_Type);

         else
            Anon_Scope := Scope (Defining_Entity (Related_Nod));
         end if;

      --  For an access type definition, if the current scope is a child
      --  unit it is the scope of the type.

      elsif Is_Compilation_Unit (Current_Scope) then
         Anon_Scope := Current_Scope;

      --  For access formals, access components, and access discriminants, the
      --  scope is that of the enclosing declaration,

      else
         Anon_Scope := Scope (Current_Scope);
      end if;

      Anon_Type :=
        Create_Itype
          (E_Anonymous_Access_Type, Related_Nod, Scope_Id => Anon_Scope);

      if All_Present (N)
        and then Ada_Version >= Ada_2005
      then
         Error_Msg_N ("ALL not permitted for anonymous access types", N);
      end if;

      --  Ada 2005 (AI-254): In case of anonymous access to subprograms call
      --  the corresponding semantic routine

      if Present (Access_To_Subprogram_Definition (N)) then
         Access_Subprogram_Declaration
           (T_Name => Anon_Type,
            T_Def  => Access_To_Subprogram_Definition (N));

         if Ekind (Anon_Type) = E_Access_Protected_Subprogram_Type then
            Mutate_Ekind
              (Anon_Type, E_Anonymous_Access_Protected_Subprogram_Type);
         else
            Mutate_Ekind (Anon_Type, E_Anonymous_Access_Subprogram_Type);
         end if;

         Set_Can_Use_Internal_Rep
           (Anon_Type, not Always_Compatible_Rep_On_Target);

         --  If the anonymous access is associated with a protected operation,
         --  create a reference to it after the enclosing protected definition
         --  because the itype will be used in the subsequent bodies.

         --  If the anonymous access itself is protected, a full type
         --  declaratiton will be created for it, so that the equivalent
         --  record type can be constructed. For further details, see
         --  Replace_Anonymous_Access_To_Protected-Subprogram.

         if Ekind (Current_Scope) = E_Protected_Type
           and then not Protected_Present (Access_To_Subprogram_Definition (N))
         then
            Build_Itype_Reference (Anon_Type, Parent (Current_Scope));
         end if;

         return Anon_Type;
      end if;

      Find_Type (Subtype_Mark (N));
      Desig_Type := Entity (Subtype_Mark (N));

      Set_Directly_Designated_Type (Anon_Type, Desig_Type);
      Set_Etype (Anon_Type, Anon_Type);

      --  Make sure the anonymous access type has size and alignment fields
      --  set, as required by gigi. This is necessary in the case of the
      --  Task_Body_Procedure.

      if not Has_Private_Component (Desig_Type) then
         Layout_Type (Anon_Type);
      end if;

      --  Ada 2005 (AI-231): Ada 2005 semantics for anonymous access differs
      --  from Ada 95 semantics. In Ada 2005, anonymous access must specify if
      --  the null value is allowed. In Ada 95 the null value is never allowed.

      if Ada_Version >= Ada_2005 then
         Set_Can_Never_Be_Null (Anon_Type, Null_Exclusion_Present (N));
      else
         Set_Can_Never_Be_Null (Anon_Type, True);
      end if;

      --  The anonymous access type is as public as the discriminated type or
      --  subprogram that defines it. It is imported (for back-end purposes)
      --  if the designated type is.

      Set_Is_Public (Anon_Type, Is_Public (Scope (Anon_Type)));

      --  Ada 2005 (AI-231): Propagate the access-constant attribute

      Set_Is_Access_Constant (Anon_Type, Constant_Present (N));

      --  The context is either a subprogram declaration, object declaration,
      --  or an access discriminant, in a private or a full type declaration.
      --  In the case of a subprogram, if the designated type is incomplete,
      --  the operation will be a primitive operation of the full type, to be
      --  updated subsequently. If the type is imported through a limited_with
      --  clause, the subprogram is not a primitive operation of the type
      --  (which is declared elsewhere in some other scope).

      if Ekind (Desig_Type) = E_Incomplete_Type
        and then not From_Limited_With (Desig_Type)
        and then Is_Overloadable (Current_Scope)
      then
         Append_Elmt (Current_Scope, Private_Dependents (Desig_Type));
         Set_Has_Delayed_Freeze (Current_Scope);
      end if;

      --  If the designated type is limited and class-wide, the object might
      --  contain tasks, so we create a Master entity for the declaration. This
      --  must be done before expansion of the full declaration, because the
      --  declaration may include an expression that is an allocator, whose
      --  expansion needs the proper Master for the created tasks.

      if Expander_Active
        and then Nkind (Related_Nod) = N_Object_Declaration
      then
         if Is_Limited_Record (Desig_Type)
           and then Is_Class_Wide_Type (Desig_Type)
         then
            Build_Class_Wide_Master (Anon_Type);

         --  Similarly, if the type is an anonymous access that designates
         --  tasks, create a master entity for it in the current context.

         elsif Has_Task (Desig_Type)
           and then Comes_From_Source (Related_Nod)
         then
            Build_Master_Entity (Defining_Identifier (Related_Nod));
            Build_Master_Renaming (Anon_Type);
         end if;
      end if;

      --  For a private component of a protected type, it is imperative that
      --  the back-end elaborate the type immediately after the protected
      --  declaration, because this type will be used in the declarations
      --  created for the component within each protected body, so we must
      --  create an itype reference for it now.

      if Nkind (Parent (Related_Nod)) = N_Protected_Definition then
         Build_Itype_Reference (Anon_Type, Parent (Parent (Related_Nod)));

      --  Similarly, if the access definition is the return result of a
      --  function, create an itype reference for it because it will be used
      --  within the function body. For a regular function that is not a
      --  compilation unit, insert reference after the declaration. For a
      --  protected operation, insert it after the enclosing protected type
      --  declaration. In either case, do not create a reference for a type
      --  obtained through a limited_with clause, because this would introduce
      --  semantic dependencies.

      --  Similarly, do not create a reference if the designated type is a
      --  generic formal, because no use of it will reach the backend.

      elsif Nkind (Related_Nod) = N_Function_Specification
        and then not From_Limited_With (Desig_Type)
        and then not Is_Generic_Type (Desig_Type)
      then
         if Present (Enclosing_Prot_Type) then
            Build_Itype_Reference (Anon_Type, Parent (Enclosing_Prot_Type));

         elsif Is_List_Member (Parent (Related_Nod))
           and then Nkind (Parent (N)) /= N_Parameter_Specification
         then
            Build_Itype_Reference (Anon_Type, Parent (Related_Nod));
         end if;

      --  Finally, create an itype reference for an object declaration of an
      --  anonymous access type. This is strictly necessary only for deferred
      --  constants, but in any case will avoid out-of-scope problems in the
      --  back-end.

      elsif Nkind (Related_Nod) = N_Object_Declaration then
         Build_Itype_Reference (Anon_Type, Related_Nod);
      end if;

      return Anon_Type;
   end Access_Definition;

   -----------------------------------
   -- Access_Subprogram_Declaration --
   -----------------------------------

   procedure Access_Subprogram_Declaration
     (T_Name : Entity_Id;
      T_Def  : Node_Id)
   is
      procedure Check_For_Premature_Usage (Def : Node_Id);
      --  Check that type T_Name is not used, directly or recursively, as a
      --  parameter or a return type in Def. Def is either a subtype, an
      --  access_definition, or an access_to_subprogram_definition.

      -------------------------------
      -- Check_For_Premature_Usage --
      -------------------------------

      procedure Check_For_Premature_Usage (Def : Node_Id) is
         Param : Node_Id;

      begin
         --  Check for a subtype mark

         if Nkind (Def) in N_Has_Etype then
            if Etype (Def) = T_Name then
               Error_Msg_N
                 ("type& cannot be used before the end of its declaration",
                  Def);
            end if;

         --  If this is not a subtype, then this is an access_definition

         elsif Nkind (Def) = N_Access_Definition then
            if Present (Access_To_Subprogram_Definition (Def)) then
               Check_For_Premature_Usage
                 (Access_To_Subprogram_Definition (Def));
            else
               Check_For_Premature_Usage (Subtype_Mark (Def));
            end if;

         --  The only cases left are N_Access_Function_Definition and
         --  N_Access_Procedure_Definition.

         else
            if Present (Parameter_Specifications (Def)) then
               Param := First (Parameter_Specifications (Def));
               while Present (Param) loop
                  Check_For_Premature_Usage (Parameter_Type (Param));
                  Next (Param);
               end loop;
            end if;

            if Nkind (Def) = N_Access_Function_Definition then
               Check_For_Premature_Usage (Result_Definition (Def));
            end if;
         end if;
      end Check_For_Premature_Usage;

      --  Local variables

      Formals    : constant List_Id := Parameter_Specifications (T_Def);
      Formal     : Entity_Id;
      D_Ityp     : Node_Id;
      Desig_Type : constant Entity_Id :=
                     Create_Itype (E_Subprogram_Type, Parent (T_Def));

   --  Start of processing for Access_Subprogram_Declaration

   begin
      --  Associate the Itype node with the inner full-type declaration or
      --  subprogram spec or entry body. This is required to handle nested
      --  anonymous declarations. For example:

      --      procedure P
      --       (X : access procedure
      --                     (Y : access procedure
      --                                   (Z : access T)))

      D_Ityp := Associated_Node_For_Itype (Desig_Type);
      while Nkind (D_Ityp) not in N_Full_Type_Declaration
                                | N_Private_Type_Declaration
                                | N_Private_Extension_Declaration
                                | N_Procedure_Specification
                                | N_Function_Specification
                                | N_Entry_Body
                                | N_Object_Declaration
                                | N_Object_Renaming_Declaration
                                | N_Formal_Object_Declaration
                                | N_Formal_Type_Declaration
                                | N_Task_Type_Declaration
                                | N_Protected_Type_Declaration
      loop
         D_Ityp := Parent (D_Ityp);
         pragma Assert (D_Ityp /= Empty);
      end loop;

      Set_Associated_Node_For_Itype (Desig_Type, D_Ityp);

      if Nkind (D_Ityp) in N_Procedure_Specification | N_Function_Specification
      then
         Set_Scope (Desig_Type, Scope (Defining_Entity (D_Ityp)));

      elsif Nkind (D_Ityp) in N_Full_Type_Declaration
                            | N_Object_Declaration
                            | N_Object_Renaming_Declaration
                            | N_Formal_Type_Declaration
      then
         Set_Scope (Desig_Type, Scope (Defining_Identifier (D_Ityp)));
      end if;

      if Nkind (T_Def) = N_Access_Function_Definition then
         if Nkind (Result_Definition (T_Def)) = N_Access_Definition then
            declare
               Acc : constant Node_Id := Result_Definition (T_Def);

            begin
               if Present (Access_To_Subprogram_Definition (Acc))
                 and then
                   Protected_Present (Access_To_Subprogram_Definition (Acc))
               then
                  Set_Etype
                    (Desig_Type,
                       Replace_Anonymous_Access_To_Protected_Subprogram
                         (T_Def));

               else
                  Set_Etype
                    (Desig_Type,
                       Access_Definition (T_Def, Result_Definition (T_Def)));
               end if;
            end;

         else
            Analyze (Result_Definition (T_Def));

            declare
               Typ : constant Entity_Id := Entity (Result_Definition (T_Def));

            begin
               --  If a null exclusion is imposed on the result type, then
               --  create a null-excluding itype (an access subtype) and use
               --  it as the function's Etype.

               if Is_Access_Type (Typ)
                 and then Null_Exclusion_In_Return_Present (T_Def)
               then
                  Set_Etype (Desig_Type,
                    Create_Null_Excluding_Itype
                      (T           => Typ,
                       Related_Nod => T_Def,
                       Scope_Id    => Current_Scope));

               else
                  if From_Limited_With (Typ) then

                     --  AI05-151: Incomplete types are allowed in all basic
                     --  declarations, including access to subprograms.

                     if Ada_Version >= Ada_2012 then
                        null;

                     else
                        Error_Msg_NE
                         ("illegal use of incomplete type&",
                          Result_Definition (T_Def), Typ);
                     end if;

                  elsif Ekind (Current_Scope) = E_Package
                    and then In_Private_Part (Current_Scope)
                  then
                     if Ekind (Typ) = E_Incomplete_Type then
                        Append_Elmt (Desig_Type, Private_Dependents (Typ));

                     elsif Is_Class_Wide_Type (Typ)
                       and then Ekind (Etype (Typ)) = E_Incomplete_Type
                     then
                        Append_Elmt
                          (Desig_Type, Private_Dependents (Etype (Typ)));
                     end if;
                  end if;

                  Set_Etype (Desig_Type, Typ);
               end if;
            end;
         end if;

         if not Is_Type (Etype (Desig_Type)) then
            Error_Msg_N
              ("expect type in function specification",
               Result_Definition (T_Def));
         end if;

      else
         Set_Etype (Desig_Type, Standard_Void_Type);
      end if;

      if Present (Formals) then
         Push_Scope (Desig_Type);

         --  Some special tests here. These special tests can be removed
         --  if and when Itypes always have proper parent pointers to their
         --  declarations???

         --  Special test 1) Link defining_identifier of formals. Required by
         --  First_Formal to provide its functionality.

         declare
            F : Node_Id;

         begin
            F := First (Formals);

            while Present (F) loop
               if No (Parent (Defining_Identifier (F))) then
                  Set_Parent (Defining_Identifier (F), F);
               end if;

               Next (F);
            end loop;
         end;

         Process_Formals (Formals, Parent (T_Def));

         --  Special test 2) End_Scope requires that the parent pointer be set
         --  to something reasonable, but Itypes don't have parent pointers. So
         --  we set it and then unset it ???

         Set_Parent (Desig_Type, T_Name);
         End_Scope;
         Set_Parent (Desig_Type, Empty);
      end if;

      --  Check for premature usage of the type being defined

      Check_For_Premature_Usage (T_Def);

      --  The return type and/or any parameter type may be incomplete. Mark the
      --  subprogram_type as depending on the incomplete type, so that it can
      --  be updated when the full type declaration is seen. This only applies
      --  to incomplete types declared in some enclosing scope, not to limited
      --  views from other packages.

      --  Prior to Ada 2012, access to functions can only have in_parameters.

      if Present (Formals) then
         Formal := First_Formal (Desig_Type);
         while Present (Formal) loop
            if Ekind (Formal) /= E_In_Parameter
              and then Nkind (T_Def) = N_Access_Function_Definition
              and then Ada_Version < Ada_2012
            then
               Error_Msg_N ("functions can only have IN parameters", Formal);
            end if;

            if Ekind (Etype (Formal)) = E_Incomplete_Type
              and then In_Open_Scopes (Scope (Etype (Formal)))
            then
               Append_Elmt (Desig_Type, Private_Dependents (Etype (Formal)));
               Set_Has_Delayed_Freeze (Desig_Type);
            end if;

            Next_Formal (Formal);
         end loop;
      end if;

      --  Check whether an indirect call without actuals may be possible. This
      --  is used when resolving calls whose result is then indexed.

      May_Need_Actuals (Desig_Type);

      --  If the return type is incomplete, this is legal as long as the type
      --  is declared in the current scope and will be completed in it (rather
      --  than being part of limited view).

      if Ekind (Etype (Desig_Type)) = E_Incomplete_Type
        and then not Has_Delayed_Freeze (Desig_Type)
        and then In_Open_Scopes (Scope (Etype (Desig_Type)))
      then
         Append_Elmt (Desig_Type, Private_Dependents (Etype (Desig_Type)));
         Set_Has_Delayed_Freeze (Desig_Type);
      end if;

      Check_Delayed_Subprogram (Desig_Type);

      if Protected_Present (T_Def) then
         Mutate_Ekind (T_Name, E_Access_Protected_Subprogram_Type);
         Set_Convention (Desig_Type, Convention_Protected);
      else
         Mutate_Ekind (T_Name, E_Access_Subprogram_Type);
      end if;

      Set_Can_Use_Internal_Rep     (T_Name,
                                      not Always_Compatible_Rep_On_Target);
      Set_Etype                    (T_Name, T_Name);
      Reinit_Size_Align            (T_Name);
      Set_Directly_Designated_Type (T_Name, Desig_Type);

      --  If the access_to_subprogram is not declared at the library level,
      --  it can only point to subprograms that are at the same or deeper
      --  accessibility level. The corresponding subprogram type might
      --  require an activation record when compiling for C.

      Set_Needs_Activation_Record  (Desig_Type,
                                      not Is_Library_Level_Entity (T_Name));

      Generate_Reference_To_Formals (T_Name);

      --  Ada 2005 (AI-231): Propagate the null-excluding attribute

      Set_Can_Never_Be_Null (T_Name, Null_Exclusion_Present (T_Def));

      Check_Restriction (No_Access_Subprograms, T_Def);

      Create_Extra_Formals (Desig_Type);
   end Access_Subprogram_Declaration;

   ----------------------------
   -- Access_Type_Declaration --
   ----------------------------

   procedure Access_Type_Declaration (T : Entity_Id; Def : Node_Id) is

      procedure Setup_Access_Type (Desig_Typ : Entity_Id);
      --  After type declaration is analysed with T being an incomplete type,
      --  this routine will mutate the kind of T to the appropriate access type
      --  and set its directly designated type to Desig_Typ.

      -----------------------
      -- Setup_Access_Type --
      -----------------------

      procedure Setup_Access_Type (Desig_Typ : Entity_Id) is
      begin
         if All_Present (Def) or else Constant_Present (Def) then
            Mutate_Ekind (T, E_General_Access_Type);
         else
            Mutate_Ekind (T, E_Access_Type);
         end if;

         Set_Directly_Designated_Type (T, Desig_Typ);
      end Setup_Access_Type;

      --  Local variables

      P : constant Node_Id := Parent (Def);
      S : constant Node_Id := Subtype_Indication (Def);

      Full_Desig : Entity_Id;

   --  Start of processing for Access_Type_Declaration

   begin
      --  Check for permissible use of incomplete type

      if Nkind (S) /= N_Subtype_Indication then

         Analyze (S);

         if Nkind (S) in N_Has_Entity
           and then Present (Entity (S))
           and then Ekind (Root_Type (Entity (S))) = E_Incomplete_Type
         then
            Setup_Access_Type (Desig_Typ => Entity (S));

            --  If the designated type is a limited view, we cannot tell if
            --  the full view contains tasks, and there is no way to handle
            --  that full view in a client. We create a master entity for the
            --  scope, which will be used when a client determines that one
            --  is needed.

            if From_Limited_With (Entity (S))
              and then not Is_Class_Wide_Type (Entity (S))
            then
               Build_Master_Entity (T);
               Build_Master_Renaming (T);
            end if;

         else
            Setup_Access_Type (Desig_Typ => Process_Subtype (S, P, T, 'P'));
         end if;

         --  If the access definition is of the form: ACCESS NOT NULL ..
         --  the subtype indication must be of an access type. Create
         --  a null-excluding subtype of it.

         if Null_Excluding_Subtype (Def) then
            if not Is_Access_Type (Entity (S)) then
               Error_Msg_N ("null exclusion must apply to access type", Def);

            else
               declare
                  Loc  : constant Source_Ptr := Sloc (S);
                  Decl : Node_Id;
                  Nam  : constant Entity_Id := Make_Temporary (Loc, 'S');

               begin
                  Decl :=
                    Make_Subtype_Declaration (Loc,
                      Defining_Identifier => Nam,
                      Subtype_Indication  =>
                        New_Occurrence_Of (Entity (S), Loc));
                  Set_Null_Exclusion_Present (Decl);
                  Insert_Before (Parent (Def), Decl);
                  Analyze (Decl);
                  Set_Entity (S, Nam);
               end;
            end if;
         end if;

      else
         Setup_Access_Type (Desig_Typ => Process_Subtype (S, P, T, 'P'));
      end if;

      if not Error_Posted (T) then
         Full_Desig := Designated_Type (T);

         if Base_Type (Full_Desig) = T then
            Error_Msg_N ("access type cannot designate itself", S);

         --  In Ada 2005, the type may have a limited view through some unit in
         --  its own context, allowing the following circularity that cannot be
         --  detected earlier.

         elsif Is_Class_Wide_Type (Full_Desig) and then Etype (Full_Desig) = T
         then
            Error_Msg_N
              ("access type cannot designate its own class-wide type", S);

            --  Clean up indication of tagged status to prevent cascaded errors

            Set_Is_Tagged_Type (T, False);
         end if;

         Set_Etype (T, T);

         --  For SPARK, check that the designated type is compatible with
         --  respect to volatility with the access type.

         if SPARK_Mode /= Off
            and then Comes_From_Source (T)
         then
            --  ??? UNIMPLEMENTED
            --  In the case where the designated type is incomplete at this
            --  point, performing this check here is harmless but the check
            --  will need to be repeated when the designated type is complete.

            --  The preceding call to Comes_From_Source is needed because the
            --  FE sometimes introduces implicitly declared access types. See,
            --  for example, the expansion of nested_po.ads in OA28-015.

            Check_Volatility_Compatibility
              (Full_Desig, T, "designated type", "access type",
               Srcpos_Bearer => T);
         end if;
      end if;

      --  If the type has appeared already in a with_type clause, it is frozen
      --  and the pointer size is already set. Else, initialize.

      if not From_Limited_With (T) then
         Reinit_Size_Align (T);
      end if;

      --  Note that Has_Task is always false, since the access type itself
      --  is not a task type. See Einfo for more description on this point.
      --  Exactly the same consideration applies to Has_Controlled_Component
      --  and to Has_Protected.

      Set_Has_Task                 (T, False);
      Set_Has_Protected            (T, False);
      Set_Has_Timing_Event         (T, False);
      Set_Has_Controlled_Component (T, False);

      --  Initialize field Finalization_Master explicitly to Empty, to avoid
      --  problems where an incomplete view of this entity has been previously
      --  established by a limited with and an overlaid version of this field
      --  (Stored_Constraint) was initialized for the incomplete view.

      --  This reset is performed in most cases except where the access type
      --  has been created for the purposes of allocating or deallocating a
      --  build-in-place object. Such access types have explicitly set pools
      --  and finalization masters.

      if No (Associated_Storage_Pool (T)) then
         Set_Finalization_Master (T, Empty);
      end if;

      --  Ada 2005 (AI-231): Propagate the null-excluding and access-constant
      --  attributes

      Set_Can_Never_Be_Null  (T, Null_Exclusion_Present (Def));
      Set_Is_Access_Constant (T, Constant_Present (Def));
   end Access_Type_Declaration;

   ----------------------------------
   -- Add_Interface_Tag_Components --
   ----------------------------------

   procedure Add_Interface_Tag_Components (N : Node_Id; Typ : Entity_Id) is
      Loc      : constant Source_Ptr := Sloc (N);
      L        : List_Id;
      Last_Tag : Node_Id;

      procedure Add_Tag (Iface : Entity_Id);
      --  Add tag for one of the progenitor interfaces

      -------------
      -- Add_Tag --
      -------------

      procedure Add_Tag (Iface : Entity_Id) is
         Decl   : Node_Id;
         Def    : Node_Id;
         Tag    : Entity_Id;
         Offset : Entity_Id;

      begin
         pragma Assert (Is_Tagged_Type (Iface) and then Is_Interface (Iface));

         --  This is a reasonable place to propagate predicates

         if Has_Predicates (Iface) then
            Set_Has_Predicates (Typ);
         end if;

         Def :=
           Make_Component_Definition (Loc,
             Aliased_Present    => True,
             Subtype_Indication =>
               New_Occurrence_Of (RTE (RE_Interface_Tag), Loc));

         Tag := Make_Temporary (Loc, 'V');

         Decl :=
           Make_Component_Declaration (Loc,
             Defining_Identifier  => Tag,
             Component_Definition => Def);

         Analyze_Component_Declaration (Decl);

         Set_Analyzed (Decl);
         Mutate_Ekind            (Tag, E_Component);
         Set_Is_Tag              (Tag);
         Set_Is_Aliased          (Tag);
         Set_Is_Independent      (Tag);
         Set_Related_Type        (Tag, Iface);
         Reinit_Component_Location (Tag);

         pragma Assert (Is_Frozen (Iface));

         Set_DT_Entry_Count    (Tag,
           DT_Entry_Count (First_Entity (Iface)));

         if No (Last_Tag) then
            Prepend (Decl, L);
         else
            Insert_After (Last_Tag, Decl);
         end if;

         Last_Tag := Decl;

         --  If the ancestor has discriminants we need to give special support
         --  to store the offset_to_top value of the secondary dispatch tables.
         --  For this purpose we add a supplementary component just after the
         --  field that contains the tag associated with each secondary DT.

         if Typ /= Etype (Typ) and then Has_Discriminants (Etype (Typ)) then
            Def :=
              Make_Component_Definition (Loc,
                Subtype_Indication =>
                  New_Occurrence_Of (RTE (RE_Storage_Offset), Loc));

            Offset := Make_Temporary (Loc, 'V');

            Decl :=
              Make_Component_Declaration (Loc,
                Defining_Identifier  => Offset,
                Component_Definition => Def);

            Analyze_Component_Declaration (Decl);

            Set_Analyzed (Decl);
            Mutate_Ekind            (Offset, E_Component);
            Set_Is_Aliased          (Offset);
            Set_Is_Independent      (Offset);
            Set_Related_Type        (Offset, Iface);
            Reinit_Component_Location (Offset);
            Insert_After (Last_Tag, Decl);
            Last_Tag := Decl;
         end if;
      end Add_Tag;

      --  Local variables

      Elmt : Elmt_Id;
      Ext  : Node_Id;
      Comp : Node_Id;

   --  Start of processing for Add_Interface_Tag_Components

   begin
      if not RTE_Available (RE_Interface_Tag) then
         Error_Msg_N
           ("(Ada 2005) interface types not supported by this run-time!", N);
         return;
      end if;

      if Ekind (Typ) /= E_Record_Type
        or else (Is_Concurrent_Record_Type (Typ)
                  and then Is_Empty_List (Abstract_Interface_List (Typ)))
        or else (not Is_Concurrent_Record_Type (Typ)
                  and then No (Interfaces (Typ))
                  and then Is_Empty_Elmt_List (Interfaces (Typ)))
      then
         return;
      end if;

      --  Find the current last tag

      if Nkind (Type_Definition (N)) = N_Derived_Type_Definition then
         Ext := Record_Extension_Part (Type_Definition (N));
      else
         pragma Assert (Nkind (Type_Definition (N)) = N_Record_Definition);
         Ext := Type_Definition (N);
      end if;

      Last_Tag := Empty;

      if not (Present (Component_List (Ext))) then
         Set_Null_Present (Ext, False);
         L := New_List;
         Set_Component_List (Ext,
           Make_Component_List (Loc,
             Component_Items => L,
             Null_Present => False));
      else
         if Nkind (Type_Definition (N)) = N_Derived_Type_Definition then
            L := Component_Items
                   (Component_List
                     (Record_Extension_Part
                       (Type_Definition (N))));
         else
            L := Component_Items
                   (Component_List
                     (Type_Definition (N)));
         end if;

         --  Find the last tag component

         Comp := First (L);
         while Present (Comp) loop
            if Nkind (Comp) = N_Component_Declaration
              and then Is_Tag (Defining_Identifier (Comp))
            then
               Last_Tag := Comp;
            end if;

            Next (Comp);
         end loop;
      end if;

      --  At this point L references the list of components and Last_Tag
      --  references the current last tag (if any). Now we add the tag
      --  corresponding with all the interfaces that are not implemented
      --  by the parent.

      if Present (Interfaces (Typ)) then
         Elmt := First_Elmt (Interfaces (Typ));
         while Present (Elmt) loop
            Add_Tag (Node (Elmt));
            Next_Elmt (Elmt);
         end loop;
      end if;
   end Add_Interface_Tag_Components;

   -------------------------------------
   -- Add_Internal_Interface_Entities --
   -------------------------------------

   procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id) is
      Elmt          : Elmt_Id;
      Iface         : Entity_Id;
      Iface_Elmt    : Elmt_Id;
      Iface_Prim    : Entity_Id;
      Ifaces_List   : Elist_Id;
      New_Subp      : Entity_Id := Empty;
      Prim          : Entity_Id;
      Restore_Scope : Boolean := False;

   begin
      pragma Assert (Ada_Version >= Ada_2005
        and then Is_Record_Type (Tagged_Type)
        and then Is_Tagged_Type (Tagged_Type)
        and then Has_Interfaces (Tagged_Type)
        and then not Is_Interface (Tagged_Type));

      --  Ensure that the internal entities are added to the scope of the type

      if Scope (Tagged_Type) /= Current_Scope then
         Push_Scope (Scope (Tagged_Type));
         Restore_Scope := True;
      end if;

      Collect_Interfaces (Tagged_Type, Ifaces_List);

      Iface_Elmt := First_Elmt (Ifaces_List);
      while Present (Iface_Elmt) loop
         Iface := Node (Iface_Elmt);

         --  Originally we excluded here from this processing interfaces that
         --  are parents of Tagged_Type because their primitives are located
         --  in the primary dispatch table (and hence no auxiliary internal
         --  entities are required to handle secondary dispatch tables in such
         --  case). However, these auxiliary entities are also required to
         --  handle derivations of interfaces in formals of generics (see
         --  Derive_Subprograms).

         Elmt := First_Elmt (Primitive_Operations (Iface));
         while Present (Elmt) loop
            Iface_Prim := Node (Elmt);

            if not Is_Predefined_Dispatching_Operation (Iface_Prim) then
               Prim :=
                 Find_Primitive_Covering_Interface
                   (Tagged_Type => Tagged_Type,
                    Iface_Prim  => Iface_Prim);

               if No (Prim) and then Serious_Errors_Detected > 0 then
                  goto Continue;
               end if;

               pragma Assert (Present (Prim));

               --  Ada 2012 (AI05-0197): If the name of the covering primitive
               --  differs from the name of the interface primitive then it is
               --  a private primitive inherited from a parent type. In such
               --  case, given that Tagged_Type covers the interface, the
               --  inherited private primitive becomes visible. For such
               --  purpose we add a new entity that renames the inherited
               --  private primitive.

               if Chars (Prim) /= Chars (Iface_Prim) then
                  pragma Assert (Has_Suffix (Prim, 'P'));
                  Derive_Subprogram
                    (New_Subp     => New_Subp,
                     Parent_Subp  => Iface_Prim,
                     Derived_Type => Tagged_Type,
                     Parent_Type  => Iface);
                  Set_Alias (New_Subp, Prim);
                  Set_Is_Abstract_Subprogram
                    (New_Subp, Is_Abstract_Subprogram (Prim));
               end if;

               Derive_Subprogram
                 (New_Subp     => New_Subp,
                  Parent_Subp  => Iface_Prim,
                  Derived_Type => Tagged_Type,
                  Parent_Type  => Iface);

               declare
                  Anc : Entity_Id;
               begin
                  if Is_Inherited_Operation (Prim)
                    and then Present (Alias (Prim))
                  then
                     Anc := Alias (Prim);
                  else
                     Anc := Overridden_Operation (Prim);
                  end if;

                  --  Apply legality checks in RM 6.1.1 (10-13) concerning
                  --  nonconforming preconditions in both an ancestor and
                  --  a progenitor operation.

                  --  If the operation is a primitive wrapper it is an explicit
                  --  (overriding) operqtion and all is fine.

                  if Present (Anc)
                    and then Has_Non_Trivial_Precondition (Anc)
                    and then Has_Non_Trivial_Precondition (Iface_Prim)
                  then
                     if Is_Abstract_Subprogram (Prim)
                       or else
                         (Ekind (Prim) = E_Procedure
                           and then Nkind (Parent (Prim)) =
                                      N_Procedure_Specification
                           and then Null_Present (Parent (Prim)))
                       or else Is_Primitive_Wrapper (Prim)
                     then
                        null;

                     --  The operation is inherited and must be overridden

                     elsif not Comes_From_Source (Prim) then
                        Error_Msg_NE
                          ("&inherits non-conforming preconditions and must "
                           & "be overridden (RM 6.1.1 (10-16))",
                           Parent (Tagged_Type), Prim);
                     end if;
                  end if;
               end;

               --  Ada 2005 (AI-251): Decorate internal entity Iface_Subp
               --  associated with interface types. These entities are
               --  only registered in the list of primitives of its
               --  corresponding tagged type because they are only used
               --  to fill the contents of the secondary dispatch tables.
               --  Therefore they are removed from the homonym chains.

               Set_Is_Hidden (New_Subp);
               Set_Is_Internal (New_Subp);
               Set_Alias (New_Subp, Prim);
               Set_Is_Abstract_Subprogram
                 (New_Subp, Is_Abstract_Subprogram (Prim));
               Set_Interface_Alias (New_Subp, Iface_Prim);

               --  If the returned type is an interface then propagate it to
               --  the returned type. Needed by the thunk to generate the code
               --  which displaces "this" to reference the corresponding
               --  secondary dispatch table in the returned object.

               if Is_Interface (Etype (Iface_Prim)) then
                  Set_Etype (New_Subp, Etype (Iface_Prim));
               end if;

               --  Internal entities associated with interface types are only
               --  registered in the list of primitives of the tagged type.
               --  They are only used to fill the contents of the secondary
               --  dispatch tables. Therefore they are not needed in the
               --  homonym chains.

               Remove_Homonym (New_Subp);

               --  Hidden entities associated with interfaces must have set
               --  the Has_Delay_Freeze attribute to ensure that, in case
               --  of locally defined tagged types (or compiling with static
               --  dispatch tables generation disabled) the corresponding
               --  entry of the secondary dispatch table is filled when such
               --  an entity is frozen.

               Set_Has_Delayed_Freeze (New_Subp);
            end if;

            <<Continue>>
            Next_Elmt (Elmt);
         end loop;

         Next_Elmt (Iface_Elmt);
      end loop;

      if Restore_Scope then
         Pop_Scope;
      end if;
   end Add_Internal_Interface_Entities;

   -----------------------------------
   -- Analyze_Component_Declaration --
   -----------------------------------

   procedure Analyze_Component_Declaration (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (Component_Definition (N));
      Id  : constant Entity_Id  := Defining_Identifier (N);
      E   : constant Node_Id    := Expression (N);
      Typ : constant Node_Id    :=
              Subtype_Indication (Component_Definition (N));
      T   : Entity_Id;
      P   : Entity_Id;

      function Contains_POC (Constr : Node_Id) return Boolean;
      --  Determines whether a constraint uses the discriminant of a record
      --  type thus becoming a per-object constraint (POC).

      function Is_Known_Limited (Typ : Entity_Id) return Boolean;
      --  Typ is the type of the current component, check whether this type is
      --  a limited type. Used to validate declaration against that of
      --  enclosing record.

      ------------------
      -- Contains_POC --
      ------------------

      function Contains_POC (Constr : Node_Id) return Boolean is
      begin
         --  Prevent cascaded errors

         if Error_Posted (Constr) then
            return False;
         end if;

         case Nkind (Constr) is
            when N_Attribute_Reference =>
               return Attribute_Name (Constr) = Name_Access
                 and then Prefix (Constr) = Scope (Entity (Prefix (Constr)));

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

            when N_Identifier =>
               return Denotes_Discriminant (Constr);

            when N_Index_Or_Discriminant_Constraint =>
               declare
                  IDC : Node_Id;

               begin
                  IDC := First (Constraints (Constr));
                  while Present (IDC) loop

                     --  One per-object constraint is sufficient

                     if Contains_POC (IDC) then
                        return True;
                     end if;

                     Next (IDC);
                  end loop;

                  return False;
               end;

            when N_Range =>
               return Denotes_Discriminant (Low_Bound (Constr))
                        or else
                      Denotes_Discriminant (High_Bound (Constr));

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

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

      ----------------------
      -- Is_Known_Limited --
      ----------------------

      function Is_Known_Limited (Typ : Entity_Id) return Boolean is
         P : constant Entity_Id := Etype (Typ);
         R : constant Entity_Id := Root_Type (Typ);

      begin
         if Is_Limited_Record (Typ) then
            return True;

         --  If the root type is limited (and not a limited interface) so is
         --  the current type.

         elsif Is_Limited_Record (R)
           and then (not Is_Interface (R) or else not Is_Limited_Interface (R))
         then
            return True;

         --  Else the type may have a limited interface progenitor, but a
         --  limited record parent that is not an interface.

         elsif R /= P
           and then Is_Limited_Record (P)
           and then not Is_Interface (P)
         then
            return True;

         else
            return False;
         end if;
      end Is_Known_Limited;

   --  Start of processing for Analyze_Component_Declaration

   begin
      Generate_Definition (Id);
      Enter_Name (Id);

      if Present (Typ) then
         T := Find_Type_Of_Object
                (Subtype_Indication (Component_Definition (N)), N);

      --  Ada 2005 (AI-230): Access Definition case

      else
         pragma Assert (Present
                          (Access_Definition (Component_Definition (N))));

         T := Access_Definition
                (Related_Nod => N,
                 N => Access_Definition (Component_Definition (N)));
         Set_Is_Local_Anonymous_Access (T);

         --  Ada 2005 (AI-254)

         if Present (Access_To_Subprogram_Definition
                      (Access_Definition (Component_Definition (N))))
           and then Protected_Present (Access_To_Subprogram_Definition
                                        (Access_Definition
                                          (Component_Definition (N))))
         then
            T := Replace_Anonymous_Access_To_Protected_Subprogram (N);
         end if;
      end if;

      --  If the subtype is a constrained subtype of the enclosing record,
      --  (which must have a partial view) the back-end does not properly
      --  handle the recursion. Rewrite the component declaration with an
      --  explicit subtype indication, which is acceptable to Gigi. We can copy
      --  the tree directly because side effects have already been removed from
      --  discriminant constraints.

      if Ekind (T) = E_Access_Subtype
        and then Is_Entity_Name (Subtype_Indication (Component_Definition (N)))
        and then Comes_From_Source (T)
        and then Nkind (Parent (T)) = N_Subtype_Declaration
        and then Etype (Directly_Designated_Type (T)) = Current_Scope
      then
         Rewrite
           (Subtype_Indication (Component_Definition (N)),
             New_Copy_Tree (Subtype_Indication (Parent (T))));
         T := Find_Type_Of_Object
                 (Subtype_Indication (Component_Definition (N)), N);
      end if;

      --  If the component declaration includes a default expression, then we
      --  check that the component is not of a limited type (RM 3.7(5)),
      --  and do the special preanalysis of the expression (see section on
      --  "Handling of Default and Per-Object Expressions" in the spec of
      --  package Sem).

      if Present (E) then
         Preanalyze_Default_Expression (E, T);
         Check_Initialization (T, E);

         if Ada_Version >= Ada_2005
           and then Ekind (T) = E_Anonymous_Access_Type
           and then Etype (E) /= Any_Type
         then
            --  Check RM 3.9.2(9): "if the expected type for an expression is
            --  an anonymous access-to-specific tagged type, then the object
            --  designated by the expression shall not be dynamically tagged
            --  unless it is a controlling operand in a call on a dispatching
            --  operation"

            if Is_Tagged_Type (Directly_Designated_Type (T))
              and then
                Ekind (Directly_Designated_Type (T)) /= E_Class_Wide_Type
              and then
                Ekind (Directly_Designated_Type (Etype (E))) =
                  E_Class_Wide_Type
            then
               Error_Msg_N
                 ("access to specific tagged type required (RM 3.9.2(9))", E);
            end if;

            --  (Ada 2005: AI-230): Accessibility check for anonymous
            --  components

            if Type_Access_Level (Etype (E)) >
               Deepest_Type_Access_Level (T)
            then
               Error_Msg_N
                 ("expression has deeper access level than component " &
                  "(RM 3.10.2 (12.2))", E);
            end if;

            --  The initialization expression is a reference to an access
            --  discriminant. The type of the discriminant is always deeper
            --  than any access type.

            if Ekind (Etype (E)) = E_Anonymous_Access_Type
              and then Is_Entity_Name (E)
              and then Ekind (Entity (E)) = E_In_Parameter
              and then Present (Discriminal_Link (Entity (E)))
            then
               Error_Msg_N
                 ("discriminant has deeper accessibility level than target",
                  E);
            end if;
         end if;
      end if;

      --  The parent type may be a private view with unknown discriminants,
      --  and thus unconstrained. Regular components must be constrained.

      if not Is_Definite_Subtype (T)
        and then Chars (Id) /= Name_uParent
      then
         if Is_Class_Wide_Type (T) then
            Error_Msg_N
               ("class-wide subtype with unknown discriminants" &
                 " in component declaration",
                 Subtype_Indication (Component_Definition (N)));
         else
            Error_Msg_N
              ("unconstrained subtype in component declaration",
               Subtype_Indication (Component_Definition (N)));
         end if;

      --  Components cannot be abstract, except for the special case of
      --  the _Parent field (case of extending an abstract tagged type)

      elsif Is_Abstract_Type (T) and then Chars (Id) /= Name_uParent then
         Error_Msg_N ("type of a component cannot be abstract", N);
      end if;

      Set_Etype (Id, T);

      if Aliased_Present (Component_Definition (N)) then
         Set_Is_Aliased (Id);

         --  AI12-001: All aliased objects are considered to be specified as
         --  independently addressable (RM C.6(8.1/4)).

         Set_Is_Independent (Id);
      end if;

      --  The component declaration may have a per-object constraint, set
      --  the appropriate flag in the defining identifier of the subtype.

      if Present (Subtype_Indication (Component_Definition (N))) then
         declare
            Sindic : constant Node_Id :=
                       Subtype_Indication (Component_Definition (N));
         begin
            if Nkind (Sindic) = N_Subtype_Indication
              and then Present (Constraint (Sindic))
              and then Contains_POC (Constraint (Sindic))
            then
               Set_Has_Per_Object_Constraint (Id);
            end if;
         end;
      end if;

      --  Ada 2005 (AI-231): Propagate the null-excluding attribute and carry
      --  out some static checks.

      if Ada_Version >= Ada_2005 and then Can_Never_Be_Null (T) then
         Null_Exclusion_Static_Checks (N);
      end if;

      --  If this component is private (or depends on a private type), flag the
      --  record type to indicate that some operations are not available.

      P := Private_Component (T);

      if Present (P) then

         --  Check for circular definitions

         if P = Any_Type then
            Set_Etype (Id, Any_Type);

         --  There is a gap in the visibility of operations only if the
         --  component type is not defined in the scope of the record type.

         elsif Scope (P) = Scope (Current_Scope) then
            null;

         elsif Is_Limited_Type (P) then
            Set_Is_Limited_Composite (Current_Scope);

         else
            Set_Is_Private_Composite (Current_Scope);
         end if;
      end if;

      if P /= Any_Type
        and then Is_Limited_Type (T)
        and then Chars (Id) /= Name_uParent
        and then Is_Tagged_Type (Current_Scope)
      then
         if Is_Derived_Type (Current_Scope)
           and then not Is_Known_Limited (Current_Scope)
         then
            Error_Msg_N
              ("extension of nonlimited type cannot have limited components",
               N);

            if Is_Interface (Root_Type (Current_Scope)) then
               Error_Msg_N
                 ("\limitedness is not inherited from limited interface", N);
               Error_Msg_N ("\add LIMITED to type indication", N);
            end if;

            Explain_Limited_Type (T, N);
            Set_Etype (Id, Any_Type);
            Set_Is_Limited_Composite (Current_Scope, False);

         elsif not Is_Derived_Type (Current_Scope)
           and then not Is_Limited_Record (Current_Scope)
           and then not Is_Concurrent_Type (Current_Scope)
         then
            Error_Msg_N
              ("nonlimited tagged type cannot have limited components", N);
            Explain_Limited_Type (T, N);
            Set_Etype (Id, Any_Type);
            Set_Is_Limited_Composite (Current_Scope, False);
         end if;
      end if;

      --  If the component is an unconstrained task or protected type with
      --  discriminants, the component and the enclosing record are limited
      --  and the component is constrained by its default values. Compute
      --  its actual subtype, else it may be allocated the maximum size by
      --  the backend, and possibly overflow.

      if Is_Concurrent_Type (T)
        and then not Is_Constrained (T)
        and then Has_Discriminants (T)
        and then not Has_Discriminants (Current_Scope)
      then
         declare
            Act_T : constant Entity_Id := Build_Default_Subtype (T, N);

         begin
            Set_Etype (Id, Act_T);

            --  Rewrite component definition to use the constrained subtype

            Rewrite (Component_Definition (N),
              Make_Component_Definition (Loc,
                Subtype_Indication => New_Occurrence_Of (Act_T, Loc)));
         end;
      end if;

      Set_Original_Record_Component (Id, Id);

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

      Analyze_Dimension (N);
   end Analyze_Component_Declaration;

   --------------------------
   -- Analyze_Declarations --
   --------------------------

   procedure Analyze_Declarations (L : List_Id) is
      Decl : Node_Id;

      procedure Adjust_Decl;
      --  Adjust Decl not to include implicit label declarations, since these
      --  have strange Sloc values that result in elaboration check problems.
      --  (They have the sloc of the label as found in the source, and that
      --  is ahead of the current declarative part).

      procedure Build_Assertion_Bodies (Decls : List_Id; Context : Node_Id);
      --  Create the subprogram bodies which verify the run-time semantics of
      --  the pragmas listed below for each elibigle type found in declarative
      --  list Decls. The pragmas are:
      --
      --    Default_Initial_Condition
      --    Invariant
      --    Type_Invariant
      --
      --  Context denotes the owner of the declarative list.

      procedure Check_Entry_Contracts;
      --  Perform a preanalysis of the pre- and postconditions of an entry
      --  declaration. This must be done before full resolution and creation
      --  of the parameter block, etc. to catch illegal uses within the
      --  contract expression. Full analysis of the expression is done when
      --  the contract is processed.

      function Contains_Lib_Incomplete_Type (Pkg : Entity_Id) return Boolean;
      --  Check if a nested package has entities within it that rely on library
      --  level private types where the full view has not been completed for
      --  the purposes of checking if it is acceptable to freeze an expression
      --  function at the point of declaration.

      procedure Handle_Late_Controlled_Primitive (Body_Decl : Node_Id);
      --  Determine whether Body_Decl denotes the body of a late controlled
      --  primitive (either Initialize, Adjust or Finalize). If this is the
      --  case, add a proper spec if the body lacks one. The spec is inserted
      --  before Body_Decl and immediately analyzed.

      procedure Remove_Partial_Visible_Refinements (Spec_Id : Entity_Id);
      --  Spec_Id is the entity of a package that may define abstract states,
      --  and in the case of a child unit, whose ancestors may define abstract
      --  states. If the states have partial visible refinement, remove the
      --  partial visibility of each constituent at the end of the package
      --  spec and body declarations.

      procedure Remove_Visible_Refinements (Spec_Id : Entity_Id);
      --  Spec_Id is the entity of a package that may define abstract states.
      --  If the states have visible refinement, remove the visibility of each
      --  constituent at the end of the package body declaration.

      procedure Resolve_Aspects;
      --  Utility to resolve the expressions of aspects at the end of a list of
      --  declarations, or before a declaration that freezes previous entities,
      --  such as in a subprogram body.

      -----------------
      -- Adjust_Decl --
      -----------------

      procedure Adjust_Decl is
      begin
         while Present (Prev (Decl))
           and then Nkind (Decl) = N_Implicit_Label_Declaration
         loop
            Prev (Decl);
         end loop;
      end Adjust_Decl;

      ----------------------------
      -- Build_Assertion_Bodies --
      ----------------------------

      procedure Build_Assertion_Bodies (Decls : List_Id; Context : Node_Id) is
         procedure Build_Assertion_Bodies_For_Type (Typ : Entity_Id);
         --  Create the subprogram bodies which verify the run-time semantics
         --  of the pragmas listed below for type Typ. The pragmas are:
         --
         --    Default_Initial_Condition
         --    Invariant
         --    Type_Invariant

         -------------------------------------
         -- Build_Assertion_Bodies_For_Type --
         -------------------------------------

         procedure Build_Assertion_Bodies_For_Type (Typ : Entity_Id) is
         begin
            if Nkind (Context) = N_Package_Specification then

               --  Preanalyze and resolve the class-wide invariants of an
               --  interface at the end of whichever declarative part has the
               --  interface type. Note that an interface may be declared in
               --  any non-package declarative part, but reaching the end of
               --  such a declarative part will always freeze the type and
               --  generate the invariant procedure (see Freeze_Type).

               if Is_Interface (Typ) then

                  --  Interfaces are treated as the partial view of a private
                  --  type, in order to achieve uniformity with the general
                  --  case. As a result, an interface receives only a "partial"
                  --  invariant procedure, which is never called.

                  if Has_Own_Invariants (Typ) then
                     Build_Invariant_Procedure_Body
                       (Typ               => Typ,
                        Partial_Invariant => True);
                  end if;

               elsif Decls = Visible_Declarations (Context) then
                  --  Preanalyze and resolve the invariants of a private type
                  --  at the end of the visible declarations to catch potential
                  --  errors. Inherited class-wide invariants are not included
                  --  because they have already been resolved.

                  if Ekind (Typ) in E_Limited_Private_Type
                                  | E_Private_Type
                                  | E_Record_Type_With_Private
                    and then Has_Own_Invariants (Typ)
                  then
                     Build_Invariant_Procedure_Body
                       (Typ               => Typ,
                        Partial_Invariant => True);
                  end if;

                  --  Preanalyze and resolve the Default_Initial_Condition
                  --  assertion expression at the end of the declarations to
                  --  catch any errors.

                  if Ekind (Typ) in E_Limited_Private_Type
                                  | E_Private_Type
                                  | E_Record_Type_With_Private
                     and then Has_Own_DIC (Typ)
                  then
                     Build_DIC_Procedure_Body
                       (Typ         => Typ,
                        Partial_DIC => True);
                  end if;

               elsif Decls = Private_Declarations (Context) then

                  --  Preanalyze and resolve the invariants of a private type's
                  --  full view at the end of the private declarations to catch
                  --  potential errors.

                  if (not Is_Private_Type (Typ)
                       or else Present (Underlying_Full_View (Typ)))
                    and then Has_Private_Declaration (Typ)
                    and then Has_Invariants (Typ)
                  then
                     Build_Invariant_Procedure_Body (Typ);
                  end if;

                  if (not Is_Private_Type (Typ)
                       or else Present (Underlying_Full_View (Typ)))
                    and then Has_Private_Declaration (Typ)
                    and then Has_DIC (Typ)
                  then
                     Build_DIC_Procedure_Body (Typ);
                  end if;
               end if;
            end if;
         end Build_Assertion_Bodies_For_Type;

         --  Local variables

         Decl    : Node_Id;
         Decl_Id : Entity_Id;

      --  Start of processing for Build_Assertion_Bodies

      begin
         Decl := First (Decls);
         while Present (Decl) loop
            if Is_Declaration (Decl) then
               Decl_Id := Defining_Entity (Decl);

               if Is_Type (Decl_Id) then
                  Build_Assertion_Bodies_For_Type (Decl_Id);
               end if;
            end if;

            Next (Decl);
         end loop;
      end Build_Assertion_Bodies;

      ---------------------------
      -- Check_Entry_Contracts --
      ---------------------------

      procedure Check_Entry_Contracts is
         ASN : Node_Id;
         Ent : Entity_Id;
         Exp : Node_Id;

      begin
         Ent := First_Entity (Current_Scope);
         while Present (Ent) loop

            --  This only concerns entries with pre/postconditions

            if Ekind (Ent) = E_Entry
              and then Present (Contract (Ent))
              and then Present (Pre_Post_Conditions (Contract (Ent)))
            then
               ASN := Pre_Post_Conditions (Contract (Ent));
               Push_Scope (Ent);
               Install_Formals (Ent);

               --  Pre/postconditions are rewritten as Check pragmas. Analysis
               --  is performed on a copy of the pragma expression, to prevent
               --  modifying the original expression.

               while Present (ASN) loop
                  if Nkind (ASN) = N_Pragma then
                     Exp :=
                       New_Copy_Tree
                         (Expression
                           (First (Pragma_Argument_Associations (ASN))));
                     Set_Parent (Exp, ASN);

                     Preanalyze_Assert_Expression (Exp, Standard_Boolean);
                  end if;

                  ASN := Next_Pragma (ASN);
               end loop;

               End_Scope;
            end if;

            Next_Entity (Ent);
         end loop;
      end Check_Entry_Contracts;

      ----------------------------------
      -- Contains_Lib_Incomplete_Type --
      ----------------------------------

      function Contains_Lib_Incomplete_Type (Pkg : Entity_Id) return Boolean is
         Curr : Entity_Id;

      begin
         --  Avoid looking through scopes that do not meet the precondition of
         --  Pkg not being within a library unit spec.

         if not Is_Compilation_Unit (Pkg)
           and then not Is_Generic_Instance (Pkg)
           and then not In_Package_Body (Enclosing_Lib_Unit_Entity (Pkg))
         then
            --  Loop through all entities in the current scope to identify
            --  an entity that depends on a private type.

            Curr := First_Entity (Pkg);
            loop
               if Nkind (Curr) in N_Entity
                 and then Depends_On_Private (Curr)
               then
                  return True;
               end if;

               exit when Last_Entity (Current_Scope) = Curr;
               Next_Entity (Curr);
            end loop;
         end if;

         return False;
      end Contains_Lib_Incomplete_Type;

      --------------------------------------
      -- Handle_Late_Controlled_Primitive --
      --------------------------------------

      procedure Handle_Late_Controlled_Primitive (Body_Decl : Node_Id) is
         Body_Spec : constant Node_Id    := Specification (Body_Decl);
         Body_Id   : constant Entity_Id  := Defining_Entity (Body_Spec);
         Loc       : constant Source_Ptr := Sloc (Body_Id);
         Params    : constant List_Id    :=
                       Parameter_Specifications (Body_Spec);
         Spec      : Node_Id;
         Spec_Id   : Entity_Id;
         Typ       : Node_Id;

      begin
         --  Consider only procedure bodies whose name matches one of the three
         --  controlled primitives.

         if Nkind (Body_Spec) /= N_Procedure_Specification
           or else Chars (Body_Id) not in Name_Adjust
                                        | Name_Finalize
                                        | Name_Initialize
         then
            return;

         --  A controlled primitive must have exactly one formal which is not
         --  an anonymous access type.

         elsif List_Length (Params) /= 1 then
            return;
         end if;

         Typ := Parameter_Type (First (Params));

         if Nkind (Typ) = N_Access_Definition then
            return;
         end if;

         Find_Type (Typ);

         --  The type of the formal must be derived from [Limited_]Controlled

         if not Is_Controlled (Entity (Typ)) then
            return;
         end if;

         --  Check whether a specification exists for this body. We do not
         --  analyze the spec of the body in full, because it will be analyzed
         --  again when the body is properly analyzed, and we cannot create
         --  duplicate entries in the formals chain. We look for an explicit
         --  specification because the body may be an overriding operation and
         --  an inherited spec may be present.

         Spec_Id := Current_Entity (Body_Id);

         while Present (Spec_Id) loop
            if Ekind (Spec_Id) in E_Procedure | E_Generic_Procedure
              and then Scope (Spec_Id) = Current_Scope
              and then Present (First_Formal (Spec_Id))
              and then No (Next_Formal (First_Formal (Spec_Id)))
              and then Etype (First_Formal (Spec_Id)) = Entity (Typ)
              and then Comes_From_Source (Spec_Id)
            then
               return;
            end if;

            Spec_Id := Homonym (Spec_Id);
         end loop;

         --  At this point the body is known to be a late controlled primitive.
         --  Generate a matching spec and insert it before the body. Note the
         --  use of Copy_Separate_Tree - we want an entirely separate semantic
         --  tree in this case.

         Spec := Copy_Separate_Tree (Body_Spec);

         --  Ensure that the subprogram declaration does not inherit the null
         --  indicator from the body as we now have a proper spec/body pair.

         Set_Null_Present (Spec, False);

         --  Ensure that the freeze node is inserted after the declaration of
         --  the primitive since its expansion will freeze the primitive.

         Decl := Make_Subprogram_Declaration (Loc, Specification => Spec);

         Insert_Before_And_Analyze (Body_Decl, Decl);
      end Handle_Late_Controlled_Primitive;

      ----------------------------------------
      -- Remove_Partial_Visible_Refinements --
      ----------------------------------------

      procedure Remove_Partial_Visible_Refinements (Spec_Id : Entity_Id) is
         State_Elmt : Elmt_Id;
      begin
         if Present (Abstract_States (Spec_Id)) then
            State_Elmt := First_Elmt (Abstract_States (Spec_Id));
            while Present (State_Elmt) loop
               Set_Has_Partial_Visible_Refinement (Node (State_Elmt), False);
               Next_Elmt (State_Elmt);
            end loop;
         end if;

         --  For a child unit, also hide the partial state refinement from
         --  ancestor packages.

         if Is_Child_Unit (Spec_Id) then
            Remove_Partial_Visible_Refinements (Scope (Spec_Id));
         end if;
      end Remove_Partial_Visible_Refinements;

      --------------------------------
      -- Remove_Visible_Refinements --
      --------------------------------

      procedure Remove_Visible_Refinements (Spec_Id : Entity_Id) is
         State_Elmt : Elmt_Id;
      begin
         if Present (Abstract_States (Spec_Id)) then
            State_Elmt := First_Elmt (Abstract_States (Spec_Id));
            while Present (State_Elmt) loop
               Set_Has_Visible_Refinement (Node (State_Elmt), False);
               Next_Elmt (State_Elmt);
            end loop;
         end if;
      end Remove_Visible_Refinements;

      ---------------------
      -- Resolve_Aspects --
      ---------------------

      procedure Resolve_Aspects is
         E : Entity_Id;

      begin
         E := First_Entity (Current_Scope);
         while Present (E) loop
            Resolve_Aspect_Expressions (E);

            --  Now that the aspect expressions have been resolved, if this is
            --  at the end of the visible declarations, we can set the flag
            --  Known_To_Have_Preelab_Init properly on types declared in the
            --  visible part, which is needed for checking whether full types
            --  in the private part satisfy the Preelaborable_Initialization
            --  aspect of the partial view. We can't wait for the creation of
            --  the pragma by Analyze_Aspects_At_Freeze_Point, because the
            --  freeze point may occur after the end of the package declaration
            --  (in the case of nested packages).

            if Is_Type (E)
              and then L = Visible_Declarations (Parent (L))
              and then Has_Aspect (E, Aspect_Preelaborable_Initialization)
            then
               declare
                  ASN  : constant Node_Id :=
                    Find_Aspect (E, Aspect_Preelaborable_Initialization);
                  Expr : constant Node_Id := Expression (ASN);
               begin
                  --  Set Known_To_Have_Preelab_Init to True if aspect has no
                  --  expression, or if the expression is True (or was folded
                  --  to True), or if the expression is a conjunction of one or
                  --  more Preelaborable_Initialization attributes applied to
                  --  formal types and wasn't folded to False. (Note that
                  --  Is_Conjunction_Of_Formal_Preelab_Init_Attributes goes to
                  --  Original_Node if needed, hence test for Standard_False.)

                  if not Present (Expr)
                    or else (Is_Entity_Name (Expr)
                              and then Entity (Expr) = Standard_True)
                    or else
                      (Is_Conjunction_Of_Formal_Preelab_Init_Attributes (Expr)
                        and then
                          not (Is_Entity_Name (Expr)
                                and then Entity (Expr) = Standard_False))
                  then
                     Set_Known_To_Have_Preelab_Init (E);
                  end if;
               end;
            end if;

            Next_Entity (E);
         end loop;
      end Resolve_Aspects;

      --  Local variables

      Context     : Node_Id   := Empty;
      Ctrl_Typ    : Entity_Id := Empty;
      Freeze_From : Entity_Id := Empty;
      Next_Decl   : Node_Id;

   --  Start of processing for Analyze_Declarations

   begin
      Decl := First (L);
      while Present (Decl) loop

         --  Complete analysis of declaration

         Analyze (Decl);
         Next_Decl := Next (Decl);

         if No (Freeze_From) then
            Freeze_From := First_Entity (Current_Scope);
         end if;

         --  Remember if the declaration we just processed is the full type
         --  declaration of a controlled type (to handle late overriding of
         --  initialize, adjust or finalize).

         if Nkind (Decl) = N_Full_Type_Declaration
           and then Is_Controlled (Defining_Identifier (Decl))
         then
            Ctrl_Typ := Defining_Identifier (Decl);
         end if;

         --  At the end of a declarative part, freeze remaining entities
         --  declared in it. The end of the visible declarations of package
         --  specification is not the end of a declarative part if private
         --  declarations are present. The end of a package declaration is a
         --  freezing point only if it a library package. A task definition or
         --  protected type definition is not a freeze point either. Finally,
         --  we do not freeze entities in generic scopes, because there is no
         --  code generated for them and freeze nodes will be generated for
         --  the instance.

         --  The end of a package instantiation is not a freeze point, but
         --  for now we make it one, because the generic body is inserted
         --  (currently) immediately after. Generic instantiations will not
         --  be a freeze point once delayed freezing of bodies is implemented.
         --  (This is needed in any case for early instantiations ???).

         if No (Next_Decl) then
            if Nkind (Parent (L)) = N_Component_List then
               null;

            elsif Nkind (Parent (L)) in
                    N_Protected_Definition | N_Task_Definition
            then
               Check_Entry_Contracts;

            elsif Nkind (Parent (L)) /= N_Package_Specification then
               if Nkind (Parent (L)) = N_Package_Body then
                  Freeze_From := First_Entity (Current_Scope);
               end if;

               --  There may have been several freezing points previously,
               --  for example object declarations or subprogram bodies, but
               --  at the end of a declarative part we check freezing from
               --  the beginning, even though entities may already be frozen,
               --  in order to perform visibility checks on delayed aspects.

               Adjust_Decl;

               --  If the current scope is a generic subprogram body. Skip the
               --  generic formal parameters that are not frozen here.

               if Is_Subprogram (Current_Scope)
                 and then Nkind (Unit_Declaration_Node (Current_Scope)) =
                            N_Generic_Subprogram_Declaration
                 and then Present (First_Entity (Current_Scope))
               then
                  while Is_Generic_Formal (Freeze_From) loop
                     Next_Entity (Freeze_From);
                  end loop;

                  Freeze_All (Freeze_From, Decl);
                  Freeze_From := Last_Entity (Current_Scope);

               else
                  --  For declarations in a subprogram body there is no issue
                  --  with name resolution in aspect specifications.

                  Freeze_All (First_Entity (Current_Scope), Decl);
                  Freeze_From := Last_Entity (Current_Scope);
               end if;

            --  Current scope is a package specification

            elsif Scope (Current_Scope) /= Standard_Standard
              and then not Is_Child_Unit (Current_Scope)
              and then No (Generic_Parent (Parent (L)))
            then
               --  ARM rule 13.1.1(11/3): usage names in aspect definitions are
               --  resolved at the end of the immediately enclosing declaration
               --  list (AI05-0183-1).

               Resolve_Aspects;

            elsif L /= Visible_Declarations (Parent (L))
              or else Is_Empty_List (Private_Declarations (Parent (L)))
            then
               Adjust_Decl;

               --  End of a package declaration

               --  This is a freeze point because it is the end of a
               --  compilation unit.

               Freeze_All (First_Entity (Current_Scope), Decl);
               Freeze_From := Last_Entity (Current_Scope);

            --  At the end of the visible declarations the expressions in
            --  aspects of all entities declared so far must be resolved.
            --  The entities themselves might be frozen later, and the
            --  generated pragmas and attribute definition clauses analyzed
            --  in full at that point, but name resolution must take place
            --  now.
            --  In addition to being the proper semantics, this is mandatory
            --  within generic units, because global name capture requires
            --  those expressions to be analyzed, given that the generated
            --  pragmas do not appear in the original generic tree.

            elsif Serious_Errors_Detected = 0 then
               Resolve_Aspects;
            end if;

         --  If next node is a body then freeze all types before the body.
         --  An exception occurs for some expander-generated bodies. If these
         --  are generated at places where in general language rules would not
         --  allow a freeze point, then we assume that the expander has
         --  explicitly checked that all required types are properly frozen,
         --  and we do not cause general freezing here. This special circuit
         --  is used when the encountered body is marked as having already
         --  been analyzed.

         --  In all other cases (bodies that come from source, and expander
         --  generated bodies that have not been analyzed yet), freeze all
         --  types now. Note that in the latter case, the expander must take
         --  care to attach the bodies at a proper place in the tree so as to
         --  not cause unwanted freezing at that point.

         --  It is also necessary to check for a case where both an expression
         --  function is used and the current scope depends on an incomplete
         --  private type from a library unit, otherwise premature freezing of
         --  the private type will occur.

         elsif not Analyzed (Next_Decl) and then Is_Body (Next_Decl)
           and then ((Nkind (Next_Decl) /= N_Subprogram_Body
                       or else not Was_Expression_Function (Next_Decl))
                      or else (not Is_Ignored_Ghost_Entity (Current_Scope)
                                and then not Contains_Lib_Incomplete_Type
                                               (Current_Scope)))
         then
            --  When a controlled type is frozen, the expander generates stream
            --  and controlled-type support routines. If the freeze is caused
            --  by the stand-alone body of Initialize, Adjust, or Finalize, the
            --  expander will end up using the wrong version of these routines,
            --  as the body has not been processed yet. To remedy this, detect
            --  a late controlled primitive and create a proper spec for it.
            --  This ensures that the primitive will override its inherited
            --  counterpart before the freeze takes place.

            --  If the declaration we just processed is a body, do not attempt
            --  to examine Next_Decl as the late primitive idiom can only apply
            --  to the first encountered body.

            --  ??? A cleaner approach may be possible and/or this solution
            --  could be extended to general-purpose late primitives.

            if Present (Ctrl_Typ) then

               --  No need to continue searching for late body overriding if
               --  the controlled type is already frozen.

               if Is_Frozen (Ctrl_Typ) then
                  Ctrl_Typ := Empty;

               elsif Nkind (Next_Decl) = N_Subprogram_Body then
                  Handle_Late_Controlled_Primitive (Next_Decl);
               end if;
            end if;

            Adjust_Decl;

            --  The generated body of an expression function does not freeze,
            --  unless it is a completion, in which case only the expression
            --  itself freezes. This is handled when the body itself is
            --  analyzed (see Freeze_Expr_Types, sem_ch6.adb).

            Freeze_All (Freeze_From, Decl);
            Freeze_From := Last_Entity (Current_Scope);
         end if;

         Decl := Next_Decl;
      end loop;

      --  Post-freezing actions

      if Present (L) then
         Context := Parent (L);

         --  Certain contract annotations have forward visibility semantics and
         --  must be analyzed after all declarative items have been processed.
         --  This timing ensures that entities referenced by such contracts are
         --  visible.

         --  Analyze the contract of an immediately enclosing package spec or
         --  body first because other contracts may depend on its information.

         if Nkind (Context) = N_Package_Body then
            Analyze_Package_Body_Contract (Defining_Entity (Context));

         elsif Nkind (Context) = N_Package_Specification then
            Analyze_Package_Contract (Defining_Entity (Context));
         end if;

         --  Analyze the contracts of various constructs in the declarative
         --  list.

         Analyze_Contracts (L);

         if Nkind (Context) = N_Package_Body then

            --  Ensure that all abstract states and objects declared in the
            --  state space of a package body are utilized as constituents.

            Check_Unused_Body_States (Defining_Entity (Context));

            --  State refinements are visible up to the end of the package body
            --  declarations. Hide the state refinements from visibility to
            --  restore the original state conditions.

            Remove_Visible_Refinements (Corresponding_Spec (Context));
            Remove_Partial_Visible_Refinements (Corresponding_Spec (Context));

         elsif Nkind (Context) = N_Package_Specification then

            --  Partial state refinements are visible up to the end of the
            --  package spec declarations. Hide the partial state refinements
            --  from visibility to restore the original state conditions.

            Remove_Partial_Visible_Refinements (Defining_Entity (Context));
         end if;

         --  Verify that all abstract states found in any package declared in
         --  the input declarative list have proper refinements. The check is
         --  performed only when the context denotes a block, entry, package,
         --  protected, subprogram, or task body (SPARK RM 7.2.2(3)).

         Check_State_Refinements (Context);

         --  Create the subprogram bodies which verify the run-time semantics
         --  of pragmas Default_Initial_Condition and [Type_]Invariant for all
         --  types within the current declarative list. This ensures that all
         --  assertion expressions are preanalyzed and resolved at the end of
         --  the declarative part. Note that the resolution happens even when
         --  freezing does not take place.

         Build_Assertion_Bodies (L, Context);
      end if;
   end Analyze_Declarations;

   -----------------------------------
   -- Analyze_Full_Type_Declaration --
   -----------------------------------

   procedure Analyze_Full_Type_Declaration (N : Node_Id) is
      Def    : constant Node_Id   := Type_Definition (N);
      Def_Id : constant Entity_Id := Defining_Identifier (N);
      T      : Entity_Id;
      Prev   : Entity_Id;

      Is_Remote : constant Boolean :=
                    (Is_Remote_Types (Current_Scope)
                       or else Is_Remote_Call_Interface (Current_Scope))
                      and then not (In_Private_Part (Current_Scope)
                                     or else In_Package_Body (Current_Scope));

      procedure Check_Nonoverridable_Aspects;
      --  Apply the rule in RM 13.1.1(18.4/4) on iterator aspects that cannot
      --  be overridden, and can only be confirmed on derivation.

      procedure Check_Ops_From_Incomplete_Type;
      --  If there is a tagged incomplete partial view of the type, traverse
      --  the primitives of the incomplete view and change the type of any
      --  controlling formals and result to indicate the full view. The
      --  primitives will be added to the full type's primitive operations
      --  list later in Sem_Disp.Check_Operation_From_Incomplete_Type (which
      --  is called from Process_Incomplete_Dependents).

      ----------------------------------
      -- Check_Nonoverridable_Aspects --
      ----------------------------------

      procedure Check_Nonoverridable_Aspects is
         function Get_Aspect_Spec
           (Specs       : List_Id;
            Aspect_Name : Name_Id) return Node_Id;
         --  Check whether a list of aspect specifications includes an entry
         --  for a specific aspect. The list is either that of a partial or
         --  a full view.

         ---------------------
         -- Get_Aspect_Spec --
         ---------------------

         function Get_Aspect_Spec
           (Specs       : List_Id;
            Aspect_Name : Name_Id) return Node_Id
         is
            Spec : Node_Id;

         begin
            Spec := First (Specs);
            while Present (Spec) loop
               if Chars (Identifier (Spec)) = Aspect_Name then
                  return Spec;
               end if;
               Next (Spec);
            end loop;

            return Empty;
         end Get_Aspect_Spec;

         --  Local variables

         Prev_Aspects   : constant List_Id :=
                            Aspect_Specifications (Parent (Def_Id));
         Par_Type       : Entity_Id;
         Prev_Aspect    : Node_Id;

      --  Start of processing for Check_Nonoverridable_Aspects

      begin
         --  Get parent type of derived type. Note that Prev is the entity in
         --  the partial declaration, but its contents are now those of full
         --  view, while Def_Id reflects the partial view.

         if Is_Private_Type (Def_Id) then
            Par_Type := Etype (Full_View (Def_Id));
         else
            Par_Type := Etype (Def_Id);
         end if;

         --  If there is an inherited Implicit_Dereference, verify that it is
         --  made explicit in the partial view.

         if Has_Discriminants (Base_Type (Par_Type))
           and then Nkind (Parent (Prev)) = N_Full_Type_Declaration
           and then Present (Discriminant_Specifications (Parent (Prev)))
           and then Present (Get_Reference_Discriminant (Par_Type))
         then
            Prev_Aspect :=
              Get_Aspect_Spec (Prev_Aspects, Name_Implicit_Dereference);

            if No (Prev_Aspect)
              and then Present
                         (Discriminant_Specifications
                           (Original_Node (Parent (Prev))))
            then
               Error_Msg_N
                 ("type does not inherit implicit dereference", Prev);

            else
               --  If one of the views has the aspect specified, verify that it
               --  is consistent with that of the parent.

               declare
                  Cur_Discr : constant Entity_Id :=
                                Get_Reference_Discriminant (Prev);
                  Par_Discr : constant Entity_Id :=
                                Get_Reference_Discriminant (Par_Type);

               begin
                  if Corresponding_Discriminant (Cur_Discr) /= Par_Discr then
                     Error_Msg_N
                       ("aspect inconsistent with that of parent", N);
                  end if;

                  --  Check that specification in partial view matches the
                  --  inherited aspect. Compare names directly because aspect
                  --  expression may not be analyzed.

                  if Present (Prev_Aspect)
                    and then Nkind (Expression (Prev_Aspect)) = N_Identifier
                    and then Chars (Expression (Prev_Aspect)) /=
                               Chars (Cur_Discr)
                  then
                     Error_Msg_N
                       ("aspect inconsistent with that of parent", N);
                  end if;
               end;
            end if;
         end if;

         --  What about other nonoverridable aspects???
      end Check_Nonoverridable_Aspects;

      ------------------------------------
      -- Check_Ops_From_Incomplete_Type --
      ------------------------------------

      procedure Check_Ops_From_Incomplete_Type is
         Elmt   : Elmt_Id;
         Formal : Entity_Id;
         Op     : Entity_Id;

      begin
         if Prev /= T
           and then Ekind (Prev) = E_Incomplete_Type
           and then Is_Tagged_Type (Prev)
           and then Is_Tagged_Type (T)
           and then Present (Primitive_Operations (Prev))
         then
            Elmt := First_Elmt (Primitive_Operations (Prev));
            while Present (Elmt) loop
               Op := Node (Elmt);

               Formal := First_Formal (Op);
               while Present (Formal) loop
                  if Etype (Formal) = Prev then
                     Set_Etype (Formal, T);
                  end if;

                  Next_Formal (Formal);
               end loop;

               if Etype (Op) = Prev then
                  Set_Etype (Op, T);
               end if;

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

   --  Start of processing for Analyze_Full_Type_Declaration

   begin
      Prev := Find_Type_Name (N);

      --  The full view, if present, now points to the current type. If there
      --  is an incomplete partial view, set a link to it, to simplify the
      --  retrieval of primitive operations of the type.

      --  Ada 2005 (AI-50217): If the type was previously decorated when
      --  imported through a LIMITED WITH clause, it appears as incomplete
      --  but has no full view.

      if Ekind (Prev) = E_Incomplete_Type
        and then Present (Full_View (Prev))
      then
         T := Full_View (Prev);
         Set_Incomplete_View (N, Parent (Prev));
      else
         T := Prev;
      end if;

      Set_Is_Pure (T, Is_Pure (Current_Scope));

      --  We set the flag Is_First_Subtype here. It is needed to set the
      --  corresponding flag for the Implicit class-wide-type created
      --  during tagged types processing.

      Set_Is_First_Subtype (T, True);

      --  Only composite types other than array types are allowed to have
      --  discriminants.

      case Nkind (Def) is

         --  For derived types, the rule will be checked once we've figured
         --  out the parent type.

         when N_Derived_Type_Definition =>
            null;

         --  For record types, discriminants are allowed.

         when N_Record_Definition =>
            null;

         when others =>
            if Present (Discriminant_Specifications (N)) then
               Error_Msg_N
                 ("elementary or array type cannot have discriminants",
                  Defining_Identifier
                    (First (Discriminant_Specifications (N))));
            end if;
      end case;

      --  Elaborate the type definition according to kind, and generate
      --  subsidiary (implicit) subtypes where needed. We skip this if it was
      --  already done (this happens during the reanalysis that follows a call
      --  to the high level optimizer).

      if not Analyzed (T) then
         Set_Analyzed (T);

         --  Set the SPARK mode from the current context

         Set_SPARK_Pragma           (T, SPARK_Mode_Pragma);
         Set_SPARK_Pragma_Inherited (T);

         case Nkind (Def) is
            when N_Access_To_Subprogram_Definition =>
               Access_Subprogram_Declaration (T, Def);

               --  If this is a remote access to subprogram, we must create the
               --  equivalent fat pointer type, and related subprograms.

               if Is_Remote then
                  Process_Remote_AST_Declaration (N);
               end if;

               --  Validate categorization rule against access type declaration
               --  usually a violation in Pure unit, Shared_Passive unit.

               Validate_Access_Type_Declaration (T, N);

               --  If the type has contracts, we create the corresponding
               --  wrapper at once, before analyzing the aspect specifications,
               --  so that pre/postconditions can be handled directly on the
               --  generated wrapper.

               if Ada_Version >= Ada_2022
                 and then Present (Aspect_Specifications (N))
               then
                  Build_Access_Subprogram_Wrapper (N);
               end if;

            when N_Access_To_Object_Definition =>
               Access_Type_Declaration (T, Def);

               --  Validate categorization rule against access type declaration
               --  usually a violation in Pure unit, Shared_Passive unit.

               Validate_Access_Type_Declaration (T, N);

               --  If we are in a Remote_Call_Interface package and define a
               --  RACW, then calling stubs and specific stream attributes
               --  must be added.

               if Is_Remote
                 and then Is_Remote_Access_To_Class_Wide_Type (Def_Id)
               then
                  Add_RACW_Features (Def_Id);
               end if;

            when N_Array_Type_Definition =>
               Array_Type_Declaration (T, Def);

            when N_Derived_Type_Definition =>
               Derived_Type_Declaration (T, N, T /= Def_Id);

               --  Inherit predicates from parent, and protect against illegal
               --  derivations.

               if Is_Type (T) and then Has_Predicates (T) then
                  Set_Has_Predicates (Def_Id);
               end if;

               --  Save the scenario for examination by the ABE Processing
               --  phase.

               Record_Elaboration_Scenario (N);

            when N_Enumeration_Type_Definition =>
               Enumeration_Type_Declaration (T, Def);

            when N_Floating_Point_Definition =>
               Floating_Point_Type_Declaration (T, Def);

            when N_Decimal_Fixed_Point_Definition =>
               Decimal_Fixed_Point_Type_Declaration (T, Def);

            when N_Ordinary_Fixed_Point_Definition =>
               Ordinary_Fixed_Point_Type_Declaration (T, Def);

            when N_Signed_Integer_Type_Definition =>
               Signed_Integer_Type_Declaration (T, Def);

            when N_Modular_Type_Definition =>
               Modular_Type_Declaration (T, Def);

            when N_Record_Definition =>
               Record_Type_Declaration (T, N, Prev);

            --  If declaration has a parse error, nothing to elaborate.

            when N_Error =>
               null;

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

      if Etype (T) = Any_Type then
         return;
      end if;

      --  Set the primitives list of the full type and its base type when
      --  needed. T may be E_Void in cases of earlier errors, and in that
      --  case we bypass this.

      if Ekind (T) /= E_Void
        and then not Present (Direct_Primitive_Operations (T))
      then
         if Etype (T) = T then
            Set_Direct_Primitive_Operations (T, New_Elmt_List);

         --  If Etype of T is the base type (as opposed to a parent type) and
         --  already has an associated list of primitive operations, then set
         --  T's primitive list to the base type's list. Otherwise, create a
         --  new empty primitives list and share the list between T and its
         --  base type. The lists need to be shared in common between the two.

         elsif Etype (T) = Base_Type (T) then

            if not Present (Direct_Primitive_Operations (Base_Type (T))) then
               Set_Direct_Primitive_Operations
                 (Base_Type (T), New_Elmt_List);
            end if;

            Set_Direct_Primitive_Operations
              (T, Direct_Primitive_Operations (Base_Type (T)));

         --  Case where the Etype is a parent type, so we need a new primitives
         --  list for T.

         else
            Set_Direct_Primitive_Operations (T, New_Elmt_List);
         end if;
      end if;

      --  Some common processing for all types

      Set_Depends_On_Private (T, Has_Private_Component (T));
      Check_Ops_From_Incomplete_Type;

      --  Both the declared entity, and its anonymous base type if one was
      --  created, need freeze nodes allocated.

      declare
         B : constant Entity_Id := Base_Type (T);

      begin
         --  In the case where the base type differs from the first subtype, we
         --  pre-allocate a freeze node, and set the proper link to the first
         --  subtype. Freeze_Entity will use this preallocated freeze node when
         --  it freezes the entity.

         --  This does not apply if the base type is a generic type, whose
         --  declaration is independent of the current derived definition.

         if B /= T and then not Is_Generic_Type (B) then
            Ensure_Freeze_Node (B);
            Set_First_Subtype_Link (Freeze_Node (B), T);
         end if;

         --  A type that is imported through a limited_with clause cannot
         --  generate any code, and thus need not be frozen. However, an access
         --  type with an imported designated type needs a finalization list,
         --  which may be referenced in some other package that has non-limited
         --  visibility on the designated type. Thus we must create the
         --  finalization list at the point the access type is frozen, to
         --  prevent unsatisfied references at link time.

         if not From_Limited_With (T) or else Is_Access_Type (T) then
            Set_Has_Delayed_Freeze (T);
         end if;
      end;

      --  Case where T is the full declaration of some private type which has
      --  been swapped in Defining_Identifier (N).

      if T /= Def_Id and then Is_Private_Type (Def_Id) then
         Process_Full_View (N, T, Def_Id);

         --  Record the reference. The form of this is a little strange, since
         --  the full declaration has been swapped in. So the first parameter
         --  here represents the entity to which a reference is made which is
         --  the "real" entity, i.e. the one swapped in, and the second
         --  parameter provides the reference location.

         --  Also, we want to kill Has_Pragma_Unreferenced temporarily here
         --  since we don't want a complaint about the full type being an
         --  unwanted reference to the private type

         declare
            B : constant Boolean := Has_Pragma_Unreferenced (T);
         begin
            Set_Has_Pragma_Unreferenced (T, False);
            Generate_Reference (T, T, 'c');
            Set_Has_Pragma_Unreferenced (T, B);
         end;

         Set_Completion_Referenced (Def_Id);

      --  For completion of incomplete type, process incomplete dependents
      --  and always mark the full type as referenced (it is the incomplete
      --  type that we get for any real reference).

      elsif Ekind (Prev) = E_Incomplete_Type then
         Process_Incomplete_Dependents (N, T, Prev);
         Generate_Reference (Prev, Def_Id, 'c');
         Set_Completion_Referenced (Def_Id);

      --  If not private type or incomplete type completion, this is a real
      --  definition of a new entity, so record it.

      else
         Generate_Definition (Def_Id);
      end if;

      --  Propagate any pending access types whose finalization masters need to
      --  be fully initialized from the partial to the full view. Guard against
      --  an illegal full view that remains unanalyzed.

      if Is_Type (Def_Id) and then Is_Incomplete_Or_Private_Type (Prev) then
         Set_Pending_Access_Types (Def_Id, Pending_Access_Types (Prev));
      end if;

      if Chars (Scope (Def_Id)) = Name_System
        and then Chars (Def_Id) = Name_Address
        and then In_Predefined_Unit (N)
      then
         Set_Is_Descendant_Of_Address (Def_Id);
         Set_Is_Descendant_Of_Address (Base_Type (Def_Id));
         Set_Is_Descendant_Of_Address (Prev);
      end if;

      Set_Optimize_Alignment_Flags (Def_Id);
      Check_Eliminated (Def_Id);

      --  If the declaration is a completion and aspects are present, apply
      --  them to the entity for the type which is currently the partial
      --  view, but which is the one that will be frozen.

      if Has_Aspects (N) then

         --  In most cases the partial view is a private type, and both views
         --  appear in different declarative parts. In the unusual case where
         --  the partial view is incomplete, perform the analysis on the
         --  full view, to prevent freezing anomalies with the corresponding
         --  class-wide type, which otherwise might be frozen before the
         --  dispatch table is built.

         if Prev /= Def_Id
           and then Ekind (Prev) /= E_Incomplete_Type
         then
            Analyze_Aspect_Specifications (N, Prev);

         --  Normal case

         else
            Analyze_Aspect_Specifications (N, Def_Id);
         end if;
      end if;

      if Is_Derived_Type (Prev)
        and then Def_Id /= Prev
      then
         Check_Nonoverridable_Aspects;
      end if;
   end Analyze_Full_Type_Declaration;

   ----------------------------------
   -- Analyze_Incomplete_Type_Decl --
   ----------------------------------

   procedure Analyze_Incomplete_Type_Decl (N : Node_Id) is
      F : constant Boolean := Is_Pure (Current_Scope);
      T : Entity_Id;

   begin
      Generate_Definition (Defining_Identifier (N));

      --  Process an incomplete declaration. The identifier must not have been
      --  declared already in the scope. However, an incomplete declaration may
      --  appear in the private part of a package, for a private type that has
      --  already been declared.

      --  In this case, the discriminants (if any) must match

      T := Find_Type_Name (N);

      Mutate_Ekind         (T, E_Incomplete_Type);
      Set_Etype            (T, T);
      Set_Is_First_Subtype (T);
      Reinit_Size_Align    (T);

      --  Set the SPARK mode from the current context

      Set_SPARK_Pragma           (T, SPARK_Mode_Pragma);
      Set_SPARK_Pragma_Inherited (T);

      --  Ada 2005 (AI-326): Minimum decoration to give support to tagged
      --  incomplete types.

      if Tagged_Present (N) then
         Set_Is_Tagged_Type (T, True);
         Set_No_Tagged_Streams_Pragma (T, No_Tagged_Streams);
         Make_Class_Wide_Type (T);
         Set_Direct_Primitive_Operations (T, New_Elmt_List);
      end if;

      Set_Stored_Constraint (T, No_Elist);

      if Present (Discriminant_Specifications (N)) then
         Push_Scope (T);
         Process_Discriminants (N);
         End_Scope;
      end if;

      --  If the type has discriminants, nontrivial subtypes may be declared
      --  before the full view of the type. The full views of those subtypes
      --  will be built after the full view of the type.

      Set_Private_Dependents (T, New_Elmt_List);
      Set_Is_Pure            (T, F);
   end Analyze_Incomplete_Type_Decl;

   -----------------------------------
   -- Analyze_Interface_Declaration --
   -----------------------------------

   procedure Analyze_Interface_Declaration (T : Entity_Id; Def : Node_Id) is
      CW : constant Entity_Id := Class_Wide_Type (T);

   begin
      Set_Is_Tagged_Type (T);
      Set_No_Tagged_Streams_Pragma (T, No_Tagged_Streams);

      Set_Is_Limited_Record (T, Limited_Present (Def)
                                  or else Task_Present (Def)
                                  or else Protected_Present (Def)
                                  or else Synchronized_Present (Def));

      --  Type is abstract if full declaration carries keyword, or if previous
      --  partial view did.

      Set_Is_Abstract_Type (T);
      Set_Is_Interface (T);

      --  Type is a limited interface if it includes the keyword limited, task,
      --  protected, or synchronized.

      Set_Is_Limited_Interface
        (T, Limited_Present (Def)
              or else Protected_Present (Def)
              or else Synchronized_Present (Def)
              or else Task_Present (Def));

      Set_Interfaces (T, New_Elmt_List);
      Set_Direct_Primitive_Operations (T, New_Elmt_List);

      --  Complete the decoration of the class-wide entity if it was already
      --  built (i.e. during the creation of the limited view)

      if Present (CW) then
         Set_Is_Interface (CW);
         Set_Is_Limited_Interface      (CW, Is_Limited_Interface (T));
      end if;

      --  Check runtime support for synchronized interfaces

      if Is_Concurrent_Interface (T)
        and then not RTE_Available (RE_Select_Specific_Data)
      then
         Error_Msg_CRT ("synchronized interfaces", T);
      end if;
   end Analyze_Interface_Declaration;

   -----------------------------
   -- Analyze_Itype_Reference --
   -----------------------------

   --  Nothing to do. This node is placed in the tree only for the benefit of
   --  back end processing, and has no effect on the semantic processing.

   procedure Analyze_Itype_Reference (N : Node_Id) is
   begin
      pragma Assert (Is_Itype (Itype (N)));
      null;
   end Analyze_Itype_Reference;

   --------------------------------
   -- Analyze_Number_Declaration --
   --------------------------------

   procedure Analyze_Number_Declaration (N : Node_Id) is
      E     : constant Node_Id   := Expression (N);
      Id    : constant Entity_Id := Defining_Identifier (N);
      Index : Interp_Index;
      It    : Interp;
      T     : Entity_Id;

   begin
      Generate_Definition (Id);
      Enter_Name (Id);

      --  This is an optimization of a common case of an integer literal

      if Nkind (E) = N_Integer_Literal then
         Set_Is_Static_Expression (E, True);
         Set_Etype                (E, Universal_Integer);

         Set_Etype     (Id, Universal_Integer);
         Mutate_Ekind  (Id, E_Named_Integer);
         Set_Is_Frozen (Id, True);

         Set_Debug_Info_Needed (Id);
         return;
      end if;

      Set_Is_Pure (Id, Is_Pure (Current_Scope));

      --  Process expression, replacing error by integer zero, to avoid
      --  cascaded errors or aborts further along in the processing

      --  Replace Error by integer zero, which seems least likely to cause
      --  cascaded errors.

      if E = Error then
         Rewrite (E, Make_Integer_Literal (Sloc (E), Uint_0));
         Set_Error_Posted (E);
      end if;

      Analyze (E);

      --  Verify that the expression is static and numeric. If
      --  the expression is overloaded, we apply the preference
      --  rule that favors root numeric types.

      if not Is_Overloaded (E) then
         T := Etype (E);
         if Has_Dynamic_Predicate_Aspect (T) then
            Error_Msg_N
              ("subtype has dynamic predicate, "
               & "not allowed in number declaration", N);
         end if;

      else
         T := Any_Type;

         Get_First_Interp (E, Index, It);
         while Present (It.Typ) loop
            if (Is_Integer_Type (It.Typ) or else Is_Real_Type (It.Typ))
              and then (Scope (Base_Type (It.Typ))) = Standard_Standard
            then
               if T = Any_Type then
                  T := It.Typ;

               elsif Is_Universal_Numeric_Type (It.Typ) then
                  --  Choose universal interpretation over any other

                  T := It.Typ;
                  exit;
               end if;
            end if;

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

      if Is_Integer_Type (T) then
         Resolve (E, T);
         Set_Etype (Id, Universal_Integer);
         Mutate_Ekind (Id, E_Named_Integer);

      elsif Is_Real_Type (T) then

         --  Because the real value is converted to universal_real, this is a
         --  legal context for a universal fixed expression.

         if T = Universal_Fixed then
            declare
               Loc  : constant Source_Ptr := Sloc (N);
               Conv : constant Node_Id := Make_Type_Conversion (Loc,
                        Subtype_Mark =>
                          New_Occurrence_Of (Universal_Real, Loc),
                        Expression => Relocate_Node (E));

            begin
               Rewrite (E, Conv);
               Analyze (E);
            end;

         elsif T = Any_Fixed then
            Error_Msg_N ("illegal context for mixed mode operation", E);

            --  Expression is of the form : universal_fixed * integer. Try to
            --  resolve as universal_real.

            T := Universal_Real;
            Set_Etype (E, T);
         end if;

         Resolve (E, T);
         Set_Etype (Id, Universal_Real);
         Mutate_Ekind (Id, E_Named_Real);

      else
         Wrong_Type (E, Any_Numeric);
         Resolve (E, T);

         Set_Etype               (Id, T);
         Mutate_Ekind            (Id, E_Constant);
         Set_Never_Set_In_Source (Id, True);
         Set_Is_True_Constant    (Id, True);
         return;
      end if;

      if Nkind (E) in N_Integer_Literal | N_Real_Literal then
         Set_Etype (E, Etype (Id));
      end if;

      if not Is_OK_Static_Expression (E) then
         Flag_Non_Static_Expr
           ("non-static expression used in number declaration!", E);
         Rewrite (E, Make_Integer_Literal (Sloc (N), 1));
         Set_Etype (E, Any_Type);
      end if;

      Analyze_Dimension (N);
   end Analyze_Number_Declaration;

   --------------------------------
   -- Analyze_Object_Declaration --
   --------------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Object_Declaration (N : Node_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Id        : constant Entity_Id  := Defining_Identifier (N);
      Next_Decl : constant Node_Id    := Next (N);

      Act_T : Entity_Id;
      T     : Entity_Id;

      E : Node_Id := Expression (N);
      --  E is set to Expression (N) throughout this routine. When Expression
      --  (N) is modified, E is changed accordingly.

      procedure Check_Dynamic_Object (Typ : Entity_Id);
      --  A library-level object with nonstatic discriminant constraints may
      --  require dynamic allocation. The declaration is illegal if the
      --  profile includes the restriction No_Implicit_Heap_Allocations.

      procedure Check_For_Null_Excluding_Components
        (Obj_Typ  : Entity_Id;
         Obj_Decl : Node_Id);
      --  Verify that each null-excluding component of object declaration
      --  Obj_Decl carrying type Obj_Typ has explicit initialization. Emit
      --  a compile-time warning if this is not the case.

      function Count_Tasks (T : Entity_Id) return Uint;
      --  This function is called when a non-generic library level object of a
      --  task type is declared. Its function is to count the static number of
      --  tasks declared within the type (it is only called if Has_Task is set
      --  for T). As a side effect, if an array of tasks with nonstatic bounds
      --  or a variant record type is encountered, Check_Restriction is called
      --  indicating the count is unknown.

      function Delayed_Aspect_Present return Boolean;
      --  If the declaration has an expression that is an aggregate, and it
      --  has aspects that require delayed analysis, the resolution of the
      --  aggregate must be deferred to the freeze point of the object. This
      --  special processing was created for address clauses, but it must
      --  also apply to address aspects. This must be done before the aspect
      --  specifications are analyzed because we must handle the aggregate
      --  before the analysis of the object declaration is complete.

      --  Any other relevant delayed aspects on object declarations ???

      --------------------------
      -- Check_Dynamic_Object --
      --------------------------

      procedure Check_Dynamic_Object (Typ : Entity_Id) is
         Comp     : Entity_Id;
         Obj_Type : Entity_Id;

      begin
         Obj_Type := Typ;

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

         if Known_Static_Esize (Obj_Type) then
            return;
         end if;

         if Restriction_Active (No_Implicit_Heap_Allocations)
           and then Expander_Active
           and then Has_Discriminants (Obj_Type)
         then
            Comp := First_Component (Obj_Type);
            while Present (Comp) loop
               if Known_Static_Esize (Etype (Comp))
                 or else Size_Known_At_Compile_Time (Etype (Comp))
               then
                  null;

               elsif not Discriminated_Size (Comp)
                 and then Comes_From_Source (Comp)
               then
                  Error_Msg_NE
                    ("component& of non-static size will violate restriction "
                     & "No_Implicit_Heap_Allocation?", N, Comp);

               elsif Is_Record_Type (Etype (Comp)) then
                  Check_Dynamic_Object (Etype (Comp));
               end if;

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

      -----------------------------------------
      -- Check_For_Null_Excluding_Components --
      -----------------------------------------

      procedure Check_For_Null_Excluding_Components
        (Obj_Typ  : Entity_Id;
         Obj_Decl : Node_Id)
      is
         procedure Check_Component
           (Comp_Typ   : Entity_Id;
            Comp_Decl  : Node_Id := Empty;
            Array_Comp : Boolean := False);
         --  Apply a compile-time null-exclusion check on a component denoted
         --  by its declaration Comp_Decl and type Comp_Typ, and all of its
         --  subcomponents (if any).

         ---------------------
         -- Check_Component --
         ---------------------

         procedure Check_Component
           (Comp_Typ  : Entity_Id;
            Comp_Decl : Node_Id := Empty;
            Array_Comp : Boolean := False)
         is
            Comp : Entity_Id;
            T    : Entity_Id;

         begin
            --  Do not consider internally-generated components or those that
            --  are already initialized.

            if Present (Comp_Decl)
              and then (not Comes_From_Source (Comp_Decl)
                         or else Present (Expression (Comp_Decl)))
            then
               return;
            end if;

            if Is_Incomplete_Or_Private_Type (Comp_Typ)
              and then Present (Full_View (Comp_Typ))
            then
               T := Full_View (Comp_Typ);
            else
               T := Comp_Typ;
            end if;

            --  Verify a component of a null-excluding access type

            if Is_Access_Type (T)
              and then Can_Never_Be_Null (T)
            then
               if Comp_Decl = Obj_Decl then
                  Null_Exclusion_Static_Checks
                    (N          => Obj_Decl,
                     Comp       => Empty,
                     Array_Comp => Array_Comp);

               else
                  Null_Exclusion_Static_Checks
                    (N          => Obj_Decl,
                     Comp       => Comp_Decl,
                     Array_Comp => Array_Comp);
               end if;

            --  Check array components

            elsif Is_Array_Type (T) then

               --  There is no suitable component when the object is of an
               --  array type. However, a namable component may appear at some
               --  point during the recursive inspection, but not at the top
               --  level. At the top level just indicate array component case.

               if Comp_Decl = Obj_Decl then
                  Check_Component (Component_Type (T), Array_Comp => True);
               else
                  Check_Component (Component_Type (T), Comp_Decl);
               end if;

            --  Verify all components of type T

            --  Note: No checks are performed on types with discriminants due
            --  to complexities involving variants. ???

            elsif (Is_Concurrent_Type (T)
                    or else Is_Incomplete_Or_Private_Type (T)
                    or else Is_Record_Type (T))
               and then not Has_Discriminants (T)
            then
               Comp := First_Component (T);
               while Present (Comp) loop
                  Check_Component (Etype (Comp), Parent (Comp));

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

      --  Start processing for Check_For_Null_Excluding_Components

      begin
         Check_Component (Obj_Typ, Obj_Decl);
      end Check_For_Null_Excluding_Components;

      -----------------
      -- Count_Tasks --
      -----------------

      function Count_Tasks (T : Entity_Id) return Uint is
         C : Entity_Id;
         X : Node_Id;
         V : Uint;

      begin
         if Is_Task_Type (T) then
            return Uint_1;

         elsif Is_Record_Type (T) then
            if Has_Discriminants (T) then
               Check_Restriction (Max_Tasks, N);
               return Uint_0;

            else
               V := Uint_0;
               C := First_Component (T);
               while Present (C) loop
                  V := V + Count_Tasks (Etype (C));
                  Next_Component (C);
               end loop;

               return V;
            end if;

         elsif Is_Array_Type (T) then
            X := First_Index (T);
            V := Count_Tasks (Component_Type (T));
            while Present (X) loop
               C := Etype (X);

               if not Is_OK_Static_Subtype (C) then
                  Check_Restriction (Max_Tasks, N);
                  return Uint_0;
               else
                  V := V * (UI_Max (Uint_0,
                                    Expr_Value (Type_High_Bound (C)) -
                                    Expr_Value (Type_Low_Bound (C)) + Uint_1));
               end if;

               Next_Index (X);
            end loop;

            return V;

         else
            return Uint_0;
         end if;
      end Count_Tasks;

      ----------------------------
      -- Delayed_Aspect_Present --
      ----------------------------

      function Delayed_Aspect_Present return Boolean is
         A    : Node_Id;
         A_Id : Aspect_Id;

      begin
         if Present (Aspect_Specifications (N)) then
            A := First (Aspect_Specifications (N));

            while Present (A) loop
               A_Id := Get_Aspect_Id (Chars (Identifier (A)));

               if A_Id = Aspect_Address then

                  --  Set flag on object entity, for later processing at
                  --  the freeze point.

                  Set_Has_Delayed_Aspects (Id);
                  return True;
               end if;

               Next (A);
            end loop;
         end if;

         return False;
      end Delayed_Aspect_Present;

      --  Local variables

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      Prev_Entity       : Entity_Id := Empty;
      Related_Id        : Entity_Id;
      Full_View_Present : Boolean := False;

   --  Start of processing for Analyze_Object_Declaration

   begin
      --  There are three kinds of implicit types generated by an
      --  object declaration:

      --   1. Those generated by the original Object Definition

      --   2. Those generated by the Expression

      --   3. Those used to constrain the Object Definition with the
      --      expression constraints when the definition is unconstrained.

      --  They must be generated in this order to avoid order of elaboration
      --  issues. Thus the first step (after entering the name) is to analyze
      --  the object definition.

      if Constant_Present (N) then
         Prev_Entity := Current_Entity_In_Scope (Id);

         if Present (Prev_Entity)
           and then
             --  If the homograph is an implicit subprogram, it is overridden
             --  by the current declaration.

             ((Is_Overloadable (Prev_Entity)
                and then Is_Inherited_Operation (Prev_Entity))

               --  The current object is a discriminal generated for an entry
               --  family index. Even though the index is a constant, in this
               --  particular context there is no true constant redeclaration.
               --  Enter_Name will handle the visibility.

               or else
                 (Is_Discriminal (Id)
                   and then Ekind (Discriminal_Link (Id)) =
                                              E_Entry_Index_Parameter)

               --  The current object is the renaming for a generic declared
               --  within the instance.

               or else
                 (Ekind (Prev_Entity) = E_Package
                   and then Nkind (Parent (Prev_Entity)) =
                                               N_Package_Renaming_Declaration
                   and then not Comes_From_Source (Prev_Entity)
                   and then
                     Is_Generic_Instance (Renamed_Entity (Prev_Entity)))

               --  The entity may be a homonym of a private component of the
               --  enclosing protected object, for which we create a local
               --  renaming declaration. The declaration is legal, even if
               --  useless when it just captures that component.

               or else
                 (Ekind (Scope (Current_Scope)) = E_Protected_Type
                   and then Nkind (Parent (Prev_Entity)) =
                              N_Object_Renaming_Declaration))
         then
            Prev_Entity := Empty;
         end if;
      end if;

      if Present (Prev_Entity) then

         --  The object declaration is Ghost when it completes a deferred Ghost
         --  constant.

         Mark_And_Set_Ghost_Completion (N, Prev_Entity);

         Constant_Redeclaration (Id, N, T);

         Generate_Reference (Prev_Entity, Id, 'c');
         Set_Completion_Referenced (Id);

         if Error_Posted (N) then

            --  Type mismatch or illegal redeclaration; do not analyze
            --  expression to avoid cascaded errors.

            T := Find_Type_Of_Object (Object_Definition (N), N);
            Set_Etype (Id, T);
            Mutate_Ekind (Id, E_Variable);
            goto Leave;
         end if;

      --  In the normal case, enter identifier at the start to catch premature
      --  usage in the initialization expression.

      else
         Generate_Definition (Id);
         Enter_Name (Id);

         Mark_Coextensions (N, Object_Definition (N));

         T := Find_Type_Of_Object (Object_Definition (N), N);

         if Nkind (Object_Definition (N)) = N_Access_Definition
           and then Present
                      (Access_To_Subprogram_Definition (Object_Definition (N)))
           and then Protected_Present
                      (Access_To_Subprogram_Definition (Object_Definition (N)))
         then
            T := Replace_Anonymous_Access_To_Protected_Subprogram (N);
         end if;

         if Error_Posted (Id) then
            Set_Etype (Id, T);
            Mutate_Ekind (Id, E_Variable);
            goto Leave;
         end if;
      end if;

      --  Ada 2005 (AI-231): Propagate the null-excluding attribute and carry
      --  out some static checks.

      if Ada_Version >= Ada_2005 then

         --  In case of aggregates we must also take care of the correct
         --  initialization of nested aggregates bug this is done at the
         --  point of the analysis of the aggregate (see sem_aggr.adb) ???

         if Can_Never_Be_Null (T) then
            if Present (Expression (N))
              and then Nkind (Expression (N)) = N_Aggregate
            then
               null;

            elsif Comes_From_Source (Id) then
               declare
                  Save_Typ : constant Entity_Id := Etype (Id);
               begin
                  Set_Etype (Id, T); --  Temp. decoration for static checks
                  Null_Exclusion_Static_Checks (N);
                  Set_Etype (Id, Save_Typ);
               end;
            end if;

         --  We might be dealing with an object of a composite type containing
         --  null-excluding components without an aggregate, so we must verify
         --  that such components have default initialization.

         else
            Check_For_Null_Excluding_Components (T, N);
         end if;
      end if;

      --  Object is marked pure if it is in a pure scope

      Set_Is_Pure (Id, Is_Pure (Current_Scope));

      --  If deferred constant, make sure context is appropriate. We detect
      --  a deferred constant as a constant declaration with no expression.
      --  A deferred constant can appear in a package body if its completion
      --  is by means of an interface pragma.

      if Constant_Present (N) and then No (E) then

         --  A deferred constant may appear in the declarative part of the
         --  following constructs:

         --     blocks
         --     entry bodies
         --     extended return statements
         --     package specs
         --     package bodies
         --     subprogram bodies
         --     task bodies

         --  When declared inside a package spec, a deferred constant must be
         --  completed by a full constant declaration or pragma Import. In all
         --  other cases, the only proper completion is pragma Import. Extended
         --  return statements are flagged as invalid contexts because they do
         --  not have a declarative part and so cannot accommodate the pragma.

         if Ekind (Current_Scope) = E_Return_Statement then
            Error_Msg_N
              ("invalid context for deferred constant declaration (RM 7.4)",
               N);
            Error_Msg_N
              ("\declaration requires an initialization expression",
                N);
            Set_Constant_Present (N, False);

         --  In Ada 83, deferred constant must be of private type

         elsif not Is_Private_Type (T) then
            if Ada_Version = Ada_83 and then Comes_From_Source (N) then
               Error_Msg_N
                 ("(Ada 83) deferred constant must be private type", N);
            end if;
         end if;

      --  If not a deferred constant, then the object declaration freezes
      --  its type, unless the object is of an anonymous type and has delayed
      --  aspects. In that case the type is frozen when the object itself is.

      else
         Check_Fully_Declared (T, N);

         if Has_Delayed_Aspects (Id)
           and then Is_Array_Type (T)
           and then Is_Itype (T)
         then
            Set_Has_Delayed_Freeze (T);
         else
            Freeze_Before (N, T);
         end if;
      end if;

      --  If the object was created by a constrained array definition, then
      --  set the link in both the anonymous base type and anonymous subtype
      --  that are built to represent the array type to point to the object.

      if Nkind (Object_Definition (Declaration_Node (Id))) =
                        N_Constrained_Array_Definition
      then
         Set_Related_Array_Object (T, Id);
         Set_Related_Array_Object (Base_Type (T), Id);
      end if;

      --  Check for protected objects not at library level

      if Has_Protected (T) and then not Is_Library_Level_Entity (Id) then
         Check_Restriction (No_Local_Protected_Objects, Id);
      end if;

      --  Check for violation of No_Local_Timing_Events

      if Has_Timing_Event (T) and then not Is_Library_Level_Entity (Id) then
         Check_Restriction (No_Local_Timing_Events, Id);
      end if;

      --  The actual subtype of the object is the nominal subtype, unless
      --  the nominal one is unconstrained and obtained from the expression.

      Act_T := T;

      if Is_Library_Level_Entity (Id) then
         Check_Dynamic_Object (T);
      end if;

      --  Process initialization expression if present and not in error

      if Present (E) and then E /= Error then

         --  Generate an error in case of CPP class-wide object initialization.
         --  Required because otherwise the expansion of the class-wide
         --  assignment would try to use 'size to initialize the object
         --  (primitive that is not available in CPP tagged types).

         if Is_Class_Wide_Type (Act_T)
           and then
             (Is_CPP_Class (Root_Type (Etype (Act_T)))
               or else
                 (Present (Full_View (Root_Type (Etype (Act_T))))
                   and then
                     Is_CPP_Class (Full_View (Root_Type (Etype (Act_T))))))
         then
            Error_Msg_N
              ("predefined assignment not available for 'C'P'P tagged types",
               E);
         end if;

         Mark_Coextensions (N, E);
         Analyze (E);

         --  In case of errors detected in the analysis of the expression,
         --  decorate it with the expected type to avoid cascaded errors.

         if No (Etype (E)) then
            Set_Etype (E, T);
         end if;

         --  If an initialization expression is present, then we set the
         --  Is_True_Constant flag. It will be reset if this is a variable
         --  and it is indeed modified.

         Set_Is_True_Constant (Id, True);

         --  If we are analyzing a constant declaration, set its completion
         --  flag after analyzing and resolving the expression.

         if Constant_Present (N) then
            Set_Has_Completion (Id);
         end if;

         --  Set type and resolve (type may be overridden later on). Note:
         --  Ekind (Id) must still be E_Void at this point so that incorrect
         --  early usage within E is properly diagnosed.

         Set_Etype (Id, T);

         --  If the expression is an aggregate we must look ahead to detect
         --  the possible presence of an address clause, and defer resolution
         --  and expansion of the aggregate to the freeze point of the entity.

         --  This is not always legal because the aggregate may contain other
         --  references that need freezing, e.g. references to other entities
         --  with address clauses. In any case, when compiling with -gnatI the
         --  presence of the address clause must be ignored.

         if Comes_From_Source (N)
           and then Expander_Active
           and then Nkind (E) = N_Aggregate
           and then
             ((Present (Following_Address_Clause (N))
                 and then not Ignore_Rep_Clauses)
              or else Delayed_Aspect_Present)
         then
            Set_Etype (E, T);

            --  If the aggregate is limited it will be built in place, and its
            --  expansion is deferred until the object declaration is expanded.

            --  This is also required when generating C code to ensure that an
            --  object with an alignment or address clause can be initialized
            --  by means of component by component assignments.

            if Is_Limited_Type (T) or else Modify_Tree_For_C then
               Set_Expansion_Delayed (E);
            end if;

         else
            --  If the expression is a formal that is a "subprogram pointer"
            --  this is illegal in accessibility terms (see RM 3.10.2 (13.1/2)
            --  and AARM 3.10.2 (13.b/2)). Add an explicit conversion to force
            --  the corresponding check, as is done for assignments.

            if Is_Entity_Name (E)
              and then Present (Entity (E))
              and then Is_Formal (Entity (E))
              and then
                Ekind (Etype (Entity (E))) = E_Anonymous_Access_Subprogram_Type
              and then Ekind (T) /= E_Anonymous_Access_Subprogram_Type
            then
               Rewrite (E, Convert_To (T, Relocate_Node (E)));
            end if;

            Resolve (E, T);
         end if;

         --  No further action needed if E is a call to an inlined function
         --  which returns an unconstrained type and it has been expanded into
         --  a procedure call. In that case N has been replaced by an object
         --  declaration without initializing expression and it has been
         --  analyzed (see Expand_Inlined_Call).

         if Back_End_Inlining
           and then Expander_Active
           and then Nkind (E) = N_Function_Call
           and then Nkind (Name (E)) in N_Has_Entity
           and then Is_Inlined (Entity (Name (E)))
           and then not Is_Constrained (Etype (E))
           and then Analyzed (N)
           and then No (Expression (N))
         then
            goto Leave;
         end if;

         --  If E is null and has been replaced by an N_Raise_Constraint_Error
         --  node (which was marked already-analyzed), we need to set the type
         --  to something other than Any_Access in order to keep gigi happy.

         if Etype (E) = Any_Access then
            Set_Etype (E, T);
         end if;

         --  If the object is an access to variable, the initialization
         --  expression cannot be an access to constant.

         if Is_Access_Type (T)
           and then not Is_Access_Constant (T)
           and then Is_Access_Type (Etype (E))
           and then Is_Access_Constant (Etype (E))
         then
            Error_Msg_N
              ("access to variable cannot be initialized with an "
               & "access-to-constant expression", E);
         end if;

         if not Assignment_OK (N) then
            Check_Initialization (T, E);
         end if;

         Check_Unset_Reference (E);

         --  If this is a variable, then set current value. If this is a
         --  declared constant of a scalar type with a static expression,
         --  indicate that it is always valid.

         if not Constant_Present (N) then
            if Compile_Time_Known_Value (E) then
               Set_Current_Value (Id, E);
            end if;

         elsif Is_Scalar_Type (T) and then Is_OK_Static_Expression (E) then
            Set_Is_Known_Valid (Id);

         --  If it is a constant initialized with a valid nonstatic entity,
         --  the constant is known valid as well, and can inherit the subtype
         --  of the entity if it is a subtype of the given type. This info
         --  is preserved on the actual subtype of the constant.

         elsif Is_Scalar_Type (T)
           and then Is_Entity_Name (E)
           and then Is_Known_Valid (Entity (E))
           and then In_Subrange_Of (Etype (Entity (E)), T)
         then
            Set_Is_Known_Valid (Id);
            Mutate_Ekind (Id, E_Constant);
            Set_Actual_Subtype (Id, Etype (Entity (E)));
         end if;

         --  Deal with setting of null flags

         if Is_Access_Type (T) then
            if Known_Non_Null (E) then
               Set_Is_Known_Non_Null (Id, True);
            elsif Known_Null (E) and then not Can_Never_Be_Null (Id) then
               Set_Is_Known_Null (Id, True);
            end if;
         end if;

         --  Check incorrect use of dynamically tagged expressions

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

         Apply_Scalar_Range_Check (E, T);
         Apply_Static_Length_Check (E, T);

         --  A formal parameter of a specific tagged type whose related
         --  subprogram is subject to pragma Extensions_Visible with value
         --  "False" cannot be implicitly converted to a class-wide type by
         --  means of an initialization expression (SPARK RM 6.1.7(3)). Do
         --  not consider internally generated expressions.

         if Is_Class_Wide_Type (T)
           and then Comes_From_Source (E)
           and then Is_EVF_Expression (E)
         then
            Error_Msg_N
              ("formal parameter cannot be implicitly converted to "
               & "class-wide type when Extensions_Visible is False", E);
         end if;
      end if;

      --  If the No_Streams restriction is set, check that the type of the
      --  object is not, and does not contain, any subtype derived from
      --  Ada.Streams.Root_Stream_Type. Note that we guard the call to
      --  Has_Stream just for efficiency reasons. There is no point in
      --  spending time on a Has_Stream check if the restriction is not set.

      if Restriction_Check_Required (No_Streams) then
         if Has_Stream (T) then
            Check_Restriction (No_Streams, N);
         end if;
      end if;

      --  Deal with predicate check before we start to do major rewriting. It
      --  is OK to initialize and then check the initialized value, since the
      --  object goes out of scope if we get a predicate failure. Note that we
      --  do this in the analyzer and not the expander because the analyzer
      --  does some substantial rewriting in some cases.

      --  We need a predicate check if the type has predicates that are not
      --  ignored, and if either there is an initializing expression, or for
      --  default initialization when we have at least one case of an explicit
      --  default initial value (including via a Default_Value or
      --  Default_Component_Value aspect, see AI12-0301) and then this is not
      --  an internal declaration whose initialization comes later (as for an
      --  aggregate expansion) or a deferred constant.
      --  If expression is an aggregate it may be expanded into assignments
      --  and the declaration itself is marked with No_Initialization, but
      --  the predicate still applies.

      if not Suppress_Assignment_Checks (N)
        and then (Predicate_Enabled (T) or else Has_Static_Predicate (T))
        and then
          (not No_Initialization (N)
            or else (Present (E) and then Nkind (E) = N_Aggregate))
        and then
          (Present (E)
            or else
              Is_Partially_Initialized_Type (T, Include_Implicit => False))
        and then not (Constant_Present (N) and then No (E))
      then
         --  If the type has a static predicate and the expression is known at
         --  compile time, see if the expression satisfies the predicate.
         --  In the case of a static expression, this must be done even if
         --  the predicate is not enabled (as per static expression rules).

         if Present (E) then
            Check_Expression_Against_Static_Predicate (E, T);
         end if;

         --  Do not perform further predicate-related checks unless
         --  predicates are enabled for the subtype.

         if not Predicate_Enabled (T) then
            null;

         --  If the type is a null record and there is no explicit initial
         --  expression, no predicate check applies.

         elsif No (E) and then Is_Null_Record_Type (T) then
            null;

         --  Do not generate a predicate check if the initialization expression
         --  is a type conversion because the conversion has been subjected to
         --  the same check. This is a small optimization which avoid redundant
         --  checks.

         elsif Present (E) and then Nkind (E) = N_Type_Conversion then
            null;

         else
            --  The check must be inserted after the expanded aggregate
            --  expansion code, if any.

            declare
               Check : constant Node_Id :=
                         Make_Predicate_Check (T, New_Occurrence_Of (Id, Loc));

            begin
               if No (Next_Decl) then
                  Append_To (List_Containing (N), Check);
               else
                  Insert_Before (Next_Decl, Check);
               end if;
            end;
         end if;
      end if;

      --  Case of unconstrained type

      if not Is_Definite_Subtype (T) then

         --  Nothing to do in deferred constant case

         if Constant_Present (N) and then No (E) then
            null;

         --  Case of no initialization present

         elsif No (E) then
            if No_Initialization (N) then
               null;

            elsif Is_Class_Wide_Type (T) then
               Error_Msg_N
                 ("initialization required in class-wide declaration", N);

            else
               Error_Msg_N
                 ("unconstrained subtype not allowed (need initialization)",
                  Object_Definition (N));

               if Is_Record_Type (T) and then Has_Discriminants (T) then
                  Error_Msg_N
                    ("\provide initial value or explicit discriminant values",
                     Object_Definition (N));

                  Error_Msg_NE
                    ("\or give default discriminant values for type&",
                     Object_Definition (N), T);

               elsif Is_Array_Type (T) then
                  Error_Msg_N
                    ("\provide initial value or explicit array bounds",
                     Object_Definition (N));
               end if;
            end if;

         --  Case of initialization present but in error. Set initial
         --  expression as absent (but do not make above complaints).

         elsif E = Error then
            Set_Expression (N, Empty);
            E := Empty;

         --  Case of initialization present

         else
            --  Unconstrained variables not allowed in Ada 83

            if Ada_Version = Ada_83
              and then not Constant_Present (N)
              and then Comes_From_Source (Object_Definition (N))
            then
               Error_Msg_N
                 ("(Ada 83) unconstrained variable not allowed",
                  Object_Definition (N));
            end if;

            --  Now we constrain the variable from the initializing expression

            --  If the expression is an aggregate, it has been expanded into
            --  individual assignments. Retrieve the actual type from the
            --  expanded construct.

            if Is_Array_Type (T)
              and then No_Initialization (N)
              and then Nkind (Original_Node (E)) = N_Aggregate
            then
               Act_T := Etype (E);

            --  In case of class-wide interface object declarations we delay
            --  the generation of the equivalent record type declarations until
            --  its expansion because there are cases in they are not required.

            elsif Is_Interface (T) then
               null;

            --  If the type is an unchecked union, no subtype can be built from
            --  the expression. Rewrite declaration as a renaming, which the
            --  back-end can handle properly. This is a rather unusual case,
            --  because most unchecked_union declarations have default values
            --  for discriminants and are thus not indefinite.

            elsif Is_Unchecked_Union (T) then
               if Constant_Present (N) or else Nkind (E) = N_Function_Call then
                  Mutate_Ekind (Id, E_Constant);
               else
                  Mutate_Ekind (Id, E_Variable);
               end if;

               --  If the expression is an aggregate it contains the required
               --  discriminant values but it has not been resolved yet, so do
               --  it now, and treat it as the initial expression of an object
               --  declaration, rather than a renaming.

               if Nkind (E) = N_Aggregate then
                  Analyze_And_Resolve (E, T);

               else
                  Rewrite (N,
                    Make_Object_Renaming_Declaration (Loc,
                      Defining_Identifier => Id,
                      Subtype_Mark        => New_Occurrence_Of (T, Loc),
                      Name                => E));

                  Set_Renamed_Object (Id, E);
                  Freeze_Before (N, T);
                  Set_Is_Frozen (Id);
                  goto Leave;
               end if;

            else
               --  Ensure that the generated subtype has a unique external name
               --  when the related object is public. This guarantees that the
               --  subtype and its bounds will not be affected by switches or
               --  pragmas that may offset the internal counter due to extra
               --  generated code.

               if Is_Public (Id) then
                  Related_Id := Id;
               else
                  Related_Id := Empty;
               end if;

               --  If the object has an unconstrained array subtype with fixed
               --  lower bound, then sliding to that bound may be needed.

               if Is_Fixed_Lower_Bound_Array_Subtype (T) then
                  Expand_Sliding_Conversion (E, T);
               end if;

               Expand_Subtype_From_Expr
                 (N             => N,
                  Unc_Type      => T,
                  Subtype_Indic => Object_Definition (N),
                  Exp           => E,
                  Related_Id    => Related_Id);

               Act_T := Find_Type_Of_Object (Object_Definition (N), N);
            end if;

            --  Propagate attributes to full view when needed

            Set_Is_Constr_Subt_For_U_Nominal (Act_T);

            if Is_Private_Type (Act_T) and then Present (Full_View (Act_T))
            then
               Full_View_Present := True;
            end if;

            if Full_View_Present then
               Set_Is_Constr_Subt_For_U_Nominal (Full_View (Act_T));
            end if;

            if Aliased_Present (N) then
               Set_Is_Constr_Subt_For_UN_Aliased (Act_T);

               if Full_View_Present then
                  Set_Is_Constr_Subt_For_UN_Aliased (Full_View (Act_T));
               end if;
            end if;

            Freeze_Before (N, Act_T);
            Freeze_Before (N, T);
         end if;

      elsif Is_Array_Type (T)
        and then No_Initialization (N)
        and then (Nkind (Original_Node (E)) = N_Aggregate
                   or else (Nkind (Original_Node (E)) = N_Qualified_Expression
                             and then Nkind (Original_Node (Expression
                                        (Original_Node (E)))) = N_Aggregate))
      then
         if not Is_Entity_Name (Object_Definition (N)) then
            Act_T := Etype (E);
            Check_Compile_Time_Size (Act_T);

            if Aliased_Present (N) then
               Set_Is_Constr_Subt_For_UN_Aliased (Act_T);
            end if;
         end if;

         --  When the given object definition and the aggregate are specified
         --  independently, and their lengths might differ do a length check.
         --  This cannot happen if the aggregate is of the form (others =>...)

         if not Is_Constrained (T) then
            null;

         elsif Nkind (E) = N_Raise_Constraint_Error then

            --  Aggregate is statically illegal. Place back in declaration

            Set_Expression (N, E);
            Set_No_Initialization (N, False);

         elsif T = Etype (E) then
            null;

         elsif Nkind (E) = N_Aggregate
           and then Present (Component_Associations (E))
           and then Present (Choice_List (First (Component_Associations (E))))
           and then
             Nkind (First (Choice_List (First (Component_Associations (E))))) =
               N_Others_Choice
         then
            null;

         else
            Apply_Length_Check (E, T);
         end if;

      --  If the type is limited unconstrained with defaulted discriminants and
      --  there is no expression, then the object is constrained by the
      --  defaults, so it is worthwhile building the corresponding subtype.

      elsif (Is_Limited_Record (T) or else Is_Concurrent_Type (T))
        and then not Is_Constrained (T)
        and then Has_Discriminants (T)
      then
         if No (E) then
            Act_T := Build_Default_Subtype (T, N);
         else
            --  Ada 2005: A limited object may be initialized by means of an
            --  aggregate. If the type has default discriminants it has an
            --  unconstrained nominal type, Its actual subtype will be obtained
            --  from the aggregate, and not from the default discriminants.

            Act_T := Etype (E);
         end if;

         Rewrite (Object_Definition (N), New_Occurrence_Of (Act_T, Loc));

      elsif Nkind (E) = N_Function_Call
        and then Constant_Present (N)
        and then Has_Unconstrained_Elements (Etype (E))
      then
         --  The back-end has problems with constants of a discriminated type
         --  with defaults, if the initial value is a function call. We
         --  generate an intermediate temporary that will receive a reference
         --  to the result of the call. The initialization expression then
         --  becomes a dereference of that temporary.

         Remove_Side_Effects (E);

      --  If this is a constant declaration of an unconstrained type and
      --  the initialization is an aggregate, we can use the subtype of the
      --  aggregate for the declared entity because it is immutable.

      elsif not Is_Constrained (T)
        and then Has_Discriminants (T)
        and then Constant_Present (N)
        and then not Has_Unchecked_Union (T)
        and then Nkind (E) = N_Aggregate
      then
         Act_T := Etype (E);
      end if;

      --  Check No_Wide_Characters restriction

      Check_Wide_Character_Restriction (T, Object_Definition (N));

      --  Indicate this is not set in source. Certainly true for constants, and
      --  true for variables so far (will be reset for a variable if and when
      --  we encounter a modification in the source).

      Set_Never_Set_In_Source (Id);

      --  Now establish the proper kind and type of the object

      if Ekind (Id) = E_Void then
         Reinit_Field_To_Zero (Id, F_Next_Inlined_Subprogram);
      end if;

      if Constant_Present (N) then
         Mutate_Ekind         (Id, E_Constant);
         Set_Is_True_Constant (Id);

      else
         Mutate_Ekind (Id, E_Variable);

         --  A variable is set as shared passive if it appears in a shared
         --  passive package, and is at the outer level. This is not done for
         --  entities generated during expansion, because those are always
         --  manipulated locally.

         if Is_Shared_Passive (Current_Scope)
           and then Is_Library_Level_Entity (Id)
           and then Comes_From_Source (Id)
         then
            Set_Is_Shared_Passive (Id);
            Check_Shared_Var (Id, T, N);
         end if;

         --  Set Has_Initial_Value if initializing expression present. Note
         --  that if there is no initializing expression, we leave the state
         --  of this flag unchanged (usually it will be False, but notably in
         --  the case of exception choice variables, it will already be true).

         if Present (E) then
            Set_Has_Initial_Value (Id);
         end if;
      end if;

      --  Set the SPARK mode from the current context (may be overwritten later
      --  with explicit pragma).

      Set_SPARK_Pragma           (Id, SPARK_Mode_Pragma);
      Set_SPARK_Pragma_Inherited (Id);

      --  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     => Id,
         Checks   => True,
         Warnings => True);

      --  Initialize alignment and size and capture alignment setting

      Reinit_Alignment             (Id);
      Reinit_Esize                 (Id);
      Set_Optimize_Alignment_Flags (Id);

      --  Deal with aliased case

      if Aliased_Present (N) then
         Set_Is_Aliased (Id);

         --  AI12-001: All aliased objects are considered to be specified as
         --  independently addressable (RM C.6(8.1/4)).

         Set_Is_Independent (Id);

         --  If the object is aliased and the type is unconstrained with
         --  defaulted discriminants and there is no expression, then the
         --  object is constrained by the defaults, so it is worthwhile
         --  building the corresponding subtype.

         --  Ada 2005 (AI-363): If the aliased object is discriminated and
         --  unconstrained, then only establish an actual subtype if the
         --  nominal subtype is indefinite. In definite cases the object is
         --  unconstrained in Ada 2005.

         if No (E)
           and then Is_Record_Type (T)
           and then not Is_Constrained (T)
           and then Has_Discriminants (T)
           and then (Ada_Version < Ada_2005
                      or else not Is_Definite_Subtype (T))
         then
            Set_Actual_Subtype (Id, Build_Default_Subtype (T, N));
         end if;
      end if;

      --  Now we can set the type of the object

      Set_Etype (Id, Act_T);

      --  Non-constant object is marked to be treated as volatile if type is
      --  volatile and we clear the Current_Value setting that may have been
      --  set above. Doing so for constants isn't required and might interfere
      --  with possible uses of the object as a static expression in contexts
      --  incompatible with volatility (e.g. as a case-statement alternative).

      if Ekind (Id) /= E_Constant and then Treat_As_Volatile (Etype (Id)) then
         Set_Treat_As_Volatile (Id);
         Set_Current_Value (Id, Empty);
      end if;

      --  Deal with controlled types

      if Has_Controlled_Component (Etype (Id))
        or else Is_Controlled (Etype (Id))
      then
         if not Is_Library_Level_Entity (Id) then
            Check_Restriction (No_Nested_Finalization, N);
         else
            Validate_Controlled_Object (Id);
         end if;
      end if;

      if Has_Task (Etype (Id)) then
         Check_Restriction (No_Tasking, N);

         --  Deal with counting max tasks

         --  Nothing to do if inside a generic

         if Inside_A_Generic then
            null;

         --  If library level entity, then count tasks

         elsif Is_Library_Level_Entity (Id) then
            Check_Restriction (Max_Tasks, N, Count_Tasks (Etype (Id)));

         --  If not library level entity, then indicate we don't know max
         --  tasks and also check task hierarchy restriction and blocking
         --  operation (since starting a task is definitely blocking).

         else
            Check_Restriction (Max_Tasks, N);
            Check_Restriction (No_Task_Hierarchy, N);
            Check_Potentially_Blocking_Operation (N);
         end if;

         --  A rather specialized test. If we see two tasks being declared
         --  of the same type in the same object declaration, and the task
         --  has an entry with an address clause, we know that program error
         --  will be raised at run time since we can't have two tasks with
         --  entries at the same address.

         if Is_Task_Type (Etype (Id)) and then More_Ids (N) then
            declare
               E : Entity_Id;

            begin
               E := First_Entity (Etype (Id));
               while Present (E) loop
                  if Ekind (E) = E_Entry
                    and then Present (Get_Attribute_Definition_Clause
                                        (E, Attribute_Address))
                  then
                     Error_Msg_Warn := SPARK_Mode /= On;
                     Error_Msg_N
                       ("more than one task with same entry address<<", N);
                     Error_Msg_N ("\Program_Error [<<", N);
                     Insert_Action (N,
                       Make_Raise_Program_Error (Loc,
                         Reason => PE_Duplicated_Entry_Address));
                     exit;
                  end if;

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

      --  Some simple constant-propagation: if the expression is a constant
      --  string initialized with a literal, share the literal. This avoids
      --  a run-time copy.

      if Present (E)
        and then Is_Entity_Name (E)
        and then Ekind (Entity (E)) = E_Constant
        and then Base_Type (Etype (E)) = Standard_String
      then
         declare
            Val : constant Node_Id := Constant_Value (Entity (E));
         begin
            if Present (Val) and then Nkind (Val) = N_String_Literal then
               Rewrite (E, New_Copy (Val));
            end if;
         end;
      end if;

      --  Another optimization: if the nominal subtype is unconstrained and
      --  the expression is a function call that returns an unconstrained
      --  type, rewrite the declaration as a renaming of the result of the
      --  call. The exceptions below are cases where the copy is expected,
      --  either by the back end (Aliased case) or by the semantics, as for
      --  initializing controlled types or copying tags for class-wide types.

      if Present (E)
        and then Nkind (E) = N_Explicit_Dereference
        and then Nkind (Original_Node (E)) = N_Function_Call
        and then not Is_Library_Level_Entity (Id)
        and then not Is_Constrained (Underlying_Type (T))
        and then not Is_Aliased (Id)
        and then not Is_Class_Wide_Type (T)
        and then not Is_Controlled (T)
        and then not Has_Controlled_Component (Base_Type (T))
        and then Expander_Active
      then
         Rewrite (N,
           Make_Object_Renaming_Declaration (Loc,
             Defining_Identifier => Id,
             Access_Definition   => Empty,
             Subtype_Mark        => New_Occurrence_Of
                                      (Base_Type (Etype (Id)), Loc),
             Name                => E));

         Set_Renamed_Object (Id, E);

         --  Force generation of debugging information for the constant and for
         --  the renamed function call.

         Set_Debug_Info_Needed (Id);
         Set_Debug_Info_Needed (Entity (Prefix (E)));
      end if;

      if Present (Prev_Entity)
        and then Is_Frozen (Prev_Entity)
        and then not Error_Posted (Id)
      then
         Error_Msg_N ("full constant declaration appears too late", N);
      end if;

      Check_Eliminated (Id);

      --  Deal with setting In_Private_Part flag if in private part

      if Ekind (Scope (Id)) = E_Package
        and then In_Private_Part (Scope (Id))
      then
         Set_In_Private_Part (Id);
      end if;

   <<Leave>>
      --  Initialize the refined state of a variable here because this is a
      --  common destination for legal and illegal object declarations.

      if Ekind (Id) = E_Variable then
         Set_Encapsulating_State (Id, Empty);
      end if;

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

      Analyze_Dimension (N);

      --  Verify whether the object declaration introduces an illegal hidden
      --  state within a package subject to a null abstract state.

      if Ekind (Id) = E_Variable then
         Check_No_Hidden_State (Id);
      end if;

      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Object_Declaration;

   ---------------------------
   -- Analyze_Others_Choice --
   ---------------------------

   --  Nothing to do for the others choice node itself, the semantic analysis
   --  of the others choice will occur as part of the processing of the parent

   procedure Analyze_Others_Choice (N : Node_Id) is
      pragma Warnings (Off, N);
   begin
      null;
   end Analyze_Others_Choice;

   -------------------------------------------
   -- Analyze_Private_Extension_Declaration --
   -------------------------------------------

   procedure Analyze_Private_Extension_Declaration (N : Node_Id) is
      Indic       : constant Node_Id   := Subtype_Indication (N);
      T           : constant Entity_Id := Defining_Identifier (N);
      Iface       : Entity_Id;
      Iface_Elmt  : Elmt_Id;
      Parent_Base : Entity_Id;
      Parent_Type : Entity_Id;

   begin
      --  Ada 2005 (AI-251): Decorate all names in list of ancestor interfaces

      if Is_Non_Empty_List (Interface_List (N)) then
         declare
            Intf : Node_Id;
            T    : Entity_Id;

         begin
            Intf := First (Interface_List (N));
            while Present (Intf) loop
               T := Find_Type_Of_Subtype_Indic (Intf);

               Diagnose_Interface (Intf, T);
               Next (Intf);
            end loop;
         end;
      end if;

      Generate_Definition (T);

      --  For other than Ada 2012, just enter the name in the current scope

      if Ada_Version < Ada_2012 then
         Enter_Name (T);

      --  Ada 2012 (AI05-0162): Enter the name in the current scope handling
      --  case of private type that completes an incomplete type.

      else
         declare
            Prev : Entity_Id;

         begin
            Prev := Find_Type_Name (N);

            pragma Assert (Prev = T
              or else (Ekind (Prev) = E_Incomplete_Type
                        and then Present (Full_View (Prev))
                        and then Full_View (Prev) = T));
         end;
      end if;

      Parent_Type := Find_Type_Of_Subtype_Indic (Indic);
      Parent_Base := Base_Type (Parent_Type);

      if Parent_Type = Any_Type or else Etype (Parent_Type) = Any_Type then
         Mutate_Ekind (T, Ekind (Parent_Type));
         Set_Etype (T, Any_Type);
         goto Leave;

      elsif not Is_Tagged_Type (Parent_Type) then
         Error_Msg_N
           ("parent of type extension must be a tagged type", Indic);
         goto Leave;

      elsif Ekind (Parent_Type) in E_Void | E_Incomplete_Type then
         Error_Msg_N ("premature derivation of incomplete type", Indic);
         goto Leave;

      elsif Is_Concurrent_Type (Parent_Type) then
         Error_Msg_N
           ("parent type of a private extension cannot be a synchronized "
            & "tagged type (RM 3.9.1 (3/1))", N);

         Set_Etype              (T, Any_Type);
         Mutate_Ekind           (T, E_Limited_Private_Type);
         Set_Private_Dependents (T, New_Elmt_List);
         Set_Error_Posted       (T);
         goto Leave;
      end if;

      Check_Wide_Character_Restriction (Parent_Type, Indic);

      --  Perhaps the parent type should be changed to the class-wide type's
      --  specific type in this case to prevent cascading errors ???

      if Is_Class_Wide_Type (Parent_Type) then
         Error_Msg_N
           ("parent of type extension must not be a class-wide type", Indic);
         goto Leave;
      end if;

      if (not Is_Package_Or_Generic_Package (Current_Scope)
           and then Nkind (Parent (N)) /= N_Generic_Subprogram_Declaration)
        or else In_Private_Part (Current_Scope)
      then
         Error_Msg_N ("invalid context for private extension", N);
      end if;

      --  Set common attributes

      Set_Is_Pure          (T, Is_Pure (Current_Scope));
      Set_Scope            (T, Current_Scope);
      Mutate_Ekind         (T, E_Record_Type_With_Private);
      Reinit_Size_Align    (T);
      Set_Default_SSO      (T);
      Set_No_Reordering    (T, No_Component_Reordering);

      Set_Etype            (T,                Parent_Base);
      Propagate_Concurrent_Flags (T, Parent_Base);

      Set_Convention       (T, Convention     (Parent_Type));
      Set_First_Rep_Item   (T, First_Rep_Item (Parent_Type));
      Set_Is_First_Subtype (T);
      Make_Class_Wide_Type (T);

      --  Set the SPARK mode from the current context

      Set_SPARK_Pragma           (T, SPARK_Mode_Pragma);
      Set_SPARK_Pragma_Inherited (T);

      if Unknown_Discriminants_Present (N) then
         Set_Discriminant_Constraint (T, No_Elist);
      end if;

      Build_Derived_Record_Type (N, Parent_Type, T);

      --  A private extension inherits the Default_Initial_Condition pragma
      --  coming from any parent type within the derivation chain.

      if Has_DIC (Parent_Type) then
         Set_Has_Inherited_DIC (T);
      end if;

      --  A private extension inherits any class-wide invariants coming from a
      --  parent type or an interface. Note that the invariant procedure of the
      --  parent type should not be inherited because the private extension may
      --  define invariants of its own.

      if Has_Inherited_Invariants (Parent_Type)
        or else Has_Inheritable_Invariants (Parent_Type)
      then
         Set_Has_Inherited_Invariants (T);

      elsif Present (Interfaces (T)) then
         Iface_Elmt := First_Elmt (Interfaces (T));
         while Present (Iface_Elmt) loop
            Iface := Node (Iface_Elmt);

            if Has_Inheritable_Invariants (Iface) then
               Set_Has_Inherited_Invariants (T);
               exit;
            end if;

            Next_Elmt (Iface_Elmt);
         end loop;
      end if;

      --  Ada 2005 (AI-443): Synchronized private extension or a rewritten
      --  synchronized formal derived type.

      if Ada_Version >= Ada_2005 and then Synchronized_Present (N) then
         Set_Is_Limited_Record (T);

         --  Formal derived type case

         if Is_Generic_Type (T) then

            --  The parent must be a tagged limited type or a synchronized
            --  interface.

            if (not Is_Tagged_Type (Parent_Type)
                 or else not Is_Limited_Type (Parent_Type))
              and then
                (not Is_Interface (Parent_Type)
                  or else not Is_Synchronized_Interface (Parent_Type))
            then
               Error_Msg_NE
                 ("parent type of & must be tagged limited or synchronized",
                  N, T);
            end if;

            --  The progenitors (if any) must be limited or synchronized
            --  interfaces.

            if Present (Interfaces (T)) then
               Iface_Elmt := First_Elmt (Interfaces (T));
               while Present (Iface_Elmt) loop
                  Iface := Node (Iface_Elmt);

                  if not Is_Limited_Interface (Iface)
                    and then not Is_Synchronized_Interface (Iface)
                  then
                     Error_Msg_NE
                       ("progenitor & must be limited or synchronized",
                        N, Iface);
                  end if;

                  Next_Elmt (Iface_Elmt);
               end loop;
            end if;

         --  Regular derived extension, the parent must be a limited or
         --  synchronized interface.

         else
            if not Is_Interface (Parent_Type)
              or else (not Is_Limited_Interface (Parent_Type)
                        and then not Is_Synchronized_Interface (Parent_Type))
            then
               Error_Msg_NE
                 ("parent type of & must be limited interface", N, T);
            end if;
         end if;

      --  A consequence of 3.9.4 (6/2) and 7.3 (7.2/2) is that a private
      --  extension with a synchronized parent must be explicitly declared
      --  synchronized, because the full view will be a synchronized type.
      --  This must be checked before the check for limited types below,
      --  to ensure that types declared limited are not allowed to extend
      --  synchronized interfaces.

      elsif Is_Interface (Parent_Type)
        and then Is_Synchronized_Interface (Parent_Type)
        and then not Synchronized_Present (N)
      then
         Error_Msg_NE
           ("private extension of& must be explicitly synchronized",
             N, Parent_Type);

      elsif Limited_Present (N) then
         Set_Is_Limited_Record (T);

         if not Is_Limited_Type (Parent_Type)
           and then
             (not Is_Interface (Parent_Type)
               or else not Is_Limited_Interface (Parent_Type))
         then
            Error_Msg_NE ("parent type& of limited extension must be limited",
              N, Parent_Type);
         end if;
      end if;

      --  Remember that its parent type has a private extension. Used to warn
      --  on public primitives of the parent type defined after its private
      --  extensions (see Check_Dispatching_Operation).

      Set_Has_Private_Extension (Parent_Type);

   <<Leave>>
      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, T);
      end if;
   end Analyze_Private_Extension_Declaration;

   ---------------------------------
   -- Analyze_Subtype_Declaration --
   ---------------------------------

   procedure Analyze_Subtype_Declaration
     (N    : Node_Id;
      Skip : Boolean := False)
   is
      Id : constant Entity_Id := Defining_Identifier (N);
      T  : Entity_Id;

   begin
      Generate_Definition (Id);
      Set_Is_Pure (Id, Is_Pure (Current_Scope));
      Reinit_Size_Align (Id);

      --  The following guard condition on Enter_Name is to handle cases where
      --  the defining identifier has already been entered into the scope but
      --  the declaration as a whole needs to be analyzed.

      --  This case in particular happens for derived enumeration types. The
      --  derived enumeration type is processed as an inserted enumeration type
      --  declaration followed by a rewritten subtype declaration. The defining
      --  identifier, however, is entered into the name scope very early in the
      --  processing of the original type declaration and therefore needs to be
      --  avoided here, when the created subtype declaration is analyzed. (See
      --  Build_Derived_Types)

      --  This also happens when the full view of a private type is derived
      --  type with constraints. In this case the entity has been introduced
      --  in the private declaration.

      --  Finally this happens in some complex cases when validity checks are
      --  enabled, where the same subtype declaration may be analyzed twice.
      --  This can happen if the subtype is created by the preanalysis of
      --  an attribute tht gives the range of a loop statement, and the loop
      --  itself appears within an if_statement that will be rewritten during
      --  expansion.

      if Skip
        or else (Present (Etype (Id))
                  and then (Is_Private_Type (Etype (Id))
                             or else Is_Task_Type (Etype (Id))
                             or else Is_Rewrite_Substitution (N)))
      then
         null;

      elsif Current_Entity (Id) = Id then
         null;

      else
         Enter_Name (Id);
      end if;

      T := Process_Subtype (Subtype_Indication (N), N, Id, 'P');

      --  Class-wide equivalent types of records with unknown discriminants
      --  involve the generation of an itype which serves as the private view
      --  of a constrained record subtype. In such cases the base type of the
      --  current subtype we are processing is the private itype. Use the full
      --  of the private itype when decorating various attributes.

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

      --  Inherit common attributes

      Set_Is_Volatile       (Id, Is_Volatile       (T));
      Set_Treat_As_Volatile (Id, Treat_As_Volatile (T));
      Set_Is_Generic_Type   (Id, Is_Generic_Type   (Base_Type (T)));
      Set_Convention        (Id, Convention        (T));

      --  If ancestor has predicates then so does the subtype, and in addition
      --  we must delay the freeze to properly arrange predicate inheritance.

      --  The Ancestor_Type test is really unpleasant, there seem to be cases
      --  in which T = ID, so the above tests and assignments do nothing???

      if Has_Predicates (T)
        or else (Present (Ancestor_Subtype (T))
                  and then Has_Predicates (Ancestor_Subtype (T)))
      then
         Set_Has_Predicates (Id);
         Set_Has_Delayed_Freeze (Id);

         --  Generated subtypes inherit the predicate function from the parent
         --  (no aspects to examine on the generated declaration).

         if not Comes_From_Source (N) then
            Mutate_Ekind (Id, Ekind (T));

            if Present (Predicate_Function (Id)) then
               null;

            elsif Present (Predicate_Function (T)) then
               Set_Predicate_Function (Id, Predicate_Function (T));

            elsif Present (Ancestor_Subtype (T))
              and then Present (Predicate_Function (Ancestor_Subtype (T)))
            then
               Set_Predicate_Function (Id,
                 Predicate_Function (Ancestor_Subtype (T)));
            end if;
         end if;
      end if;

      --  In the case where there is no constraint given in the subtype
      --  indication, Process_Subtype just returns the Subtype_Mark, so its
      --  semantic attributes must be established here.

      if Nkind (Subtype_Indication (N)) /= N_Subtype_Indication then
         Set_Etype (Id, Base_Type (T));

         case Ekind (T) is
            when Array_Kind =>
               Mutate_Ekind                  (Id, E_Array_Subtype);
               Copy_Array_Subtype_Attributes (Id, T);

            when Decimal_Fixed_Point_Kind =>
               Mutate_Ekind             (Id, E_Decimal_Fixed_Point_Subtype);
               Set_Digits_Value         (Id, Digits_Value       (T));
               Set_Delta_Value          (Id, Delta_Value        (T));
               Set_Scale_Value          (Id, Scale_Value        (T));
               Set_Small_Value          (Id, Small_Value        (T));
               Set_Scalar_Range         (Id, Scalar_Range       (T));
               Set_Machine_Radix_10     (Id, Machine_Radix_10   (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));
               Set_Is_Known_Valid       (Id, Is_Known_Valid     (T));
               Copy_RM_Size             (To => Id, From => T);

            when Enumeration_Kind =>
               Mutate_Ekind             (Id, E_Enumeration_Subtype);
               Set_First_Literal        (Id, First_Literal (Base_Type (T)));
               Set_Scalar_Range         (Id, Scalar_Range       (T));
               Set_Is_Character_Type    (Id, Is_Character_Type  (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));
               Set_Is_Known_Valid       (Id, Is_Known_Valid     (T));
               Copy_RM_Size             (To => Id, From => T);

            when Ordinary_Fixed_Point_Kind =>
               Mutate_Ekind          (Id, E_Ordinary_Fixed_Point_Subtype);
               Set_Scalar_Range         (Id, Scalar_Range       (T));
               Set_Small_Value          (Id, Small_Value        (T));
               Set_Delta_Value          (Id, Delta_Value        (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));
               Set_Is_Known_Valid       (Id, Is_Known_Valid     (T));
               Copy_RM_Size             (To => Id, From => T);

            when Float_Kind =>
               Mutate_Ekind             (Id, E_Floating_Point_Subtype);
               Set_Scalar_Range         (Id, Scalar_Range       (T));
               Set_Digits_Value         (Id, Digits_Value       (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));

               --  If the floating point type has dimensions, these will be
               --  inherited subsequently when Analyze_Dimensions is called.

            when Signed_Integer_Kind =>
               Mutate_Ekind             (Id, E_Signed_Integer_Subtype);
               Set_Scalar_Range         (Id, Scalar_Range       (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));
               Set_Is_Known_Valid       (Id, Is_Known_Valid     (T));
               Copy_RM_Size             (To => Id, From => T);

            when Modular_Integer_Kind =>
               Mutate_Ekind             (Id, E_Modular_Integer_Subtype);
               Set_Scalar_Range         (Id, Scalar_Range       (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));
               Set_Is_Known_Valid       (Id, Is_Known_Valid     (T));
               Copy_RM_Size             (To => Id, From => T);

            when Class_Wide_Kind =>
               Mutate_Ekind             (Id, E_Class_Wide_Subtype);
               Set_Class_Wide_Type      (Id, Class_Wide_Type    (T));
               Set_Cloned_Subtype       (Id, T);
               Set_Is_Tagged_Type       (Id, True);
               Set_Is_Limited_Record    (Id, Is_Limited_Record  (T));
               Set_Has_Unknown_Discriminants
                                        (Id, True);
               Set_No_Tagged_Streams_Pragma
                                        (Id, No_Tagged_Streams_Pragma (T));

               if Ekind (T) = E_Class_Wide_Subtype then
                  Set_Equivalent_Type   (Id, Equivalent_Type    (T));
               end if;

            when E_Record_Subtype
               | E_Record_Type
            =>
               Mutate_Ekind             (Id, E_Record_Subtype);

               --  Subtype declarations introduced for formal type parameters
               --  in generic instantiations should inherit the Size value of
               --  the type they rename.

               if Present (Generic_Parent_Type (N)) then
                  Copy_RM_Size (To => Id, From => T);
               end if;

               if Ekind (T) = E_Record_Subtype
                 and then Present (Cloned_Subtype (T))
               then
                  Set_Cloned_Subtype    (Id, Cloned_Subtype (T));
               else
                  Set_Cloned_Subtype    (Id, T);
               end if;

               Set_First_Entity         (Id, First_Entity       (T));
               Set_Last_Entity          (Id, Last_Entity        (T));
               Set_Has_Discriminants    (Id, Has_Discriminants  (T));
               Set_Is_Constrained       (Id, Is_Constrained     (T));
               Set_Is_Limited_Record    (Id, Is_Limited_Record  (T));
               Set_Has_Implicit_Dereference
                                        (Id, Has_Implicit_Dereference (T));
               Set_Has_Unknown_Discriminants
                                        (Id, Has_Unknown_Discriminants (T));

               if Has_Discriminants (T) then
                  Set_Discriminant_Constraint
                                        (Id, Discriminant_Constraint (T));
                  Set_Stored_Constraint_From_Discriminant_Constraint (Id);

               elsif Has_Unknown_Discriminants (Id) then
                  Set_Discriminant_Constraint (Id, No_Elist);
               end if;

               if Is_Tagged_Type (T) then
                  Set_Is_Tagged_Type    (Id, True);
                  Set_No_Tagged_Streams_Pragma
                                        (Id, No_Tagged_Streams_Pragma (T));
                  Set_Is_Abstract_Type  (Id, Is_Abstract_Type (T));
                  Set_Direct_Primitive_Operations
                                        (Id, Direct_Primitive_Operations (T));
                  Set_Class_Wide_Type   (Id, Class_Wide_Type (T));

                  if Is_Interface (T) then
                     Set_Is_Interface (Id);
                     Set_Is_Limited_Interface (Id, Is_Limited_Interface (T));
                  end if;
               end if;

            when Private_Kind =>
               Mutate_Ekind           (Id, Subtype_Kind (Ekind        (T)));
               Set_Has_Discriminants  (Id, Has_Discriminants          (T));
               Set_Is_Constrained     (Id, Is_Constrained             (T));
               Set_First_Entity       (Id, First_Entity               (T));
               Set_Last_Entity        (Id, Last_Entity                (T));
               Set_Private_Dependents (Id, New_Elmt_List);
               Set_Is_Limited_Record  (Id, Is_Limited_Record          (T));
               Set_Has_Implicit_Dereference
                                      (Id, Has_Implicit_Dereference   (T));
               Set_Has_Unknown_Discriminants
                                      (Id, Has_Unknown_Discriminants  (T));
               Set_Known_To_Have_Preelab_Init
                                      (Id, Known_To_Have_Preelab_Init (T));

               if Is_Tagged_Type (T) then
                  Set_Is_Tagged_Type              (Id);
                  Set_No_Tagged_Streams_Pragma    (Id,
                    No_Tagged_Streams_Pragma (T));
                  Set_Is_Abstract_Type            (Id, Is_Abstract_Type (T));
                  Set_Class_Wide_Type             (Id, Class_Wide_Type  (T));
                  Set_Direct_Primitive_Operations (Id,
                    Direct_Primitive_Operations (T));
               end if;

               --  In general the attributes of the subtype of a private type
               --  are the attributes of the partial view of parent. However,
               --  the full view may be a discriminated type, and the subtype
               --  must share the discriminant constraint to generate correct
               --  calls to initialization procedures.

               if Has_Discriminants (T) then
                  Set_Discriminant_Constraint
                    (Id, Discriminant_Constraint (T));
                  Set_Stored_Constraint_From_Discriminant_Constraint (Id);

               elsif Present (Full_View (T))
                 and then Has_Discriminants (Full_View (T))
               then
                  Set_Discriminant_Constraint
                    (Id, Discriminant_Constraint (Full_View (T)));
                  Set_Stored_Constraint_From_Discriminant_Constraint (Id);

                  --  This would seem semantically correct, but apparently
                  --  generates spurious errors about missing components ???

                  --  Set_Has_Discriminants (Id);
               end if;

               Prepare_Private_Subtype_Completion (Id, N);

               --  If this is the subtype of a constrained private type with
               --  discriminants that has got a full view and we also have
               --  built a completion just above, show that the completion
               --  is a clone of the full view to the back-end.

               if Has_Discriminants (T)
                  and then not Has_Unknown_Discriminants (T)
                  and then not Is_Empty_Elmt_List (Discriminant_Constraint (T))
                  and then Present (Full_View (T))
                  and then Present (Full_View (Id))
               then
                  Set_Cloned_Subtype (Full_View (Id), Full_View (T));
               end if;

            when Access_Kind =>
               Mutate_Ekind          (Id, E_Access_Subtype);
               Set_Is_Constrained    (Id, Is_Constrained        (T));
               Set_Is_Access_Constant
                                     (Id, Is_Access_Constant    (T));
               Set_Directly_Designated_Type
                                     (Id, Designated_Type       (T));
               Set_Can_Never_Be_Null (Id, Can_Never_Be_Null     (T));

               --  A Pure library_item must not contain the declaration of a
               --  named access type, except within a subprogram, generic
               --  subprogram, task unit, or protected unit, or if it has
               --  a specified Storage_Size of zero (RM05-10.2.1(15.4-15.5)).

               if Comes_From_Source (Id)
                 and then In_Pure_Unit
                 and then not In_Subprogram_Task_Protected_Unit
                 and then not No_Pool_Assigned (Id)
               then
                  Error_Msg_N
                    ("named access types not allowed in pure unit", N);
               end if;

            when Concurrent_Kind =>
               Mutate_Ekind             (Id, Subtype_Kind (Ekind   (T)));
               Set_Corresponding_Record_Type (Id,
                                         Corresponding_Record_Type (T));
               Set_First_Entity         (Id, First_Entity          (T));
               Set_First_Private_Entity (Id, First_Private_Entity  (T));
               Set_Has_Discriminants    (Id, Has_Discriminants     (T));
               Set_Is_Constrained       (Id, Is_Constrained        (T));
               Set_Is_Tagged_Type       (Id, Is_Tagged_Type        (T));
               Set_Last_Entity          (Id, Last_Entity           (T));

               if Is_Tagged_Type (T) then
                  Set_No_Tagged_Streams_Pragma
                    (Id, No_Tagged_Streams_Pragma (T));
               end if;

               if Has_Discriminants (T) then
                  Set_Discriminant_Constraint
                    (Id, Discriminant_Constraint (T));
                  Set_Stored_Constraint_From_Discriminant_Constraint (Id);
               end if;

            when Incomplete_Kind =>
               if Ada_Version >= Ada_2005 then

                  --  In Ada 2005 an incomplete type can be explicitly tagged:
                  --  propagate indication. Note that we also have to include
                  --  subtypes for Ada 2012 extended use of incomplete types.

                  Mutate_Ekind           (Id, E_Incomplete_Subtype);
                  Set_Is_Tagged_Type     (Id, Is_Tagged_Type (T));
                  Set_Private_Dependents (Id, New_Elmt_List);

                  if Is_Tagged_Type (Id) then
                     Set_No_Tagged_Streams_Pragma
                       (Id, No_Tagged_Streams_Pragma (T));
                     Set_Direct_Primitive_Operations (Id, New_Elmt_List);
                  end if;

                  --  Ada 2005 (AI-412): Decorate an incomplete subtype of an
                  --  incomplete type visible through a limited with clause.

                  if From_Limited_With (T)
                    and then Present (Non_Limited_View (T))
                  then
                     Set_From_Limited_With (Id);
                     Set_Non_Limited_View  (Id, Non_Limited_View (T));

                  --  Ada 2005 (AI-412): Add the regular incomplete subtype
                  --  to the private dependents of the original incomplete
                  --  type for future transformation.

                  else
                     Append_Elmt (Id, Private_Dependents (T));
                  end if;

               --  If the subtype name denotes an incomplete type an error
               --  was already reported by Process_Subtype.

               else
                  Set_Etype (Id, Any_Type);
               end if;

            when others =>
               raise Program_Error;
         end case;

         --  If there is no constraint in the subtype indication, the
         --  declared entity inherits predicates from the parent.

         Inherit_Predicate_Flags (Id, T);
      end if;

      --  When prefixed calls are enabled for untagged types, the subtype
      --  shares the primitive operations of its base type.

      if Extensions_Allowed then
         Set_Direct_Primitive_Operations
           (Id, Direct_Primitive_Operations (Base_Type (T)));
      end if;

      if Etype (Id) = Any_Type then
         goto Leave;
      end if;

      --  Some common processing on all types

      Set_Size_Info      (Id, T);
      Set_First_Rep_Item (Id, First_Rep_Item (T));

      --  If the parent type is a generic actual, so is the subtype. This may
      --  happen in a nested instance. Why Comes_From_Source test???

      if not Comes_From_Source (N) then
         Set_Is_Generic_Actual_Type (Id, Is_Generic_Actual_Type (T));
      end if;

      --  If this is a subtype declaration for an actual in an instance,
      --  inherit static and dynamic predicates if any.

      --  If declaration has no aspect specifications, inherit predicate
      --  info as well. Unclear how to handle the case of both specified
      --  and inherited predicates ??? Other inherited aspects, such as
      --  invariants, should be OK, but the combination with later pragmas
      --  may also require special merging.

      if Has_Predicates (T)
        and then Present (Predicate_Function (T))
        and then
          ((In_Instance and then not Comes_From_Source (N))
             or else No (Aspect_Specifications (N)))
      then
         --  Inherit Subprograms_For_Type from the full view, if present

         if Present (Full_View (T))
           and then Subprograms_For_Type (Full_View (T)) /= No_Elist
         then
            Set_Subprograms_For_Type
              (Id, Subprograms_For_Type (Full_View (T)));
         else
            Set_Subprograms_For_Type (Id, Subprograms_For_Type (T));
         end if;

         --  If the current declaration created both a private and a full view,
         --  then propagate Predicate_Function to the latter as well.

         if Present (Full_View (Id))
           and then No (Predicate_Function (Full_View (Id)))
         then
            Set_Subprograms_For_Type
              (Full_View (Id), Subprograms_For_Type (Id));
         end if;

         if Has_Static_Predicate (T) then
            Set_Has_Static_Predicate (Id);
            Set_Static_Discrete_Predicate (Id, Static_Discrete_Predicate (T));
         end if;
      end if;

      --  If the base type is a scalar type, or else if there is no
      --  constraint, the atomic flag is inherited by the subtype.
      --  Ditto for the Independent aspect.

      if Is_Scalar_Type (Id)
        or else Is_Entity_Name (Subtype_Indication (N))
      then
         Set_Is_Atomic (Id, Is_Atomic (T));
         Set_Is_Independent (Id, Is_Independent (T));
      end if;

      --  Remaining processing depends on characteristics of base type

      T := Etype (Id);

      Set_Is_Immediately_Visible   (Id, True);
      Set_Depends_On_Private       (Id, Has_Private_Component (T));
      Set_Is_Descendant_Of_Address (Id, Is_Descendant_Of_Address (T));

      if Is_Interface (T) then
         Set_Is_Interface (Id);
         Set_Is_Limited_Interface (Id, Is_Limited_Interface (T));
      end if;

      if Present (Generic_Parent_Type (N))
        and then
          (Nkind (Parent (Generic_Parent_Type (N))) /=
                                              N_Formal_Type_Declaration
            or else Nkind (Formal_Type_Definition
                            (Parent (Generic_Parent_Type (N)))) /=
                                              N_Formal_Private_Type_Definition)
      then
         if Is_Tagged_Type (Id) then

            --  If this is a generic actual subtype for a synchronized type,
            --  the primitive operations are those of the corresponding record
            --  for which there is a separate subtype declaration.

            if Is_Concurrent_Type (Id) then
               null;
            elsif Is_Class_Wide_Type (Id) then
               Derive_Subprograms (Generic_Parent_Type (N), Id, Etype (T));
            else
               Derive_Subprograms (Generic_Parent_Type (N), Id, T);
            end if;

         elsif Scope (Etype (Id)) /= Standard_Standard then
            Derive_Subprograms (Generic_Parent_Type (N), Id);
         end if;
      end if;

      if Is_Private_Type (T) and then Present (Full_View (T)) then
         Conditional_Delay (Id, Full_View (T));

      --  The subtypes of components or subcomponents of protected types
      --  do not need freeze nodes, which would otherwise appear in the
      --  wrong scope (before the freeze node for the protected type). The
      --  proper subtypes are those of the subcomponents of the corresponding
      --  record.

      elsif Ekind (Scope (Id)) /= E_Protected_Type
        and then Present (Scope (Scope (Id))) -- error defense
        and then Ekind (Scope (Scope (Id))) /= E_Protected_Type
      then
         Conditional_Delay (Id, T);
      end if;

      --  If we have a subtype of an incomplete type whose full type is a
      --  derived numeric type, we need to have a freeze node for the subtype.
      --  Otherwise gigi will complain while computing the (static) bounds of
      --  the subtype.

      if Is_Itype (T)
        and then Is_Elementary_Type (Id)
        and then Etype (Id) /= Id
      then
         declare
            Partial : constant Entity_Id :=
                        Incomplete_Or_Partial_View (First_Subtype (Id));
         begin
            if Present (Partial)
              and then Ekind (Partial) = E_Incomplete_Type
            then
               Set_Has_Delayed_Freeze (Id);
            end if;
         end;
      end if;

      --  Check that Constraint_Error is raised for a scalar subtype indication
      --  when the lower or upper bound of a non-null range lies outside the
      --  range of the type mark. Likewise for an array subtype, but check the
      --  compatibility for each index.

      if Nkind (Subtype_Indication (N)) = N_Subtype_Indication then
         declare
            Indic_Typ    : constant Entity_Id :=
                             Etype (Subtype_Mark (Subtype_Indication (N)));
            Subt_Index   : Node_Id;
            Target_Index : Node_Id;

         begin
            if Is_Scalar_Type (Etype (Id))
              and then Scalar_Range (Id) /= Scalar_Range (Indic_Typ)
            then
               Apply_Range_Check (Scalar_Range (Id), Indic_Typ);

            elsif Is_Array_Type (Etype (Id))
              and then Present (First_Index (Id))
            then
               Subt_Index   := First_Index (Id);
               Target_Index := First_Index (Indic_Typ);

               while Present (Subt_Index) loop
                  if ((Nkind (Subt_Index) in N_Expanded_Name | N_Identifier
                        and then Is_Scalar_Type (Entity (Subt_Index)))
                       or else Nkind (Subt_Index) = N_Subtype_Indication)
                    and then
                      Nkind (Scalar_Range (Etype (Subt_Index))) = N_Range
                  then
                     Apply_Range_Check
                       (Scalar_Range (Etype (Subt_Index)),
                        Etype (Target_Index),
                        Insert_Node => N);
                  end if;

                  Next_Index (Subt_Index);
                  Next_Index (Target_Index);
               end loop;
            end if;
         end;
      end if;

      Set_Optimize_Alignment_Flags (Id);
      Check_Eliminated (Id);

   <<Leave>>
      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, Id);
      end if;

      Analyze_Dimension (N);

      --  Check No_Dynamic_Sized_Objects restriction, which disallows subtype
      --  indications on composite types where the constraints are dynamic.
      --  Note that object declarations and aggregates generate implicit
      --  subtype declarations, which this covers. One special case is that the
      --  implicitly generated "=" for discriminated types includes an
      --  offending subtype declaration, which is harmless, so we ignore it
      --  here.

      if Nkind (Subtype_Indication (N)) = N_Subtype_Indication then
         declare
            Cstr : constant Node_Id := Constraint (Subtype_Indication (N));
         begin
            if Nkind (Cstr) = N_Index_Or_Discriminant_Constraint
              and then not (Is_Internal (Id)
                             and then Is_TSS (Scope (Id),
                                              TSS_Composite_Equality))
              and then not Within_Init_Proc
              and then not All_Composite_Constraints_Static (Cstr)
            then
               Check_Restriction (No_Dynamic_Sized_Objects, Cstr);
            end if;
         end;
      end if;
   end Analyze_Subtype_Declaration;

   --------------------------------
   -- Analyze_Subtype_Indication --
   --------------------------------

   procedure Analyze_Subtype_Indication (N : Node_Id) is
      T : constant Entity_Id := Subtype_Mark (N);
      R : constant Node_Id   := Range_Expression (Constraint (N));

   begin
      Analyze (T);

      if R /= Error then
         Analyze (R);
         Set_Etype (N, Etype (R));
         Resolve (R, Entity (T));
      else
         Set_Error_Posted (R);
         Set_Error_Posted (T);
      end if;
   end Analyze_Subtype_Indication;

   --------------------------
   -- Analyze_Variant_Part --
   --------------------------

   procedure Analyze_Variant_Part (N : Node_Id) is
      Discr_Name : Node_Id;
      Discr_Type : Entity_Id;

      procedure Process_Variant (A : Node_Id);
      --  Analyze declarations for a single variant

      package Analyze_Variant_Choices is
        new Generic_Analyze_Choices (Process_Variant);
      use Analyze_Variant_Choices;

      ---------------------
      -- Process_Variant --
      ---------------------

      procedure Process_Variant (A : Node_Id) is
         CL : constant Node_Id := Component_List (A);
      begin
         if not Null_Present (CL) then
            Analyze_Declarations (Component_Items (CL));

            if Present (Variant_Part (CL)) then
               Analyze (Variant_Part (CL));
            end if;
         end if;
      end Process_Variant;

   --  Start of processing for Analyze_Variant_Part

   begin
      Discr_Name := Name (N);
      Analyze (Discr_Name);

      --  If Discr_Name bad, get out (prevent cascaded errors)

      if Etype (Discr_Name) = Any_Type then
         return;
      end if;

      --  Check invalid discriminant in variant part

      if Ekind (Entity (Discr_Name)) /= E_Discriminant then
         Error_Msg_N ("invalid discriminant name in variant part", Discr_Name);
      end if;

      Discr_Type := Etype (Entity (Discr_Name));

      if not Is_Discrete_Type (Discr_Type) then
         Error_Msg_N
           ("discriminant in a variant part must be of a discrete type",
             Name (N));
         return;
      end if;

      --  Now analyze the choices, which also analyzes the declarations that
      --  are associated with each choice.

      Analyze_Choices (Variants (N), Discr_Type);

      --  Note: we used to instantiate and call Check_Choices here to check
      --  that the choices covered the discriminant, but it's too early to do
      --  that because of statically predicated subtypes, whose analysis may
      --  be deferred to their freeze point which may be as late as the freeze
      --  point of the containing record. So this call is now to be found in
      --  Freeze_Record_Declaration.

   end Analyze_Variant_Part;

   ----------------------------
   -- Array_Type_Declaration --
   ----------------------------

   procedure Array_Type_Declaration (T : in out Entity_Id; Def : Node_Id) is
      Component_Def : constant Node_Id := Component_Definition (Def);
      Component_Typ : constant Node_Id := Subtype_Indication (Component_Def);
      P             : constant Node_Id := Parent (Def);
      Element_Type  : Entity_Id;
      Implicit_Base : Entity_Id;
      Index         : Node_Id;
      Nb_Index      : Pos;
      Priv          : Entity_Id;
      Related_Id    : Entity_Id;
      Has_FLB_Index : Boolean := False;

   begin
      if Nkind (Def) = N_Constrained_Array_Definition then
         Index := First (Discrete_Subtype_Definitions (Def));
      else
         Index := First (Subtype_Marks (Def));
      end if;

      --  Find proper names for the implicit types which may be public. In case
      --  of anonymous arrays we use the name of the first object of that type
      --  as prefix.

      if No (T) then
         Related_Id := Defining_Identifier (P);
      else
         Related_Id := T;
      end if;

      Nb_Index := 1;
      while Present (Index) loop
         Analyze (Index);

         --  Test for odd case of trying to index a type by the type itself

         if Is_Entity_Name (Index) and then Entity (Index) = T then
            Error_Msg_N ("type& cannot be indexed by itself", Index);
            Set_Entity (Index, Standard_Boolean);
            Set_Etype (Index, Standard_Boolean);
         end if;

         --  Add a subtype declaration for each index of private array type
         --  declaration whose type is also private. For example:

         --     package Pkg is
         --        type Index is private;
         --     private
         --        type Table is array (Index) of ...
         --     end;

         --  This is currently required by the expander for the internally
         --  generated equality subprogram of records with variant parts in
         --  which the type of some component is such a private type. And it
         --  also helps semantic analysis in peculiar cases where the array
         --  type is referenced from an instance but not the index directly.

         if Is_Package_Or_Generic_Package (Current_Scope)
           and then In_Private_Part (Current_Scope)
           and then Has_Private_Declaration (Etype (Index))
           and then Scope (Etype (Index)) = Current_Scope
         then
            declare
               Loc   : constant Source_Ptr := Sloc (Def);
               Decl  : Node_Id;
               New_E : Entity_Id;

            begin
               New_E := Make_Temporary (Loc, 'T');
               Set_Is_Internal (New_E);

               Decl :=
                 Make_Subtype_Declaration (Loc,
                   Defining_Identifier => New_E,
                   Subtype_Indication  =>
                     New_Occurrence_Of (Etype (Index), Loc));

               Insert_Before (Parent (Def), Decl);
               Analyze (Decl);
               Set_Etype (Index, New_E);

               --  If the index is a range or a subtype indication it carries
               --  no entity. Example:

               --     package Pkg is
               --        type T is private;
               --     private
               --        type T is new Natural;
               --        Table : array (T(1) .. T(10)) of Boolean;
               --     end Pkg;

               --  Otherwise the type of the reference is its entity.

               if Is_Entity_Name (Index) then
                  Set_Entity (Index, New_E);
               end if;
            end;
         end if;

         Make_Index (Index, P, Related_Id, Nb_Index);

         --  In the case where we have an unconstrained array with an index
         --  given by a subtype_indication, this is necessarily a "fixed lower
         --  bound" index. We change the upper bound of that index to the upper
         --  bound of the index's subtype (denoted by the subtype_mark), since
         --  that upper bound was originally set by the parser to be the same
         --  as the lower bound. In truth, that upper bound corresponds to
         --  a box ("<>"), and could be set to Empty, but it's convenient to
         --  set it to the upper bound to avoid needing to add special tests
         --  in various places for an Empty upper bound, and in any case that
         --  accurately characterizes the index's range of values.

         if Nkind (Def) = N_Unconstrained_Array_Definition
           and then Nkind (Index) = N_Subtype_Indication
         then
            declare
               Index_Subtype_High_Bound : constant Entity_Id :=
                 Type_High_Bound (Entity (Subtype_Mark (Index)));
            begin
               Set_High_Bound (Range_Expression (Constraint (Index)),
                               Index_Subtype_High_Bound);

               --  Record that the array type has one or more indexes with
               --  a fixed lower bound.

               Has_FLB_Index := True;

               --  Mark the index as belonging to an array type with a fixed
               --  lower bound.

               Set_Is_Fixed_Lower_Bound_Index_Subtype (Etype (Index));
            end;
         end if;

         --  Check error of subtype with predicate for index type

         Bad_Predicated_Subtype_Use
           ("subtype& has predicate, not allowed as index subtype",
            Index, Etype (Index));

         --  Move to next index

         Next (Index);
         Nb_Index := Nb_Index + 1;
      end loop;

      --  Process subtype indication if one is present

      if Present (Component_Typ) then
         Element_Type := Process_Subtype (Component_Typ, P, Related_Id, 'C');
         Set_Etype (Component_Typ, Element_Type);

      --  Ada 2005 (AI-230): Access Definition case

      else pragma Assert (Present (Access_Definition (Component_Def)));

         --  Indicate that the anonymous access type is created by the
         --  array type declaration.

         Element_Type := Access_Definition
                           (Related_Nod => P,
                            N           => Access_Definition (Component_Def));
         Set_Is_Local_Anonymous_Access (Element_Type);

         --  Propagate the parent. This field is needed if we have to generate
         --  the master_id associated with an anonymous access to task type
         --  component (see Expand_N_Full_Type_Declaration.Build_Master)

         Copy_Parent (To => Element_Type, From => T);

         --  Ada 2005 (AI-230): In case of components that are anonymous access
         --  types the level of accessibility depends on the enclosing type
         --  declaration

         Set_Scope (Element_Type, Current_Scope); -- Ada 2005 (AI-230)

         --  Ada 2005 (AI-254)

         declare
            CD : constant Node_Id :=
                   Access_To_Subprogram_Definition
                     (Access_Definition (Component_Def));
         begin
            if Present (CD) and then Protected_Present (CD) then
               Element_Type :=
                 Replace_Anonymous_Access_To_Protected_Subprogram (Def);
            end if;
         end;
      end if;

      --  Constrained array case

      if No (T) then
         --  We might be creating more than one itype with the same Related_Id,
         --  e.g. for an array object definition and its initial value. Give
         --  them unique suffixes, because GNATprove require distinct types to
         --  have different names.

         T := Create_Itype (E_Void, P, Related_Id, 'T', Suffix_Index => -1);
      end if;

      if Nkind (Def) = N_Constrained_Array_Definition then

         if Ekind (T) in Incomplete_Or_Private_Kind then
            Reinit_Field_To_Zero (T, F_Stored_Constraint);
         else
            pragma Assert (Ekind (T) = E_Void);
         end if;

         --  Establish Implicit_Base as unconstrained base type

         Implicit_Base := Create_Itype (E_Array_Type, P, Related_Id, 'B');

         Set_Etype              (Implicit_Base, Implicit_Base);
         Set_Scope              (Implicit_Base, Current_Scope);
         Set_Has_Delayed_Freeze (Implicit_Base);
         Set_Default_SSO        (Implicit_Base);

         --  The constrained array type is a subtype of the unconstrained one

         Mutate_Ekind           (T, E_Array_Subtype);
         Reinit_Size_Align      (T);
         Set_Etype              (T, Implicit_Base);
         Set_Scope              (T, Current_Scope);
         Set_Is_Constrained     (T);
         Set_First_Index        (T,
           First (Discrete_Subtype_Definitions (Def)));
         Set_Has_Delayed_Freeze (T);

         --  Complete setup of implicit base type

         pragma Assert (not Known_Component_Size (Implicit_Base));
         Set_Component_Type (Implicit_Base, Element_Type);
         Set_Finalize_Storage_Only
                            (Implicit_Base,
                              Finalize_Storage_Only (Element_Type));
         Set_First_Index    (Implicit_Base, First_Index (T));
         Set_Has_Controlled_Component
                            (Implicit_Base,
                              Has_Controlled_Component (Element_Type)
                                or else Is_Controlled (Element_Type));
         Set_Packed_Array_Impl_Type
                            (Implicit_Base, Empty);

         Propagate_Concurrent_Flags (Implicit_Base, Element_Type);

      --  Unconstrained array case

      else pragma Assert (Nkind (Def) = N_Unconstrained_Array_Definition);

         if Ekind (T) in Incomplete_Or_Private_Kind then
            Reinit_Field_To_Zero (T, F_Stored_Constraint);
         else
            pragma Assert (Ekind (T) = E_Void);
         end if;

         Mutate_Ekind                 (T, E_Array_Type);
         Reinit_Size_Align            (T);
         Set_Etype                    (T, T);
         Set_Scope                    (T, Current_Scope);
         pragma Assert (not Known_Component_Size (T));
         Set_Is_Constrained           (T, False);
         Set_Is_Fixed_Lower_Bound_Array_Subtype
                                      (T, Has_FLB_Index);
         Set_First_Index              (T, First (Subtype_Marks (Def)));
         Set_Has_Delayed_Freeze       (T, True);
         Propagate_Concurrent_Flags   (T, Element_Type);
         Set_Has_Controlled_Component (T, Has_Controlled_Component
                                                        (Element_Type)
                                            or else
                                          Is_Controlled (Element_Type));
         Set_Finalize_Storage_Only    (T, Finalize_Storage_Only
                                                        (Element_Type));
         Set_Default_SSO              (T);
      end if;

      --  Common attributes for both cases

      Set_Component_Type (Base_Type (T), Element_Type);
      Set_Packed_Array_Impl_Type (T, Empty);

      if Aliased_Present (Component_Definition (Def)) then
         Set_Has_Aliased_Components (Etype (T));

         --  AI12-001: All aliased objects are considered to be specified as
         --  independently addressable (RM C.6(8.1/4)).

         Set_Has_Independent_Components (Etype (T));
      end if;

      --  Ada 2005 (AI-231): Propagate the null-excluding attribute to the
      --  array type to ensure that objects of this type are initialized.

      if Ada_Version >= Ada_2005 and then Can_Never_Be_Null (Element_Type) then
         Set_Can_Never_Be_Null (T);

         if Null_Exclusion_Present (Component_Definition (Def))

            --  No need to check itypes because in their case this check was
            --  done at their point of creation

           and then not Is_Itype (Element_Type)
         then
            Error_Msg_N
              ("`NOT NULL` not allowed (null already excluded)",
               Subtype_Indication (Component_Definition (Def)));
         end if;
      end if;

      Priv := Private_Component (Element_Type);

      if Present (Priv) then

         --  Check for circular definitions

         if Priv = Any_Type then
            Set_Component_Type (Etype (T), Any_Type);

         --  There is a gap in the visibility of operations on the composite
         --  type only if the component type is defined in a different scope.

         elsif Scope (Priv) = Current_Scope then
            null;

         elsif Is_Limited_Type (Priv) then
            Set_Is_Limited_Composite (Etype (T));
            Set_Is_Limited_Composite (T);
         else
            Set_Is_Private_Composite (Etype (T));
            Set_Is_Private_Composite (T);
         end if;
      end if;

      --  A syntax error in the declaration itself may lead to an empty index
      --  list, in which case do a minimal patch.

      if No (First_Index (T)) then
         Error_Msg_N ("missing index definition in array type declaration", T);

         declare
            Indexes : constant List_Id :=
                        New_List (New_Occurrence_Of (Any_Id, Sloc (T)));
         begin
            Set_Discrete_Subtype_Definitions (Def, Indexes);
            Set_First_Index (T, First (Indexes));
            return;
         end;
      end if;

      --  Create a concatenation operator for the new type. Internal array
      --  types created for packed entities do not need such, they are
      --  compatible with the user-defined type.

      if Number_Dimensions (T) = 1
        and then not Is_Packed_Array_Impl_Type (T)
      then
         New_Concatenation_Op (T);
      end if;

      --  In the case of an unconstrained array the parser has already verified
      --  that all the indexes are unconstrained but we still need to make sure
      --  that the element type is constrained.

      if not Is_Definite_Subtype (Element_Type) then
         Error_Msg_N
           ("unconstrained element type in array declaration",
            Subtype_Indication (Component_Def));

      elsif Is_Abstract_Type (Element_Type) then
         Error_Msg_N
           ("the type of a component cannot be abstract",
            Subtype_Indication (Component_Def));
      end if;

      --  There may be an invariant declared for the component type, but
      --  the construction of the component invariant checking procedure
      --  takes place during expansion.
   end Array_Type_Declaration;

   ------------------------------------------------------
   -- Replace_Anonymous_Access_To_Protected_Subprogram --
   ------------------------------------------------------

   function Replace_Anonymous_Access_To_Protected_Subprogram
     (N : Node_Id) return Entity_Id
   is
      Loc : constant Source_Ptr := Sloc (N);

      Curr_Scope : constant Scope_Stack_Entry :=
                     Scope_Stack.Table (Scope_Stack.Last);

      Anon : constant Entity_Id := Make_Temporary (Loc, 'S');

      Acc : Node_Id;
      --  Access definition in declaration

      Comp : Node_Id;
      --  Object definition or formal definition with an access definition

      Decl : Node_Id;
      --  Declaration of anonymous access to subprogram type

      Spec : Node_Id;
      --  Original specification in access to subprogram

      P : Node_Id;

   begin
      Set_Is_Internal (Anon);

      case Nkind (N) is
         when N_Constrained_Array_Definition
            | N_Component_Declaration
            | N_Unconstrained_Array_Definition
         =>
            Comp := Component_Definition (N);
            Acc  := Access_Definition (Comp);

         when N_Discriminant_Specification =>
            Comp := Discriminant_Type (N);
            Acc  := Comp;

         when N_Parameter_Specification =>
            Comp := Parameter_Type (N);
            Acc  := Comp;

         when N_Access_Function_Definition  =>
            Comp := Result_Definition (N);
            Acc  := Comp;

         when N_Object_Declaration  =>
            Comp := Object_Definition (N);
            Acc  := Comp;

         when N_Function_Specification =>
            Comp := Result_Definition (N);
            Acc  := Comp;

         when others =>
            raise Program_Error;
      end case;

      Spec := Access_To_Subprogram_Definition (Acc);

      Decl :=
        Make_Full_Type_Declaration (Loc,
          Defining_Identifier => Anon,
          Type_Definition     => Copy_Separate_Tree (Spec));

      Mark_Rewrite_Insertion (Decl);

      --  Insert the new declaration in the nearest enclosing scope. If the
      --  parent is a body and N is its return type, the declaration belongs
      --  in the enclosing scope. Likewise if N is the type of a parameter.

      P := Parent (N);

      if Nkind (N) = N_Function_Specification
        and then Nkind (P) = N_Subprogram_Body
      then
         P := Parent (P);
      elsif Nkind (N) = N_Parameter_Specification
        and then Nkind (P) in N_Subprogram_Specification
        and then Nkind (Parent (P)) = N_Subprogram_Body
      then
         P := Parent (Parent (P));
      end if;

      while Present (P) and then not Has_Declarations (P) loop
         P := Parent (P);
      end loop;

      pragma Assert (Present (P));

      if Nkind (P) = N_Package_Specification then
         Prepend (Decl, Visible_Declarations (P));
      else
         Prepend (Decl, Declarations (P));
      end if;

      --  Replace the anonymous type with an occurrence of the new declaration.
      --  In all cases the rewritten node does not have the null-exclusion
      --  attribute because (if present) it was already inherited by the
      --  anonymous entity (Anon). Thus, in case of components we do not
      --  inherit this attribute.

      if Nkind (N) = N_Parameter_Specification then
         Rewrite (Comp, New_Occurrence_Of (Anon, Loc));
         Set_Etype (Defining_Identifier (N), Anon);
         Set_Null_Exclusion_Present (N, False);

      elsif Nkind (N) = N_Object_Declaration then
         Rewrite (Comp, New_Occurrence_Of (Anon, Loc));
         Set_Etype (Defining_Identifier (N), Anon);

      elsif Nkind (N) = N_Access_Function_Definition then
         Rewrite (Comp, New_Occurrence_Of (Anon, Loc));

      elsif Nkind (N) = N_Function_Specification then
         Rewrite (Comp, New_Occurrence_Of (Anon, Loc));
         Set_Etype (Defining_Unit_Name (N), Anon);

      else
         Rewrite (Comp,
           Make_Component_Definition (Loc,
             Subtype_Indication => New_Occurrence_Of (Anon, Loc)));
      end if;

      Mark_Rewrite_Insertion (Comp);

      if Nkind (N) in N_Object_Declaration | N_Access_Function_Definition
        or else (Nkind (Parent (N)) = N_Full_Type_Declaration
                  and then not Is_Type (Current_Scope))
      then

         --  Declaration can be analyzed in the current scope.

         Analyze (Decl);

      else
         --  Temporarily remove the current scope (record or subprogram) from
         --  the stack to add the new declarations to the enclosing scope.
         --  The anonymous entity is an Itype with the proper attributes.

         Scope_Stack.Decrement_Last;
         Analyze (Decl);
         Set_Is_Itype (Anon);
         Set_Associated_Node_For_Itype (Anon, N);
         Scope_Stack.Append (Curr_Scope);
      end if;

      Mutate_Ekind (Anon, E_Anonymous_Access_Protected_Subprogram_Type);
      Set_Can_Use_Internal_Rep (Anon, not Always_Compatible_Rep_On_Target);
      return Anon;
   end Replace_Anonymous_Access_To_Protected_Subprogram;

   -------------------------------------
   -- Build_Access_Subprogram_Wrapper --
   -------------------------------------

   procedure Build_Access_Subprogram_Wrapper (Decl : Node_Id) is
      Loc      : constant Source_Ptr := Sloc (Decl);
      Id       : constant Entity_Id  := Defining_Identifier (Decl);
      Type_Def : constant Node_Id    := Type_Definition (Decl);
      Specs   :  constant List_Id    :=
                              Parameter_Specifications (Type_Def);
      Profile : constant List_Id     := New_List;
      Subp    : constant Entity_Id   := Make_Temporary (Loc, 'A');

      Contracts : constant List_Id := New_List;
      Form_P    : Node_Id;
      New_P     : Node_Id;
      New_Decl  : Node_Id;
      Spec      : Node_Id;

      procedure Replace_Type_Name (Expr : Node_Id);
      --  In the expressions for contract aspects, replace occurrences of the
      --  access type with the name of the subprogram entity, as needed, e.g.
      --  for 'Result. Aspects that are not contracts, e.g. Size or Alignment)
      --  remain on the original access type declaration. What about expanded
      --  names denoting formals, whose prefix in source is the type name ???

      -----------------------
      -- Replace_Type_Name --
      -----------------------

      procedure Replace_Type_Name (Expr : Node_Id) is
         function Process (N : Node_Id) return Traverse_Result;
         function Process (N : Node_Id) return Traverse_Result is
         begin
            if Nkind (N) = N_Attribute_Reference
              and then Is_Entity_Name (Prefix (N))
              and then Chars (Prefix (N)) = Chars (Id)
            then
               Set_Prefix (N, Make_Identifier (Sloc (N), Chars (Subp)));
            end if;

            return OK;
         end Process;

         procedure Traverse is new Traverse_Proc (Process);
      begin
         Traverse (Expr);
      end Replace_Type_Name;

   begin
      if Ekind (Id) in E_Access_Subprogram_Type
                     | E_Access_Protected_Subprogram_Type
                     | E_Anonymous_Access_Protected_Subprogram_Type
                     | E_Anonymous_Access_Subprogram_Type
      then
         null;

      else
         Error_Msg_N
           ("illegal pre/postcondition on access type", Decl);
         return;
      end if;

      declare
         Asp  : Node_Id;
         A_Id : Aspect_Id;
         Cond : Node_Id;
         Expr : Node_Id;

      begin
         Asp := First (Aspect_Specifications (Decl));
         while Present (Asp) loop
            A_Id := Get_Aspect_Id (Chars (Identifier (Asp)));
            if A_Id = Aspect_Pre or else A_Id = Aspect_Post then
               Cond := Asp;
               Expr := Expression (Cond);
               Replace_Type_Name (Expr);
               Next (Asp);

               Remove (Cond);
               Append (Cond, Contracts);

            else
               Next (Asp);
            end if;
         end loop;
      end;

      --  If there are no contract aspects, no need for a wrapper.

      if Is_Empty_List (Contracts) then
         return;
      end if;

      Form_P := First (Specs);

      while Present (Form_P) loop
         New_P := New_Copy_Tree (Form_P);
         Set_Defining_Identifier (New_P,
           Make_Defining_Identifier
            (Loc, Chars (Defining_Identifier (Form_P))));
         Append (New_P, Profile);
         Next (Form_P);
      end loop;

      --  Add to parameter specifications the access parameter that is passed
      --  in from an indirect call.

      Append (
         Make_Parameter_Specification (Loc,
           Defining_Identifier => Make_Temporary (Loc, 'P'),
           Parameter_Type  =>  New_Occurrence_Of (Id, Loc)),
         Profile);

      if Nkind (Type_Def) = N_Access_Procedure_Definition then
         Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       => Subp,
             Parameter_Specifications => Profile);
         Mutate_Ekind (Subp, E_Procedure);
      else
         Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name       => Subp,
             Parameter_Specifications => Profile,
             Result_Definition        =>
               New_Copy_Tree
                 (Result_Definition (Type_Definition (Decl))));
         Mutate_Ekind (Subp, E_Function);
      end if;

      New_Decl :=
        Make_Subprogram_Declaration (Loc, Specification => Spec);
      Set_Aspect_Specifications (New_Decl, Contracts);
      Set_Is_Wrapper (Subp);

      --  The wrapper is declared in the freezing actions to facilitate its
      --  identification and thus avoid handling it as a primitive operation
      --  of a tagged type (see Is_Access_To_Subprogram_Wrapper); otherwise it
      --  may be handled as a dispatching operation and erroneously registered
      --  in a dispatch table.

      if not GNATprove_Mode then
         Ensure_Freeze_Node (Id);
         Append_Freeze_Actions (Id, New_List (New_Decl));

      --  Under GNATprove mode there is no such problem but we do not declare
      --  it in the freezing actions since they are not analyzed under this
      --  mode.

      else
         Insert_After (Decl, New_Decl);
      end if;

      Set_Access_Subprogram_Wrapper (Designated_Type (Id), Subp);
      Build_Access_Subprogram_Wrapper_Body (Decl, New_Decl);
   end Build_Access_Subprogram_Wrapper;

   -------------------------------
   -- Build_Derived_Access_Type --
   -------------------------------

   procedure Build_Derived_Access_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id)
   is
      S : constant Node_Id := Subtype_Indication (Type_Definition (N));

      Desig_Type      : Entity_Id;
      Discr           : Entity_Id;
      Discr_Con_Elist : Elist_Id;
      Discr_Con_El    : Elmt_Id;
      Subt            : Entity_Id;

   begin
      --  Set the designated type so it is available in case this is an access
      --  to a self-referential type, e.g. a standard list type with a next
      --  pointer. Will be reset after subtype is built.

      Set_Directly_Designated_Type
        (Derived_Type, Designated_Type (Parent_Type));

      Subt := Process_Subtype (S, N);

      if Nkind (S) /= N_Subtype_Indication
        and then Subt /= Base_Type (Subt)
      then
         Mutate_Ekind (Derived_Type, E_Access_Subtype);
      end if;

      if Ekind (Derived_Type) = E_Access_Subtype then
         declare
            Pbase      : constant Entity_Id := Base_Type (Parent_Type);
            Ibase      : constant Entity_Id :=
                           Create_Itype (Ekind (Pbase), N, Derived_Type, 'B');
            Svg_Chars  : constant Name_Id   := Chars (Ibase);
            Svg_Next_E : constant Entity_Id := Next_Entity (Ibase);
            Svg_Prev_E : constant Entity_Id := Prev_Entity (Ibase);

         begin
            Copy_Node (Pbase, Ibase);

            --  Restore Itype status after Copy_Node

            Set_Is_Itype (Ibase);
            Set_Associated_Node_For_Itype (Ibase, N);

            Set_Chars             (Ibase, Svg_Chars);
            Set_Prev_Entity       (Ibase, Svg_Prev_E);
            Set_Next_Entity       (Ibase, Svg_Next_E);
            Set_Sloc              (Ibase, Sloc (Derived_Type));
            Set_Scope             (Ibase, Scope (Derived_Type));
            Set_Freeze_Node       (Ibase, Empty);
            Set_Is_Frozen         (Ibase, False);
            Set_Comes_From_Source (Ibase, False);
            Set_Is_First_Subtype  (Ibase, False);

            Set_Etype (Ibase, Pbase);
            Set_Etype (Derived_Type, Ibase);
         end;
      end if;

      Set_Directly_Designated_Type
        (Derived_Type, Designated_Type (Subt));

      Set_Is_Constrained     (Derived_Type, Is_Constrained (Subt));
      Set_Is_Access_Constant (Derived_Type, Is_Access_Constant (Parent_Type));
      Set_Size_Info          (Derived_Type, Parent_Type);
      Copy_RM_Size           (To => Derived_Type, From => Parent_Type);
      Set_Depends_On_Private (Derived_Type,
                              Has_Private_Component (Derived_Type));
      Conditional_Delay      (Derived_Type, Subt);

      if Is_Access_Subprogram_Type (Derived_Type)
        and then Is_Base_Type (Derived_Type)
      then
         Set_Can_Use_Internal_Rep
           (Derived_Type, Can_Use_Internal_Rep (Parent_Type));
      end if;

      --  Ada 2005 (AI-231): Set the null-exclusion attribute, and verify
      --  that it is not redundant.

      if Null_Exclusion_Present (Type_Definition (N)) then
         Set_Can_Never_Be_Null (Derived_Type);

      elsif Can_Never_Be_Null (Parent_Type) then
         Set_Can_Never_Be_Null (Derived_Type);
      end if;

      --  Note: we do not copy the Storage_Size_Variable, since we always go to
      --  the root type for this information.

      --  Apply range checks to discriminants for derived record case
      --  ??? THIS CODE SHOULD NOT BE HERE REALLY.

      Desig_Type := Designated_Type (Derived_Type);

      if Is_Composite_Type (Desig_Type)
        and then (not Is_Array_Type (Desig_Type))
        and then Has_Discriminants (Desig_Type)
        and then Base_Type (Desig_Type) /= Desig_Type
      then
         Discr_Con_Elist := Discriminant_Constraint (Desig_Type);
         Discr_Con_El := First_Elmt (Discr_Con_Elist);

         Discr := First_Discriminant (Base_Type (Desig_Type));
         while Present (Discr_Con_El) loop
            Apply_Range_Check (Node (Discr_Con_El), Etype (Discr));
            Next_Elmt (Discr_Con_El);
            Next_Discriminant (Discr);
         end loop;
      end if;
   end Build_Derived_Access_Type;

   ------------------------------
   -- Build_Derived_Array_Type --
   ------------------------------

   procedure Build_Derived_Array_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id)
   is
      Loc           : constant Source_Ptr := Sloc (N);
      Tdef          : constant Node_Id    := Type_Definition (N);
      Indic         : constant Node_Id    := Subtype_Indication (Tdef);
      Parent_Base   : constant Entity_Id  := Base_Type (Parent_Type);
      Implicit_Base : Entity_Id           := Empty;
      New_Indic     : Node_Id;

      procedure Make_Implicit_Base;
      --  If the parent subtype is constrained, the derived type is a subtype
      --  of an implicit base type derived from the parent base.

      ------------------------
      -- Make_Implicit_Base --
      ------------------------

      procedure Make_Implicit_Base is
      begin
         Implicit_Base :=
           Create_Itype (Ekind (Parent_Base), N, Derived_Type, 'B');

         Mutate_Ekind (Implicit_Base, Ekind (Parent_Base));
         Set_Etype (Implicit_Base, Parent_Base);

         Copy_Array_Subtype_Attributes   (Implicit_Base, Parent_Base);
         Copy_Array_Base_Type_Attributes (Implicit_Base, Parent_Base);

         Set_Has_Delayed_Freeze (Implicit_Base, True);
      end Make_Implicit_Base;

   --  Start of processing for Build_Derived_Array_Type

   begin
      if not Is_Constrained (Parent_Type) then
         if Nkind (Indic) /= N_Subtype_Indication then
            Mutate_Ekind (Derived_Type, E_Array_Type);

            Copy_Array_Subtype_Attributes   (Derived_Type, Parent_Type);
            Copy_Array_Base_Type_Attributes (Derived_Type, Parent_Type);

            Set_Has_Delayed_Freeze (Derived_Type, True);

         else
            Make_Implicit_Base;
            Set_Etype (Derived_Type, Implicit_Base);

            New_Indic :=
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => Derived_Type,
                Subtype_Indication  =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark => New_Occurrence_Of (Implicit_Base, Loc),
                    Constraint => Constraint (Indic)));

            Rewrite (N, New_Indic);
            Analyze (N);
         end if;

      else
         if Nkind (Indic) /= N_Subtype_Indication then
            Make_Implicit_Base;

            Mutate_Ekind               (Derived_Type, Ekind (Parent_Type));
            Set_Etype                     (Derived_Type, Implicit_Base);
            Copy_Array_Subtype_Attributes (Derived_Type, Parent_Type);

         else
            Error_Msg_N ("illegal constraint on constrained type", Indic);
         end if;
      end if;

      --  If parent type is not a derived type itself, and is declared in
      --  closed scope (e.g. a subprogram), then we must explicitly introduce
      --  the new type's concatenation operator since Derive_Subprograms
      --  will not inherit the parent's operator. If the parent type is
      --  unconstrained, the operator is of the unconstrained base type.

      if Number_Dimensions (Parent_Type) = 1
        and then not Is_Limited_Type (Parent_Type)
        and then not Is_Derived_Type (Parent_Type)
        and then not Is_Package_Or_Generic_Package
                       (Scope (Base_Type (Parent_Type)))
      then
         if not Is_Constrained (Parent_Type)
           and then Is_Constrained (Derived_Type)
         then
            New_Concatenation_Op (Implicit_Base);
         else
            New_Concatenation_Op (Derived_Type);
         end if;
      end if;
   end Build_Derived_Array_Type;

   -----------------------------------
   -- Build_Derived_Concurrent_Type --
   -----------------------------------

   procedure Build_Derived_Concurrent_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id)
   is
      Loc   : constant Source_Ptr := Sloc (N);
      Def   : constant Node_Id    := Type_Definition (N);
      Indic : constant Node_Id    := Subtype_Indication (Def);

      Corr_Record      : constant Entity_Id := Make_Temporary (Loc, 'C');
      Corr_Decl        : Node_Id;
      Corr_Decl_Needed : Boolean;
      --  If the derived type has fewer discriminants than its parent, the
      --  corresponding record is also a derived type, in order to account for
      --  the bound discriminants. We create a full type declaration for it in
      --  this case.

      Constraint_Present : constant Boolean :=
                                          Nkind (Indic) = N_Subtype_Indication;

      D_Constraint   : Node_Id;
      New_Constraint : Elist_Id := No_Elist;
      Old_Disc       : Entity_Id;
      New_Disc       : Entity_Id;
      New_N          : Node_Id;

   begin
      Set_Stored_Constraint (Derived_Type, No_Elist);
      Corr_Decl_Needed := False;
      Old_Disc := Empty;

      if Present (Discriminant_Specifications (N))
        and then Constraint_Present
      then
         Old_Disc := First_Discriminant (Parent_Type);
         New_Disc := First (Discriminant_Specifications (N));
         while Present (New_Disc) and then Present (Old_Disc) loop
            Next_Discriminant (Old_Disc);
            Next (New_Disc);
         end loop;
      end if;

      if Present (Old_Disc) and then Expander_Active then

         --  The new type has fewer discriminants, so we need to create a new
         --  corresponding record, which is derived from the corresponding
         --  record of the parent, and has a stored constraint that captures
         --  the values of the discriminant constraints. The corresponding
         --  record is needed only if expander is active and code generation is
         --  enabled.

         --  The type declaration for the derived corresponding record has the
         --  same discriminant part and constraints as the current declaration.
         --  Copy the unanalyzed tree to build declaration.

         Corr_Decl_Needed := True;
         New_N := Copy_Separate_Tree (N);

         Corr_Decl :=
           Make_Full_Type_Declaration (Loc,
             Defining_Identifier         => Corr_Record,
             Discriminant_Specifications =>
                Discriminant_Specifications (New_N),
             Type_Definition             =>
               Make_Derived_Type_Definition (Loc,
                 Subtype_Indication =>
                   Make_Subtype_Indication (Loc,
                     Subtype_Mark =>
                        New_Occurrence_Of
                          (Corresponding_Record_Type (Parent_Type), Loc),
                     Constraint   =>
                       Constraint
                         (Subtype_Indication (Type_Definition (New_N))))));
      end if;

      --  Copy Storage_Size and Relative_Deadline variables if task case

      if Is_Task_Type (Parent_Type) then
         Set_Storage_Size_Variable (Derived_Type,
           Storage_Size_Variable (Parent_Type));
         Set_Relative_Deadline_Variable (Derived_Type,
           Relative_Deadline_Variable (Parent_Type));
      end if;

      if Present (Discriminant_Specifications (N)) then
         Push_Scope (Derived_Type);
         Check_Or_Process_Discriminants (N, Derived_Type);

         if Constraint_Present then
            New_Constraint :=
              Expand_To_Stored_Constraint
                (Parent_Type,
                 Build_Discriminant_Constraints
                   (Parent_Type, Indic, True));
         end if;

         End_Scope;

      elsif Constraint_Present then

         --  Build an unconstrained derived type and rewrite the derived type
         --  as a subtype of this new base type.

         declare
            Parent_Base : constant Entity_Id := Base_Type (Parent_Type);
            New_Base    : Entity_Id;
            New_Decl    : Node_Id;
            New_Indic   : Node_Id;

         begin
            New_Base :=
                     Create_Itype (Ekind (Derived_Type), N, Derived_Type, 'B');

            New_Decl :=
              Make_Full_Type_Declaration (Loc,
                 Defining_Identifier => New_Base,
                 Type_Definition     =>
                   Make_Derived_Type_Definition (Loc,
                     Abstract_Present      => Abstract_Present (Def),
                     Limited_Present       => Limited_Present (Def),
                     Subtype_Indication    =>
                       New_Occurrence_Of (Parent_Base, Loc)));

            Mark_Rewrite_Insertion (New_Decl);
            Insert_Before (N, New_Decl);
            Analyze (New_Decl);

            New_Indic :=
              Make_Subtype_Indication (Loc,
                Subtype_Mark => New_Occurrence_Of (New_Base, Loc),
                Constraint   => Relocate_Node (Constraint (Indic)));

            Rewrite (N,
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => Derived_Type,
                Subtype_Indication  => New_Indic));

            Analyze (N);
            return;
         end;
      end if;

      --  By default, operations and private data are inherited from parent.
      --  However, in the presence of bound discriminants, a new corresponding
      --  record will be created, see below.

      Set_Has_Discriminants
        (Derived_Type, Has_Discriminants         (Parent_Type));
      Set_Corresponding_Record_Type
        (Derived_Type, Corresponding_Record_Type (Parent_Type));

      --  Is_Constrained is set according the parent subtype, but is set to
      --  False if the derived type is declared with new discriminants.

      Set_Is_Constrained
        (Derived_Type,
         (Is_Constrained (Parent_Type) or else Constraint_Present)
           and then not Present (Discriminant_Specifications (N)));

      if Constraint_Present then
         if not Has_Discriminants (Parent_Type) then
            Error_Msg_N ("untagged parent must have discriminants", N);

         elsif Present (Discriminant_Specifications (N)) then

            --  Verify that new discriminants are used to constrain old ones

            D_Constraint := First (Constraints (Constraint (Indic)));

            Old_Disc := First_Discriminant (Parent_Type);

            while Present (D_Constraint) loop
               if Nkind (D_Constraint) /= N_Discriminant_Association then

                  --  Positional constraint. If it is a reference to a new
                  --  discriminant, it constrains the corresponding old one.

                  if Nkind (D_Constraint) = N_Identifier then
                     New_Disc := First_Discriminant (Derived_Type);
                     while Present (New_Disc) loop
                        exit when Chars (New_Disc) = Chars (D_Constraint);
                        Next_Discriminant (New_Disc);
                     end loop;

                     if Present (New_Disc) then
                        Set_Corresponding_Discriminant (New_Disc, Old_Disc);
                     end if;
                  end if;

                  Next_Discriminant (Old_Disc);

                  --  if this is a named constraint, search by name for the old
                  --  discriminants constrained by the new one.

               elsif Nkind (Expression (D_Constraint)) = N_Identifier then

                  --  Find new discriminant with that name

                  New_Disc := First_Discriminant (Derived_Type);
                  while Present (New_Disc) loop
                     exit when
                       Chars (New_Disc) = Chars (Expression (D_Constraint));
                     Next_Discriminant (New_Disc);
                  end loop;

                  if Present (New_Disc) then

                     --  Verify that new discriminant renames some discriminant
                     --  of the parent type, and associate the new discriminant
                     --  with one or more old ones that it renames.

                     declare
                        Selector : Node_Id;

                     begin
                        Selector := First (Selector_Names (D_Constraint));
                        while Present (Selector) loop
                           Old_Disc := First_Discriminant (Parent_Type);
                           while Present (Old_Disc) loop
                              exit when Chars (Old_Disc) = Chars (Selector);
                              Next_Discriminant (Old_Disc);
                           end loop;

                           if Present (Old_Disc) then
                              Set_Corresponding_Discriminant
                                (New_Disc, Old_Disc);
                           end if;

                           Next (Selector);
                        end loop;
                     end;
                  end if;
               end if;

               Next (D_Constraint);
            end loop;

            New_Disc := First_Discriminant (Derived_Type);
            while Present (New_Disc) loop
               if No (Corresponding_Discriminant (New_Disc)) then
                  Error_Msg_NE
                    ("new discriminant& must constrain old one", N, New_Disc);

               --  If a new discriminant is used in the constraint, then its
               --  subtype must be statically compatible with the subtype of
               --  the parent discriminant (RM 3.7(15)).

               else
                  Check_Constraining_Discriminant
                    (New_Disc, Corresponding_Discriminant (New_Disc));
               end if;

               Next_Discriminant (New_Disc);
            end loop;
         end if;

      elsif Present (Discriminant_Specifications (N)) then
         Error_Msg_N
           ("missing discriminant constraint in untagged derivation", N);
      end if;

      --  The entity chain of the derived type includes the new discriminants
      --  but shares operations with the parent.

      if Present (Discriminant_Specifications (N)) then
         Old_Disc := First_Discriminant (Parent_Type);
         while Present (Old_Disc) loop
            if No (Next_Entity (Old_Disc))
              or else Ekind (Next_Entity (Old_Disc)) /= E_Discriminant
            then
               Link_Entities
                 (Last_Entity (Derived_Type), Next_Entity (Old_Disc));
               exit;
            end if;

            Next_Discriminant (Old_Disc);
         end loop;

      else
         Set_First_Entity (Derived_Type, First_Entity (Parent_Type));
         if Has_Discriminants (Parent_Type) then
            Set_Is_Constrained (Derived_Type, Is_Constrained (Parent_Type));
            Set_Discriminant_Constraint (
              Derived_Type, Discriminant_Constraint (Parent_Type));
         end if;
      end if;

      Set_Last_Entity  (Derived_Type, Last_Entity  (Parent_Type));

      Set_Has_Completion (Derived_Type);

      if Corr_Decl_Needed then
         Set_Stored_Constraint (Derived_Type, New_Constraint);
         Insert_After (N, Corr_Decl);
         Analyze (Corr_Decl);
         Set_Corresponding_Record_Type (Derived_Type, Corr_Record);
      end if;
   end Build_Derived_Concurrent_Type;

   ------------------------------------
   -- Build_Derived_Enumeration_Type --
   ------------------------------------

   procedure Build_Derived_Enumeration_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id)
   is
      function Bound_Belongs_To_Type (B : Node_Id) return Boolean;
      --  When the type declaration includes a constraint, we generate
      --  a subtype declaration of an anonymous base type, with the constraint
      --  given in the original type declaration. Conceptually, the bounds
      --  are converted to the new base type, and this conversion freezes
      --  (prematurely) that base type, when the bounds are simply literals.
      --  As a result, a representation clause for the derived type is then
      --  rejected or ignored. This procedure recognizes the simple case of
      --  literal bounds, which allows us to indicate that the conversions
      --  are not freeze points, and the subsequent representation clause
      --  can be accepted.
      --  A similar approach might be used to resolve the long-standing
      --  problem of premature freezing of derived numeric types ???

      function Bound_Belongs_To_Type (B : Node_Id) return Boolean is
      begin
         return Nkind (B) = N_Type_Conversion
           and then Is_Entity_Name (Expression (B))
           and then Ekind (Entity (Expression (B))) = E_Enumeration_Literal;
      end Bound_Belongs_To_Type;

      Loc           : constant Source_Ptr := Sloc (N);
      Def           : constant Node_Id    := Type_Definition (N);
      Indic         : constant Node_Id    := Subtype_Indication (Def);
      Implicit_Base : Entity_Id;
      Literal       : Entity_Id;
      New_Lit       : Entity_Id;
      Literals_List : List_Id;
      Type_Decl     : Node_Id;
      Hi, Lo        : Node_Id;
      Rang_Expr     : Node_Id;

   begin
      --  Since types Standard.Character and Standard.[Wide_]Wide_Character do
      --  not have explicit literals lists we need to process types derived
      --  from them specially. This is handled by Derived_Standard_Character.
      --  If the parent type is a generic type, there are no literals either,
      --  and we construct the same skeletal representation as for the generic
      --  parent type.

      if Is_Standard_Character_Type (Parent_Type) then
         Derived_Standard_Character (N, Parent_Type, Derived_Type);

      elsif Is_Generic_Type (Root_Type (Parent_Type)) then
         declare
            Lo : Node_Id;
            Hi : Node_Id;

         begin
            if Nkind (Indic) /= N_Subtype_Indication then
               Lo :=
                  Make_Attribute_Reference (Loc,
                    Attribute_Name => Name_First,
                    Prefix         => New_Occurrence_Of (Derived_Type, Loc));
               Set_Etype (Lo, Derived_Type);

               Hi :=
                  Make_Attribute_Reference (Loc,
                    Attribute_Name => Name_Last,
                    Prefix         => New_Occurrence_Of (Derived_Type, Loc));
               Set_Etype (Hi, Derived_Type);

               Set_Scalar_Range (Derived_Type,
                  Make_Range (Loc,
                    Low_Bound  => Lo,
                    High_Bound => Hi));
            else

               --   Analyze subtype indication and verify compatibility
               --   with parent type.

               if Base_Type (Process_Subtype (Indic, N)) /=
                  Base_Type (Parent_Type)
               then
                  Error_Msg_N
                    ("illegal constraint for formal discrete type", N);
               end if;
            end if;
         end;

      else
         --  If a constraint is present, analyze the bounds to catch
         --  premature usage of the derived literals.

         if Nkind (Indic) = N_Subtype_Indication
           and then Nkind (Range_Expression (Constraint (Indic))) = N_Range
         then
            Analyze (Low_Bound  (Range_Expression (Constraint (Indic))));
            Analyze (High_Bound (Range_Expression (Constraint (Indic))));
         end if;

         --  Introduce an implicit base type for the derived type even if there
         --  is no constraint attached to it, since this seems closer to the
         --  Ada semantics. Build a full type declaration tree for the derived
         --  type using the implicit base type as the defining identifier. Then
         --  build a subtype declaration tree which applies the constraint (if
         --  any) have it replace the derived type declaration.

         Literal := First_Literal (Parent_Type);
         Literals_List := New_List;
         while Present (Literal)
           and then Ekind (Literal) = E_Enumeration_Literal
         loop
            --  Literals of the derived type have the same representation as
            --  those of the parent type, but this representation can be
            --  overridden by an explicit representation clause. Indicate
            --  that there is no explicit representation given yet. These
            --  derived literals are implicit operations of the new type,
            --  and can be overridden by explicit ones.

            if Nkind (Literal) = N_Defining_Character_Literal then
               New_Lit :=
                 Make_Defining_Character_Literal (Loc, Chars (Literal));
            else
               New_Lit := Make_Defining_Identifier (Loc, Chars (Literal));
            end if;

            Mutate_Ekind             (New_Lit, E_Enumeration_Literal);
            Set_Enumeration_Pos      (New_Lit, Enumeration_Pos (Literal));
            Set_Enumeration_Rep      (New_Lit, Enumeration_Rep (Literal));
            Set_Enumeration_Rep_Expr (New_Lit, Empty);
            Set_Alias                (New_Lit, Literal);
            Set_Is_Known_Valid       (New_Lit, True);

            Append (New_Lit, Literals_List);
            Next_Literal (Literal);
         end loop;

         Implicit_Base :=
           Make_Defining_Identifier (Sloc (Derived_Type),
             Chars => New_External_Name (Chars (Derived_Type), 'B'));

         --  Indicate the proper nature of the derived type. This must be done
         --  before analysis of the literals, to recognize cases when a literal
         --  may be hidden by a previous explicit function definition (cf.
         --  c83031a).

         Mutate_Ekind (Derived_Type, E_Enumeration_Subtype);
         Set_Etype (Derived_Type, Implicit_Base);

         Type_Decl :=
           Make_Full_Type_Declaration (Loc,
             Defining_Identifier => Implicit_Base,
             Discriminant_Specifications => No_List,
             Type_Definition =>
               Make_Enumeration_Type_Definition (Loc, Literals_List));

         Mark_Rewrite_Insertion (Type_Decl);
         Insert_Before (N, Type_Decl);
         Analyze (Type_Decl);

         --  The anonymous base now has a full declaration, but this base
         --  is not a first subtype.

         Set_Is_First_Subtype (Implicit_Base, False);

         --  After the implicit base is analyzed its Etype needs to be changed
         --  to reflect the fact that it is derived from the parent type which
         --  was ignored during analysis. We also set the size at this point.

         Set_Etype (Implicit_Base, Parent_Type);

         Set_Size_Info      (Implicit_Base,                 Parent_Type);
         Set_RM_Size        (Implicit_Base, RM_Size        (Parent_Type));
         Set_First_Rep_Item (Implicit_Base, First_Rep_Item (Parent_Type));

         --  Copy other flags from parent type

         Set_Has_Non_Standard_Rep
                            (Implicit_Base, Has_Non_Standard_Rep
                                                           (Parent_Type));
         Set_Has_Pragma_Ordered
                            (Implicit_Base, Has_Pragma_Ordered
                                                           (Parent_Type));
         Set_Has_Delayed_Freeze (Implicit_Base);

         --  Process the subtype indication including a validation check on the
         --  constraint, if any. If a constraint is given, its bounds must be
         --  implicitly converted to the new type.

         if Nkind (Indic) = N_Subtype_Indication then
            declare
               R : constant Node_Id :=
                     Range_Expression (Constraint (Indic));

            begin
               if Nkind (R) = N_Range then
                  Hi := Build_Scalar_Bound
                          (High_Bound (R), Parent_Type, Implicit_Base);
                  Lo := Build_Scalar_Bound
                          (Low_Bound  (R), Parent_Type, Implicit_Base);

               else
                  --  Constraint is a Range attribute. Replace with explicit
                  --  mention of the bounds of the prefix, which must be a
                  --  subtype.

                  Analyze (Prefix (R));
                  Hi :=
                    Convert_To (Implicit_Base,
                      Make_Attribute_Reference (Loc,
                        Attribute_Name => Name_Last,
                        Prefix =>
                          New_Occurrence_Of (Entity (Prefix (R)), Loc)));

                  Lo :=
                    Convert_To (Implicit_Base,
                      Make_Attribute_Reference (Loc,
                        Attribute_Name => Name_First,
                        Prefix =>
                          New_Occurrence_Of (Entity (Prefix (R)), Loc)));
               end if;
            end;

         else
            Hi :=
              Build_Scalar_Bound
                (Type_High_Bound (Parent_Type),
                 Parent_Type, Implicit_Base);
            Lo :=
               Build_Scalar_Bound
                 (Type_Low_Bound (Parent_Type),
                  Parent_Type, Implicit_Base);
         end if;

         Rang_Expr :=
           Make_Range (Loc,
             Low_Bound  => Lo,
             High_Bound => Hi);

         --  If we constructed a default range for the case where no range
         --  was given, then the expressions in the range must not freeze
         --  since they do not correspond to expressions in the source.
         --  However, if the type inherits predicates the expressions will
         --  be elaborated earlier and must freeze.

         if (Nkind (Indic) /= N_Subtype_Indication
           or else
             (Bound_Belongs_To_Type (Lo) and then Bound_Belongs_To_Type (Hi)))
           and then not Has_Predicates (Derived_Type)
         then
            Set_Must_Not_Freeze (Lo);
            Set_Must_Not_Freeze (Hi);
            Set_Must_Not_Freeze (Rang_Expr);
         end if;

         Rewrite (N,
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => Derived_Type,
             Subtype_Indication =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark => New_Occurrence_Of (Implicit_Base, Loc),
                 Constraint =>
                   Make_Range_Constraint (Loc,
                     Range_Expression => Rang_Expr))));

         Analyze (N);

         --  Propagate the aspects from the original type declaration to the
         --  declaration of the implicit base.

         Move_Aspects (From => Original_Node (N), To => Type_Decl);

         --  Apply a range check. Since this range expression doesn't have an
         --  Etype, we have to specifically pass the Source_Typ parameter. Is
         --  this right???

         if Nkind (Indic) = N_Subtype_Indication then
            Apply_Range_Check
              (Range_Expression (Constraint (Indic)), Parent_Type,
               Source_Typ => Entity (Subtype_Mark (Indic)));
         end if;
      end if;
   end Build_Derived_Enumeration_Type;

   --------------------------------
   -- Build_Derived_Numeric_Type --
   --------------------------------

   procedure Build_Derived_Numeric_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id)
   is
      Loc           : constant Source_Ptr := Sloc (N);
      Tdef          : constant Node_Id    := Type_Definition (N);
      Indic         : constant Node_Id    := Subtype_Indication (Tdef);
      Parent_Base   : constant Entity_Id  := Base_Type (Parent_Type);
      No_Constraint : constant Boolean    := Nkind (Indic) /=
                                                  N_Subtype_Indication;
      Implicit_Base : Entity_Id;

      Lo : Node_Id;
      Hi : Node_Id;

   begin
      --  Process the subtype indication including a validation check on
      --  the constraint if any.

      Discard_Node (Process_Subtype (Indic, N));

      --  Introduce an implicit base type for the derived type even if there
      --  is no constraint attached to it, since this seems closer to the Ada
      --  semantics.

      Implicit_Base :=
        Create_Itype (Ekind (Parent_Base), N, Derived_Type, 'B');

      Set_Etype          (Implicit_Base, Parent_Base);
      Mutate_Ekind       (Implicit_Base, Ekind          (Parent_Base));
      Set_Size_Info      (Implicit_Base,                 Parent_Base);
      Set_First_Rep_Item (Implicit_Base, First_Rep_Item (Parent_Base));
      Set_Parent         (Implicit_Base, Parent (Derived_Type));
      Set_Is_Known_Valid (Implicit_Base, Is_Known_Valid (Parent_Base));
      Set_Is_Volatile    (Implicit_Base, Is_Volatile    (Parent_Base));

      --  Set RM Size for discrete type or decimal fixed-point type
      --  Ordinary fixed-point is excluded, why???

      if Is_Discrete_Type (Parent_Base)
        or else Is_Decimal_Fixed_Point_Type (Parent_Base)
      then
         Set_RM_Size (Implicit_Base, RM_Size (Parent_Base));
      end if;

      Set_Has_Delayed_Freeze (Implicit_Base);

      Lo := New_Copy_Tree (Type_Low_Bound  (Parent_Base));
      Hi := New_Copy_Tree (Type_High_Bound (Parent_Base));

      Set_Scalar_Range (Implicit_Base,
        Make_Range (Loc,
          Low_Bound  => Lo,
          High_Bound => Hi));

      if Has_Infinities (Parent_Base) then
         Set_Includes_Infinities (Scalar_Range (Implicit_Base));
      end if;

      --  The Derived_Type, which is the entity of the declaration, is a
      --  subtype of the implicit base. Its Ekind is a subtype, even in the
      --  absence of an explicit constraint.

      Set_Etype (Derived_Type, Implicit_Base);

      --  If we did not have a constraint, then the Ekind is set from the
      --  parent type (otherwise Process_Subtype has set the bounds)

      if No_Constraint then
         Mutate_Ekind (Derived_Type, Subtype_Kind (Ekind (Parent_Type)));
      end if;

      --  If we did not have a range constraint, then set the range from the
      --  parent type. Otherwise, the Process_Subtype call has set the bounds.

      if No_Constraint or else not Has_Range_Constraint (Indic) then
         Set_Scalar_Range (Derived_Type,
           Make_Range (Loc,
             Low_Bound  => New_Copy_Tree (Type_Low_Bound  (Parent_Type)),
             High_Bound => New_Copy_Tree (Type_High_Bound (Parent_Type))));
         Set_Is_Constrained (Derived_Type, Is_Constrained (Parent_Type));

         if Has_Infinities (Parent_Type) then
            Set_Includes_Infinities (Scalar_Range (Derived_Type));
         end if;

         Set_Is_Known_Valid (Derived_Type, Is_Known_Valid (Parent_Type));
      end if;

      Set_Is_Descendant_Of_Address (Derived_Type,
        Is_Descendant_Of_Address (Parent_Type));
      Set_Is_Descendant_Of_Address (Implicit_Base,
        Is_Descendant_Of_Address (Parent_Type));

      --  Set remaining type-specific fields, depending on numeric type

      if Is_Modular_Integer_Type (Parent_Type) then
         Set_Modulus (Implicit_Base, Modulus (Parent_Base));

         Set_Non_Binary_Modulus
           (Implicit_Base, Non_Binary_Modulus (Parent_Base));

         Set_Is_Known_Valid
           (Implicit_Base, Is_Known_Valid (Parent_Base));

      elsif Is_Floating_Point_Type (Parent_Type) then

         --  Digits of base type is always copied from the digits value of
         --  the parent base type, but the digits of the derived type will
         --  already have been set if there was a constraint present.

         Set_Digits_Value (Implicit_Base, Digits_Value (Parent_Base));
         Set_Float_Rep    (Implicit_Base, Float_Rep    (Parent_Base));

         if No_Constraint then
            Set_Digits_Value (Derived_Type, Digits_Value (Parent_Type));
         end if;

      elsif Is_Fixed_Point_Type (Parent_Type) then

         --  Small of base type and derived type are always copied from the
         --  parent base type, since smalls never change. The delta of the
         --  base type is also copied from the parent base type. However the
         --  delta of the derived type will have been set already if a
         --  constraint was present.

         Set_Small_Value (Derived_Type,  Small_Value (Parent_Base));
         Set_Small_Value (Implicit_Base, Small_Value (Parent_Base));
         Set_Delta_Value (Implicit_Base, Delta_Value (Parent_Base));

         if No_Constraint then
            Set_Delta_Value (Derived_Type,  Delta_Value (Parent_Type));
         end if;

         --  The scale and machine radix in the decimal case are always
         --  copied from the parent base type.

         if Is_Decimal_Fixed_Point_Type (Parent_Type) then
            Set_Scale_Value (Derived_Type,  Scale_Value (Parent_Base));
            Set_Scale_Value (Implicit_Base, Scale_Value (Parent_Base));

            Set_Machine_Radix_10
              (Derived_Type,  Machine_Radix_10 (Parent_Base));
            Set_Machine_Radix_10
              (Implicit_Base, Machine_Radix_10 (Parent_Base));

            Set_Digits_Value (Implicit_Base, Digits_Value (Parent_Base));

            if No_Constraint then
               Set_Digits_Value (Derived_Type, Digits_Value (Parent_Base));

            else
               --  the analysis of the subtype_indication sets the
               --  digits value of the derived type.

               null;
            end if;
         end if;
      end if;

      if Is_Integer_Type (Parent_Type) then
         Set_Has_Shift_Operator
           (Implicit_Base, Has_Shift_Operator (Parent_Type));
      end if;

      --  The type of the bounds is that of the parent type, and they
      --  must be converted to the derived type.

      Convert_Scalar_Bounds (N, Parent_Type, Derived_Type, Loc);

      --  The implicit_base should be frozen when the derived type is frozen,
      --  but note that it is used in the conversions of the bounds. For fixed
      --  types we delay the determination of the bounds until the proper
      --  freezing point. For other numeric types this is rejected by GCC, for
      --  reasons that are currently unclear (???), so we choose to freeze the
      --  implicit base now. In the case of integers and floating point types
      --  this is harmless because subsequent representation clauses cannot
      --  affect anything, but it is still baffling that we cannot use the
      --  same mechanism for all derived numeric types.

      --  There is a further complication: actually some representation
      --  clauses can affect the implicit base type. For example, attribute
      --  definition clauses for stream-oriented attributes need to set the
      --  corresponding TSS entries on the base type, and this normally
      --  cannot be done after the base type is frozen, so the circuitry in
      --  Sem_Ch13.New_Stream_Subprogram must account for this possibility
      --  and not use Set_TSS in this case.

      --  There are also consequences for the case of delayed representation
      --  aspects for some cases. For example, a Size aspect is delayed and
      --  should not be evaluated to the freeze point. This early freezing
      --  means that the size attribute evaluation happens too early???

      if Is_Fixed_Point_Type (Parent_Type) then
         Conditional_Delay (Implicit_Base, Parent_Type);
      else
         Freeze_Before (N, Implicit_Base);
      end if;
   end Build_Derived_Numeric_Type;

   --------------------------------
   -- Build_Derived_Private_Type --
   --------------------------------

   procedure Build_Derived_Private_Type
     (N             : Node_Id;
      Parent_Type   : Entity_Id;
      Derived_Type  : Entity_Id;
      Is_Completion : Boolean;
      Derive_Subps  : Boolean := True)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Par_Base  : constant Entity_Id  := Base_Type (Parent_Type);
      Par_Scope : constant Entity_Id  := Scope (Par_Base);
      Full_N    : constant Node_Id    := New_Copy_Tree (N);
      Full_Der  : Entity_Id           := New_Copy (Derived_Type);
      Full_P    : Entity_Id;

      function Available_Full_View (Typ : Entity_Id) return Entity_Id;
      --  Return the Full_View or Underlying_Full_View of Typ, whichever is
      --  present (they cannot be both present for the same type), or Empty.

      procedure Build_Full_Derivation;
      --  Build full derivation, i.e. derive from the full view

      procedure Copy_And_Build;
      --  Copy derived type declaration, replace parent with its full view,
      --  and build derivation

      -------------------------
      -- Available_Full_View --
      -------------------------

      function Available_Full_View (Typ : Entity_Id) return Entity_Id is
      begin
         if Present (Full_View (Typ)) then
            return Full_View (Typ);

         elsif Present (Underlying_Full_View (Typ)) then

            --  We should be called on a type with an underlying full view
            --  only by means of the recursive call made in Copy_And_Build
            --  through the first call to Build_Derived_Type, or else if
            --  the parent scope is being analyzed because we are deriving
            --  a completion.

            pragma Assert (Is_Completion or else In_Private_Part (Par_Scope));

            return Underlying_Full_View (Typ);

         else
            return Empty;
         end if;
      end Available_Full_View;

      ---------------------------
      -- Build_Full_Derivation --
      ---------------------------

      procedure Build_Full_Derivation is
      begin
         --  If parent scope is not open, install the declarations

         if not In_Open_Scopes (Par_Scope) then
            Install_Private_Declarations (Par_Scope);
            Install_Visible_Declarations (Par_Scope);
            Copy_And_Build;
            Uninstall_Declarations (Par_Scope);

         --  If parent scope is open and in another unit, and parent has a
         --  completion, then the derivation is taking place in the visible
         --  part of a child unit. In that case retrieve the full view of
         --  the parent momentarily.

         elsif not In_Same_Source_Unit (N, Parent_Type)
           and then Present (Full_View (Parent_Type))
         then
            Full_P := Full_View (Parent_Type);
            Exchange_Declarations (Parent_Type);
            Copy_And_Build;
            Exchange_Declarations (Full_P);

         --  Otherwise it is a local derivation

         else
            Copy_And_Build;
         end if;
      end Build_Full_Derivation;

      --------------------
      -- Copy_And_Build --
      --------------------

      procedure Copy_And_Build is
         Full_Parent : Entity_Id := Parent_Type;

      begin
         --  If the parent is itself derived from another private type,
         --  installing the private declarations has not affected its
         --  privacy status, so use its own full view explicitly.

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

         --  If the full view is itself derived from another private type
         --  and has got an underlying full view, and this is done for a
         --  completion, i.e. to build the underlying full view of the type,
         --  then use this underlying full view. We cannot do that if this
         --  is not a completion, i.e. to build the full view of the type,
         --  because this would break the privacy of the parent type, except
         --  if the parent scope is being analyzed because we are deriving a
         --  completion.

         if Is_Private_Type (Full_Parent)
           and then Present (Underlying_Full_View (Full_Parent))
           and then (Is_Completion or else In_Private_Part (Par_Scope))
         then
            Full_Parent := Underlying_Full_View (Full_Parent);
         end if;

         --  For private, record, concurrent, access and almost all enumeration
         --  types, the derivation from the full view requires a fully-fledged
         --  declaration. In the other cases, just use an itype.

         if Is_Private_Type (Full_Parent)
           or else Is_Record_Type (Full_Parent)
           or else Is_Concurrent_Type (Full_Parent)
           or else Is_Access_Type (Full_Parent)
           or else
             (Is_Enumeration_Type (Full_Parent)
               and then not Is_Standard_Character_Type (Full_Parent)
               and then not Is_Generic_Type (Root_Type (Full_Parent)))
         then
            --  Copy and adjust declaration to provide a completion for what
            --  is originally a private declaration. Indicate that full view
            --  is internally generated.

            Set_Comes_From_Source (Full_N, False);
            Set_Comes_From_Source (Full_Der, False);
            Set_Parent (Full_Der, Full_N);
            Set_Defining_Identifier (Full_N, Full_Der);

            --  If there are no constraints, adjust the subtype mark

            if Nkind (Subtype_Indication (Type_Definition (Full_N))) /=
                                                       N_Subtype_Indication
            then
               Set_Subtype_Indication
                 (Type_Definition (Full_N),
                  New_Occurrence_Of (Full_Parent, Sloc (Full_N)));
            end if;

            Insert_After (N, Full_N);

            --  Build full view of derived type from full view of parent which
            --  is now installed. Subprograms have been derived on the partial
            --  view, the completion does not derive them anew.

            if Is_Record_Type (Full_Parent) then

               --  If parent type is tagged, the completion inherits the proper
               --  primitive operations.

               if Is_Tagged_Type (Parent_Type) then
                  Build_Derived_Record_Type
                    (Full_N, Full_Parent, Full_Der, Derive_Subps);
               else
                  Build_Derived_Record_Type
                    (Full_N, Full_Parent, Full_Der, Derive_Subps => False);
               end if;

            else
               --  If the parent type is private, this is not a completion and
               --  we build the full derivation recursively as a completion.

               Build_Derived_Type
                 (Full_N, Full_Parent, Full_Der,
                  Is_Completion => Is_Private_Type (Full_Parent),
                  Derive_Subps => False);
            end if;

            --  The full declaration has been introduced into the tree and
            --  processed in the step above. It should not be analyzed again
            --  (when encountered later in the current list of declarations)
            --  to prevent spurious name conflicts. The full entity remains
            --  invisible.

            Set_Analyzed (Full_N);

         else
            Full_Der :=
              Make_Defining_Identifier (Sloc (Derived_Type),
                Chars => Chars (Derived_Type));
            Set_Is_Itype (Full_Der);
            Set_Associated_Node_For_Itype (Full_Der, N);
            Set_Parent (Full_Der, N);
            Build_Derived_Type
              (N, Full_Parent, Full_Der,
               Is_Completion => False, Derive_Subps => False);
         end if;

         Set_Has_Private_Declaration (Full_Der);
         Set_Has_Private_Declaration (Derived_Type);

         Set_Scope                (Full_Der, Scope (Derived_Type));
         Set_Is_First_Subtype     (Full_Der, Is_First_Subtype (Derived_Type));
         Set_Has_Size_Clause      (Full_Der, False);
         Set_Has_Alignment_Clause (Full_Der, False);
         Set_Has_Delayed_Freeze   (Full_Der);
         Set_Is_Frozen            (Full_Der, False);
         Set_Freeze_Node          (Full_Der, Empty);
         Set_Depends_On_Private   (Full_Der, Has_Private_Component (Full_Der));
         Set_Is_Public            (Full_Der, Is_Public (Derived_Type));

         --  The convention on the base type may be set in the private part
         --  and not propagated to the subtype until later, so we obtain the
         --  convention from the base type of the parent.

         Set_Convention (Full_Der, Convention (Base_Type (Full_Parent)));
      end Copy_And_Build;

   --  Start of processing for Build_Derived_Private_Type

   begin
      if Is_Tagged_Type (Parent_Type) then
         Full_P := Full_View (Parent_Type);

         --  A type extension of a type with unknown discriminants is an
         --  indefinite type that the back-end cannot handle directly.
         --  We treat it as a private type, and build a completion that is
         --  derived from the full view of the parent, and hopefully has
         --  known discriminants.

         --  If the full view of the parent type has an underlying record view,
         --  use it to generate the underlying record view of this derived type
         --  (required for chains of derivations with unknown discriminants).

         --  Minor optimization: we avoid the generation of useless underlying
         --  record view entities if the private type declaration has unknown
         --  discriminants but its corresponding full view has no
         --  discriminants.

         if Has_Unknown_Discriminants (Parent_Type)
           and then Present (Full_P)
           and then (Has_Discriminants (Full_P)
                      or else Present (Underlying_Record_View (Full_P)))
           and then not In_Open_Scopes (Par_Scope)
           and then Expander_Active
         then
            declare
               Full_Der : constant Entity_Id := Make_Temporary (Loc, 'T');
               New_Ext  : constant Node_Id :=
                            Copy_Separate_Tree
                              (Record_Extension_Part (Type_Definition (N)));
               Decl     : Node_Id;

            begin
               Build_Derived_Record_Type
                 (N, Parent_Type, Derived_Type, Derive_Subps);

               --  Build anonymous completion, as a derivation from the full
               --  view of the parent. This is not a completion in the usual
               --  sense, because the current type is not private.

               Decl :=
                 Make_Full_Type_Declaration (Loc,
                   Defining_Identifier => Full_Der,
                   Type_Definition     =>
                     Make_Derived_Type_Definition (Loc,
                       Subtype_Indication =>
                         New_Copy_Tree
                           (Subtype_Indication (Type_Definition (N))),
                       Record_Extension_Part => New_Ext));

               --  If the parent type has an underlying record view, use it
               --  here to build the new underlying record view.

               if Present (Underlying_Record_View (Full_P)) then
                  pragma Assert
                    (Nkind (Subtype_Indication (Type_Definition (Decl)))
                       = N_Identifier);
                  Set_Entity (Subtype_Indication (Type_Definition (Decl)),
                    Underlying_Record_View (Full_P));
               end if;

               Install_Private_Declarations (Par_Scope);
               Install_Visible_Declarations (Par_Scope);
               Insert_Before (N, Decl);

               --  Mark entity as an underlying record view before analysis,
               --  to avoid generating the list of its primitive operations
               --  (which is not really required for this entity) and thus
               --  prevent spurious errors associated with missing overriding
               --  of abstract primitives (overridden only for Derived_Type).

               Mutate_Ekind (Full_Der, E_Record_Type);
               Set_Is_Underlying_Record_View (Full_Der);
               Set_Default_SSO (Full_Der);
               Set_No_Reordering (Full_Der, No_Component_Reordering);

               Analyze (Decl);

               pragma Assert (Has_Discriminants (Full_Der)
                 and then not Has_Unknown_Discriminants (Full_Der));

               Uninstall_Declarations (Par_Scope);

               --  Freeze the underlying record view, to prevent generation of
               --  useless dispatching information, which is simply shared with
               --  the real derived type.

               Set_Is_Frozen (Full_Der);

               --  If the derived type has access discriminants, create
               --  references to their anonymous types now, to prevent
               --  back-end problems when their first use is in generated
               --  bodies of primitives.

               declare
                  E : Entity_Id;

               begin
                  E := First_Entity (Full_Der);

                  while Present (E) loop
                     if Ekind (E) = E_Discriminant
                       and then Ekind (Etype (E)) = E_Anonymous_Access_Type
                     then
                        Build_Itype_Reference (Etype (E), Decl);
                     end if;

                     Next_Entity (E);
                  end loop;
               end;

               --  Set up links between real entity and underlying record view

               Set_Underlying_Record_View (Derived_Type, Base_Type (Full_Der));
               Set_Underlying_Record_View (Base_Type (Full_Der), Derived_Type);
            end;

         --  If discriminants are known, build derived record

         else
            Build_Derived_Record_Type
              (N, Parent_Type, Derived_Type, Derive_Subps);
         end if;

         return;

      elsif Has_Discriminants (Parent_Type) then

         --  Build partial view of derived type from partial view of parent.
         --  This must be done before building the full derivation because the
         --  second derivation will modify the discriminants of the first and
         --  the discriminants are chained with the rest of the components in
         --  the full derivation.

         Build_Derived_Record_Type
           (N, Parent_Type, Derived_Type, Derive_Subps);

         --  Build the full derivation if this is not the anonymous derived
         --  base type created by Build_Derived_Record_Type in the constrained
         --  case (see point 5. of its head comment) since we build it for the
         --  derived subtype.

         if Present (Available_Full_View (Parent_Type))
           and then not Is_Itype (Derived_Type)
         then
            declare
               Der_Base   : constant Entity_Id := Base_Type (Derived_Type);
               Discr      : Entity_Id;
               Last_Discr : Entity_Id;

            begin
               --  If this is not a completion, construct the implicit full
               --  view by deriving from the full view of the parent type.
               --  But if this is a completion, the derived private type
               --  being built is a full view and the full derivation can
               --  only be its underlying full view.

               Build_Full_Derivation;

               if not Is_Completion then
                  Set_Full_View (Derived_Type, Full_Der);
               else
                  Set_Underlying_Full_View (Derived_Type, Full_Der);
                  Set_Is_Underlying_Full_View (Full_Der);
               end if;

               if not Is_Base_Type (Derived_Type) then
                  Set_Full_View (Der_Base, Base_Type (Full_Der));
               end if;

               --  Copy the discriminant list from full view to the partial
               --  view (base type and its subtype). Gigi requires that the
               --  partial and full views have the same discriminants.

               --  Note that since the partial view points to discriminants
               --  in the full view, their scope will be that of the full
               --  view. This might cause some front end problems and need
               --  adjustment???

               Discr := First_Discriminant (Base_Type (Full_Der));
               Set_First_Entity (Der_Base, Discr);

               loop
                  Last_Discr := Discr;
                  Next_Discriminant (Discr);
                  exit when No (Discr);
               end loop;

               Set_Last_Entity (Der_Base, Last_Discr);
               Set_First_Entity (Derived_Type, First_Entity (Der_Base));
               Set_Last_Entity  (Derived_Type, Last_Entity  (Der_Base));
            end;
         end if;

      elsif Present (Available_Full_View (Parent_Type))
        and then Has_Discriminants (Available_Full_View (Parent_Type))
      then
         if Has_Unknown_Discriminants (Parent_Type)
           and then Nkind (Subtype_Indication (Type_Definition (N))) =
                                                         N_Subtype_Indication
         then
            Error_Msg_N
              ("cannot constrain type with unknown discriminants",
               Subtype_Indication (Type_Definition (N)));
            return;
         end if;

         --  If this is not a completion, construct the implicit full view by
         --  deriving from the full view of the parent type. But if this is a
         --  completion, the derived private type being built is a full view
         --  and the full derivation can only be its underlying full view.

         Build_Full_Derivation;

         if not Is_Completion then
            Set_Full_View (Derived_Type, Full_Der);
         else
            Set_Underlying_Full_View (Derived_Type, Full_Der);
            Set_Is_Underlying_Full_View (Full_Der);
         end if;

         --  In any case, the primitive operations are inherited from the
         --  parent type, not from the internal full view.

         Set_Etype (Base_Type (Derived_Type), Base_Type (Parent_Type));

         if Derive_Subps then
            Derive_Subprograms (Parent_Type, Derived_Type);
         end if;

         Set_Stored_Constraint (Derived_Type, No_Elist);
         Set_Is_Constrained
           (Derived_Type, Is_Constrained (Available_Full_View (Parent_Type)));

      else
         --  Untagged type, No discriminants on either view

         if Nkind (Subtype_Indication (Type_Definition (N))) =
                                                   N_Subtype_Indication
         then
            Error_Msg_N
              ("illegal constraint on type without discriminants", N);
         end if;

         if Present (Discriminant_Specifications (N))
           and then Present (Available_Full_View (Parent_Type))
           and then not Is_Tagged_Type (Available_Full_View (Parent_Type))
         then
            Error_Msg_N ("cannot add discriminants to untagged type", N);
         end if;

         Set_Stored_Constraint (Derived_Type, No_Elist);
         Set_Is_Constrained    (Derived_Type, Is_Constrained (Parent_Type));

         Set_Is_Controlled_Active
           (Derived_Type, Is_Controlled_Active     (Parent_Type));

         Set_Disable_Controlled
           (Derived_Type, Disable_Controlled       (Parent_Type));

         Set_Has_Controlled_Component
           (Derived_Type, Has_Controlled_Component (Parent_Type));

         --  Direct controlled types do not inherit Finalize_Storage_Only flag

         if not Is_Controlled (Parent_Type) then
            Set_Finalize_Storage_Only
              (Base_Type (Derived_Type), Finalize_Storage_Only (Parent_Type));
         end if;

         --  If this is not a completion, construct the implicit full view by
         --  deriving from the full view of the parent type. But if this is a
         --  completion, the derived private type being built is a full view
         --  and the full derivation can only be its underlying full view.

         --  ??? If the parent type is untagged private and its completion is
         --  tagged, this mechanism will not work because we cannot derive from
         --  the tagged full view unless we have an extension.

         if Present (Available_Full_View (Parent_Type))
           and then not Is_Tagged_Type (Available_Full_View (Parent_Type))
           and then not Error_Posted (N)
         then
            Build_Full_Derivation;

            if not Is_Completion then
               Set_Full_View (Derived_Type, Full_Der);
            else
               Set_Underlying_Full_View (Derived_Type, Full_Der);
               Set_Is_Underlying_Full_View (Full_Der);
            end if;
         end if;
      end if;

      Set_Has_Unknown_Discriminants (Derived_Type,
        Has_Unknown_Discriminants (Parent_Type));

      if Is_Private_Type (Derived_Type) then
         Set_Private_Dependents (Derived_Type, New_Elmt_List);
      end if;

      --  If the parent base type is in scope, add the derived type to its
      --  list of private dependents, because its full view may become
      --  visible subsequently (in a nested private part, a body, or in a
      --  further child unit).

      if Is_Private_Type (Par_Base) and then In_Open_Scopes (Par_Scope) then
         Append_Elmt (Derived_Type, Private_Dependents (Parent_Type));

         --  Check for unusual case where a type completed by a private
         --  derivation occurs within a package nested in a child unit, and
         --  the parent is declared in an ancestor.

         if Is_Child_Unit (Scope (Current_Scope))
           and then Is_Completion
           and then In_Private_Part (Current_Scope)
           and then Scope (Parent_Type) /= Current_Scope

           --  Note that if the parent has a completion in the private part,
           --  (which is itself a derivation from some other private type)
           --  it is that completion that is visible, there is no full view
           --  available, and no special processing is needed.

           and then Present (Full_View (Parent_Type))
         then
            --  In this case, the full view of the parent type will become
            --  visible in the body of the enclosing child, and only then will
            --  the current type be possibly non-private. Build an underlying
            --  full view that will be installed when the enclosing child body
            --  is compiled.

            if Present (Underlying_Full_View (Derived_Type)) then
               Full_Der := Underlying_Full_View (Derived_Type);
            else
               Build_Full_Derivation;
               Set_Underlying_Full_View (Derived_Type, Full_Der);
               Set_Is_Underlying_Full_View (Full_Der);
            end if;

            --  The full view will be used to swap entities on entry/exit to
            --  the body, and must appear in the entity list for the package.

            Append_Entity (Full_Der, Scope (Derived_Type));
         end if;
      end if;
   end Build_Derived_Private_Type;

   -------------------------------
   -- Build_Derived_Record_Type --
   -------------------------------

   --  1. INTRODUCTION

   --  Ideally we would like to use the same model of type derivation for
   --  tagged and untagged record types. Unfortunately this is not quite
   --  possible because the semantics of representation clauses is different
   --  for tagged and untagged records under inheritance. Consider the
   --  following:

   --     type R (...) is [tagged] record ... end record;
   --     type T (...) is new R (...) [with ...];

   --  The representation clauses for T can specify a completely different
   --  record layout from R's. Hence the same component can be placed in two
   --  very different positions in objects of type T and R. If R and T are
   --  tagged types, representation clauses for T can only specify the layout
   --  of non inherited components, thus components that are common in R and T
   --  have the same position in objects of type R and T.

   --  This has two implications. The first is that the entire tree for R's
   --  declaration needs to be copied for T in the untagged case, so that T
   --  can be viewed as a record type of its own with its own representation
   --  clauses. The second implication is the way we handle discriminants.
   --  Specifically, in the untagged case we need a way to communicate to Gigi
   --  what are the real discriminants in the record, while for the semantics
   --  we need to consider those introduced by the user to rename the
   --  discriminants in the parent type. This is handled by introducing the
   --  notion of stored discriminants. See below for more.

   --  Fortunately the way regular components are inherited can be handled in
   --  the same way in tagged and untagged types.

   --  To complicate things a bit more the private view of a private extension
   --  cannot be handled in the same way as the full view (for one thing the
   --  semantic rules are somewhat different). We will explain what differs
   --  below.

   --  2. DISCRIMINANTS UNDER INHERITANCE

   --  The semantic rules governing the discriminants of derived types are
   --  quite subtle.

   --   type Derived_Type_Name [KNOWN_DISCRIMINANT_PART] is new
   --      [abstract] Parent_Type_Name [CONSTRAINT] [RECORD_EXTENSION_PART]

   --  If parent type has discriminants, then the discriminants that are
   --  declared in the derived type are [3.4 (11)]:

   --  o The discriminants specified by a new KNOWN_DISCRIMINANT_PART, if
   --    there is one;

   --  o Otherwise, each discriminant of the parent type (implicitly declared
   --    in the same order with the same specifications). In this case, the
   --    discriminants are said to be "inherited", or if unknown in the parent
   --    are also unknown in the derived type.

   --  Furthermore if a KNOWN_DISCRIMINANT_PART is provided, then [3.7(13-18)]:

   --  o The parent subtype must be constrained;

   --  o If the parent type is not a tagged type, then each discriminant of
   --    the derived type must be used in the constraint defining a parent
   --    subtype. [Implementation note: This ensures that the new discriminant
   --    can share storage with an existing discriminant.]

   --  For the derived type each discriminant of the parent type is either
   --  inherited, constrained to equal some new discriminant of the derived
   --  type, or constrained to the value of an expression.

   --  When inherited or constrained to equal some new discriminant, the
   --  parent discriminant and the discriminant of the derived type are said
   --  to "correspond".

   --  If a discriminant of the parent type is constrained to a specific value
   --  in the derived type definition, then the discriminant is said to be
   --  "specified" by that derived type definition.

   --  3. DISCRIMINANTS IN DERIVED UNTAGGED RECORD TYPES

   --  We have spoken about stored discriminants in point 1 (introduction)
   --  above. There are two sorts of stored discriminants: implicit and
   --  explicit. As long as the derived type inherits the same discriminants as
   --  the root record type, stored discriminants are the same as regular
   --  discriminants, and are said to be implicit. However, if any discriminant
   --  in the root type was renamed in the derived type, then the derived
   --  type will contain explicit stored discriminants. Explicit stored
   --  discriminants are discriminants in addition to the semantically visible
   --  discriminants defined for the derived type. Stored discriminants are
   --  used by Gigi to figure out what are the physical discriminants in
   --  objects of the derived type (see precise definition in einfo.ads).
   --  As an example, consider the following:

   --           type R  (D1, D2, D3 : Int) is record ... end record;
   --           type T1 is new R;
   --           type T2 (X1, X2: Int) is new T1 (X2, 88, X1);
   --           type T3 is new T2;
   --           type T4 (Y : Int) is new T3 (Y, 99);

   --  The following table summarizes the discriminants and stored
   --  discriminants in R and T1 through T4:

   --   Type      Discrim     Stored Discrim  Comment
   --    R      (D1, D2, D3)   (D1, D2, D3)   Stored discrims implicit in R
   --    T1     (D1, D2, D3)   (D1, D2, D3)   Stored discrims implicit in T1
   --    T2     (X1, X2)       (D1, D2, D3)   Stored discrims EXPLICIT in T2
   --    T3     (X1, X2)       (D1, D2, D3)   Stored discrims EXPLICIT in T3
   --    T4     (Y)            (D1, D2, D3)   Stored discrims EXPLICIT in T4

   --  Field Corresponding_Discriminant (abbreviated CD below) allows us to
   --  find the corresponding discriminant in the parent type, while
   --  Original_Record_Component (abbreviated ORC below) the actual physical
   --  component that is renamed. Finally the field Is_Completely_Hidden
   --  (abbreviated ICH below) is set for all explicit stored discriminants
   --  (see einfo.ads for more info). For the above example this gives:

   --                 Discrim     CD        ORC     ICH
   --                 ^^^^^^^     ^^        ^^^     ^^^
   --                 D1 in R    empty     itself    no
   --                 D2 in R    empty     itself    no
   --                 D3 in R    empty     itself    no

   --                 D1 in T1  D1 in R    itself    no
   --                 D2 in T1  D2 in R    itself    no
   --                 D3 in T1  D3 in R    itself    no

   --                 X1 in T2  D3 in T1  D3 in T2   no
   --                 X2 in T2  D1 in T1  D1 in T2   no
   --                 D1 in T2   empty    itself    yes
   --                 D2 in T2   empty    itself    yes
   --                 D3 in T2   empty    itself    yes

   --                 X1 in T3  X1 in T2  D3 in T3   no
   --                 X2 in T3  X2 in T2  D1 in T3   no
   --                 D1 in T3   empty    itself    yes
   --                 D2 in T3   empty    itself    yes
   --                 D3 in T3   empty    itself    yes

   --                 Y  in T4  X1 in T3  D3 in T4   no
   --                 D1 in T4   empty    itself    yes
   --                 D2 in T4   empty    itself    yes
   --                 D3 in T4   empty    itself    yes

   --  4. DISCRIMINANTS IN DERIVED TAGGED RECORD TYPES

   --  Type derivation for tagged types is fairly straightforward. If no
   --  discriminants are specified by the derived type, these are inherited
   --  from the parent. No explicit stored discriminants are ever necessary.
   --  The only manipulation that is done to the tree is that of adding a
   --  _parent field with parent type and constrained to the same constraint
   --  specified for the parent in the derived type definition. For instance:

   --           type R  (D1, D2, D3 : Int) is tagged record ... end record;
   --           type T1 is new R with null record;
   --           type T2 (X1, X2: Int) is new T1 (X2, 88, X1) with null record;

   --  are changed into:

   --           type T1 (D1, D2, D3 : Int) is new R (D1, D2, D3) with record
   --              _parent : R (D1, D2, D3);
   --           end record;

   --           type T2 (X1, X2: Int) is new T1 (X2, 88, X1) with record
   --              _parent : T1 (X2, 88, X1);
   --           end record;

   --  The discriminants actually present in R, T1 and T2 as well as their CD,
   --  ORC and ICH fields are:

   --                 Discrim     CD        ORC     ICH
   --                 ^^^^^^^     ^^        ^^^     ^^^
   --                 D1 in R    empty     itself    no
   --                 D2 in R    empty     itself    no
   --                 D3 in R    empty     itself    no

   --                 D1 in T1  D1 in R    D1 in R   no
   --                 D2 in T1  D2 in R    D2 in R   no
   --                 D3 in T1  D3 in R    D3 in R   no

   --                 X1 in T2  D3 in T1   D3 in R   no
   --                 X2 in T2  D1 in T1   D1 in R   no

   --  5. FIRST TRANSFORMATION FOR DERIVED RECORDS
   --
   --  Regardless of whether we dealing with a tagged or untagged type
   --  we will transform all derived type declarations of the form
   --
   --               type T is new R (...) [with ...];
   --  or
   --               subtype S is R (...);
   --               type T is new S [with ...];
   --  into
   --               type BT is new R [with ...];
   --               subtype T is BT (...);
   --
   --  That is, the base derived type is constrained only if it has no
   --  discriminants. The reason for doing this is that GNAT's semantic model
   --  assumes that a base type with discriminants is unconstrained.
   --
   --  Note that, strictly speaking, the above transformation is not always
   --  correct. Consider for instance the following excerpt from ACVC b34011a:
   --
   --       procedure B34011A is
   --          type REC (D : integer := 0) is record
   --             I : Integer;
   --          end record;

   --          package P is
   --             type T6 is new Rec;
   --             function F return T6;
   --          end P;

   --          use P;
   --          package Q6 is
   --             type U is new T6 (Q6.F.I);                   -- ERROR: Q6.F.
   --          end Q6;
   --
   --  The definition of Q6.U is illegal. However transforming Q6.U into

   --             type BaseU is new T6;
   --             subtype U is BaseU (Q6.F.I)

   --  turns U into a legal subtype, which is incorrect. To avoid this problem
   --  we always analyze the constraint (in this case (Q6.F.I)) before applying
   --  the transformation described above.

   --  There is another instance where the above transformation is incorrect.
   --  Consider:

   --          package Pack is
   --             type Base (D : Integer) is tagged null record;
   --             procedure P (X : Base);

   --             type Der is new Base (2) with null record;
   --             procedure P (X : Der);
   --          end Pack;

   --  Then the above transformation turns this into

   --             type Der_Base is new Base with null record;
   --             --  procedure P (X : Base) is implicitly inherited here
   --             --  as procedure P (X : Der_Base).

   --             subtype Der is Der_Base (2);
   --             procedure P (X : Der);
   --             --  The overriding of P (X : Der_Base) is illegal since we
   --             --  have a parameter conformance problem.

   --  To get around this problem, after having semantically processed Der_Base
   --  and the rewritten subtype declaration for Der, we copy Der_Base field
   --  Discriminant_Constraint from Der so that when parameter conformance is
   --  checked when P is overridden, no semantic errors are flagged.

   --  6. SECOND TRANSFORMATION FOR DERIVED RECORDS

   --  Regardless of whether we are dealing with a tagged or untagged type
   --  we will transform all derived type declarations of the form

   --               type R (D1, .., Dn : ...) is [tagged] record ...;
   --               type T is new R [with ...];
   --  into
   --               type T (D1, .., Dn : ...) is new R (D1, .., Dn) [with ...];

   --  The reason for such transformation is that it allows us to implement a
   --  very clean form of component inheritance as explained below.

   --  Note that this transformation is not achieved by direct tree rewriting
   --  and manipulation, but rather by redoing the semantic actions that the
   --  above transformation will entail. This is done directly in routine
   --  Inherit_Components.

   --  7. TYPE DERIVATION AND COMPONENT INHERITANCE

   --  In both tagged and untagged derived types, regular non discriminant
   --  components are inherited in the derived type from the parent type. In
   --  the absence of discriminants component, inheritance is straightforward
   --  as components can simply be copied from the parent.

   --  If the parent has discriminants, inheriting components constrained with
   --  these discriminants requires caution. Consider the following example:

   --      type R  (D1, D2 : Positive) is [tagged] record
   --         S : String (D1 .. D2);
   --      end record;

   --      type T1                is new R        [with null record];
   --      type T2 (X : positive) is new R (1, X) [with null record];

   --  As explained in 6. above, T1 is rewritten as
   --      type T1 (D1, D2 : Positive) is new R (D1, D2) [with null record];
   --  which makes the treatment for T1 and T2 identical.

   --  What we want when inheriting S, is that references to D1 and D2 in R are
   --  replaced with references to their correct constraints, i.e. D1 and D2 in
   --  T1 and 1 and X in T2. So all R's discriminant references are replaced
   --  with either discriminant references in the derived type or expressions.
   --  This replacement is achieved as follows: before inheriting R's
   --  components, a subtype R (D1, D2) for T1 (resp. R (1, X) for T2) is
   --  created in the scope of T1 (resp. scope of T2) so that discriminants D1
   --  and D2 of T1 are visible (resp. discriminant X of T2 is visible).
   --  For T2, for instance, this has the effect of replacing String (D1 .. D2)
   --  by String (1 .. X).

   --  8. TYPE DERIVATION IN PRIVATE TYPE EXTENSIONS

   --  We explain here the rules governing private type extensions relevant to
   --  type derivation. These rules are explained on the following example:

   --      type D [(...)] is new A [(...)] with private;      <-- partial view
   --      type D [(...)] is new P [(...)] with null record;  <-- full view

   --  Type A is called the ancestor subtype of the private extension.
   --  Type P is the parent type of the full view of the private extension. It
   --  must be A or a type derived from A.

   --  The rules concerning the discriminants of private type extensions are
   --  [7.3(10-13)]:

   --  o If a private extension inherits known discriminants from the ancestor
   --    subtype, then the full view must also inherit its discriminants from
   --    the ancestor subtype and the parent subtype of the full view must be
   --    constrained if and only if the ancestor subtype is constrained.

   --  o If a partial view has unknown discriminants, then the full view may
   --    define a definite or an indefinite subtype, with or without
   --    discriminants.

   --  o If a partial view has neither known nor unknown discriminants, then
   --    the full view must define a definite subtype.

   --  o If the ancestor subtype of a private extension has constrained
   --    discriminants, then the parent subtype of the full view must impose a
   --    statically matching constraint on those discriminants.

   --  This means that only the following forms of private extensions are
   --  allowed:

   --      type D is new A with private;      <-- partial view
   --      type D is new P with null record;  <-- full view

   --  If A has no discriminants than P has no discriminants, otherwise P must
   --  inherit A's discriminants.

   --      type D is new A (...) with private;      <-- partial view
   --      type D is new P (:::) with null record;  <-- full view

   --  P must inherit A's discriminants and (...) and (:::) must statically
   --  match.

   --      subtype A is R (...);
   --      type D is new A with private;      <-- partial view
   --      type D is new P with null record;  <-- full view

   --  P must have inherited R's discriminants and must be derived from A or
   --  any of its subtypes.

   --      type D (..) is new A with private;              <-- partial view
   --      type D (..) is new P [(:::)] with null record;  <-- full view

   --  No specific constraints on P's discriminants or constraint (:::).
   --  Note that A can be unconstrained, but the parent subtype P must either
   --  be constrained or (:::) must be present.

   --      type D (..) is new A [(...)] with private;      <-- partial view
   --      type D (..) is new P [(:::)] with null record;  <-- full view

   --  P's constraints on A's discriminants must statically match those
   --  imposed by (...).

   --  9. IMPLEMENTATION OF TYPE DERIVATION FOR PRIVATE EXTENSIONS

   --  The full view of a private extension is handled exactly as described
   --  above. The model chose for the private view of a private extension is
   --  the same for what concerns discriminants (i.e. they receive the same
   --  treatment as in the tagged case). However, the private view of the
   --  private extension always inherits the components of the parent base,
   --  without replacing any discriminant reference. Strictly speaking this is
   --  incorrect. However, Gigi never uses this view to generate code so this
   --  is a purely semantic issue. In theory, a set of transformations similar
   --  to those given in 5. and 6. above could be applied to private views of
   --  private extensions to have the same model of component inheritance as
   --  for non private extensions. However, this is not done because it would
   --  further complicate private type processing. Semantically speaking, this
   --  leaves us in an uncomfortable situation. As an example consider:

   --          package Pack is
   --             type R (D : integer) is tagged record
   --                S : String (1 .. D);
   --             end record;
   --             procedure P (X : R);
   --             type T is new R (1) with private;
   --          private
   --             type T is new R (1) with null record;
   --          end;

   --  This is transformed into:

   --          package Pack is
   --             type R (D : integer) is tagged record
   --                S : String (1 .. D);
   --             end record;
   --             procedure P (X : R);
   --             type T is new R (1) with private;
   --          private
   --             type BaseT is new R with null record;
   --             subtype  T is BaseT (1);
   --          end;

   --  (strictly speaking the above is incorrect Ada)

   --  From the semantic standpoint the private view of private extension T
   --  should be flagged as constrained since one can clearly have
   --
   --             Obj : T;
   --
   --  in a unit withing Pack. However, when deriving subprograms for the
   --  private view of private extension T, T must be seen as unconstrained
   --  since T has discriminants (this is a constraint of the current
   --  subprogram derivation model). Thus, when processing the private view of
   --  a private extension such as T, we first mark T as unconstrained, we
   --  process it, we perform program derivation and just before returning from
   --  Build_Derived_Record_Type we mark T as constrained.

   --  ??? Are there are other uncomfortable cases that we will have to
   --      deal with.

   --  10. RECORD_TYPE_WITH_PRIVATE complications

   --  Types that are derived from a visible record type and have a private
   --  extension present other peculiarities. They behave mostly like private
   --  types, but if they have primitive operations defined, these will not
   --  have the proper signatures for further inheritance, because other
   --  primitive operations will use the implicit base that we define for
   --  private derivations below. This affect subprogram inheritance (see
   --  Derive_Subprograms for details). We also derive the implicit base from
   --  the base type of the full view, so that the implicit base is a record
   --  type and not another private type, This avoids infinite loops.

   procedure Build_Derived_Record_Type
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id;
      Derive_Subps : Boolean := True)
   is
      Discriminant_Specs : constant Boolean :=
                             Present (Discriminant_Specifications (N));
      Is_Tagged          : constant Boolean := Is_Tagged_Type (Parent_Type);
      Loc                : constant Source_Ptr := Sloc (N);
      Private_Extension  : constant Boolean :=
                             Nkind (N) = N_Private_Extension_Declaration;
      Assoc_List         : Elist_Id;
      Constraint_Present : Boolean;
      Constrs            : Elist_Id;
      Discrim            : Entity_Id;
      Indic              : Node_Id;
      Inherit_Discrims   : Boolean := False;
      Last_Discrim       : Entity_Id;
      New_Base           : Entity_Id;
      New_Decl           : Node_Id;
      New_Discrs         : Elist_Id;
      New_Indic          : Node_Id;
      Parent_Base        : Entity_Id;
      Save_Etype         : Entity_Id;
      Save_Discr_Constr  : Elist_Id;
      Save_Next_Entity   : Entity_Id;
      Type_Def           : Node_Id;

      Discs : Elist_Id := New_Elmt_List;
      --  An empty Discs list means that there were no constraints in the
      --  subtype indication or that there was an error processing it.

      procedure Check_Generic_Ancestors;
      --  In Ada 2005 (AI-344), the restriction that a derived tagged type
      --  cannot be declared at a deeper level than its parent type is
      --  removed. The check on derivation within a generic body is also
      --  relaxed, but there's a restriction that a derived tagged type
      --  cannot be declared in a generic body if it's derived directly
      --  or indirectly from a formal type of that generic. This applies
      --  to progenitors as well.

      -----------------------------
      -- Check_Generic_Ancestors --
      -----------------------------

      procedure Check_Generic_Ancestors is
         Ancestor_Type : Entity_Id;
         Intf_List     : List_Id;
         Intf_Name     : Node_Id;

         procedure Check_Ancestor;
         --  For parent and progenitors.

         --------------------
         -- Check_Ancestor --
         --------------------

         procedure Check_Ancestor is
         begin
            --  If the derived type does have a formal type as an ancestor
            --  then it's an error if the derived type is declared within
            --  the body of the generic unit that declares the formal type
            --  in its generic formal part. It's sufficient to check whether
            --  the ancestor type is declared inside the same generic body
            --  as the derived type (such as within a nested generic spec),
            --  in which case the derivation is legal. If the formal type is
            --  declared outside of that generic body, then it's certain
            --  that the derived type is declared within the generic body
            --  of the generic unit declaring the formal type.

            if Is_Generic_Type (Ancestor_Type)
              and then Enclosing_Generic_Body (Ancestor_Type) /=
                         Enclosing_Generic_Body (Derived_Type)
            then
               Error_Msg_NE
                 ("ancestor type& is formal type of enclosing"
                    & " generic unit (RM 3.9.1 (4/2))",
                      Indic, Ancestor_Type);
            end if;
         end Check_Ancestor;

      begin
         if Nkind (N) = N_Private_Extension_Declaration then
            Intf_List := Interface_List (N);
         else
            Intf_List := Interface_List (Type_Definition (N));
         end if;

         if Present (Enclosing_Generic_Body (Derived_Type)) then
            Ancestor_Type := Parent_Type;

            while not Is_Generic_Type (Ancestor_Type)
              and then Etype (Ancestor_Type) /= Ancestor_Type
            loop
               Ancestor_Type := Etype (Ancestor_Type);
            end loop;

            Check_Ancestor;

            if Present (Intf_List) then
               Intf_Name := First (Intf_List);
               while Present (Intf_Name) loop
                  Ancestor_Type := Entity (Intf_Name);
                  Check_Ancestor;
                  Next (Intf_Name);
               end loop;
            end if;
         end if;
      end Check_Generic_Ancestors;

   --  Start of processing for Build_Derived_Record_Type

   begin
      if Ekind (Parent_Type) = E_Record_Type_With_Private
        and then Present (Full_View (Parent_Type))
        and then Has_Discriminants (Parent_Type)
      then
         Parent_Base := Base_Type (Full_View (Parent_Type));
      else
         Parent_Base := Base_Type (Parent_Type);
      end if;

      --  If the parent type is declared as a subtype of another private
      --  type with inherited discriminants, its generated base type is
      --  itself a record subtype. To further inherit the constraint we
      --  need to use its own base to have an unconstrained type on which
      --  to apply the inherited constraint.

      if Ekind (Parent_Base) = E_Record_Subtype then
         Parent_Base := Base_Type (Parent_Base);
      end if;

      --  AI05-0115: if this is a derivation from a private type in some
      --  other scope that may lead to invisible components for the derived
      --  type, mark it accordingly.

      if Is_Private_Type (Parent_Type) then
         if Scope (Parent_Base) = Scope (Derived_Type) then
            null;

         elsif In_Open_Scopes (Scope (Parent_Base))
           and then In_Private_Part (Scope (Parent_Base))
         then
            null;

         else
            Set_Has_Private_Ancestor (Derived_Type);
         end if;

      else
         Set_Has_Private_Ancestor
           (Derived_Type, Has_Private_Ancestor (Parent_Type));
      end if;

      --  Before we start the previously documented transformations, here is
      --  little fix for size and alignment of tagged types. Normally when we
      --  derive type D from type P, we copy the size and alignment of P as the
      --  default for D, and in the absence of explicit representation clauses
      --  for D, the size and alignment are indeed the same as the parent.

      --  But this is wrong for tagged types, since fields may be added, and
      --  the default size may need to be larger, and the default alignment may
      --  need to be larger.

      --  We therefore reset the size and alignment fields in the tagged case.
      --  Note that the size and alignment will in any case be at least as
      --  large as the parent type (since the derived type has a copy of the
      --  parent type in the _parent field)

      --  The type is also marked as being tagged here, which is needed when
      --  processing components with a self-referential anonymous access type
      --  in the call to Check_Anonymous_Access_Components below. Note that
      --  this flag is also set later on for completeness.

      if Is_Tagged then
         Set_Is_Tagged_Type (Derived_Type);
         Reinit_Size_Align  (Derived_Type);
      end if;

      --  STEP 0a: figure out what kind of derived type declaration we have

      if Private_Extension then
         Type_Def := N;
         Mutate_Ekind (Derived_Type, E_Record_Type_With_Private);
         Set_Default_SSO (Derived_Type);
         Set_No_Reordering (Derived_Type, No_Component_Reordering);

      else
         Type_Def := Type_Definition (N);

         --  Ekind (Parent_Base) is not necessarily E_Record_Type since
         --  Parent_Base can be a private type or private extension. However,
         --  for tagged types with an extension the newly added fields are
         --  visible and hence the Derived_Type is always an E_Record_Type.
         --  (except that the parent may have its own private fields).
         --  For untagged types we preserve the Ekind of the Parent_Base.

         if Present (Record_Extension_Part (Type_Def)) then
            Mutate_Ekind (Derived_Type, E_Record_Type);
            Set_Default_SSO (Derived_Type);
            Set_No_Reordering (Derived_Type, No_Component_Reordering);

            --  Create internal access types for components with anonymous
            --  access types.

            if Ada_Version >= Ada_2005 then
               Check_Anonymous_Access_Components
                 (N, Derived_Type, Derived_Type,
                   Component_List (Record_Extension_Part (Type_Def)));
            end if;

         else
            Mutate_Ekind (Derived_Type, Ekind (Parent_Base));
         end if;
      end if;

      --  Indic can either be an N_Identifier if the subtype indication
      --  contains no constraint or an N_Subtype_Indication if the subtype
      --  indication has a constraint. In either case it can include an
      --  interface list.

      Indic := Subtype_Indication (Type_Def);
      Constraint_Present := (Nkind (Indic) = N_Subtype_Indication);

      --  Check that the type has visible discriminants. The type may be
      --  a private type with unknown discriminants whose full view has
      --  discriminants which are invisible.

      if Constraint_Present then
         if not Has_Discriminants (Parent_Base)
           or else
             (Has_Unknown_Discriminants (Parent_Base)
               and then Is_Private_Type (Parent_Base))
         then
            Error_Msg_N
              ("invalid constraint: type has no discriminant",
                 Constraint (Indic));

            Constraint_Present := False;
            Rewrite (Indic, New_Copy_Tree (Subtype_Mark (Indic)));

         elsif Is_Constrained (Parent_Type) then
            Error_Msg_N
               ("invalid constraint: parent type is already constrained",
                  Constraint (Indic));

            Constraint_Present := False;
            Rewrite (Indic, New_Copy_Tree (Subtype_Mark (Indic)));
         end if;
      end if;

      --  STEP 0b: If needed, apply transformation given in point 5. above

      if not Private_Extension
        and then Has_Discriminants (Parent_Type)
        and then not Discriminant_Specs
        and then (Is_Constrained (Parent_Type) or else Constraint_Present)
      then
         --  First, we must analyze the constraint (see comment in point 5.)
         --  The constraint may come from the subtype indication of the full
         --  declaration.

         if Constraint_Present then
            New_Discrs := Build_Discriminant_Constraints (Parent_Type, Indic);

         --  If there is no explicit constraint, there might be one that is
         --  inherited from a constrained parent type. In that case verify that
         --  it conforms to the constraint in the partial view. In perverse
         --  cases the parent subtypes of the partial and full view can have
         --  different constraints.

         elsif Present (Stored_Constraint (Parent_Type)) then
            New_Discrs := Stored_Constraint (Parent_Type);

         else
            New_Discrs := No_Elist;
         end if;

         if Has_Discriminants (Derived_Type)
           and then Has_Private_Declaration (Derived_Type)
           and then Present (Discriminant_Constraint (Derived_Type))
           and then Present (New_Discrs)
         then
            --  Verify that constraints of the full view statically match
            --  those given in the partial view.

            declare
               C1, C2 : Elmt_Id;

            begin
               C1 := First_Elmt (New_Discrs);
               C2 := First_Elmt (Discriminant_Constraint (Derived_Type));
               while Present (C1) and then Present (C2) loop
                  if Fully_Conformant_Expressions (Node (C1), Node (C2))
                    or else
                      (Is_OK_Static_Expression (Node (C1))
                        and then Is_OK_Static_Expression (Node (C2))
                        and then
                          Expr_Value (Node (C1)) = Expr_Value (Node (C2)))
                  then
                     null;

                  else
                     if Constraint_Present then
                        Error_Msg_N
                          ("constraint not conformant to previous declaration",
                           Node (C1));
                     else
                        Error_Msg_N
                          ("constraint of full view is incompatible "
                           & "with partial view", N);
                     end if;
                  end if;

                  Next_Elmt (C1);
                  Next_Elmt (C2);
               end loop;
            end;
         end if;

         --  Insert and analyze the declaration for the unconstrained base type

         New_Base := Create_Itype (Ekind (Derived_Type), N, Derived_Type, 'B');

         New_Decl :=
           Make_Full_Type_Declaration (Loc,
              Defining_Identifier => New_Base,
              Type_Definition     =>
                Make_Derived_Type_Definition (Loc,
                  Abstract_Present      => Abstract_Present (Type_Def),
                  Limited_Present       => Limited_Present (Type_Def),
                  Subtype_Indication    =>
                    New_Occurrence_Of (Parent_Base, Loc),
                  Record_Extension_Part =>
                    Relocate_Node (Record_Extension_Part (Type_Def)),
                  Interface_List        => Interface_List (Type_Def)));

         Set_Parent (New_Decl, Parent (N));
         Mark_Rewrite_Insertion (New_Decl);
         Insert_Before (N, New_Decl);

         --  In the extension case, make sure ancestor is frozen appropriately
         --  (see also non-discriminated case below).

         if Present (Record_Extension_Part (Type_Def))
           or else Is_Interface (Parent_Base)
         then
            Freeze_Before (New_Decl, Parent_Type);
         end if;

         --  Note that this call passes False for the Derive_Subps parameter
         --  because subprogram derivation is deferred until after creating
         --  the subtype (see below).

         Build_Derived_Type
           (New_Decl, Parent_Base, New_Base,
            Is_Completion => False, Derive_Subps => False);

         --  ??? This needs re-examination to determine whether the
         --  above call can simply be replaced by a call to Analyze.

         Set_Analyzed (New_Decl);

         --  Insert and analyze the declaration for the constrained subtype

         if Constraint_Present then
            New_Indic :=
              Make_Subtype_Indication (Loc,
                Subtype_Mark => New_Occurrence_Of (New_Base, Loc),
                Constraint   => Relocate_Node (Constraint (Indic)));

         else
            declare
               Constr_List : constant List_Id := New_List;
               C           : Elmt_Id;
               Expr        : Node_Id;

            begin
               C := First_Elmt (Discriminant_Constraint (Parent_Type));
               while Present (C) loop
                  Expr := Node (C);

                  --  It is safe here to call New_Copy_Tree since we called
                  --  Force_Evaluation on each constraint previously
                  --  in Build_Discriminant_Constraints.

                  Append (New_Copy_Tree (Expr), To => Constr_List);

                  Next_Elmt (C);
               end loop;

               New_Indic :=
                 Make_Subtype_Indication (Loc,
                   Subtype_Mark => New_Occurrence_Of (New_Base, Loc),
                   Constraint   =>
                     Make_Index_Or_Discriminant_Constraint (Loc, Constr_List));
            end;
         end if;

         Rewrite (N,
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => Derived_Type,
             Subtype_Indication  => New_Indic));

         Analyze (N);

         --  Derivation of subprograms must be delayed until the full subtype
         --  has been established, to ensure proper overriding of subprograms
         --  inherited by full types. If the derivations occurred as part of
         --  the call to Build_Derived_Type above, then the check for type
         --  conformance would fail because earlier primitive subprograms
         --  could still refer to the full type prior the change to the new
         --  subtype and hence would not match the new base type created here.
         --  Subprograms are not derived, however, when Derive_Subps is False
         --  (since otherwise there could be redundant derivations).

         if Derive_Subps then
            Derive_Subprograms (Parent_Type, Derived_Type);
         end if;

         --  For tagged types the Discriminant_Constraint of the new base itype
         --  is inherited from the first subtype so that no subtype conformance
         --  problem arise when the first subtype overrides primitive
         --  operations inherited by the implicit base type.

         if Is_Tagged then
            Set_Discriminant_Constraint
              (New_Base, Discriminant_Constraint (Derived_Type));
         end if;

         return;
      end if;

      --  If we get here Derived_Type will have no discriminants or it will be
      --  a discriminated unconstrained base type.

      --  STEP 1a: perform preliminary actions/checks for derived tagged types

      if Is_Tagged then

         --  The parent type is frozen for non-private extensions (RM 13.14(7))
         --  The declaration of a specific descendant of an interface type
         --  freezes the interface type (RM 13.14).

         if not Private_Extension or else Is_Interface (Parent_Base) then
            Freeze_Before (N, Parent_Type);
         end if;

         if Ada_Version >= Ada_2005 then
            Check_Generic_Ancestors;

         elsif Type_Access_Level (Derived_Type) /=
                 Type_Access_Level (Parent_Type)
           and then not Is_Generic_Type (Derived_Type)
         then
            if Is_Controlled (Parent_Type) then
               Error_Msg_N
                 ("controlled type must be declared at the library level",
                  Indic);
            else
               Error_Msg_N
                 ("type extension at deeper accessibility level than parent",
                  Indic);
            end if;

         else
            declare
               GB : constant Node_Id := Enclosing_Generic_Body (Derived_Type);
            begin
               if Present (GB)
                 and then GB /= Enclosing_Generic_Body (Parent_Base)
               then
                  Error_Msg_NE
                    ("parent type of& must not be outside generic body"
                       & " (RM 3.9.1(4))",
                         Indic, Derived_Type);
               end if;
            end;
         end if;
      end if;

      --  Ada 2005 (AI-251)

      if Ada_Version >= Ada_2005 and then Is_Tagged then

         --  "The declaration of a specific descendant of an interface type
         --  freezes the interface type" (RM 13.14).

         declare
            Iface : Node_Id;
         begin
            if Is_Non_Empty_List (Interface_List (Type_Def)) then
               Iface := First (Interface_List (Type_Def));
               while Present (Iface) loop
                  Freeze_Before (N, Etype (Iface));
                  Next (Iface);
               end loop;
            end if;
         end;
      end if;

      --  STEP 1b : preliminary cleanup of the full view of private types

      --  If the type is already marked as having discriminants, then it's the
      --  completion of a private type or private extension and we need to
      --  retain the discriminants from the partial view if the current
      --  declaration has Discriminant_Specifications so that we can verify
      --  conformance. However, we must remove any existing components that
      --  were inherited from the parent (and attached in Copy_And_Swap)
      --  because the full type inherits all appropriate components anyway, and
      --  we do not want the partial view's components interfering.

      if Has_Discriminants (Derived_Type) and then Discriminant_Specs then
         Discrim := First_Discriminant (Derived_Type);
         loop
            Last_Discrim := Discrim;
            Next_Discriminant (Discrim);
            exit when No (Discrim);
         end loop;

         Set_Last_Entity (Derived_Type, Last_Discrim);

      --  In all other cases wipe out the list of inherited components (even
      --  inherited discriminants), it will be properly rebuilt here.

      else
         Set_First_Entity (Derived_Type, Empty);
         Set_Last_Entity  (Derived_Type, Empty);
      end if;

      --  STEP 1c: Initialize some flags for the Derived_Type

      --  The following flags must be initialized here so that
      --  Process_Discriminants can check that discriminants of tagged types do
      --  not have a default initial value and that access discriminants are
      --  only specified for limited records. For completeness, these flags are
      --  also initialized along with all the other flags below.

      --  AI-419: Limitedness is not inherited from an interface parent, so to
      --  be limited in that case the type must be explicitly declared as
      --  limited. However, task and protected interfaces are always limited.

      if Limited_Present (Type_Def) then
         Set_Is_Limited_Record (Derived_Type);

      elsif Is_Limited_Record (Parent_Type)
        or else (Present (Full_View (Parent_Type))
                  and then Is_Limited_Record (Full_View (Parent_Type)))
      then
         if not Is_Interface (Parent_Type)
           or else Is_Concurrent_Interface (Parent_Type)
         then
            Set_Is_Limited_Record (Derived_Type);
         end if;
      end if;

      --  STEP 2a: process discriminants of derived type if any

      Push_Scope (Derived_Type);

      if Discriminant_Specs then
         Set_Has_Unknown_Discriminants (Derived_Type, False);

         --  The following call initializes fields Has_Discriminants and
         --  Discriminant_Constraint, unless we are processing the completion
         --  of a private type declaration.

         Check_Or_Process_Discriminants (N, Derived_Type);

         --  For untagged types, the constraint on the Parent_Type must be
         --  present and is used to rename the discriminants.

         if not Is_Tagged and then not Has_Discriminants (Parent_Type) then
            Error_Msg_N ("untagged parent must have discriminants", Indic);

         elsif not Is_Tagged and then not Constraint_Present then
            Error_Msg_N
              ("discriminant constraint needed for derived untagged records",
               Indic);

         --  Otherwise the parent subtype must be constrained unless we have a
         --  private extension.

         elsif not Constraint_Present
           and then not Private_Extension
           and then not Is_Constrained (Parent_Type)
         then
            Error_Msg_N
              ("unconstrained type not allowed in this context", Indic);

         elsif Constraint_Present then
            --  The following call sets the field Corresponding_Discriminant
            --  for the discriminants in the Derived_Type.

            Discs := Build_Discriminant_Constraints (Parent_Type, Indic, True);

            --  For untagged types all new discriminants must rename
            --  discriminants in the parent. For private extensions new
            --  discriminants cannot rename old ones (implied by [7.3(13)]).

            Discrim := First_Discriminant (Derived_Type);
            while Present (Discrim) loop
               if not Is_Tagged
                 and then No (Corresponding_Discriminant (Discrim))
               then
                  Error_Msg_N
                    ("new discriminants must constrain old ones", Discrim);

               elsif Private_Extension
                 and then Present (Corresponding_Discriminant (Discrim))
               then
                  Error_Msg_N
                    ("only static constraints allowed for parent"
                     & " discriminants in the partial view", Indic);
                  exit;
               end if;

               --  If a new discriminant is used in the constraint, then its
               --  subtype must be statically compatible with the subtype of
               --  the parent discriminant (RM 3.7(15)).

               if Present (Corresponding_Discriminant (Discrim)) then
                  Check_Constraining_Discriminant
                    (Discrim, Corresponding_Discriminant (Discrim));
               end if;

               Next_Discriminant (Discrim);
            end loop;

            --  Check whether the constraints of the full view statically
            --  match those imposed by the parent subtype [7.3(13)].

            if Present (Stored_Constraint (Derived_Type)) then
               declare
                  C1, C2 : Elmt_Id;

               begin
                  C1 := First_Elmt (Discs);
                  C2 := First_Elmt (Stored_Constraint (Derived_Type));
                  while Present (C1) and then Present (C2) loop
                     if not
                       Fully_Conformant_Expressions (Node (C1), Node (C2))
                     then
                        Error_Msg_N
                          ("not conformant with previous declaration",
                           Node (C1));
                     end if;

                     Next_Elmt (C1);
                     Next_Elmt (C2);
                  end loop;
               end;
            end if;
         end if;

      --  STEP 2b: No new discriminants, inherit discriminants if any

      else
         if Private_Extension then
            Set_Has_Unknown_Discriminants
              (Derived_Type,
               Has_Unknown_Discriminants (Parent_Type)
                 or else Unknown_Discriminants_Present (N));

         --  The partial view of the parent may have unknown discriminants,
         --  but if the full view has discriminants and the parent type is
         --  in scope they must be inherited.

         elsif Has_Unknown_Discriminants (Parent_Type)
           and then
            (not Has_Discriminants (Parent_Type)
              or else not In_Open_Scopes (Scope (Parent_Base)))
         then
            Set_Has_Unknown_Discriminants (Derived_Type);
         end if;

         if not Has_Unknown_Discriminants (Derived_Type)
           and then not Has_Unknown_Discriminants (Parent_Base)
           and then Has_Discriminants (Parent_Type)
         then
            Inherit_Discrims := True;
            Set_Has_Discriminants
              (Derived_Type, True);
            Set_Discriminant_Constraint
              (Derived_Type, Discriminant_Constraint (Parent_Base));
         end if;

         --  The following test is true for private types (remember
         --  transformation 5. is not applied to those) and in an error
         --  situation.

         if Constraint_Present then
            Discs := Build_Discriminant_Constraints (Parent_Type, Indic);
         end if;

         --  For now mark a new derived type as constrained only if it has no
         --  discriminants. At the end of Build_Derived_Record_Type we properly
         --  set this flag in the case of private extensions. See comments in
         --  point 9. just before body of Build_Derived_Record_Type.

         Set_Is_Constrained
           (Derived_Type,
            not (Inherit_Discrims
                  or else Has_Unknown_Discriminants (Derived_Type)));
      end if;

      --  STEP 3: initialize fields of derived type

      Set_Is_Tagged_Type    (Derived_Type, Is_Tagged);
      Set_Stored_Constraint (Derived_Type, No_Elist);

      --  Ada 2005 (AI-251): Private type-declarations can implement interfaces
      --  but cannot be interfaces

      if not Private_Extension
         and then Ekind (Derived_Type) /= E_Private_Type
         and then Ekind (Derived_Type) /= E_Limited_Private_Type
      then
         if Interface_Present (Type_Def) then
            Analyze_Interface_Declaration (Derived_Type, Type_Def);
         end if;

         Set_Interfaces (Derived_Type, No_Elist);
      end if;

      --  Fields inherited from the Parent_Type

      Set_Has_Specified_Layout
        (Derived_Type, Has_Specified_Layout     (Parent_Type));
      Set_Is_Limited_Composite
        (Derived_Type, Is_Limited_Composite     (Parent_Type));
      Set_Is_Private_Composite
        (Derived_Type, Is_Private_Composite     (Parent_Type));

      if Is_Tagged_Type (Parent_Type) then
         Set_No_Tagged_Streams_Pragma
           (Derived_Type, No_Tagged_Streams_Pragma (Parent_Type));
      end if;

      --  Fields inherited from the Parent_Base

      Set_Has_Controlled_Component
        (Derived_Type, Has_Controlled_Component (Parent_Base));
      Set_Has_Non_Standard_Rep
        (Derived_Type, Has_Non_Standard_Rep     (Parent_Base));
      Set_Has_Primitive_Operations
        (Derived_Type, Has_Primitive_Operations (Parent_Base));

      --  Set fields for private derived types

      if Is_Private_Type (Derived_Type) then
         Set_Depends_On_Private (Derived_Type, True);
         Set_Private_Dependents (Derived_Type, New_Elmt_List);
      end if;

      --  Inherit fields for non-private types. If this is the completion of a
      --  derivation from a private type, the parent itself is private and the
      --  attributes come from its full view, which must be present.

      if Is_Record_Type (Derived_Type) then
         declare
            Parent_Full : Entity_Id;

         begin
            if Is_Private_Type (Parent_Base)
              and then not Is_Record_Type (Parent_Base)
            then
               Parent_Full := Full_View (Parent_Base);
            else
               Parent_Full := Parent_Base;
            end if;

            Set_Component_Alignment
              (Derived_Type, Component_Alignment        (Parent_Full));
            Set_C_Pass_By_Copy
              (Derived_Type, C_Pass_By_Copy             (Parent_Full));
            Set_Has_Complex_Representation
              (Derived_Type, Has_Complex_Representation (Parent_Full));

            --  For untagged types, inherit the layout by default to avoid
            --  costly changes of representation for type conversions.

            if not Is_Tagged then
               Set_Is_Packed     (Derived_Type, Is_Packed     (Parent_Full));
               Set_No_Reordering (Derived_Type, No_Reordering (Parent_Full));
            end if;
         end;
      end if;

      --  When prefixed-call syntax is allowed for untagged types, initialize
      --  the list of primitive operations to an empty list.

      if Extensions_Allowed and then not Is_Tagged then
         Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);
      end if;

      --  Set fields for tagged types

      if Is_Tagged then
         Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);

         --  All tagged types defined in Ada.Finalization are controlled

         if Chars (Scope (Derived_Type)) = Name_Finalization
           and then Chars (Scope (Scope (Derived_Type))) = Name_Ada
           and then Scope (Scope (Scope (Derived_Type))) = Standard_Standard
         then
            Set_Is_Controlled_Active (Derived_Type);
         else
            Set_Is_Controlled_Active
              (Derived_Type, Is_Controlled_Active (Parent_Base));
         end if;

         --  Minor optimization: there is no need to generate the class-wide
         --  entity associated with an underlying record view.

         if not Is_Underlying_Record_View (Derived_Type) then
            Make_Class_Wide_Type (Derived_Type);
         end if;

         Set_Is_Abstract_Type (Derived_Type, Abstract_Present (Type_Def));

         if Has_Discriminants (Derived_Type)
           and then Constraint_Present
         then
            Set_Stored_Constraint
              (Derived_Type, Expand_To_Stored_Constraint (Parent_Base, Discs));
         end if;

         if Ada_Version >= Ada_2005 then
            declare
               Ifaces_List : Elist_Id;

            begin
               --  Checks rules 3.9.4 (13/2 and 14/2)

               if Comes_From_Source (Derived_Type)
                 and then not Is_Private_Type (Derived_Type)
                 and then Is_Interface (Parent_Type)
                 and then not Is_Interface (Derived_Type)
               then
                  if Is_Task_Interface (Parent_Type) then
                     Error_Msg_N
                       ("(Ada 2005) task type required (RM 3.9.4 (13.2))",
                        Derived_Type);

                  elsif Is_Protected_Interface (Parent_Type) then
                     Error_Msg_N
                       ("(Ada 2005) protected type required (RM 3.9.4 (14.2))",
                        Derived_Type);
                  end if;
               end if;

               --  Check ARM rules 3.9.4 (15/2), 9.1 (9.d/2) and 9.4 (11.d/2)

               Check_Interfaces (N, Type_Def);

               --  Ada 2005 (AI-251): Collect the list of progenitors that are
               --  not already in the parents.

               Collect_Interfaces
                 (T               => Derived_Type,
                  Ifaces_List     => Ifaces_List,
                  Exclude_Parents => True);

               Set_Interfaces (Derived_Type, Ifaces_List);

               --  If the derived type is the anonymous type created for
               --  a declaration whose parent has a constraint, propagate
               --  the interface list to the source type. This must be done
               --  prior to the completion of the analysis of the source type
               --  because the components in the extension may contain current
               --  instances whose legality depends on some ancestor.

               if Is_Itype (Derived_Type) then
                  declare
                     Def : constant Node_Id :=
                             Associated_Node_For_Itype (Derived_Type);
                  begin
                     if Present (Def)
                       and then Nkind (Def) = N_Full_Type_Declaration
                     then
                        Set_Interfaces
                          (Defining_Identifier (Def), Ifaces_List);
                     end if;
                  end;
               end if;

               --  A type extension is automatically Ghost when one of its
               --  progenitors is Ghost (SPARK RM 6.9(9)). This property is
               --  also inherited when the parent type is Ghost, but this is
               --  done in Build_Derived_Type as the mechanism also handles
               --  untagged derivations.

               if Implements_Ghost_Interface (Derived_Type) then
                  Set_Is_Ghost_Entity (Derived_Type);
               end if;
            end;
         end if;
      end if;

      --  STEP 4: Inherit components from the parent base and constrain them.
      --          Apply the second transformation described in point 6. above.

      if (not Is_Empty_Elmt_List (Discs) or else Inherit_Discrims)
        or else not Has_Discriminants (Parent_Type)
        or else not Is_Constrained (Parent_Type)
      then
         Constrs := Discs;
      else
         Constrs := Discriminant_Constraint (Parent_Type);
      end if;

      Assoc_List :=
        Inherit_Components
          (N, Parent_Base, Derived_Type, Is_Tagged, Inherit_Discrims, Constrs);

      --  STEP 5a: Copy the parent record declaration for untagged types

      Set_Has_Implicit_Dereference
        (Derived_Type, Has_Implicit_Dereference (Parent_Type));

      if not Is_Tagged then

         --  Discriminant_Constraint (Derived_Type) has been properly
         --  constructed. Save it and temporarily set it to Empty because we
         --  do not want the call to New_Copy_Tree below to mess this list.

         if Has_Discriminants (Derived_Type) then
            Save_Discr_Constr := Discriminant_Constraint (Derived_Type);
            Set_Discriminant_Constraint (Derived_Type, No_Elist);
         else
            Save_Discr_Constr := No_Elist;
         end if;

         --  Save the Etype field of Derived_Type. It is correctly set now,
         --  but the call to New_Copy tree may remap it to point to itself,
         --  which is not what we want. Ditto for the Next_Entity field.

         Save_Etype       := Etype (Derived_Type);
         Save_Next_Entity := Next_Entity (Derived_Type);

         --  Assoc_List maps all stored discriminants in the Parent_Base to
         --  stored discriminants in the Derived_Type. It is fundamental that
         --  no types or itypes with discriminants other than the stored
         --  discriminants appear in the entities declared inside
         --  Derived_Type, since the back end cannot deal with it.

         New_Decl :=
           New_Copy_Tree
             (Parent (Parent_Base), Map => Assoc_List, New_Sloc => Loc);
         Copy_Dimensions_Of_Components (Derived_Type);

         --  Restore the fields saved prior to the New_Copy_Tree call
         --  and compute the stored constraint.

         Set_Etype     (Derived_Type, Save_Etype);
         Link_Entities (Derived_Type, Save_Next_Entity);

         if Has_Discriminants (Derived_Type) then
            Set_Discriminant_Constraint
              (Derived_Type, Save_Discr_Constr);
            Set_Stored_Constraint
              (Derived_Type, Expand_To_Stored_Constraint (Parent_Type, Discs));

            Replace_Discriminants (Derived_Type, New_Decl);
         end if;

         --  Insert the new derived type declaration

         Rewrite (N, New_Decl);

      --  STEP 5b: Complete the processing for record extensions in generics

      --  There is no completion for record extensions declared in the
      --  parameter part of a generic, so we need to complete processing for
      --  these generic record extensions here. The Record_Type_Definition call
      --  will change the Ekind of the components from E_Void to E_Component.

      elsif Private_Extension and then Is_Generic_Type (Derived_Type) then
         Record_Type_Definition (Empty, Derived_Type);

      --  STEP 5c: Process the record extension for non private tagged types

      elsif not Private_Extension then
         Expand_Record_Extension (Derived_Type, Type_Def);

         --  Ada 2005 (AI-251): Addition of the Tag corresponding to all the
         --  implemented interfaces if we are in expansion mode

         if Expander_Active
           and then Has_Interfaces (Derived_Type)
         then
            Add_Interface_Tag_Components (N, Derived_Type);
         end if;

         --  Analyze the record extension

         Record_Type_Definition
           (Record_Extension_Part (Type_Def), Derived_Type);
      end if;

      End_Scope;

      --  Nothing else to do if there is an error in the derivation.
      --  An unusual case: the full view may be derived from a type in an
      --  instance, when the partial view was used illegally as an actual
      --  in that instance, leading to a circular definition.

      if Etype (Derived_Type) = Any_Type
        or else Etype (Parent_Type) = Derived_Type
      then
         return;
      end if;

      --  Set delayed freeze and then derive subprograms, we need to do
      --  this in this order so that derived subprograms inherit the
      --  derived freeze if necessary.

      Set_Has_Delayed_Freeze (Derived_Type);

      if Derive_Subps then
         Derive_Subprograms (Parent_Type, Derived_Type);
      end if;

      --  If we have a private extension which defines a constrained derived
      --  type mark as constrained here after we have derived subprograms. See
      --  comment on point 9. just above the body of Build_Derived_Record_Type.

      if Private_Extension and then Inherit_Discrims then
         if Constraint_Present and then not Is_Empty_Elmt_List (Discs) then
            Set_Is_Constrained          (Derived_Type, True);
            Set_Discriminant_Constraint (Derived_Type, Discs);

         elsif Is_Constrained (Parent_Type) then
            Set_Is_Constrained
              (Derived_Type, True);
            Set_Discriminant_Constraint
              (Derived_Type, Discriminant_Constraint (Parent_Type));
         end if;
      end if;

      --  Update the class-wide type, which shares the now-completed entity
      --  list with its specific type. In case of underlying record views,
      --  we do not generate the corresponding class wide entity.

      if Is_Tagged
        and then not Is_Underlying_Record_View (Derived_Type)
      then
         Set_First_Entity
           (Class_Wide_Type (Derived_Type), First_Entity (Derived_Type));
         Set_Last_Entity
           (Class_Wide_Type (Derived_Type), Last_Entity (Derived_Type));
      end if;

      Check_Function_Writable_Actuals (N);
   end Build_Derived_Record_Type;

   ------------------------
   -- Build_Derived_Type --
   ------------------------

   procedure Build_Derived_Type
     (N             : Node_Id;
      Parent_Type   : Entity_Id;
      Derived_Type  : Entity_Id;
      Is_Completion : Boolean;
      Derive_Subps  : Boolean := True)
   is
      Parent_Base : constant Entity_Id := Base_Type (Parent_Type);

   begin
      --  Set common attributes

      if Ekind (Derived_Type) in Incomplete_Or_Private_Kind
        and then Ekind (Parent_Base) in Modular_Integer_Kind | Array_Kind
      then
         Reinit_Field_To_Zero (Derived_Type, F_Stored_Constraint);
      end if;

      Set_Scope                  (Derived_Type, Current_Scope);
      Set_Etype                  (Derived_Type,        Parent_Base);
      Mutate_Ekind               (Derived_Type, Ekind (Parent_Base));
      Propagate_Concurrent_Flags (Derived_Type,        Parent_Base);

      Set_Size_Info (Derived_Type, Parent_Type);
      Copy_RM_Size (To => Derived_Type, From => Parent_Type);

      Set_Is_Controlled_Active
        (Derived_Type, Is_Controlled_Active (Parent_Type));

      Set_Disable_Controlled (Derived_Type, Disable_Controlled (Parent_Type));
      Set_Is_Tagged_Type     (Derived_Type, Is_Tagged_Type     (Parent_Type));
      Set_Is_Volatile        (Derived_Type, Is_Volatile        (Parent_Type));

      if Is_Tagged_Type (Derived_Type) then
         Set_No_Tagged_Streams_Pragma
           (Derived_Type, No_Tagged_Streams_Pragma (Parent_Type));
      end if;

      --  If the parent has primitive routines and may have not-seen-yet aspect
      --  specifications (e.g., a Pack pragma), then set the derived type link
      --  in order to later diagnose "early derivation" issues. If in different
      --  compilation units, then "early derivation" cannot be an issue (and we
      --  don't like interunit references that go in the opposite direction of
      --  semantic dependencies).

      if Has_Primitive_Operations (Parent_Type)
         and then Enclosing_Comp_Unit_Node (Parent_Type) =
           Enclosing_Comp_Unit_Node (Derived_Type)
      then
         Set_Derived_Type_Link (Parent_Base, Derived_Type);
      end if;

      --  If the parent type is a private subtype, the convention on the base
      --  type may be set in the private part, and not propagated to the
      --  subtype until later, so we obtain the convention from the base type.

      Set_Convention (Derived_Type, Convention (Parent_Base));

      if Is_Tagged_Type (Derived_Type)
        and then Present (Class_Wide_Type (Derived_Type))
      then
         Set_Convention (Class_Wide_Type (Derived_Type),
           Convention (Class_Wide_Type (Parent_Base)));
      end if;

      --  Set SSO default for record or array type

      if (Is_Array_Type (Derived_Type) or else Is_Record_Type (Derived_Type))
        and then Is_Base_Type (Derived_Type)
      then
         Set_Default_SSO (Derived_Type);
      end if;

      --  A derived type inherits the Default_Initial_Condition pragma coming
      --  from any parent type within the derivation chain.

      if Has_DIC (Parent_Type) then
         Set_Has_Inherited_DIC (Derived_Type);
      end if;

      --  A derived type inherits any class-wide invariants coming from a
      --  parent type or an interface. Note that the invariant procedure of
      --  the parent type should not be inherited because the derived type may
      --  define invariants of its own.

      if not Is_Interface (Derived_Type) then
         if Has_Inherited_Invariants (Parent_Type)
           or else Has_Inheritable_Invariants (Parent_Type)
         then
            Set_Has_Inherited_Invariants (Derived_Type);

         elsif Is_Concurrent_Type (Derived_Type)
           or else Is_Tagged_Type (Derived_Type)
         then
            declare
               Iface      : Entity_Id;
               Ifaces     : Elist_Id;
               Iface_Elmt : Elmt_Id;

            begin
               Collect_Interfaces
                 (T               => Derived_Type,
                  Ifaces_List     => Ifaces,
                  Exclude_Parents => True);

               if Present (Ifaces) then
                  Iface_Elmt := First_Elmt (Ifaces);
                  while Present (Iface_Elmt) loop
                     Iface := Node (Iface_Elmt);

                     if Has_Inheritable_Invariants (Iface) then
                        Set_Has_Inherited_Invariants (Derived_Type);
                        exit;
                     end if;

                     Next_Elmt (Iface_Elmt);
                  end loop;
               end if;
            end;
         end if;
      end if;

      --  We similarly inherit predicates. Note that for scalar derived types
      --  the predicate is inherited from the first subtype, and not from its
      --  (anonymous) base type.

      if Has_Predicates (Parent_Type)
        or else Has_Predicates (First_Subtype (Parent_Type))
      then
         Set_Has_Predicates (Derived_Type);
      end if;

      --  The derived type inherits representation clauses from the parent
      --  type, and from any interfaces.

      Inherit_Rep_Item_Chain (Derived_Type, Parent_Type);

      declare
         Iface : Node_Id := First (Abstract_Interface_List (Derived_Type));
      begin
         while Present (Iface) loop
            Inherit_Rep_Item_Chain (Derived_Type, Entity (Iface));
            Next (Iface);
         end loop;
      end;

      --  If the parent type has delayed rep aspects, then mark the derived
      --  type as possibly inheriting a delayed rep aspect.

      if Has_Delayed_Rep_Aspects (Parent_Type) then
         Set_May_Inherit_Delayed_Rep_Aspects (Derived_Type);
      end if;

      --  A derived type becomes Ghost when its parent type is also Ghost
      --  (SPARK RM 6.9(9)). Note that the Ghost-related attributes are not
      --  directly inherited because the Ghost policy in effect may differ.

      if Is_Ghost_Entity (Parent_Type) then
         Set_Is_Ghost_Entity (Derived_Type);
      end if;

      --  Type dependent processing

      case Ekind (Parent_Type) is
         when Numeric_Kind =>
            Build_Derived_Numeric_Type (N, Parent_Type, Derived_Type);

         when Array_Kind =>
            Build_Derived_Array_Type (N, Parent_Type,  Derived_Type);

         when Class_Wide_Kind
            | E_Record_Subtype
            | E_Record_Type
         =>
            Build_Derived_Record_Type
              (N, Parent_Type, Derived_Type, Derive_Subps);
            return;

         when Enumeration_Kind =>
            Build_Derived_Enumeration_Type (N, Parent_Type, Derived_Type);

         when Access_Kind =>
            Build_Derived_Access_Type (N, Parent_Type, Derived_Type);

         when Incomplete_Or_Private_Kind =>
            Build_Derived_Private_Type
              (N, Parent_Type, Derived_Type, Is_Completion, Derive_Subps);

            --  For discriminated types, the derivation includes deriving
            --  primitive operations. For others it is done below.

            if Is_Tagged_Type (Parent_Type)
              or else Has_Discriminants (Parent_Type)
              or else (Present (Full_View (Parent_Type))
                        and then Has_Discriminants (Full_View (Parent_Type)))
            then
               return;
            end if;

         when Concurrent_Kind =>
            Build_Derived_Concurrent_Type (N, Parent_Type, Derived_Type);

         when others =>
            raise Program_Error;
      end case;

      --  Nothing more to do if some error occurred

      if Etype (Derived_Type) = Any_Type then
         return;
      end if;

      --  If not already set, initialize the derived type's list of primitive
      --  operations to an empty element list.

      if not Present (Direct_Primitive_Operations (Derived_Type)) then
         Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);

         --  If Etype of the derived type is the base type (as opposed to
         --  a parent type) and doesn't have an associated list of primitive
         --  operations, then set the base type's primitive list to the
         --  derived type's list. The lists need to be shared in common
         --  between the two.

         if Etype (Derived_Type) = Base_Type (Derived_Type)
           and then
             not Present (Direct_Primitive_Operations (Etype (Derived_Type)))
         then
            Set_Direct_Primitive_Operations
              (Etype (Derived_Type),
               Direct_Primitive_Operations (Derived_Type));
         end if;
      end if;

      --  Set delayed freeze and then derive subprograms, we need to do this
      --  in this order so that derived subprograms inherit the derived freeze
      --  if necessary.

      Set_Has_Delayed_Freeze (Derived_Type);

      if Derive_Subps then
         Derive_Subprograms (Parent_Type, Derived_Type);
      end if;

      Set_Has_Primitive_Operations
        (Base_Type (Derived_Type), Has_Primitive_Operations (Parent_Type));
   end Build_Derived_Type;

   -----------------------
   -- Build_Discriminal --
   -----------------------

   procedure Build_Discriminal (Discrim : Entity_Id) is
      D_Minal : Entity_Id;
      CR_Disc : Entity_Id;

   begin
      --  A discriminal has the same name as the discriminant

      D_Minal := Make_Defining_Identifier (Sloc (Discrim), Chars (Discrim));

      Mutate_Ekind  (D_Minal, E_In_Parameter);
      Set_Mechanism (D_Minal, Default_Mechanism);
      Set_Etype     (D_Minal, Etype (Discrim));
      Set_Scope     (D_Minal, Current_Scope);
      Set_Parent    (D_Minal, Parent (Discrim));

      Set_Discriminal (Discrim, D_Minal);
      Set_Discriminal_Link (D_Minal, Discrim);

      --  For task types, build at once the discriminants of the corresponding
      --  record, which are needed if discriminants are used in entry defaults
      --  and in family bounds.

      if Is_Concurrent_Type (Current_Scope)
           or else
         Is_Limited_Type    (Current_Scope)
      then
         CR_Disc := Make_Defining_Identifier (Sloc (Discrim), Chars (Discrim));

         Mutate_Ekind         (CR_Disc, E_In_Parameter);
         Set_Mechanism        (CR_Disc, Default_Mechanism);
         Set_Etype            (CR_Disc, Etype (Discrim));
         Set_Scope            (CR_Disc, Current_Scope);
         Set_Discriminal_Link (CR_Disc, Discrim);
         Set_CR_Discriminant  (Discrim, CR_Disc);
      end if;
   end Build_Discriminal;

   ------------------------------------
   -- Build_Discriminant_Constraints --
   ------------------------------------

   function Build_Discriminant_Constraints
     (T           : Entity_Id;
      Def         : Node_Id;
      Derived_Def : Boolean := False) return Elist_Id
   is
      C        : constant Node_Id := Constraint (Def);
      Nb_Discr : constant Nat     := Number_Discriminants (T);

      Discr_Expr : array (1 .. Nb_Discr) of Node_Id := (others => Empty);
      --  Saves the expression corresponding to a given discriminant in T

      function Pos_Of_Discr (T : Entity_Id; D : Entity_Id) return Nat;
      --  Return the Position number within array Discr_Expr of a discriminant
      --  D within the discriminant list of the discriminated type T.

      procedure Process_Discriminant_Expression
         (Expr : Node_Id;
          D    : Entity_Id);
      --  If this is a discriminant constraint on a partial view, do not
      --  generate an overflow check on the discriminant expression. The check
      --  will be generated when constraining the full view. Otherwise the
      --  backend creates duplicate symbols for the temporaries corresponding
      --  to the expressions to be checked, causing spurious assembler errors.

      ------------------
      -- Pos_Of_Discr --
      ------------------

      function Pos_Of_Discr (T : Entity_Id; D : Entity_Id) return Nat is
         Disc : Entity_Id;

      begin
         Disc := First_Discriminant (T);
         for J in Discr_Expr'Range loop
            if Disc = D then
               return J;
            end if;

            Next_Discriminant (Disc);
         end loop;

         --  Note: Since this function is called on discriminants that are
         --  known to belong to the discriminated type, falling through the
         --  loop with no match signals an internal compiler error.

         raise Program_Error;
      end Pos_Of_Discr;

      -------------------------------------
      -- Process_Discriminant_Expression --
      -------------------------------------

      procedure Process_Discriminant_Expression
         (Expr : Node_Id;
          D    : Entity_Id)
      is
         BDT : constant Entity_Id := Base_Type (Etype (D));

      begin
         --  If this is a discriminant constraint on a partial view, do
         --  not generate an overflow on the discriminant expression. The
         --  check will be generated when constraining the full view.

         if Is_Private_Type (T)
           and then Present (Full_View (T))
         then
            Analyze_And_Resolve (Expr, BDT, Suppress => Overflow_Check);
         else
            Analyze_And_Resolve (Expr, BDT);
         end if;
      end Process_Discriminant_Expression;

      --  Declarations local to Build_Discriminant_Constraints

      Discr : Entity_Id;
      E     : Entity_Id;
      Elist : constant Elist_Id := New_Elmt_List;

      Constr   : Node_Id;
      Expr     : Node_Id;
      Id       : Node_Id;
      Position : Nat;
      Found    : Boolean;

      Discrim_Present : Boolean := False;

   --  Start of processing for Build_Discriminant_Constraints

   begin
      --  The following loop will process positional associations only.
      --  For a positional association, the (single) discriminant is
      --  implicitly specified by position, in textual order (RM 3.7.2).

      Discr  := First_Discriminant (T);
      Constr := First (Constraints (C));
      for D in Discr_Expr'Range loop
         exit when Nkind (Constr) = N_Discriminant_Association;

         if No (Constr) then
            Error_Msg_N ("too few discriminants given in constraint", C);
            return New_Elmt_List;

         elsif Nkind (Constr) = N_Range
           or else (Nkind (Constr) = N_Attribute_Reference
                     and then Attribute_Name (Constr) = Name_Range)
         then
            Error_Msg_N
              ("a range is not a valid discriminant constraint", Constr);
            Discr_Expr (D) := Error;

         elsif Nkind (Constr) = N_Subtype_Indication then
            Error_Msg_N
              ("a subtype indication is not a valid discriminant constraint",
               Constr);
            Discr_Expr (D) := Error;

         else
            Process_Discriminant_Expression (Constr, Discr);
            Discr_Expr (D) := Constr;
         end if;

         Next_Discriminant (Discr);
         Next (Constr);
      end loop;

      if No (Discr) and then Present (Constr) then
         Error_Msg_N ("too many discriminants given in constraint", Constr);
         return New_Elmt_List;
      end if;

      --  Named associations can be given in any order, but if both positional
      --  and named associations are used in the same discriminant constraint,
      --  then positional associations must occur first, at their normal
      --  position. Hence once a named association is used, the rest of the
      --  discriminant constraint must use only named associations.

      while Present (Constr) loop

         --  Positional association forbidden after a named association

         if Nkind (Constr) /= N_Discriminant_Association then
            Error_Msg_N ("positional association follows named one", Constr);
            return New_Elmt_List;

         --  Otherwise it is a named association

         else
            --  E records the type of the discriminants in the named
            --  association. All the discriminants specified in the same name
            --  association must have the same type.

            E := Empty;

            --  Search the list of discriminants in T to see if the simple name
            --  given in the constraint matches any of them.

            Id := First (Selector_Names (Constr));
            while Present (Id) loop
               Found := False;

               --  If Original_Discriminant is present, we are processing a
               --  generic instantiation and this is an instance node. We need
               --  to find the name of the corresponding discriminant in the
               --  actual record type T and not the name of the discriminant in
               --  the generic formal. Example:

               --    generic
               --       type G (D : int) is private;
               --    package P is
               --       subtype W is G (D => 1);
               --    end package;
               --    type Rec (X : int) is record ... end record;
               --    package Q is new P (G => Rec);

               --  At the point of the instantiation, formal type G is Rec
               --  and therefore when reanalyzing "subtype W is G (D => 1);"
               --  which really looks like "subtype W is Rec (D => 1);" at
               --  the point of instantiation, we want to find the discriminant
               --  that corresponds to D in Rec, i.e. X.

               if Present (Original_Discriminant (Id))
                 and then In_Instance
               then
                  Discr := Find_Corresponding_Discriminant (Id, T);
                  Found := True;

               else
                  Discr := First_Discriminant (T);
                  while Present (Discr) loop
                     if Chars (Discr) = Chars (Id) then
                        Found := True;
                        exit;
                     end if;

                     Next_Discriminant (Discr);
                  end loop;

                  if not Found then
                     Error_Msg_N ("& does not match any discriminant", Id);
                     return New_Elmt_List;

                  --  If the parent type is a generic formal, preserve the
                  --  name of the discriminant for subsequent instances.
                  --  see comment at the beginning of this if statement.

                  elsif Is_Generic_Type (Root_Type (T)) then
                     Set_Original_Discriminant (Id, Discr);
                  end if;
               end if;

               Position := Pos_Of_Discr (T, Discr);

               if Present (Discr_Expr (Position)) then
                  Error_Msg_N ("duplicate constraint for discriminant&", Id);

               else
                  --  Each discriminant specified in the same named association
                  --  must be associated with a separate copy of the
                  --  corresponding expression.

                  if Present (Next (Id)) then
                     Expr := New_Copy_Tree (Expression (Constr));
                     Set_Parent (Expr, Parent (Expression (Constr)));
                  else
                     Expr := Expression (Constr);
                  end if;

                  Discr_Expr (Position) := Expr;
                  Process_Discriminant_Expression (Expr, Discr);
               end if;

               --  A discriminant association with more than one discriminant
               --  name is only allowed if the named discriminants are all of
               --  the same type (RM 3.7.1(8)).

               if E = Empty then
                  E := Base_Type (Etype (Discr));

               elsif Base_Type (Etype (Discr)) /= E then
                  Error_Msg_N
                    ("all discriminants in an association " &
                     "must have the same type", Id);
               end if;

               Next (Id);
            end loop;
         end if;

         Next (Constr);
      end loop;

      --  A discriminant constraint must provide exactly one value for each
      --  discriminant of the type (RM 3.7.1(8)).

      for J in Discr_Expr'Range loop
         if No (Discr_Expr (J)) then
            Error_Msg_N ("too few discriminants given in constraint", C);
            return New_Elmt_List;
         end if;
      end loop;

      --  Determine if there are discriminant expressions in the constraint

      for J in Discr_Expr'Range loop
         if Denotes_Discriminant
              (Discr_Expr (J), Check_Concurrent => True)
         then
            Discrim_Present := True;
            exit;
         end if;
      end loop;

      --  Build an element list consisting of the expressions given in the
      --  discriminant constraint and apply the appropriate checks. The list
      --  is constructed after resolving any named discriminant associations
      --  and therefore the expressions appear in the textual order of the
      --  discriminants.

      Discr := First_Discriminant (T);
      for J in Discr_Expr'Range loop
         if Discr_Expr (J) /= Error then
            Append_Elmt (Discr_Expr (J), Elist);

            --  If any of the discriminant constraints is given by a
            --  discriminant and we are in a derived type declaration we
            --  have a discriminant renaming. Establish link between new
            --  and old discriminant. The new discriminant has an implicit
            --  dereference if the old one does.

            if Denotes_Discriminant (Discr_Expr (J)) then
               if Derived_Def then
                  declare
                     New_Discr : constant Entity_Id := Entity (Discr_Expr (J));

                  begin
                     Set_Corresponding_Discriminant (New_Discr, Discr);
                     Set_Has_Implicit_Dereference (New_Discr,
                       Has_Implicit_Dereference (Discr));
                  end;
               end if;

            --  Force the evaluation of non-discriminant expressions.
            --  If we have found a discriminant in the constraint 3.4(26)
            --  and 3.8(18) demand that no range checks are performed are
            --  after evaluation. If the constraint is for a component
            --  definition that has a per-object constraint, expressions are
            --  evaluated but not checked either. In all other cases perform
            --  a range check.

            else
               if Discrim_Present then
                  null;

               elsif Parent_Kind (Parent (Def)) = N_Component_Declaration
                 and then Has_Per_Object_Constraint
                            (Defining_Identifier (Parent (Parent (Def))))
               then
                  null;

               elsif Is_Access_Type (Etype (Discr)) then
                  Apply_Constraint_Check (Discr_Expr (J), Etype (Discr));

               else
                  Apply_Range_Check (Discr_Expr (J), Etype (Discr));
               end if;

               --  If the value of the discriminant may be visible in
               --  another unit or child unit, create an external name
               --  for it. We use the name of the object or component
               --  that carries the discriminated subtype. The code
               --  below may generate external symbols for the discriminant
               --  expression when not strictly needed, which is harmless.

               if Expander_Active
                 and then Comes_From_Source (Def)
                 and then not Is_Subprogram (Current_Scope)
               then
                  declare
                     Id : Entity_Id := Empty;
                  begin
                     if Nkind (Parent (Def)) = N_Object_Declaration then
                        Id := Defining_Identifier (Parent (Def));

                     elsif Nkind (Parent (Def)) = N_Component_Definition
                       and then
                         Nkind (Parent (Parent (Def)))
                            = N_Component_Declaration
                     then
                        Id := Defining_Identifier (Parent (Parent (Def)));
                     end if;

                     if Present (Id) then
                        Force_Evaluation (
                          Discr_Expr (J),
                          Related_Id => Id,
                          Discr_Number => J);
                     else
                        Force_Evaluation (Discr_Expr (J));
                     end if;
                  end;
               else
                  Force_Evaluation (Discr_Expr (J));
               end if;
            end if;

            --  Check that the designated type of an access discriminant's
            --  expression is not a class-wide type unless the discriminant's
            --  designated type is also class-wide.

            if Ekind (Etype (Discr)) = E_Anonymous_Access_Type
              and then not Is_Class_Wide_Type
                             (Designated_Type (Etype (Discr)))
              and then Etype (Discr_Expr (J)) /= Any_Type
              and then Is_Class_Wide_Type
                         (Designated_Type (Etype (Discr_Expr (J))))
            then
               Wrong_Type (Discr_Expr (J), Etype (Discr));

            elsif Is_Access_Type (Etype (Discr))
              and then not Is_Access_Constant (Etype (Discr))
              and then Is_Access_Type (Etype (Discr_Expr (J)))
              and then Is_Access_Constant (Etype (Discr_Expr (J)))
            then
               Error_Msg_NE
                 ("constraint for discriminant& must be access to variable",
                  Def, Discr);
            end if;
         end if;

         Next_Discriminant (Discr);
      end loop;

      return Elist;
   end Build_Discriminant_Constraints;

   ---------------------------------
   -- Build_Discriminated_Subtype --
   ---------------------------------

   procedure Build_Discriminated_Subtype
     (T           : Entity_Id;
      Def_Id      : Entity_Id;
      Elist       : Elist_Id;
      Related_Nod : Node_Id;
      For_Access  : Boolean := False)
   is
      Has_Discrs  : constant Boolean := Has_Discriminants (T);
      Constrained : constant Boolean :=
                      (Has_Discrs
                         and then not Is_Empty_Elmt_List (Elist)
                         and then not Is_Class_Wide_Type (T))
                        or else Is_Constrained (T);

   begin
      if Ekind (T) = E_Record_Type then
         Mutate_Ekind (Def_Id, E_Record_Subtype);

         --  Inherit preelaboration flag from base, for types for which it
         --  may have been set: records, private types, protected types.

         Set_Known_To_Have_Preelab_Init
           (Def_Id, Known_To_Have_Preelab_Init (T));

      elsif Ekind (T) = E_Task_Type then
         Mutate_Ekind (Def_Id, E_Task_Subtype);

      elsif Ekind (T) = E_Protected_Type then
         Mutate_Ekind (Def_Id, E_Protected_Subtype);
         Set_Known_To_Have_Preelab_Init
           (Def_Id, Known_To_Have_Preelab_Init (T));

      elsif Is_Private_Type (T) then
         Mutate_Ekind (Def_Id, Subtype_Kind (Ekind (T)));
         Set_Known_To_Have_Preelab_Init
           (Def_Id, Known_To_Have_Preelab_Init (T));

         --  Private subtypes may have private dependents

         Set_Private_Dependents (Def_Id, New_Elmt_List);

      elsif Is_Class_Wide_Type (T) then
         Mutate_Ekind (Def_Id, E_Class_Wide_Subtype);

      else
         --  Incomplete type. Attach subtype to list of dependents, to be
         --  completed with full view of parent type,  unless is it the
         --  designated subtype of a record component within an init_proc.
         --  This last case arises for a component of an access type whose
         --  designated type is incomplete (e.g. a Taft Amendment type).
         --  The designated subtype is within an inner scope, and needs no
         --  elaboration, because only the access type is needed in the
         --  initialization procedure.

         if Ekind (T) = E_Incomplete_Type then
            Mutate_Ekind (Def_Id, E_Incomplete_Subtype);
         else
            Mutate_Ekind (Def_Id, Ekind (T));
         end if;

         if For_Access and then Within_Init_Proc then
            null;
         else
            Append_Elmt (Def_Id, Private_Dependents (T));
         end if;
      end if;

      Set_Etype             (Def_Id, T);
      Reinit_Size_Align     (Def_Id);
      Set_Has_Discriminants (Def_Id, Has_Discrs);
      Set_Is_Constrained    (Def_Id, Constrained);

      Set_First_Entity      (Def_Id, First_Entity   (T));
      Set_Last_Entity       (Def_Id, Last_Entity    (T));
      Set_Has_Implicit_Dereference
                            (Def_Id, Has_Implicit_Dereference (T));
      Set_Has_Pragma_Unreferenced_Objects
                            (Def_Id, Has_Pragma_Unreferenced_Objects (T));

      --  If the subtype is the completion of a private declaration, there may
      --  have been representation clauses for the partial view, and they must
      --  be preserved. Build_Derived_Type chains the inherited clauses with
      --  the ones appearing on the extension. If this comes from a subtype
      --  declaration, all clauses are inherited.

      if No (First_Rep_Item (Def_Id)) then
         Set_First_Rep_Item (Def_Id, First_Rep_Item (T));
      end if;

      if Is_Tagged_Type (T) then
         Set_Is_Tagged_Type (Def_Id);
         Set_No_Tagged_Streams_Pragma (Def_Id, No_Tagged_Streams_Pragma (T));
         Make_Class_Wide_Type (Def_Id);
      end if;

      Set_Stored_Constraint (Def_Id, No_Elist);

      if Has_Discrs then
         Set_Discriminant_Constraint (Def_Id, Elist);
         Set_Stored_Constraint_From_Discriminant_Constraint (Def_Id);
      end if;

      if Is_Tagged_Type (T) then

         --  Ada 2005 (AI-251): In case of concurrent types we inherit the
         --  concurrent record type (which has the list of primitive
         --  operations).

         if Ada_Version >= Ada_2005
           and then Is_Concurrent_Type (T)
         then
            Set_Corresponding_Record_Type (Def_Id,
               Corresponding_Record_Type (T));
         else
            Set_Direct_Primitive_Operations (Def_Id,
              Direct_Primitive_Operations (T));
         end if;

         Set_Is_Abstract_Type (Def_Id, Is_Abstract_Type (T));
      end if;

      --  Subtypes introduced by component declarations do not need to be
      --  marked as delayed, and do not get freeze nodes, because the semantics
      --  verifies that the parents of the subtypes are frozen before the
      --  enclosing record is frozen.

      if not Is_Type (Scope (Def_Id)) then
         Set_Depends_On_Private (Def_Id, Depends_On_Private (T));

         if Is_Private_Type (T)
           and then Present (Full_View (T))
         then
            Conditional_Delay (Def_Id, Full_View (T));
         else
            Conditional_Delay (Def_Id, T);
         end if;
      end if;

      if Is_Record_Type (T) then
         Set_Is_Limited_Record (Def_Id, Is_Limited_Record (T));

         if Has_Discrs
           and then not Is_Empty_Elmt_List (Elist)
           and then not For_Access
         then
            Create_Constrained_Components (Def_Id, Related_Nod, T, Elist);

         elsif not Is_Private_Type (T) then
            Set_Cloned_Subtype (Def_Id, T);
         end if;
      end if;
   end Build_Discriminated_Subtype;

   ---------------------------
   -- Build_Itype_Reference --
   ---------------------------

   procedure Build_Itype_Reference
     (Ityp : Entity_Id;
      Nod  : Node_Id)
   is
      IR : constant Node_Id := Make_Itype_Reference (Sloc (Nod));
   begin

      --  Itype references are only created for use by the back-end

      if Inside_A_Generic then
         return;
      else
         Set_Itype (IR, Ityp);

         --  If Nod is a library unit entity, then Insert_After won't work,
         --  because Nod is not a member of any list. Therefore, we use
         --  Add_Global_Declaration in this case. This can happen if we have a
         --  build-in-place library function, child unit or not.

         if (Nkind (Nod) in N_Entity and then Is_Compilation_Unit (Nod))
           or else (Nkind (Nod) in
                      N_Defining_Program_Unit_Name | N_Subprogram_Declaration
                     and then Is_Compilation_Unit (Defining_Entity (Nod)))
         then
            Add_Global_Declaration (IR);
         else
            Insert_After (Nod, IR);
         end if;
      end if;
   end Build_Itype_Reference;

   ------------------------
   -- Build_Scalar_Bound --
   ------------------------

   function Build_Scalar_Bound
     (Bound : Node_Id;
      Par_T : Entity_Id;
      Der_T : Entity_Id) return Node_Id
   is
      New_Bound : Entity_Id;

   begin
      --  Note: not clear why this is needed, how can the original bound
      --  be unanalyzed at this point? and if it is, what business do we
      --  have messing around with it? and why is the base type of the
      --  parent type the right type for the resolution. It probably is
      --  not. It is OK for the new bound we are creating, but not for
      --  the old one??? Still if it never happens, no problem.

      Analyze_And_Resolve (Bound, Base_Type (Par_T));

      if Nkind (Bound) in N_Integer_Literal | N_Real_Literal then
         New_Bound := New_Copy (Bound);
         Set_Etype (New_Bound, Der_T);
         Set_Analyzed (New_Bound);

      elsif Is_Entity_Name (Bound) then
         New_Bound := OK_Convert_To (Der_T, New_Copy (Bound));

      --  The following is almost certainly wrong. What business do we have
      --  relocating a node (Bound) that is presumably still attached to
      --  the tree elsewhere???

      else
         New_Bound := OK_Convert_To (Der_T, Relocate_Node (Bound));
      end if;

      Set_Etype (New_Bound, Der_T);
      return New_Bound;
   end Build_Scalar_Bound;

   -------------------------------
   -- Check_Abstract_Overriding --
   -------------------------------

   procedure Check_Abstract_Overriding (T : Entity_Id) is
      Alias_Subp : Entity_Id;
      Elmt       : Elmt_Id;
      Op_List    : Elist_Id;
      Subp       : Entity_Id;
      Type_Def   : Node_Id;

      procedure Check_Pragma_Implemented (Subp : Entity_Id);
      --  Ada 2012 (AI05-0030): Subprogram Subp overrides an interface routine
      --  which has pragma Implemented already set. Check whether Subp's entity
      --  kind conforms to the implementation kind of the overridden routine.

      procedure Check_Pragma_Implemented
        (Subp       : Entity_Id;
         Iface_Subp : Entity_Id);
      --  Ada 2012 (AI05-0030): Subprogram Subp overrides interface routine
      --  Iface_Subp and both entities have pragma Implemented already set on
      --  them. Check whether the two implementation kinds are conforming.

      procedure Inherit_Pragma_Implemented
        (Subp       : Entity_Id;
         Iface_Subp : Entity_Id);
      --  Ada 2012 (AI05-0030): Interface primitive Subp overrides interface
      --  subprogram Iface_Subp which has been marked by pragma Implemented.
      --  Propagate the implementation kind of Iface_Subp to Subp.

      ------------------------------
      -- Check_Pragma_Implemented --
      ------------------------------

      procedure Check_Pragma_Implemented (Subp : Entity_Id) is
         Iface_Alias : constant Entity_Id := Interface_Alias (Subp);
         Impl_Kind   : constant Name_Id   := Implementation_Kind (Iface_Alias);
         Subp_Alias  : constant Entity_Id := Alias (Subp);
         Contr_Typ   : Entity_Id;
         Impl_Subp   : Entity_Id;

      begin
         --  Subp must have an alias since it is a hidden entity used to link
         --  an interface subprogram to its overriding counterpart.

         pragma Assert (Present (Subp_Alias));

         --  Handle aliases to synchronized wrappers

         Impl_Subp := Subp_Alias;

         if Is_Primitive_Wrapper (Impl_Subp) then
            Impl_Subp := Wrapped_Entity (Impl_Subp);
         end if;

         --  Extract the type of the controlling formal

         Contr_Typ := Etype (First_Formal (Subp_Alias));

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

         --  An interface subprogram whose implementation kind is By_Entry must
         --  be implemented by an entry.

         if Impl_Kind = Name_By_Entry
           and then Ekind (Impl_Subp) /= E_Entry
         then
            Error_Msg_Node_2 := Iface_Alias;
            Error_Msg_NE
              ("type & must implement abstract subprogram & with an entry",
               Subp_Alias, Contr_Typ);

         elsif Impl_Kind = Name_By_Protected_Procedure then

            --  An interface subprogram whose implementation kind is By_
            --  Protected_Procedure cannot be implemented by a primitive
            --  procedure of a task type.

            if Ekind (Contr_Typ) /= E_Protected_Type then
               Error_Msg_Node_2 := Contr_Typ;
               Error_Msg_NE
                 ("interface subprogram & cannot be implemented by a "
                  & "primitive procedure of task type &",
                  Subp_Alias, Iface_Alias);

            --  An interface subprogram whose implementation kind is By_
            --  Protected_Procedure must be implemented by a procedure.

            elsif Ekind (Impl_Subp) /= E_Procedure then
               Error_Msg_Node_2 := Iface_Alias;
               Error_Msg_NE
                 ("type & must implement abstract subprogram & with a "
                  & "procedure", Subp_Alias, Contr_Typ);

            elsif Present (Get_Rep_Pragma (Impl_Subp, Name_Implemented))
              and then Implementation_Kind (Impl_Subp) /= Impl_Kind
            then
               Error_Msg_Name_1 := Impl_Kind;
               Error_Msg_N
                 ("overriding operation& must have synchronization%",
                  Subp_Alias);
            end if;

         --  If primitive has Optional synchronization, overriding operation
         --  must match if it has an explicit synchronization.

         elsif Present (Get_Rep_Pragma (Impl_Subp, Name_Implemented))
           and then Implementation_Kind (Impl_Subp) /= Impl_Kind
         then
            Error_Msg_Name_1 := Impl_Kind;
            Error_Msg_N
              ("overriding operation& must have synchronization%", Subp_Alias);
         end if;
      end Check_Pragma_Implemented;

      ------------------------------
      -- Check_Pragma_Implemented --
      ------------------------------

      procedure Check_Pragma_Implemented
        (Subp       : Entity_Id;
         Iface_Subp : Entity_Id)
      is
         Iface_Kind : constant Name_Id := Implementation_Kind (Iface_Subp);
         Subp_Kind  : constant Name_Id := Implementation_Kind (Subp);

      begin
         --  Ada 2012 (AI05-0030): The implementation kinds of an overridden
         --  and overriding subprogram are different. In general this is an
         --  error except when the implementation kind of the overridden
         --  subprograms is By_Any or Optional.

         if Iface_Kind /= Subp_Kind
           and then Iface_Kind /= Name_By_Any
           and then Iface_Kind /= Name_Optional
         then
            if Iface_Kind = Name_By_Entry then
               Error_Msg_N
                 ("incompatible implementation kind, overridden subprogram " &
                  "is marked By_Entry", Subp);
            else
               Error_Msg_N
                 ("incompatible implementation kind, overridden subprogram " &
                  "is marked By_Protected_Procedure", Subp);
            end if;
         end if;
      end Check_Pragma_Implemented;

      --------------------------------
      -- Inherit_Pragma_Implemented --
      --------------------------------

      procedure Inherit_Pragma_Implemented
        (Subp       : Entity_Id;
         Iface_Subp : Entity_Id)
      is
         Iface_Kind : constant Name_Id    := Implementation_Kind (Iface_Subp);
         Loc        : constant Source_Ptr := Sloc (Subp);
         Impl_Prag  : Node_Id;

      begin
         --  Since the implementation kind is stored as a representation item
         --  rather than a flag, create a pragma node.

         Impl_Prag :=
           Make_Pragma (Loc,
             Chars                        => Name_Implemented,
             Pragma_Argument_Associations => New_List (
               Make_Pragma_Argument_Association (Loc,
                 Expression => New_Occurrence_Of (Subp, Loc)),

               Make_Pragma_Argument_Association (Loc,
                 Expression => Make_Identifier (Loc, Iface_Kind))));

         --  The pragma doesn't need to be analyzed because it is internally
         --  built. It is safe to directly register it as a rep item since we
         --  are only interested in the characters of the implementation kind.

         Record_Rep_Item (Subp, Impl_Prag);
      end Inherit_Pragma_Implemented;

   --  Start of processing for Check_Abstract_Overriding

   begin
      Op_List := Primitive_Operations (T);

      --  Loop to check primitive operations

      Elmt := First_Elmt (Op_List);
      while Present (Elmt) loop
         Subp := Node (Elmt);
         Alias_Subp := Alias (Subp);

         --  Inherited subprograms are identified by the fact that they do not
         --  come from source, and the associated source location is the
         --  location of the first subtype of the derived type.

         --  Ada 2005 (AI-228): Apply the rules of RM-3.9.3(6/2) for
         --  subprograms that "require overriding".

         --  Special exception, do not complain about failure to override the
         --  stream routines _Input and _Output, as well as the primitive
         --  operations used in dispatching selects since we always provide
         --  automatic overridings for these subprograms.

         --  The partial view of T may have been a private extension, for
         --  which inherited functions dispatching on result are abstract.
         --  If the full view is a null extension, there is no need for
         --  overriding in Ada 2005, but wrappers need to be built for them
         --  (see exp_ch3, Build_Controlling_Function_Wrappers).

         if Is_Null_Extension (T)
           and then Has_Controlling_Result (Subp)
           and then Ada_Version >= Ada_2005
           and then Present (Alias_Subp)
           and then not Comes_From_Source (Subp)
           and then not Is_Abstract_Subprogram (Alias_Subp)
           and then not Is_Access_Type (Etype (Subp))
         then
            null;

         --  Ada 2005 (AI-251): Internal entities of interfaces need no
         --  processing because this check is done with the aliased
         --  entity

         elsif Present (Interface_Alias (Subp)) then
            null;

         --  AI12-0042: Test for rule in 7.3.2(6.1/4), that requires overriding
         --  of a visible private primitive inherited from an ancestor with
         --  the aspect Type_Invariant'Class, unless the inherited primitive
         --  is abstract.

         elsif not Is_Abstract_Subprogram (Subp)
           and then not Comes_From_Source (Subp) -- An inherited subprogram
           and then Requires_Overriding (Subp)
           and then Present (Alias_Subp)
           and then Has_Invariants (Etype (T))
           and then Present (Get_Pragma (Etype (T), Pragma_Invariant))
           and then Class_Present (Get_Pragma (Etype (T), Pragma_Invariant))
           and then Is_Private_Primitive (Alias_Subp)
         then
            Error_Msg_NE
              ("inherited private primitive & must be overridden", T, Subp);
            Error_Msg_N
              ("\because ancestor type has 'Type_'Invariant''Class " &
               "(RM 7.3.2(6.1))", T);

         elsif (Is_Abstract_Subprogram (Subp)
                 or else Requires_Overriding (Subp)
                 or else
                   (Has_Controlling_Result (Subp)
                     and then Present (Alias_Subp)
                     and then not Comes_From_Source (Subp)
                     and then Sloc (Subp) = Sloc (First_Subtype (T))))
           and then not Is_TSS (Subp, TSS_Stream_Input)
           and then not Is_TSS (Subp, TSS_Stream_Output)
           and then not Is_Abstract_Type (T)
           and then not Is_Predefined_Interface_Primitive (Subp)

            --  Ada 2005 (AI-251): Do not consider hidden entities associated
            --  with abstract interface types because the check will be done
            --  with the aliased entity (otherwise we generate a duplicated
            --  error message).

           and then not Present (Interface_Alias (Subp))
         then
            if Present (Alias_Subp) then

               --  Only perform the check for a derived subprogram when the
               --  type has an explicit record extension. This avoids incorrect
               --  flagging of abstract subprograms for the case of a type
               --  without an extension that is derived from a formal type
               --  with a tagged actual (can occur within a private part).

               --  Ada 2005 (AI-391): In the case of an inherited function with
               --  a controlling result of the type, the rule does not apply if
               --  the type is a null extension (unless the parent function
               --  itself is abstract, in which case the function must still be
               --  be overridden). The expander will generate an overriding
               --  wrapper function calling the parent subprogram (see
               --  Exp_Ch3.Make_Controlling_Wrapper_Functions).

               Type_Def := Type_Definition (Parent (T));

               if Nkind (Type_Def) = N_Derived_Type_Definition
                 and then Present (Record_Extension_Part (Type_Def))
                 and then
                   (Ada_Version < Ada_2005
                      or else not Is_Null_Extension (T)
                      or else Ekind (Subp) = E_Procedure
                      or else not Has_Controlling_Result (Subp)
                      or else Is_Abstract_Subprogram (Alias_Subp)
                      or else Requires_Overriding (Subp)
                      or else Is_Access_Type (Etype (Subp)))
               then
                  --  Avoid reporting error in case of abstract predefined
                  --  primitive inherited from interface type because the
                  --  body of internally generated predefined primitives
                  --  of tagged types are generated later by Freeze_Type

                  if Is_Interface (Root_Type (T))
                    and then Is_Abstract_Subprogram (Subp)
                    and then Is_Predefined_Dispatching_Operation (Subp)
                    and then not Comes_From_Source (Ultimate_Alias (Subp))
                  then
                     null;

                  --  A null extension is not obliged to override an inherited
                  --  procedure subject to pragma Extensions_Visible with value
                  --  False and at least one controlling OUT parameter
                  --  (SPARK RM 6.1.7(6)).

                  elsif Is_Null_Extension (T)
                    and then Is_EVF_Procedure (Subp)
                  then
                     null;

                  --  Subprogram renamings cannot be overridden

                  elsif Comes_From_Source (Subp)
                     and then Present (Alias (Subp))
                  then
                     null;

                  --  Skip reporting the error on Ada 2022 only subprograms
                  --  that require overriding if we are not in Ada 2022 mode.

                  elsif Ada_Version < Ada_2022
                    and then Requires_Overriding (Subp)
                    and then Is_Ada_2022_Only (Ultimate_Alias (Subp))
                  then
                     null;

                  else
                     Error_Msg_NE
                       ("type must be declared abstract or & overridden",
                        T, Subp);

                     --  Traverse the whole chain of aliased subprograms to
                     --  complete the error notification. This is especially
                     --  useful for traceability of the chain of entities when
                     --  the subprogram corresponds with an interface
                     --  subprogram (which may be defined in another package).

                     if Present (Alias_Subp) then
                        declare
                           E : Entity_Id;

                        begin
                           E := Subp;
                           while Present (Alias (E)) loop

                              --  Avoid reporting redundant errors on entities
                              --  inherited from interfaces

                              if Sloc (E) /= Sloc (T) then
                                 Error_Msg_Sloc := Sloc (E);
                                 Error_Msg_NE
                                   ("\& has been inherited #", T, Subp);
                              end if;

                              E := Alias (E);
                           end loop;

                           Error_Msg_Sloc := Sloc (E);

                           --  AI05-0068: report if there is an overriding
                           --  non-abstract subprogram that is invisible.

                           if Is_Hidden (E)
                             and then not Is_Abstract_Subprogram (E)
                           then
                              Error_Msg_NE
                                ("\& subprogram# is not visible",
                                 T, Subp);

                           --  Clarify the case where a non-null extension must
                           --  override inherited procedure subject to pragma
                           --  Extensions_Visible with value False and at least
                           --  one controlling OUT param.

                           elsif Is_EVF_Procedure (E) then
                              Error_Msg_NE
                                ("\& # is subject to Extensions_Visible False",
                                 T, Subp);

                           else
                              Error_Msg_NE
                                ("\& has been inherited from subprogram #",
                                 T, Subp);
                           end if;
                        end;
                     end if;
                  end if;

               --  Ada 2005 (AI-345): Protected or task type implementing
               --  abstract interfaces.

               elsif Is_Concurrent_Record_Type (T)
                 and then Present (Interfaces (T))
               then
                  --  There is no need to check here RM 9.4(11.9/3) since we
                  --  are processing the corresponding record type and the
                  --  mode of the overriding subprograms was verified by
                  --  Check_Conformance when the corresponding concurrent
                  --  type declaration was analyzed.

                  Error_Msg_NE
                    ("interface subprogram & must be overridden", T, Subp);

                  --  Examine primitive operations of synchronized type to find
                  --  homonyms that have the wrong profile.

                  declare
                     Prim : Entity_Id;

                  begin
                     Prim := First_Entity (Corresponding_Concurrent_Type (T));
                     while Present (Prim) loop
                        if Chars (Prim) = Chars (Subp) then
                           Error_Msg_NE
                             ("profile is not type conformant with prefixed "
                              & "view profile of inherited operation&",
                              Prim, Subp);
                        end if;

                        Next_Entity (Prim);
                     end loop;
                  end;
               end if;

            else
               Error_Msg_Node_2 := T;
               Error_Msg_N
                 ("abstract subprogram& not allowed for type&", Subp);

               --  Also post unconditional warning on the type (unconditional
               --  so that if there are more than one of these cases, we get
               --  them all, and not just the first one).

               Error_Msg_Node_2 := Subp;
               Error_Msg_N ("nonabstract type& has abstract subprogram&!", T);
            end if;

         --  A subprogram subject to pragma Extensions_Visible with value
         --  "True" cannot override a subprogram subject to the same pragma
         --  with value "False" (SPARK RM 6.1.7(5)).

         elsif Extensions_Visible_Status (Subp) = Extensions_Visible_True
           and then Present (Overridden_Operation (Subp))
           and then Extensions_Visible_Status (Overridden_Operation (Subp)) =
                    Extensions_Visible_False
         then
            Error_Msg_Sloc := Sloc (Overridden_Operation (Subp));
            Error_Msg_N
              ("subprogram & with Extensions_Visible True cannot override "
               & "subprogram # with Extensions_Visible False", Subp);
         end if;

         --  Ada 2012 (AI05-0030): Perform checks related to pragma Implemented

         --  Subp is an expander-generated procedure which maps an interface
         --  alias to a protected wrapper. The interface alias is flagged by
         --  pragma Implemented. Ensure that Subp is a procedure when the
         --  implementation kind is By_Protected_Procedure or an entry when
         --  By_Entry.

         if Ada_Version >= Ada_2012
           and then Is_Hidden (Subp)
           and then Present (Interface_Alias (Subp))
           and then Has_Rep_Pragma (Interface_Alias (Subp), Name_Implemented)
         then
            Check_Pragma_Implemented (Subp);
         end if;

         --  Subp is an interface primitive which overrides another interface
         --  primitive marked with pragma Implemented.

         if Ada_Version >= Ada_2012
           and then Present (Overridden_Operation (Subp))
           and then Has_Rep_Pragma
                      (Overridden_Operation (Subp), Name_Implemented)
         then
            --  If the overriding routine is also marked by Implemented, check
            --  that the two implementation kinds are conforming.

            if Has_Rep_Pragma (Subp, Name_Implemented) then
               Check_Pragma_Implemented
                 (Subp       => Subp,
                  Iface_Subp => Overridden_Operation (Subp));

            --  Otherwise the overriding routine inherits the implementation
            --  kind from the overridden subprogram.

            else
               Inherit_Pragma_Implemented
                 (Subp       => Subp,
                  Iface_Subp => Overridden_Operation (Subp));
            end if;
         end if;

         --  Ada 2005 (AI95-0414) and Ada 2022 (AI12-0269): Diagnose failure to
         --  match No_Return in parent, but do it unconditionally in Ada 95 too
         --  for procedures, since this is our pragma.

         if Present (Overridden_Operation (Subp))
           and then No_Return (Overridden_Operation (Subp))
         then

            --  If the subprogram is a renaming, check that the renamed
            --  subprogram is No_Return.

            if Present (Renamed_Or_Alias (Subp)) then
               if not No_Return (Renamed_Or_Alias (Subp)) then
                  Error_Msg_NE ("subprogram & must be No_Return",
                    Subp,
                    Renamed_Or_Alias (Subp));
                  Error_Msg_N ("\since renaming & overrides No_Return "
                    & "subprogram (RM 6.5.1(6/2))",
                    Subp);
               end if;

            --  Make sure that the subprogram itself is No_Return.

            elsif not No_Return (Subp) then
               Error_Msg_N ("overriding subprogram & must be No_Return", Subp);
               Error_Msg_N
                 ("\since overridden subprogram is No_Return (RM 6.5.1(6/2))",
                  Subp);
            end if;
         end if;

         --  If the operation is a wrapper for a synchronized primitive, it
         --  may be called indirectly through a dispatching select. We assume
         --  that it will be referenced elsewhere indirectly, and suppress
         --  warnings about an unused entity.

         if Is_Primitive_Wrapper (Subp)
           and then Present (Wrapped_Entity (Subp))
         then
            Set_Referenced (Wrapped_Entity (Subp));
         end if;

         Next_Elmt (Elmt);
      end loop;
   end Check_Abstract_Overriding;

   ------------------------------------------------
   -- Check_Access_Discriminant_Requires_Limited --
   ------------------------------------------------

   procedure Check_Access_Discriminant_Requires_Limited
     (D   : Node_Id;
      Loc : Node_Id)
   is
   begin
      --  A discriminant_specification for an access discriminant shall appear
      --  only in the declaration for a task or protected type, or for a type
      --  with the reserved word 'limited' in its definition or in one of its
      --  ancestors (RM 3.7(10)).

      --  AI-0063: The proper condition is that type must be immutably limited,
      --  or else be a partial view.

      if Nkind (Discriminant_Type (D)) = N_Access_Definition then
         if Is_Limited_View (Current_Scope)
           or else
             (Nkind (Parent (Current_Scope)) = N_Private_Type_Declaration
               and then Limited_Present (Parent (Current_Scope)))
         then
            null;

         else
            Error_Msg_N
              ("access discriminants allowed only for limited types", Loc);
         end if;
      end if;
   end Check_Access_Discriminant_Requires_Limited;

   -----------------------------------
   -- Check_Aliased_Component_Types --
   -----------------------------------

   procedure Check_Aliased_Component_Types (T : Entity_Id) is
      C : Entity_Id;

   begin
      --  ??? Also need to check components of record extensions, but not
      --  components of protected types (which are always limited).

      --  Ada 2005: AI-363 relaxes this rule, to allow heap objects of such
      --  types to be unconstrained. This is safe because it is illegal to
      --  create access subtypes to such types with explicit discriminant
      --  constraints.

      if not Is_Limited_Type (T) then
         if Ekind (T) = E_Record_Type then
            C := First_Component (T);
            while Present (C) loop
               if Is_Aliased (C)
                 and then Has_Discriminants (Etype (C))
                 and then not Is_Constrained (Etype (C))
                 and then not In_Instance_Body
                 and then Ada_Version < Ada_2005
               then
                  Error_Msg_N
                    ("aliased component must be constrained (RM 3.6(11))",
                      C);
               end if;

               Next_Component (C);
            end loop;

         elsif Ekind (T) = E_Array_Type then
            if Has_Aliased_Components (T)
              and then Has_Discriminants (Component_Type (T))
              and then not Is_Constrained (Component_Type (T))
              and then not In_Instance_Body
              and then Ada_Version < Ada_2005
            then
               Error_Msg_N
                 ("aliased component type must be constrained (RM 3.6(11))",
                    T);
            end if;
         end if;
      end if;
   end Check_Aliased_Component_Types;

   --------------------------------------
   -- Check_Anonymous_Access_Component --
   --------------------------------------

   procedure Check_Anonymous_Access_Component
     (Typ_Decl   : Node_Id;
      Typ        : Entity_Id;
      Prev       : Entity_Id;
      Comp_Def   : Node_Id;
      Access_Def : Node_Id)
   is
      Loc         : constant Source_Ptr := Sloc (Comp_Def);
      Anon_Access : Entity_Id;
      Acc_Def     : Node_Id;
      Decl        : Node_Id;
      Type_Def    : Node_Id;

      procedure Build_Incomplete_Type_Declaration;
      --  If the record type contains components that include an access to the
      --  current record, then create an incomplete type declaration for the
      --  record, to be used as the designated type of the anonymous access.
      --  This is done only once, and only if there is no previous partial
      --  view of the type.

      function Designates_T (Subt : Node_Id) return Boolean;
      --  Check whether a node designates the enclosing record type, or 'Class
      --  of that type

      function Mentions_T (Acc_Def : Node_Id) return Boolean;
      --  Check whether an access definition includes a reference to
      --  the enclosing record type. The reference can be a subtype mark
      --  in the access definition itself, a 'Class attribute reference, or
      --  recursively a reference appearing in a parameter specification
      --  or result definition of an access_to_subprogram definition.

      --------------------------------------
      -- Build_Incomplete_Type_Declaration --
      --------------------------------------

      procedure Build_Incomplete_Type_Declaration is
         Decl  : Node_Id;
         Inc_T : Entity_Id;
         H     : Entity_Id;

         --  Is_Tagged indicates whether the type is tagged. It is tagged if
         --  it's "is new ... with record" or else "is tagged record ...".

         Typ_Def   : constant Node_Id :=
           (if Nkind (Typ_Decl) = N_Full_Type_Declaration
            then Type_Definition (Typ_Decl) else Empty);
         Is_Tagged : constant Boolean :=
           Present (Typ_Def)
             and then
               ((Nkind (Typ_Def) = N_Derived_Type_Definition
                  and then
                    Present (Record_Extension_Part (Typ_Def)))
                or else
                  (Nkind (Typ_Def) = N_Record_Definition
                    and then Tagged_Present (Typ_Def)));

      begin
         --  If there is a previous partial view, no need to create a new one
         --  If the partial view, given by Prev, is incomplete,  If Prev is
         --  a private declaration, full declaration is flagged accordingly.

         if Prev /= Typ then
            if Is_Tagged then
               Make_Class_Wide_Type (Prev);
               Set_Class_Wide_Type (Typ, Class_Wide_Type (Prev));
               Set_Etype (Class_Wide_Type (Typ), Typ);
            end if;

            return;

         elsif Has_Private_Declaration (Typ) then

            --  If we refer to T'Class inside T, and T is the completion of a
            --  private type, then make sure the class-wide type exists.

            if Is_Tagged then
               Make_Class_Wide_Type (Typ);
            end if;

            return;

         --  If there was a previous anonymous access type, the incomplete
         --  type declaration will have been created already.

         elsif Present (Current_Entity (Typ))
           and then Ekind (Current_Entity (Typ)) = E_Incomplete_Type
           and then Full_View (Current_Entity (Typ)) = Typ
         then
            if Is_Tagged
              and then Comes_From_Source (Current_Entity (Typ))
              and then not Is_Tagged_Type (Current_Entity (Typ))
            then
               Make_Class_Wide_Type (Typ);
               Error_Msg_N
                 ("incomplete view of tagged type should be declared tagged??",
                  Parent (Current_Entity (Typ)));
            end if;
            return;

         else
            Inc_T := Make_Defining_Identifier (Loc, Chars (Typ));
            Decl  := Make_Incomplete_Type_Declaration (Loc, Inc_T);

            --  Type has already been inserted into the current scope. Remove
            --  it, and add incomplete declaration for type, so that subsequent
            --  anonymous access types can use it. The entity is unchained from
            --  the homonym list and from immediate visibility. After analysis,
            --  the entity in the incomplete declaration becomes immediately
            --  visible in the record declaration that follows.

            H := Current_Entity (Typ);

            if H = Typ then
               Set_Name_Entity_Id (Chars (Typ), Homonym (Typ));
            else
               while Present (H)
                 and then Homonym (H) /= Typ
               loop
                  H := Homonym (Typ);
               end loop;

               Set_Homonym (H, Homonym (Typ));
            end if;

            Insert_Before (Typ_Decl, Decl);
            Analyze (Decl);
            Set_Full_View (Inc_T, Typ);

            if Is_Tagged then

               --  Create a common class-wide type for both views, and set the
               --  Etype of the class-wide type to the full view.

               Make_Class_Wide_Type (Inc_T);
               Set_Class_Wide_Type (Typ, Class_Wide_Type (Inc_T));
               Set_Etype (Class_Wide_Type (Typ), Typ);
            end if;
         end if;
      end Build_Incomplete_Type_Declaration;

      ------------------
      -- Designates_T --
      ------------------

      function Designates_T (Subt : Node_Id) return Boolean is
         Type_Id : constant Name_Id := Chars (Typ);

         function Names_T (Nam : Node_Id) return Boolean;
         --  The record type has not been introduced in the current scope
         --  yet, so we must examine the name of the type itself, either
         --  an identifier T, or an expanded name of the form P.T, where
         --  P denotes the current scope.

         -------------
         -- Names_T --
         -------------

         function Names_T (Nam : Node_Id) return Boolean is
         begin
            if Nkind (Nam) = N_Identifier then
               return Chars (Nam) = Type_Id;

            elsif Nkind (Nam) = N_Selected_Component then
               if Chars (Selector_Name (Nam)) = Type_Id then
                  if Nkind (Prefix (Nam)) = N_Identifier then
                     return Chars (Prefix (Nam)) = Chars (Current_Scope);

                  elsif Nkind (Prefix (Nam)) = N_Selected_Component then
                     return Chars (Selector_Name (Prefix (Nam))) =
                            Chars (Current_Scope);
                  else
                     return False;
                  end if;

               else
                  return False;
               end if;

            else
               return False;
            end if;
         end Names_T;

      --  Start of processing for Designates_T

      begin
         if Nkind (Subt) = N_Identifier then
            return Chars (Subt) = Type_Id;

            --  Reference can be through an expanded name which has not been
            --  analyzed yet, and which designates enclosing scopes.

         elsif Nkind (Subt) = N_Selected_Component then
            if Names_T (Subt) then
               return True;

            --  Otherwise it must denote an entity that is already visible.
            --  The access definition may name a subtype of the enclosing
            --  type, if there is a previous incomplete declaration for it.

            else
               Find_Selected_Component (Subt);
               return
                 Is_Entity_Name (Subt)
                   and then Scope (Entity (Subt)) = Current_Scope
                   and then
                     (Chars (Base_Type (Entity (Subt))) = Type_Id
                       or else
                         (Is_Class_Wide_Type (Entity (Subt))
                           and then
                             Chars (Etype (Base_Type (Entity (Subt)))) =
                                                                  Type_Id));
            end if;

         --  A reference to the current type may appear as the prefix of
         --  a 'Class attribute.

         elsif Nkind (Subt) = N_Attribute_Reference
           and then Attribute_Name (Subt) = Name_Class
         then
            return Names_T (Prefix (Subt));

         else
            return False;
         end if;
      end Designates_T;

      ----------------
      -- Mentions_T --
      ----------------

      function Mentions_T (Acc_Def : Node_Id) return Boolean is
         Param_Spec : Node_Id;

         Acc_Subprg : constant Node_Id :=
                        Access_To_Subprogram_Definition (Acc_Def);

      begin
         if No (Acc_Subprg) then
            return Designates_T (Subtype_Mark (Acc_Def));
         end if;

         --  Component is an access_to_subprogram: examine its formals,
         --  and result definition in the case of an access_to_function.

         Param_Spec := First (Parameter_Specifications (Acc_Subprg));
         while Present (Param_Spec) loop
            if Nkind (Parameter_Type (Param_Spec)) = N_Access_Definition
              and then Mentions_T (Parameter_Type (Param_Spec))
            then
               return True;

            elsif Designates_T (Parameter_Type (Param_Spec)) then
               return True;
            end if;

            Next (Param_Spec);
         end loop;

         if Nkind (Acc_Subprg) = N_Access_Function_Definition then
            if Nkind (Result_Definition (Acc_Subprg)) =
                 N_Access_Definition
            then
               return Mentions_T (Result_Definition (Acc_Subprg));
            else
               return Designates_T (Result_Definition (Acc_Subprg));
            end if;
         end if;

         return False;
      end Mentions_T;

   --  Start of processing for Check_Anonymous_Access_Component

   begin
      if Present (Access_Def) and then Mentions_T (Access_Def) then
         Acc_Def := Access_To_Subprogram_Definition (Access_Def);

         Build_Incomplete_Type_Declaration;
         Anon_Access := Make_Temporary (Loc, 'S');

         --  Create a declaration for the anonymous access type: either
         --  an access_to_object or an access_to_subprogram.

         if Present (Acc_Def) then
            if Nkind (Acc_Def) = N_Access_Function_Definition then
               Type_Def :=
                 Make_Access_Function_Definition (Loc,
                   Parameter_Specifications =>
                     Parameter_Specifications (Acc_Def),
                   Result_Definition        => Result_Definition (Acc_Def));
            else
               Type_Def :=
                 Make_Access_Procedure_Definition (Loc,
                   Parameter_Specifications =>
                     Parameter_Specifications (Acc_Def));
            end if;

         else
            Type_Def :=
              Make_Access_To_Object_Definition (Loc,
                Subtype_Indication =>
                   Relocate_Node (Subtype_Mark (Access_Def)));

            Set_Constant_Present (Type_Def, Constant_Present (Access_Def));
            Set_All_Present (Type_Def, All_Present (Access_Def));
         end if;

         Set_Null_Exclusion_Present
           (Type_Def, Null_Exclusion_Present (Access_Def));

         Decl :=
           Make_Full_Type_Declaration (Loc,
             Defining_Identifier => Anon_Access,
             Type_Definition     => Type_Def);

         Insert_Before (Typ_Decl, Decl);
         Analyze (Decl);

         --  If an access to subprogram, create the extra formals

         if Present (Acc_Def) then
            Create_Extra_Formals (Designated_Type (Anon_Access));
         end if;

         if Nkind (Comp_Def) = N_Component_Definition then
            Rewrite (Comp_Def,
              Make_Component_Definition (Loc,
                Subtype_Indication => New_Occurrence_Of (Anon_Access, Loc)));
         else
            pragma Assert (Nkind (Comp_Def) = N_Discriminant_Specification);
            Rewrite (Comp_Def,
              Make_Discriminant_Specification (Loc,
                Defining_Identifier => Defining_Identifier (Comp_Def),
                Discriminant_Type   => New_Occurrence_Of (Anon_Access, Loc)));
         end if;

         if Ekind (Designated_Type (Anon_Access)) = E_Subprogram_Type then
            Mutate_Ekind (Anon_Access, E_Anonymous_Access_Subprogram_Type);
         else
            Mutate_Ekind (Anon_Access, E_Anonymous_Access_Type);
         end if;

         Set_Is_Local_Anonymous_Access (Anon_Access);
      end if;
   end Check_Anonymous_Access_Component;

   ---------------------------------------
   -- Check_Anonymous_Access_Components --
   ---------------------------------------

   procedure Check_Anonymous_Access_Components
     (Typ_Decl  : Node_Id;
      Typ       : Entity_Id;
      Prev      : Entity_Id;
      Comp_List : Node_Id)
   is
      Comp : Node_Id;
   begin
      if No (Comp_List) then
         return;
      end if;

      Comp := First (Component_Items (Comp_List));
      while Present (Comp) loop
         if Nkind (Comp) = N_Component_Declaration then
            Check_Anonymous_Access_Component
              (Typ_Decl, Typ, Prev,
               Component_Definition (Comp),
               Access_Definition (Component_Definition (Comp)));
         end if;

         Next (Comp);
      end loop;

      if Present (Variant_Part (Comp_List)) then
         declare
            V : Node_Id;
         begin
            V := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
            while Present (V) loop
               Check_Anonymous_Access_Components
                 (Typ_Decl, Typ, Prev, Component_List (V));
               Next_Non_Pragma (V);
            end loop;
         end;
      end if;
   end Check_Anonymous_Access_Components;

   ----------------------
   -- Check_Completion --
   ----------------------

   procedure Check_Completion (Body_Id : Node_Id := Empty) is
      E : Entity_Id;

      procedure Post_Error;
      --  Post error message for lack of completion for entity E

      ----------------
      -- Post_Error --
      ----------------

      procedure Post_Error is
         procedure Missing_Body;
         --  Output missing body message

         ------------------
         -- Missing_Body --
         ------------------

         procedure Missing_Body is
         begin
            --  Spec is in same unit, so we can post on spec

            if In_Same_Source_Unit (Body_Id, E) then
               Error_Msg_N ("missing body for &", E);

            --  Spec is in a separate unit, so we have to post on the body

            else
               Error_Msg_NE ("missing body for & declared#!", Body_Id, E);
            end if;
         end Missing_Body;

      --  Start of processing for Post_Error

      begin
         if not Comes_From_Source (E) then
            if Ekind (E) in E_Task_Type | E_Protected_Type then

               --  It may be an anonymous protected type created for a
               --  single variable. Post error on variable, if present.

               declare
                  Var : Entity_Id;

               begin
                  Var := First_Entity (Current_Scope);
                  while Present (Var) loop
                     exit when Etype (Var) = E
                       and then Comes_From_Source (Var);

                     Next_Entity (Var);
                  end loop;

                  if Present (Var) then
                     E := Var;
                  end if;
               end;
            end if;
         end if;

         --  If a generated entity has no completion, then either previous
         --  semantic errors have disabled the expansion phase, or else we had
         --  missing subunits, or else we are compiling without expansion,
         --  or else something is very wrong.

         if not Comes_From_Source (E) then
            pragma Assert
              (Serious_Errors_Detected > 0
                or else Configurable_Run_Time_Violations > 0
                or else Subunits_Missing
                or else not Expander_Active);
            return;

         --  Here for source entity

         else
            --  Here if no body to post the error message, so we post the error
            --  on the declaration that has no completion. This is not really
            --  the right place to post it, think about this later ???

            if No (Body_Id) then
               if Is_Type (E) then
                  Error_Msg_NE
                    ("missing full declaration for }", Parent (E), E);
               else
                  Error_Msg_NE ("missing body for &", Parent (E), E);
               end if;

            --  Package body has no completion for a declaration that appears
            --  in the corresponding spec. Post error on the body, with a
            --  reference to the non-completed declaration.

            else
               Error_Msg_Sloc := Sloc (E);

               if Is_Type (E) then
                  Error_Msg_NE ("missing full declaration for }!", Body_Id, E);

               elsif Is_Overloadable (E)
                 and then Current_Entity_In_Scope (E) /= E
               then
                  --  It may be that the completion is mistyped and appears as
                  --  a distinct overloading of the entity.

                  declare
                     Candidate : constant Entity_Id :=
                                   Current_Entity_In_Scope (E);
                     Decl      : constant Node_Id :=
                                   Unit_Declaration_Node (Candidate);

                  begin
                     if Is_Overloadable (Candidate)
                       and then Ekind (Candidate) = Ekind (E)
                       and then Nkind (Decl) = N_Subprogram_Body
                       and then Acts_As_Spec (Decl)
                     then
                        Check_Type_Conformant (Candidate, E);

                     else
                        Missing_Body;
                     end if;
                  end;

               else
                  Missing_Body;
               end if;
            end if;
         end if;
      end Post_Error;

      --  Local variables

      Pack_Id : constant Entity_Id := Current_Scope;

   --  Start of processing for Check_Completion

   begin
      E := First_Entity (Pack_Id);
      while Present (E) loop
         if Is_Intrinsic_Subprogram (E) then
            null;

         --  The following situation requires special handling: a child unit
         --  that appears in the context clause of the body of its parent:

         --    procedure Parent.Child (...);

         --    with Parent.Child;
         --    package body Parent is

         --  Here Parent.Child appears as a local entity, but should not be
         --  flagged as requiring completion, because it is a compilation
         --  unit.

         --  Ignore missing completion for a subprogram that does not come from
         --  source (including the _Call primitive operation of RAS types,
         --  which has to have the flag Comes_From_Source for other purposes):
         --  we assume that the expander will provide the missing completion.
         --  In case of previous errors, other expansion actions that provide
         --  bodies for null procedures with not be invoked, so inhibit message
         --  in those cases.

         --  Note that E_Operator is not in the list that follows, because
         --  this kind is reserved for predefined operators, that are
         --  intrinsic and do not need completion.

         elsif Ekind (E) in E_Function
                          | E_Procedure
                          | E_Generic_Function
                          | E_Generic_Procedure
         then
            if Has_Completion (E) then
               null;

            elsif Is_Subprogram (E) and then Is_Abstract_Subprogram (E) then
               null;

            elsif Is_Subprogram (E)
              and then (not Comes_From_Source (E)
                         or else Chars (E) = Name_uCall)
            then
               null;

            elsif
               Nkind (Parent (Unit_Declaration_Node (E))) = N_Compilation_Unit
            then
               null;

            elsif Nkind (Parent (E)) = N_Procedure_Specification
              and then Null_Present (Parent (E))
              and then Serious_Errors_Detected > 0
            then
               null;

            else
               Post_Error;
            end if;

         elsif Is_Entry (E) then
            if not Has_Completion (E)
              and then Ekind (Scope (E)) = E_Protected_Type
            then
               Post_Error;
            end if;

         elsif Is_Package_Or_Generic_Package (E) then
            if Unit_Requires_Body (E) then
               if not Has_Completion (E)
                 and then Nkind (Parent (Unit_Declaration_Node (E))) /=
                                                       N_Compilation_Unit
               then
                  Post_Error;
               end if;

            elsif not Is_Child_Unit (E) then
               May_Need_Implicit_Body (E);
            end if;

         --  A formal incomplete type (Ada 2012) does not require a completion;
         --  other incomplete type declarations do.

         elsif Ekind (E) = E_Incomplete_Type then
            if No (Underlying_Type (E))
              and then not Is_Generic_Type (E)
            then
               Post_Error;
            end if;

         elsif Ekind (E) in E_Task_Type | E_Protected_Type then
            if not Has_Completion (E) then
               Post_Error;
            end if;

         --  A single task declared in the current scope is a constant, verify
         --  that the body of its anonymous type is in the same scope. If the
         --  task is defined elsewhere, this may be a renaming declaration for
         --  which no completion is needed.

         elsif Ekind (E) = E_Constant then
            if Ekind (Etype (E)) = E_Task_Type
              and then not Has_Completion (Etype (E))
              and then Scope (Etype (E)) = Current_Scope
            then
               Post_Error;
            end if;

         elsif Ekind (E) = E_Record_Type then
            if Is_Tagged_Type (E) then
               Check_Abstract_Overriding (E);
               Check_Conventions (E);
            end if;

            Check_Aliased_Component_Types (E);

         elsif Ekind (E) = E_Array_Type then
            Check_Aliased_Component_Types (E);

         end if;

         Next_Entity (E);
      end loop;
   end Check_Completion;

   -------------------------------------
   -- Check_Constraining_Discriminant --
   -------------------------------------

   procedure Check_Constraining_Discriminant (New_Disc, Old_Disc : Entity_Id)
   is
      New_Type : constant Entity_Id := Etype (New_Disc);
      Old_Type : Entity_Id;

   begin
      --  If the record type contains an array constrained by the discriminant
      --  but with some different bound, the compiler tries to create a smaller
      --  range for the discriminant type (see exp_ch3.Adjust_Discriminants).
      --  In this case, where the discriminant type is a scalar type, the check
      --  must use the original discriminant type in the parent declaration.

      if Is_Scalar_Type (New_Type) then
         Old_Type := Entity (Discriminant_Type (Parent (Old_Disc)));
      else
         Old_Type := Etype (Old_Disc);
      end if;

      if not Subtypes_Statically_Compatible (New_Type, Old_Type) then
         Error_Msg_N
           ("subtype must be statically compatible with parent discriminant",
            New_Disc);

         if not Predicates_Compatible (New_Type, Old_Type) then
            Error_Msg_N
              ("\subtype predicate is not compatible with parent discriminant",
               New_Disc);
         end if;
      end if;
   end Check_Constraining_Discriminant;

   ------------------------------------
   -- Check_CPP_Type_Has_No_Defaults --
   ------------------------------------

   procedure Check_CPP_Type_Has_No_Defaults (T : Entity_Id) is
      Tdef  : constant Node_Id := Type_Definition (Declaration_Node (T));
      Clist : Node_Id;
      Comp  : Node_Id;

   begin
      --  Obtain the component list

      if Nkind (Tdef) = N_Record_Definition then
         Clist := Component_List (Tdef);
      else pragma Assert (Nkind (Tdef) = N_Derived_Type_Definition);
         Clist := Component_List (Record_Extension_Part (Tdef));
      end if;

      --  Check all components to ensure no default expressions

      if Present (Clist) then
         Comp := First (Component_Items (Clist));
         while Present (Comp) loop
            if Present (Expression (Comp)) then
               Error_Msg_N
                 ("component of imported 'C'P'P type cannot have "
                  & "default expression", Expression (Comp));
            end if;

            Next (Comp);
         end loop;
      end if;
   end Check_CPP_Type_Has_No_Defaults;

   ----------------------------
   -- Check_Delta_Expression --
   ----------------------------

   procedure Check_Delta_Expression (E : Node_Id) is
   begin
      if not (Is_Real_Type (Etype (E))) then
         Wrong_Type (E, Any_Real);

      elsif not Is_OK_Static_Expression (E) then
         Flag_Non_Static_Expr
           ("non-static expression used for delta value!", E);

      elsif not UR_Is_Positive (Expr_Value_R (E)) then
         Error_Msg_N ("delta expression must be positive", E);

      else
         return;
      end if;

      --  If any of above errors occurred, then replace the incorrect
      --  expression by the real 0.1, which should prevent further errors.

      Rewrite (E,
        Make_Real_Literal (Sloc (E), Ureal_Tenth));
      Analyze_And_Resolve (E, Standard_Float);
   end Check_Delta_Expression;

   -----------------------------
   -- Check_Digits_Expression --
   -----------------------------

   procedure Check_Digits_Expression (E : Node_Id) is
   begin
      if not (Is_Integer_Type (Etype (E))) then
         Wrong_Type (E, Any_Integer);

      elsif not Is_OK_Static_Expression (E) then
         Flag_Non_Static_Expr
           ("non-static expression used for digits value!", E);

      elsif Expr_Value (E) <= 0 then
         Error_Msg_N ("digits value must be greater than zero", E);

      else
         return;
      end if;

      --  If any of above errors occurred, then replace the incorrect
      --  expression by the integer 1, which should prevent further errors.

      Rewrite (E, Make_Integer_Literal (Sloc (E), 1));
      Analyze_And_Resolve (E, Standard_Integer);

   end Check_Digits_Expression;

   --------------------------
   -- Check_Initialization --
   --------------------------

   procedure Check_Initialization (T : Entity_Id; Exp : Node_Id) is
   begin
      --  Special processing for limited types

      if Is_Limited_Type (T)
        and then not In_Instance
        and then not In_Inlined_Body
      then
         if not OK_For_Limited_Init (T, Exp) then

            --  In GNAT mode, this is just a warning, to allow it to be evilly
            --  turned off. Otherwise it is a real error.

            if GNAT_Mode then
               Error_Msg_N
                 ("??cannot initialize entities of limited type!", Exp);

            elsif Ada_Version < Ada_2005 then

               --  The side effect removal machinery may generate illegal Ada
               --  code to avoid the usage of access types and 'reference in
               --  SPARK mode. Since this is legal code with respect to theorem
               --  proving, do not emit the error.

               if GNATprove_Mode
                 and then Nkind (Exp) = N_Function_Call
                 and then Nkind (Parent (Exp)) = N_Object_Declaration
                 and then not Comes_From_Source
                                (Defining_Identifier (Parent (Exp)))
               then
                  null;

               else
                  Error_Msg_N
                    ("cannot initialize entities of limited type", Exp);
                  Explain_Limited_Type (T, Exp);
               end if;

            else
               --  Specialize error message according to kind of illegal
               --  initial expression. We check the Original_Node to cover
               --  cases where the initialization expression of an object
               --  declaration generated by the compiler has been rewritten
               --  (such as for dispatching calls).

               if Nkind (Original_Node (Exp)) = N_Type_Conversion
                 and then
                   Nkind (Expression (Original_Node (Exp))) = N_Function_Call
               then
                  --  No error for internally-generated object declarations,
                  --  which can come from build-in-place assignment statements.

                  if Nkind (Parent (Exp)) = N_Object_Declaration
                    and then not Comes_From_Source
                                   (Defining_Identifier (Parent (Exp)))
                  then
                     null;

                  else
                     Error_Msg_N
                       ("illegal context for call to function with limited "
                        & "result", Exp);
                  end if;

               else
                  Error_Msg_N
                    ("initialization of limited object requires aggregate or "
                     & "function call",  Exp);
               end if;
            end if;
         end if;
      end if;

      --  In gnatc or gnatprove mode, make sure set Do_Range_Check flag gets
      --  set unless we can be sure that no range check is required.

      if not Expander_Active
        and then Is_Scalar_Type (T)
        and then not Is_In_Range (Exp, T, Assume_Valid => True)
      then
         Set_Do_Range_Check (Exp);
      end if;
   end Check_Initialization;

   ----------------------
   -- Check_Interfaces --
   ----------------------

   procedure Check_Interfaces (N : Node_Id; Def : Node_Id) is
      Parent_Type : constant Entity_Id := Etype (Defining_Identifier (N));

      Iface       : Node_Id;
      Iface_Def   : Node_Id;
      Iface_Typ   : Entity_Id;
      Parent_Node : Node_Id;

      Is_Task : Boolean := False;
      --  Set True if parent type or any progenitor is a task interface

      Is_Protected : Boolean := False;
      --  Set True if parent type or any progenitor is a protected interface

      procedure Check_Ifaces (Iface_Def : Node_Id; Error_Node : Node_Id);
      --  Check that a progenitor is compatible with declaration. If an error
      --  message is output, it is posted on Error_Node.

      ------------------
      -- Check_Ifaces --
      ------------------

      procedure Check_Ifaces (Iface_Def : Node_Id; Error_Node : Node_Id) is
         Iface_Id : constant Entity_Id :=
                      Defining_Identifier (Parent (Iface_Def));
         Type_Def : Node_Id;

      begin
         if Nkind (N) = N_Private_Extension_Declaration then
            Type_Def := N;
         else
            Type_Def := Type_Definition (N);
         end if;

         if Is_Task_Interface (Iface_Id) then
            Is_Task := True;

         elsif Is_Protected_Interface (Iface_Id) then
            Is_Protected := True;
         end if;

         if Is_Synchronized_Interface (Iface_Id) then

            --  A consequence of 3.9.4 (6/2) and 7.3 (7.2/2) is that a private
            --  extension derived from a synchronized interface must explicitly
            --  be declared synchronized, because the full view will be a
            --  synchronized type.

            if Nkind (N) = N_Private_Extension_Declaration then
               if not Synchronized_Present (N) then
                  Error_Msg_NE
                    ("private extension of& must be explicitly synchronized",
                      N, Iface_Id);
               end if;

            --  However, by 3.9.4(16/2), a full type that is a record extension
            --  is never allowed to derive from a synchronized interface (note
            --  that interfaces must be excluded from this check, because those
            --  are represented by derived type definitions in some cases).

            elsif Nkind (Type_Definition (N)) = N_Derived_Type_Definition
              and then not Interface_Present (Type_Definition (N))
            then
               Error_Msg_N ("record extension cannot derive from synchronized "
                            & "interface", Error_Node);
            end if;
         end if;

         --  Check that the characteristics of the progenitor are compatible
         --  with the explicit qualifier in the declaration.
         --  The check only applies to qualifiers that come from source.
         --  Limited_Present also appears in the declaration of corresponding
         --  records, and the check does not apply to them.

         if Limited_Present (Type_Def)
           and then not
             Is_Concurrent_Record_Type (Defining_Identifier (N))
         then
            if Is_Limited_Interface (Parent_Type)
              and then not Is_Limited_Interface (Iface_Id)
            then
               Error_Msg_NE
                 ("progenitor & must be limited interface",
                   Error_Node, Iface_Id);

            elsif
              (Task_Present (Iface_Def)
                or else Protected_Present (Iface_Def)
                or else Synchronized_Present (Iface_Def))
              and then Nkind (N) /= N_Private_Extension_Declaration
              and then not Error_Posted (N)
            then
               Error_Msg_NE
                 ("progenitor & must be limited interface",
                   Error_Node, Iface_Id);
            end if;

         --  Protected interfaces can only inherit from limited, synchronized
         --  or protected interfaces.

         elsif Nkind (N) = N_Full_Type_Declaration
           and then Protected_Present (Type_Def)
         then
            if Limited_Present (Iface_Def)
              or else Synchronized_Present (Iface_Def)
              or else Protected_Present (Iface_Def)
            then
               null;

            elsif Task_Present (Iface_Def) then
               Error_Msg_N ("(Ada 2005) protected interface cannot inherit "
                            & "from task interface", Error_Node);

            else
               Error_Msg_N ("(Ada 2005) protected interface cannot inherit "
                            & "from non-limited interface", Error_Node);
            end if;

         --  Ada 2005 (AI-345): Synchronized interfaces can only inherit from
         --  limited and synchronized.

         elsif Synchronized_Present (Type_Def) then
            if Limited_Present (Iface_Def)
              or else Synchronized_Present (Iface_Def)
            then
               null;

            elsif Protected_Present (Iface_Def)
              and then Nkind (N) /= N_Private_Extension_Declaration
            then
               Error_Msg_N ("(Ada 2005) synchronized interface cannot inherit "
                            & "from protected interface", Error_Node);

            elsif Task_Present (Iface_Def)
              and then Nkind (N) /= N_Private_Extension_Declaration
            then
               Error_Msg_N ("(Ada 2005) synchronized interface cannot inherit "
                            & "from task interface", Error_Node);

            elsif not Is_Limited_Interface (Iface_Id) then
               Error_Msg_N ("(Ada 2005) synchronized interface cannot inherit "
                            & "from non-limited interface", Error_Node);
            end if;

         --  Ada 2005 (AI-345): Task interfaces can only inherit from limited,
         --  synchronized or task interfaces.

         elsif Nkind (N) = N_Full_Type_Declaration
           and then Task_Present (Type_Def)
         then
            if Limited_Present (Iface_Def)
              or else Synchronized_Present (Iface_Def)
              or else Task_Present (Iface_Def)
            then
               null;

            elsif Protected_Present (Iface_Def) then
               Error_Msg_N ("(Ada 2005) task interface cannot inherit from "
                            & "protected interface", Error_Node);

            else
               Error_Msg_N ("(Ada 2005) task interface cannot inherit from "
                            & "non-limited interface", Error_Node);
            end if;
         end if;
      end Check_Ifaces;

   --  Start of processing for Check_Interfaces

   begin
      if Is_Interface (Parent_Type) then
         if Is_Task_Interface (Parent_Type) then
            Is_Task := True;

         elsif Is_Protected_Interface (Parent_Type) then
            Is_Protected := True;
         end if;
      end if;

      if Nkind (N) = N_Private_Extension_Declaration then

         --  Check that progenitors are compatible with declaration

         Iface := First (Interface_List (Def));
         while Present (Iface) loop
            Iface_Typ := Find_Type_Of_Subtype_Indic (Iface);

            Parent_Node := Parent (Base_Type (Iface_Typ));
            Iface_Def   := Type_Definition (Parent_Node);

            if not Is_Interface (Iface_Typ) then
               Diagnose_Interface (Iface, Iface_Typ);
            else
               Check_Ifaces (Iface_Def, Iface);
            end if;

            Next (Iface);
         end loop;

         if Is_Task and Is_Protected then
            Error_Msg_N
              ("type cannot derive from task and protected interface", N);
         end if;

         return;
      end if;

      --  Full type declaration of derived type.
      --  Check compatibility with parent if it is interface type

      if Nkind (Type_Definition (N)) = N_Derived_Type_Definition
        and then Is_Interface (Parent_Type)
      then
         Parent_Node := Parent (Parent_Type);

         --  More detailed checks for interface varieties

         Check_Ifaces
           (Iface_Def  => Type_Definition (Parent_Node),
            Error_Node => Subtype_Indication (Type_Definition (N)));
      end if;

      Iface := First (Interface_List (Def));
      while Present (Iface) loop
         Iface_Typ := Find_Type_Of_Subtype_Indic (Iface);

         Parent_Node := Parent (Base_Type (Iface_Typ));
         Iface_Def   := Type_Definition (Parent_Node);

         if not Is_Interface (Iface_Typ) then
            Diagnose_Interface (Iface, Iface_Typ);

         else
            --  "The declaration of a specific descendant of an interface
            --   type freezes the interface type" RM 13.14

            Freeze_Before (N, Iface_Typ);
            Check_Ifaces (Iface_Def, Error_Node => Iface);
         end if;

         Next (Iface);
      end loop;

      if Is_Task and Is_Protected then
         Error_Msg_N
           ("type cannot derive from task and protected interface", N);
      end if;
   end Check_Interfaces;

   ------------------------------------
   -- Check_Or_Process_Discriminants --
   ------------------------------------

   --  If an incomplete or private type declaration was already given for the
   --  type, the discriminants may have already been processed if they were
   --  present on the incomplete declaration. In this case a full conformance
   --  check has been performed in Find_Type_Name, and we then recheck here
   --  some properties that can't be checked on the partial view alone.
   --  Otherwise we call Process_Discriminants.

   procedure Check_Or_Process_Discriminants
     (N    : Node_Id;
      T    : Entity_Id;
      Prev : Entity_Id := Empty)
   is
   begin
      if Has_Discriminants (T) then

         --  Discriminants are already set on T if they were already present
         --  on the partial view. Make them visible to component declarations.

         declare
            D : Entity_Id;
            --  Discriminant on T (full view) referencing expr on partial view

            Prev_D : Entity_Id;
            --  Entity of corresponding discriminant on partial view

            New_D : Node_Id;
            --  Discriminant specification for full view, expression is
            --  the syntactic copy on full view (which has been checked for
            --  conformance with partial view), only used here to post error
            --  message.

         begin
            D     := First_Discriminant (T);
            New_D := First (Discriminant_Specifications (N));
            while Present (D) loop
               Prev_D := Current_Entity (D);
               Set_Current_Entity (D);
               Set_Is_Immediately_Visible (D);
               Set_Homonym (D, Prev_D);

               --  Handle the case where there is an untagged partial view and
               --  the full view is tagged: must disallow discriminants with
               --  defaults, unless compiling for Ada 2012, which allows a
               --  limited tagged type to have defaulted discriminants (see
               --  AI05-0214). However, suppress error here if it was already
               --  reported on the default expression of the partial view.

               if Is_Tagged_Type (T)
                 and then Present (Expression (Parent (D)))
                 and then (not Is_Limited_Type (Current_Scope)
                            or else Ada_Version < Ada_2012)
                 and then not Error_Posted (Expression (Parent (D)))
               then
                  if Ada_Version >= Ada_2012 then
                     Error_Msg_N
                       ("discriminants of nonlimited tagged type cannot have "
                        & "defaults",
                        Expression (New_D));
                  else
                     Error_Msg_N
                       ("discriminants of tagged type cannot have defaults",
                        Expression (New_D));
                  end if;
               end if;

               --  Ada 2005 (AI-230): Access discriminant allowed in
               --  non-limited record types.

               if Ada_Version < Ada_2005 then

                  --  This restriction gets applied to the full type here. It
                  --  has already been applied earlier to the partial view.

                  Check_Access_Discriminant_Requires_Limited (Parent (D), N);
               end if;

               Next_Discriminant (D);
               Next (New_D);
            end loop;
         end;

      elsif Present (Discriminant_Specifications (N)) then
         Process_Discriminants (N, Prev);
      end if;
   end Check_Or_Process_Discriminants;

   ----------------------
   -- Check_Real_Bound --
   ----------------------

   procedure Check_Real_Bound (Bound : Node_Id) is
   begin
      if not Is_Real_Type (Etype (Bound)) then
         Error_Msg_N
           ("bound in real type definition must be of real type", Bound);

      elsif not Is_OK_Static_Expression (Bound) then
         Flag_Non_Static_Expr
           ("non-static expression used for real type bound!", Bound);

      else
         return;
      end if;

      Rewrite
        (Bound, Make_Real_Literal (Sloc (Bound), Ureal_0));
      Analyze (Bound);
      Resolve (Bound, Standard_Float);
   end Check_Real_Bound;

   ------------------------------
   -- Complete_Private_Subtype --
   ------------------------------

   procedure Complete_Private_Subtype
     (Priv        : Entity_Id;
      Full        : Entity_Id;
      Full_Base   : Entity_Id;
      Related_Nod : Node_Id)
   is
      Save_Next_Entity : Entity_Id;
      Save_Homonym     : Entity_Id;

   begin
      --  Set semantic attributes for (implicit) private subtype completion.
      --  If the full type has no discriminants, then it is a copy of the
      --  full view of the base. Otherwise, it is a subtype of the base with
      --  a possible discriminant constraint. Save and restore the original
      --  Next_Entity field of full to ensure that the calls to Copy_Node do
      --  not corrupt the entity chain.

      Save_Next_Entity := Next_Entity (Full);
      Save_Homonym     := Homonym (Priv);

      if Is_Private_Type (Full_Base)
        or else Is_Record_Type (Full_Base)
        or else Is_Concurrent_Type (Full_Base)
      then
         Copy_Node (Priv, Full);

         --  Note that the Etype of the full view is the same as the Etype of
         --  the partial view. In this fashion, the subtype has access to the
         --  correct view of the parent.

         Set_Has_Discriminants (Full, Has_Discriminants (Full_Base));
         Set_Has_Unknown_Discriminants
                                 (Full, Has_Unknown_Discriminants (Full_Base));
         Set_First_Entity (Full, First_Entity (Full_Base));
         Set_Last_Entity  (Full, Last_Entity (Full_Base));

         --  If the underlying base type is constrained, we know that the
         --  full view of the subtype is constrained as well (the converse
         --  is not necessarily true).

         if Is_Constrained (Full_Base) then
            Set_Is_Constrained (Full);
         end if;

      else
         Copy_Node (Full_Base, Full);

         --  The following subtlety with the Etype of the full view needs to be
         --  taken into account here. One could think that it must naturally be
         --  set to the base type of the full base:

         --    Set_Etype (Full, Base_Type (Full_Base));

         --  so that the full view becomes a subtype of the full base when the
         --  latter is a base type, which must for example happen when the full
         --  base is declared as derived type. That's also correct if the full
         --  base is declared as an array type, or a floating-point type, or a
         --  fixed-point type, or a signed integer type, as these declarations
         --  create an implicit base type and a first subtype so the Etype of
         --  the full views must be the implicit base type. But that's wrong
         --  if the full base is declared as an access type, or an enumeration
         --  type, or a modular integer type, as these declarations directly
         --  create a base type, i.e. with Etype pointing to itself. Moreover
         --  the full base being declared in the private part, i.e. when the
         --  views are swapped, the end result is that the Etype of the full
         --  base is set to its private view in this case and that we need to
         --  propagate this setting to the full view in order for the subtype
         --  to be compatible with the base type.

         if Is_Base_Type (Full_Base)
           and then (Is_Derived_Type (Full_Base)
                      or else Ekind (Full_Base) in Array_Kind
                      or else Ekind (Full_Base) in Fixed_Point_Kind
                      or else Ekind (Full_Base) in Float_Kind
                      or else Ekind (Full_Base) in Signed_Integer_Kind)
         then
            Set_Etype (Full, Full_Base);
         end if;

         Set_Chars         (Full, Chars (Priv));
         Set_Sloc          (Full, Sloc (Priv));
         Conditional_Delay (Full, Priv);
      end if;

      Link_Entities                 (Full, Save_Next_Entity);
      Set_Homonym                   (Full, Save_Homonym);
      Set_Associated_Node_For_Itype (Full, Related_Nod);

      if Ekind (Full) in Incomplete_Or_Private_Kind then
         Reinit_Field_To_Zero (Full, F_Private_Dependents);
      end if;

      --  Set common attributes for all subtypes: kind, convention, etc.

      Mutate_Ekind         (Full, Subtype_Kind (Ekind (Full_Base)));
      Set_Convention       (Full, Convention (Full_Base));
      Set_Is_First_Subtype (Full, False);
      Set_Scope            (Full, Scope (Priv));
      Set_Size_Info        (Full, Full_Base);
      Copy_RM_Size         (To => Full, From => Full_Base);
      Set_Is_Itype         (Full);

      --  A subtype of a private-type-without-discriminants, whose full-view
      --  has discriminants with default expressions, is not constrained.

      if not Has_Discriminants (Priv) then
         Set_Is_Constrained (Full, Is_Constrained (Full_Base));

         if Has_Discriminants (Full_Base) then
            Set_Discriminant_Constraint
              (Full, Discriminant_Constraint (Full_Base));

            --  The partial view may have been indefinite, the full view
            --  might not be.

            Set_Has_Unknown_Discriminants
              (Full, Has_Unknown_Discriminants (Full_Base));
         end if;
      end if;

      Set_First_Rep_Item     (Full, First_Rep_Item (Full_Base));
      Set_Depends_On_Private (Full, Has_Private_Component (Full));

      --  Freeze the private subtype entity if its parent is delayed, and not
      --  already frozen. We skip this processing if the type is an anonymous
      --  subtype of a record component, or is the corresponding record of a
      --  protected type, since these are processed when the enclosing type
      --  is frozen. If the parent type is declared in a nested package then
      --  the freezing of the private and full views also happens later.

      if not Is_Type (Scope (Full)) then
         if Is_Itype (Priv)
           and then In_Same_Source_Unit (Full, Full_Base)
           and then Scope (Full_Base) /= Scope (Full)
         then
            Set_Has_Delayed_Freeze (Full);
            Set_Has_Delayed_Freeze (Priv);

         else
            Set_Has_Delayed_Freeze (Full,
              Has_Delayed_Freeze (Full_Base)
                and then not Is_Frozen (Full_Base));
         end if;
      end if;

      Set_Freeze_Node (Full, Empty);
      Set_Is_Frozen (Full, False);

      if Has_Discriminants (Full) then
         Set_Stored_Constraint_From_Discriminant_Constraint (Full);
         Set_Stored_Constraint (Priv, Stored_Constraint (Full));

         if Has_Unknown_Discriminants (Full) then
            Set_Discriminant_Constraint (Full, No_Elist);
         end if;
      end if;

      if Ekind (Full_Base) = E_Record_Type
        and then Has_Discriminants (Full_Base)
        and then Has_Discriminants (Priv) -- might not, if errors
        and then not Has_Unknown_Discriminants (Priv)
        and then not Is_Empty_Elmt_List (Discriminant_Constraint (Priv))
      then
         Create_Constrained_Components
           (Full, Related_Nod, Full_Base, Discriminant_Constraint (Priv));

      --  If the full base is itself derived from private, build a congruent
      --  subtype of its underlying full view, for use by the back end.

      elsif Is_Private_Type (Full_Base)
        and then Present (Underlying_Full_View (Full_Base))
      then
         declare
            Underlying_Full_Base : constant Entity_Id
                                           := Underlying_Full_View (Full_Base);
            Underlying_Full : constant Entity_Id
                       := Make_Defining_Identifier (Sloc (Priv), Chars (Priv));
         begin
            Set_Is_Itype (Underlying_Full);
            Set_Associated_Node_For_Itype (Underlying_Full, Related_Nod);
            Complete_Private_Subtype
              (Priv, Underlying_Full, Underlying_Full_Base, Related_Nod);
            Set_Underlying_Full_View (Full, Underlying_Full);
            Set_Is_Underlying_Full_View (Underlying_Full);
         end;

      elsif Is_Record_Type (Full_Base) then

         --  Show Full is simply a renaming of Full_Base

         Set_Cloned_Subtype (Full, Full_Base);
         Set_Is_Limited_Record (Full, Is_Limited_Record (Full_Base));

         --  Propagate predicates

         Propagate_Predicate_Attributes (Full, Full_Base);
      end if;

      --  It is unsafe to share the bounds of a scalar type, because the Itype
      --  is elaborated on demand, and if a bound is nonstatic, then different
      --  orders of elaboration in different units will lead to different
      --  external symbols.

      if Is_Scalar_Type (Full_Base) then
         Set_Scalar_Range (Full,
           Make_Range (Sloc (Related_Nod),
             Low_Bound  =>
               Duplicate_Subexpr_No_Checks (Type_Low_Bound  (Full_Base)),
             High_Bound =>
               Duplicate_Subexpr_No_Checks (Type_High_Bound (Full_Base))));

         --  This completion inherits the bounds of the full parent, but if
         --  the parent is an unconstrained floating point type, so is the
         --  completion.

         if Is_Floating_Point_Type (Full_Base) then
            Set_Includes_Infinities
             (Scalar_Range (Full), Has_Infinities (Full_Base));
         end if;
      end if;

      --  ??? It seems that a lot of fields are missing that should be copied
      --  from Full_Base to Full. Here are some that are introduced in a
      --  non-disruptive way but a cleanup is necessary.

      if Is_Tagged_Type (Full_Base) then
         Set_Is_Tagged_Type (Full);
         Set_Is_Limited_Record (Full, Is_Limited_Record (Full_Base));

         Set_Direct_Primitive_Operations
           (Full, Direct_Primitive_Operations (Full_Base));
         Set_No_Tagged_Streams_Pragma
           (Full, No_Tagged_Streams_Pragma (Full_Base));

         if Is_Interface (Full_Base) then
            Set_Is_Interface (Full);
            Set_Is_Limited_Interface (Full, Is_Limited_Interface (Full_Base));
         end if;

         --  Inherit class_wide type of full_base in case the partial view was
         --  not tagged. Otherwise it has already been created when the private
         --  subtype was analyzed.

         if No (Class_Wide_Type (Full)) then
            Set_Class_Wide_Type (Full, Class_Wide_Type (Full_Base));
         end if;

      --  If this is a subtype of a protected or task type, constrain its
      --  corresponding record, unless this is a subtype without constraints,
      --  i.e. a simple renaming as with an actual subtype in an instance.

      elsif Is_Concurrent_Type (Full_Base) then
         if Has_Discriminants (Full)
           and then Present (Corresponding_Record_Type (Full_Base))
           and then
             not Is_Empty_Elmt_List (Discriminant_Constraint (Full))
         then
            Set_Corresponding_Record_Type (Full,
              Constrain_Corresponding_Record
                (Full, Corresponding_Record_Type (Full_Base), Related_Nod));

         else
            Set_Corresponding_Record_Type (Full,
              Corresponding_Record_Type (Full_Base));
         end if;
      end if;

      --  Link rep item chain, and also setting of Has_Predicates from private
      --  subtype to full subtype, since we will need these on the full subtype
      --  to create the predicate function. Note that the full subtype may
      --  already have rep items, inherited from the full view of the base
      --  type, so we must be sure not to overwrite these entries.

      declare
         Append    : Boolean;
         Item      : Node_Id;
         Next_Item : Node_Id;
         Priv_Item : Node_Id;

      begin
         Item := First_Rep_Item (Full);
         Priv_Item := First_Rep_Item (Priv);

         --  If no existing rep items on full type, we can just link directly
         --  to the list of items on the private type, if any exist.. Same if
         --  the rep items are only those inherited from the base

         if (No (Item)
              or else Nkind (Item) /= N_Aspect_Specification
              or else Entity (Item) = Full_Base)
           and then Present (First_Rep_Item (Priv))
         then
            Set_First_Rep_Item (Full, Priv_Item);

         --  Otherwise, search to the end of items currently linked to the full
         --  subtype and append the private items to the end. However, if Priv
         --  and Full already have the same list of rep items, then the append
         --  is not done, as that would create a circularity.
         --
         --  The partial view may have a predicate and the rep item lists of
         --  both views agree when inherited from the same ancestor. In that
         --  case, simply propagate the list from one view to the other.
         --  A more complex analysis needed here ???

         elsif Present (Priv_Item)
           and then Item = Next_Rep_Item (Priv_Item)
         then
            Set_First_Rep_Item (Full, Priv_Item);

         elsif Item /= Priv_Item then
            Append := True;
            loop
               Next_Item := Next_Rep_Item (Item);
               exit when No (Next_Item);
               Item := Next_Item;

               --  If the private view has aspect specifications, the full view
               --  inherits them. Since these aspects may already have been
               --  attached to the full view during derivation, do not append
               --  them if already present.

               if Item = First_Rep_Item (Priv) then
                  Append := False;
                  exit;
               end if;
            end loop;

            --  And link the private type items at the end of the chain

            if Append then
               Set_Next_Rep_Item (Item, First_Rep_Item (Priv));
            end if;
         end if;
      end;

      --  Make sure Has_Predicates is set on full type if it is set on the
      --  private type. Note that it may already be set on the full type and
      --  if so, we don't want to unset it. Similarly, propagate information
      --  about delayed aspects, because the corresponding pragmas must be
      --  analyzed when one of the views is frozen. This last step is needed
      --  in particular when the full type is a scalar type for which an
      --  anonymous base type is constructed.

      --  The predicate functions are generated either at the freeze point
      --  of the type or at the end of the visible part, and we must avoid
      --  generating them twice.

      Propagate_Predicate_Attributes (Full, Priv);

      if Has_Delayed_Aspects (Priv) then
         Set_Has_Delayed_Aspects (Full);
      end if;
   end Complete_Private_Subtype;

   ----------------------------
   -- Constant_Redeclaration --
   ----------------------------

   procedure Constant_Redeclaration
     (Id : Entity_Id;
      N  : Node_Id;
      T  : out Entity_Id)
   is
      Prev    : constant Entity_Id := Current_Entity_In_Scope (Id);
      Obj_Def : constant Node_Id := Object_Definition (N);
      New_T   : Entity_Id;

      procedure Check_Possible_Deferred_Completion
        (Prev_Id      : Entity_Id;
         Prev_Obj_Def : Node_Id;
         Curr_Obj_Def : Node_Id);
      --  Determine whether the two object definitions describe the partial
      --  and the full view of a constrained deferred constant. Generate
      --  a subtype for the full view and verify that it statically matches
      --  the subtype of the partial view.

      procedure Check_Recursive_Declaration (Typ : Entity_Id);
      --  If deferred constant is an access type initialized with an allocator,
      --  check whether there is an illegal recursion in the definition,
      --  through a default value of some record subcomponent. This is normally
      --  detected when generating init procs, but requires this additional
      --  mechanism when expansion is disabled.

      ----------------------------------------
      -- Check_Possible_Deferred_Completion --
      ----------------------------------------

      procedure Check_Possible_Deferred_Completion
        (Prev_Id      : Entity_Id;
         Prev_Obj_Def : Node_Id;
         Curr_Obj_Def : Node_Id)
      is
      begin
         if Nkind (Prev_Obj_Def) = N_Subtype_Indication
           and then Present (Constraint (Prev_Obj_Def))
           and then Nkind (Curr_Obj_Def) = N_Subtype_Indication
           and then Present (Constraint (Curr_Obj_Def))
         then
            declare
               Loc    : constant Source_Ptr := Sloc (N);
               Def_Id : constant Entity_Id  := Make_Temporary (Loc, 'S');
               Decl   : constant Node_Id    :=
                          Make_Subtype_Declaration (Loc,
                            Defining_Identifier => Def_Id,
                            Subtype_Indication  =>
                              Relocate_Node (Curr_Obj_Def));

            begin
               Insert_Before_And_Analyze (N, Decl);
               Set_Etype (Id, Def_Id);

               if not Subtypes_Statically_Match (Etype (Prev_Id), Def_Id) then
                  Error_Msg_Sloc := Sloc (Prev_Id);
                  Error_Msg_N ("subtype does not statically match deferred "
                               & "declaration #", N);
               end if;
            end;
         end if;
      end Check_Possible_Deferred_Completion;

      ---------------------------------
      -- Check_Recursive_Declaration --
      ---------------------------------

      procedure Check_Recursive_Declaration (Typ : Entity_Id) is
         Comp : Entity_Id;

      begin
         if Is_Record_Type (Typ) then
            Comp := First_Component (Typ);
            while Present (Comp) loop
               if Comes_From_Source (Comp) then
                  if Present (Expression (Parent (Comp)))
                    and then Is_Entity_Name (Expression (Parent (Comp)))
                    and then Entity (Expression (Parent (Comp))) = Prev
                  then
                     Error_Msg_Sloc := Sloc (Parent (Comp));
                     Error_Msg_NE
                       ("illegal circularity with declaration for & #",
                         N, Comp);
                     return;

                  elsif Is_Record_Type (Etype (Comp)) then
                     Check_Recursive_Declaration (Etype (Comp));
                  end if;
               end if;

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

   --  Start of processing for Constant_Redeclaration

   begin
      if Nkind (Parent (Prev)) = N_Object_Declaration then
         if Nkind (Object_Definition
                     (Parent (Prev))) = N_Subtype_Indication
         then
            --  Find type of new declaration. The constraints of the two
            --  views must match statically, but there is no point in
            --  creating an itype for the full view.

            if Nkind (Obj_Def) = N_Subtype_Indication then
               Find_Type (Subtype_Mark (Obj_Def));
               New_T := Entity (Subtype_Mark (Obj_Def));

            else
               Find_Type (Obj_Def);
               New_T := Entity (Obj_Def);
            end if;

            T := Etype (Prev);

         else
            --  The full view may impose a constraint, even if the partial
            --  view does not, so construct the subtype.

            New_T := Find_Type_Of_Object (Obj_Def, N);
            T     := New_T;
         end if;

      else
         --  Current declaration is illegal, diagnosed below in Enter_Name

         T := Empty;
         New_T := Any_Type;
      end if;

      --  If previous full declaration or a renaming declaration exists, or if
      --  a homograph is present, let Enter_Name handle it, either with an
      --  error or with the removal of an overridden implicit subprogram.
      --  The previous one is a full declaration if it has an expression
      --  (which in the case of an aggregate is indicated by the Init flag).

      if Ekind (Prev) /= E_Constant
        or else Nkind (Parent (Prev)) = N_Object_Renaming_Declaration
        or else Present (Expression (Parent (Prev)))
        or else Has_Init_Expression (Parent (Prev))
        or else Present (Full_View (Prev))
      then
         Enter_Name (Id);

      --  Verify that types of both declarations match, or else that both types
      --  are anonymous access types whose designated subtypes statically match
      --  (as allowed in Ada 2005 by AI-385).

      elsif Base_Type (Etype (Prev)) /= Base_Type (New_T)
        and then
          (Ekind (Etype (Prev)) /= E_Anonymous_Access_Type
             or else Ekind (Etype (New_T)) /= E_Anonymous_Access_Type
             or else Is_Access_Constant (Etype (New_T)) /=
                     Is_Access_Constant (Etype (Prev))
             or else Can_Never_Be_Null (Etype (New_T)) /=
                     Can_Never_Be_Null (Etype (Prev))
             or else Null_Exclusion_Present (Parent (Prev)) /=
                     Null_Exclusion_Present (Parent (Id))
             or else not Subtypes_Statically_Match
                           (Designated_Type (Etype (Prev)),
                            Designated_Type (Etype (New_T))))
      then
         Error_Msg_Sloc := Sloc (Prev);
         Error_Msg_N ("type does not match declaration#", N);
         Set_Full_View (Prev, Id);
         Set_Etype (Id, Any_Type);

         --  A deferred constant whose type is an anonymous array is always
         --  illegal (unless imported). A detailed error message might be
         --  helpful for Ada beginners.

         if Nkind (Object_Definition (Parent (Prev)))
            = N_Constrained_Array_Definition
           and then Nkind (Object_Definition (N))
              = N_Constrained_Array_Definition
         then
            Error_Msg_N ("\each anonymous array is a distinct type", N);
            Error_Msg_N ("a deferred constant must have a named type",
              Object_Definition (Parent (Prev)));
         end if;

      elsif
        Null_Exclusion_Present (Parent (Prev))
          and then not Null_Exclusion_Present (N)
      then
         Error_Msg_Sloc := Sloc (Prev);
         Error_Msg_N ("null-exclusion does not match declaration#", N);
         Set_Full_View (Prev, Id);
         Set_Etype (Id, Any_Type);

      --  If so, process the full constant declaration

      else
         --  RM 7.4 (6): If the subtype defined by the subtype_indication in
         --  the deferred declaration is constrained, then the subtype defined
         --  by the subtype_indication in the full declaration shall match it
         --  statically.

         Check_Possible_Deferred_Completion
           (Prev_Id      => Prev,
            Prev_Obj_Def => Object_Definition (Parent (Prev)),
            Curr_Obj_Def => Obj_Def);

         Set_Full_View (Prev, Id);
         Set_Is_Public (Id, Is_Public (Prev));
         Set_Is_Internal (Id);
         Append_Entity (Id, Current_Scope);

         --  Check ALIASED present if present before (RM 7.4(7))

         if Is_Aliased (Prev)
           and then not Aliased_Present (N)
         then
            Error_Msg_Sloc := Sloc (Prev);
            Error_Msg_N ("ALIASED required (see declaration #)", N);
         end if;

         --  Check that placement is in private part and that the incomplete
         --  declaration appeared in the visible part.

         if Ekind (Current_Scope) = E_Package
           and then not In_Private_Part (Current_Scope)
         then
            Error_Msg_Sloc := Sloc (Prev);
            Error_Msg_N
              ("full constant for declaration # must be in private part", N);

         elsif Ekind (Current_Scope) = E_Package
           and then
             List_Containing (Parent (Prev)) /=
               Visible_Declarations (Package_Specification (Current_Scope))
         then
            Error_Msg_N
              ("deferred constant must be declared in visible part",
               Parent (Prev));
         end if;

         if Is_Access_Type (T)
           and then Nkind (Expression (N)) = N_Allocator
         then
            Check_Recursive_Declaration (Designated_Type (T));
         end if;

         --  A deferred constant is a visible entity. If type has invariants,
         --  verify that the initial value satisfies them. This is not done in
         --  GNATprove mode, as GNATprove handles invariant checks itself.

         if Has_Invariants (T)
           and then Present (Invariant_Procedure (T))
           and then not GNATprove_Mode
         then
            Insert_After (N,
              Make_Invariant_Call (New_Occurrence_Of (Prev, Sloc (N))));
         end if;
      end if;
   end Constant_Redeclaration;

   ----------------------
   -- Constrain_Access --
   ----------------------

   procedure Constrain_Access
     (Def_Id      : in out Entity_Id;
      S           : Node_Id;
      Related_Nod : Node_Id)
   is
      T             : constant Entity_Id := Entity (Subtype_Mark (S));
      Desig_Type    : constant Entity_Id := Designated_Type (T);
      Desig_Subtype : Entity_Id := Create_Itype (E_Void, Related_Nod);
      Constraint_OK : Boolean := True;

   begin
      if Is_Array_Type (Desig_Type) then
         Constrain_Array (Desig_Subtype, S, Related_Nod, Def_Id, 'P');

      elsif (Is_Record_Type (Desig_Type)
              or else Is_Incomplete_Or_Private_Type (Desig_Type))
        and then not Is_Constrained (Desig_Type)
      then
         --  If this is a constrained access definition for a record
         --  component, we leave the type as an unconstrained access,
         --  and mark the component so that its actual type is built
         --  at a point of use (e.g., an assignment statement). This
         --  is handled in Sem_Util.Build_Actual_Subtype_Of_Component.

         if Desig_Type = Current_Scope
           and then No (Def_Id)
         then
            Desig_Subtype :=
              Create_Itype
                (E_Void, Related_Nod, Scope_Id => Scope (Desig_Type));
            Mutate_Ekind (Desig_Subtype, E_Record_Subtype);
            Def_Id := Entity (Subtype_Mark (S));

            --  We indicate that the component has a per-object constraint
            --  for treatment at a point of use, even though the constraint
            --  may be independent of discriminants of the enclosing type.

            if Nkind (Related_Nod) = N_Component_Declaration then
               Set_Has_Per_Object_Constraint
                 (Defining_Identifier (Related_Nod));
            end if;

            --  This call added to ensure that the constraint is analyzed
            --  (needed for a B test). Note that we still return early from
            --  this procedure to avoid recursive processing.

            Constrain_Discriminated_Type
              (Desig_Subtype, S, Related_Nod, For_Access => True);
            return;
         end if;

         --  Enforce rule that the constraint is illegal if there is an
         --  unconstrained view of the designated type. This means that the
         --  partial view (either a private type declaration or a derivation
         --  from a private type) has no discriminants. (Defect Report
         --  8652/0008, Technical Corrigendum 1, checked by ACATS B371001).

         --  Rule updated for Ada 2005: The private type is said to have
         --  a constrained partial view, given that objects of the type
         --  can be declared. Furthermore, the rule applies to all access
         --  types, unlike the rule concerning default discriminants (see
         --  RM 3.7.1(7/3))

         if (Ekind (T) = E_General_Access_Type or else Ada_Version >= Ada_2005)
           and then Has_Private_Declaration (Desig_Type)
           and then In_Open_Scopes (Scope (Desig_Type))
           and then Has_Discriminants (Desig_Type)
         then
            declare
               Pack  : constant Node_Id :=
                         Unit_Declaration_Node (Scope (Desig_Type));
               Decls : List_Id;
               Decl  : Node_Id;

            begin
               if Nkind (Pack) = N_Package_Declaration then
                  Decls := Visible_Declarations (Specification (Pack));
                  Decl := First (Decls);
                  while Present (Decl) loop
                     if (Nkind (Decl) = N_Private_Type_Declaration
                          and then Chars (Defining_Identifier (Decl)) =
                                                           Chars (Desig_Type))

                       or else
                        (Nkind (Decl) = N_Full_Type_Declaration
                          and then
                            Chars (Defining_Identifier (Decl)) =
                                                     Chars (Desig_Type)
                          and then Is_Derived_Type (Desig_Type)
                          and then
                            Has_Private_Declaration (Etype (Desig_Type)))
                     then
                        if No (Discriminant_Specifications (Decl)) then
                           Error_Msg_N
                             ("cannot constrain access type if designated "
                              & "type has constrained partial view", S);
                        end if;

                        exit;
                     end if;

                     Next (Decl);
                  end loop;
               end if;
            end;
         end if;

         Constrain_Discriminated_Type (Desig_Subtype, S, Related_Nod,
           For_Access => True);

      elsif Is_Concurrent_Type (Desig_Type)
        and then not Is_Constrained (Desig_Type)
      then
         Constrain_Concurrent (Desig_Subtype, S, Related_Nod, Desig_Type, ' ');

      else
         Error_Msg_N ("invalid constraint on access type", S);

         --  We simply ignore an invalid constraint

         Desig_Subtype := Desig_Type;
         Constraint_OK := False;
      end if;

      if No (Def_Id) then
         Def_Id := Create_Itype (E_Access_Subtype, Related_Nod);
      else
         Mutate_Ekind (Def_Id, E_Access_Subtype);
      end if;

      if Constraint_OK then
         Set_Etype (Def_Id, Base_Type (T));

         if Is_Private_Type (Desig_Type) then
            Prepare_Private_Subtype_Completion (Desig_Subtype, Related_Nod);
         end if;
      else
         Set_Etype (Def_Id, Any_Type);
      end if;

      Set_Size_Info                (Def_Id, T);
      Set_Is_Constrained           (Def_Id, Constraint_OK);
      Set_Directly_Designated_Type (Def_Id, Desig_Subtype);
      Set_Depends_On_Private       (Def_Id, Has_Private_Component (Def_Id));
      Set_Is_Access_Constant       (Def_Id, Is_Access_Constant (T));

      Conditional_Delay (Def_Id, T);

      --  AI-363 : Subtypes of general access types whose designated types have
      --  default discriminants are disallowed. In instances, the rule has to
      --  be checked against the actual, of which T is the subtype. In a
      --  generic body, the rule is checked assuming that the actual type has
      --  defaulted discriminants.

      if Ada_Version >= Ada_2005 or else Warn_On_Ada_2005_Compatibility then
         if Ekind (Base_Type (T)) = E_General_Access_Type
           and then Has_Defaulted_Discriminants (Desig_Type)
         then
            if Ada_Version < Ada_2005 then
               Error_Msg_N
                 ("access subtype of general access type would not " &
                  "be allowed in Ada 2005?y?", S);
            else
               Error_Msg_N
                 ("access subtype of general access type not allowed", S);
            end if;

            Error_Msg_N ("\discriminants have defaults", S);

         elsif Is_Access_Type (T)
           and then Is_Generic_Type (Desig_Type)
           and then Has_Discriminants (Desig_Type)
           and then In_Package_Body (Current_Scope)
         then
            if Ada_Version < Ada_2005 then
               Error_Msg_N
                 ("access subtype would not be allowed in generic body "
                  & "in Ada 2005?y?", S);
            else
               Error_Msg_N
                 ("access subtype not allowed in generic body", S);
            end if;

            Error_Msg_N
              ("\designated type is a discriminated formal", S);
         end if;
      end if;
   end Constrain_Access;

   ---------------------
   -- Constrain_Array --
   ---------------------

   procedure Constrain_Array
     (Def_Id      : in out Entity_Id;
      SI          : Node_Id;
      Related_Nod : Node_Id;
      Related_Id  : Entity_Id;
      Suffix      : Character)
   is
      C                     : constant Node_Id := Constraint (SI);
      Number_Of_Constraints : Nat := 0;
      Index                 : Node_Id;
      S, T                  : Entity_Id;
      Constraint_OK         : Boolean := True;
      Is_FLB_Array_Subtype  : Boolean := False;

   begin
      T := Entity (Subtype_Mark (SI));

      if Is_Access_Type (T) then
         T := Designated_Type (T);
      end if;

      --  If an index constraint follows a subtype mark in a subtype indication
      --  then the type or subtype denoted by the subtype mark must not already
      --  impose an index constraint. The subtype mark must denote either an
      --  unconstrained array type or an access type whose designated type
      --  is such an array type... (RM 3.6.1)

      if Is_Constrained (T) then
         Error_Msg_N ("array type is already constrained", Subtype_Mark (SI));
         Constraint_OK := False;

      else
         S := First (Constraints (C));
         while Present (S) loop
            Number_Of_Constraints := Number_Of_Constraints + 1;
            Next (S);
         end loop;

         --  In either case, the index constraint must provide a discrete
         --  range for each index of the array type and the type of each
         --  discrete range must be the same as that of the corresponding
         --  index. (RM 3.6.1)

         if Number_Of_Constraints /= Number_Dimensions (T) then
            Error_Msg_NE ("incorrect number of index constraints for }", C, T);
            Constraint_OK := False;

         else
            S := First (Constraints (C));
            Index := First_Index (T);
            Analyze (Index);

            --  Apply constraints to each index type

            for J in 1 .. Number_Of_Constraints loop
               Constrain_Index (Index, S, Related_Nod, Related_Id, Suffix, J);

               --  If the subtype of the index has been set to indicate that
               --  it has a fixed lower bound, then record that the subtype's
               --  entity will need to be marked as being a fixed-lower-bound
               --  array subtype.

               if S = First (Constraints (C)) then
                  Is_FLB_Array_Subtype :=
                    Is_Fixed_Lower_Bound_Index_Subtype (Etype (S));

                  --  If the parent subtype (or should this be Etype of that?)
                  --  is an FLB array subtype, we flag an error, because we
                  --  don't currently allow subtypes of such subtypes to
                  --  specify a fixed lower bound for any of their indexes,
                  --  even if the index of the parent subtype is a "range <>"
                  --  index.

                  if Is_FLB_Array_Subtype
                    and then Is_Fixed_Lower_Bound_Array_Subtype (T)
                  then
                     Error_Msg_NE
                       ("index with fixed lower bound not allowed for subtype "
                          & "of fixed-lower-bound }", S, T);

                     Is_FLB_Array_Subtype := False;
                  end if;

               elsif Is_FLB_Array_Subtype
                 and then not Is_Fixed_Lower_Bound_Index_Subtype (Etype (S))
               then
                  Error_Msg_NE
                    ("constrained index not allowed for fixed-lower-bound "
                       & "subtype of}", S, T);

               elsif not Is_FLB_Array_Subtype
                 and then Is_Fixed_Lower_Bound_Index_Subtype (Etype (S))
               then
                  Error_Msg_NE
                    ("index with fixed lower bound not allowed for "
                       & "constrained subtype of}", S, T);
               end if;

               Next (Index);
               Next (S);
            end loop;

         end if;
      end if;

      if No (Def_Id) then
         Def_Id :=
           Create_Itype (E_Array_Subtype, Related_Nod, Related_Id, Suffix);
         Set_Parent (Def_Id, Related_Nod);

      else
         Mutate_Ekind (Def_Id, E_Array_Subtype);
      end if;

      Set_Size_Info      (Def_Id,                (T));
      Set_First_Rep_Item (Def_Id, First_Rep_Item (T));
      Set_Etype          (Def_Id, Base_Type      (T));

      if Constraint_OK then
         Set_First_Index (Def_Id, First (Constraints (C)));
      else
         Set_First_Index (Def_Id, First_Index (T));
      end if;

      Set_Is_Constrained     (Def_Id, not Is_FLB_Array_Subtype);
      Set_Is_Fixed_Lower_Bound_Array_Subtype
                             (Def_Id, Is_FLB_Array_Subtype);
      Set_Is_Aliased         (Def_Id, Is_Aliased (T));
      Set_Is_Independent     (Def_Id, Is_Independent (T));
      Set_Depends_On_Private (Def_Id, Has_Private_Component (Def_Id));

      Set_Is_Private_Composite (Def_Id, Is_Private_Composite (T));
      Set_Is_Limited_Composite (Def_Id, Is_Limited_Composite (T));

      --  A subtype does not inherit the Packed_Array_Impl_Type of is parent.
      --  We need to initialize the attribute because if Def_Id is previously
      --  analyzed through a limited_with clause, it will have the attributes
      --  of an incomplete type, one of which is an Elist that overlaps the
      --  Packed_Array_Impl_Type field.

      Set_Packed_Array_Impl_Type (Def_Id, Empty);

      --  Build a freeze node if parent still needs one. Also make sure that
      --  the Depends_On_Private status is set because the subtype will need
      --  reprocessing at the time the base type does, and also we must set a
      --  conditional delay.

      Set_Depends_On_Private (Def_Id, Depends_On_Private (T));
      Conditional_Delay (Def_Id, T);
   end Constrain_Array;

   ------------------------------
   -- Constrain_Component_Type --
   ------------------------------

   function Constrain_Component_Type
     (Comp            : Entity_Id;
      Constrained_Typ : Entity_Id;
      Related_Node    : Node_Id;
      Typ             : Entity_Id;
      Constraints     : Elist_Id) return Entity_Id
   is
      Loc         : constant Source_Ptr := Sloc (Constrained_Typ);
      Compon_Type : constant Entity_Id := Etype (Comp);

      function Build_Constrained_Array_Type
        (Old_Type : Entity_Id) return Entity_Id;
      --  If Old_Type is an array type, one of whose indexes is constrained
      --  by a discriminant, build an Itype whose constraint replaces the
      --  discriminant with its value in the constraint.

      function Build_Constrained_Discriminated_Type
        (Old_Type : Entity_Id) return Entity_Id;
      --  Ditto for record components. Handle the case where the constraint
      --  is a conversion of the discriminant value, introduced during
      --  expansion.

      function Build_Constrained_Access_Type
        (Old_Type : Entity_Id) return Entity_Id;
      --  Ditto for access types. Makes use of previous two functions, to
      --  constrain designated type.

      function Is_Discriminant (Expr : Node_Id) return Boolean;
      --  Returns True if Expr is a discriminant

      function Get_Discr_Value (Discr_Expr : Node_Id) return Node_Id;
      --  Find the value of a discriminant named by Discr_Expr in Constraints

      -----------------------------------
      -- Build_Constrained_Access_Type --
      -----------------------------------

      function Build_Constrained_Access_Type
        (Old_Type : Entity_Id) return Entity_Id
      is
         Desig_Type    : constant Entity_Id := Designated_Type (Old_Type);
         Itype         : Entity_Id;
         Desig_Subtype : Entity_Id;
         Scop          : Entity_Id;

      begin
         --  If the original access type was not embedded in the enclosing
         --  type definition, there is no need to produce a new access
         --  subtype. In fact every access type with an explicit constraint
         --  generates an itype whose scope is the enclosing record.

         if not Is_Type (Scope (Old_Type)) then
            return Old_Type;

         elsif Is_Array_Type (Desig_Type) then
            Desig_Subtype := Build_Constrained_Array_Type (Desig_Type);

         elsif Has_Discriminants (Desig_Type) then

            --  This may be an access type to an enclosing record type for
            --  which we are constructing the constrained components. Return
            --  the enclosing record subtype. This is not always correct,
            --  but avoids infinite recursion. ???

            Desig_Subtype := Any_Type;

            for J in reverse 0 .. Scope_Stack.Last loop
               Scop := Scope_Stack.Table (J).Entity;

               if Is_Type (Scop)
                 and then Base_Type (Scop) = Base_Type (Desig_Type)
               then
                  Desig_Subtype := Scop;
               end if;

               exit when not Is_Type (Scop);
            end loop;

            if Desig_Subtype = Any_Type then
               Desig_Subtype :=
                 Build_Constrained_Discriminated_Type (Desig_Type);
            end if;

         else
            return Old_Type;
         end if;

         if Desig_Subtype /= Desig_Type then

            --  The Related_Node better be here or else we won't be able
            --  to attach new itypes to a node in the tree.

            pragma Assert (Present (Related_Node));

            Itype := Create_Itype (E_Access_Subtype, Related_Node);

            Set_Etype                    (Itype, Base_Type      (Old_Type));
            Set_Size_Info                (Itype,                (Old_Type));
            Set_Directly_Designated_Type (Itype, Desig_Subtype);
            Set_Depends_On_Private       (Itype, Has_Private_Component
                                                                (Old_Type));
            Set_Is_Access_Constant       (Itype, Is_Access_Constant
                                                                (Old_Type));

            --  The new itype needs freezing when it depends on a not frozen
            --  type and the enclosing subtype needs freezing.

            if Has_Delayed_Freeze (Constrained_Typ)
              and then not Is_Frozen (Constrained_Typ)
            then
               Conditional_Delay (Itype, Base_Type (Old_Type));
            end if;

            return Itype;

         else
            return Old_Type;
         end if;
      end Build_Constrained_Access_Type;

      ----------------------------------
      -- Build_Constrained_Array_Type --
      ----------------------------------

      function Build_Constrained_Array_Type
        (Old_Type : Entity_Id) return Entity_Id
      is
         Lo_Expr     : Node_Id;
         Hi_Expr     : Node_Id;
         Old_Index   : Node_Id;
         Range_Node  : Node_Id;
         Constr_List : List_Id;

         Need_To_Create_Itype : Boolean := False;

      begin
         Old_Index := First_Index (Old_Type);
         while Present (Old_Index) loop
            Get_Index_Bounds (Old_Index, Lo_Expr, Hi_Expr);

            if Is_Discriminant (Lo_Expr)
                 or else
               Is_Discriminant (Hi_Expr)
            then
               Need_To_Create_Itype := True;
               exit;
            end if;

            Next_Index (Old_Index);
         end loop;

         if Need_To_Create_Itype then
            Constr_List := New_List;

            Old_Index := First_Index (Old_Type);
            while Present (Old_Index) loop
               Get_Index_Bounds (Old_Index, Lo_Expr, Hi_Expr);

               if Is_Discriminant (Lo_Expr) then
                  Lo_Expr := Get_Discr_Value (Lo_Expr);
               end if;

               if Is_Discriminant (Hi_Expr) then
                  Hi_Expr := Get_Discr_Value (Hi_Expr);
               end if;

               Range_Node :=
                 Make_Range
                   (Loc, New_Copy_Tree (Lo_Expr), New_Copy_Tree (Hi_Expr));

               Append (Range_Node, To => Constr_List);

               Next_Index (Old_Index);
            end loop;

            return Build_Subtype (Related_Node, Loc, Old_Type, Constr_List);

         else
            return Old_Type;
         end if;
      end Build_Constrained_Array_Type;

      ------------------------------------------
      -- Build_Constrained_Discriminated_Type --
      ------------------------------------------

      function Build_Constrained_Discriminated_Type
        (Old_Type : Entity_Id) return Entity_Id
      is
         Expr           : Node_Id;
         Constr_List    : List_Id;
         Old_Constraint : Elmt_Id;

         Need_To_Create_Itype : Boolean := False;

      begin
         Old_Constraint := First_Elmt (Discriminant_Constraint (Old_Type));
         while Present (Old_Constraint) loop
            Expr := Node (Old_Constraint);

            if Is_Discriminant (Expr) then
               Need_To_Create_Itype := True;
               exit;

            --  After expansion of discriminated task types, the value
            --  of the discriminant may be converted to a run-time type
            --  for restricted run-times. Propagate the value of the
            --  discriminant as well, so that e.g. the secondary stack
            --  component has a static constraint. Necessary for LLVM.

            elsif Nkind (Expr) = N_Type_Conversion
              and then Is_Discriminant (Expression (Expr))
            then
               Need_To_Create_Itype := True;
               exit;
            end if;

            Next_Elmt (Old_Constraint);
         end loop;

         if Need_To_Create_Itype then
            Constr_List := New_List;

            Old_Constraint := First_Elmt (Discriminant_Constraint (Old_Type));
            while Present (Old_Constraint) loop
               Expr := Node (Old_Constraint);

               if Is_Discriminant (Expr) then
                  Expr := Get_Discr_Value (Expr);

               elsif Nkind (Expr) = N_Type_Conversion
                 and then Is_Discriminant (Expression (Expr))
               then
                  Expr := New_Copy_Tree (Expr);
                  Set_Expression (Expr, Get_Discr_Value (Expression (Expr)));
               end if;

               Append (New_Copy_Tree (Expr), To => Constr_List);

               Next_Elmt (Old_Constraint);
            end loop;

            return Build_Subtype (Related_Node, Loc, Old_Type, Constr_List);

         else
            return Old_Type;
         end if;
      end Build_Constrained_Discriminated_Type;

      ---------------------
      -- Get_Discr_Value --
      ---------------------

      function Get_Discr_Value (Discr_Expr : Node_Id) return Node_Id is
         Discr_Id : constant Entity_Id := Entity (Discr_Expr);
         --  Entity of a discriminant that appear as a standalone expression in
         --  the constraint of a component.

         D : Entity_Id;
         E : Elmt_Id;

      begin
         --  The discriminant may be declared for the type, in which case we
         --  find it by iterating over the list of discriminants. If the
         --  discriminant is inherited from a parent type, it appears as the
         --  corresponding discriminant of the current type. This will be the
         --  case when constraining an inherited component whose constraint is
         --  given by a discriminant of the parent.

         D := First_Discriminant (Typ);
         E := First_Elmt (Constraints);

         while Present (D) loop
            if D = Discr_Id
              or else D = CR_Discriminant (Discr_Id)
              or else Corresponding_Discriminant (D) = Discr_Id
            then
               return Node (E);
            end if;

            Next_Discriminant (D);
            Next_Elmt (E);
         end loop;

         --  The Corresponding_Discriminant mechanism is incomplete, because
         --  the correspondence between new and old discriminants is not one
         --  to one: one new discriminant can constrain several old ones. In
         --  that case, scan sequentially the stored_constraint, the list of
         --  discriminants of the parents, and the constraints.

         --  Previous code checked for the present of the Stored_Constraint
         --  list for the derived type, but did not use it at all. Should it
         --  be present when the component is a discriminated task type?

         if Is_Derived_Type (Typ)
           and then Scope (Discr_Id) = Etype (Typ)
         then
            D := First_Discriminant (Etype (Typ));
            E := First_Elmt (Constraints);
            while Present (D) loop
               if D = Discr_Id then
                  return Node (E);
               end if;

               Next_Discriminant (D);
               Next_Elmt (E);
            end loop;
         end if;

         --  Something is wrong if we did not find the value

         raise Program_Error;
      end Get_Discr_Value;

      ---------------------
      -- Is_Discriminant --
      ---------------------

      function Is_Discriminant (Expr : Node_Id) return Boolean is
         Discrim_Scope : Entity_Id;

      begin
         if Denotes_Discriminant (Expr) then
            Discrim_Scope := Scope (Entity (Expr));

            --  Either we have a reference to one of Typ's discriminants,

            pragma Assert (Discrim_Scope = Typ

               --  or to the discriminants of the parent type, in the case
               --  of a derivation of a tagged type with variants.

               or else Discrim_Scope = Etype (Typ)
               or else Full_View (Discrim_Scope) = Etype (Typ)

               --  or same as above for the case where the discriminants
               --  were declared in Typ's private view.

               or else (Is_Private_Type (Discrim_Scope)
                         and then Chars (Discrim_Scope) = Chars (Typ))

               --  or else we are deriving from the full view and the
               --  discriminant is declared in the private entity.

               or else (Is_Private_Type (Typ)
                         and then Chars (Discrim_Scope) = Chars (Typ))

               --  Or we are constrained the corresponding record of a
               --  synchronized type that completes a private declaration.

               or else (Is_Concurrent_Record_Type (Typ)
                         and then
                           Corresponding_Concurrent_Type (Typ) = Discrim_Scope)

               --  or we have a class-wide type, in which case make sure the
               --  discriminant found belongs to the root type.

               or else (Is_Class_Wide_Type (Typ)
                         and then Etype (Typ) = Discrim_Scope));

            return True;
         end if;

         --  In all other cases we have something wrong

         return False;
      end Is_Discriminant;

   --  Start of processing for Constrain_Component_Type

   begin
      if Nkind (Parent (Comp)) = N_Component_Declaration
        and then Comes_From_Source (Parent (Comp))
        and then Comes_From_Source
          (Subtype_Indication (Component_Definition (Parent (Comp))))
        and then
          Is_Entity_Name
            (Subtype_Indication (Component_Definition (Parent (Comp))))
      then
         return Compon_Type;

      elsif Is_Array_Type (Compon_Type) then
         return Build_Constrained_Array_Type (Compon_Type);

      elsif Has_Discriminants (Compon_Type) then
         return Build_Constrained_Discriminated_Type (Compon_Type);

      elsif Is_Access_Type (Compon_Type) then
         return Build_Constrained_Access_Type (Compon_Type);

      else
         return Compon_Type;
      end if;
   end Constrain_Component_Type;

   --------------------------
   -- Constrain_Concurrent --
   --------------------------

   --  For concurrent types, the associated record value type carries the same
   --  discriminants, so when we constrain a concurrent type, we must constrain
   --  the corresponding record type as well.

   procedure Constrain_Concurrent
     (Def_Id      : in out Entity_Id;
      SI          : Node_Id;
      Related_Nod : Node_Id;
      Related_Id  : Entity_Id;
      Suffix      : Character)
   is
      --  Retrieve Base_Type to ensure getting to the concurrent type in the
      --  case of a private subtype (needed when only doing semantic analysis).

      T_Ent : Entity_Id := Base_Type (Entity (Subtype_Mark (SI)));
      T_Val : Entity_Id;

   begin
      if Is_Access_Type (T_Ent) then
         T_Ent := Designated_Type (T_Ent);
      end if;

      T_Val := Corresponding_Record_Type (T_Ent);

      if Present (T_Val) then

         if No (Def_Id) then
            Def_Id := Create_Itype (E_Void, Related_Nod, Related_Id, Suffix);

            --  Elaborate itype now, as it may be used in a subsequent
            --  synchronized operation in another scope.

            if Nkind (Related_Nod) = N_Full_Type_Declaration then
               Build_Itype_Reference (Def_Id, Related_Nod);
            end if;
         end if;

         Constrain_Discriminated_Type (Def_Id, SI, Related_Nod);
         Set_First_Private_Entity (Def_Id, First_Private_Entity (T_Ent));

         Set_Depends_On_Private (Def_Id, Has_Private_Component (Def_Id));
         Set_Corresponding_Record_Type (Def_Id,
           Constrain_Corresponding_Record (Def_Id, T_Val, Related_Nod));

      else
         --  If there is no associated record, expansion is disabled and this
         --  is a generic context. Create a subtype in any case, so that
         --  semantic analysis can proceed.

         if No (Def_Id) then
            Def_Id := Create_Itype (E_Void, Related_Nod, Related_Id, Suffix);
         end if;

         Constrain_Discriminated_Type (Def_Id, SI, Related_Nod);
      end if;
   end Constrain_Concurrent;

   ------------------------------------
   -- Constrain_Corresponding_Record --
   ------------------------------------

   function Constrain_Corresponding_Record
     (Prot_Subt   : Entity_Id;
      Corr_Rec    : Entity_Id;
      Related_Nod : Node_Id) return Entity_Id
   is
      T_Sub : constant Entity_Id :=
                Create_Itype
                  (Ekind        => E_Record_Subtype,
                   Related_Nod  => Related_Nod,
                   Related_Id   => Corr_Rec,
                   Suffix       => 'C',
                   Suffix_Index => -1);

   begin
      Set_Etype             (T_Sub, Corr_Rec);
      Set_Has_Discriminants (T_Sub, Has_Discriminants (Prot_Subt));
      Set_Is_Tagged_Type    (T_Sub, Is_Tagged_Type (Corr_Rec));
      Set_Is_Constrained    (T_Sub, True);
      Set_First_Entity      (T_Sub, First_Entity (Corr_Rec));
      Set_Last_Entity       (T_Sub, Last_Entity  (Corr_Rec));

      if Has_Discriminants (Prot_Subt) then -- False only if errors.
         Set_Discriminant_Constraint
           (T_Sub, Discriminant_Constraint (Prot_Subt));
         Set_Stored_Constraint_From_Discriminant_Constraint (T_Sub);
         Create_Constrained_Components
           (T_Sub, Related_Nod, Corr_Rec, Discriminant_Constraint (T_Sub));
      end if;

      Set_Depends_On_Private      (T_Sub, Has_Private_Component (T_Sub));

      if Ekind (Scope (Prot_Subt)) /= E_Record_Type then
         Conditional_Delay (T_Sub, Corr_Rec);

      else
         --  This is a component subtype: it will be frozen in the context of
         --  the enclosing record's init_proc, so that discriminant references
         --  are resolved to discriminals. (Note: we used to skip freezing
         --  altogether in that case, which caused errors downstream for
         --  components of a bit packed array type).

         Set_Has_Delayed_Freeze (T_Sub);
      end if;

      return T_Sub;
   end Constrain_Corresponding_Record;

   -----------------------
   -- Constrain_Decimal --
   -----------------------

   procedure Constrain_Decimal (Def_Id : Entity_Id; S : Node_Id) is
      T           : constant Entity_Id  := Entity (Subtype_Mark (S));
      C           : constant Node_Id    := Constraint (S);
      Loc         : constant Source_Ptr := Sloc (C);
      Range_Expr  : Node_Id;
      Digits_Expr : Node_Id;
      Digits_Val  : Uint;
      Bound_Val   : Ureal;

   begin
      Mutate_Ekind (Def_Id, E_Decimal_Fixed_Point_Subtype);

      if Nkind (C) = N_Range_Constraint then
         Range_Expr := Range_Expression (C);
         Digits_Val := Digits_Value (T);

      else
         pragma Assert (Nkind (C) = N_Digits_Constraint);

         Digits_Expr := Digits_Expression (C);
         Analyze_And_Resolve (Digits_Expr, Any_Integer);

         Check_Digits_Expression (Digits_Expr);
         Digits_Val := Expr_Value (Digits_Expr);

         if Digits_Val > Digits_Value (T) then
            Error_Msg_N
               ("digits expression is incompatible with subtype", C);
            Digits_Val := Digits_Value (T);
         end if;

         if Present (Range_Constraint (C)) then
            Range_Expr := Range_Expression (Range_Constraint (C));
         else
            Range_Expr := Empty;
         end if;
      end if;

      Set_Etype            (Def_Id, Base_Type        (T));
      Set_Size_Info        (Def_Id,                  (T));
      Set_First_Rep_Item   (Def_Id, First_Rep_Item   (T));
      Set_Delta_Value      (Def_Id, Delta_Value      (T));
      Set_Scale_Value      (Def_Id, Scale_Value      (T));
      Set_Small_Value      (Def_Id, Small_Value      (T));
      Set_Machine_Radix_10 (Def_Id, Machine_Radix_10 (T));
      Set_Digits_Value     (Def_Id, Digits_Val);

      --  Manufacture range from given digits value if no range present

      if No (Range_Expr) then
         Bound_Val := (Ureal_10 ** Digits_Val - Ureal_1) * Small_Value (T);
         Range_Expr :=
           Make_Range (Loc,
             Low_Bound =>
               Convert_To (T, Make_Real_Literal (Loc, (-Bound_Val))),
             High_Bound =>
               Convert_To (T, Make_Real_Literal (Loc, Bound_Val)));
      end if;

      Set_Scalar_Range_For_Subtype (Def_Id, Range_Expr, T);
      Set_Discrete_RM_Size (Def_Id);

      --  Unconditionally delay the freeze, since we cannot set size
      --  information in all cases correctly until the freeze point.

      Set_Has_Delayed_Freeze (Def_Id);
   end Constrain_Decimal;

   ----------------------------------
   -- Constrain_Discriminated_Type --
   ----------------------------------

   procedure Constrain_Discriminated_Type
     (Def_Id      : Entity_Id;
      S           : Node_Id;
      Related_Nod : Node_Id;
      For_Access  : Boolean := False)
   is
      E : Entity_Id := Entity (Subtype_Mark (S));
      T : Entity_Id;

      procedure Fixup_Bad_Constraint;
      --  Called after finding a bad constraint, and after having posted an
      --  appropriate error message. The goal is to leave type Def_Id in as
      --  reasonable state as possible.

      --------------------------
      -- Fixup_Bad_Constraint --
      --------------------------

      procedure Fixup_Bad_Constraint is
      begin
         --  Set a reasonable Ekind for the entity, including incomplete types.

         Mutate_Ekind (Def_Id, Subtype_Kind (Ekind (T)));

         --  Set Etype to the known type, to reduce chances of cascaded errors

         Set_Etype (Def_Id, E);
         Set_Error_Posted (Def_Id);
      end Fixup_Bad_Constraint;

      --  Local variables

      C      : Node_Id;
      Constr : Elist_Id := New_Elmt_List;

   --  Start of processing for Constrain_Discriminated_Type

   begin
      C := Constraint (S);

      --  A discriminant constraint is only allowed in a subtype indication,
      --  after a subtype mark. This subtype mark must denote either a type
      --  with discriminants, or an access type whose designated type is a
      --  type with discriminants. A discriminant constraint specifies the
      --  values of these discriminants (RM 3.7.2(5)).

      T := Base_Type (Entity (Subtype_Mark (S)));

      if Is_Access_Type (T) then
         T := Designated_Type (T);
      end if;

      --  In an instance it may be necessary to retrieve the full view of a
      --  type with unknown discriminants, or a full view with defaulted
      --  discriminants. In other contexts the constraint is illegal.

      if In_Instance
        and then Is_Private_Type (T)
        and then Present (Full_View (T))
        and then
          (Has_Unknown_Discriminants (T)
            or else
              (not Has_Discriminants (T)
                and then Has_Defaulted_Discriminants (Full_View (T))))
      then
         T := Full_View (T);
         E := Full_View (E);
      end if;

      --  Ada 2005 (AI-412): Constrained incomplete subtypes are illegal. Avoid
      --  generating an error for access-to-incomplete subtypes.

      if Ada_Version >= Ada_2005
        and then Ekind (T) = E_Incomplete_Type
        and then Nkind (Parent (S)) = N_Subtype_Declaration
        and then not Is_Itype (Def_Id)
      then
         --  A little sanity check: emit an error message if the type has
         --  discriminants to begin with. Type T may be a regular incomplete
         --  type or imported via a limited with clause.

         if Has_Discriminants (T)
           or else (From_Limited_With (T)
                     and then Present (Non_Limited_View (T))
                     and then Nkind (Parent (Non_Limited_View (T))) =
                                               N_Full_Type_Declaration
                     and then Present (Discriminant_Specifications
                                         (Parent (Non_Limited_View (T)))))
         then
            Error_Msg_N
              ("(Ada 2005) incomplete subtype may not be constrained", C);
         else
            Error_Msg_N ("invalid constraint: type has no discriminant", C);
         end if;

         Fixup_Bad_Constraint;
         return;

      --  Check that the type has visible discriminants. The type may be
      --  a private type with unknown discriminants whose full view has
      --  discriminants which are invisible.

      elsif not Has_Discriminants (T)
        or else
          (Has_Unknown_Discriminants (T)
             and then Is_Private_Type (T))
      then
         Error_Msg_N ("invalid constraint: type has no discriminant", C);
         Fixup_Bad_Constraint;
         return;

      elsif Is_Constrained (E)
        or else (Ekind (E) = E_Class_Wide_Subtype
                  and then Present (Discriminant_Constraint (E)))
      then
         Error_Msg_N ("type is already constrained", Subtype_Mark (S));
         Fixup_Bad_Constraint;
         return;
      end if;

      --  T may be an unconstrained subtype (e.g. a generic actual). Constraint
      --  applies to the base type.

      T := Base_Type (T);

      Constr := Build_Discriminant_Constraints (T, S);

      --  If the list returned was empty we had an error in building the
      --  discriminant constraint. We have also already signalled an error
      --  in the incomplete type case

      if Is_Empty_Elmt_List (Constr) then
         Fixup_Bad_Constraint;
         return;
      end if;

      Build_Discriminated_Subtype (T, Def_Id, Constr, Related_Nod, For_Access);
   end Constrain_Discriminated_Type;

   ---------------------------
   -- Constrain_Enumeration --
   ---------------------------

   procedure Constrain_Enumeration (Def_Id : Entity_Id; S : Node_Id) is
      T : constant Entity_Id := Entity (Subtype_Mark (S));
      C : constant Node_Id   := Constraint (S);

   begin
      Mutate_Ekind (Def_Id, E_Enumeration_Subtype);

      Set_First_Literal     (Def_Id, First_Literal (Base_Type (T)));

      Set_Etype             (Def_Id, Base_Type         (T));
      Set_Size_Info         (Def_Id,                   (T));
      Set_First_Rep_Item    (Def_Id, First_Rep_Item    (T));
      Set_Is_Character_Type (Def_Id, Is_Character_Type (T));

      Set_Scalar_Range_For_Subtype (Def_Id, Range_Expression (C), T);

      Set_Discrete_RM_Size (Def_Id);
   end Constrain_Enumeration;

   ----------------------
   -- Constrain_Float --
   ----------------------

   procedure Constrain_Float (Def_Id : Entity_Id; S : Node_Id) is
      T    : constant Entity_Id := Entity (Subtype_Mark (S));
      C    : Node_Id;
      D    : Node_Id;
      Rais : Node_Id;

   begin
      Mutate_Ekind (Def_Id, E_Floating_Point_Subtype);

      Set_Etype          (Def_Id, Base_Type      (T));
      Set_Size_Info      (Def_Id,                (T));
      Set_First_Rep_Item (Def_Id, First_Rep_Item (T));

      --  Process the constraint

      C := Constraint (S);

      --  Digits constraint present

      if Nkind (C) = N_Digits_Constraint then
         Check_Restriction (No_Obsolescent_Features, C);

         if Warn_On_Obsolescent_Feature then
            Error_Msg_N
              ("subtype digits constraint is an " &
               "obsolescent feature (RM J.3(8))?j?", C);
         end if;

         D := Digits_Expression (C);
         Analyze_And_Resolve (D, Any_Integer);
         Check_Digits_Expression (D);
         Set_Digits_Value (Def_Id, Expr_Value (D));

         --  Check that digits value is in range. Obviously we can do this
         --  at compile time, but it is strictly a runtime check, and of
         --  course there is an ACVC test that checks this.

         if Digits_Value (Def_Id) > Digits_Value (T) then
            Error_Msg_Uint_1 := Digits_Value (T);
            Error_Msg_N ("??digits value is too large, maximum is ^", D);
            Rais :=
              Make_Raise_Constraint_Error (Sloc (D),
                Reason => CE_Range_Check_Failed);
            Insert_Action (Declaration_Node (Def_Id), Rais);
         end if;

         C := Range_Constraint (C);

      --  No digits constraint present

      else
         Set_Digits_Value (Def_Id, Digits_Value (T));
      end if;

      --  Range constraint present

      if Nkind (C) = N_Range_Constraint then
         Set_Scalar_Range_For_Subtype (Def_Id, Range_Expression (C), T);

      --  No range constraint present

      else
         pragma Assert (No (C));
         Set_Scalar_Range (Def_Id, Scalar_Range (T));
      end if;

      Set_Is_Constrained (Def_Id);
   end Constrain_Float;

   ---------------------
   -- Constrain_Index --
   ---------------------

   procedure Constrain_Index
     (Index        : Node_Id;
      S            : Node_Id;
      Related_Nod  : Node_Id;
      Related_Id   : Entity_Id;
      Suffix       : Character;
      Suffix_Index : Pos)
   is
      Def_Id : Entity_Id;
      R      : Node_Id := Empty;
      T      : constant Entity_Id := Etype (Index);
      Is_FLB_Index : Boolean := False;

   begin
      Def_Id :=
        Create_Itype (E_Void, Related_Nod, Related_Id, Suffix, Suffix_Index);
      Set_Etype (Def_Id, Base_Type (T));

      if Nkind (S) = N_Range
        or else
          (Nkind (S) = N_Attribute_Reference
            and then Attribute_Name (S) = Name_Range)
      then
         --  A Range attribute will be transformed into N_Range by Resolve

         --  If a range has an Empty upper bound, then remember that for later
         --  setting of the index subtype's Is_Fixed_Lower_Bound_Index_Subtype
         --  flag, and also set the upper bound of the range to the index
         --  subtype's upper bound rather than leaving it Empty. In truth,
         --  that upper bound corresponds to a box ("<>"), but it's convenient
         --  to set it to the upper bound to avoid needing to add special tests
         --  in various places for an Empty upper bound, and in any case it
         --  accurately characterizes the index's range of values.

         if Nkind (S) = N_Range and then not Present (High_Bound (S)) then
            Is_FLB_Index := True;
            Set_High_Bound (S, Type_High_Bound (T));
         end if;

         R := S;

         Process_Range_Expr_In_Decl (R, T);

         if not Error_Posted (S)
           and then
             (Nkind (S) /= N_Range
               or else not Covers (T, (Etype (Low_Bound (S))))
               or else not Covers (T, (Etype (High_Bound (S)))))
         then
            if Base_Type (T) /= Any_Type
              and then Etype (Low_Bound (S)) /= Any_Type
              and then Etype (High_Bound (S)) /= Any_Type
            then
               Error_Msg_N ("range expected", S);
            end if;
         end if;

      elsif Nkind (S) = N_Subtype_Indication then

         --  The parser has verified that this is a discrete indication

         Resolve_Discrete_Subtype_Indication (S, T);
         Bad_Predicated_Subtype_Use
           ("subtype& has predicate, not allowed in index constraint",
            S, Entity (Subtype_Mark (S)));

         R := Range_Expression (Constraint (S));

         --  Capture values of bounds and generate temporaries for them if
         --  needed, since checks may cause duplication of the expressions
         --  which must not be reevaluated.

         --  The forced evaluation removes side effects from expressions, which
         --  should occur also in GNATprove mode. Otherwise, we end up with
         --  unexpected insertions of actions at places where this is not
         --  supposed to occur, e.g. on default parameters of a call.

         if Expander_Active or GNATprove_Mode then
            Force_Evaluation
              (Low_Bound (R),  Related_Id => Def_Id, Is_Low_Bound  => True);
            Force_Evaluation
              (High_Bound (R), Related_Id => Def_Id, Is_High_Bound => True);
         end if;

      elsif Nkind (S) = N_Discriminant_Association then

         --  Syntactically valid in subtype indication

         Error_Msg_N ("invalid index constraint", S);
         Rewrite (S, New_Occurrence_Of (T, Sloc (S)));
         return;

      --  Subtype_Mark case, no anonymous subtypes to construct

      else
         Analyze (S);

         if Is_Entity_Name (S) then
            if not Is_Type (Entity (S)) then
               Error_Msg_N ("expect subtype mark for index constraint", S);

            elsif Base_Type (Entity (S)) /= Base_Type (T) then
               Wrong_Type (S, Base_Type (T));

            --  Check error of subtype with predicate in index constraint

            else
               Bad_Predicated_Subtype_Use
                 ("subtype& has predicate, not allowed in index constraint",
                  S, Entity (S));
            end if;

            return;

         else
            Error_Msg_N ("invalid index constraint", S);
            Rewrite (S, New_Occurrence_Of (T, Sloc (S)));
            return;
         end if;
      end if;

      --  Complete construction of the Itype

      if Is_Modular_Integer_Type (T) then
         Mutate_Ekind (Def_Id, E_Modular_Integer_Subtype);

      elsif Is_Integer_Type (T) then
         Mutate_Ekind (Def_Id, E_Signed_Integer_Subtype);

      else
         Mutate_Ekind (Def_Id, E_Enumeration_Subtype);
         Set_Is_Character_Type (Def_Id, Is_Character_Type (T));
         Set_First_Literal     (Def_Id, First_Literal (T));
      end if;

      Set_Size_Info      (Def_Id,                (T));
      Copy_RM_Size       (To => Def_Id, From => T);
      Set_First_Rep_Item (Def_Id, First_Rep_Item (T));

      --  If this is a range for a fixed-lower-bound subtype, then set the
      --  index itype's low bound to the FLB and the index itype's upper bound
      --  to the high bound of the parent array type's index subtype. Also,
      --  mark the itype as an FLB index subtype.

      if Nkind (S) = N_Range and then Is_FLB_Index then
         Set_Scalar_Range
           (Def_Id,
            Make_Range (Sloc (S),
              Low_Bound  => Low_Bound (S),
              High_Bound => Type_High_Bound (T)));
         Set_Is_Fixed_Lower_Bound_Index_Subtype (Def_Id);

      else
         Set_Scalar_Range (Def_Id, R);
      end if;

      Set_Etype (S, Def_Id);
      Set_Discrete_RM_Size (Def_Id);
   end Constrain_Index;

   -----------------------
   -- Constrain_Integer --
   -----------------------

   procedure Constrain_Integer (Def_Id : Entity_Id; S : Node_Id) is
      T : constant Entity_Id := Entity (Subtype_Mark (S));
      C : constant Node_Id   := Constraint (S);

   begin
      Set_Scalar_Range_For_Subtype (Def_Id, Range_Expression (C), T);

      if Is_Modular_Integer_Type (T) then
         Mutate_Ekind (Def_Id, E_Modular_Integer_Subtype);
      else
         Mutate_Ekind (Def_Id, E_Signed_Integer_Subtype);
      end if;

      Set_Etype            (Def_Id, Base_Type      (T));
      Set_Size_Info        (Def_Id,                (T));
      Set_First_Rep_Item   (Def_Id, First_Rep_Item (T));
      Set_Discrete_RM_Size (Def_Id);
   end Constrain_Integer;

   ------------------------------
   -- Constrain_Ordinary_Fixed --
   ------------------------------

   procedure Constrain_Ordinary_Fixed (Def_Id : Entity_Id; S : Node_Id) is
      T    : constant Entity_Id := Entity (Subtype_Mark (S));
      C    : Node_Id;
      D    : Node_Id;
      Rais : Node_Id;

   begin
      Mutate_Ekind       (Def_Id, E_Ordinary_Fixed_Point_Subtype);
      Set_Etype          (Def_Id, Base_Type      (T));
      Set_Size_Info      (Def_Id,                (T));
      Set_First_Rep_Item (Def_Id, First_Rep_Item (T));
      Set_Small_Value    (Def_Id, Small_Value    (T));

      --  Process the constraint

      C := Constraint (S);

      --  Delta constraint present

      if Nkind (C) = N_Delta_Constraint then
         Check_Restriction (No_Obsolescent_Features, C);

         if Warn_On_Obsolescent_Feature then
            Error_Msg_S
              ("subtype delta constraint is an " &
               "obsolescent feature (RM J.3(7))?j?");
         end if;

         D := Delta_Expression (C);
         Analyze_And_Resolve (D, Any_Real);
         Check_Delta_Expression (D);
         Set_Delta_Value (Def_Id, Expr_Value_R (D));

         --  Check that delta value is in range. Obviously we can do this
         --  at compile time, but it is strictly a runtime check, and of
         --  course there is an ACVC test that checks this.

         if Delta_Value (Def_Id) < Delta_Value (T) then
            Error_Msg_N ("??delta value is too small", D);
            Rais :=
              Make_Raise_Constraint_Error (Sloc (D),
                Reason => CE_Range_Check_Failed);
            Insert_Action (Declaration_Node (Def_Id), Rais);
         end if;

         C := Range_Constraint (C);

      --  No delta constraint present

      else
         Set_Delta_Value (Def_Id, Delta_Value (T));
      end if;

      --  Range constraint present

      if Nkind (C) = N_Range_Constraint then
         Set_Scalar_Range_For_Subtype (Def_Id, Range_Expression (C), T);

      --  No range constraint present

      else
         pragma Assert (No (C));
         Set_Scalar_Range (Def_Id, Scalar_Range (T));
      end if;

      Set_Discrete_RM_Size (Def_Id);

      --  Unconditionally delay the freeze, since we cannot set size
      --  information in all cases correctly until the freeze point.

      Set_Has_Delayed_Freeze (Def_Id);
   end Constrain_Ordinary_Fixed;

   -----------------------
   -- Contain_Interface --
   -----------------------

   function Contain_Interface
     (Iface  : Entity_Id;
      Ifaces : Elist_Id) return Boolean
   is
      Iface_Elmt : Elmt_Id;

   begin
      if Present (Ifaces) then
         Iface_Elmt := First_Elmt (Ifaces);
         while Present (Iface_Elmt) loop
            if Node (Iface_Elmt) = Iface then
               return True;
            end if;

            Next_Elmt (Iface_Elmt);
         end loop;
      end if;

      return False;
   end Contain_Interface;

   ---------------------------
   -- Convert_Scalar_Bounds --
   ---------------------------

   procedure Convert_Scalar_Bounds
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id;
      Loc          : Source_Ptr)
   is
      Implicit_Base : constant Entity_Id := Base_Type (Derived_Type);

      Lo  : Node_Id;
      Hi  : Node_Id;
      Rng : Node_Id;

   begin
      --  Defend against previous errors

      if No (Scalar_Range (Derived_Type)) then
         Check_Error_Detected;
         return;
      end if;

      Lo := Build_Scalar_Bound
              (Type_Low_Bound (Derived_Type),
               Parent_Type, Implicit_Base);

      Hi := Build_Scalar_Bound
              (Type_High_Bound (Derived_Type),
               Parent_Type, Implicit_Base);

      Rng :=
        Make_Range (Loc,
          Low_Bound  => Lo,
          High_Bound => Hi);

      Set_Includes_Infinities (Rng, Has_Infinities (Derived_Type));

      Set_Parent (Rng, N);
      Set_Scalar_Range (Derived_Type, Rng);

      --  Analyze the bounds

      Analyze_And_Resolve (Lo, Implicit_Base);
      Analyze_And_Resolve (Hi, Implicit_Base);

      --  Analyze the range itself, except that we do not analyze it if
      --  the bounds are real literals, and we have a fixed-point type.
      --  The reason for this is that we delay setting the bounds in this
      --  case till we know the final Small and Size values (see circuit
      --  in Freeze.Freeze_Fixed_Point_Type for further details).

      if Is_Fixed_Point_Type (Parent_Type)
        and then Nkind (Lo) = N_Real_Literal
        and then Nkind (Hi) = N_Real_Literal
      then
         return;

      --  Here we do the analysis of the range

      --  Note: we do this manually, since if we do a normal Analyze and
      --  Resolve call, there are problems with the conversions used for
      --  the derived type range.

      else
         Set_Etype    (Rng, Implicit_Base);
         Set_Analyzed (Rng, True);
      end if;
   end Convert_Scalar_Bounds;

   -------------------
   -- Copy_And_Swap --
   -------------------

   procedure Copy_And_Swap (Priv, Full : Entity_Id) is
   begin
      --  Initialize new full declaration entity by copying the pertinent
      --  fields of the corresponding private declaration entity.

      --  We temporarily set Ekind to a value appropriate for a type to
      --  avoid assert failures in Einfo from checking for setting type
      --  attributes on something that is not a type. Ekind (Priv) is an
      --  appropriate choice, since it allowed the attributes to be set
      --  in the first place. This Ekind value will be modified later.

      Mutate_Ekind (Full, Ekind (Priv));

      --  Also set Etype temporarily to Any_Type, again, in the absence
      --  of errors, it will be properly reset, and if there are errors,
      --  then we want a value of Any_Type to remain.

      Set_Etype (Full, Any_Type);

      --  Now start copying attributes

      Set_Has_Discriminants          (Full, Has_Discriminants       (Priv));

      if Has_Discriminants (Full) then
         Set_Discriminant_Constraint (Full, Discriminant_Constraint (Priv));
         Set_Stored_Constraint       (Full, Stored_Constraint       (Priv));
      end if;

      Set_First_Rep_Item             (Full, First_Rep_Item          (Priv));
      Set_Homonym                    (Full, Homonym                 (Priv));
      Set_Is_Immediately_Visible     (Full, Is_Immediately_Visible  (Priv));
      Set_Is_Public                  (Full, Is_Public               (Priv));
      Set_Is_Pure                    (Full, Is_Pure                 (Priv));
      Set_Is_Tagged_Type             (Full, Is_Tagged_Type          (Priv));
      Set_Has_Pragma_Unmodified      (Full, Has_Pragma_Unmodified   (Priv));
      Set_Has_Pragma_Unreferenced    (Full, Has_Pragma_Unreferenced (Priv));
      Set_Has_Pragma_Unreferenced_Objects
                                     (Full, Has_Pragma_Unreferenced_Objects
                                                                    (Priv));

      Conditional_Delay              (Full,                          Priv);

      if Is_Tagged_Type (Full) then
         Set_Direct_Primitive_Operations
           (Full, Direct_Primitive_Operations (Priv));
         Set_No_Tagged_Streams_Pragma
           (Full, No_Tagged_Streams_Pragma (Priv));

         if Is_Base_Type (Priv) then
            Set_Class_Wide_Type      (Full, Class_Wide_Type         (Priv));
         end if;
      end if;

      Set_Is_Volatile                (Full, Is_Volatile             (Priv));
      Set_Treat_As_Volatile          (Full, Treat_As_Volatile       (Priv));
      Set_Scope                      (Full, Scope                   (Priv));
      Set_Prev_Entity                (Full, Prev_Entity             (Priv));
      Set_Next_Entity                (Full, Next_Entity             (Priv));
      Set_First_Entity               (Full, First_Entity            (Priv));
      Set_Last_Entity                (Full, Last_Entity             (Priv));

      --  If access types have been recorded for later handling, keep them in
      --  the full view so that they get handled when the full view freeze
      --  node is expanded.

      if Present (Freeze_Node (Priv))
        and then Present (Access_Types_To_Process (Freeze_Node (Priv)))
      then
         Ensure_Freeze_Node (Full);
         Set_Access_Types_To_Process
           (Freeze_Node (Full),
            Access_Types_To_Process (Freeze_Node (Priv)));
      end if;

      --  Swap the two entities. Now Private is the full type entity and Full
      --  is the private one. They will be swapped back at the end of the
      --  private part. This swapping ensures that the entity that is visible
      --  in the private part is the full declaration.

      Exchange_Entities (Priv, Full);
      Append_Entity (Full, Scope (Full));
   end Copy_And_Swap;

   -------------------------------------
   -- Copy_Array_Base_Type_Attributes --
   -------------------------------------

   procedure Copy_Array_Base_Type_Attributes (T1, T2 : Entity_Id) is
   begin
      Set_Component_Alignment        (T1, Component_Alignment        (T2));
      Set_Component_Type             (T1, Component_Type             (T2));
      Set_Component_Size             (T1, Component_Size             (T2));
      Set_Has_Controlled_Component   (T1, Has_Controlled_Component   (T2));
      Set_Has_Non_Standard_Rep       (T1, Has_Non_Standard_Rep       (T2));
      Propagate_Concurrent_Flags     (T1,                             T2);
      Set_Is_Packed                  (T1, Is_Packed                  (T2));
      Set_Has_Aliased_Components     (T1, Has_Aliased_Components     (T2));
      Set_Has_Atomic_Components      (T1, Has_Atomic_Components      (T2));
      Set_Has_Independent_Components (T1, Has_Independent_Components (T2));
      Set_Has_Volatile_Components    (T1, Has_Volatile_Components    (T2));
   end Copy_Array_Base_Type_Attributes;

   -----------------------------------
   -- Copy_Array_Subtype_Attributes --
   -----------------------------------

   procedure Copy_Array_Subtype_Attributes (T1, T2 : Entity_Id) is
   begin
      Set_Size_Info (T1, T2);

      Set_First_Index             (T1, First_Index             (T2));
      Set_Is_Aliased              (T1, Is_Aliased              (T2));
      Set_Is_Atomic               (T1, Is_Atomic               (T2));
      Set_Is_Independent          (T1, Is_Independent          (T2));
      Set_Is_Volatile             (T1, Is_Volatile             (T2));
      Set_Is_Volatile_Full_Access (T1, Is_Volatile_Full_Access (T2));
      Set_Treat_As_Volatile       (T1, Treat_As_Volatile       (T2));
      Set_Is_Constrained          (T1, Is_Constrained          (T2));
      Set_Depends_On_Private      (T1, Has_Private_Component   (T2));
      Inherit_Rep_Item_Chain      (T1,                          T2);
      Set_Convention              (T1, Convention              (T2));
      Set_Is_Limited_Composite    (T1, Is_Limited_Composite    (T2));
      Set_Is_Private_Composite    (T1, Is_Private_Composite    (T2));
      Set_Packed_Array_Impl_Type  (T1, Packed_Array_Impl_Type  (T2));
   end Copy_Array_Subtype_Attributes;

   -----------------------------------
   -- Create_Constrained_Components --
   -----------------------------------

   procedure Create_Constrained_Components
     (Subt        : Entity_Id;
      Decl_Node   : Node_Id;
      Typ         : Entity_Id;
      Constraints : Elist_Id)
   is
      Loc         : constant Source_Ptr := Sloc (Subt);
      Comp_List   : constant Elist_Id   := New_Elmt_List;
      Parent_Type : constant Entity_Id  := Etype (Typ);
      Assoc_List  : constant List_Id    := New_List;

      Discr_Val             : Elmt_Id;
      Errors                : Boolean;
      New_C                 : Entity_Id;
      Old_C                 : Entity_Id;
      Is_Static             : Boolean := True;
      Is_Compile_Time_Known : Boolean := True;

      procedure Collect_Fixed_Components (Typ : Entity_Id);
      --  Collect parent type components that do not appear in a variant part

      procedure Create_All_Components;
      --  Iterate over Comp_List to create the components of the subtype

      function Create_Component (Old_Compon : Entity_Id) return Entity_Id;
      --  Creates a new component from Old_Compon, copying all the fields from
      --  it, including its Etype, inserts the new component in the Subt entity
      --  chain and returns the new component.

      function Is_Variant_Record (T : Entity_Id) return Boolean;
      --  If true, and discriminants are static, collect only components from
      --  variants selected by discriminant values.

      ------------------------------
      -- Collect_Fixed_Components --
      ------------------------------

      procedure Collect_Fixed_Components (Typ : Entity_Id) is
      begin
      --  Build association list for discriminants, and find components of the
      --  variant part selected by the values of the discriminants.

         Old_C := First_Discriminant (Typ);
         Discr_Val := First_Elmt (Constraints);
         while Present (Old_C) loop
            Append_To (Assoc_List,
              Make_Component_Association (Loc,
                 Choices    => New_List (New_Occurrence_Of (Old_C, Loc)),
                 Expression => New_Copy (Node (Discr_Val))));

            Next_Elmt (Discr_Val);
            Next_Discriminant (Old_C);
         end loop;

         --  The tag and the possible parent component are unconditionally in
         --  the subtype.

         if Is_Tagged_Type (Typ) or else Has_Controlled_Component (Typ) then
            Old_C := First_Component (Typ);
            while Present (Old_C) loop
               if Chars (Old_C) in Name_uTag | Name_uParent then
                  Append_Elmt (Old_C, Comp_List);
               end if;

               Next_Component (Old_C);
            end loop;
         end if;
      end Collect_Fixed_Components;

      ---------------------------
      -- Create_All_Components --
      ---------------------------

      procedure Create_All_Components is
         Comp : Elmt_Id;

      begin
         Comp := First_Elmt (Comp_List);
         while Present (Comp) loop
            Old_C := Node (Comp);
            New_C := Create_Component (Old_C);

            Set_Etype
              (New_C,
               Constrain_Component_Type
                 (Old_C, Subt, Decl_Node, Typ, Constraints));
            Set_Is_Public (New_C, Is_Public (Subt));

            Next_Elmt (Comp);
         end loop;
      end Create_All_Components;

      ----------------------
      -- Create_Component --
      ----------------------

      function Create_Component (Old_Compon : Entity_Id) return Entity_Id is
         New_Compon : constant Entity_Id := New_Copy (Old_Compon);

      begin
         if Ekind (Old_Compon) = E_Discriminant
           and then Is_Completely_Hidden (Old_Compon)
         then
            --  This is a shadow discriminant created for a discriminant of
            --  the parent type, which needs to be present in the subtype.
            --  Give the shadow discriminant an internal name that cannot
            --  conflict with that of visible components.

            Set_Chars (New_Compon, New_Internal_Name ('C'));
         end if;

         --  Set the parent so we have a proper link for freezing etc. This is
         --  not a real parent pointer, since of course our parent does not own
         --  up to us and reference us, we are an illegitimate child of the
         --  original parent.

         Set_Parent (New_Compon, Parent (Old_Compon));

         --  We do not want this node marked as Comes_From_Source, since
         --  otherwise it would get first class status and a separate cross-
         --  reference line would be generated. Illegitimate children do not
         --  rate such recognition.

         Set_Comes_From_Source (New_Compon, False);

         --  But it is a real entity, and a birth certificate must be properly
         --  registered by entering it into the entity list, and setting its
         --  scope to the given subtype. This turns out to be useful for the
         --  LLVM code generator, but that scope is not used otherwise.

         Enter_Name (New_Compon);
         Set_Scope (New_Compon, Subt);

         return New_Compon;
      end Create_Component;

      -----------------------
      -- Is_Variant_Record --
      -----------------------

      function Is_Variant_Record (T : Entity_Id) return Boolean is
      begin
         return Nkind (Parent (T)) = N_Full_Type_Declaration
           and then Nkind (Type_Definition (Parent (T))) = N_Record_Definition
           and then Present (Component_List (Type_Definition (Parent (T))))
           and then
             Present
               (Variant_Part (Component_List (Type_Definition (Parent (T)))));
      end Is_Variant_Record;

   --  Start of processing for Create_Constrained_Components

   begin
      pragma Assert (Subt /= Base_Type (Subt));
      pragma Assert (Typ = Base_Type (Typ));

      Set_First_Entity (Subt, Empty);
      Set_Last_Entity  (Subt, Empty);

      --  Check whether constraint is fully static, in which case we can
      --  optimize the list of components.

      Discr_Val := First_Elmt (Constraints);
      while Present (Discr_Val) loop
         if not Is_OK_Static_Expression (Node (Discr_Val)) then
            Is_Static := False;

            if not Compile_Time_Known_Value (Node (Discr_Val)) then
               Is_Compile_Time_Known := False;
               exit;
            end if;
         end if;

         Next_Elmt (Discr_Val);
      end loop;

      Set_Has_Static_Discriminants (Subt, Is_Static);

      Push_Scope (Subt);

      --  Inherit the discriminants of the parent type

      Add_Discriminants : declare
         Num_Disc : Nat;
         Num_Stor : Nat;

      begin
         Num_Disc := 0;
         Old_C := First_Discriminant (Typ);

         while Present (Old_C) loop
            Num_Disc := Num_Disc + 1;
            New_C := Create_Component (Old_C);
            Set_Is_Public (New_C, Is_Public (Subt));
            Next_Discriminant (Old_C);
         end loop;

         --  For an untagged derived subtype, the number of discriminants may
         --  be smaller than the number of inherited discriminants, because
         --  several of them may be renamed by a single new discriminant or
         --  constrained. In this case, add the hidden discriminants back into
         --  the subtype, because they need to be present if the optimizer of
         --  the GCC 4.x back-end decides to break apart assignments between
         --  objects using the parent view into member-wise assignments.

         Num_Stor := 0;

         if Is_Derived_Type (Typ)
           and then not Is_Tagged_Type (Typ)
         then
            Old_C := First_Stored_Discriminant (Typ);

            while Present (Old_C) loop
               Num_Stor := Num_Stor + 1;
               Next_Stored_Discriminant (Old_C);
            end loop;
         end if;

         if Num_Stor > Num_Disc then

            --  Find out multiple uses of new discriminants, and add hidden
            --  components for the extra renamed discriminants. We recognize
            --  multiple uses through the Corresponding_Discriminant of a
            --  new discriminant: if it constrains several old discriminants,
            --  this field points to the last one in the parent type. The
            --  stored discriminants of the derived type have the same name
            --  as those of the parent.

            declare
               Constr    : Elmt_Id;
               New_Discr : Entity_Id;
               Old_Discr : Entity_Id;

            begin
               Constr    := First_Elmt (Stored_Constraint (Typ));
               Old_Discr := First_Stored_Discriminant (Typ);
               while Present (Constr) loop
                  if Is_Entity_Name (Node (Constr))
                    and then Ekind (Entity (Node (Constr))) = E_Discriminant
                  then
                     New_Discr := Entity (Node (Constr));

                     if Chars (Corresponding_Discriminant (New_Discr)) /=
                        Chars (Old_Discr)
                     then
                        --  The new discriminant has been used to rename a
                        --  subsequent old discriminant. Introduce a shadow
                        --  component for the current old discriminant.

                        New_C := Create_Component (Old_Discr);
                        Set_Original_Record_Component (New_C, Old_Discr);
                     end if;

                  else
                     --  The constraint has eliminated the old discriminant.
                     --  Introduce a shadow component.

                     New_C := Create_Component (Old_Discr);
                     Set_Original_Record_Component (New_C, Old_Discr);
                  end if;

                  Next_Elmt (Constr);
                  Next_Stored_Discriminant (Old_Discr);
               end loop;
            end;
         end if;
      end Add_Discriminants;

      if Is_Compile_Time_Known
        and then Is_Variant_Record (Typ)
      then
         Collect_Fixed_Components (Typ);
         Gather_Components
           (Typ,
            Component_List (Type_Definition (Parent (Typ))),
            Governed_By          => Assoc_List,
            Into                 => Comp_List,
            Report_Errors        => Errors,
            Allow_Compile_Time   => True);
         pragma Assert (not Errors or else Serious_Errors_Detected > 0);

         Create_All_Components;

      --  If the subtype declaration is created for a tagged type derivation
      --  with constraints, we retrieve the record definition of the parent
      --  type to select the components of the proper variant.

      elsif Is_Compile_Time_Known
        and then Is_Tagged_Type (Typ)
        and then Nkind (Parent (Typ)) = N_Full_Type_Declaration
        and then
          Nkind (Type_Definition (Parent (Typ))) = N_Derived_Type_Definition
        and then Is_Variant_Record (Parent_Type)
      then
         Collect_Fixed_Components (Typ);
         Gather_Components
           (Typ,
            Component_List (Type_Definition (Parent (Parent_Type))),
            Governed_By          => Assoc_List,
            Into                 => Comp_List,
            Report_Errors        => Errors,
            Allow_Compile_Time   => True);

         --  Note: previously there was a check at this point that no errors
         --  were detected. As a consequence of AI05-220 there may be an error
         --  if an inherited discriminant that controls a variant has a non-
         --  static constraint.

         --  If the tagged derivation has a type extension, collect all the
         --  new relevant components therein via Gather_Components.

         if Present (Record_Extension_Part (Type_Definition (Parent (Typ))))
         then
            Gather_Components
              (Typ,
               Component_List
                 (Record_Extension_Part (Type_Definition (Parent (Typ)))),
               Governed_By           => Assoc_List,
               Into                  => Comp_List,
               Report_Errors         => Errors,
               Allow_Compile_Time    => True,
               Include_Interface_Tag => True);
         end if;

         Create_All_Components;

      else
         --  If discriminants are not static, or if this is a multi-level type
         --  extension, we have to include all components of the parent type.

         Old_C := First_Component (Typ);
         while Present (Old_C) loop
            New_C := Create_Component (Old_C);

            Set_Etype
              (New_C,
               Constrain_Component_Type
                 (Old_C, Subt, Decl_Node, Typ, Constraints));
            Set_Is_Public (New_C, Is_Public (Subt));

            Next_Component (Old_C);
         end loop;
      end if;

      End_Scope;
   end Create_Constrained_Components;

   ------------------------------------------
   -- Decimal_Fixed_Point_Type_Declaration --
   ------------------------------------------

   procedure Decimal_Fixed_Point_Type_Declaration
     (T   : Entity_Id;
      Def : Node_Id)
   is
      Loc           : constant Source_Ptr := Sloc (Def);
      Digs_Expr     : constant Node_Id    := Digits_Expression (Def);
      Delta_Expr    : constant Node_Id    := Delta_Expression (Def);
      Max_Digits    : constant Nat        :=
                        (if System_Max_Integer_Size = 128 then 38 else 18);
      --  Maximum number of digits that can be represented in an integer

      Implicit_Base : Entity_Id;
      Digs_Val      : Uint;
      Delta_Val     : Ureal;
      Scale_Val     : Uint;
      Bound_Val     : Ureal;

   begin
      Check_Restriction (No_Fixed_Point, Def);

      --  Create implicit base type

      Implicit_Base :=
        Create_Itype (E_Decimal_Fixed_Point_Type, Parent (Def), T, 'B');
      Set_Etype (Implicit_Base, Implicit_Base);

      --  Analyze and process delta expression

      Analyze_And_Resolve (Delta_Expr, Universal_Real);

      Check_Delta_Expression (Delta_Expr);
      Delta_Val := Expr_Value_R (Delta_Expr);

      --  Check delta is power of 10, and determine scale value from it

      declare
         Val : Ureal;

      begin
         Scale_Val := Uint_0;
         Val := Delta_Val;

         if Val < Ureal_1 then
            while Val < Ureal_1 loop
               Val := Val * Ureal_10;
               Scale_Val := Scale_Val + 1;
            end loop;

            if Scale_Val > Max_Digits then
               Error_Msg_Uint_1 := UI_From_Int (Max_Digits);
               Error_Msg_N ("scale exceeds maximum value of ^", Def);
               Scale_Val := UI_From_Int (Max_Digits);
            end if;

         else
            while Val > Ureal_1 loop
               Val := Val / Ureal_10;
               Scale_Val := Scale_Val - 1;
            end loop;

            if Scale_Val < -Max_Digits then
               Error_Msg_Uint_1 := UI_From_Int (-Max_Digits);
               Error_Msg_N ("scale is less than minimum value of ^", Def);
               Scale_Val := UI_From_Int (-Max_Digits);
            end if;
         end if;

         if Val /= Ureal_1 then
            Error_Msg_N ("delta expression must be a power of 10", Def);
            Delta_Val := Ureal_10 ** (-Scale_Val);
         end if;
      end;

      --  Set delta, scale and small (small = delta for decimal type)

      Set_Delta_Value (Implicit_Base, Delta_Val);
      Set_Scale_Value (Implicit_Base, Scale_Val);
      Set_Small_Value (Implicit_Base, Delta_Val);

      --  Analyze and process digits expression

      Analyze_And_Resolve (Digs_Expr, Any_Integer);
      Check_Digits_Expression (Digs_Expr);
      Digs_Val := Expr_Value (Digs_Expr);

      if Digs_Val > Max_Digits then
         Error_Msg_Uint_1 := UI_From_Int (Max_Digits);
         Error_Msg_N ("digits value out of range, maximum is ^", Digs_Expr);
         Digs_Val := UI_From_Int (Max_Digits);
      end if;

      Set_Digits_Value (Implicit_Base, Digs_Val);
      Bound_Val := UR_From_Uint (10 ** Digs_Val - 1) * Delta_Val;

      --  Set range of base type from digits value for now. This will be
      --  expanded to represent the true underlying base range by Freeze.

      Set_Fixed_Range (Implicit_Base, Loc, -Bound_Val, Bound_Val);

      --  Note: We leave Esize unset for now, size will be set at freeze
      --  time. We have to do this for ordinary fixed-point, because the size
      --  depends on the specified small, and we might as well do the same for
      --  decimal fixed-point.

      pragma Assert (not Known_Esize (Implicit_Base));

      --  If there are bounds given in the declaration use them as the
      --  bounds of the first named subtype.

      if Present (Real_Range_Specification (Def)) then
         declare
            RRS      : constant Node_Id := Real_Range_Specification (Def);
            Low      : constant Node_Id := Low_Bound (RRS);
            High     : constant Node_Id := High_Bound (RRS);
            Low_Val  : Ureal;
            High_Val : Ureal;

         begin
            Analyze_And_Resolve (Low, Any_Real);
            Analyze_And_Resolve (High, Any_Real);
            Check_Real_Bound (Low);
            Check_Real_Bound (High);
            Low_Val := Expr_Value_R (Low);
            High_Val := Expr_Value_R (High);

            if Low_Val < (-Bound_Val) then
               Error_Msg_N
                 ("range low bound too small for digits value", Low);
               Low_Val := -Bound_Val;
            end if;

            if High_Val > Bound_Val then
               Error_Msg_N
                 ("range high bound too large for digits value", High);
               High_Val := Bound_Val;
            end if;

            Set_Fixed_Range (T, Loc, Low_Val, High_Val);
         end;

      --  If no explicit range, use range that corresponds to given
      --  digits value. This will end up as the final range for the
      --  first subtype.

      else
         Set_Fixed_Range (T, Loc, -Bound_Val, Bound_Val);
      end if;

      --  Complete entity for first subtype. The inheritance of the rep item
      --  chain ensures that SPARK-related pragmas are not clobbered when the
      --  decimal fixed point type acts as a full view of a private type.

      Mutate_Ekind           (T, E_Decimal_Fixed_Point_Subtype);
      Set_Etype              (T, Implicit_Base);
      Set_Size_Info          (T, Implicit_Base);
      Inherit_Rep_Item_Chain (T, Implicit_Base);
      Set_Digits_Value       (T, Digs_Val);
      Set_Delta_Value        (T, Delta_Val);
      Set_Small_Value        (T, Delta_Val);
      Set_Scale_Value        (T, Scale_Val);
      Set_Is_Constrained     (T);
   end Decimal_Fixed_Point_Type_Declaration;

   -----------------------------------
   -- Derive_Progenitor_Subprograms --
   -----------------------------------

   procedure Derive_Progenitor_Subprograms
     (Parent_Type : Entity_Id;
      Tagged_Type : Entity_Id)
   is
      E           : Entity_Id;
      Elmt        : Elmt_Id;
      Iface       : Entity_Id;
      Iface_Alias : Entity_Id;
      Iface_Elmt  : Elmt_Id;
      Iface_Subp  : Entity_Id;
      New_Subp    : Entity_Id := Empty;
      Prim_Elmt   : Elmt_Id;
      Subp        : Entity_Id;
      Typ         : Entity_Id;

   begin
      pragma Assert (Ada_Version >= Ada_2005
        and then Is_Record_Type (Tagged_Type)
        and then Is_Tagged_Type (Tagged_Type)
        and then Has_Interfaces (Tagged_Type));

      --  Step 1: Transfer to the full-view primitives associated with the
      --  partial-view that cover interface primitives. Conceptually this
      --  work should be done later by Process_Full_View; done here to
      --  simplify its implementation at later stages. It can be safely
      --  done here because interfaces must be visible in the partial and
      --  private view (RM 7.3(7.3/2)).

      --  Small optimization: This work is only required if the parent may
      --  have entities whose Alias attribute reference an interface primitive.
      --  Such a situation may occur if the parent is an abstract type and the
      --  primitive has not been yet overridden or if the parent is a generic
      --  formal type covering interfaces.

      --  If the tagged type is not abstract, it cannot have abstract
      --  primitives (the only entities in the list of primitives of
      --  non-abstract tagged types that can reference abstract primitives
      --  through its Alias attribute are the internal entities that have
      --  attribute Interface_Alias, and these entities are generated later
      --  by Add_Internal_Interface_Entities).

      if In_Private_Part (Current_Scope)
        and then (Is_Abstract_Type (Parent_Type)
                    or else
                  Is_Generic_Type  (Parent_Type))
      then
         Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
         while Present (Elmt) loop
            Subp := Node (Elmt);

            --  At this stage it is not possible to have entities in the list
            --  of primitives that have attribute Interface_Alias.

            pragma Assert (No (Interface_Alias (Subp)));

            Typ := Find_Dispatching_Type (Ultimate_Alias (Subp));

            if Is_Interface (Typ) then
               E := Find_Primitive_Covering_Interface
                      (Tagged_Type => Tagged_Type,
                       Iface_Prim  => Subp);

               if Present (E)
                 and then Find_Dispatching_Type (Ultimate_Alias (E)) /= Typ
               then
                  Replace_Elmt (Elmt, E);
                  Remove_Homonym (Subp);
               end if;
            end if;

            Next_Elmt (Elmt);
         end loop;
      end if;

      --  Step 2: Add primitives of progenitors that are not implemented by
      --  parents of Tagged_Type.

      if Present (Interfaces (Base_Type (Tagged_Type))) then
         Iface_Elmt := First_Elmt (Interfaces (Base_Type (Tagged_Type)));
         while Present (Iface_Elmt) loop
            Iface := Node (Iface_Elmt);

            Prim_Elmt := First_Elmt (Primitive_Operations (Iface));
            while Present (Prim_Elmt) loop
               Iface_Subp  := Node (Prim_Elmt);
               Iface_Alias := Ultimate_Alias (Iface_Subp);

               --  Exclude derivation of predefined primitives except those
               --  that come from source, or are inherited from one that comes
               --  from source. Required to catch declarations of equality
               --  operators of interfaces. For example:

               --     type Iface is interface;
               --     function "=" (Left, Right : Iface) return Boolean;

               if not Is_Predefined_Dispatching_Operation (Iface_Subp)
                 or else Comes_From_Source (Iface_Alias)
               then
                  E :=
                    Find_Primitive_Covering_Interface
                      (Tagged_Type => Tagged_Type,
                       Iface_Prim  => Iface_Subp);

                  --  If not found we derive a new primitive leaving its alias
                  --  attribute referencing the interface primitive.

                  if No (E) then
                     Derive_Subprogram
                       (New_Subp, Iface_Subp, Tagged_Type, Iface);

                  --  Ada 2012 (AI05-0197): If the covering primitive's name
                  --  differs from the name of the interface primitive then it
                  --  is a private primitive inherited from a parent type. In
                  --  such case, given that Tagged_Type covers the interface,
                  --  the inherited private primitive becomes visible. For such
                  --  purpose we add a new entity that renames the inherited
                  --  private primitive.

                  elsif Chars (E) /= Chars (Iface_Subp) then
                     pragma Assert (Has_Suffix (E, 'P'));
                     Derive_Subprogram
                       (New_Subp, Iface_Subp, Tagged_Type, Iface);
                     Set_Alias (New_Subp, E);
                     Set_Is_Abstract_Subprogram (New_Subp,
                       Is_Abstract_Subprogram (E));

                  --  Propagate to the full view interface entities associated
                  --  with the partial view.

                  elsif In_Private_Part (Current_Scope)
                    and then Present (Alias (E))
                    and then Alias (E) = Iface_Subp
                    and then
                      List_Containing (Parent (E)) /=
                        Private_Declarations
                          (Specification
                            (Unit_Declaration_Node (Current_Scope)))
                  then
                     Append_Elmt (E, Primitive_Operations (Tagged_Type));
                  end if;
               end if;

               Next_Elmt (Prim_Elmt);
            end loop;

            Next_Elmt (Iface_Elmt);
         end loop;
      end if;
   end Derive_Progenitor_Subprograms;

   -----------------------
   -- Derive_Subprogram --
   -----------------------

   procedure Derive_Subprogram
     (New_Subp     : out Entity_Id;
      Parent_Subp  : Entity_Id;
      Derived_Type : Entity_Id;
      Parent_Type  : Entity_Id;
      Actual_Subp  : Entity_Id := Empty)
   is
      Formal : Entity_Id;
      --  Formal parameter of parent primitive operation

      Formal_Of_Actual : Entity_Id;
      --  Formal parameter of actual operation, when the derivation is to
      --  create a renaming for a primitive operation of an actual in an
      --  instantiation.

      New_Formal : Entity_Id;
      --  Formal of inherited operation

      Visible_Subp : Entity_Id := Parent_Subp;

      function Is_Private_Overriding return Boolean;
      --  If Subp is a private overriding of a visible operation, the inherited
      --  operation derives from the overridden op (even though its body is the
      --  overriding one) and the inherited operation is visible now. See
      --  sem_disp to see the full details of the handling of the overridden
      --  subprogram, which is removed from the list of primitive operations of
      --  the type. The overridden subprogram is saved locally in Visible_Subp,
      --  and used to diagnose abstract operations that need overriding in the
      --  derived type.

      procedure Replace_Type (Id, New_Id : Entity_Id);
      --  When the type is an anonymous access type, create a new access type
      --  designating the derived type.

      procedure Set_Derived_Name;
      --  This procedure sets the appropriate Chars name for New_Subp. This
      --  is normally just a copy of the parent name. An exception arises for
      --  type support subprograms, where the name is changed to reflect the
      --  name of the derived type, e.g. if type foo is derived from type bar,
      --  then a procedure barDA is derived with a name fooDA.

      ---------------------------
      -- Is_Private_Overriding --
      ---------------------------

      function Is_Private_Overriding return Boolean is
         Prev : Entity_Id;

      begin
         --  If the parent is not a dispatching operation there is no
         --  need to investigate overridings

         if not Is_Dispatching_Operation (Parent_Subp) then
            return False;
         end if;

         --  The visible operation that is overridden is a homonym of the
         --  parent subprogram. We scan the homonym chain to find the one
         --  whose alias is the subprogram we are deriving.

         Prev := Current_Entity (Parent_Subp);
         while Present (Prev) loop
            if Ekind (Prev) = Ekind (Parent_Subp)
              and then Alias (Prev) = Parent_Subp
              and then Scope (Parent_Subp) = Scope (Prev)
              and then not Is_Hidden (Prev)
            then
               Visible_Subp := Prev;
               return True;
            end if;

            Prev := Homonym (Prev);
         end loop;

         return False;
      end Is_Private_Overriding;

      ------------------
      -- Replace_Type --
      ------------------

      procedure Replace_Type (Id, New_Id : Entity_Id) is
         Id_Type  : constant Entity_Id := Etype (Id);
         Acc_Type : Entity_Id;
         Par      : constant Node_Id := Parent (Derived_Type);

      begin
         --  When the type is an anonymous access type, create a new access
         --  type designating the derived type. This itype must be elaborated
         --  at the point of the derivation, not on subsequent calls that may
         --  be out of the proper scope for Gigi, so we insert a reference to
         --  it after the derivation.

         if Ekind (Id_Type) = E_Anonymous_Access_Type then
            declare
               Desig_Typ : Entity_Id := Designated_Type (Id_Type);

            begin
               if Ekind (Desig_Typ) = E_Record_Type_With_Private
                 and then Present (Full_View (Desig_Typ))
                 and then not Is_Private_Type (Parent_Type)
               then
                  Desig_Typ := Full_View (Desig_Typ);
               end if;

               if Base_Type (Desig_Typ) = Base_Type (Parent_Type)

                  --  Ada 2005 (AI-251): Handle also derivations of abstract
                  --  interface primitives.

                 or else (Is_Interface (Desig_Typ)
                           and then not Is_Class_Wide_Type (Desig_Typ))
               then
                  Acc_Type := New_Copy (Id_Type);
                  Set_Etype (Acc_Type, Acc_Type);
                  Set_Scope (Acc_Type, New_Subp);

                  --  Set size of anonymous access type. If we have an access
                  --  to an unconstrained array, this is a fat pointer, so it
                  --  is sizes at twice addtress size.

                  if Is_Array_Type (Desig_Typ)
                    and then not Is_Constrained (Desig_Typ)
                  then
                     Init_Size (Acc_Type, 2 * System_Address_Size);

                  --  Other cases use a thin pointer

                  else
                     Init_Size (Acc_Type, System_Address_Size);
                  end if;

                  --  Set remaining characterstics of anonymous access type

                  Reinit_Alignment (Acc_Type);
                  Set_Directly_Designated_Type (Acc_Type, Derived_Type);

                  Set_Etype (New_Id, Acc_Type);
                  Set_Scope (New_Id, New_Subp);

                  --  Create a reference to it

                  Build_Itype_Reference (Acc_Type, Parent (Derived_Type));

               else
                  Set_Etype (New_Id, Id_Type);
               end if;
            end;

         --  In Ada2012, a formal may have an incomplete type but the type
         --  derivation that inherits the primitive follows the full view.

         elsif Base_Type (Id_Type) = Base_Type (Parent_Type)
           or else
             (Ekind (Id_Type) = E_Record_Type_With_Private
               and then Present (Full_View (Id_Type))
               and then
                 Base_Type (Full_View (Id_Type)) = Base_Type (Parent_Type))
           or else
             (Ada_Version >= Ada_2012
               and then Ekind (Id_Type) = E_Incomplete_Type
               and then Full_View (Id_Type) = Parent_Type)
         then
            --  Constraint checks on formals are generated during expansion,
            --  based on the signature of the original subprogram. The bounds
            --  of the derived type are not relevant, and thus we can use
            --  the base type for the formals. However, the return type may be
            --  used in a context that requires that the proper static bounds
            --  be used (a case statement, for example) and for those cases
            --  we must use the derived type (first subtype), not its base.

            --  If the derived_type_definition has no constraints, we know that
            --  the derived type has the same constraints as the first subtype
            --  of the parent, and we can also use it rather than its base,
            --  which can lead to more efficient code.

            if Etype (Id) = Parent_Type then
               if Is_Scalar_Type (Parent_Type)
                 and then
                   Subtypes_Statically_Compatible (Parent_Type, Derived_Type)
               then
                  Set_Etype (New_Id, Derived_Type);

               elsif Nkind (Par) = N_Full_Type_Declaration
                 and then
                   Nkind (Type_Definition (Par)) = N_Derived_Type_Definition
                 and then
                   Is_Entity_Name
                     (Subtype_Indication (Type_Definition (Par)))
               then
                  Set_Etype (New_Id, Derived_Type);

               else
                  Set_Etype (New_Id, Base_Type (Derived_Type));
               end if;

            else
               Set_Etype (New_Id, Base_Type (Derived_Type));
            end if;

         else
            Set_Etype (New_Id, Etype (Id));
         end if;
      end Replace_Type;

      ----------------------
      -- Set_Derived_Name --
      ----------------------

      procedure Set_Derived_Name is
         Nm : constant TSS_Name_Type := Get_TSS_Name (Parent_Subp);
      begin
         if Nm = TSS_Null then
            Set_Chars (New_Subp, Chars (Parent_Subp));
         else
            Set_Chars (New_Subp, Make_TSS_Name (Base_Type (Derived_Type), Nm));
         end if;
      end Set_Derived_Name;

   --  Start of processing for Derive_Subprogram

   begin
      New_Subp := New_Entity (Nkind (Parent_Subp), Sloc (Derived_Type));
      Mutate_Ekind (New_Subp, Ekind (Parent_Subp));

      --  Check whether the inherited subprogram is a private operation that
      --  should be inherited but not yet made visible. Such subprograms can
      --  become visible at a later point (e.g., the private part of a public
      --  child unit) via Declare_Inherited_Private_Subprograms. If the
      --  following predicate is true, then this is not such a private
      --  operation and the subprogram simply inherits the name of the parent
      --  subprogram. Note the special check for the names of controlled
      --  operations, which are currently exempted from being inherited with
      --  a hidden name because they must be findable for generation of
      --  implicit run-time calls.

      if not Is_Hidden (Parent_Subp)
        or else Is_Internal (Parent_Subp)
        or else Is_Private_Overriding
        or else Is_Internal_Name (Chars (Parent_Subp))
        or else (Is_Controlled (Parent_Type)
                  and then Chars (Parent_Subp) in Name_Adjust
                                                | Name_Finalize
                                                | Name_Initialize)
      then
         Set_Derived_Name;

      --  An inherited dispatching equality will be overridden by an internally
      --  generated one, or by an explicit one, so preserve its name and thus
      --  its entry in the dispatch table. Otherwise, if Parent_Subp is a
      --  private operation it may become invisible if the full view has
      --  progenitors, and the dispatch table will be malformed.
      --  We check that the type is limited to handle the anomalous declaration
      --  of Limited_Controlled, which is derived from a non-limited type, and
      --  which is handled specially elsewhere as well.

      elsif Chars (Parent_Subp) = Name_Op_Eq
        and then Is_Dispatching_Operation (Parent_Subp)
        and then Etype (Parent_Subp) = Standard_Boolean
        and then not Is_Limited_Type (Etype (First_Formal (Parent_Subp)))
        and then
          Etype (First_Formal (Parent_Subp)) =
            Etype (Next_Formal (First_Formal (Parent_Subp)))
      then
         Set_Derived_Name;

      --  If parent is hidden, this can be a regular derivation if the
      --  parent is immediately visible in a non-instantiating context,
      --  or if we are in the private part of an instance. This test
      --  should still be refined ???

      --  The test for In_Instance_Not_Visible avoids inheriting the derived
      --  operation as a non-visible operation in cases where the parent
      --  subprogram might not be visible now, but was visible within the
      --  original generic, so it would be wrong to make the inherited
      --  subprogram non-visible now. (Not clear if this test is fully
      --  correct; are there any cases where we should declare the inherited
      --  operation as not visible to avoid it being overridden, e.g., when
      --  the parent type is a generic actual with private primitives ???)

      --  (they should be treated the same as other private inherited
      --  subprograms, but it's not clear how to do this cleanly). ???

      elsif (In_Open_Scopes (Scope (Base_Type (Parent_Type)))
              and then Is_Immediately_Visible (Parent_Subp)
              and then not In_Instance)
        or else In_Instance_Not_Visible
      then
         Set_Derived_Name;

      --  Ada 2005 (AI-251): Regular derivation if the parent subprogram
      --  overrides an interface primitive because interface primitives
      --  must be visible in the partial view of the parent (RM 7.3 (7.3/2))

      elsif Ada_Version >= Ada_2005
         and then Is_Dispatching_Operation (Parent_Subp)
         and then Present (Covered_Interface_Op (Parent_Subp))
      then
         Set_Derived_Name;

      --  Otherwise, the type is inheriting a private operation, so enter it
      --  with a special name so it can't be overridden. See also below, where
      --  we check for this case, and if so avoid setting Requires_Overriding.

      else
         Set_Chars (New_Subp, New_External_Name (Chars (Parent_Subp), 'P'));
      end if;

      Set_Parent (New_Subp, Parent (Derived_Type));

      if Present (Actual_Subp) then
         Replace_Type (Actual_Subp, New_Subp);
      else
         Replace_Type (Parent_Subp, New_Subp);
      end if;

      Conditional_Delay (New_Subp, Parent_Subp);

      --  If we are creating a renaming for a primitive operation of an
      --  actual of a generic derived type, we must examine the signature
      --  of the actual primitive, not that of the generic formal, which for
      --  example may be an interface. However the name and initial value
      --  of the inherited operation are those of the formal primitive.

      Formal := First_Formal (Parent_Subp);

      if Present (Actual_Subp) then
         Formal_Of_Actual := First_Formal (Actual_Subp);
      else
         Formal_Of_Actual := Empty;
      end if;

      while Present (Formal) loop
         New_Formal := New_Copy (Formal);

         --  Extra formals are not inherited from a limited interface parent
         --  since limitedness is not inherited in such case (AI-419) and this
         --  affects the extra formals.

         if Is_Limited_Interface (Parent_Type) then
            Set_Extra_Formal (New_Formal, Empty);
            Set_Extra_Accessibility (New_Formal, Empty);
         end if;

         --  Normally we do not go copying parents, but in the case of
         --  formals, we need to link up to the declaration (which is the
         --  parameter specification), and it is fine to link up to the
         --  original formal's parameter specification in this case.

         Set_Parent (New_Formal, Parent (Formal));
         Append_Entity (New_Formal, New_Subp);

         if Present (Formal_Of_Actual) then
            Replace_Type (Formal_Of_Actual, New_Formal);
            Next_Formal (Formal_Of_Actual);
         else
            Replace_Type (Formal, New_Formal);
         end if;

         Next_Formal (Formal);
      end loop;

      --  Extra formals are shared between the parent subprogram and the
      --  derived subprogram (implicit in the above copy of formals), unless
      --  the parent type is a limited interface type; hence we must inherit
      --  also the reference to the first extra formal. When the parent type is
      --  an interface the extra formals will be added when the subprogram is
      --  frozen (see Freeze.Freeze_Subprogram).

      if not Is_Limited_Interface (Parent_Type) then
         Set_Extra_Formals (New_Subp, Extra_Formals (Parent_Subp));

         if Ekind (New_Subp) = E_Function then
            Set_Extra_Accessibility_Of_Result (New_Subp,
              Extra_Accessibility_Of_Result (Parent_Subp));
         end if;
      end if;

      --  If this derivation corresponds to a tagged generic actual, then
      --  primitive operations rename those of the actual. Otherwise the
      --  primitive operations rename those of the parent type, If the parent
      --  renames an intrinsic operator, so does the new subprogram. We except
      --  concatenation, which is always properly typed, and does not get
      --  expanded as other intrinsic operations.

      if No (Actual_Subp) then
         if Is_Intrinsic_Subprogram (Parent_Subp) then
            Set_Is_Intrinsic_Subprogram (New_Subp);

            if Present (Alias (Parent_Subp))
              and then Chars (Parent_Subp) /= Name_Op_Concat
            then
               Set_Alias (New_Subp, Alias (Parent_Subp));
            else
               Set_Alias (New_Subp, Parent_Subp);
            end if;

         else
            Set_Alias (New_Subp, Parent_Subp);
         end if;

      else
         Set_Alias (New_Subp, Actual_Subp);
      end if;

      --  Derived subprograms of a tagged type must inherit the convention
      --  of the parent subprogram (a requirement of AI-117). Derived
      --  subprograms of untagged types simply get convention Ada by default.

      --  If the derived type is a tagged generic formal type with unknown
      --  discriminants, its convention is intrinsic (RM 6.3.1 (8)).

      --  However, if the type is derived from a generic formal, the further
      --  inherited subprogram has the convention of the non-generic ancestor.
      --  Otherwise there would be no way to override the operation.
      --  (This is subject to forthcoming ARG discussions).

      if Is_Tagged_Type (Derived_Type) then
         if Is_Generic_Type (Derived_Type)
           and then Has_Unknown_Discriminants (Derived_Type)
         then
            Set_Convention (New_Subp, Convention_Intrinsic);

         else
            if Is_Generic_Type (Parent_Type)
              and then Has_Unknown_Discriminants (Parent_Type)
            then
               Set_Convention (New_Subp, Convention (Alias (Parent_Subp)));
            else
               Set_Convention (New_Subp, Convention (Parent_Subp));
            end if;
         end if;
      end if;

      --  Predefined controlled operations retain their name even if the parent
      --  is hidden (see above), but they are not primitive operations if the
      --  ancestor is not visible, for example if the parent is a private
      --  extension completed with a controlled extension. Note that a full
      --  type that is controlled can break privacy: the flag Is_Controlled is
      --  set on both views of the type.

      if Is_Controlled (Parent_Type)
        and then Chars (Parent_Subp) in Name_Initialize
                                      | Name_Adjust
                                      | Name_Finalize
        and then Is_Hidden (Parent_Subp)
        and then not Is_Visibly_Controlled (Parent_Type)
      then
         Set_Is_Hidden (New_Subp);
      end if;

      Set_Is_Imported (New_Subp, Is_Imported (Parent_Subp));
      Set_Is_Exported (New_Subp, Is_Exported (Parent_Subp));

      if Ekind (Parent_Subp) = E_Procedure then
         Set_Is_Valued_Procedure
           (New_Subp, Is_Valued_Procedure (Parent_Subp));
      else
         Set_Has_Controlling_Result
           (New_Subp, Has_Controlling_Result (Parent_Subp));
      end if;

      --  No_Return must be inherited properly. If this is overridden in the
      --  case of a dispatching operation, then the check is made later in
      --  Check_Abstract_Overriding that the overriding operation is also
      --  No_Return (no such check is required for the nondispatching case).

      Set_No_Return (New_Subp, No_Return (Parent_Subp));

      --  If the parent subprogram is marked as Ghost, then so is the derived
      --  subprogram. The ghost policy for the derived subprogram is set from
      --  the effective ghost policy at the point of derived type declaration.

      if Is_Ghost_Entity (Parent_Subp) then
         Set_Is_Ghost_Entity (New_Subp);
      end if;

      --  A derived function with a controlling result is abstract. If the
      --  Derived_Type is a nonabstract formal generic derived type, then
      --  inherited operations are not abstract: the required check is done at
      --  instantiation time. If the derivation is for a generic actual, the
      --  function is not abstract unless the actual is.

      if Is_Generic_Type (Derived_Type)
        and then not Is_Abstract_Type (Derived_Type)
      then
         null;

      --  Ada 2005 (AI-228): Calculate the "require overriding" and "abstract"
      --  properties of the subprogram, as defined in RM-3.9.3(4/2-6/2). Note
      --  that functions with controlling access results of record extensions
      --  with a null extension part require overriding (AI95-00391/06).

      --  Ada 2022 (AI12-0042): Similarly, set those properties for
      --  implementing the rule of RM 7.3.2(6.1/4).

      --  A subprogram subject to pragma Extensions_Visible with value False
      --  requires overriding if the subprogram has at least one controlling
      --  OUT parameter (SPARK RM 6.1.7(6)).

      elsif Ada_Version >= Ada_2005
        and then (Is_Abstract_Subprogram (Alias (New_Subp))
                   or else (Is_Tagged_Type (Derived_Type)
                             and then Etype (New_Subp) = Derived_Type
                             and then not Is_Null_Extension (Derived_Type))
                   or else (Is_Tagged_Type (Derived_Type)
                             and then Ekind (Etype (New_Subp)) =
                                                       E_Anonymous_Access_Type
                             and then Designated_Type (Etype (New_Subp)) =
                                                        Derived_Type)
                   or else (Comes_From_Source (Alias (New_Subp))
                             and then Is_EVF_Procedure (Alias (New_Subp)))

                   --  AI12-0042: Set Requires_Overriding when a type extension
                   --  inherits a private operation that is visible at the
                   --  point of extension (Has_Private_Ancestor is False) from
                   --  an ancestor that has Type_Invariant'Class, and when the
                   --  type extension is in a visible part (the latter as
                   --  clarified by AI12-0382).

                   or else
                     (not Has_Private_Ancestor (Derived_Type)
                       and then Has_Invariants (Parent_Type)
                       and then
                         Present (Get_Pragma (Parent_Type, Pragma_Invariant))
                       and then
                         Class_Present
                           (Get_Pragma (Parent_Type, Pragma_Invariant))
                       and then Is_Private_Primitive (Parent_Subp)
                       and then In_Visible_Part (Scope (Derived_Type))))

        and then No (Actual_Subp)
      then
         if not Is_Tagged_Type (Derived_Type)
           or else Is_Abstract_Type (Derived_Type)
           or else Is_Abstract_Subprogram (Alias (New_Subp))
         then
            Set_Is_Abstract_Subprogram (New_Subp);

         --  If the Chars of the new subprogram is different from that of the
         --  parent's one, it means that we entered it with a special name so
         --  it can't be overridden (see above). In that case we had better not
         --  *require* it to be overridden. This is the case where the parent
         --  type inherited the operation privately, so there's no danger of
         --  dangling dispatching.

         elsif Chars (New_Subp) = Chars (Alias (New_Subp)) then
            Set_Requires_Overriding (New_Subp);
         end if;

      elsif Ada_Version < Ada_2005
        and then (Is_Abstract_Subprogram (Alias (New_Subp))
                   or else (Is_Tagged_Type (Derived_Type)
                             and then Etype (New_Subp) = Derived_Type
                             and then No (Actual_Subp)))
      then
         Set_Is_Abstract_Subprogram (New_Subp);

      --  AI05-0097 : an inherited operation that dispatches on result is
      --  abstract if the derived type is abstract, even if the parent type
      --  is concrete and the derived type is a null extension.

      elsif Has_Controlling_Result (Alias (New_Subp))
        and then Is_Abstract_Type (Etype (New_Subp))
      then
         Set_Is_Abstract_Subprogram (New_Subp);

      --  Finally, if the parent type is abstract we must verify that all
      --  inherited operations are either non-abstract or overridden, or that
      --  the derived type itself is abstract (this check is performed at the
      --  end of a package declaration, in Check_Abstract_Overriding). A
      --  private overriding in the parent type will not be visible in the
      --  derivation if we are not in an inner package or in a child unit of
      --  the parent type, in which case the abstractness of the inherited
      --  operation is carried to the new subprogram.

      elsif Is_Abstract_Type (Parent_Type)
        and then not In_Open_Scopes (Scope (Parent_Type))
        and then Is_Private_Overriding
        and then Is_Abstract_Subprogram (Visible_Subp)
      then
         if No (Actual_Subp) then
            Set_Alias (New_Subp, Visible_Subp);
            Set_Is_Abstract_Subprogram (New_Subp, True);

         else
            --  If this is a derivation for an instance of a formal derived
            --  type, abstractness comes from the primitive operation of the
            --  actual, not from the operation inherited from the ancestor.

            Set_Is_Abstract_Subprogram
              (New_Subp, Is_Abstract_Subprogram (Actual_Subp));
         end if;
      end if;

      New_Overloaded_Entity (New_Subp, Derived_Type);

      --  Ada RM 6.1.1 (15): If a subprogram inherits nonconforming class-wide
      --  preconditions and the derived type is abstract, the derived operation
      --  is abstract as well if parent subprogram is not abstract or null.

      if Is_Abstract_Type (Derived_Type)
        and then Has_Non_Trivial_Precondition (Parent_Subp)
        and then Present (Interfaces (Derived_Type))
      then

         --  Add useful attributes of subprogram before the freeze point,
         --  in case freezing is delayed or there are previous errors.

         Set_Is_Dispatching_Operation (New_Subp);

         declare
            Iface_Prim : constant Entity_Id := Covered_Interface_Op (New_Subp);

         begin
            if Present (Iface_Prim)
              and then Has_Non_Trivial_Precondition (Iface_Prim)
            then
               Set_Is_Abstract_Subprogram (New_Subp);
            end if;
         end;
      end if;

      --  Check for case of a derived subprogram for the instantiation of a
      --  formal derived tagged type, if so mark the subprogram as dispatching
      --  and inherit the dispatching attributes of the actual subprogram. The
      --  derived subprogram is effectively renaming of the actual subprogram,
      --  so it needs to have the same attributes as the actual.

      if Present (Actual_Subp)
        and then Is_Dispatching_Operation (Actual_Subp)
      then
         Set_Is_Dispatching_Operation (New_Subp);

         if Present (DTC_Entity (Actual_Subp)) then
            Set_DTC_Entity (New_Subp, DTC_Entity (Actual_Subp));
            Set_DT_Position_Value (New_Subp, DT_Position (Actual_Subp));
         end if;
      end if;

      --  Indicate that a derived subprogram does not require a body and that
      --  it does not require processing of default expressions.

      Set_Has_Completion (New_Subp);
      Set_Default_Expressions_Processed (New_Subp);

      if Ekind (New_Subp) = E_Function then
         Set_Mechanism (New_Subp, Mechanism (Parent_Subp));
      end if;

      --  Ada 2022 (AI12-0279): If a Yield aspect is specified True for a
      --  primitive subprogram S of a type T, then the aspect is inherited
      --  by the corresponding primitive subprogram of each descendant of T.

      if Is_Tagged_Type (Derived_Type)
        and then Is_Dispatching_Operation (New_Subp)
        and then Has_Yield_Aspect (Alias (New_Subp))
      then
         Set_Has_Yield_Aspect (New_Subp, Has_Yield_Aspect (Alias (New_Subp)));
      end if;

      Set_Is_Ada_2022_Only (New_Subp, Is_Ada_2022_Only (Parent_Subp));
   end Derive_Subprogram;

   ------------------------
   -- Derive_Subprograms --
   ------------------------

   procedure Derive_Subprograms
     (Parent_Type    : Entity_Id;
      Derived_Type   : Entity_Id;
      Generic_Actual : Entity_Id := Empty)
   is
      Op_List : constant Elist_Id :=
                  Collect_Primitive_Operations (Parent_Type);

      function Check_Derived_Type return Boolean;
      --  Check that all the entities derived from Parent_Type are found in
      --  the list of primitives of Derived_Type exactly in the same order.

      procedure Derive_Interface_Subprogram
        (New_Subp    : out Entity_Id;
         Subp        : Entity_Id;
         Actual_Subp : Entity_Id);
      --  Derive New_Subp from the ultimate alias of the parent subprogram Subp
      --  (which is an interface primitive). If Generic_Actual is present then
      --  Actual_Subp is the actual subprogram corresponding with the generic
      --  subprogram Subp.

      ------------------------
      -- Check_Derived_Type --
      ------------------------

      function Check_Derived_Type return Boolean is
         E        : Entity_Id;
         Elmt     : Elmt_Id;
         List     : Elist_Id;
         New_Subp : Entity_Id;
         Op_Elmt  : Elmt_Id;
         Subp     : Entity_Id;

      begin
         --  Traverse list of entities in the current scope searching for
         --  an incomplete type whose full-view is derived type.

         E := First_Entity (Scope (Derived_Type));
         while Present (E) and then E /= Derived_Type loop
            if Ekind (E) = E_Incomplete_Type
              and then Present (Full_View (E))
              and then Full_View (E) = Derived_Type
            then
               --  Disable this test if Derived_Type completes an incomplete
               --  type because in such case more primitives can be added
               --  later to the list of primitives of Derived_Type by routine
               --  Process_Incomplete_Dependents

               return True;
            end if;

            Next_Entity (E);
         end loop;

         List := Collect_Primitive_Operations (Derived_Type);
         Elmt := First_Elmt (List);

         Op_Elmt := First_Elmt (Op_List);
         while Present (Op_Elmt) loop
            Subp     := Node (Op_Elmt);
            New_Subp := Node (Elmt);

            --  At this early stage Derived_Type has no entities with attribute
            --  Interface_Alias. In addition, such primitives are always
            --  located at the end of the list of primitives of Parent_Type.
            --  Therefore, if found we can safely stop processing pending
            --  entities.

            exit when Present (Interface_Alias (Subp));

            --  Handle hidden entities

            if not Is_Predefined_Dispatching_Operation (Subp)
              and then Is_Hidden (Subp)
            then
               if Present (New_Subp)
                 and then Primitive_Names_Match (Subp, New_Subp)
               then
                  Next_Elmt (Elmt);
               end if;

            else
               if not Present (New_Subp)
                 or else Ekind (Subp) /= Ekind (New_Subp)
                 or else not Primitive_Names_Match (Subp, New_Subp)
               then
                  return False;
               end if;

               Next_Elmt (Elmt);
            end if;

            Next_Elmt (Op_Elmt);
         end loop;

         return True;
      end Check_Derived_Type;

      ---------------------------------
      -- Derive_Interface_Subprogram --
      ---------------------------------

      procedure Derive_Interface_Subprogram
        (New_Subp    : out Entity_Id;
         Subp        : Entity_Id;
         Actual_Subp : Entity_Id)
      is
         Iface_Subp : constant Entity_Id := Ultimate_Alias (Subp);
         Iface_Type : constant Entity_Id := Find_Dispatching_Type (Iface_Subp);

      begin
         pragma Assert (Is_Interface (Iface_Type));

         Derive_Subprogram
           (New_Subp     => New_Subp,
            Parent_Subp  => Iface_Subp,
            Derived_Type => Derived_Type,
            Parent_Type  => Iface_Type,
            Actual_Subp  => Actual_Subp);

         --  Given that this new interface entity corresponds with a primitive
         --  of the parent that was not overridden we must leave it associated
         --  with its parent primitive to ensure that it will share the same
         --  dispatch table slot when overridden. We must set the Alias to Subp
         --  (instead of Iface_Subp), and we must fix Is_Abstract_Subprogram
         --  (in case we inherited Subp from Iface_Type via a nonabstract
         --  generic formal type).

         if No (Actual_Subp) then
            Set_Alias (New_Subp, Subp);

            declare
               T : Entity_Id := Find_Dispatching_Type (Subp);
            begin
               while Etype (T) /= T loop
                  if Is_Generic_Type (T) and then not Is_Abstract_Type (T) then
                     Set_Is_Abstract_Subprogram (New_Subp, False);
                     exit;
                  end if;

                  T := Etype (T);
               end loop;
            end;

         --  For instantiations this is not needed since the previous call to
         --  Derive_Subprogram leaves the entity well decorated.

         else
            pragma Assert (Alias (New_Subp) = Actual_Subp);
            null;
         end if;
      end Derive_Interface_Subprogram;

      --  Local variables

      Alias_Subp   : Entity_Id;
      Act_List     : Elist_Id;
      Act_Elmt     : Elmt_Id;
      Act_Subp     : Entity_Id := Empty;
      Elmt         : Elmt_Id;
      Need_Search  : Boolean   := False;
      New_Subp     : Entity_Id := Empty;
      Parent_Base  : Entity_Id;
      Subp         : Entity_Id;

   --  Start of processing for Derive_Subprograms

   begin
      if Ekind (Parent_Type) = E_Record_Type_With_Private
        and then Has_Discriminants (Parent_Type)
        and then Present (Full_View (Parent_Type))
      then
         Parent_Base := Full_View (Parent_Type);
      else
         Parent_Base := Parent_Type;
      end if;

      if Present (Generic_Actual) then
         Act_List := Collect_Primitive_Operations (Generic_Actual);
         Act_Elmt := First_Elmt (Act_List);
      else
         Act_List := No_Elist;
         Act_Elmt := No_Elmt;
      end if;

      --  Derive primitives inherited from the parent. Note that if the generic
      --  actual is present, this is not really a type derivation, it is a
      --  completion within an instance.

      --  Case 1: Derived_Type does not implement interfaces

      if not Is_Tagged_Type (Derived_Type)
        or else (not Has_Interfaces (Derived_Type)
                  and then not (Present (Generic_Actual)
                                 and then Has_Interfaces (Generic_Actual)))
      then
         Elmt := First_Elmt (Op_List);
         while Present (Elmt) loop
            Subp := Node (Elmt);

            --  Literals are derived earlier in the process of building the
            --  derived type, and are skipped here.

            if Ekind (Subp) = E_Enumeration_Literal then
               null;

            --  The actual is a direct descendant and the common primitive
            --  operations appear in the same order.

            --  If the generic parent type is present, the derived type is an
            --  instance of a formal derived type, and within the instance its
            --  operations are those of the actual. We derive from the formal
            --  type but make the inherited operations aliases of the
            --  corresponding operations of the actual.

            else
               pragma Assert (No (Node (Act_Elmt))
                 or else (Primitive_Names_Match (Subp, Node (Act_Elmt))
                           and then
                             Type_Conformant
                               (Subp, Node (Act_Elmt),
                                Skip_Controlling_Formals => True)));

               Derive_Subprogram
                 (New_Subp, Subp, Derived_Type, Parent_Base, Node (Act_Elmt));

               if Present (Act_Elmt) then
                  Next_Elmt (Act_Elmt);
               end if;
            end if;

            Next_Elmt (Elmt);
         end loop;

      --  Case 2: Derived_Type implements interfaces

      else
         --  If the parent type has no predefined primitives we remove
         --  predefined primitives from the list of primitives of generic
         --  actual to simplify the complexity of this algorithm.

         if Present (Generic_Actual) then
            declare
               Has_Predefined_Primitives : Boolean := False;

            begin
               --  Check if the parent type has predefined primitives

               Elmt := First_Elmt (Op_List);
               while Present (Elmt) loop
                  Subp := Node (Elmt);

                  if Is_Predefined_Dispatching_Operation (Subp)
                    and then not Comes_From_Source (Ultimate_Alias (Subp))
                  then
                     Has_Predefined_Primitives := True;
                     exit;
                  end if;

                  Next_Elmt (Elmt);
               end loop;

               --  Remove predefined primitives of Generic_Actual. We must use
               --  an auxiliary list because in case of tagged types the value
               --  returned by Collect_Primitive_Operations is the value stored
               --  in its Primitive_Operations attribute (and we don't want to
               --  modify its current contents).

               if not Has_Predefined_Primitives then
                  declare
                     Aux_List : constant Elist_Id := New_Elmt_List;

                  begin
                     Elmt := First_Elmt (Act_List);
                     while Present (Elmt) loop
                        Subp := Node (Elmt);

                        if not Is_Predefined_Dispatching_Operation (Subp)
                          or else Comes_From_Source (Subp)
                        then
                           Append_Elmt (Subp, Aux_List);
                        end if;

                        Next_Elmt (Elmt);
                     end loop;

                     Act_List := Aux_List;
                  end;
               end if;

               Act_Elmt := First_Elmt (Act_List);
               Act_Subp := Node (Act_Elmt);
            end;
         end if;

         --  Stage 1: If the generic actual is not present we derive the
         --  primitives inherited from the parent type. If the generic parent
         --  type is present, the derived type is an instance of a formal
         --  derived type, and within the instance its operations are those of
         --  the actual. We derive from the formal type but make the inherited
         --  operations aliases of the corresponding operations of the actual.

         Elmt := First_Elmt (Op_List);
         while Present (Elmt) loop
            Subp       := Node (Elmt);
            Alias_Subp := Ultimate_Alias (Subp);

            --  Do not derive internal entities of the parent that link
            --  interface primitives with their covering primitive. These
            --  entities will be added to this type when frozen.

            if Present (Interface_Alias (Subp)) then
               goto Continue;
            end if;

            --  If the generic actual is present find the corresponding
            --  operation in the generic actual. If the parent type is a
            --  direct ancestor of the derived type then, even if it is an
            --  interface, the operations are inherited from the primary
            --  dispatch table and are in the proper order. If we detect here
            --  that primitives are not in the same order we traverse the list
            --  of primitive operations of the actual to find the one that
            --  implements the interface primitive.

            if Need_Search
              or else
                (Present (Generic_Actual)
                  and then Present (Act_Subp)
                  and then not
                    (Primitive_Names_Match (Subp, Act_Subp)
                       and then
                     Type_Conformant (Subp, Act_Subp,
                                      Skip_Controlling_Formals => True)))
            then
               pragma Assert (not Is_Ancestor (Parent_Base, Generic_Actual,
                                               Use_Full_View => True));

               --  Remember that we need searching for all pending primitives

               Need_Search := True;

               --  Handle entities associated with interface primitives

               if Present (Alias_Subp)
                 and then Is_Interface (Find_Dispatching_Type (Alias_Subp))
                 and then not Is_Predefined_Dispatching_Operation (Subp)
               then
                  --  Search for the primitive in the homonym chain

                  Act_Subp :=
                    Find_Primitive_Covering_Interface
                      (Tagged_Type => Generic_Actual,
                       Iface_Prim  => Alias_Subp);

                  --  Previous search may not locate primitives covering
                  --  interfaces defined in generics units or instantiations.
                  --  (it fails if the covering primitive has formals whose
                  --  type is also defined in generics or instantiations).
                  --  In such case we search in the list of primitives of the
                  --  generic actual for the internal entity that links the
                  --  interface primitive and the covering primitive.

                  if No (Act_Subp)
                    and then Is_Generic_Type (Parent_Type)
                  then
                     --  This code has been designed to handle only generic
                     --  formals that implement interfaces that are defined
                     --  in a generic unit or instantiation. If this code is
                     --  needed for other cases we must review it because
                     --  (given that it relies on Original_Location to locate
                     --  the primitive of Generic_Actual that covers the
                     --  interface) it could leave linked through attribute
                     --  Alias entities of unrelated instantiations).

                     pragma Assert
                       (Is_Generic_Unit
                          (Scope (Find_Dispatching_Type (Alias_Subp)))
                         or else
                           Instantiation_Depth
                             (Sloc (Find_Dispatching_Type (Alias_Subp))) > 0);

                     declare
                        Iface_Prim_Loc : constant Source_Ptr :=
                                         Original_Location (Sloc (Alias_Subp));

                        Elmt : Elmt_Id;
                        Prim : Entity_Id;

                     begin
                        Elmt :=
                          First_Elmt (Primitive_Operations (Generic_Actual));

                        Search : while Present (Elmt) loop
                           Prim := Node (Elmt);

                           if Present (Interface_Alias (Prim))
                             and then Original_Location
                                        (Sloc (Interface_Alias (Prim))) =
                                                              Iface_Prim_Loc
                           then
                              Act_Subp := Alias (Prim);
                              exit Search;
                           end if;

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

                  pragma Assert (Present (Act_Subp)
                    or else Is_Abstract_Type (Generic_Actual)
                    or else Serious_Errors_Detected > 0);

               --  Handle predefined primitives plus the rest of user-defined
               --  primitives

               else
                  Act_Elmt := First_Elmt (Act_List);
                  while Present (Act_Elmt) loop
                     Act_Subp := Node (Act_Elmt);

                     exit when Primitive_Names_Match (Subp, Act_Subp)
                       and then Type_Conformant
                                  (Subp, Act_Subp,
                                   Skip_Controlling_Formals => True)
                       and then No (Interface_Alias (Act_Subp));

                     Next_Elmt (Act_Elmt);
                  end loop;

                  if No (Act_Elmt) then
                     Act_Subp := Empty;
                  end if;
               end if;
            end if;

            --   Case 1: If the parent is a limited interface then it has the
            --   predefined primitives of synchronized interfaces. However, the
            --   actual type may be a non-limited type and hence it does not
            --   have such primitives.

            if Present (Generic_Actual)
              and then not Present (Act_Subp)
              and then Is_Limited_Interface (Parent_Base)
              and then Is_Predefined_Interface_Primitive (Subp)
            then
               null;

            --  Case 2: Inherit entities associated with interfaces that were
            --  not covered by the parent type. We exclude here null interface
            --  primitives because they do not need special management.

            --  We also exclude interface operations that are renamings. If the
            --  subprogram is an explicit renaming of an interface primitive,
            --  it is a regular primitive operation, and the presence of its
            --  alias is not relevant: it has to be derived like any other
            --  primitive.

            elsif Present (Alias (Subp))
              and then Nkind (Unit_Declaration_Node (Subp)) /=
                                            N_Subprogram_Renaming_Declaration
              and then Is_Interface (Find_Dispatching_Type (Alias_Subp))
              and then not
                (Nkind (Parent (Alias_Subp)) = N_Procedure_Specification
                  and then Null_Present (Parent (Alias_Subp)))
            then
               --  If this is an abstract private type then we transfer the
               --  derivation of the interface primitive from the partial view
               --  to the full view. This is safe because all the interfaces
               --  must be visible in the partial view. Done to avoid adding
               --  a new interface derivation to the private part of the
               --  enclosing package; otherwise this new derivation would be
               --  decorated as hidden when the analysis of the enclosing
               --  package completes.

               if Is_Abstract_Type (Derived_Type)
                 and then In_Private_Part (Current_Scope)
                 and then Has_Private_Declaration (Derived_Type)
               then
                  declare
                     Partial_View : Entity_Id;
                     Elmt         : Elmt_Id;
                     Ent          : Entity_Id;

                  begin
                     Partial_View := First_Entity (Current_Scope);
                     loop
                        exit when No (Partial_View)
                          or else (Has_Private_Declaration (Partial_View)
                                    and then
                                      Full_View (Partial_View) = Derived_Type);

                        Next_Entity (Partial_View);
                     end loop;

                     --  If the partial view was not found then the source code
                     --  has errors and the derivation is not needed.

                     if Present (Partial_View) then
                        Elmt :=
                          First_Elmt (Primitive_Operations (Partial_View));
                        while Present (Elmt) loop
                           Ent := Node (Elmt);

                           if Present (Alias (Ent))
                             and then Ultimate_Alias (Ent) = Alias (Subp)
                           then
                              Append_Elmt
                                (Ent, Primitive_Operations (Derived_Type));
                              exit;
                           end if;

                           Next_Elmt (Elmt);
                        end loop;

                        --  If the interface primitive was not found in the
                        --  partial view then this interface primitive was
                        --  overridden. We add a derivation to activate in
                        --  Derive_Progenitor_Subprograms the machinery to
                        --  search for it.

                        if No (Elmt) then
                           Derive_Interface_Subprogram
                             (New_Subp    => New_Subp,
                              Subp        => Subp,
                              Actual_Subp => Act_Subp);
                        end if;
                     end if;
                  end;
               else
                  Derive_Interface_Subprogram
                    (New_Subp     => New_Subp,
                     Subp         => Subp,
                     Actual_Subp  => Act_Subp);
               end if;

            --  Case 3: Common derivation

            else
               Derive_Subprogram
                 (New_Subp     => New_Subp,
                  Parent_Subp  => Subp,
                  Derived_Type => Derived_Type,
                  Parent_Type  => Parent_Base,
                  Actual_Subp  => Act_Subp);
            end if;

            --  No need to update Act_Elm if we must search for the
            --  corresponding operation in the generic actual

            if not Need_Search
              and then Present (Act_Elmt)
            then
               Next_Elmt (Act_Elmt);
               Act_Subp := Node (Act_Elmt);
            end if;

            <<Continue>>
            Next_Elmt (Elmt);
         end loop;

         --  Inherit additional operations from progenitors. If the derived
         --  type is a generic actual, there are not new primitive operations
         --  for the type because it has those of the actual, and therefore
         --  nothing needs to be done. The renamings generated above are not
         --  primitive operations, and their purpose is simply to make the
         --  proper operations visible within an instantiation.

         if No (Generic_Actual) then
            Derive_Progenitor_Subprograms (Parent_Base, Derived_Type);
         end if;
      end if;

      --  Final check: Direct descendants must have their primitives in the
      --  same order. We exclude from this test untagged types and instances
      --  of formal derived types. We skip this test if we have already
      --  reported serious errors in the sources.

      pragma Assert (not Is_Tagged_Type (Derived_Type)
        or else Present (Generic_Actual)
        or else Serious_Errors_Detected > 0
        or else Check_Derived_Type);
   end Derive_Subprograms;

   --------------------------------
   -- Derived_Standard_Character --
   --------------------------------

   procedure Derived_Standard_Character
     (N            : Node_Id;
      Parent_Type  : Entity_Id;
      Derived_Type : Entity_Id)
   is
      Loc           : constant Source_Ptr := Sloc (N);
      Def           : constant Node_Id    := Type_Definition (N);
      Indic         : constant Node_Id    := Subtype_Indication (Def);
      Parent_Base   : constant Entity_Id  := Base_Type (Parent_Type);
      Implicit_Base : constant Entity_Id  :=
                        Create_Itype
                          (E_Enumeration_Type, N, Derived_Type, 'B');

      Lo : Node_Id;
      Hi : Node_Id;

   begin
      Discard_Node (Process_Subtype (Indic, N));

      Set_Etype     (Implicit_Base, Parent_Base);
      Set_Size_Info (Implicit_Base, Root_Type (Parent_Type));
      Set_RM_Size   (Implicit_Base, RM_Size (Root_Type (Parent_Type)));

      Set_Is_Character_Type  (Implicit_Base, True);
      Set_Has_Delayed_Freeze (Implicit_Base);

      --  The bounds of the implicit base are the bounds of the parent base.
      --  Note that their type is the parent base.

      Lo := New_Copy_Tree (Type_Low_Bound  (Parent_Base));
      Hi := New_Copy_Tree (Type_High_Bound (Parent_Base));

      Set_Scalar_Range (Implicit_Base,
        Make_Range (Loc,
          Low_Bound  => Lo,
          High_Bound => Hi));

      Conditional_Delay (Derived_Type, Parent_Type);

      Mutate_Ekind (Derived_Type, E_Enumeration_Subtype);
      Set_Etype (Derived_Type, Implicit_Base);
      Set_Size_Info         (Derived_Type, Parent_Type);

      if not Known_RM_Size (Derived_Type) then
         Set_RM_Size (Derived_Type, RM_Size (Parent_Type));
      end if;

      Set_Is_Character_Type (Derived_Type, True);

      if Nkind (Indic) /= N_Subtype_Indication then

         --  If no explicit constraint, the bounds are those
         --  of the parent type.

         Lo := New_Copy_Tree (Type_Low_Bound  (Parent_Type));
         Hi := New_Copy_Tree (Type_High_Bound (Parent_Type));
         Set_Scalar_Range (Derived_Type, Make_Range (Loc, Lo, Hi));
      end if;

      Convert_Scalar_Bounds (N, Parent_Type, Derived_Type, Loc);

      --  Because the implicit base is used in the conversion of the bounds, we
      --  have to freeze it now. This is similar to what is done for numeric
      --  types, and it equally suspicious, but otherwise a nonstatic bound
      --  will have a reference to an unfrozen type, which is rejected by Gigi
      --  (???). This requires specific care for definition of stream
      --  attributes. For details, see comments at the end of
      --  Build_Derived_Numeric_Type.

      Freeze_Before (N, Implicit_Base);
   end Derived_Standard_Character;

   ------------------------------
   -- Derived_Type_Declaration --
   ------------------------------

   procedure Derived_Type_Declaration
     (T             : Entity_Id;
      N             : Node_Id;
      Is_Completion : Boolean)
   is
      Parent_Type  : Entity_Id;

      function Comes_From_Generic (Typ : Entity_Id) return Boolean;
      --  Check whether the parent type is a generic formal, or derives
      --  directly or indirectly from one.

      ------------------------
      -- Comes_From_Generic --
      ------------------------

      function Comes_From_Generic (Typ : Entity_Id) return Boolean is
      begin
         if Is_Generic_Type (Typ) then
            return True;

         elsif Is_Generic_Type (Root_Type (Parent_Type)) then
            return True;

         elsif Is_Private_Type (Typ)
           and then Present (Full_View (Typ))
           and then Is_Generic_Type (Root_Type (Full_View (Typ)))
         then
            return True;

         elsif Is_Generic_Actual_Type (Typ) then
            return True;

         else
            return False;
         end if;
      end Comes_From_Generic;

      --  Local variables

      Def          : constant Node_Id := Type_Definition (N);
      Iface_Def    : Node_Id;
      Indic        : constant Node_Id := Subtype_Indication (Def);
      Extension    : constant Node_Id := Record_Extension_Part (Def);
      Parent_Node  : Node_Id;
      Taggd        : Boolean;

   --  Start of processing for Derived_Type_Declaration

   begin
      Parent_Type := Find_Type_Of_Subtype_Indic (Indic);

      if SPARK_Mode = On
        and then Is_Tagged_Type (Parent_Type)
      then
         declare
            Partial_View : constant Entity_Id :=
                             Incomplete_Or_Partial_View (Parent_Type);

         begin
            --  If the partial view was not found then the parent type is not
            --  a private type. Otherwise check if the partial view is a tagged
            --  private type.

            if Present (Partial_View)
              and then Is_Private_Type (Partial_View)
              and then not Is_Tagged_Type (Partial_View)
            then
               Error_Msg_NE
                 ("cannot derive from & declared as untagged private "
                  & "(SPARK RM 3.4(1))", N, Partial_View);
            end if;
         end;
      end if;

      --  Ada 2005 (AI-251): In case of interface derivation check that the
      --  parent is also an interface.

      if Interface_Present (Def) then
         if not Is_Interface (Parent_Type) then
            Diagnose_Interface (Indic, Parent_Type);

         else
            Parent_Node := Parent (Base_Type (Parent_Type));
            Iface_Def   := Type_Definition (Parent_Node);

            --  Ada 2005 (AI-251): Limited interfaces can only inherit from
            --  other limited interfaces.

            if Limited_Present (Def) then
               if Limited_Present (Iface_Def) then
                  null;

               elsif Protected_Present (Iface_Def) then
                  Error_Msg_NE
                    ("descendant of & must be declared as a protected "
                     & "interface", N, Parent_Type);

               elsif Synchronized_Present (Iface_Def) then
                  Error_Msg_NE
                    ("descendant of & must be declared as a synchronized "
                     & "interface", N, Parent_Type);

               elsif Task_Present (Iface_Def) then
                  Error_Msg_NE
                    ("descendant of & must be declared as a task interface",
                       N, Parent_Type);

               else
                  Error_Msg_N
                    ("(Ada 2005) limited interface cannot inherit from "
                     & "non-limited interface", Indic);
               end if;

            --  Ada 2005 (AI-345): Non-limited interfaces can only inherit
            --  from non-limited or limited interfaces.

            elsif not Protected_Present (Def)
              and then not Synchronized_Present (Def)
              and then not Task_Present (Def)
            then
               if Limited_Present (Iface_Def) then
                  null;

               elsif Protected_Present (Iface_Def) then
                  Error_Msg_NE
                    ("descendant of & must be declared as a protected "
                     & "interface", N, Parent_Type);

               elsif Synchronized_Present (Iface_Def) then
                  Error_Msg_NE
                    ("descendant of & must be declared as a synchronized "
                     & "interface", N, Parent_Type);

               elsif Task_Present (Iface_Def) then
                  Error_Msg_NE
                    ("descendant of & must be declared as a task interface",
                       N, Parent_Type);
               else
                  null;
               end if;
            end if;
         end if;
      end if;

      if Is_Tagged_Type (Parent_Type)
        and then Is_Concurrent_Type (Parent_Type)
        and then not Is_Interface (Parent_Type)
      then
         Error_Msg_N
           ("parent type of a record extension cannot be a synchronized "
            & "tagged type (RM 3.9.1 (3/1))", N);
         Set_Etype (T, Any_Type);
         return;
      end if;

      --  Ada 2005 (AI-251): Decorate all the names in the list of ancestor
      --  interfaces

      if Is_Tagged_Type (Parent_Type)
        and then Is_Non_Empty_List (Interface_List (Def))
      then
         declare
            Intf : Node_Id;
            T    : Entity_Id;

         begin
            Intf := First (Interface_List (Def));
            while Present (Intf) loop
               T := Find_Type_Of_Subtype_Indic (Intf);

               if not Is_Interface (T) then
                  Diagnose_Interface (Intf, T);

               --  Check the rules of 3.9.4(12/2) and 7.5(2/2) that disallow
               --  a limited type from having a nonlimited progenitor.

               elsif (Limited_Present (Def)
                       or else (not Is_Interface (Parent_Type)
                                 and then Is_Limited_Type (Parent_Type)))
                 and then not Is_Limited_Interface (T)
               then
                  Error_Msg_NE
                   ("progenitor interface& of limited type must be limited",
                     N, T);
               end if;

               Next (Intf);
            end loop;
         end;

         --  Check consistency of any nonoverridable aspects that are
         --  inherited from multiple sources.

         Check_Inherited_Nonoverridable_Aspects
           (Inheritor      => T,
            Interface_List => Interface_List (Def),
            Parent_Type    => Parent_Type);
      end if;

      if Parent_Type = Any_Type
        or else Etype (Parent_Type) = Any_Type
        or else (Is_Class_Wide_Type (Parent_Type)
                  and then Etype (Parent_Type) = T)
      then
         --  If Parent_Type is undefined or illegal, make new type into a
         --  subtype of Any_Type, and set a few attributes to prevent cascaded
         --  errors. If this is a self-definition, emit error now.

         if T = Parent_Type or else T = Etype (Parent_Type) then
            Error_Msg_N ("type cannot be used in its own definition", Indic);
         end if;

         Mutate_Ekind     (T, Ekind (Parent_Type));
         Set_Etype        (T, Any_Type);
         Set_Scalar_Range (T, Scalar_Range (Any_Type));

         if Is_Tagged_Type (T)
           and then Is_Record_Type (T)
         then
            Set_Direct_Primitive_Operations (T, New_Elmt_List);
         end if;

         return;
      end if;

      --  Ada 2005 (AI-251): The case in which the parent of the full-view is
      --  an interface is special because the list of interfaces in the full
      --  view can be given in any order. For example:

      --     type A is interface;
      --     type B is interface and A;
      --     type D is new B with private;
      --   private
      --     type D is new A and B with null record; -- 1 --

      --  In this case we perform the following transformation of -1-:

      --     type D is new B and A with null record;

      --  If the parent of the full-view covers the parent of the partial-view
      --  we have two possible cases:

      --     1) They have the same parent
      --     2) The parent of the full-view implements some further interfaces

      --  In both cases we do not need to perform the transformation. In the
      --  first case the source program is correct and the transformation is
      --  not needed; in the second case the source program does not fulfill
      --  the no-hidden interfaces rule (AI-396) and the error will be reported
      --  later.

      --  This transformation not only simplifies the rest of the analysis of
      --  this type declaration but also simplifies the correct generation of
      --  the object layout to the expander.

      if In_Private_Part (Current_Scope)
        and then Is_Interface (Parent_Type)
      then
         declare
            Iface               : Node_Id;
            Partial_View        : Entity_Id;
            Partial_View_Parent : Entity_Id;
            New_Iface           : Node_Id;

         begin
            --  Look for the associated private type declaration

            Partial_View := Incomplete_Or_Partial_View (T);

            --  If the partial view was not found then the source code has
            --  errors and the transformation is not needed.

            if Present (Partial_View) then
               Partial_View_Parent := Etype (Partial_View);

               --  If the parent of the full-view covers the parent of the
               --  partial-view we have nothing else to do.

               if Interface_Present_In_Ancestor
                    (Parent_Type, Partial_View_Parent)
               then
                  null;

               --  Traverse the list of interfaces of the full-view to look
               --  for the parent of the partial-view and perform the tree
               --  transformation.

               else
                  Iface := First (Interface_List (Def));
                  while Present (Iface) loop
                     if Etype (Iface) = Etype (Partial_View) then
                        Rewrite (Subtype_Indication (Def),
                          New_Copy (Subtype_Indication
                                     (Parent (Partial_View))));

                        New_Iface :=
                          Make_Identifier (Sloc (N), Chars (Parent_Type));
                        Append (New_Iface, Interface_List (Def));

                        --  Analyze the transformed code

                        Derived_Type_Declaration (T, N, Is_Completion);
                        return;
                     end if;

                     Next (Iface);
                  end loop;
               end if;
            end if;
         end;
      end if;

      --  Only composite types other than array types are allowed to have
      --  discriminants.

      if Present (Discriminant_Specifications (N)) then
         if (Is_Elementary_Type (Parent_Type)
               or else
             Is_Array_Type      (Parent_Type))
           and then not Error_Posted (N)
         then
            Error_Msg_N
              ("elementary or array type cannot have discriminants",
               Defining_Identifier (First (Discriminant_Specifications (N))));

            --  Unset Has_Discriminants flag to prevent cascaded errors, but
            --  only if we are not already processing a malformed syntax tree.

            if Is_Type (T) then
               Set_Has_Discriminants (T, False);
            end if;
         end if;
      end if;

      --  In Ada 83, a derived type defined in a package specification cannot
      --  be used for further derivation until the end of its visible part.
      --  Note that derivation in the private part of the package is allowed.

      if Ada_Version = Ada_83
        and then Is_Derived_Type (Parent_Type)
        and then In_Visible_Part (Scope (Parent_Type))
      then
         if Ada_Version = Ada_83 and then Comes_From_Source (Indic) then
            Error_Msg_N
              ("(Ada 83) premature use of type for derivation", Indic);
         end if;
      end if;

      --  Check for early use of incomplete or private type

      if Ekind (Parent_Type) in E_Void | E_Incomplete_Type then
         Error_Msg_N ("premature derivation of incomplete type", Indic);
         return;

      elsif (Is_Incomplete_Or_Private_Type (Parent_Type)
              and then not Comes_From_Generic (Parent_Type))
        or else Has_Private_Component (Parent_Type)
      then
         --  The ancestor type of a formal type can be incomplete, in which
         --  case only the operations of the partial view are available in the
         --  generic. Subsequent checks may be required when the full view is
         --  analyzed to verify that a derivation from a tagged type has an
         --  extension.

         if Nkind (Original_Node (N)) = N_Formal_Type_Declaration then
            null;

         elsif No (Underlying_Type (Parent_Type))
           or else Has_Private_Component (Parent_Type)
         then
            Error_Msg_N
              ("premature derivation of derived or private type", Indic);

            --  Flag the type itself as being in error, this prevents some
            --  nasty problems with subsequent uses of the malformed type.

            Set_Error_Posted (T);

         --  Check that within the immediate scope of an untagged partial
         --  view it's illegal to derive from the partial view if the
         --  full view is tagged. (7.3(7))

         --  We verify that the Parent_Type is a partial view by checking
         --  that it is not a Full_Type_Declaration (i.e. a private type or
         --  private extension declaration), to distinguish a partial view
         --  from  a derivation from a private type which also appears as
         --  E_Private_Type. If the parent base type is not declared in an
         --  enclosing scope there is no need to check.

         elsif Present (Full_View (Parent_Type))
           and then Nkind (Parent (Parent_Type)) /= N_Full_Type_Declaration
           and then not Is_Tagged_Type (Parent_Type)
           and then Is_Tagged_Type (Full_View (Parent_Type))
           and then In_Open_Scopes (Scope (Base_Type (Parent_Type)))
         then
            Error_Msg_N
              ("premature derivation from type with tagged full view",
                Indic);
         end if;
      end if;

      --  Check that form of derivation is appropriate

      Taggd := Is_Tagged_Type (Parent_Type);

      --  Set the parent type to the class-wide type's specific type in this
      --  case to prevent cascading errors

      if Present (Extension) and then Is_Class_Wide_Type (Parent_Type) then
         Error_Msg_N ("parent type must not be a class-wide type", Indic);
         Set_Etype (T, Etype (Parent_Type));
         return;
      end if;

      if Present (Extension) and then not Taggd then
         Error_Msg_N
           ("type derived from untagged type cannot have extension", Indic);

      elsif No (Extension) and then Taggd then

         --  If this declaration is within a private part (or body) of a
         --  generic instantiation then the derivation is allowed (the parent
         --  type can only appear tagged in this case if it's a generic actual
         --  type, since it would otherwise have been rejected in the analysis
         --  of the generic template).

         if not Is_Generic_Actual_Type (Parent_Type)
           or else In_Visible_Part (Scope (Parent_Type))
         then
            if Is_Class_Wide_Type (Parent_Type) then
               Error_Msg_N
                 ("parent type must not be a class-wide type", Indic);

               --  Use specific type to prevent cascaded errors.

               Parent_Type := Etype (Parent_Type);

            else
               Error_Msg_N
                 ("type derived from tagged type must have extension", Indic);
            end if;
         end if;
      end if;

      --  AI-443: Synchronized formal derived types require a private
      --  extension. There is no point in checking the ancestor type or
      --  the progenitors since the construct is wrong to begin with.

      if Ada_Version >= Ada_2005
        and then Is_Generic_Type (T)
        and then Present (Original_Node (N))
      then
         declare
            Decl : constant Node_Id := Original_Node (N);

         begin
            if Nkind (Decl) = N_Formal_Type_Declaration
              and then Nkind (Formal_Type_Definition (Decl)) =
                                          N_Formal_Derived_Type_Definition
              and then Synchronized_Present (Formal_Type_Definition (Decl))
              and then No (Extension)

               --  Avoid emitting a duplicate error message

              and then not Error_Posted (Indic)
            then
               Error_Msg_N
                 ("synchronized derived type must have extension", N);
            end if;
         end;
      end if;

      if Null_Exclusion_Present (Def)
        and then not Is_Access_Type (Parent_Type)
      then
         Error_Msg_N ("null exclusion can only apply to an access type", N);
      end if;

      Check_Wide_Character_Restriction (Parent_Type, Indic);

      --  Avoid deriving parent primitives of underlying record views

      Build_Derived_Type (N, Parent_Type, T, Is_Completion,
        Derive_Subps => not Is_Underlying_Record_View (T));

      --  AI-419: The parent type of an explicitly limited derived type must
      --  be a limited type or a limited interface.

      if Limited_Present (Def) then
         Set_Is_Limited_Record (T);

         if Is_Interface (T) then
            Set_Is_Limited_Interface (T);
         end if;

         if not Is_Limited_Type (Parent_Type)
           and then
             (not Is_Interface (Parent_Type)
               or else not Is_Limited_Interface (Parent_Type))
         then
            --  AI05-0096: a derivation in the private part of an instance is
            --  legal if the generic formal is untagged limited, and the actual
            --  is non-limited.

            if Is_Generic_Actual_Type (Parent_Type)
              and then In_Private_Part (Current_Scope)
              and then
                not Is_Tagged_Type
                      (Generic_Parent_Type (Parent (Parent_Type)))
            then
               null;

            else
               Error_Msg_NE
                 ("parent type& of limited type must be limited",
                  N, Parent_Type);
            end if;
         end if;
      end if;
   end Derived_Type_Declaration;

   ------------------------
   -- Diagnose_Interface --
   ------------------------

   procedure Diagnose_Interface (N : Node_Id;  E : Entity_Id) is
   begin
      if not Is_Interface (E) and then E /= Any_Type then
         Error_Msg_NE ("(Ada 2005) & must be an interface", N, E);
      end if;
   end Diagnose_Interface;

   ----------------------------------
   -- Enumeration_Type_Declaration --
   ----------------------------------

   procedure Enumeration_Type_Declaration (T : Entity_Id; Def : Node_Id) is
      Ev     : Uint;
      L      : Node_Id;
      R_Node : Node_Id;
      B_Node : Node_Id;

   begin
      --  Create identifier node representing lower bound

      B_Node := New_Node (N_Identifier, Sloc (Def));
      L := First (Literals (Def));
      Set_Chars (B_Node, Chars (L));
      Set_Entity (B_Node,  L);
      Set_Etype (B_Node, T);
      Set_Is_Static_Expression (B_Node, True);

      R_Node := New_Node (N_Range, Sloc (Def));
      Set_Low_Bound  (R_Node, B_Node);

      Mutate_Ekind (T, E_Enumeration_Type);
      Set_First_Literal (T, L);
      Set_Etype (T, T);
      Set_Is_Constrained (T);

      Ev := Uint_0;

      --  Loop through literals of enumeration type setting pos and rep values
      --  except that if the Ekind is already set, then it means the literal
      --  was already constructed (case of a derived type declaration and we
      --  should not disturb the Pos and Rep values.

      while Present (L) loop
         if Ekind (L) /= E_Enumeration_Literal then
            Mutate_Ekind (L, E_Enumeration_Literal);
            Set_Enumeration_Pos (L, Ev);
            Set_Enumeration_Rep (L, Ev);
            Set_Is_Known_Valid  (L, True);
         end if;

         Set_Etype (L, T);
         New_Overloaded_Entity (L);
         Generate_Definition (L);
         Set_Convention (L, Convention_Intrinsic);

         --  Case of character literal

         if Nkind (L) = N_Defining_Character_Literal then
            Set_Is_Character_Type (T, True);

            --  Check violation of No_Wide_Characters

            if Restriction_Check_Required (No_Wide_Characters) then
               Get_Name_String (Chars (L));

               if Name_Len >= 3 and then Name_Buffer (1 .. 2) = "QW" then
                  Check_Restriction (No_Wide_Characters, L);
               end if;
            end if;
         end if;

         Ev := Ev + 1;
         Next (L);
      end loop;

      --  Now create a node representing upper bound

      B_Node := New_Node (N_Identifier, Sloc (Def));
      Set_Chars (B_Node, Chars (Last (Literals (Def))));
      Set_Entity (B_Node,  Last (Literals (Def)));
      Set_Etype (B_Node, T);
      Set_Is_Static_Expression (B_Node, True);

      Set_High_Bound (R_Node, B_Node);

      --  Initialize various fields of the type. Some of this information
      --  may be overwritten later through rep. clauses.

      Set_Scalar_Range    (T, R_Node);
      Set_RM_Size         (T, UI_From_Int (Minimum_Size (T)));
      Set_Enum_Esize      (T);
      Set_Enum_Pos_To_Rep (T, Empty);

      --  Set Discard_Names if configuration pragma set, or if there is
      --  a parameterless pragma in the current declarative region

      if Global_Discard_Names or else Discard_Names (Scope (T)) then
         Set_Discard_Names (T);
      end if;

      --  Process end label if there is one

      if Present (Def) then
         Process_End_Label (Def, 'e', T);
      end if;
   end Enumeration_Type_Declaration;

   ---------------------------------
   -- Expand_To_Stored_Constraint --
   ---------------------------------

   function Expand_To_Stored_Constraint
     (Typ        : Entity_Id;
      Constraint : Elist_Id) return Elist_Id
   is
      Explicitly_Discriminated_Type : Entity_Id;
      Expansion    : Elist_Id;
      Discriminant : Entity_Id;

      function Type_With_Explicit_Discrims (Id : Entity_Id) return Entity_Id;
      --  Find the nearest type that actually specifies discriminants

      ---------------------------------
      -- Type_With_Explicit_Discrims --
      ---------------------------------

      function Type_With_Explicit_Discrims (Id : Entity_Id) return Entity_Id is
         Typ : constant E := Base_Type (Id);

      begin
         if Ekind (Typ) in Incomplete_Or_Private_Kind then
            if Present (Full_View (Typ)) then
               return Type_With_Explicit_Discrims (Full_View (Typ));
            end if;

         else
            if Has_Discriminants (Typ) then
               return Typ;
            end if;
         end if;

         if Etype (Typ) = Typ then
            return Empty;
         elsif Has_Discriminants (Typ) then
            return Typ;
         else
            return Type_With_Explicit_Discrims (Etype (Typ));
         end if;

      end Type_With_Explicit_Discrims;

   --  Start of processing for Expand_To_Stored_Constraint

   begin
      if No (Constraint) or else Is_Empty_Elmt_List (Constraint) then
         return No_Elist;
      end if;

      Explicitly_Discriminated_Type := Type_With_Explicit_Discrims (Typ);

      if No (Explicitly_Discriminated_Type) then
         return No_Elist;
      end if;

      Expansion := New_Elmt_List;

      Discriminant :=
         First_Stored_Discriminant (Explicitly_Discriminated_Type);
      while Present (Discriminant) loop
         Append_Elmt
           (Get_Discriminant_Value
              (Discriminant, Explicitly_Discriminated_Type, Constraint),
            To => Expansion);
         Next_Stored_Discriminant (Discriminant);
      end loop;

      return Expansion;
   end Expand_To_Stored_Constraint;

   ---------------------------
   -- Find_Hidden_Interface --
   ---------------------------

   function Find_Hidden_Interface
     (Src  : Elist_Id;
      Dest : Elist_Id) return Entity_Id
   is
      Iface      : Entity_Id;
      Iface_Elmt : Elmt_Id;

   begin
      if Present (Src) and then Present (Dest) then
         Iface_Elmt := First_Elmt (Src);
         while Present (Iface_Elmt) loop
            Iface := Node (Iface_Elmt);

            if Is_Interface (Iface)
              and then not Contain_Interface (Iface, Dest)
            then
               return Iface;
            end if;

            Next_Elmt (Iface_Elmt);
         end loop;
      end if;

      return Empty;
   end Find_Hidden_Interface;

   --------------------
   -- Find_Type_Name --
   --------------------

   function Find_Type_Name (N : Node_Id) return Entity_Id is
      Id       : constant Entity_Id := Defining_Identifier (N);
      New_Id   : Entity_Id;
      Prev     : Entity_Id;
      Prev_Par : Node_Id;

      procedure Check_Duplicate_Aspects;
      --  Check that aspects specified in a completion have not been specified
      --  already in the partial view.

      procedure Tag_Mismatch;
      --  Diagnose a tagged partial view whose full view is untagged. We post
      --  the message on the full view, with a reference to the previous
      --  partial view. The partial view can be private or incomplete, and
      --  these are handled in a different manner, so we determine the position
      --  of the error message from the respective slocs of both.

      -----------------------------
      -- Check_Duplicate_Aspects --
      -----------------------------

      procedure Check_Duplicate_Aspects is
         function Get_Partial_View_Aspect (Asp : Node_Id) return Node_Id;
         --  Return the corresponding aspect of the partial view which matches
         --  the aspect id of Asp. Return Empty is no such aspect exists.

         -----------------------------
         -- Get_Partial_View_Aspect --
         -----------------------------

         function Get_Partial_View_Aspect (Asp : Node_Id) return Node_Id is
            Asp_Id    : constant Aspect_Id := Get_Aspect_Id (Asp);
            Prev_Asps : constant List_Id   := Aspect_Specifications (Prev_Par);
            Prev_Asp  : Node_Id;

         begin
            if Present (Prev_Asps) then
               Prev_Asp := First (Prev_Asps);
               while Present (Prev_Asp) loop
                  if Get_Aspect_Id (Prev_Asp) = Asp_Id then
                     return Prev_Asp;
                  end if;

                  Next (Prev_Asp);
               end loop;
            end if;

            return Empty;
         end Get_Partial_View_Aspect;

         --  Local variables

         Full_Asps : constant List_Id := Aspect_Specifications (N);
         Full_Asp  : Node_Id;
         Part_Asp  : Node_Id;

      --  Start of processing for Check_Duplicate_Aspects

      begin
         if Present (Full_Asps) then
            Full_Asp := First (Full_Asps);
            while Present (Full_Asp) loop
               Part_Asp := Get_Partial_View_Aspect (Full_Asp);

               --  An aspect and its class-wide counterpart are two distinct
               --  aspects and may apply to both views of an entity.

               if Present (Part_Asp)
                 and then Class_Present (Part_Asp) = Class_Present (Full_Asp)
               then
                  Error_Msg_N
                    ("aspect already specified in private declaration",
                     Full_Asp);

                  Remove (Full_Asp);
                  return;
               end if;

               if Has_Discriminants (Prev)
                 and then not Has_Unknown_Discriminants (Prev)
                 and then Get_Aspect_Id (Full_Asp) =
                            Aspect_Implicit_Dereference
               then
                  Error_Msg_N
                    ("cannot specify aspect if partial view has known "
                     & "discriminants", Full_Asp);
               end if;

               Next (Full_Asp);
            end loop;
         end if;
      end Check_Duplicate_Aspects;

      ------------------
      -- Tag_Mismatch --
      ------------------

      procedure Tag_Mismatch is
      begin
         if Sloc (Prev) < Sloc (Id) then
            if Ada_Version >= Ada_2012
              and then Nkind (N) = N_Private_Type_Declaration
            then
               Error_Msg_NE
                 ("declaration of private } must be a tagged type", Id, Prev);
            else
               Error_Msg_NE
                 ("full declaration of } must be a tagged type", Id, Prev);
            end if;

         else
            if Ada_Version >= Ada_2012
              and then Nkind (N) = N_Private_Type_Declaration
            then
               Error_Msg_NE
                 ("declaration of private } must be a tagged type", Prev, Id);
            else
               Error_Msg_NE
                 ("full declaration of } must be a tagged type", Prev, Id);
            end if;
         end if;
      end Tag_Mismatch;

   --  Start of processing for Find_Type_Name

   begin
      --  Find incomplete declaration, if one was given

      Prev := Current_Entity_In_Scope (Id);

      --  New type declaration

      if No (Prev) then
         Enter_Name (Id);
         return Id;

      --  Previous declaration exists

      else
         Prev_Par := Parent (Prev);

         --  Error if not incomplete/private case except if previous
         --  declaration is implicit, etc. Enter_Name will emit error if
         --  appropriate.

         if not Is_Incomplete_Or_Private_Type (Prev) then
            Enter_Name (Id);
            New_Id := Id;

         --  Check invalid completion of private or incomplete type

         elsif Nkind (N) not in N_Full_Type_Declaration
                              | N_Task_Type_Declaration
                              | N_Protected_Type_Declaration
           and then
             (Ada_Version < Ada_2012
               or else not Is_Incomplete_Type (Prev)
               or else Nkind (N) not in N_Private_Type_Declaration
                                      | N_Private_Extension_Declaration)
         then
            --  Completion must be a full type declarations (RM 7.3(4))

            Error_Msg_Sloc := Sloc (Prev);
            Error_Msg_NE ("invalid completion of }", Id, Prev);

            --  Set scope of Id to avoid cascaded errors. Entity is never
            --  examined again, except when saving globals in generics.

            Set_Scope (Id, Current_Scope);
            New_Id := Id;

            --  If this is a repeated incomplete declaration, no further
            --  checks are possible.

            if Nkind (N) = N_Incomplete_Type_Declaration then
               return Prev;
            end if;

         --  Case of full declaration of incomplete type

         elsif Ekind (Prev) = E_Incomplete_Type
           and then (Ada_Version < Ada_2012
                      or else No (Full_View (Prev))
                      or else not Is_Private_Type (Full_View (Prev)))
         then
            --  Indicate that the incomplete declaration has a matching full
            --  declaration. The defining occurrence of the incomplete
            --  declaration remains the visible one, and the procedure
            --  Get_Full_View dereferences it whenever the type is used.

            if Present (Full_View (Prev)) then
               Error_Msg_NE ("invalid redeclaration of }", Id, Prev);
            end if;

            Set_Full_View (Prev, Id);
            Append_Entity (Id, Current_Scope);
            Set_Is_Public (Id, Is_Public (Prev));
            Set_Is_Internal (Id);
            New_Id := Prev;

            --  If the incomplete view is tagged, a class_wide type has been
            --  created already. Use it for the private type as well, in order
            --  to prevent multiple incompatible class-wide types that may be
            --  created for self-referential anonymous access components.

            if Is_Tagged_Type (Prev)
              and then Present (Class_Wide_Type (Prev))
            then
               Mutate_Ekind (Id, Ekind (Prev));         --  will be reset later
               Set_Class_Wide_Type (Id, Class_Wide_Type (Prev));

               --  Type of the class-wide type is the current Id. Previously
               --  this was not done for private declarations because of order-
               --  of-elaboration issues in the back end, but gigi now handles
               --  this properly.

               Set_Etype (Class_Wide_Type (Id), Id);
            end if;

         --  Case of full declaration of private type

         else
            --  If the private type was a completion of an incomplete type then
            --  update Prev to reference the private type

            if Ada_Version >= Ada_2012
              and then Ekind (Prev) = E_Incomplete_Type
              and then Present (Full_View (Prev))
              and then Is_Private_Type (Full_View (Prev))
            then
               Prev := Full_View (Prev);
               Prev_Par := Parent (Prev);
            end if;

            if Nkind (N) = N_Full_Type_Declaration
              and then Nkind (Type_Definition (N)) in
                         N_Record_Definition | N_Derived_Type_Definition
              and then Interface_Present (Type_Definition (N))
            then
               Error_Msg_N
                 ("completion of private type cannot be an interface", N);
            end if;

            if Nkind (Parent (Prev)) /= N_Private_Extension_Declaration then
               if Etype (Prev) /= Prev then

                  --  Prev is a private subtype or a derived type, and needs
                  --  no completion.

                  Error_Msg_NE ("invalid redeclaration of }", Id, Prev);
                  New_Id := Id;

               elsif Ekind (Prev) = E_Private_Type
                 and then Nkind (N) in N_Task_Type_Declaration
                                     | N_Protected_Type_Declaration
               then
                  Error_Msg_N
                   ("completion of nonlimited type cannot be limited", N);

               elsif Ekind (Prev) = E_Record_Type_With_Private
                 and then Nkind (N) in N_Task_Type_Declaration
                                     | N_Protected_Type_Declaration
               then
                  if not Is_Limited_Record (Prev) then
                     Error_Msg_N
                        ("completion of nonlimited type cannot be limited", N);

                  elsif No (Interface_List (N)) then
                     Error_Msg_N
                        ("completion of tagged private type must be tagged",
                         N);
                  end if;
               end if;

            --  Ada 2005 (AI-251): Private extension declaration of a task
            --  type or a protected type. This case arises when covering
            --  interface types.

            elsif Nkind (N) in N_Task_Type_Declaration
                             | N_Protected_Type_Declaration
            then
               null;

            elsif Nkind (N) /= N_Full_Type_Declaration
              or else Nkind (Type_Definition (N)) /= N_Derived_Type_Definition
            then
               Error_Msg_N
                 ("full view of private extension must be an extension", N);

            elsif not (Abstract_Present (Parent (Prev)))
              and then Abstract_Present (Type_Definition (N))
            then
               Error_Msg_N
                 ("full view of non-abstract extension cannot be abstract", N);
            end if;

            if not In_Private_Part (Current_Scope) then
               Error_Msg_N
                 ("declaration of full view must appear in private part", N);
            end if;

            if Ada_Version >= Ada_2012 then
               Check_Duplicate_Aspects;
            end if;

            Copy_And_Swap (Prev, Id);
            Set_Has_Private_Declaration (Prev);
            Set_Has_Private_Declaration (Id);

            --  AI12-0133: Indicate whether we have a partial view with
            --  unknown discriminants, in which case initialization of objects
            --  of the type do not receive an invariant check.

            Set_Partial_View_Has_Unknown_Discr
              (Prev, Has_Unknown_Discriminants (Id));

            --  Preserve aspect and iterator flags that may have been set on
            --  the partial view.

            Set_Has_Delayed_Aspects (Prev, Has_Delayed_Aspects (Id));
            Set_Has_Implicit_Dereference (Prev, Has_Implicit_Dereference (Id));

            --  If no error, propagate freeze_node from private to full view.
            --  It may have been generated for an early operational item.

            if Present (Freeze_Node (Id))
              and then Serious_Errors_Detected = 0
              and then No (Full_View (Id))
            then
               Set_Freeze_Node (Prev, Freeze_Node (Id));
               Set_Freeze_Node (Id, Empty);
               Set_First_Rep_Item (Prev, First_Rep_Item (Id));
            end if;

            Set_Full_View (Id, Prev);
            New_Id := Prev;
         end if;

         --  Verify that full declaration conforms to partial one

         if Is_Incomplete_Or_Private_Type (Prev)
           and then Present (Discriminant_Specifications (Prev_Par))
         then
            if Present (Discriminant_Specifications (N)) then
               if Ekind (Prev) = E_Incomplete_Type then
                  Check_Discriminant_Conformance (N, Prev, Prev);
               else
                  Check_Discriminant_Conformance (N, Prev, Id);
               end if;

            else
               Error_Msg_N
                 ("missing discriminants in full type declaration", N);

               --  To avoid cascaded errors on subsequent use, share the
               --  discriminants of the partial view.

               Set_Discriminant_Specifications (N,
                 Discriminant_Specifications (Prev_Par));
            end if;
         end if;

         --  A prior untagged partial view can have an associated class-wide
         --  type due to use of the class attribute, and in this case the full
         --  type must also be tagged. This Ada 95 usage is deprecated in favor
         --  of incomplete tagged declarations, but we check for it.

         if Is_Type (Prev)
           and then (Is_Tagged_Type (Prev)
                      or else Present (Class_Wide_Type (Prev)))
         then
            --  Ada 2012 (AI05-0162): A private type may be the completion of
            --  an incomplete type.

            if Ada_Version >= Ada_2012
              and then Is_Incomplete_Type (Prev)
              and then Nkind (N) in N_Private_Type_Declaration
                                  | N_Private_Extension_Declaration
            then
               --  No need to check private extensions since they are tagged

               if Nkind (N) = N_Private_Type_Declaration
                 and then not Tagged_Present (N)
               then
                  Tag_Mismatch;
               end if;

            --  The full declaration is either a tagged type (including
            --  a synchronized type that implements interfaces) or a
            --  type extension, otherwise this is an error.

            elsif Nkind (N) in N_Task_Type_Declaration
                             | N_Protected_Type_Declaration
            then
               if No (Interface_List (N)) and then not Error_Posted (N) then
                  Tag_Mismatch;
               end if;

            elsif Nkind (Type_Definition (N)) = N_Record_Definition then

               --  Indicate that the previous declaration (tagged incomplete
               --  or private declaration) requires the same on the full one.

               if not Tagged_Present (Type_Definition (N)) then
                  Tag_Mismatch;
                  Set_Is_Tagged_Type (Id);
               end if;

            elsif Nkind (Type_Definition (N)) = N_Derived_Type_Definition then
               if No (Record_Extension_Part (Type_Definition (N))) then
                  Error_Msg_NE
                    ("full declaration of } must be a record extension",
                     Prev, Id);

                  --  Set some attributes to produce a usable full view

                  Set_Is_Tagged_Type (Id);
               end if;

            else
               Tag_Mismatch;
            end if;
         end if;

         if Present (Prev)
           and then Nkind (Parent (Prev)) = N_Incomplete_Type_Declaration
           and then Present (Premature_Use (Parent (Prev)))
         then
            Error_Msg_Sloc := Sloc (N);
            Error_Msg_N
              ("\full declaration #", Premature_Use (Parent (Prev)));
         end if;

         return New_Id;
      end if;
   end Find_Type_Name;

   -------------------------
   -- Find_Type_Of_Object --
   -------------------------

   function Find_Type_Of_Object
     (Obj_Def     : Node_Id;
      Related_Nod : Node_Id) return Entity_Id
   is
      Def_Kind : constant Node_Kind := Nkind (Obj_Def);
      P        : Node_Id := Parent (Obj_Def);
      T        : Entity_Id;
      Nam      : Name_Id;

   begin
      --  If the parent is a component_definition node we climb to the
      --  component_declaration node

      if Nkind (P) = N_Component_Definition then
         P := Parent (P);
      end if;

      --  Case of an anonymous array subtype

      if Def_Kind in N_Array_Type_Definition then
         T := Empty;
         Array_Type_Declaration (T, Obj_Def);

      --  Create an explicit subtype whenever possible

      elsif Nkind (P) /= N_Component_Declaration
        and then Def_Kind = N_Subtype_Indication
      then
         --  Base name of subtype on object name, which will be unique in
         --  the current scope.

         --  If this is a duplicate declaration, return base type, to avoid
         --  generating duplicate anonymous types.

         if Error_Posted (P) then
            Analyze (Subtype_Mark (Obj_Def));
            return Entity (Subtype_Mark (Obj_Def));
         end if;

         Nam :=
            New_External_Name
             (Chars (Defining_Identifier (Related_Nod)), 'S', 0, 'T');

         T := Make_Defining_Identifier (Sloc (P), Nam);

         --  If In_Spec_Expression, for example within a pre/postcondition,
         --  provide enough information for use of the subtype without
         --  depending on full analysis and freezing, which will happen when
         --  building the correspondiing subprogram.

         if In_Spec_Expression then
            Analyze (Subtype_Mark (Obj_Def));

            declare
               Base_T : constant Entity_Id := Entity (Subtype_Mark (Obj_Def));
               Decl   : constant Node_Id :=
                 Make_Subtype_Declaration (Sloc (P),
                   Defining_Identifier => T,
                   Subtype_Indication  => Relocate_Node (Obj_Def));
            begin
               Set_Etype  (T, Base_T);
               Mutate_Ekind  (T, Subtype_Kind (Ekind (Base_T)));
               Set_Parent (T, Obj_Def);

               if Ekind (T) = E_Array_Subtype then
                  Set_First_Index (T, First_Index (Base_T));
                  Set_Is_Constrained (T);

               elsif Ekind (T) = E_Record_Subtype then
                  Set_First_Entity (T, First_Entity (Base_T));
                  Set_Has_Discriminants (T, Has_Discriminants (Base_T));
                  Set_Is_Constrained (T);
               end if;

               Insert_Before (Related_Nod, Decl);
            end;

            return T;
         end if;

         --  When generating code, insert subtype declaration ahead of
         --  declaration that generated it.

         Insert_Action (Obj_Def,
           Make_Subtype_Declaration (Sloc (P),
             Defining_Identifier => T,
             Subtype_Indication  => Relocate_Node (Obj_Def)));

         --  This subtype may need freezing, and this will not be done
         --  automatically if the object declaration is not in declarative
         --  part. Since this is an object declaration, the type cannot always
         --  be frozen here. Deferred constants do not freeze their type
         --  (which often enough will be private).

         if Nkind (P) = N_Object_Declaration
           and then Constant_Present (P)
           and then No (Expression (P))
         then
            null;

         --  Here we freeze the base type of object type to catch premature use
         --  of discriminated private type without a full view.

         else
            Insert_Actions (Obj_Def, Freeze_Entity (Base_Type (T), P));
         end if;

      --  Ada 2005 AI-406: the object definition in an object declaration
      --  can be an access definition.

      elsif Def_Kind = N_Access_Definition then
         T := Access_Definition (Related_Nod, Obj_Def);

         Set_Is_Local_Anonymous_Access
           (T, Ada_Version < Ada_2012
                   or else Nkind (P) /= N_Object_Declaration
                   or else Is_Library_Level_Entity (Defining_Identifier (P)));

      --  Otherwise, the object definition is just a subtype_mark

      else
         T := Process_Subtype (Obj_Def, Related_Nod);
      end if;

      return T;
   end Find_Type_Of_Object;

   --------------------------------
   -- Find_Type_Of_Subtype_Indic --
   --------------------------------

   function Find_Type_Of_Subtype_Indic (S : Node_Id) return Entity_Id is
      Typ : Entity_Id;

   begin
      --  Case of subtype mark with a constraint

      if Nkind (S) = N_Subtype_Indication then
         Find_Type (Subtype_Mark (S));
         Typ := Entity (Subtype_Mark (S));

         if not
           Is_Valid_Constraint_Kind (Ekind (Typ), Nkind (Constraint (S)))
         then
            Error_Msg_N
              ("incorrect constraint for this kind of type", Constraint (S));
            Rewrite (S, New_Copy_Tree (Subtype_Mark (S)));
         end if;

      --  Otherwise we have a subtype mark without a constraint

      elsif Error_Posted (S) then
         Rewrite (S, New_Occurrence_Of (Any_Id, Sloc (S)));
         return Any_Type;

      else
         Find_Type (S);
         Typ := Entity (S);
      end if;

      return Typ;
   end Find_Type_Of_Subtype_Indic;

   -------------------------------------
   -- Floating_Point_Type_Declaration --
   -------------------------------------

   procedure Floating_Point_Type_Declaration (T : Entity_Id; Def : Node_Id) is
      Digs          : constant Node_Id := Digits_Expression (Def);
      Max_Digs_Val  : constant Uint := Digits_Value (Standard_Long_Long_Float);
      Digs_Val      : Uint;
      Base_Typ      : Entity_Id;
      Implicit_Base : Entity_Id;

      function Can_Derive_From (E : Entity_Id) return Boolean;
      --  Find if given digits value, and possibly a specified range, allows
      --  derivation from specified type

      procedure Convert_Bound (B : Node_Id);
      --  If specified, the bounds must be static but may be of different
      --  types. They must be converted into machine numbers of the base type,
      --  in accordance with RM 4.9(38).

      function Find_Base_Type return Entity_Id;
      --  Find a predefined base type that Def can derive from, or generate
      --  an error and substitute Long_Long_Float if none exists.

      ---------------------
      -- Can_Derive_From --
      ---------------------

      function Can_Derive_From (E : Entity_Id) return Boolean is
         Spec : constant Entity_Id := Real_Range_Specification (Def);

      begin
         --  Check specified "digits" constraint

         if Digs_Val > Digits_Value (E) then
            return False;
         end if;

         --  Check for matching range, if specified

         if Present (Spec) then
            if Expr_Value_R (Type_Low_Bound (E)) >
               Expr_Value_R (Low_Bound (Spec))
            then
               return False;
            end if;

            if Expr_Value_R (Type_High_Bound (E)) <
               Expr_Value_R (High_Bound (Spec))
            then
               return False;
            end if;
         end if;

         return True;
      end Can_Derive_From;

      -------------------
      -- Convert_Bound --
      --------------------

      procedure Convert_Bound (B : Node_Id) is
      begin
         --  If the bound is not a literal it can only be static if it is
         --  a static constant, possibly of a specified type.

         if Is_Entity_Name (B)
           and then Ekind (Entity (B)) = E_Constant
         then
            Rewrite (B, Constant_Value (Entity (B)));
         end if;

         if Nkind (B) = N_Real_Literal then
            Set_Realval (B, Machine (Base_Typ, Realval (B), Round, B));
            Set_Is_Machine_Number (B);
            Set_Etype (B, Base_Typ);
         end if;
      end Convert_Bound;

      --------------------
      -- Find_Base_Type --
      --------------------

      function Find_Base_Type return Entity_Id is
         Choice : Elmt_Id := First_Elmt (Predefined_Float_Types);

      begin
         --  Iterate over the predefined types in order, returning the first
         --  one that Def can derive from.

         while Present (Choice) loop
            if Can_Derive_From (Node (Choice)) then
               return Node (Choice);
            end if;

            Next_Elmt (Choice);
         end loop;

         --  If we can't derive from any existing type, use Long_Long_Float
         --  and give appropriate message explaining the problem.

         if Digs_Val > Max_Digs_Val then
            --  It might be the case that there is a type with the requested
            --  range, just not the combination of digits and range.

            Error_Msg_N
              ("no predefined type has requested range and precision",
               Real_Range_Specification (Def));

         else
            Error_Msg_N
              ("range too large for any predefined type",
               Real_Range_Specification (Def));
         end if;

         return Standard_Long_Long_Float;
      end Find_Base_Type;

   --  Start of processing for Floating_Point_Type_Declaration

   begin
      Check_Restriction (No_Floating_Point, Def);

      --  Create an implicit base type

      Implicit_Base :=
        Create_Itype (E_Floating_Point_Type, Parent (Def), T, 'B');

      --  Analyze and verify digits value

      Analyze_And_Resolve (Digs, Any_Integer);
      Check_Digits_Expression (Digs);
      Digs_Val := Expr_Value (Digs);

      --  Process possible range spec and find correct type to derive from

      Process_Real_Range_Specification (Def);

      --  Check that requested number of digits is not too high.

      if Digs_Val > Max_Digs_Val then

         --  The check for Max_Base_Digits may be somewhat expensive, as it
         --  requires reading System, so only do it when necessary.

         declare
            Max_Base_Digits : constant Uint :=
                                Expr_Value
                                  (Expression
                                     (Parent (RTE (RE_Max_Base_Digits))));

         begin
            if Digs_Val > Max_Base_Digits then
               Error_Msg_Uint_1 := Max_Base_Digits;
               Error_Msg_N ("digits value out of range, maximum is ^", Digs);

            elsif No (Real_Range_Specification (Def)) then
               Error_Msg_Uint_1 := Max_Digs_Val;
               Error_Msg_N ("types with more than ^ digits need range spec "
                 & "(RM 3.5.7(6))", Digs);
            end if;
         end;
      end if;

      --  Find a suitable type to derive from or complain and use a substitute

      Base_Typ := Find_Base_Type;

      --  If there are bounds given in the declaration use them as the bounds
      --  of the type, otherwise use the bounds of the predefined base type
      --  that was chosen based on the Digits value.

      if Present (Real_Range_Specification (Def)) then
         Set_Scalar_Range (T, Real_Range_Specification (Def));
         Set_Is_Constrained (T);

         Convert_Bound (Type_Low_Bound (T));
         Convert_Bound (Type_High_Bound (T));

      else
         Set_Scalar_Range (T, Scalar_Range (Base_Typ));
      end if;

      --  Complete definition of implicit base and declared first subtype. The
      --  inheritance of the rep item chain ensures that SPARK-related pragmas
      --  are not clobbered when the floating point type acts as a full view of
      --  a private type.

      Set_Etype              (Implicit_Base,                 Base_Typ);
      Set_Scalar_Range       (Implicit_Base, Scalar_Range   (Base_Typ));
      Set_Size_Info          (Implicit_Base,                 Base_Typ);
      Set_RM_Size            (Implicit_Base, RM_Size        (Base_Typ));
      Set_First_Rep_Item     (Implicit_Base, First_Rep_Item (Base_Typ));
      Set_Digits_Value       (Implicit_Base, Digits_Value   (Base_Typ));
      Set_Float_Rep          (Implicit_Base, Float_Rep      (Base_Typ));

      Mutate_Ekind           (T, E_Floating_Point_Subtype);
      Set_Etype              (T,          Implicit_Base);
      Set_Size_Info          (T,          Implicit_Base);
      Set_RM_Size            (T, RM_Size (Implicit_Base));
      Inherit_Rep_Item_Chain (T,          Implicit_Base);

      if Digs_Val >= Uint_1 then
         Set_Digits_Value (T, Digs_Val);
      else
         pragma Assert (Serious_Errors_Detected > 0); null;
      end if;
   end Floating_Point_Type_Declaration;

   ----------------------------
   -- Get_Discriminant_Value --
   ----------------------------

   --  This is the situation:

   --  There is a non-derived type

   --       type T0 (Dx, Dy, Dz...)

   --  There are zero or more levels of derivation, with each derivation
   --  either purely inheriting the discriminants, or defining its own.

   --       type Ti      is new Ti-1
   --  or
   --       type Ti (Dw) is new Ti-1(Dw, 1, X+Y)
   --  or
   --       subtype Ti is ...

   --  The subtype issue is avoided by the use of Original_Record_Component,
   --  and the fact that derived subtypes also derive the constraints.

   --  This chain leads back from

   --       Typ_For_Constraint

   --  Typ_For_Constraint has discriminants, and the value for each
   --  discriminant is given by its corresponding Elmt of Constraints.

   --  Discriminant is some discriminant in this hierarchy

   --  We need to return its value

   --  We do this by recursively searching each level, and looking for
   --  Discriminant. Once we get to the bottom, we start backing up
   --  returning the value for it which may in turn be a discriminant
   --  further up, so on the backup we continue the substitution.

   function Get_Discriminant_Value
     (Discriminant       : Entity_Id;
      Typ_For_Constraint : Entity_Id;
      Constraint         : Elist_Id) return Node_Id
   is
      function Root_Corresponding_Discriminant
        (Discr : Entity_Id) return Entity_Id;
      --  Given a discriminant, traverse the chain of inherited discriminants
      --  and return the topmost discriminant.

      function Search_Derivation_Levels
        (Ti                    : Entity_Id;
         Discrim_Values        : Elist_Id;
         Stored_Discrim_Values : Boolean) return Node_Or_Entity_Id;
      --  This is the routine that performs the recursive search of levels
      --  as described above.

      -------------------------------------
      -- Root_Corresponding_Discriminant --
      -------------------------------------

      function Root_Corresponding_Discriminant
        (Discr : Entity_Id) return Entity_Id
      is
         D : Entity_Id;

      begin
         D := Discr;
         while Present (Corresponding_Discriminant (D)) loop
            D := Corresponding_Discriminant (D);
         end loop;

         return D;
      end Root_Corresponding_Discriminant;

      ------------------------------
      -- Search_Derivation_Levels --
      ------------------------------

      function Search_Derivation_Levels
        (Ti                    : Entity_Id;
         Discrim_Values        : Elist_Id;
         Stored_Discrim_Values : Boolean) return Node_Or_Entity_Id
      is
         Assoc          : Elmt_Id;
         Disc           : Entity_Id;
         Result         : Node_Or_Entity_Id;
         Result_Entity  : Node_Id;

      begin
         --  If inappropriate type, return Error, this happens only in
         --  cascaded error situations, and we want to avoid a blow up.

         if not Is_Composite_Type (Ti) or else Is_Array_Type (Ti) then
            return Error;
         end if;

         --  Look deeper if possible. Use Stored_Constraints only for
         --  untagged types. For tagged types use the given constraint.
         --  This asymmetry needs explanation???

         if not Stored_Discrim_Values
           and then Present (Stored_Constraint (Ti))
           and then not Is_Tagged_Type (Ti)
         then
            Result :=
              Search_Derivation_Levels (Ti, Stored_Constraint (Ti), True);

         else
            declare
               Td : Entity_Id := Etype (Ti);

            begin
               --  If the parent type is private, the full view may include
               --  renamed discriminants, and it is those stored values that
               --  may be needed (the partial view never has more information
               --  than the full view).

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

               if Td = Ti then
                  Result := Discriminant;

               else
                  if Present (Stored_Constraint (Ti)) then
                     Result :=
                        Search_Derivation_Levels
                          (Td, Stored_Constraint (Ti), True);
                  else
                     Result :=
                        Search_Derivation_Levels
                          (Td, Discrim_Values, Stored_Discrim_Values);
                  end if;
               end if;
            end;
         end if;

         --  Extra underlying places to search, if not found above. For
         --  concurrent types, the relevant discriminant appears in the
         --  corresponding record. For a type derived from a private type
         --  without discriminant, the full view inherits the discriminants
         --  of the full view of the parent.

         if Result = Discriminant then
            if Is_Concurrent_Type (Ti)
              and then Present (Corresponding_Record_Type (Ti))
            then
               Result :=
                 Search_Derivation_Levels (
                   Corresponding_Record_Type (Ti),
                   Discrim_Values,
                   Stored_Discrim_Values);

            elsif Is_Private_Type (Ti)
              and then not Has_Discriminants (Ti)
              and then Present (Full_View (Ti))
              and then Etype (Full_View (Ti)) /= Ti
            then
               Result :=
                 Search_Derivation_Levels (
                   Full_View (Ti),
                   Discrim_Values,
                   Stored_Discrim_Values);
            end if;
         end if;

         --  If Result is not a (reference to a) discriminant, return it,
         --  otherwise set Result_Entity to the discriminant.

         if Nkind (Result) = N_Defining_Identifier then
            pragma Assert (Result = Discriminant);
            Result_Entity := Result;

         else
            if not Denotes_Discriminant (Result) then
               return Result;
            end if;

            Result_Entity := Entity (Result);
         end if;

         --  See if this level of derivation actually has discriminants because
         --  tagged derivations can add them, hence the lower levels need not
         --  have any.

         if not Has_Discriminants (Ti) then
            return Result;
         end if;

         --  Scan Ti's discriminants for Result_Entity, and return its
         --  corresponding value, if any.

         Result_Entity := Original_Record_Component (Result_Entity);

         Assoc := First_Elmt (Discrim_Values);

         if Stored_Discrim_Values then
            Disc := First_Stored_Discriminant (Ti);
         else
            Disc := First_Discriminant (Ti);
         end if;

         while Present (Disc) loop

            --  If no further associations return the discriminant, value will
            --  be found on the second pass.

            if No (Assoc) then
               return Result;
            end if;

            if Original_Record_Component (Disc) = Result_Entity then
               return Node (Assoc);
            end if;

            Next_Elmt (Assoc);

            if Stored_Discrim_Values then
               Next_Stored_Discriminant (Disc);
            else
               Next_Discriminant (Disc);
            end if;
         end loop;

         --  Could not find it

         return Result;
      end Search_Derivation_Levels;

      --  Local Variables

      Result : Node_Or_Entity_Id;

   --  Start of processing for Get_Discriminant_Value

   begin
      --  ??? This routine is a gigantic mess and will be deleted. For the
      --  time being just test for the trivial case before calling recurse.

      --  We are now celebrating the 20th anniversary of this comment!

      if Base_Type (Scope (Discriminant)) = Base_Type (Typ_For_Constraint) then
         declare
            D : Entity_Id;
            E : Elmt_Id;

         begin
            D := First_Discriminant (Typ_For_Constraint);
            E := First_Elmt (Constraint);
            while Present (D) loop
               if Chars (D) = Chars (Discriminant) then
                  return Node (E);
               end if;

               Next_Discriminant (D);
               Next_Elmt (E);
            end loop;
         end;
      end if;

      Result := Search_Derivation_Levels
        (Typ_For_Constraint, Constraint, False);

      --  ??? hack to disappear when this routine is gone

      if Nkind (Result) = N_Defining_Identifier then
         declare
            D : Entity_Id;
            E : Elmt_Id;

         begin
            D := First_Discriminant (Typ_For_Constraint);
            E := First_Elmt (Constraint);
            while Present (D) loop
               if Root_Corresponding_Discriminant (D) = Discriminant then
                  return Node (E);
               end if;

               Next_Discriminant (D);
               Next_Elmt (E);
            end loop;
         end;
      end if;

      pragma Assert (Nkind (Result) /= N_Defining_Identifier);
      return Result;
   end Get_Discriminant_Value;

   --------------------------
   -- Has_Range_Constraint --
   --------------------------

   function Has_Range_Constraint (N : Node_Id) return Boolean is
      C : constant Node_Id := Constraint (N);

   begin
      if Nkind (C) = N_Range_Constraint then
         return True;

      elsif Nkind (C) = N_Digits_Constraint then
         return
            Is_Decimal_Fixed_Point_Type (Entity (Subtype_Mark (N)))
              or else Present (Range_Constraint (C));

      elsif Nkind (C) = N_Delta_Constraint then
         return Present (Range_Constraint (C));

      else
         return False;
      end if;
   end Has_Range_Constraint;

   ------------------------
   -- Inherit_Components --
   ------------------------

   function Inherit_Components
     (N             : Node_Id;
      Parent_Base   : Entity_Id;
      Derived_Base  : Entity_Id;
      Is_Tagged     : Boolean;
      Inherit_Discr : Boolean;
      Discs         : Elist_Id) return Elist_Id
   is
      Assoc_List : constant Elist_Id := New_Elmt_List;

      procedure Inherit_Component
        (Old_C          : Entity_Id;
         Plain_Discrim  : Boolean := False;
         Stored_Discrim : Boolean := False);
      --  Inherits component Old_C from Parent_Base to the Derived_Base. If
      --  Plain_Discrim is True, Old_C is a discriminant. If Stored_Discrim is
      --  True, Old_C is a stored discriminant. If they are both false then
      --  Old_C is a regular component.

      -----------------------
      -- Inherit_Component --
      -----------------------

      procedure Inherit_Component
        (Old_C          : Entity_Id;
         Plain_Discrim  : Boolean := False;
         Stored_Discrim : Boolean := False)
      is
         procedure Set_Anonymous_Type (Id : Entity_Id);
         --  Id denotes the entity of an access discriminant or anonymous
         --  access component. Set the type of Id to either the same type of
         --  Old_C or create a new one depending on whether the parent and
         --  the child types are in the same scope.

         ------------------------
         -- Set_Anonymous_Type --
         ------------------------

         procedure Set_Anonymous_Type (Id : Entity_Id) is
            Old_Typ : constant Entity_Id := Etype (Old_C);

         begin
            if Scope (Parent_Base) = Scope (Derived_Base) then
               Set_Etype (Id, Old_Typ);

            --  The parent and the derived type are in two different scopes.
            --  Reuse the type of the original discriminant / component by
            --  copying it in order to preserve all attributes.

            else
               declare
                  Typ : constant Entity_Id := New_Copy (Old_Typ);

               begin
                  Set_Etype (Id, Typ);

                  --  Since we do not generate component declarations for
                  --  inherited components, associate the itype with the
                  --  derived type.

                  Set_Associated_Node_For_Itype (Typ, Parent (Derived_Base));
                  Set_Scope                     (Typ, Derived_Base);
               end;
            end if;
         end Set_Anonymous_Type;

         --  Local variables and constants

         New_C : constant Entity_Id := New_Copy (Old_C);

         Corr_Discrim : Entity_Id;
         Discrim      : Entity_Id;

      --  Start of processing for Inherit_Component

      begin
         pragma Assert (not Is_Tagged or not Stored_Discrim);

         Set_Parent (New_C, Parent (Old_C));

         --  Regular discriminants and components must be inserted in the scope
         --  of the Derived_Base. Do it here.

         if not Stored_Discrim then
            Enter_Name (New_C);
         end if;

         --  For tagged types the Original_Record_Component must point to
         --  whatever this field was pointing to in the parent type. This has
         --  already been achieved by the call to New_Copy above.

         if not Is_Tagged then
            Set_Original_Record_Component (New_C, New_C);
            Set_Corresponding_Record_Component (New_C, Old_C);
         end if;

         --  Set the proper type of an access discriminant

         if Ekind (New_C) = E_Discriminant
           and then Ekind (Etype (New_C)) = E_Anonymous_Access_Type
         then
            Set_Anonymous_Type (New_C);
         end if;

         --  If we have inherited a component then see if its Etype contains
         --  references to Parent_Base discriminants. In this case, replace
         --  these references with the constraints given in Discs. We do not
         --  do this for the partial view of private types because this is
         --  not needed (only the components of the full view will be used
         --  for code generation) and cause problem. We also avoid this
         --  transformation in some error situations.

         if Ekind (New_C) = E_Component then

            --  Set the proper type of an anonymous access component

            if Ekind (Etype (New_C)) = E_Anonymous_Access_Type then
               Set_Anonymous_Type (New_C);

            elsif (Is_Private_Type (Derived_Base)
                    and then not Is_Generic_Type (Derived_Base))
              or else (Is_Empty_Elmt_List (Discs)
                        and then not Expander_Active)
            then
               Set_Etype (New_C, Etype (Old_C));

            else
               --  The current component introduces a circularity of the
               --  following kind:

               --     limited with Pack_2;
               --     package Pack_1 is
               --        type T_1 is tagged record
               --           Comp : access Pack_2.T_2;
               --           ...
               --        end record;
               --     end Pack_1;

               --     with Pack_1;
               --     package Pack_2 is
               --        type T_2 is new Pack_1.T_1 with ...;
               --     end Pack_2;

               Set_Etype
                 (New_C,
                  Constrain_Component_Type
                    (Old_C, Derived_Base, N, Parent_Base, Discs));
            end if;
         end if;

         --  In derived tagged types it is illegal to reference a non
         --  discriminant component in the parent type. To catch this, mark
         --  these components with an Ekind of E_Void. This will be reset in
         --  Record_Type_Definition after processing the record extension of
         --  the derived type.

         --  If the declaration is a private extension, there is no further
         --  record extension to process, and the components retain their
         --  current kind, because they are visible at this point.

         if Is_Tagged and then Ekind (New_C) = E_Component
           and then Nkind (N) /= N_Private_Extension_Declaration
         then
            Mutate_Ekind (New_C, E_Void);
         end if;

         if Plain_Discrim then
            Set_Corresponding_Discriminant (New_C, Old_C);
            Build_Discriminal (New_C);

         --  If we are explicitly inheriting a stored discriminant it will be
         --  completely hidden.

         elsif Stored_Discrim then
            Set_Corresponding_Discriminant (New_C, Empty);
            Set_Discriminal (New_C, Empty);
            Set_Is_Completely_Hidden (New_C);

            --  Set the Original_Record_Component of each discriminant in the
            --  derived base to point to the corresponding stored that we just
            --  created.

            Discrim := First_Discriminant (Derived_Base);
            while Present (Discrim) loop
               Corr_Discrim := Corresponding_Discriminant (Discrim);

               --  Corr_Discrim could be missing in an error situation

               if Present (Corr_Discrim)
                 and then Original_Record_Component (Corr_Discrim) = Old_C
               then
                  Set_Original_Record_Component (Discrim, New_C);
                  Set_Corresponding_Record_Component (Discrim, Empty);
               end if;

               Next_Discriminant (Discrim);
            end loop;

            Append_Entity (New_C, Derived_Base);
         end if;

         if not Is_Tagged then
            Append_Elmt (Old_C, Assoc_List);
            Append_Elmt (New_C, Assoc_List);
         end if;
      end Inherit_Component;

      --  Variables local to Inherit_Component

      Loc : constant Source_Ptr := Sloc (N);

      Parent_Discrim : Entity_Id;
      Stored_Discrim : Entity_Id;
      D              : Entity_Id;
      Component      : Entity_Id;

   --  Start of processing for Inherit_Components

   begin
      if not Is_Tagged then
         Append_Elmt (Parent_Base,  Assoc_List);
         Append_Elmt (Derived_Base, Assoc_List);
      end if;

      --  Inherit parent discriminants if needed

      if Inherit_Discr then
         Parent_Discrim := First_Discriminant (Parent_Base);
         while Present (Parent_Discrim) loop
            Inherit_Component (Parent_Discrim, Plain_Discrim => True);
            Next_Discriminant (Parent_Discrim);
         end loop;
      end if;

      --  Create explicit stored discrims for untagged types when necessary

      if not Has_Unknown_Discriminants (Derived_Base)
        and then Has_Discriminants (Parent_Base)
        and then not Is_Tagged
        and then
          (not Inherit_Discr
            or else First_Discriminant (Parent_Base) /=
                    First_Stored_Discriminant (Parent_Base))
      then
         Stored_Discrim := First_Stored_Discriminant (Parent_Base);
         while Present (Stored_Discrim) loop
            Inherit_Component (Stored_Discrim, Stored_Discrim => True);
            Next_Stored_Discriminant (Stored_Discrim);
         end loop;
      end if;

      --  See if we can apply the second transformation for derived types, as
      --  explained in point 6. in the comments above Build_Derived_Record_Type
      --  This is achieved by appending Derived_Base discriminants into Discs,
      --  which has the side effect of returning a non empty Discs list to the
      --  caller of Inherit_Components, which is what we want. This must be
      --  done for private derived types if there are explicit stored
      --  discriminants, to ensure that we can retrieve the values of the
      --  constraints provided in the ancestors.

      if Inherit_Discr
        and then Is_Empty_Elmt_List (Discs)
        and then Present (First_Discriminant (Derived_Base))
        and then
          (not Is_Private_Type (Derived_Base)
            or else Is_Completely_Hidden
                      (First_Stored_Discriminant (Derived_Base))
            or else Is_Generic_Type (Derived_Base))
      then
         D := First_Discriminant (Derived_Base);
         while Present (D) loop
            Append_Elmt (New_Occurrence_Of (D, Loc), Discs);
            Next_Discriminant (D);
         end loop;
      end if;

      --  Finally, inherit non-discriminant components unless they are not
      --  visible because defined or inherited from the full view of the
      --  parent. Don't inherit the _parent field of the parent type.

      Component := First_Entity (Parent_Base);
      while Present (Component) loop

         --  Ada 2005 (AI-251): Do not inherit components associated with
         --  secondary tags of the parent.

         if Ekind (Component) = E_Component
           and then Present (Related_Type (Component))
         then
            null;

         elsif Ekind (Component) /= E_Component
           or else Chars (Component) = Name_uParent
         then
            null;

         --  If the derived type is within the parent type's declarative
         --  region, then the components can still be inherited even though
         --  they aren't visible at this point. This can occur for cases
         --  such as within public child units where the components must
         --  become visible upon entering the child unit's private part.

         elsif not Is_Visible_Component (Component)
           and then not In_Open_Scopes (Scope (Parent_Base))
         then
            null;

         elsif Ekind (Derived_Base) in E_Private_Type | E_Limited_Private_Type
         then
            null;

         else
            Inherit_Component (Component);
         end if;

         Next_Entity (Component);
      end loop;

      --  For tagged derived types, inherited discriminants cannot be used in
      --  component declarations of the record extension part. To achieve this
      --  we mark the inherited discriminants as not visible.

      if Is_Tagged and then Inherit_Discr then
         D := First_Discriminant (Derived_Base);
         while Present (D) loop
            Set_Is_Immediately_Visible (D, False);
            Next_Discriminant (D);
         end loop;
      end if;

      return Assoc_List;
   end Inherit_Components;

   ----------------------
   -- Is_EVF_Procedure --
   ----------------------

   function Is_EVF_Procedure (Subp : Entity_Id) return Boolean is
      Formal : Entity_Id;

   begin
      --  Examine the formals of an Extensions_Visible False procedure looking
      --  for a controlling OUT parameter.

      if Ekind (Subp) = E_Procedure
        and then Extensions_Visible_Status (Subp) = Extensions_Visible_False
      then
         Formal := First_Formal (Subp);
         while Present (Formal) loop
            if Ekind (Formal) = E_Out_Parameter
              and then Is_Controlling_Formal (Formal)
            then
               return True;
            end if;

            Next_Formal (Formal);
         end loop;
      end if;

      return False;
   end Is_EVF_Procedure;

   --------------------------
   -- Is_Private_Primitive --
   --------------------------

   function Is_Private_Primitive (Prim : Entity_Id) return Boolean is
      Prim_Scope  : constant Entity_Id := Scope (Prim);
      Priv_Entity : Entity_Id;
   begin
      if Is_Package_Or_Generic_Package (Prim_Scope) then
         Priv_Entity := First_Private_Entity (Prim_Scope);

         while Present (Priv_Entity) loop
            if Priv_Entity = Prim then
               return True;
            end if;

            Next_Entity (Priv_Entity);
         end loop;
      end if;

      return False;
   end Is_Private_Primitive;

   ------------------------------
   -- Is_Valid_Constraint_Kind --
   ------------------------------

   function Is_Valid_Constraint_Kind
     (T_Kind          : Type_Kind;
      Constraint_Kind : Node_Kind) return Boolean
   is
   begin
      case T_Kind is
         when Enumeration_Kind
            | Integer_Kind
         =>
            return Constraint_Kind = N_Range_Constraint;

         when Decimal_Fixed_Point_Kind =>
            return Constraint_Kind in N_Digits_Constraint | N_Range_Constraint;

         when Ordinary_Fixed_Point_Kind =>
            return Constraint_Kind in N_Delta_Constraint | N_Range_Constraint;

         when Float_Kind =>
            return Constraint_Kind in N_Digits_Constraint | N_Range_Constraint;

         when Access_Kind
            | Array_Kind
            | Class_Wide_Kind
            | Concurrent_Kind
            | Private_Kind
            | E_Incomplete_Type
            | E_Record_Subtype
            | E_Record_Type
         =>
            return Constraint_Kind = N_Index_Or_Discriminant_Constraint;

         when others =>
            return True; -- Error will be detected later
      end case;
   end Is_Valid_Constraint_Kind;

   --------------------------
   -- Is_Visible_Component --
   --------------------------

   function Is_Visible_Component
     (C : Entity_Id;
      N : Node_Id := Empty) return Boolean
   is
      Original_Comp : Entity_Id := Empty;
      Original_Type : Entity_Id;
      Type_Scope    : Entity_Id;

      function Is_Local_Type (Typ : Entity_Id) return Boolean;
      --  Check whether parent type of inherited component is declared locally,
      --  possibly within a nested package or instance. The current scope is
      --  the derived record itself.

      -------------------
      -- Is_Local_Type --
      -------------------

      function Is_Local_Type (Typ : Entity_Id) return Boolean is
      begin
         return Scope_Within (Inner => Typ, Outer => Scope (Current_Scope));
      end Is_Local_Type;

   --  Start of processing for Is_Visible_Component

   begin
      if Ekind (C) in E_Component | E_Discriminant then
         Original_Comp := Original_Record_Component (C);
      end if;

      if No (Original_Comp) then

         --  Premature usage, or previous error

         return False;

      else
         Original_Type := Scope (Original_Comp);
         Type_Scope    := Scope (Base_Type (Scope (C)));
      end if;

      --  This test only concerns tagged types

      if not Is_Tagged_Type (Original_Type) then

         --  Check if this is a renamed discriminant (hidden either by the
         --  derived type or by some ancestor), unless we are analyzing code
         --  generated by the expander since it may reference such components
         --  (for example see the expansion of Deep_Adjust).

         if Ekind (C) = E_Discriminant and then Present (N) then
            return
              not Comes_From_Source (N)
                or else not Is_Completely_Hidden (C);
         else
            return True;
         end if;

      --  If it is _Parent or _Tag, there is no visibility issue

      elsif not Comes_From_Source (Original_Comp) then
         return True;

      --  Discriminants are visible unless the (private) type has unknown
      --  discriminants. If the discriminant reference is inserted for a
      --  discriminant check on a full view it is also visible.

      elsif Ekind (Original_Comp) = E_Discriminant
        and then
          (not Has_Unknown_Discriminants (Original_Type)
            or else (Present (N)
                      and then Nkind (N) = N_Selected_Component
                      and then Nkind (Prefix (N)) = N_Type_Conversion
                      and then not Comes_From_Source (Prefix (N))))
      then
         return True;

      --  If the component has been declared in an ancestor which is currently
      --  a private type, then it is not visible. The same applies if the
      --  component's containing type is not in an open scope and the original
      --  component's enclosing type is a visible full view of a private type
      --  (which can occur in cases where an attempt is being made to reference
      --  a component in a sibling package that is inherited from a visible
      --  component of a type in an ancestor package; the component in the
      --  sibling package should not be visible even though the component it
      --  inherited from is visible), but instance bodies are not subject to
      --  this second case since they have the Has_Private_View mechanism to
      --  ensure proper visibility. This does not apply however in the case
      --  where the scope of the type is a private child unit, or when the
      --  parent comes from a local package in which the ancestor is currently
      --  visible. The latter suppression of visibility is needed for cases
      --  that are tested in B730006.

      elsif Is_Private_Type (Original_Type)
        or else
          (not Is_Private_Descendant (Type_Scope)
            and then not In_Open_Scopes (Type_Scope)
            and then Has_Private_Declaration (Original_Type)
            and then not In_Instance_Body)
      then
         --  If the type derives from an entity in a formal package, there
         --  are no additional visible components.

         if Nkind (Original_Node (Unit_Declaration_Node (Type_Scope))) =
            N_Formal_Package_Declaration
         then
            return False;

         --  if we are not in the private part of the current package, there
         --  are no additional visible components.

         elsif Ekind (Scope (Current_Scope)) = E_Package
           and then not In_Private_Part (Scope (Current_Scope))
         then
            return False;
         else
            return
              Is_Child_Unit (Cunit_Entity (Current_Sem_Unit))
                and then In_Open_Scopes (Scope (Original_Type))
                and then Is_Local_Type (Type_Scope);
         end if;

      --  There is another weird way in which a component may be invisible when
      --  the private and the full view are not derived from the same ancestor.
      --  Here is an example :

      --       type A1 is tagged      record F1 : integer; end record;
      --       type A2 is new A1 with record F2 : integer; end record;
      --       type T is new A1 with private;
      --     private
      --       type T is new A2 with null record;

      --  In this case, the full view of T inherits F1 and F2 but the private
      --  view inherits only F1

      else
         declare
            Ancestor : Entity_Id := Scope (C);

         begin
            loop
               if Ancestor = Original_Type then
                  return True;

               --  The ancestor may have a partial view of the original type,
               --  but if the full view is in scope, as in a child body, the
               --  component is visible.

               elsif In_Private_Part (Scope (Original_Type))
                 and then Full_View (Ancestor) = Original_Type
               then
                  return True;

               elsif Ancestor = Etype (Ancestor) then

                  --  No further ancestors to examine

                  return False;
               end if;

               Ancestor := Etype (Ancestor);
            end loop;
         end;
      end if;
   end Is_Visible_Component;

   --------------------------
   -- Make_Class_Wide_Type --
   --------------------------

   procedure Make_Class_Wide_Type (T : Entity_Id) is
      CW_Type : Entity_Id;
      CW_Name : Name_Id;
      Next_E  : Entity_Id;
      Prev_E  : Entity_Id;

   begin
      if Present (Class_Wide_Type (T)) then

         --  The class-wide type is a partially decorated entity created for a
         --  unanalyzed tagged type referenced through a limited with clause.
         --  When the tagged type is analyzed, its class-wide type needs to be
         --  redecorated. Note that we reuse the entity created by Decorate_
         --  Tagged_Type in order to preserve all links.

         if Materialize_Entity (Class_Wide_Type (T)) then
            CW_Type := Class_Wide_Type (T);
            Set_Materialize_Entity (CW_Type, False);

         --  The class wide type can have been defined by the partial view, in
         --  which case everything is already done.

         else
            return;
         end if;

      --  Default case, we need to create a new class-wide type

      else
         CW_Type :=
           New_External_Entity (E_Void, Scope (T), Sloc (T), T, 'C', 0, 'T');
      end if;

      --  Inherit root type characteristics

      CW_Name := Chars (CW_Type);
      Next_E  := Next_Entity (CW_Type);
      Prev_E  := Prev_Entity (CW_Type);
      Copy_Node (T, CW_Type);
      Set_Comes_From_Source (CW_Type, False);
      Set_Chars (CW_Type, CW_Name);
      Set_Parent (CW_Type, Parent (T));
      Set_Prev_Entity (CW_Type, Prev_E);
      Set_Next_Entity (CW_Type, Next_E);

      --  Ensure we have a new freeze node for the class-wide type. The partial
      --  view may have freeze action of its own, requiring a proper freeze
      --  node, and the same freeze node cannot be shared between the two
      --  types.

      Set_Has_Delayed_Freeze (CW_Type);
      Set_Freeze_Node (CW_Type, Empty);

      --  Customize the class-wide type: It has no prim. op., it cannot be
      --  abstract, its Etype points back to the specific root type, and it
      --  cannot have any invariants.

      if Ekind (CW_Type) in Incomplete_Or_Private_Kind then
         Reinit_Field_To_Zero (CW_Type, F_Private_Dependents);

      elsif Ekind (CW_Type) in Concurrent_Kind then
         Reinit_Field_To_Zero (CW_Type, F_First_Private_Entity);
         Reinit_Field_To_Zero (CW_Type, F_Scope_Depth_Value);

         if Ekind (CW_Type) in Task_Kind then
            Reinit_Field_To_Zero (CW_Type, F_Is_Elaboration_Checks_OK_Id);
            Reinit_Field_To_Zero (CW_Type, F_Is_Elaboration_Warnings_OK_Id);
         end if;

         if Ekind (CW_Type) in E_Task_Type | E_Protected_Type then
            Reinit_Field_To_Zero (CW_Type, F_SPARK_Aux_Pragma_Inherited);
         end if;
      end if;

      Mutate_Ekind                    (CW_Type, E_Class_Wide_Type);
      Set_Is_Tagged_Type              (CW_Type, True);
      Set_Direct_Primitive_Operations (CW_Type, New_Elmt_List);
      Set_Is_Abstract_Type            (CW_Type, False);
      Set_Is_Constrained              (CW_Type, False);
      Set_Is_First_Subtype            (CW_Type, Is_First_Subtype (T));
      Set_Default_SSO                 (CW_Type);
      Set_Has_Inheritable_Invariants  (CW_Type, False);
      Set_Has_Inherited_Invariants    (CW_Type, False);
      Set_Has_Own_Invariants          (CW_Type, False);

      if Ekind (T) = E_Class_Wide_Subtype then
         Set_Etype (CW_Type, Etype (Base_Type (T)));
      else
         Set_Etype (CW_Type, T);
      end if;

      Set_No_Tagged_Streams_Pragma (CW_Type, No_Tagged_Streams);

      --  If this is the class_wide type of a constrained subtype, it does
      --  not have discriminants.

      Set_Has_Discriminants (CW_Type,
        Has_Discriminants (T) and then not Is_Constrained (T));

      Set_Has_Unknown_Discriminants (CW_Type, True);
      Set_Class_Wide_Type (T, CW_Type);
      Set_Equivalent_Type (CW_Type, Empty);

      --  The class-wide type of a class-wide type is itself (RM 3.9(14))

      Set_Class_Wide_Type (CW_Type, CW_Type);
   end Make_Class_Wide_Type;

   ----------------
   -- Make_Index --
   ----------------

   procedure Make_Index
     (N            : Node_Id;
      Related_Nod  : Node_Id;
      Related_Id   : Entity_Id := Empty;
      Suffix_Index : Pos       := 1)
   is
      R      : Node_Id;
      T      : Entity_Id;
      Def_Id : Entity_Id := Empty;
      Found  : Boolean := False;

   begin
      --  For a discrete range used in a constrained array definition and
      --  defined by a range, an implicit conversion to the predefined type
      --  INTEGER is assumed if each bound is either a numeric literal, a named
      --  number, or an attribute, and the type of both bounds (prior to the
      --  implicit conversion) is the type universal_integer. Otherwise, both
      --  bounds must be of the same discrete type, other than universal
      --  integer; this type must be determinable independently of the
      --  context, but using the fact that the type must be discrete and that
      --  both bounds must have the same type.

      --  Character literals also have a universal type in the absence of
      --  of additional context,  and are resolved to Standard_Character.

      if Nkind (N) = N_Range then

         --  The index is given by a range constraint. The bounds are known
         --  to be of a consistent type.

         if not Is_Overloaded (N) then
            T := Etype (N);

            --  For universal bounds, choose the specific predefined type

            if T = Universal_Integer then
               T := Standard_Integer;

            elsif T = Any_Character then
               Ambiguous_Character (Low_Bound (N));

               T := Standard_Character;
            end if;

         --  The node may be overloaded because some user-defined operators
         --  are available, but if a universal interpretation exists it is
         --  also the selected one.

         elsif Universal_Interpretation (N) = Universal_Integer then
            T := Standard_Integer;

         else
            T := Any_Type;

            declare
               Ind : Interp_Index;
               It  : Interp;

            begin
               Get_First_Interp (N, Ind, It);
               while Present (It.Typ) loop
                  if Is_Discrete_Type (It.Typ) then

                     if Found
                       and then not Covers (It.Typ, T)
                       and then not Covers (T, It.Typ)
                     then
                        Error_Msg_N ("ambiguous bounds in discrete range", N);
                        exit;
                     else
                        T := It.Typ;
                        Found := True;
                     end if;
                  end if;

                  Get_Next_Interp (Ind, It);
               end loop;

               if T = Any_Type then
                  Error_Msg_N ("discrete type required for range", N);
                  Set_Etype (N, Any_Type);
                  return;

               elsif T = Universal_Integer then
                  T := Standard_Integer;
               end if;
            end;
         end if;

         if not Is_Discrete_Type (T) then
            Error_Msg_N ("discrete type required for range", N);
            Set_Etype (N, Any_Type);
            return;
         end if;

         --  If the range bounds are "T'First .. T'Last" where T is a name of a
         --  discrete type, then use T as the type of the index.

         if Nkind (Low_Bound (N)) = N_Attribute_Reference
           and then Attribute_Name (Low_Bound (N)) = Name_First
           and then Is_Entity_Name (Prefix (Low_Bound (N)))
           and then Is_Discrete_Type (Entity (Prefix (Low_Bound (N))))

           and then Nkind (High_Bound (N)) = N_Attribute_Reference
           and then Attribute_Name (High_Bound (N)) = Name_Last
           and then Is_Entity_Name (Prefix (High_Bound (N)))
           and then Entity (Prefix (High_Bound (N))) = Def_Id
         then
            Def_Id := Entity (Prefix (Low_Bound (N)));
         end if;

         R := N;
         Process_Range_Expr_In_Decl (R, T);

      elsif Nkind (N) = N_Subtype_Indication then

         --  The index is given by a subtype with a range constraint

         T := Base_Type (Entity (Subtype_Mark (N)));

         if not Is_Discrete_Type (T) then
            Error_Msg_N ("discrete type required for range", N);
            Set_Etype (N, Any_Type);
            return;
         end if;

         R := Range_Expression (Constraint (N));

         Resolve (R, T);
         Process_Range_Expr_In_Decl (R, Entity (Subtype_Mark (N)));

      elsif Nkind (N) = N_Attribute_Reference then

         --  Catch beginner's error (use of attribute other than 'Range)

         if Attribute_Name (N) /= Name_Range then
            Error_Msg_N ("expect attribute ''Range", N);
            Set_Etype (N, Any_Type);
            return;
         end if;

         --  If the node denotes the range of a type mark, that is also the
         --  resulting type, and we do not need to create an Itype for it.

         if Is_Entity_Name (Prefix (N))
           and then Comes_From_Source (N)
           and then Is_Discrete_Type (Entity (Prefix (N)))
         then
            Def_Id := Entity (Prefix (N));
         end if;

         Analyze_And_Resolve (N);
         T := Etype (N);
         R := N;

      --  If none of the above, must be a subtype. We convert this to a
      --  range attribute reference because in the case of declared first
      --  named subtypes, the types in the range reference can be different
      --  from the type of the entity. A range attribute normalizes the
      --  reference and obtains the correct types for the bounds.

      --  This transformation is in the nature of an expansion, is only
      --  done if expansion is active. In particular, it is not done on
      --  formal generic types,  because we need to retain the name of the
      --  original index for instantiation purposes.

      else
         if not Is_Entity_Name (N) or else not Is_Type (Entity (N)) then
            Error_Msg_N ("invalid subtype mark in discrete range", N);
            Set_Etype (N, Any_Integer);
            return;

         else
            --  The type mark may be that of an incomplete type. It is only
            --  now that we can get the full view, previous analysis does
            --  not look specifically for a type mark.

            Set_Entity (N, Get_Full_View (Entity (N)));
            Set_Etype  (N, Entity (N));
            Def_Id := Entity (N);

            if not Is_Discrete_Type (Def_Id) then
               Error_Msg_N ("discrete type required for index", N);
               Set_Etype (N, Any_Type);
               return;
            end if;
         end if;

         if Expander_Active then
            Rewrite (N,
              Make_Attribute_Reference (Sloc (N),
                Attribute_Name => Name_Range,
                Prefix         => Relocate_Node (N)));

            --  The original was a subtype mark that does not freeze. This
            --  means that the rewritten version must not freeze either.

            Set_Must_Not_Freeze (N);
            Set_Must_Not_Freeze (Prefix (N));
            Analyze_And_Resolve (N);
            T := Etype (N);
            R := N;

         --  If expander is inactive, type is legal, nothing else to construct

         else
            return;
         end if;
      end if;

      if not Is_Discrete_Type (T) then
         Error_Msg_N ("discrete type required for range", N);
         Set_Etype (N, Any_Type);
         return;

      elsif T = Any_Type then
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  We will now create the appropriate Itype to describe the range, but
      --  first a check. If we originally had a subtype, then we just label
      --  the range with this subtype. Not only is there no need to construct
      --  a new subtype, but it is wrong to do so for two reasons:

      --    1. A legality concern, if we have a subtype, it must not freeze,
      --       and the Itype would cause freezing incorrectly

      --    2. An efficiency concern, if we created an Itype, it would not be
      --       recognized as the same type for the purposes of eliminating
      --       checks in some circumstances.

      --  We signal this case by setting the subtype entity in Def_Id

      if No (Def_Id) then
         Def_Id :=
           Create_Itype (E_Void, Related_Nod, Related_Id, 'D', Suffix_Index);
         Set_Etype (Def_Id, Base_Type (T));

         if Is_Signed_Integer_Type (T) then
            Mutate_Ekind (Def_Id, E_Signed_Integer_Subtype);

         elsif Is_Modular_Integer_Type (T) then
            Mutate_Ekind (Def_Id, E_Modular_Integer_Subtype);

         else
            Mutate_Ekind          (Def_Id, E_Enumeration_Subtype);
            Set_Is_Character_Type (Def_Id, Is_Character_Type (T));
            Set_First_Literal     (Def_Id, First_Literal (T));
         end if;

         Set_Size_Info      (Def_Id,                (T));
         Set_RM_Size        (Def_Id, RM_Size        (T));
         Set_First_Rep_Item (Def_Id, First_Rep_Item (T));

         Set_Scalar_Range   (Def_Id, R);
         Conditional_Delay  (Def_Id, T);

         --  In the subtype indication case inherit properties of the parent

         if Nkind (N) = N_Subtype_Indication then

            --  It is enough to inherit predicate flags and not the predicate
            --  functions, because predicates on an index type are illegal
            --  anyway and the flags are enough to detect them.

            Inherit_Predicate_Flags (Def_Id, Entity (Subtype_Mark (N)));

            --  If the immediate parent of the new subtype is nonstatic, then
            --  the subtype we create is nonstatic as well, even if its bounds
            --  are static.

            if not Is_OK_Static_Subtype (Entity (Subtype_Mark (N))) then
               Set_Is_Non_Static_Subtype (Def_Id);
            end if;
         end if;

         Set_Parent (Def_Id, N);
      end if;

      --  Final step is to label the index with this constructed type

      Set_Etype (N, Def_Id);
   end Make_Index;

   ------------------------------
   -- Modular_Type_Declaration --
   ------------------------------

   procedure Modular_Type_Declaration (T : Entity_Id; Def : Node_Id) is
      Mod_Expr : constant Node_Id := Expression (Def);
      M_Val    : Uint;

      procedure Set_Modular_Size (Bits : Int);
      --  Sets RM_Size to Bits, and Esize to normal word size above this

      ----------------------
      -- Set_Modular_Size --
      ----------------------

      procedure Set_Modular_Size (Bits : Int) is
         Siz : Int;

      begin
         Set_RM_Size (T, UI_From_Int (Bits));

         if Bits < System_Max_Binary_Modulus_Power then
            Siz := 8;

            while Siz < 128 loop
               exit when Bits <= Siz;
               Siz := Siz * 2;
            end loop;

            Set_Esize (T, UI_From_Int (Siz));

         else
            Set_Esize (T, UI_From_Int (System_Max_Binary_Modulus_Power));
         end if;

         if not Non_Binary_Modulus (T) and then Esize (T) = RM_Size (T) then
            Set_Is_Known_Valid (T);
         end if;
      end Set_Modular_Size;

   --  Start of processing for Modular_Type_Declaration

   begin
      --  If the mod expression is (exactly) 2 * literal, where literal is
      --  128 or less, then almost certainly the * was meant to be **. Warn.

      if Warn_On_Suspicious_Modulus_Value
        and then Nkind (Mod_Expr) = N_Op_Multiply
        and then Nkind (Left_Opnd (Mod_Expr)) = N_Integer_Literal
        and then Intval (Left_Opnd (Mod_Expr)) = Uint_2
        and then Nkind (Right_Opnd (Mod_Expr)) = N_Integer_Literal
        and then Intval (Right_Opnd (Mod_Expr)) <= Uint_128
      then
         Error_Msg_N
           ("suspicious MOD value, was '*'* intended'??.m?", Mod_Expr);
      end if;

      --  Proceed with analysis of mod expression

      Analyze_And_Resolve (Mod_Expr, Any_Integer);

      if Ekind (T) in Incomplete_Or_Private_Kind then
         Reinit_Field_To_Zero (T, F_Stored_Constraint);
      end if;

      Set_Etype (T, T);
      Mutate_Ekind (T, E_Modular_Integer_Type);
      Reinit_Alignment (T);
      Set_Is_Constrained (T);

      if not Is_OK_Static_Expression (Mod_Expr) then
         Flag_Non_Static_Expr
           ("non-static expression used for modular type bound!", Mod_Expr);
         M_Val := 2 ** System_Max_Binary_Modulus_Power;
      else
         M_Val := Expr_Value (Mod_Expr);
      end if;

      if M_Val < 1 then
         Error_Msg_N ("modulus value must be positive", Mod_Expr);
         M_Val := 2 ** System_Max_Binary_Modulus_Power;
      end if;

      if M_Val > 2 ** Standard_Long_Integer_Size then
         Check_Restriction (No_Long_Long_Integers, Mod_Expr);
      end if;

      Set_Modulus (T, M_Val);

      --   Create bounds for the modular type based on the modulus given in
      --   the type declaration and then analyze and resolve those bounds.

      Set_Scalar_Range (T,
        Make_Range (Sloc (Mod_Expr),
          Low_Bound  => Make_Integer_Literal (Sloc (Mod_Expr), 0),
          High_Bound => Make_Integer_Literal (Sloc (Mod_Expr), M_Val - 1)));

      --  Properly analyze the literals for the range. We do this manually
      --  because we can't go calling Resolve, since we are resolving these
      --  bounds with the type, and this type is certainly not complete yet.

      Set_Etype (Low_Bound  (Scalar_Range (T)), T);
      Set_Etype (High_Bound (Scalar_Range (T)), T);
      Set_Is_Static_Expression (Low_Bound  (Scalar_Range (T)));
      Set_Is_Static_Expression (High_Bound (Scalar_Range (T)));

      --  Loop through powers of two to find number of bits required

      for Bits in Int range 0 .. System_Max_Binary_Modulus_Power loop

         --  Binary case

         if M_Val = 2 ** Bits then
            Set_Modular_Size (Bits);
            return;

         --  Nonbinary case

         elsif M_Val < 2 ** Bits then
            Set_Non_Binary_Modulus (T);

            if Bits > System_Max_Nonbinary_Modulus_Power then
               Error_Msg_Uint_1 :=
                 UI_From_Int (System_Max_Nonbinary_Modulus_Power);
               Error_Msg_F
                 ("nonbinary modulus exceeds limit (2 '*'*^ - 1)", Mod_Expr);
               Set_Modular_Size (System_Max_Binary_Modulus_Power);
               return;

            else
               --  In the nonbinary case, set size as per RM 13.3(55)

               Set_Modular_Size (Bits);
               return;
            end if;
         end if;

      end loop;

      --  If we fall through, then the size exceed System.Max_Binary_Modulus
      --  so we just signal an error and set the maximum size.

      Error_Msg_Uint_1 := UI_From_Int (System_Max_Binary_Modulus_Power);
      Error_Msg_F ("modulus exceeds limit (2 '*'*^)", Mod_Expr);

      Set_Modular_Size (System_Max_Binary_Modulus_Power);
      Reinit_Alignment (T);

   end Modular_Type_Declaration;

   --------------------------
   -- New_Concatenation_Op --
   --------------------------

   procedure New_Concatenation_Op (Typ : Entity_Id) is
      Loc : constant Source_Ptr := Sloc (Typ);
      Op  : Entity_Id;

      function Make_Op_Formal (Typ, Op : Entity_Id) return Entity_Id;
      --  Create abbreviated declaration for the formal of a predefined
      --  Operator 'Op' of type 'Typ'

      --------------------
      -- Make_Op_Formal --
      --------------------

      function Make_Op_Formal (Typ, Op : Entity_Id) return Entity_Id is
         Formal : Entity_Id;
      begin
         Formal := New_Internal_Entity (E_In_Parameter, Op, Loc, 'P');
         Set_Etype (Formal, Typ);
         Set_Mechanism (Formal, Default_Mechanism);
         return Formal;
      end Make_Op_Formal;

   --  Start of processing for New_Concatenation_Op

   begin
      Op := Make_Defining_Operator_Symbol (Loc, Name_Op_Concat);

      Mutate_Ekind                (Op, E_Operator);
      Set_Scope                   (Op, Current_Scope);
      Set_Etype                   (Op, Typ);
      Set_Homonym                 (Op, Get_Name_Entity_Id (Name_Op_Concat));
      Set_Is_Immediately_Visible  (Op);
      Set_Is_Intrinsic_Subprogram (Op);
      Set_Has_Completion          (Op);
      Append_Entity               (Op, Current_Scope);

      Set_Name_Entity_Id (Name_Op_Concat, Op);

      Append_Entity (Make_Op_Formal (Typ, Op), Op);
      Append_Entity (Make_Op_Formal (Typ, Op), Op);
   end New_Concatenation_Op;

   -------------------------
   -- OK_For_Limited_Init --
   -------------------------

   --  ???Check all calls of this, and compare the conditions under which it's
   --  called.

   function OK_For_Limited_Init
     (Typ : Entity_Id;
      Exp : Node_Id) return Boolean
   is
   begin
      return Is_CPP_Constructor_Call (Exp)
        or else (Ada_Version >= Ada_2005
                  and then not Debug_Flag_Dot_L
                  and then OK_For_Limited_Init_In_05 (Typ, Exp));
   end OK_For_Limited_Init;

   -------------------------------
   -- OK_For_Limited_Init_In_05 --
   -------------------------------

   function OK_For_Limited_Init_In_05
     (Typ : Entity_Id;
      Exp : Node_Id) return Boolean
   is
   begin
      --  An object of a limited interface type can be initialized with any
      --  expression of a nonlimited descendant type. However this does not
      --  apply if this is a view conversion of some other expression. This
      --  is checked below.

      if Is_Class_Wide_Type (Typ)
        and then Is_Limited_Interface (Typ)
        and then not Is_Limited_Type (Etype (Exp))
        and then Nkind (Exp) /= N_Type_Conversion
      then
         return True;
      end if;

      --  Ada 2005 (AI-287, AI-318): Relax the strictness of the front end in
      --  case of limited aggregates (including extension aggregates), and
      --  function calls. The function call may have been given in prefixed
      --  notation, in which case the original node is an indexed component.
      --  If the function is parameterless, the original node was an explicit
      --  dereference. The function may also be parameterless, in which case
      --  the source node is just an identifier.

      --  A branch of a conditional expression may have been removed if the
      --  condition is statically known. This happens during expansion, and
      --  thus will not happen if previous errors were encountered. The check
      --  will have been performed on the chosen branch, which replaces the
      --  original conditional expression.

      if No (Exp) then
         return True;
      end if;

      case Nkind (Original_Node (Exp)) is
         when N_Aggregate
            | N_Extension_Aggregate
            | N_Function_Call
            | N_Op
         =>
            return True;

         when N_Identifier =>
            return Present (Entity (Original_Node (Exp)))
              and then Ekind (Entity (Original_Node (Exp))) = E_Function;

         when N_Qualified_Expression =>
            return
              OK_For_Limited_Init_In_05
                (Typ, Expression (Original_Node (Exp)));

         --  Ada 2005 (AI-251): If a class-wide interface object is initialized
         --  with a function call, the expander has rewritten the call into an
         --  N_Type_Conversion node to force displacement of the pointer to
         --  reference the component containing the secondary dispatch table.
         --  Otherwise a type conversion is not a legal context.
         --  A return statement for a build-in-place function returning a
         --  synchronized type also introduces an unchecked conversion.

         when N_Type_Conversion
            | N_Unchecked_Type_Conversion
         =>
            return not Comes_From_Source (Exp)
              and then
                --  If the conversion has been rewritten, check Original_Node

                ((Original_Node (Exp) /= Exp
                   and then
                     OK_For_Limited_Init_In_05 (Typ, Original_Node (Exp)))

                  --  Otherwise, check the expression of the compiler-generated
                  --  conversion (which is a conversion that we want to ignore
                  --  for purposes of the limited-initialization restrictions).

                  or else
                    (Original_Node (Exp) = Exp
                      and then
                        OK_For_Limited_Init_In_05 (Typ, Expression (Exp))));

         when N_Explicit_Dereference
            | N_Indexed_Component
            | N_Selected_Component
         =>
            return Nkind (Exp) = N_Function_Call;

         --  A use of 'Input is a function call, hence allowed. Normally the
         --  attribute will be changed to a call, but the attribute by itself
         --  can occur with -gnatc.

         when N_Attribute_Reference =>
            return Attribute_Name (Original_Node (Exp)) = Name_Input;

         --  "return raise ..." is OK

         when N_Raise_Expression =>
            return True;

         --  For a case expression, all dependent expressions must be legal

         when N_Case_Expression =>
            declare
               Alt : Node_Id;

            begin
               Alt := First (Alternatives (Original_Node (Exp)));
               while Present (Alt) loop
                  if not OK_For_Limited_Init_In_05 (Typ, Expression (Alt)) then
                     return False;
                  end if;

                  Next (Alt);
               end loop;

               return True;
            end;

         --  For an if expression, all dependent expressions must be legal

         when N_If_Expression =>
            declare
               Then_Expr : constant Node_Id :=
                             Next (First (Expressions (Original_Node (Exp))));
               Else_Expr : constant Node_Id := Next (Then_Expr);
            begin
               return OK_For_Limited_Init_In_05 (Typ, Then_Expr)
                        and then
                      OK_For_Limited_Init_In_05 (Typ, Else_Expr);
            end;

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

   -------------------------------------------
   -- Ordinary_Fixed_Point_Type_Declaration --
   -------------------------------------------

   procedure Ordinary_Fixed_Point_Type_Declaration
     (T   : Entity_Id;
      Def : Node_Id)
   is
      Loc           : constant Source_Ptr := Sloc (Def);
      Delta_Expr    : constant Node_Id    := Delta_Expression (Def);
      RRS           : constant Node_Id    := Real_Range_Specification (Def);
      Implicit_Base : Entity_Id;
      Delta_Val     : Ureal;
      Small_Val     : Ureal;
      Low_Val       : Ureal;
      High_Val      : Ureal;

   begin
      Check_Restriction (No_Fixed_Point, Def);

      --  Create implicit base type

      Implicit_Base :=
        Create_Itype (E_Ordinary_Fixed_Point_Type, Parent (Def), T, 'B');
      Set_Etype (Implicit_Base, Implicit_Base);

      --  Analyze and process delta expression

      Analyze_And_Resolve (Delta_Expr, Any_Real);

      Check_Delta_Expression (Delta_Expr);
      Delta_Val := Expr_Value_R (Delta_Expr);

      Set_Delta_Value (Implicit_Base, Delta_Val);

      --  Compute default small from given delta, which is the largest power
      --  of two that does not exceed the given delta value.

      declare
         Tmp   : Ureal;
         Scale : Int;

      begin
         Tmp := Ureal_1;
         Scale := 0;

         if Delta_Val < Ureal_1 then
            while Delta_Val < Tmp loop
               Tmp := Tmp / Ureal_2;
               Scale := Scale + 1;
            end loop;

         else
            loop
               Tmp := Tmp * Ureal_2;
               exit when Tmp > Delta_Val;
               Scale := Scale - 1;
            end loop;
         end if;

         Small_Val := UR_From_Components (Uint_1, UI_From_Int (Scale), 2);
      end;

      Set_Small_Value (Implicit_Base, Small_Val);

      --  If no range was given, set a dummy range

      if RRS <= Empty_Or_Error then
         Low_Val  := -Small_Val;
         High_Val := Small_Val;

      --  Otherwise analyze and process given range

      else
         declare
            Low  : constant Node_Id := Low_Bound  (RRS);
            High : constant Node_Id := High_Bound (RRS);

         begin
            Analyze_And_Resolve (Low, Any_Real);
            Analyze_And_Resolve (High, Any_Real);
            Check_Real_Bound (Low);
            Check_Real_Bound (High);

            --  Obtain and set the range

            Low_Val  := Expr_Value_R (Low);
            High_Val := Expr_Value_R (High);

            if Low_Val > High_Val then
               Error_Msg_NE ("??fixed point type& has null range", Def, T);
            end if;
         end;
      end if;

      --  The range for both the implicit base and the declared first subtype
      --  cannot be set yet, so we use the special routine Set_Fixed_Range to
      --  set a temporary range in place. Note that the bounds of the base
      --  type will be widened to be symmetrical and to fill the available
      --  bits when the type is frozen.

      --  We could do this with all discrete types, and probably should, but
      --  we absolutely have to do it for fixed-point, since the end-points
      --  of the range and the size are determined by the small value, which
      --  could be reset before the freeze point.

      Set_Fixed_Range (Implicit_Base, Loc, Low_Val, High_Val);
      Set_Fixed_Range (T, Loc, Low_Val, High_Val);

      --  Complete definition of first subtype. The inheritance of the rep item
      --  chain ensures that SPARK-related pragmas are not clobbered when the
      --  ordinary fixed point type acts as a full view of a private type.

      Mutate_Ekind           (T, E_Ordinary_Fixed_Point_Subtype);
      Set_Etype              (T, Implicit_Base);
      Reinit_Size_Align      (T);
      Inherit_Rep_Item_Chain (T, Implicit_Base);
      Set_Small_Value        (T, Small_Val);
      Set_Delta_Value        (T, Delta_Val);
      Set_Is_Constrained     (T);
   end Ordinary_Fixed_Point_Type_Declaration;

   ----------------------------------
   -- Preanalyze_Assert_Expression --
   ----------------------------------

   procedure Preanalyze_Assert_Expression (N : Node_Id; T : Entity_Id) is
   begin
      In_Assertion_Expr := In_Assertion_Expr + 1;
      Preanalyze_Spec_Expression (N, T);
      In_Assertion_Expr := In_Assertion_Expr - 1;
   end Preanalyze_Assert_Expression;

   -----------------------------------
   -- Preanalyze_Default_Expression --
   -----------------------------------

   procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id) is
      Save_In_Default_Expr    : constant Boolean := In_Default_Expr;
      Save_In_Spec_Expression : constant Boolean := In_Spec_Expression;

   begin
      In_Default_Expr    := True;
      In_Spec_Expression := True;

      Preanalyze_With_Freezing_And_Resolve (N, T);

      In_Default_Expr    := Save_In_Default_Expr;
      In_Spec_Expression := Save_In_Spec_Expression;
   end Preanalyze_Default_Expression;

   --------------------------------
   -- Preanalyze_Spec_Expression --
   --------------------------------

   procedure Preanalyze_Spec_Expression (N : Node_Id; T : Entity_Id) is
      Save_In_Spec_Expression : constant Boolean := In_Spec_Expression;
   begin
      In_Spec_Expression := True;
      Preanalyze_And_Resolve (N, T);
      In_Spec_Expression := Save_In_Spec_Expression;
   end Preanalyze_Spec_Expression;

   ----------------------------------------
   -- Prepare_Private_Subtype_Completion --
   ----------------------------------------

   procedure Prepare_Private_Subtype_Completion
     (Id          : Entity_Id;
      Related_Nod : Node_Id)
   is
      Id_B   : constant Entity_Id := Base_Type (Id);
      Full_B : constant Entity_Id := Full_View (Id_B);
      Full   : Entity_Id;

   begin
      if Present (Full_B) then

         --  The Base_Type is already completed, we can complete the subtype
         --  now. We have to create a new entity with the same name, Thus we
         --  can't use Create_Itype.

         Full := Make_Defining_Identifier (Sloc (Id), Chars (Id));
         Set_Is_Itype (Full);
         Set_Associated_Node_For_Itype (Full, Related_Nod);
         Complete_Private_Subtype (Id, Full, Full_B, Related_Nod);
         Set_Full_View (Id, Full);
      end if;

      --  The parent subtype may be private, but the base might not, in some
      --  nested instances. In that case, the subtype does not need to be
      --  exchanged. It would still be nice to make private subtypes and their
      --  bases consistent at all times ???

      if Is_Private_Type (Id_B) then
         Append_Elmt (Id, Private_Dependents (Id_B));
      end if;
   end Prepare_Private_Subtype_Completion;

   ---------------------------
   -- Process_Discriminants --
   ---------------------------

   procedure Process_Discriminants
     (N    : Node_Id;
      Prev : Entity_Id := Empty)
   is
      Elist               : constant Elist_Id := New_Elmt_List;
      Id                  : Node_Id;
      Discr               : Node_Id;
      Discr_Number        : Uint;
      Discr_Type          : Entity_Id;
      Default_Present     : Boolean := False;
      Default_Not_Present : Boolean := False;

   begin
      --  A composite type other than an array type can have discriminants.
      --  On entry, the current scope is the composite type.

      --  The discriminants are initially entered into the scope of the type
      --  via Enter_Name with the default Ekind of E_Void to prevent premature
      --  use, as explained at the end of this procedure.

      Discr := First (Discriminant_Specifications (N));
      while Present (Discr) loop
         Enter_Name (Defining_Identifier (Discr));

         --  For navigation purposes we add a reference to the discriminant
         --  in the entity for the type. If the current declaration is a
         --  completion, place references on the partial view. Otherwise the
         --  type is the current scope.

         if Present (Prev) then

            --  The references go on the partial view, if present. If the
            --  partial view has discriminants, the references have been
            --  generated already.

            if not Has_Discriminants (Prev) then
               Generate_Reference (Prev, Defining_Identifier (Discr), 'd');
            end if;
         else
            Generate_Reference
              (Current_Scope, Defining_Identifier (Discr), 'd');
         end if;

         if Nkind (Discriminant_Type (Discr)) = N_Access_Definition then
            Check_Anonymous_Access_Component
              (Typ_Decl   => N,
               Typ        => Defining_Identifier (N),
               Prev       => Prev,
               Comp_Def   => Discr,
               Access_Def => Discriminant_Type (Discr));

            --  if Check_Anonymous_Access_Component replaced Discr then
            --  its Original_Node points to the old Discr and the access type
            --  for Discr_Type has already been created.

            if Original_Node (Discr) /= Discr then
               Discr_Type := Etype (Discriminant_Type (Discr));
            else
               Discr_Type :=
                 Access_Definition (Discr, Discriminant_Type (Discr));

               --  Ada 2005 (AI-254)

               if Present (Access_To_Subprogram_Definition
                            (Discriminant_Type (Discr)))
                 and then Protected_Present (Access_To_Subprogram_Definition
                                              (Discriminant_Type (Discr)))
               then
                  Discr_Type :=
                    Replace_Anonymous_Access_To_Protected_Subprogram (Discr);
               end if;
            end if;
         else
            Find_Type (Discriminant_Type (Discr));
            Discr_Type := Etype (Discriminant_Type (Discr));

            if Error_Posted (Discriminant_Type (Discr)) then
               Discr_Type := Any_Type;
            end if;
         end if;

         --  Handling of discriminants that are access types

         if Is_Access_Type (Discr_Type) then

            --  Ada 2005 (AI-230): Access discriminant allowed in non-
            --  limited record types

            if Ada_Version < Ada_2005 then
               Check_Access_Discriminant_Requires_Limited
                 (Discr, Discriminant_Type (Discr));
            end if;

            if Ada_Version = Ada_83 and then Comes_From_Source (Discr) then
               Error_Msg_N
                 ("(Ada 83) access discriminant not allowed", Discr);
            end if;

         --  If not access type, must be a discrete type

         elsif not Is_Discrete_Type (Discr_Type) then
            Error_Msg_N
              ("discriminants must have a discrete or access type",
               Discriminant_Type (Discr));
         end if;

         Set_Etype (Defining_Identifier (Discr), Discr_Type);

         --  If a discriminant specification includes the assignment compound
         --  delimiter followed by an expression, the expression is the default
         --  expression of the discriminant; the default expression must be of
         --  the type of the discriminant. (RM 3.7.1) Since this expression is
         --  a default expression, we do the special preanalysis, since this
         --  expression does not freeze (see section "Handling of Default and
         --  Per-Object Expressions" in spec of package Sem).

         if Present (Expression (Discr)) then
            Preanalyze_Default_Expression (Expression (Discr), Discr_Type);

            --  Legaity checks

            if Nkind (N) = N_Formal_Type_Declaration then
               Error_Msg_N
                 ("discriminant defaults not allowed for formal type",
                  Expression (Discr));

            --  Flag an error for a tagged type with defaulted discriminants,
            --  excluding limited tagged types when compiling for Ada 2012
            --  (see AI05-0214).

            elsif Is_Tagged_Type (Current_Scope)
              and then (not Is_Limited_Type (Current_Scope)
                         or else Ada_Version < Ada_2012)
              and then Comes_From_Source (N)
            then
               --  Note: see similar test in Check_Or_Process_Discriminants, to
               --  handle the (illegal) case of the completion of an untagged
               --  view with discriminants with defaults by a tagged full view.
               --  We skip the check if Discr does not come from source, to
               --  account for the case of an untagged derived type providing
               --  defaults for a renamed discriminant from a private untagged
               --  ancestor with a tagged full view (ACATS B460006).

               if Ada_Version >= Ada_2012 then
                  Error_Msg_N
                    ("discriminants of nonlimited tagged type cannot have"
                       & " defaults",
                     Expression (Discr));
               else
                  Error_Msg_N
                    ("discriminants of tagged type cannot have defaults",
                     Expression (Discr));
               end if;

            else
               Default_Present := True;
               Append_Elmt (Expression (Discr), Elist);

               --  Tag the defining identifiers for the discriminants with
               --  their corresponding default expressions from the tree.

               Set_Discriminant_Default_Value
                 (Defining_Identifier (Discr), Expression (Discr));
            end if;

            --  In gnatc or GNATprove mode, make sure set Do_Range_Check flag
            --  gets set unless we can be sure that no range check is required.

            if not Expander_Active
              and then not
                Is_In_Range
                  (Expression (Discr), Discr_Type, Assume_Valid => True)
            then
               Set_Do_Range_Check (Expression (Discr));
            end if;

         --  No default discriminant value given

         else
            Default_Not_Present := True;
         end if;

         --  Ada 2005 (AI-231): Create an Itype that is a duplicate of
         --  Discr_Type but with the null-exclusion attribute

         if Ada_Version >= Ada_2005 then

            --  Ada 2005 (AI-231): Static checks

            if Can_Never_Be_Null (Discr_Type) then
               Null_Exclusion_Static_Checks (Discr);

            elsif Is_Access_Type (Discr_Type)
              and then Null_Exclusion_Present (Discr)

               --  No need to check itypes because in their case this check
               --  was done at their point of creation

              and then not Is_Itype (Discr_Type)
            then
               if Can_Never_Be_Null (Discr_Type) then
                  Error_Msg_NE
                    ("`NOT NULL` not allowed (& already excludes null)",
                     Discr,
                     Discr_Type);
               end if;

               Set_Etype (Defining_Identifier (Discr),
                 Create_Null_Excluding_Itype
                   (T           => Discr_Type,
                    Related_Nod => Discr));

            --  Check for improper null exclusion if the type is otherwise
            --  legal for a discriminant.

            elsif Null_Exclusion_Present (Discr)
              and then Is_Discrete_Type (Discr_Type)
            then
               Error_Msg_N
                 ("null exclusion can only apply to an access type", Discr);
            end if;

            --  Ada 2005 (AI-402): access discriminants of nonlimited types
            --  can't have defaults. Synchronized types, or types that are
            --  explicitly limited are fine, but special tests apply to derived
            --  types in generics: in a generic body we have to assume the
            --  worst, and therefore defaults are not allowed if the parent is
            --  a generic formal private type (see ACATS B370001).

            if Is_Access_Type (Discr_Type) and then Default_Present then
               if Ekind (Discr_Type) /= E_Anonymous_Access_Type
                 or else Is_Limited_Record (Current_Scope)
                 or else Is_Concurrent_Type (Current_Scope)
                 or else Is_Concurrent_Record_Type (Current_Scope)
                 or else Ekind (Current_Scope) = E_Limited_Private_Type
               then
                  if not Is_Derived_Type (Current_Scope)
                    or else not Is_Generic_Type (Etype (Current_Scope))
                    or else not In_Package_Body (Scope (Etype (Current_Scope)))
                    or else Limited_Present
                              (Type_Definition (Parent (Current_Scope)))
                  then
                     null;

                  else
                     Error_Msg_N
                       ("access discriminants of nonlimited types cannot "
                        & "have defaults", Expression (Discr));
                  end if;

               elsif Present (Expression (Discr)) then
                  Error_Msg_N
                    ("(Ada 2005) access discriminants of nonlimited types "
                     & "cannot have defaults", Expression (Discr));
               end if;
            end if;
         end if;

         --  A discriminant cannot be effectively volatile (SPARK RM 7.1.3(4)).
         --  This check is relevant only when SPARK_Mode is on as it is not a
         --  standard Ada legality rule. The only way for a discriminant to be
         --  effectively volatile is to have an effectively volatile type, so
         --  we check this directly, because the Ekind of Discr might not be
         --  set yet (to help preventing cascaded errors on derived types).

         if SPARK_Mode = On
           and then Is_Effectively_Volatile (Discr_Type)
         then
            Error_Msg_N ("discriminant cannot be volatile", Discr);
         end if;

         Next (Discr);
      end loop;

      --  An element list consisting of the default expressions of the
      --  discriminants is constructed in the above loop and used to set
      --  the Discriminant_Constraint attribute for the type. If an object
      --  is declared of this (record or task) type without any explicit
      --  discriminant constraint given, this element list will form the
      --  actual parameters for the corresponding initialization procedure
      --  for the type.

      Set_Discriminant_Constraint (Current_Scope, Elist);
      Set_Stored_Constraint (Current_Scope, No_Elist);

      --  Default expressions must be provided either for all or for none
      --  of the discriminants of a discriminant part. (RM 3.7.1)

      if Default_Present and then Default_Not_Present then
         Error_Msg_N
           ("incomplete specification of defaults for discriminants", N);
      end if;

      --  The use of the name of a discriminant is not allowed in default
      --  expressions of a discriminant part if the specification of the
      --  discriminant is itself given in the discriminant part. (RM 3.7.1)

      --  To detect this, the discriminant names are entered initially with an
      --  Ekind of E_Void (which is the default Ekind given by Enter_Name). Any
      --  attempt to use a void entity (for example in an expression that is
      --  type-checked) produces the error message: premature usage. Now after
      --  completing the semantic analysis of the discriminant part, we can set
      --  the Ekind of all the discriminants appropriately.

      Discr := First (Discriminant_Specifications (N));
      Discr_Number := Uint_1;
      while Present (Discr) loop
         Id := Defining_Identifier (Discr);

         if Ekind (Id) = E_In_Parameter then
            Reinit_Field_To_Zero (Id, F_Discriminal_Link);
         end if;

         Mutate_Ekind (Id, E_Discriminant);
         Reinit_Component_Location (Id);
         Reinit_Esize (Id);
         Set_Discriminant_Number (Id, Discr_Number);

         --  Make sure this is always set, even in illegal programs

         Set_Corresponding_Discriminant (Id, Empty);

         --  Initialize the Original_Record_Component to the entity itself.
         --  Inherit_Components will propagate the right value to
         --  discriminants in derived record types.

         Set_Original_Record_Component (Id, Id);

         --  Create the discriminal for the discriminant

         Build_Discriminal (Id);

         Next (Discr);
         Discr_Number := Discr_Number + 1;
      end loop;

      Set_Has_Discriminants (Current_Scope);
   end Process_Discriminants;

   -----------------------
   -- Process_Full_View --
   -----------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Process_Full_View (N : Node_Id; Full_T, Priv_T : Entity_Id) is
      procedure Collect_Implemented_Interfaces
        (Typ    : Entity_Id;
         Ifaces : Elist_Id);
      --  Ada 2005: Gather all the interfaces that Typ directly or
      --  inherently implements. Duplicate entries are not added to
      --  the list Ifaces.

      ------------------------------------
      -- Collect_Implemented_Interfaces --
      ------------------------------------

      procedure Collect_Implemented_Interfaces
        (Typ    : Entity_Id;
         Ifaces : Elist_Id)
      is
         Iface      : Entity_Id;
         Iface_Elmt : Elmt_Id;

      begin
         --  Abstract interfaces are only associated with tagged record types

         if not Is_Tagged_Type (Typ) or else not Is_Record_Type (Typ) then
            return;
         end if;

         --  Recursively climb to the ancestors

         if Etype (Typ) /= Typ

            --  Protect the frontend against wrong cyclic declarations like:

            --     type B is new A with private;
            --     type C is new A with private;
            --  private
            --     type B is new C with null record;
            --     type C is new B with null record;

           and then Etype (Typ) /= Priv_T
           and then Etype (Typ) /= Full_T
         then
            --  Keep separate the management of private type declarations

            if Ekind (Typ) = E_Record_Type_With_Private then

               --  Handle the following illegal usage:
               --      type Private_Type is tagged private;
               --   private
               --      type Private_Type is new Type_Implementing_Iface;

               if Present (Full_View (Typ))
                 and then Etype (Typ) /= Full_View (Typ)
               then
                  if Is_Interface (Etype (Typ)) then
                     Append_Unique_Elmt (Etype (Typ), Ifaces);
                  end if;

                  Collect_Implemented_Interfaces (Etype (Typ), Ifaces);
               end if;

            --  Non-private types

            else
               if Is_Interface (Etype (Typ)) then
                  Append_Unique_Elmt (Etype (Typ), Ifaces);
               end if;

               Collect_Implemented_Interfaces (Etype (Typ), Ifaces);
            end if;
         end if;

         --  Handle entities in the list of abstract interfaces

         if Present (Interfaces (Typ)) then
            Iface_Elmt := First_Elmt (Interfaces (Typ));
            while Present (Iface_Elmt) loop
               Iface := Node (Iface_Elmt);

               pragma Assert (Is_Interface (Iface));

               if not Contain_Interface (Iface, Ifaces) then
                  Append_Elmt (Iface, Ifaces);
                  Collect_Implemented_Interfaces (Iface, Ifaces);
               end if;

               Next_Elmt (Iface_Elmt);
            end loop;
         end if;
      end Collect_Implemented_Interfaces;

      --  Local variables

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      Full_Indic  : Node_Id;
      Full_Parent : Entity_Id;
      Priv_Parent : Entity_Id;

   --  Start of processing for Process_Full_View

   begin
      Mark_And_Set_Ghost_Completion (N, Priv_T);

      --  First some sanity checks that must be done after semantic
      --  decoration of the full view and thus cannot be placed with other
      --  similar checks in Find_Type_Name

      if not Is_Limited_Type (Priv_T)
        and then (Is_Limited_Type (Full_T)
                   or else Is_Limited_Composite (Full_T))
      then
         if In_Instance then
            null;
         else
            Error_Msg_N
              ("completion of nonlimited type cannot be limited", Full_T);
            Explain_Limited_Type (Full_T, Full_T);
         end if;

      elsif Is_Abstract_Type (Full_T)
        and then not Is_Abstract_Type (Priv_T)
      then
         Error_Msg_N
           ("completion of nonabstract type cannot be abstract", Full_T);

      elsif Is_Tagged_Type (Priv_T)
        and then Is_Limited_Type (Priv_T)
        and then not Is_Limited_Type (Full_T)
      then
         --  If pragma CPP_Class was applied to the private declaration
         --  propagate the limitedness to the full-view

         if Is_CPP_Class (Priv_T) then
            Set_Is_Limited_Record (Full_T);

         --  GNAT allow its own definition of Limited_Controlled to disobey
         --  this rule in order in ease the implementation. This test is safe
         --  because Root_Controlled is defined in a child of System that
         --  normal programs are not supposed to use.

         elsif Is_RTE (Etype (Full_T), RE_Root_Controlled) then
            Set_Is_Limited_Composite (Full_T);
         else
            Error_Msg_N
              ("completion of limited tagged type must be limited", Full_T);
         end if;

      elsif Is_Generic_Type (Priv_T) then
         Error_Msg_N ("generic type cannot have a completion", Full_T);
      end if;

      --  Check that ancestor interfaces of private and full views are
      --  consistent. We omit this check for synchronized types because
      --  they are performed on the corresponding record type when frozen.

      if Ada_Version >= Ada_2005
        and then Is_Tagged_Type (Priv_T)
        and then Is_Tagged_Type (Full_T)
        and then not Is_Concurrent_Type (Full_T)
      then
         declare
            Iface         : Entity_Id;
            Priv_T_Ifaces : constant Elist_Id := New_Elmt_List;
            Full_T_Ifaces : constant Elist_Id := New_Elmt_List;

         begin
            Collect_Implemented_Interfaces (Priv_T, Priv_T_Ifaces);
            Collect_Implemented_Interfaces (Full_T, Full_T_Ifaces);

            --  Ada 2005 (AI-251): The partial view shall be a descendant of
            --  an interface type if and only if the full type is descendant
            --  of the interface type (AARM 7.3 (7.3/2)).

            Iface := Find_Hidden_Interface (Priv_T_Ifaces, Full_T_Ifaces);

            if Present (Iface) then
               Error_Msg_NE
                 ("interface in partial view& not implemented by full type "
                  & "(RM-2005 7.3 (7.3/2))", Full_T, Iface);
            end if;

            Iface := Find_Hidden_Interface (Full_T_Ifaces, Priv_T_Ifaces);

            if Present (Iface) then
               Error_Msg_NE
                 ("interface & not implemented by partial view "
                  & "(RM-2005 7.3 (7.3/2))", Full_T, Iface);
            end if;
         end;
      end if;

      if Is_Tagged_Type (Priv_T)
        and then Nkind (Parent (Priv_T)) = N_Private_Extension_Declaration
        and then Is_Derived_Type (Full_T)
      then
         Priv_Parent := Etype (Priv_T);

         --  The full view of a private extension may have been transformed
         --  into an unconstrained derived type declaration and a subtype
         --  declaration (see build_derived_record_type for details).

         if Nkind (N) = N_Subtype_Declaration then
            Full_Indic  := Subtype_Indication (N);
            Full_Parent := Etype (Base_Type (Full_T));
         else
            Full_Indic  := Subtype_Indication (Type_Definition (N));
            Full_Parent := Etype (Full_T);
         end if;

         --  Check that the parent type of the full type is a descendant of
         --  the ancestor subtype given in the private extension. If either
         --  entity has an Etype equal to Any_Type then we had some previous
         --  error situation [7.3(8)].

         if Priv_Parent = Any_Type or else Full_Parent = Any_Type then
            goto Leave;

         --  Ada 2005 (AI-251): Interfaces in the full type can be given in
         --  any order. Therefore we don't have to check that its parent must
         --  be a descendant of the parent of the private type declaration.

         elsif Is_Interface (Priv_Parent)
           and then Is_Interface (Full_Parent)
         then
            null;

         --  Ada 2005 (AI-251): If the parent of the private type declaration
         --  is an interface there is no need to check that it is an ancestor
         --  of the associated full type declaration. The required tests for
         --  this case are performed by Build_Derived_Record_Type.

         elsif not Is_Interface (Base_Type (Priv_Parent))
           and then not Is_Ancestor (Base_Type (Priv_Parent), Full_Parent)
         then
            Error_Msg_N
              ("parent of full type must descend from parent of private "
               & "extension", Full_Indic);

         --  First check a formal restriction, and then proceed with checking
         --  Ada rules. Since the formal restriction is not a serious error, we
         --  don't prevent further error detection for this check, hence the
         --  ELSE.

         else
            --  Check the rules of 7.3(10): if the private extension inherits
            --  known discriminants, then the full type must also inherit those
            --  discriminants from the same (ancestor) type, and the parent
            --  subtype of the full type must be constrained if and only if
            --  the ancestor subtype of the private extension is constrained.

            if No (Discriminant_Specifications (Parent (Priv_T)))
              and then not Has_Unknown_Discriminants (Priv_T)
              and then Has_Discriminants (Base_Type (Priv_Parent))
            then
               declare
                  Priv_Indic  : constant Node_Id :=
                                  Subtype_Indication (Parent (Priv_T));

                  Priv_Constr : constant Boolean :=
                                  Is_Constrained (Priv_Parent)
                                    or else
                                      Nkind (Priv_Indic) = N_Subtype_Indication
                                    or else
                                      Is_Constrained (Entity (Priv_Indic));

                  Full_Constr : constant Boolean :=
                                  Is_Constrained (Full_Parent)
                                    or else
                                      Nkind (Full_Indic) = N_Subtype_Indication
                                    or else
                                      Is_Constrained (Entity (Full_Indic));

                  Priv_Discr : Entity_Id;
                  Full_Discr : Entity_Id;

               begin
                  Priv_Discr := First_Discriminant (Priv_Parent);
                  Full_Discr := First_Discriminant (Full_Parent);
                  while Present (Priv_Discr) and then Present (Full_Discr) loop
                     if Original_Record_Component (Priv_Discr) =
                        Original_Record_Component (Full_Discr)
                          or else
                        Corresponding_Discriminant (Priv_Discr) =
                        Corresponding_Discriminant (Full_Discr)
                     then
                        null;
                     else
                        exit;
                     end if;

                     Next_Discriminant (Priv_Discr);
                     Next_Discriminant (Full_Discr);
                  end loop;

                  if Present (Priv_Discr) or else Present (Full_Discr) then
                     Error_Msg_N
                       ("full view must inherit discriminants of the parent "
                        & "type used in the private extension", Full_Indic);

                  elsif Priv_Constr and then not Full_Constr then
                     Error_Msg_N
                       ("parent subtype of full type must be constrained",
                        Full_Indic);

                  elsif Full_Constr and then not Priv_Constr then
                     Error_Msg_N
                       ("parent subtype of full type must be unconstrained",
                        Full_Indic);
                  end if;
               end;

               --  Check the rules of 7.3(12): if a partial view has neither
               --  known or unknown discriminants, then the full type
               --  declaration shall define a definite subtype.

            elsif not Has_Unknown_Discriminants (Priv_T)
              and then not Has_Discriminants (Priv_T)
              and then not Is_Constrained (Full_T)
            then
               Error_Msg_N
                 ("full view must define a constrained type if partial view "
                  & "has no discriminants", Full_T);
            end if;

            --  Do we implement the following properly???
            --  If the ancestor subtype of a private extension has constrained
            --  discriminants, then the parent subtype of the full view shall
            --  impose a statically matching constraint on those discriminants
            --  [7.3(13)].
         end if;

      else
         --  For untagged types, verify that a type without discriminants is
         --  not completed with an unconstrained type. A separate error message
         --  is produced if the full type has defaulted discriminants.

         if Is_Definite_Subtype (Priv_T)
           and then not Is_Definite_Subtype (Full_T)
         then
            Error_Msg_Sloc := Sloc (Parent (Priv_T));
            Error_Msg_NE
              ("full view of& not compatible with declaration#",
               Full_T, Priv_T);

            if not Is_Tagged_Type (Full_T) then
               Error_Msg_N
                 ("\one is constrained, the other unconstrained", Full_T);
            end if;
         end if;
      end if;

      --  AI-419: verify that the use of "limited" is consistent

      declare
         Orig_Decl : constant Node_Id := Original_Node (N);

      begin
         if Nkind (Parent (Priv_T)) = N_Private_Extension_Declaration
           and then Nkind (Orig_Decl) = N_Full_Type_Declaration
           and then Nkind
             (Type_Definition (Orig_Decl)) = N_Derived_Type_Definition
         then
            if not Limited_Present (Parent (Priv_T))
              and then not Synchronized_Present (Parent (Priv_T))
              and then Limited_Present (Type_Definition (Orig_Decl))
            then
               Error_Msg_N
                 ("full view of non-limited extension cannot be limited", N);

            --  Conversely, if the partial view carries the limited keyword,
            --  the full view must as well, even if it may be redundant.

            elsif Limited_Present (Parent (Priv_T))
              and then not Limited_Present (Type_Definition (Orig_Decl))
            then
               Error_Msg_N
                 ("full view of limited extension must be explicitly limited",
                  N);
            end if;
         end if;
      end;

      --  Ada 2005 (AI-443): A synchronized private extension must be
      --  completed by a task or protected type.

      if Ada_Version >= Ada_2005
        and then Nkind (Parent (Priv_T)) = N_Private_Extension_Declaration
        and then Synchronized_Present (Parent (Priv_T))
        and then not Is_Concurrent_Type (Full_T)
      then
         Error_Msg_N ("full view of synchronized extension must " &
                      "be synchronized type", N);
      end if;

      --  Ada 2005 AI-363: if the full view has discriminants with
      --  defaults, it is illegal to declare constrained access subtypes
      --  whose designated type is the current type. This allows objects
      --  of the type that are declared in the heap to be unconstrained.

      if not Has_Unknown_Discriminants (Priv_T)
        and then not Has_Discriminants (Priv_T)
        and then Has_Defaulted_Discriminants (Full_T)
      then
         Set_Has_Constrained_Partial_View (Base_Type (Full_T));
         Set_Has_Constrained_Partial_View (Priv_T);
      end if;

      --  Create a full declaration for all its subtypes recorded in
      --  Private_Dependents and swap them similarly to the base type. These
      --  are subtypes that have been define before the full declaration of
      --  the private type. We also swap the entry in Private_Dependents list
      --  so we can properly restore the private view on exit from the scope.

      declare
         Priv_Elmt : Elmt_Id;
         Priv_Scop : Entity_Id;
         Priv      : Entity_Id;
         Full      : Entity_Id;

      begin
         Priv_Elmt := First_Elmt (Private_Dependents (Priv_T));
         while Present (Priv_Elmt) loop
            Priv := Node (Priv_Elmt);
            Priv_Scop := Scope (Priv);

            if Ekind (Priv) in E_Private_Subtype
                             | E_Limited_Private_Subtype
                             | E_Record_Subtype_With_Private
            then
               Full := Make_Defining_Identifier (Sloc (Priv), Chars (Priv));
               Set_Is_Itype (Full);
               Set_Parent (Full, Parent (Priv));
               Set_Associated_Node_For_Itype (Full, N);

               --  Now we need to complete the private subtype, but since the
               --  base type has already been swapped, we must also swap the
               --  subtypes (and thus, reverse the arguments in the call to
               --  Complete_Private_Subtype). Also note that we may need to
               --  re-establish the scope of the private subtype.

               Copy_And_Swap (Priv, Full);

               if not In_Open_Scopes (Priv_Scop) then
                  Push_Scope (Priv_Scop);

               else
                  --  Reset Priv_Scop to Empty to indicate no scope was pushed

                  Priv_Scop := Empty;
               end if;

               Complete_Private_Subtype (Full, Priv, Full_T, N);
               Set_Full_View (Full, Priv);

               if Present (Priv_Scop) then
                  Pop_Scope;
               end if;

               Replace_Elmt (Priv_Elmt, Full);
            end if;

            Next_Elmt (Priv_Elmt);
         end loop;
      end;

      declare
         Disp_Typ  : Entity_Id;
         Full_List : Elist_Id;
         Prim      : Entity_Id;
         Prim_Elmt : Elmt_Id;
         Priv_List : Elist_Id;

         function Contains
           (E : Entity_Id;
            L : Elist_Id) return Boolean;
         --  Determine whether list L contains element E

         --------------
         -- Contains --
         --------------

         function Contains
           (E : Entity_Id;
            L : Elist_Id) return Boolean
         is
            List_Elmt : Elmt_Id;

         begin
            List_Elmt := First_Elmt (L);
            while Present (List_Elmt) loop
               if Node (List_Elmt) = E then
                  return True;
               end if;

               Next_Elmt (List_Elmt);
            end loop;

            return False;
         end Contains;

      --  Start of processing

      begin
         --  If the private view was tagged, copy the new primitive operations
         --  from the private view to the full view.

         if Is_Tagged_Type (Full_T) then
            if Is_Tagged_Type (Priv_T) then
               Priv_List := Primitive_Operations (Priv_T);
               Prim_Elmt := First_Elmt (Priv_List);

               --  In the case of a concurrent type completing a private tagged
               --  type, primitives may have been declared in between the two
               --  views. These subprograms need to be wrapped the same way
               --  entries and protected procedures are handled because they
               --  cannot be directly shared by the two views.

               if Is_Concurrent_Type (Full_T) then
                  declare
                     Conc_Typ  : constant Entity_Id :=
                                   Corresponding_Record_Type (Full_T);
                     Curr_Nod  : Node_Id := Parent (Conc_Typ);
                     Wrap_Spec : Node_Id;

                  begin
                     while Present (Prim_Elmt) loop
                        Prim := Node (Prim_Elmt);

                        if Comes_From_Source (Prim)
                          and then not Is_Abstract_Subprogram (Prim)
                        then
                           Wrap_Spec :=
                             Make_Subprogram_Declaration (Sloc (Prim),
                               Specification =>
                                 Build_Wrapper_Spec
                                   (Subp_Id => Prim,
                                    Obj_Typ => Conc_Typ,
                                    Formals =>
                                      Parameter_Specifications
                                        (Parent (Prim))));

                           Insert_After (Curr_Nod, Wrap_Spec);
                           Curr_Nod := Wrap_Spec;

                           Analyze (Wrap_Spec);

                           --  Remove the wrapper from visibility to avoid
                           --  spurious conflict with the wrapped entity.

                           Set_Is_Immediately_Visible
                             (Defining_Entity (Specification (Wrap_Spec)),
                              False);
                        end if;

                        Next_Elmt (Prim_Elmt);
                     end loop;

                     goto Leave;
                  end;

               --  For nonconcurrent types, transfer explicit primitives, but
               --  omit those inherited from the parent of the private view
               --  since they will be re-inherited later on.

               else
                  Full_List := Primitive_Operations (Full_T);
                  while Present (Prim_Elmt) loop
                     Prim := Node (Prim_Elmt);

                     if Comes_From_Source (Prim)
                       and then not Contains (Prim, Full_List)
                     then
                        Append_Elmt (Prim, Full_List);
                     end if;

                     Next_Elmt (Prim_Elmt);
                  end loop;
               end if;

            --  Untagged private view

            else
               Full_List := Primitive_Operations (Full_T);

               --  In this case the partial view is untagged, so here we locate
               --  all of the earlier primitives that need to be treated as
               --  dispatching (those that appear between the two views). Note
               --  that these additional operations must all be new operations
               --  (any earlier operations that override inherited operations
               --  of the full view will already have been inserted in the
               --  primitives list, marked by Check_Operation_From_Private_View
               --  as dispatching. Note that implicit "/=" operators are
               --  excluded from being added to the primitives list since they
               --  shouldn't be treated as dispatching (tagged "/=" is handled
               --  specially).

               Prim := Next_Entity (Full_T);
               while Present (Prim) and then Prim /= Priv_T loop
                  if Ekind (Prim) in E_Procedure | E_Function then
                     Disp_Typ := Find_Dispatching_Type (Prim);

                     if Disp_Typ = Full_T
                       and then (Chars (Prim) /= Name_Op_Ne
                                  or else Comes_From_Source (Prim))
                     then
                        Check_Controlling_Formals (Full_T, Prim);

                        if Is_Suitable_Primitive (Prim)
                          and then not Is_Dispatching_Operation (Prim)
                        then
                           Append_Elmt (Prim, Full_List);
                           Set_Is_Dispatching_Operation (Prim);
                           Set_DT_Position_Value (Prim, No_Uint);
                        end if;

                     elsif Is_Dispatching_Operation (Prim)
                       and then Disp_Typ /= Full_T
                     then
                        --  Verify that it is not otherwise controlled by a
                        --  formal or a return value of type T.

                        Check_Controlling_Formals (Disp_Typ, Prim);
                     end if;
                  end if;

                  Next_Entity (Prim);
               end loop;
            end if;

            --  For the tagged case, the two views can share the same primitive
            --  operations list and the same class-wide type. Update attributes
            --  of the class-wide type which depend on the full declaration.

            if Is_Tagged_Type (Priv_T) then
               Set_Direct_Primitive_Operations (Priv_T, Full_List);
               Set_Class_Wide_Type
                 (Base_Type (Full_T), Class_Wide_Type (Priv_T));

               Propagate_Concurrent_Flags (Class_Wide_Type (Priv_T), Full_T);
            end if;

         --  For untagged types, copy the primitives across from the private
         --  view to the full view (when extensions are allowed), for support
         --  of prefixed calls (when extensions are enabled).

         elsif Extensions_Allowed then
            Priv_List := Primitive_Operations (Priv_T);
            Prim_Elmt := First_Elmt (Priv_List);

            Full_List := Primitive_Operations (Full_T);
            while Present (Prim_Elmt) loop
               Prim := Node (Prim_Elmt);
               Append_Elmt (Prim, Full_List);
               Next_Elmt (Prim_Elmt);
            end loop;
         end if;
      end;

      --  Ada 2005 AI 161: Check preelaborable initialization consistency

      if Known_To_Have_Preelab_Init (Priv_T) then

         --  Case where there is a pragma Preelaborable_Initialization. We
         --  always allow this in predefined units, which is cheating a bit,
         --  but it means we don't have to struggle to meet the requirements in
         --  the RM for having Preelaborable Initialization. Otherwise we
         --  require that the type meets the RM rules. But we can't check that
         --  yet, because of the rule about overriding Initialize, so we simply
         --  set a flag that will be checked at freeze time.

         if not In_Predefined_Unit (Full_T) then
            Set_Must_Have_Preelab_Init (Full_T);
         end if;
      end if;

      --  If pragma CPP_Class was applied to the private type declaration,
      --  propagate it now to the full type declaration.

      if Is_CPP_Class (Priv_T) then
         Set_Is_CPP_Class (Full_T);
         Set_Convention   (Full_T, Convention_CPP);

         --  Check that components of imported CPP types do not have default
         --  expressions.

         Check_CPP_Type_Has_No_Defaults (Full_T);
      end if;

      --  If the private view has user specified stream attributes, then so has
      --  the full view.

      --  Why the test, how could these flags be already set in Full_T ???

      if Has_Specified_Stream_Read (Priv_T) then
         Set_Has_Specified_Stream_Read (Full_T);
      end if;

      if Has_Specified_Stream_Write (Priv_T) then
         Set_Has_Specified_Stream_Write (Full_T);
      end if;

      if Has_Specified_Stream_Input (Priv_T) then
         Set_Has_Specified_Stream_Input (Full_T);
      end if;

      if Has_Specified_Stream_Output (Priv_T) then
         Set_Has_Specified_Stream_Output (Full_T);
      end if;

      --  Propagate Default_Initial_Condition-related attributes from the
      --  partial view to the full view.

      Propagate_DIC_Attributes (Full_T, From_Typ => Priv_T);

      --  And to the underlying full view, if any

      if Is_Private_Type (Full_T)
        and then Present (Underlying_Full_View (Full_T))
      then
         Propagate_DIC_Attributes
           (Underlying_Full_View (Full_T), From_Typ => Priv_T);
      end if;

      --  Propagate invariant-related attributes from the partial view to the
      --  full view.

      Propagate_Invariant_Attributes (Full_T, From_Typ => Priv_T);

      --  And to the underlying full view, if any

      if Is_Private_Type (Full_T)
        and then Present (Underlying_Full_View (Full_T))
      then
         Propagate_Invariant_Attributes
           (Underlying_Full_View (Full_T), From_Typ => Priv_T);
      end if;

      --  AI12-0041: Detect an attempt to inherit a class-wide type invariant
      --  in the full view without advertising the inheritance in the partial
      --  view. This can only occur when the partial view has no parent type
      --  and the full view has an interface as a parent. Any other scenarios
      --  are illegal because implemented interfaces must match between the
      --  two views.

      if Is_Tagged_Type (Priv_T) and then Is_Tagged_Type (Full_T) then
         declare
            Full_Par : constant Entity_Id := Etype (Full_T);
            Priv_Par : constant Entity_Id := Etype (Priv_T);

         begin
            if not Is_Interface (Priv_Par)
              and then Is_Interface (Full_Par)
              and then Has_Inheritable_Invariants (Full_Par)
            then
               Error_Msg_N
                 ("hidden inheritance of class-wide type invariants not "
                  & "allowed", N);
            end if;
         end;
      end if;

      --  Propagate predicates to full type, and predicate function if already
      --  defined. It is not clear that this can actually happen? the partial
      --  view cannot be frozen yet, and the predicate function has not been
      --  built. Still it is a cheap check and seems safer to make it.

      Propagate_Predicate_Attributes (Full_T, Priv_T);

      if Is_Private_Type (Full_T)
        and then Present (Underlying_Full_View (Full_T))
      then
         Propagate_Predicate_Attributes
           (Underlying_Full_View (Full_T), Priv_T);
      end if;

   <<Leave>>
      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Process_Full_View;

   -----------------------------------
   -- Process_Incomplete_Dependents --
   -----------------------------------

   procedure Process_Incomplete_Dependents
     (N      : Node_Id;
      Full_T : Entity_Id;
      Inc_T  : Entity_Id)
   is
      Inc_Elmt : Elmt_Id;
      Priv_Dep : Entity_Id;
      New_Subt : Entity_Id;

      Disc_Constraint : Elist_Id;

   begin
      if No (Private_Dependents (Inc_T)) then
         return;
      end if;

      --  Itypes that may be generated by the completion of an incomplete
      --  subtype are not used by the back-end and not attached to the tree.
      --  They are created only for constraint-checking purposes.

      Inc_Elmt := First_Elmt (Private_Dependents (Inc_T));
      while Present (Inc_Elmt) loop
         Priv_Dep := Node (Inc_Elmt);

         if Ekind (Priv_Dep) = E_Subprogram_Type then

            --  An Access_To_Subprogram type may have a return type or a
            --  parameter type that is incomplete. Replace with the full view.

            if Etype (Priv_Dep) = Inc_T then
               Set_Etype (Priv_Dep, Full_T);
            end if;

            declare
               Formal : Entity_Id;

            begin
               Formal := First_Formal (Priv_Dep);
               while Present (Formal) loop
                  if Etype (Formal) = Inc_T then
                     Set_Etype (Formal, Full_T);
                  end if;

                  Next_Formal (Formal);
               end loop;
            end;

         elsif Is_Overloadable (Priv_Dep) then

            --  If a subprogram in the incomplete dependents list is primitive
            --  for a tagged full type then mark it as a dispatching operation,
            --  check whether it overrides an inherited subprogram, and check
            --  restrictions on its controlling formals. Note that a protected
            --  operation is never dispatching: only its wrapper operation
            --  (which has convention Ada) is.

            if Is_Tagged_Type (Full_T)
              and then Is_Primitive (Priv_Dep)
              and then Convention (Priv_Dep) /= Convention_Protected
            then
               Check_Operation_From_Incomplete_Type (Priv_Dep, Inc_T);
               Set_Is_Dispatching_Operation (Priv_Dep);
               Check_Controlling_Formals (Full_T, Priv_Dep);
            end if;

         elsif Ekind (Priv_Dep) = E_Subprogram_Body then

            --  Can happen during processing of a body before the completion
            --  of a TA type. Ignore, because spec is also on dependent list.

            return;

         --  Ada 2005 (AI-412): Transform a regular incomplete subtype into a
         --  corresponding subtype of the full view.

         elsif Ekind (Priv_Dep) = E_Incomplete_Subtype
           and then Comes_From_Source (Priv_Dep)
         then
            Set_Subtype_Indication
              (Parent (Priv_Dep), New_Occurrence_Of (Full_T, Sloc (Priv_Dep)));
            Reinit_Field_To_Zero
              (Priv_Dep, F_Private_Dependents,
               Old_Ekind => E_Incomplete_Subtype);
            Mutate_Ekind (Priv_Dep, Subtype_Kind (Ekind (Full_T)));
            Set_Etype (Priv_Dep, Full_T);
            Set_Analyzed (Parent (Priv_Dep), False);

            --  Reanalyze the declaration, suppressing the call to Enter_Name
            --  to avoid duplicate names.

            Analyze_Subtype_Declaration
              (N    => Parent (Priv_Dep),
               Skip => True);

         --  Dependent is a subtype

         else
            --  We build a new subtype indication using the full view of the
            --  incomplete parent. The discriminant constraints have been
            --  elaborated already at the point of the subtype declaration.

            New_Subt := Create_Itype (E_Void, N);

            if Has_Discriminants (Full_T) then
               Disc_Constraint := Discriminant_Constraint (Priv_Dep);
            else
               Disc_Constraint := No_Elist;
            end if;

            Build_Discriminated_Subtype (Full_T, New_Subt, Disc_Constraint, N);
            Set_Full_View (Priv_Dep, New_Subt);
         end if;

         Next_Elmt (Inc_Elmt);
      end loop;
   end Process_Incomplete_Dependents;

   --------------------------------
   -- Process_Range_Expr_In_Decl --
   --------------------------------

   procedure Process_Range_Expr_In_Decl
     (R          : Node_Id;
      T          : Entity_Id;
      Subtyp     : Entity_Id := Empty;
      Check_List : List_Id   := No_List)
   is
      Lo, Hi      : Node_Id;
      R_Checks    : Check_Result;
      Insert_Node : Node_Id;
      Def_Id      : Entity_Id;

   begin
      Analyze_And_Resolve (R, Base_Type (T));

      if Nkind (R) = N_Range then
         Lo := Low_Bound (R);
         Hi := High_Bound (R);

         --  Validity checks on the range of a quantified expression are
         --  delayed until the construct is transformed into a loop.

         if Nkind (Parent (R)) = N_Loop_Parameter_Specification
           and then Nkind (Parent (Parent (R))) = N_Quantified_Expression
         then
            null;

         --  We need to ensure validity of the bounds here, because if we
         --  go ahead and do the expansion, then the expanded code will get
         --  analyzed with range checks suppressed and we miss the check.

         --  WARNING: The capture of the range bounds with xxx_FIRST/_LAST and
         --  the temporaries generated by routine Remove_Side_Effects by means
         --  of validity checks must use the same names. When a range appears
         --  in the parent of a generic, the range is processed with checks
         --  disabled as part of the generic context and with checks enabled
         --  for code generation purposes. This leads to link issues as the
         --  generic contains references to xxx_FIRST/_LAST, but the inlined
         --  template sees the temporaries generated by Remove_Side_Effects.

         else
            Validity_Check_Range (R, Subtyp);
         end if;

         --  If there were errors in the declaration, try and patch up some
         --  common mistakes in the bounds. The cases handled are literals
         --  which are Integer where the expected type is Real and vice versa.
         --  These corrections allow the compilation process to proceed further
         --  along since some basic assumptions of the format of the bounds
         --  are guaranteed.

         if Etype (R) = Any_Type then
            if Nkind (Lo) = N_Integer_Literal and then Is_Real_Type (T) then
               Rewrite (Lo,
                 Make_Real_Literal (Sloc (Lo), UR_From_Uint (Intval (Lo))));

            elsif Nkind (Hi) = N_Integer_Literal and then Is_Real_Type (T) then
               Rewrite (Hi,
                 Make_Real_Literal (Sloc (Hi), UR_From_Uint (Intval (Hi))));

            elsif Nkind (Lo) = N_Real_Literal and then Is_Integer_Type (T) then
               Rewrite (Lo,
                 Make_Integer_Literal (Sloc (Lo), UR_To_Uint (Realval (Lo))));

            elsif Nkind (Hi) = N_Real_Literal and then Is_Integer_Type (T) then
               Rewrite (Hi,
                 Make_Integer_Literal (Sloc (Hi), UR_To_Uint (Realval (Hi))));
            end if;

            Set_Etype (Lo, T);
            Set_Etype (Hi, T);
         end if;

         --  If the bounds of the range have been mistakenly given as string
         --  literals (perhaps in place of character literals), then an error
         --  has already been reported, but we rewrite the string literal as a
         --  bound of the range's type to avoid blowups in later processing
         --  that looks at static values.

         if Nkind (Lo) = N_String_Literal then
            Rewrite (Lo,
              Make_Attribute_Reference (Sloc (Lo),
                Prefix         => New_Occurrence_Of (T, Sloc (Lo)),
                Attribute_Name => Name_First));
            Analyze_And_Resolve (Lo);
         end if;

         if Nkind (Hi) = N_String_Literal then
            Rewrite (Hi,
              Make_Attribute_Reference (Sloc (Hi),
                Prefix         => New_Occurrence_Of (T, Sloc (Hi)),
                Attribute_Name => Name_First));
            Analyze_And_Resolve (Hi);
         end if;

         --  If bounds aren't scalar at this point then exit, avoiding
         --  problems with further processing of the range in this procedure.

         if not Is_Scalar_Type (Etype (Lo)) then
            return;
         end if;

         --  Resolve (actually Sem_Eval) has checked that the bounds are in
         --  then range of the base type. Here we check whether the bounds
         --  are in the range of the subtype itself. Note that if the bounds
         --  represent the null range the Constraint_Error exception should
         --  not be raised.

         --  Capture values of bounds and generate temporaries for them
         --  if needed, before applying checks, since checks may cause
         --  duplication of the expression without forcing evaluation.

         --  The forced evaluation removes side effects from expressions,
         --  which should occur also in GNATprove mode. Otherwise, we end up
         --  with unexpected insertions of actions at places where this is
         --  not supposed to occur, e.g. on default parameters of a call.

         if Expander_Active or GNATprove_Mode then

            --  Call Force_Evaluation to create declarations as needed
            --  to deal with side effects, and also create typ_FIRST/LAST
            --  entities for bounds if we have a subtype name.

            --  Note: we do this transformation even if expansion is not
            --  active if we are in GNATprove_Mode since the transformation
            --  is in general required to ensure that the resulting tree has
            --  proper Ada semantics.

            Force_Evaluation
              (Lo, Related_Id => Subtyp, Is_Low_Bound  => True);
            Force_Evaluation
              (Hi, Related_Id => Subtyp, Is_High_Bound => True);
         end if;

         --  We use a flag here instead of suppressing checks on the type
         --  because the type we check against isn't necessarily the place
         --  where we put the check.

         R_Checks := Get_Range_Checks (R, T);

         --  Look up tree to find an appropriate insertion point. We can't
         --  just use insert_actions because later processing depends on
         --  the insertion node. Prior to Ada 2012 the insertion point could
         --  only be a declaration or a loop, but quantified expressions can
         --  appear within any context in an expression, and the insertion
         --  point can be any statement, pragma, or declaration.

         Insert_Node := Parent (R);
         while Present (Insert_Node) loop
            exit when
              Nkind (Insert_Node) in N_Declaration
              and then
                Nkind (Insert_Node) not in N_Component_Declaration
                                         | N_Loop_Parameter_Specification
                                         | N_Function_Specification
                                         | N_Procedure_Specification;

            exit when Nkind (Insert_Node) in
                        N_Later_Decl_Item                     |
                        N_Statement_Other_Than_Procedure_Call |
                        N_Procedure_Call_Statement            |
                        N_Pragma;

            Insert_Node := Parent (Insert_Node);
         end loop;

         if Present (Insert_Node) then

            --  Case of loop statement. Verify that the range is part of the
            --  subtype indication of the iteration scheme.

            if Nkind (Insert_Node) = N_Loop_Statement then
               declare
                  Indic : Node_Id;

               begin
                  Indic := Parent (R);
                  while Present (Indic)
                    and then Nkind (Indic) /= N_Subtype_Indication
                  loop
                     Indic := Parent (Indic);
                  end loop;

                  if Present (Indic) then
                     Def_Id := Etype (Subtype_Mark (Indic));

                     Insert_Range_Checks
                       (R_Checks,
                        Insert_Node,
                        Def_Id,
                        Sloc (Insert_Node),
                        Do_Before => True);
                  end if;
               end;

            --  Case of declarations. If the declaration is for a type and
            --  involves discriminants, the checks are premature at the
            --  declaration point and need to wait for the expansion of the
            --  initialization procedure, which will pass in the list to put
            --  them on; otherwise, the checks are done at the declaration
            --  point and there is no need to do them again in the
            --  initialization procedure.

            elsif Nkind (Insert_Node) in N_Declaration then
               Def_Id := Defining_Identifier (Insert_Node);

               if (Ekind (Def_Id) = E_Record_Type
                    and then Depends_On_Discriminant (R))
                 or else
                  (Ekind (Def_Id) = E_Protected_Type
                    and then Has_Discriminants (Def_Id))
               then
                  if Present (Check_List) then
                     Append_Range_Checks
                       (R_Checks,
                         Check_List, Def_Id, Sloc (Insert_Node));
                  end if;

               else
                  if No (Check_List) then
                     Insert_Range_Checks
                       (R_Checks,
                         Insert_Node, Def_Id, Sloc (Insert_Node));
                  end if;
               end if;

            --  Case of statements. Drop the checks, as the range appears in
            --  the context of a quantified expression. Insertion will take
            --  place when expression is expanded.

            else
               null;
            end if;
         end if;

      --  Case of other than an explicit N_Range node

      --  The forced evaluation removes side effects from expressions, which
      --  should occur also in GNATprove mode. Otherwise, we end up with
      --  unexpected insertions of actions at places where this is not
      --  supposed to occur, e.g. on default parameters of a call.

      elsif Expander_Active or GNATprove_Mode then
         Get_Index_Bounds (R, Lo, Hi);
         Force_Evaluation (Lo);
         Force_Evaluation (Hi);
      end if;
   end Process_Range_Expr_In_Decl;

   --------------------------------------
   -- Process_Real_Range_Specification --
   --------------------------------------

   procedure Process_Real_Range_Specification (Def : Node_Id) is
      Spec : constant Node_Id := Real_Range_Specification (Def);
      Lo   : Node_Id;
      Hi   : Node_Id;
      Err  : Boolean := False;

      procedure Analyze_Bound (N : Node_Id);
      --  Analyze and check one bound

      -------------------
      -- Analyze_Bound --
      -------------------

      procedure Analyze_Bound (N : Node_Id) is
      begin
         Analyze_And_Resolve (N, Any_Real);

         if not Is_OK_Static_Expression (N) then
            Flag_Non_Static_Expr
              ("bound in real type definition is not static!", N);
            Err := True;
         end if;
      end Analyze_Bound;

   --  Start of processing for Process_Real_Range_Specification

   begin
      if Present (Spec) then
         Lo := Low_Bound (Spec);
         Hi := High_Bound (Spec);
         Analyze_Bound (Lo);
         Analyze_Bound (Hi);

         --  If error, clear away junk range specification

         if Err then
            Set_Real_Range_Specification (Def, Empty);
         end if;
      end if;
   end Process_Real_Range_Specification;

   ---------------------
   -- Process_Subtype --
   ---------------------

   function Process_Subtype
     (S           : Node_Id;
      Related_Nod : Node_Id;
      Related_Id  : Entity_Id := Empty;
      Suffix      : Character := ' ') return Entity_Id
   is
      procedure Check_Incomplete (T : Node_Id);
      --  Called to verify that an incomplete type is not used prematurely

      ----------------------
      -- Check_Incomplete --
      ----------------------

      procedure Check_Incomplete (T : Node_Id) is
      begin
         --  Ada 2005 (AI-412): Incomplete subtypes are legal

         if Ekind (Root_Type (Entity (T))) = E_Incomplete_Type
           and then
             not (Ada_Version >= Ada_2005
                   and then
                     (Nkind (Parent (T)) = N_Subtype_Declaration
                       or else (Nkind (Parent (T)) = N_Subtype_Indication
                                 and then Nkind (Parent (Parent (T))) =
                                                   N_Subtype_Declaration)))
         then
            Error_Msg_N ("invalid use of type before its full declaration", T);
         end if;
      end Check_Incomplete;

      --  Local variables

      P               : Node_Id;
      Def_Id          : Entity_Id;
      Error_Node      : Node_Id;
      Full_View_Id    : Entity_Id;
      Subtype_Mark_Id : Entity_Id;

      May_Have_Null_Exclusion : Boolean;

   --  Start of processing for Process_Subtype

   begin
      --  Case of no constraints present

      if Nkind (S) /= N_Subtype_Indication then
         Find_Type (S);

         --  No way to proceed if the subtype indication is malformed. This
         --  will happen for example when the subtype indication in an object
         --  declaration is missing altogether and the expression is analyzed
         --  as if it were that indication.

         if not Is_Entity_Name (S) then
            return Any_Type;
         end if;

         Check_Incomplete (S);
         P := Parent (S);

         --  The following mirroring of assertion in Null_Exclusion_Present is
         --  ugly, can't we have a range, a static predicate or even a flag???

         May_Have_Null_Exclusion :=
           Present (P)
             and then
           Nkind (P) in N_Access_Definition
                      | N_Access_Function_Definition
                      | N_Access_Procedure_Definition
                      | N_Access_To_Object_Definition
                      | N_Allocator
                      | N_Component_Definition
                      | N_Derived_Type_Definition
                      | N_Discriminant_Specification
                      | N_Formal_Object_Declaration
                      | N_Function_Specification
                      | N_Object_Declaration
                      | N_Object_Renaming_Declaration
                      | N_Parameter_Specification
                      | N_Subtype_Declaration;

         --  Ada 2005 (AI-231): Static check

         if Ada_Version >= Ada_2005
           and then May_Have_Null_Exclusion
           and then Null_Exclusion_Present (P)
           and then Nkind (P) /= N_Access_To_Object_Definition
           and then not Is_Access_Type (Entity (S))
         then
            Error_Msg_N ("`NOT NULL` only allowed for an access type", S);
         end if;

         --  Create an Itype that is a duplicate of Entity (S) but with the
         --  null-exclusion attribute.

         if May_Have_Null_Exclusion
           and then Is_Access_Type (Entity (S))
           and then Null_Exclusion_Present (P)

            --  No need to check the case of an access to object definition.
            --  It is correct to define double not-null pointers.

            --  Example:
            --     type Not_Null_Int_Ptr is not null access Integer;
            --     type Acc is not null access Not_Null_Int_Ptr;

           and then Nkind (P) /= N_Access_To_Object_Definition
         then
            if Can_Never_Be_Null (Entity (S)) then
               case Nkind (Related_Nod) is
                  when N_Full_Type_Declaration =>
                     if Nkind (Type_Definition (Related_Nod))
                       in N_Array_Type_Definition
                     then
                        Error_Node :=
                          Subtype_Indication
                            (Component_Definition
                             (Type_Definition (Related_Nod)));
                     else
                        Error_Node :=
                          Subtype_Indication (Type_Definition (Related_Nod));
                     end if;

                  when N_Subtype_Declaration =>
                     Error_Node := Subtype_Indication (Related_Nod);

                  when N_Object_Declaration =>
                     Error_Node := Object_Definition (Related_Nod);

                  when N_Component_Declaration =>
                     Error_Node :=
                       Subtype_Indication (Component_Definition (Related_Nod));

                  when N_Allocator =>
                     Error_Node := Expression (Related_Nod);

                  when others =>
                     pragma Assert (False);
                     Error_Node := Related_Nod;
               end case;

               Error_Msg_NE
                 ("`NOT NULL` not allowed (& already excludes null)",
                  Error_Node,
                  Entity (S));
            end if;

            Set_Etype  (S,
              Create_Null_Excluding_Itype
                (T           => Entity (S),
                 Related_Nod => P));
            Set_Entity (S, Etype (S));
         end if;

         return Entity (S);

      --  Case of constraint present, so that we have an N_Subtype_Indication
      --  node (this node is created only if constraints are present).

      else
         Find_Type (Subtype_Mark (S));

         if Nkind (Parent (S)) /= N_Access_To_Object_Definition
           and then not
            (Nkind (Parent (S)) = N_Subtype_Declaration
              and then Is_Itype (Defining_Identifier (Parent (S))))
         then
            Check_Incomplete (Subtype_Mark (S));
         end if;

         P := Parent (S);
         Subtype_Mark_Id := Entity (Subtype_Mark (S));

         --  Explicit subtype declaration case

         if Nkind (P) = N_Subtype_Declaration then
            Def_Id := Defining_Identifier (P);

         --  Explicit derived type definition case

         elsif Nkind (P) = N_Derived_Type_Definition then
            Def_Id := Defining_Identifier (Parent (P));

         --  Implicit case, the Def_Id must be created as an implicit type.
         --  The one exception arises in the case of concurrent types, array
         --  and access types, where other subsidiary implicit types may be
         --  created and must appear before the main implicit type. In these
         --  cases we leave Def_Id set to Empty as a signal that Create_Itype
         --  has not yet been called to create Def_Id.

         else
            if Is_Array_Type (Subtype_Mark_Id)
              or else Is_Concurrent_Type (Subtype_Mark_Id)
              or else Is_Access_Type (Subtype_Mark_Id)
            then
               Def_Id := Empty;

            --  For the other cases, we create a new unattached Itype,
            --  and set the indication to ensure it gets attached later.

            else
               Def_Id :=
                 Create_Itype (E_Void, Related_Nod, Related_Id, Suffix);
            end if;
         end if;

         --  If the kind of constraint is invalid for this kind of type,
         --  then give an error, and then pretend no constraint was given.

         if not Is_Valid_Constraint_Kind
                   (Ekind (Subtype_Mark_Id), Nkind (Constraint (S)))
         then
            Error_Msg_N
              ("incorrect constraint for this kind of type", Constraint (S));

            Rewrite (S, New_Copy_Tree (Subtype_Mark (S)));

            --  Set Ekind of orphan itype, to prevent cascaded errors

            if Present (Def_Id) then
               Mutate_Ekind (Def_Id, Ekind (Any_Type));
            end if;

            --  Make recursive call, having got rid of the bogus constraint

            return Process_Subtype (S, Related_Nod, Related_Id, Suffix);
         end if;

         --  Remaining processing depends on type. Select on Base_Type kind to
         --  ensure getting to the concrete type kind in the case of a private
         --  subtype (needed when only doing semantic analysis).

         case Ekind (Base_Type (Subtype_Mark_Id)) is
            when Access_Kind =>

               --  If this is a constraint on a class-wide type, discard it.
               --  There is currently no way to express a partial discriminant
               --  constraint on a type with unknown discriminants. This is
               --  a pathology that the ACATS wisely decides not to test.

               if Is_Class_Wide_Type (Designated_Type (Subtype_Mark_Id)) then
                  if Comes_From_Source (S) then
                     Error_Msg_N
                       ("constraint on class-wide type ignored??",
                        Constraint (S));
                  end if;

                  if Nkind (P) = N_Subtype_Declaration then
                     Set_Subtype_Indication (P,
                        New_Occurrence_Of (Subtype_Mark_Id, Sloc (S)));
                  end if;

                  return Subtype_Mark_Id;
               end if;

               Constrain_Access (Def_Id, S, Related_Nod);

               if Expander_Active
                 and then Is_Itype (Designated_Type (Def_Id))
                 and then Nkind (Related_Nod) = N_Subtype_Declaration
                 and then not Is_Incomplete_Type (Designated_Type (Def_Id))
               then
                  Build_Itype_Reference
                    (Designated_Type (Def_Id), Related_Nod);
               end if;

            when Array_Kind =>
               Constrain_Array (Def_Id, S, Related_Nod, Related_Id, Suffix);

            when Decimal_Fixed_Point_Kind =>
               Constrain_Decimal (Def_Id, S);

            when Enumeration_Kind =>
               Constrain_Enumeration (Def_Id, S);

            when Ordinary_Fixed_Point_Kind =>
               Constrain_Ordinary_Fixed (Def_Id, S);

            when Float_Kind =>
               Constrain_Float (Def_Id, S);

            when Integer_Kind =>
               Constrain_Integer (Def_Id, S);

            when Class_Wide_Kind
               | E_Incomplete_Type
               | E_Record_Subtype
               | E_Record_Type
            =>
               Constrain_Discriminated_Type (Def_Id, S, Related_Nod);

               if Ekind (Def_Id) = E_Incomplete_Type then
                  Set_Private_Dependents (Def_Id, New_Elmt_List);
               end if;

            when Private_Kind =>

               --  A private type with unknown discriminants may be completed
               --  by an unconstrained array type.

               if Has_Unknown_Discriminants (Subtype_Mark_Id)
                 and then Present (Full_View (Subtype_Mark_Id))
                 and then Is_Array_Type (Full_View (Subtype_Mark_Id))
               then
                  Constrain_Array (Def_Id, S, Related_Nod, Related_Id, Suffix);

               --  ... but more commonly is completed by a discriminated record
               --  type.

               else
                  Constrain_Discriminated_Type (Def_Id, S, Related_Nod);
               end if;

               --  The base type may be private but Def_Id may be a full view
               --  in an instance.

               if Is_Private_Type (Def_Id) then
                  Set_Private_Dependents (Def_Id, New_Elmt_List);
               end if;

               --  In case of an invalid constraint prevent further processing
               --  since the type constructed is missing expected fields.

               if Etype (Def_Id) = Any_Type then
                  return Def_Id;
               end if;

               --  If the full view is that of a task with discriminants,
               --  we must constrain both the concurrent type and its
               --  corresponding record type. Otherwise we will just propagate
               --  the constraint to the full view, if available.

               if Present (Full_View (Subtype_Mark_Id))
                 and then Has_Discriminants (Subtype_Mark_Id)
                 and then Is_Concurrent_Type (Full_View (Subtype_Mark_Id))
               then
                  Full_View_Id :=
                    Create_Itype (E_Void, Related_Nod, Related_Id, Suffix);

                  Set_Entity (Subtype_Mark (S), Full_View (Subtype_Mark_Id));
                  Constrain_Concurrent (Full_View_Id, S,
                    Related_Nod, Related_Id, Suffix);
                  Set_Entity (Subtype_Mark (S), Subtype_Mark_Id);
                  Set_Full_View (Def_Id, Full_View_Id);

                  --  Introduce an explicit reference to the private subtype,
                  --  to prevent scope anomalies in gigi if first use appears
                  --  in a nested context, e.g. a later function body.
                  --  Should this be generated in other contexts than a full
                  --  type declaration?

                  if Is_Itype (Def_Id)
                    and then
                      Nkind (Parent (P)) = N_Full_Type_Declaration
                  then
                     Build_Itype_Reference (Def_Id, Parent (P));
                  end if;

               else
                  Prepare_Private_Subtype_Completion (Def_Id, Related_Nod);
               end if;

            when Concurrent_Kind  =>
               Constrain_Concurrent (Def_Id, S,
                 Related_Nod, Related_Id, Suffix);

            when others =>
               Error_Msg_N ("invalid subtype mark in subtype indication", S);
         end case;

         --  Size, Alignment, Representation aspects and Convention are always
         --  inherited from the base type.

         Set_Size_Info  (Def_Id,            (Subtype_Mark_Id));
         Set_Rep_Info   (Def_Id,            (Subtype_Mark_Id));
         Set_Convention (Def_Id, Convention (Subtype_Mark_Id));

         --  The anonymous subtype created for the subtype indication
         --  inherits the predicates of the parent.

         if Has_Predicates (Subtype_Mark_Id) then
            Inherit_Predicate_Flags (Def_Id, Subtype_Mark_Id);

            --  Indicate where the predicate function may be found

            if No (Predicate_Function (Def_Id)) and then Is_Itype (Def_Id) then
               Set_Predicated_Parent (Def_Id, Subtype_Mark_Id);
            end if;
         end if;

         return Def_Id;
      end if;
   end Process_Subtype;

   -----------------------------
   -- Record_Type_Declaration --
   -----------------------------

   procedure Record_Type_Declaration
     (T    : Entity_Id;
      N    : Node_Id;
      Prev : Entity_Id)
   is
      Def       : constant Node_Id := Type_Definition (N);
      Is_Tagged : Boolean;
      Tag_Comp  : Entity_Id;

   begin
      --  These flags must be initialized before calling Process_Discriminants
      --  because this routine makes use of them.

      Mutate_Ekind          (T, E_Record_Type);
      Set_Etype             (T, T);
      Reinit_Size_Align     (T);
      Set_Interfaces        (T, No_Elist);
      Set_Stored_Constraint (T, No_Elist);
      Set_Default_SSO       (T);
      Set_No_Reordering     (T, No_Component_Reordering);

      --  Normal case

      if Ada_Version < Ada_2005 or else not Interface_Present (Def) then
         --  The flag Is_Tagged_Type might have already been set by
         --  Find_Type_Name if it detected an error for declaration T. This
         --  arises in the case of private tagged types where the full view
         --  omits the word tagged.

         Is_Tagged :=
           Tagged_Present (Def)
             or else (Serious_Errors_Detected > 0 and then Is_Tagged_Type (T));

         Set_Is_Limited_Record (T, Limited_Present (Def));

         if Is_Tagged then
            Set_Is_Tagged_Type (T, True);
            Set_No_Tagged_Streams_Pragma (T, No_Tagged_Streams);
         end if;

         --  Type is abstract if full declaration carries keyword, or if
         --  previous partial view did.

         Set_Is_Abstract_Type    (T, Is_Abstract_Type (T)
                                      or else Abstract_Present (Def));

      else
         Is_Tagged := True;
         Analyze_Interface_Declaration (T, Def);

         if Present (Discriminant_Specifications (N)) then
            Error_Msg_N
              ("interface types cannot have discriminants",
                Defining_Identifier
                  (First (Discriminant_Specifications (N))));
         end if;
      end if;

      --  First pass: if there are self-referential access components,
      --  create the required anonymous access type declarations, and if
      --  need be an incomplete type declaration for T itself.

      Check_Anonymous_Access_Components (N, T, Prev, Component_List (Def));

      if Ada_Version >= Ada_2005
        and then Present (Interface_List (Def))
      then
         Check_Interfaces (N, Def);

         declare
            Ifaces_List : Elist_Id;

         begin
            --  Ada 2005 (AI-251): Collect the list of progenitors that are not
            --  already in the parents.

            Collect_Interfaces
              (T               => T,
               Ifaces_List     => Ifaces_List,
               Exclude_Parents => True);

            Set_Interfaces (T, Ifaces_List);
         end;
      end if;

      --  Records constitute a scope for the component declarations within.
      --  The scope is created prior to the processing of these declarations.
      --  Discriminants are processed first, so that they are visible when
      --  processing the other components. The Ekind of the record type itself
      --  is set to E_Record_Type (subtypes appear as E_Record_Subtype).

      --  Enter record scope

      Push_Scope (T);

      --  If an incomplete or private type declaration was already given for
      --  the type, then this scope already exists, and the discriminants have
      --  been declared within. We must verify that the full declaration
      --  matches the incomplete one.

      Check_Or_Process_Discriminants (N, T, Prev);

      Set_Is_Constrained     (T, not Has_Discriminants (T));
      Set_Has_Delayed_Freeze (T, True);

      --  For tagged types add a manually analyzed component corresponding
      --  to the component _tag, the corresponding piece of tree will be
      --  expanded as part of the freezing actions if it is not a CPP_Class.

      if Is_Tagged then

         --  Do not add the tag unless we are in expansion mode

         if Expander_Active then
            Tag_Comp := Make_Defining_Identifier (Sloc (Def), Name_uTag);
            Enter_Name (Tag_Comp);

            Mutate_Ekind                  (Tag_Comp, E_Component);
            Set_Is_Tag                    (Tag_Comp);
            Set_Is_Aliased                (Tag_Comp);
            Set_Is_Independent            (Tag_Comp);
            Set_Etype                     (Tag_Comp, RTE (RE_Tag));
            Set_DT_Entry_Count            (Tag_Comp, No_Uint);
            Set_Original_Record_Component (Tag_Comp, Tag_Comp);
            Reinit_Component_Location     (Tag_Comp);

            --  Ada 2005 (AI-251): Addition of the Tag corresponding to all the
            --  implemented interfaces.

            if Has_Interfaces (T) then
               Add_Interface_Tag_Components (N, T);
            end if;
         end if;

         Make_Class_Wide_Type (T);
         Set_Direct_Primitive_Operations (T, New_Elmt_List);
      end if;

      --  We must suppress range checks when processing record components in
      --  the presence of discriminants, since we don't want spurious checks to
      --  be generated during their analysis, but Suppress_Range_Checks flags
      --  must be reset the after processing the record definition.

      --  Note: this is the only use of Kill_Range_Checks, and is a bit odd,
      --  couldn't we just use the normal range check suppression method here.
      --  That would seem cleaner ???

      if Has_Discriminants (T) and then not Range_Checks_Suppressed (T) then
         Set_Kill_Range_Checks (T, True);
         Record_Type_Definition (Def, Prev);
         Set_Kill_Range_Checks (T, False);
      else
         Record_Type_Definition (Def, Prev);
      end if;

      --  Exit from record scope

      End_Scope;

      --  Ada 2005 (AI-251 and AI-345): Derive the interface subprograms of all
      --  the implemented interfaces and associate them an aliased entity.

      if Is_Tagged
        and then not Is_Empty_List (Interface_List (Def))
      then
         Derive_Progenitor_Subprograms (T, T);
      end if;

      Check_Function_Writable_Actuals (N);
   end Record_Type_Declaration;

   ----------------------------
   -- Record_Type_Definition --
   ----------------------------

   procedure Record_Type_Definition (Def : Node_Id; Prev_T : Entity_Id) is
      Component          : Entity_Id;
      Ctrl_Components    : Boolean := False;
      Final_Storage_Only : Boolean;
      T                  : Entity_Id;

   begin
      if Ekind (Prev_T) = E_Incomplete_Type then
         T := Full_View (Prev_T);
      else
         T := Prev_T;
      end if;

      Final_Storage_Only := not Is_Controlled (T);

      --  Ada 2005: Check whether an explicit "limited" is present in a derived
      --  type declaration.

      if Parent_Kind (Def) = N_Derived_Type_Definition
        and then Limited_Present (Parent (Def))
      then
         Set_Is_Limited_Record (T);
      end if;

      --  If the component list of a record type is defined by the reserved
      --  word null and there is no discriminant part, then the record type has
      --  no components and all records of the type are null records (RM 3.7)
      --  This procedure is also called to process the extension part of a
      --  record extension, in which case the current scope may have inherited
      --  components.

      if Present (Def)
        and then Present (Component_List (Def))
        and then not Null_Present (Component_List (Def))
      then
         Analyze_Declarations (Component_Items (Component_List (Def)));

         if Present (Variant_Part (Component_List (Def))) then
            Analyze (Variant_Part (Component_List (Def)));
         end if;
      end if;

      --  After completing the semantic analysis of the record definition,
      --  record components, both new and inherited, are accessible. Set their
      --  kind accordingly. Exclude malformed itypes from illegal declarations,
      --  whose Ekind may be void.

      Component := First_Entity (Current_Scope);
      while Present (Component) loop
         if Ekind (Component) = E_Void
           and then not Is_Itype (Component)
         then
            Mutate_Ekind (Component, E_Component);
            Reinit_Component_Location (Component);
         end if;

         Propagate_Concurrent_Flags (T, Etype (Component));

         if Ekind (Component) /= E_Component then
            null;

         --  Do not set Has_Controlled_Component on a class-wide equivalent
         --  type. See Make_CW_Equivalent_Type.

         elsif not Is_Class_Wide_Equivalent_Type (T)
           and then (Has_Controlled_Component (Etype (Component))
                      or else (Chars (Component) /= Name_uParent
                                and then Is_Controlled (Etype (Component))))
         then
            Set_Has_Controlled_Component (T, True);
            Final_Storage_Only :=
              Final_Storage_Only
                and then Finalize_Storage_Only (Etype (Component));
            Ctrl_Components := True;
         end if;

         Next_Entity (Component);
      end loop;

      --  A Type is Finalize_Storage_Only only if all its controlled components
      --  are also.

      if Ctrl_Components then
         Set_Finalize_Storage_Only (T, Final_Storage_Only);
      end if;

      --  Place reference to end record on the proper entity, which may
      --  be a partial view.

      if Present (Def) then
         Process_End_Label (Def, 'e', Prev_T);
      end if;
   end Record_Type_Definition;

   ---------------------------
   -- Replace_Discriminants --
   ---------------------------

   procedure Replace_Discriminants (Typ : Entity_Id; Decl : Node_Id) is
      function Process (N : Node_Id) return Traverse_Result;

      -------------
      -- Process --
      -------------

      function Process (N : Node_Id) return Traverse_Result is
         Comp : Entity_Id;

      begin
         if Nkind (N) = N_Discriminant_Specification then
            Comp := First_Discriminant (Typ);
            while Present (Comp) loop
               if Original_Record_Component (Comp) = Defining_Identifier (N)
                 or else Chars (Comp) = Chars (Defining_Identifier (N))
               then
                  Set_Defining_Identifier (N, Comp);
                  exit;
               end if;

               Next_Discriminant (Comp);
            end loop;

         elsif Nkind (N) = N_Variant_Part then
            Comp := First_Discriminant (Typ);
            while Present (Comp) loop
               if Original_Record_Component (Comp) = Entity (Name (N))
                 or else Chars (Comp) = Chars (Name (N))
               then
                  --  Make sure to preserve the type coming from the parent on
                  --  the Name, even if the subtype of the discriminant can be
                  --  constrained, so that discrete choices inherited from the
                  --  parent in the variant part are not flagged as violating
                  --  the constraints of the subtype.

                  declare
                     Typ : constant Entity_Id := Etype (Name (N));
                  begin
                     Rewrite (Name (N), New_Occurrence_Of (Comp, Sloc (N)));
                     Set_Etype (Name (N), Typ);
                  end;
                  exit;
               end if;

               Next_Discriminant (Comp);
            end loop;
         end if;

         return OK;
      end Process;

      procedure Replace is new Traverse_Proc (Process);

   --  Start of processing for Replace_Discriminants

   begin
      Replace (Decl);
   end Replace_Discriminants;

   -------------------------------
   -- Set_Completion_Referenced --
   -------------------------------

   procedure Set_Completion_Referenced (E : Entity_Id) is
   begin
      --  If in main unit, mark entity that is a completion as referenced,
      --  warnings go on the partial view when needed.

      if In_Extended_Main_Source_Unit (E) then
         Set_Referenced (E);
      end if;
   end Set_Completion_Referenced;

   ---------------------
   -- Set_Default_SSO --
   ---------------------

   procedure Set_Default_SSO (T : Entity_Id) is
   begin
      case Opt.Default_SSO is
         when ' ' =>
            null;
         when 'L' =>
            Set_SSO_Set_Low_By_Default (T, True);
         when 'H' =>
            Set_SSO_Set_High_By_Default (T, True);
         when others =>
            raise Program_Error;
      end case;
   end Set_Default_SSO;

   ---------------------
   -- Set_Fixed_Range --
   ---------------------

   --  The range for fixed-point types is complicated by the fact that we
   --  do not know the exact end points at the time of the declaration. This
   --  is true for three reasons:

   --     A size clause may affect the fudging of the end-points.
   --     A small clause may affect the values of the end-points.
   --     We try to include the end-points if it does not affect the size.

   --  This means that the actual end-points must be established at the
   --  point when the type is frozen. Meanwhile, we first narrow the range
   --  as permitted (so that it will fit if necessary in a small specified
   --  size), and then build a range subtree with these narrowed bounds.
   --  Set_Fixed_Range constructs the range from real literal values, and
   --  sets the range as the Scalar_Range of the given fixed-point type entity.

   --  The parent of this range is set to point to the entity so that it is
   --  properly hooked into the tree (unlike normal Scalar_Range entries for
   --  other scalar types, which are just pointers to the range in the
   --  original tree, this would otherwise be an orphan).

   --  The tree is left unanalyzed. When the type is frozen, the processing
   --  in Freeze.Freeze_Fixed_Point_Type notices that the range is not
   --  analyzed, and uses this as an indication that it should complete
   --  work on the range (it will know the final small and size values).

   procedure Set_Fixed_Range
     (E   : Entity_Id;
      Loc : Source_Ptr;
      Lo  : Ureal;
      Hi  : Ureal)
   is
      S : constant Node_Id :=
            Make_Range (Loc,
              Low_Bound  => Make_Real_Literal (Loc, Lo),
              High_Bound => Make_Real_Literal (Loc, Hi));
   begin
      Set_Scalar_Range (E, S);
      Set_Parent (S, E);

      --  Before the freeze point, the bounds of a fixed point are universal
      --  and carry the corresponding type.

      Set_Etype (Low_Bound (S),  Universal_Real);
      Set_Etype (High_Bound (S), Universal_Real);
   end Set_Fixed_Range;

   ----------------------------------
   -- Set_Scalar_Range_For_Subtype --
   ----------------------------------

   procedure Set_Scalar_Range_For_Subtype
     (Def_Id : Entity_Id;
      R      : Node_Id;
      Subt   : Entity_Id)
   is
      Kind : constant Entity_Kind := Ekind (Def_Id);

   begin
      --  Defend against previous error

      if Nkind (R) = N_Error then
         return;
      end if;

      Set_Scalar_Range (Def_Id, R);

      --  We need to link the range into the tree before resolving it so
      --  that types that are referenced, including importantly the subtype
      --  itself, are properly frozen (Freeze_Expression requires that the
      --  expression be properly linked into the tree). Of course if it is
      --  already linked in, then we do not disturb the current link.

      if No (Parent (R)) then
         Set_Parent (R, Def_Id);
      end if;

      --  Reset the kind of the subtype during analysis of the range, to
      --  catch possible premature use in the bounds themselves.

      Mutate_Ekind (Def_Id, E_Void);
      Process_Range_Expr_In_Decl (R, Subt, Subtyp => Def_Id);
      Mutate_Ekind (Def_Id, Kind);
   end Set_Scalar_Range_For_Subtype;

   --------------------------------------------------------
   -- Set_Stored_Constraint_From_Discriminant_Constraint --
   --------------------------------------------------------

   procedure Set_Stored_Constraint_From_Discriminant_Constraint
     (E : Entity_Id)
   is
   begin
      --  Make sure set if encountered during Expand_To_Stored_Constraint

      Set_Stored_Constraint (E, No_Elist);

      --  Give it the right value

      if Is_Constrained (E) and then Has_Discriminants (E) then
         Set_Stored_Constraint (E,
           Expand_To_Stored_Constraint (E, Discriminant_Constraint (E)));
      end if;
   end Set_Stored_Constraint_From_Discriminant_Constraint;

   -------------------------------------
   -- Signed_Integer_Type_Declaration --
   -------------------------------------

   procedure Signed_Integer_Type_Declaration (T : Entity_Id; Def : Node_Id) is
      Implicit_Base : Entity_Id;
      Base_Typ      : Entity_Id;
      Lo_Val        : Uint;
      Hi_Val        : Uint;
      Errs          : Boolean := False;
      Lo            : Node_Id;
      Hi            : Node_Id;

      function Can_Derive_From (E : Entity_Id) return Boolean;
      --  Determine whether given bounds allow derivation from specified type

      procedure Check_Bound (Expr : Node_Id);
      --  Check bound to make sure it is integral and static. If not, post
      --  appropriate error message and set Errs flag

      ---------------------
      -- Can_Derive_From --
      ---------------------

      --  Note we check both bounds against both end values, to deal with
      --  strange types like ones with a range of 0 .. -12341234.

      function Can_Derive_From (E : Entity_Id) return Boolean is
         Lo : constant Uint := Expr_Value (Type_Low_Bound (E));
         Hi : constant Uint := Expr_Value (Type_High_Bound (E));
      begin
         return Lo <= Lo_Val and then Lo_Val <= Hi
                  and then
                Lo <= Hi_Val and then Hi_Val <= Hi;
      end Can_Derive_From;

      -----------------
      -- Check_Bound --
      -----------------

      procedure Check_Bound (Expr : Node_Id) is
      begin
         --  If a range constraint is used as an integer type definition, each
         --  bound of the range must be defined by a static expression of some
         --  integer type, but the two bounds need not have the same integer
         --  type (Negative bounds are allowed.) (RM 3.5.4)

         if not Is_Integer_Type (Etype (Expr)) then
            Error_Msg_N
              ("integer type definition bounds must be of integer type", Expr);
            Errs := True;

         elsif not Is_OK_Static_Expression (Expr) then
            Flag_Non_Static_Expr
              ("non-static expression used for integer type bound!", Expr);
            Errs := True;

         --  Otherwise the bounds are folded into literals

         elsif Is_Entity_Name (Expr) then
            Fold_Uint (Expr, Expr_Value (Expr), True);
         end if;
      end Check_Bound;

   --  Start of processing for Signed_Integer_Type_Declaration

   begin
      --  Create an anonymous base type

      Implicit_Base :=
        Create_Itype (E_Signed_Integer_Type, Parent (Def), T, 'B');

      --  Analyze and check the bounds, they can be of any integer type

      Lo := Low_Bound (Def);
      Hi := High_Bound (Def);

      --  Arbitrarily use Integer as the type if either bound had an error

      if Hi = Error or else Lo = Error then
         Base_Typ := Any_Integer;
         Set_Error_Posted (T, True);
         Errs := True;

      --  Here both bounds are OK expressions

      else
         Analyze_And_Resolve (Lo, Any_Integer);
         Analyze_And_Resolve (Hi, Any_Integer);

         Check_Bound (Lo);
         Check_Bound (Hi);

         if Errs then
            Hi := Type_High_Bound (Standard_Long_Long_Long_Integer);
            Lo := Type_Low_Bound  (Standard_Long_Long_Long_Integer);
         end if;

         --  Find type to derive from

         Lo_Val := Expr_Value (Lo);
         Hi_Val := Expr_Value (Hi);

         if Can_Derive_From (Standard_Short_Short_Integer) then
            Base_Typ := Base_Type (Standard_Short_Short_Integer);

         elsif Can_Derive_From (Standard_Short_Integer) then
            Base_Typ := Base_Type (Standard_Short_Integer);

         elsif Can_Derive_From (Standard_Integer) then
            Base_Typ := Base_Type (Standard_Integer);

         elsif Can_Derive_From (Standard_Long_Integer) then
            Base_Typ := Base_Type (Standard_Long_Integer);

         elsif Can_Derive_From (Standard_Long_Long_Integer) then
            Check_Restriction (No_Long_Long_Integers, Def);
            Base_Typ := Base_Type (Standard_Long_Long_Integer);

         elsif Can_Derive_From (Standard_Long_Long_Long_Integer) then
            Check_Restriction (No_Long_Long_Integers, Def);
            Base_Typ := Base_Type (Standard_Long_Long_Long_Integer);

         else
            Base_Typ := Base_Type (Standard_Long_Long_Long_Integer);
            Error_Msg_N ("integer type definition bounds out of range", Def);
            Hi := Type_High_Bound (Standard_Long_Long_Long_Integer);
            Lo := Type_Low_Bound  (Standard_Long_Long_Long_Integer);
         end if;
      end if;

      --  Set the type of the bounds to the implicit base: we cannot set it to
      --  the new type, because this would be a forward reference for the code
      --  generator and, if the original type is user-defined, this could even
      --  lead to spurious semantic errors. Furthermore we do not set it to be
      --  universal, because this could make it much larger than needed here.

      if not Errs then
         Set_Etype (Lo, Implicit_Base);
         Set_Etype (Hi, Implicit_Base);
      end if;

      --  Complete both implicit base and declared first subtype entities. The
      --  inheritance of the rep item chain ensures that SPARK-related pragmas
      --  are not clobbered when the signed integer type acts as a full view of
      --  a private type.

      Set_Etype          (Implicit_Base,                 Base_Typ);
      Set_Size_Info      (Implicit_Base,                 Base_Typ);
      Set_RM_Size        (Implicit_Base, RM_Size        (Base_Typ));
      Set_First_Rep_Item (Implicit_Base, First_Rep_Item (Base_Typ));
      Set_Scalar_Range   (Implicit_Base, Scalar_Range   (Base_Typ));

      Mutate_Ekind        (T, E_Signed_Integer_Subtype);
      Set_Etype              (T, Implicit_Base);
      Set_Size_Info          (T, Implicit_Base);
      Inherit_Rep_Item_Chain (T, Implicit_Base);
      Set_Scalar_Range       (T, Def);
      Set_RM_Size            (T, UI_From_Int (Minimum_Size (T)));
      Set_Is_Constrained     (T);
   end Signed_Integer_Type_Declaration;

end Sem_Ch3;
