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

with 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 Expander;       use Expander;
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_Ch10;       use Sem_Ch10;
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 Strub;          use Strub;
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;

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

      --  When possible, build the default subtype

      if Build_Default_Subtype_OK (T) 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, 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 then
         if 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.

            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;

         --  If T already has a Direct_Primitive_Operations list but its
         --  base type doesn't then set the base type's list to T's list.

         elsif not Present (Direct_Primitive_Operations (Base_Type (T))) then
            Set_Direct_Primitive_Operations
              (Base_Type (T), Direct_Primitive_Operations (T));
         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;

      --  Check for tagged type declaration at library level

      if Is_Tagged_Type (T)
        and then not Is_Library_Level_Entity (T)
      then
         Check_Restriction (No_Local_Tagged_Types, T);
      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);
      end if;

      --  Initialize the list of primitive operations to an empty list,
      --  to cover tagged types as well as untagged types. For untagged
      --  types this is used either to analyze the call as legal when
      --  Extensions_Allowed is True, or to issue a better error message
      --  otherwise.

      Set_Direct_Primitive_Operations (T, New_Elmt_List);

      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 Is_Record_Type (Etype (Comp)) then
                  Check_Dynamic_Object (Etype (Comp));

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

               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 else than Universal_Access to keep gigi happy.

         if Etype (E) = Universal_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 whose target subtype statically matches the
         --  object's subtype because the conversion has been subjected to the
         --  same check. This is a small optimization which avoids redundant
         --  checks.

         elsif Present (E)
           and then Nkind (E) in N_Type_Conversion
           and then Subtypes_Statically_Match (Etype (Subtype_Mark (E)), T)
         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;

      --  When possible, build the default subtype

      elsif Build_Default_Subtype_OK (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 on the secondary
      --  stack, 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.
      --  ??? To be moved to Expand_N_Object_Declaration.Rewrite_As_Renaming.

      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_Aliased (Id)
        and then Needs_Secondary_Stack (T)
        and then not Is_Class_Wide_Type (T)
        and then not Needs_Finalization (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 that 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);
               Set_Packed_Array_Impl_Type    (Id, Packed_Array_Impl_Type (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));
                  end if;

                  --  For tagged types, or when prefixed-call syntax is allowed
                  --  for untagged types, initialize the list of primitive
                  --  operations to an empty list.

                  if Is_Tagged_Type (Id)
                    or else Extensions_Allowed
                  then
                     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;

      if Etype (Id) = Any_Type then
         goto Leave;
      end if;

      --  When prefixed calls are enabled for untagged types, the subtype
      --  shares the primitive operations of its base type. Do this even
      --  when Extensions_Allowed is False to issue better error messages.

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

      --  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 Present (Subprograms_For_Type (Full_View (T)))
         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 :=
              Underlying_Type (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
         Set_Error_Posted (R);
         Set_Error_Posted (T);
      else
         Analyze (R);
         Set_Etype (N, Etype (R));
         Resolve (R, Entity (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
         Append_Freeze_Action (Id, 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 := Empty;
      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
            --  Initialize the list of primitive operations to an empty list,
            --  to cover tagged types as well as untagged types. For untagged
            --  types this is used either to analyze the call as legal when
            --  Extensions_Allowed is True, or to issue a better error message
            --  otherwise.

            Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);

            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
            Iface := First (Interface_List (Type_Def));
            while Present (Iface) loop
               Freeze_Before (N, Etype (Iface));
               Next (Iface);
            end loop;
         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;

      --  Initialize the list of primitive operations to an empty list,
      --  to cover tagged types as well as untagged types. For untagged
      --  types this is used either to analyze the call as legal when
      --  Extensions_Allowed is True, or to issue a better error message
      --  otherwise.

      Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);

      --  Set fields for tagged types

      if Is_Tagged then
         --  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);

         --  If the parent type is untagged, then no overriding error checks
         --  are needed (such as in the case of an implicit full type for
         --  a derived type whose parent is an untagged private type with
         --  a tagged full type).

         if not Is_Tagged_Type (Etype (T)) then
            null;

         --  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).

         elsif 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 (Homonym (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);
            Set_Incomplete_View (Typ_Decl, Inc_T);

            --  If the type is tagged, create a common class-wide type for
            --  both views, and set the Etype of the class-wide type to the
            --  full view.

            if Is_Tagged then
               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;

            --  If the scope is a package with a limited view, create a shadow
            --  entity for the incomplete type like Build_Limited_Views, so as
            --  to make it possible for Remove_Limited_With_Unit to reinstall
            --  this incomplete type as the visible entity.

            if Ekind (Scope (Inc_T)) = E_Package
              and then Present (Limited_View (Scope (Inc_T)))
            then
               declare
                  Shadow : constant Entity_Id := Make_Temporary (Loc, 'Z');

               begin
                  --  This is modeled on Build_Shadow_Entity

                  Set_Chars              (Shadow, Chars (Inc_T));
                  Set_Parent             (Shadow, Decl);
                  Decorate_Type          (Shadow, Scope (Inc_T), Is_Tagged);
                  Set_Is_Internal        (Shadow);
                  Set_From_Limited_With  (Shadow);
                  Set_Non_Limited_View   (Shadow, Inc_T);
                  Set_Private_Dependents (Shadow, New_Elmt_List);

                  if Is_Tagged then
                     Set_Non_Limited_View
                       (Class_Wide_Type (Shadow), Class_Wide_Type (Inc_T));
                  end if;

                  Append_Entity (Shadow, Limited_View (Scope (Inc_T)));
               end;
            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;
      Constraint_OK : Boolean := True;

   begin
      if Is_Array_Type (Desig_Type) then
         Desig_Subtype := Create_Itype (E_Void, Related_Nod);
         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;

         Desig_Subtype := Create_Itype (E_Void, Related_Nod);
         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
         Desig_Subtype := Create_Itype (E_Void, Related_Nod);
         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));
      Set_Can_Never_Be_Null        (Def_Id, Can_Never_Be_Null (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;

      T := Underlying_Type (T);

      --  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 New_Copy_Tree (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 New_Copy_Tree (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 --
   -----------------------------------

   --  Note that we used to copy Packed_Array_Impl_Type too here, but we now
   --  let it be recreated during freezing for the sake of better debug info.

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

      Copy_Strub_Mode (New_Subp, Alias (New_Subp));

      --  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));
         Set_Returns_By_Ref (New_Subp, Returns_By_Ref (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;
         Derived_Elmt : Elmt_Id;
         Derived_Op   : Entity_Id;
         Derived_Ops  : Elist_Id;
         Parent_Elmt  : Elmt_Id;
         Parent_Op    : 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;

         Derived_Ops := Collect_Primitive_Operations (Derived_Type);

         Derived_Elmt := First_Elmt (Derived_Ops);
         Parent_Elmt  := First_Elmt (Op_List);
         while Present (Parent_Elmt) loop
            Parent_Op  := Node (Parent_Elmt);
            Derived_Op := Node (Derived_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 (Parent_Op));

            --  Handle hidden entities

            if not Is_Predefined_Dispatching_Operation (Parent_Op)
              and then Is_Hidden (Parent_Op)
            then
               if Present (Derived_Op)
                 and then Primitive_Names_Match (Parent_Op, Derived_Op)
               then
                  Next_Elmt (Derived_Elmt);
               end if;

            else
               if No (Derived_Op)
                 or else Ekind (Parent_Op) /= Ekind (Derived_Op)
                 or else not Primitive_Names_Match (Parent_Op, Derived_Op)
               then
                  return False;
               end if;

               Next_Elmt (Derived_Elmt);
            end if;

            Next_Elmt (Parent_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));

         --  Initialize the list of primitive operations to an empty list,
         --  to cover tagged types as well as untagged types. For untagged
         --  types this is used either to analyze the call as legal when
         --  Extensions_Allowed is True, or to issue a better error message
         --  otherwise.

         Set_Direct_Primitive_Operations (T, New_Elmt_List);

         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
            Partial_View        : Entity_Id;
            Partial_View_Parent : Entity_Id;

            function Reorder_Interfaces return Boolean;
            --  Look for an interface in the full view's interface list that
            --  matches the parent type of the partial view, and when found,
            --  rewrite the full view's parent with the partial view's parent,
            --  append the full view's original parent to the interface list,
            --  recursively call Derived_Type_Definition on the full type, and
            --  return True. If a match is not found, return False.

            ------------------------
            -- Reorder_Interfaces --
            ------------------------

            function Reorder_Interfaces return Boolean is
               Iface     : Node_Id;
               New_Iface : Node_Id;

            begin
               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));
                     Rewrite (Iface, New_Iface);

                     --  Analyze the transformed code

                     Derived_Type_Declaration (T, N, Is_Completion);
                     return True;
                  end if;

                  Next (Iface);
               end loop;
               return False;
            end Reorder_Interfaces;

         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 reorder the
               --  interfaces to match the order in the partial view,
               --  if needed.

               else

                  if Reorder_Interfaces then
                     --  Having the interfaces listed in any order is legal.
                     --  However, the compiler does not properly handle
                     --  different orders between partial and full views in
                     --  generic units. We give a warning about the order
                     --  mismatch, so the user can work around this problem.

                     Error_Msg_N ("??full declaration does not respect " &
                                  "partial declaration order", T);
                     Error_Msg_N ("\??consider reordering", T);

                     return;
                  end if;
               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 corresponding 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;
                --  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).

                (if Is_Rewrite_Substitution (Exp)
                 then OK_For_Limited_Init_In_05 (Typ, Original_Node (Exp))
                 else 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;

   --  ??? The variant below explicitly saves and restores all the flags,
   --  because it is impossible to compose the existing variety of
   --  Analyze/Resolve (and their wrappers, e.g. Preanalyze_Spec_Expression)
   --  to achieve the desired semantics.

   procedure Preanalyze_Assert_Expression (N : Node_Id) is
      Save_In_Spec_Expression : constant Boolean := In_Spec_Expression;
      Save_Must_Not_Freeze    : constant Boolean := Must_Not_Freeze (N);
      Save_Full_Analysis      : constant Boolean := Full_Analysis;

   begin
      In_Assertion_Expr  := In_Assertion_Expr + 1;
      In_Spec_Expression := True;
      Set_Must_Not_Freeze (N);
      Inside_Preanalysis_Without_Freezing :=
        Inside_Preanalysis_Without_Freezing + 1;
      Full_Analysis      := False;
      Expander_Mode_Save_And_Set (False);

      if GNATprove_Mode then
         Analyze_And_Resolve (N);
      else
         Analyze_And_Resolve (N, Suppress => All_Checks);
      end if;

      Expander_Mode_Restore;
      Full_Analysis      := Save_Full_Analysis;
      Inside_Preanalysis_Without_Freezing :=
        Inside_Preanalysis_Without_Freezing - 1;
      Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);
      In_Spec_Expression := Save_In_Spec_Expression;
      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 Is_Rewrite_Substitution (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, for support of prefixed calls when
         --  extensions are enabled, and better error messages otherwise.

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