------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ C H 1 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 Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Exp_Disp;       use Exp_Disp;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Ghost;          use Ghost;
with 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 Par_SCO;        use Par_SCO;
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_Ch3;        use Sem_Ch3;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch7;        use Sem_Ch7;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Dim;        use Sem_Dim;
with Sem_Eval;       use Sem_Eval;
with Sem_Prag;       use Sem_Prag;
with Sem_Res;        use Sem_Res;
with Sem_Type;       use Sem_Type;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
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 Stand;          use Stand;
with Table;
with Targparm;       use Targparm;
with Ttypes;         use Ttypes;
with Tbuild;         use Tbuild;
with Urealp;         use Urealp;
with Warnsw;         use Warnsw;

with GNAT.Heap_Sort_G;

package body Sem_Ch13 is

   SSU : constant Pos := System_Storage_Unit;
   --  Convenient short hand for commonly used constant

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

   procedure Adjust_Record_For_Reverse_Bit_Order_Ada_95 (R : Entity_Id);
   --  Helper routine providing the original (pre-AI95-0133) behavior for
   --  Adjust_Record_For_Reverse_Bit_Order.

   procedure Alignment_Check_For_Size_Change (Typ : Entity_Id; Size : Uint);
   --  This routine is called after setting one of the sizes of type entity
   --  Typ to Size. The purpose is to deal with the situation of a derived
   --  type whose inherited alignment is no longer appropriate for the new
   --  size value. In this case, we reset the Alignment to unknown.

   function All_Static_Choices (L : List_Id) return Boolean;
   --  Returns true if all elements of the list are OK static choices
   --  as defined below for Is_Static_Choice. Used for case expression
   --  alternatives and for the right operand of a membership test. An
   --  others_choice is static if the corresponding expression is static.
   --  The staticness of the bounds is checked separately.

   procedure Build_Discrete_Static_Predicate
     (Typ  : Entity_Id;
      Expr : Node_Id;
      Nam  : Name_Id);
   --  Given a predicated type Typ, where Typ is a discrete static subtype,
   --  whose predicate expression is Expr, tests if Expr is a static predicate,
   --  and if so, builds the predicate range list. Nam is the name of the one
   --  argument to the predicate function. Occurrences of the type name in the
   --  predicate expression have been replaced by identifier references to this
   --  name, which is unique, so any identifier with Chars matching Nam must be
   --  a reference to the type. If the predicate is non-static, this procedure
   --  returns doing nothing. If the predicate is static, then the predicate
   --  list is stored in Static_Discrete_Predicate (Typ), and the Expr is
   --  rewritten as a canonicalized membership operation.

   function Build_Export_Import_Pragma
     (Asp : Node_Id;
      Id  : Entity_Id) return Node_Id;
   --  Create the corresponding pragma for aspect Export or Import denoted by
   --  Asp. Id is the related entity subject to the aspect. Return Empty when
   --  the expression of aspect Asp evaluates to False or is erroneous.

   function Build_Predicate_Function_Declaration
      (Typ : Entity_Id) return Node_Id;
   --  Build the declaration for a predicate function. The declaration is built
   --  at the end of the declarative part containing the type definition, which
   --  may be before the freeze point of the type. The predicate expression is
   --  preanalyzed at this point, to catch visibility errors.

   procedure Build_Predicate_Functions (Typ : Entity_Id; N : Node_Id);
   --  If Typ has predicates (indicated by Has_Predicates being set for Typ),
   --  then either there are pragma Predicate entries on the rep chain for the
   --  type (note that Predicate aspects are converted to pragma Predicate), or
   --  there are inherited aspects from a parent type, or ancestor subtypes.
   --  This procedure builds body for the Predicate function that tests these
   --  predicates. N is the freeze node for the type. The spec of the function
   --  is inserted before the freeze node, and the body of the function is
   --  inserted after the freeze node. If the predicate expression has a least
   --  one Raise_Expression, then this procedure also builds the M version of
   --  the predicate function for use in membership tests.

   procedure Check_Pool_Size_Clash (Ent : Entity_Id; SP, SS : Node_Id);
   --  Called if both Storage_Pool and Storage_Size attribute definition
   --  clauses (SP and SS) are present for entity Ent. Issue error message.

   procedure Freeze_Entity_Checks (N : Node_Id);
   --  Called from Analyze_Freeze_Entity and Analyze_Generic_Freeze Entity
   --  to generate appropriate semantic checks that are delayed until this
   --  point (they had to be delayed this long for cases of delayed aspects,
   --  e.g. analysis of statically predicated subtypes in choices, for which
   --  we have to be sure the subtypes in question are frozen before checking).

   function Get_Alignment_Value (Expr : Node_Id) return Uint;
   --  Given the expression for an alignment value, returns the corresponding
   --  Uint value. If the value is inappropriate, then error messages are
   --  posted as required, and a value of No_Uint is returned.

   function Is_Operational_Item (N : Node_Id) return Boolean;
   --  A specification for a stream attribute is allowed before the full type
   --  is declared, as explained in AI-00137 and the corrigendum. Attributes
   --  that do not specify a representation characteristic are operational
   --  attributes.

   function Is_Static_Choice (N : Node_Id) return Boolean;
   --  Returns True if N represents a static choice (static subtype, or
   --  static subtype indication, or static expression, or static range).
   --
   --  Note that this is a bit more inclusive than we actually need
   --  (in particular membership tests do not allow the use of subtype
   --  indications). But that doesn't matter, we have already checked
   --  that the construct is legal to get this far.

   function Is_Type_Related_Rep_Item (N : Node_Id) return Boolean;
   --  Returns True for a representation clause/pragma that specifies a
   --  type-related representation (as opposed to operational) aspect.

   function Is_Predicate_Static
     (Expr : Node_Id;
      Nam  : Name_Id) return Boolean;
   --  Given predicate expression Expr, tests if Expr is predicate-static in
   --  the sense of the rules in (RM 3.2.4 (15-24)). Occurrences of the type
   --  name in the predicate expression have been replaced by references to
   --  an identifier whose Chars field is Nam. This name is unique, so any
   --  identifier with Chars matching Nam must be a reference to the type.
   --  Returns True if the expression is predicate-static and False otherwise,
   --  but is not in the business of setting flags or issuing error messages.
   --
   --  Only scalar types can have static predicates, so False is always
   --  returned for non-scalar types.
   --
   --  Note: the RM seems to suggest that string types can also have static
   --  predicates. But that really makes lttle sense as very few useful
   --  predicates can be constructed for strings. Remember that:
   --
   --     "ABC" < "DEF"
   --
   --  is not a static expression. So even though the clearly faulty RM wording
   --  allows the following:
   --
   --     subtype S is String with Static_Predicate => S < "DEF"
   --
   --  We can't allow this, otherwise we have predicate-static applying to a
   --  larger class than static expressions, which was never intended.

   procedure New_Put_Image_Subprogram
     (N    : Node_Id;
      Ent  : Entity_Id;
      Subp : Entity_Id);
   --  Similar to New_Stream_Subprogram, but for the Put_Image attribute

   procedure New_Stream_Subprogram
     (N    : Node_Id;
      Ent  : Entity_Id;
      Subp : Entity_Id;
      Nam  : TSS_Name_Type);
   --  Create a subprogram renaming of a given stream attribute to the
   --  designated subprogram and then in the tagged case, provide this as a
   --  primitive operation, or in the untagged case make an appropriate TSS
   --  entry. This is more properly an expansion activity than just semantics,
   --  but the presence of user-defined stream functions for limited types
   --  is a legality check, which is why this takes place here rather than in
   --  exp_ch13, where it was previously. Nam indicates the name of the TSS
   --  function to be generated.
   --
   --  To avoid elaboration anomalies with freeze nodes, for untagged types
   --  we generate both a subprogram declaration and a subprogram renaming
   --  declaration, so that the attribute specification is handled as a
   --  renaming_as_body. For tagged types, the specification is one of the
   --  primitive specs.

   procedure No_Type_Rep_Item (N : Node_Id);
   --  Output message indicating that no type-related aspects can be
   --  specified due to some property of the parent type.

   procedure Register_Address_Clause_Check
     (N   : Node_Id;
      X   : Entity_Id;
      A   : Uint;
      Y   : Entity_Id;
      Off : Boolean);
   --  Register a check for the address clause N. The rest of the parameters
   --  are in keeping with the components of Address_Clause_Check_Record below.

   procedure Validate_Aspect_Aggregate (N : Node_Id);
   --  Check legality of operations given in the Ada 2022 Aggregate aspect for
   --  containers.

   procedure Resolve_Aspect_Aggregate
    (Typ  : Entity_Id;
     Expr : Node_Id);
   --  Resolve each one of the operations specified in the specification of
   --  Aspect_Aggregate.

   procedure Validate_Aspect_Stable_Properties
     (E : Entity_Id; N : Node_Id; Class_Present : Boolean);
   --  Check legality of functions given in the Ada 2022 Stable_Properties
   --  (or Stable_Properties'Class) aspect.

   procedure Validate_Storage_Model_Type_Aspect
     (Typ : Entity_Id; ASN : Node_Id);
   --  Check legality and completeness of the aggregate associations given in
   --  the Storage_Model_Type aspect associated with Typ.

   procedure Resolve_Storage_Model_Type_Argument
     (N         : Node_Id;
      Typ       : Entity_Id;
      Addr_Type : in out Entity_Id;
      Nam       : Name_Id);
   --  Resolve argument N to be of the proper kind (when a type or constant)
   --  or to have the proper profile (when a subprogram).

   procedure Resolve_Aspect_Stable_Properties
    (Typ_Or_Subp   : Entity_Id;
     Expr          : Node_Id;
     Class_Present : Boolean);
   --  Resolve each one of the functions specified in the specification of
   --  aspect Stable_Properties (or Stable_Properties'Class).

   procedure Resolve_Iterable_Operation
     (N      : Node_Id;
      Cursor : Entity_Id;
      Typ    : Entity_Id;
      Nam    : Name_Id);
   --  If the name of a primitive operation for an Iterable aspect is
   --  overloaded, resolve according to required signature.

   procedure Set_Biased
     (E      : Entity_Id;
      N      : Node_Id;
      Msg    : String;
      Biased : Boolean := True);
   --  If Biased is True, sets Has_Biased_Representation flag for E, and
   --  outputs a warning message at node N if Warn_On_Biased_Representation is
   --  is True. This warning inserts the string Msg to describe the construct
   --  causing biasing.

   -----------------------------------------------------------
   --  Visibility of Discriminants in Aspect Specifications --
   -----------------------------------------------------------

   --  The discriminants of a type are visible when analyzing the aspect
   --  specifications of a type declaration or protected type declaration,
   --  but not when analyzing those of a subtype declaration. The following
   --  routines enforce this distinction.

   procedure Push_Type (E : Entity_Id);
   --  Push scope E and make visible the discriminants of type entity E if E
   --  has discriminants and is not a subtype.

   procedure Pop_Type (E : Entity_Id);
   --  Remove visibility to the discriminants of type entity E and pop the
   --  scope stack if E has discriminants and is not a subtype.

   ----------------------------------------------
   -- Table for Validate_Unchecked_Conversions --
   ----------------------------------------------

   --  The following table collects unchecked conversions for validation.
   --  Entries are made by Validate_Unchecked_Conversion and then the call
   --  to Validate_Unchecked_Conversions does the actual error checking and
   --  posting of warnings. The reason for this delayed processing is to take
   --  advantage of back-annotations of size and alignment values performed by
   --  the back end.

   --  Note: the reason we store a Source_Ptr value instead of a Node_Id is
   --  that by the time Validate_Unchecked_Conversions is called, Sprint will
   --  already have modified all Sloc values if the -gnatD option is set.

   type UC_Entry is record
      Eloc     : Source_Ptr; -- node used for posting warnings
      Source   : Entity_Id;  -- source type for unchecked conversion
      Target   : Entity_Id;  -- target type for unchecked conversion
      Act_Unit : Entity_Id;  -- actual function instantiated
   end record;

   package Unchecked_Conversions is new Table.Table (
     Table_Component_Type => UC_Entry,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 1,
     Table_Initial        => 50,
     Table_Increment      => 200,
     Table_Name           => "Unchecked_Conversions");

   ----------------------------------------
   -- Table for Validate_Address_Clauses --
   ----------------------------------------

   --  If an address clause has the form

   --    for X'Address use Expr

   --  where Expr has a value known at compile time or is of the form Y'Address
   --  or recursively is a reference to a constant initialized with either of
   --  these forms, and the value of Expr is not a multiple of X's alignment,
   --  or if Y has a smaller alignment than X, then that merits a warning about
   --  possible bad alignment. The following table collects address clauses of
   --  this kind. We put these in a table so that they can be checked after the
   --  back end has completed annotation of the alignments of objects, since we
   --  can catch more cases that way.

   type Address_Clause_Check_Record is record
      N : Node_Id;
      --  The address clause

      X : Entity_Id;
      --  The entity of the object subject to the address clause

      A : Uint;
      --  The value of the address in the first case

      Y : Entity_Id;
      --  The entity of the object being overlaid in the second case

      Off : Boolean;
      --  Whether the address is offset within Y in the second case

      Alignment_Checks_Suppressed : Boolean;
      --  Whether alignment checks are suppressed by an active scope suppress
      --  setting. We need to save the value in order to be able to reuse it
      --  after the back end has been run.
   end record;

   package Address_Clause_Checks is new Table.Table (
     Table_Component_Type => Address_Clause_Check_Record,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 200,
     Table_Name           => "Address_Clause_Checks");

   function Alignment_Checks_Suppressed
     (ACCR : Address_Clause_Check_Record) return Boolean;
   --  Return whether the alignment check generated for the address clause
   --  is suppressed.

   ---------------------------------
   -- Alignment_Checks_Suppressed --
   ---------------------------------

   function Alignment_Checks_Suppressed
     (ACCR : Address_Clause_Check_Record) return Boolean
   is
   begin
      if Checks_May_Be_Suppressed (ACCR.X) then
         return Is_Check_Suppressed (ACCR.X, Alignment_Check);
      else
         return ACCR.Alignment_Checks_Suppressed;
      end if;
   end Alignment_Checks_Suppressed;

   -----------------------------------------
   -- Adjust_Record_For_Reverse_Bit_Order --
   -----------------------------------------

   procedure Adjust_Record_For_Reverse_Bit_Order (R : Entity_Id) is
      Max_Machine_Scalar_Size : constant Uint :=
                                  UI_From_Int (System_Max_Integer_Size);
      --  We use this as the maximum machine scalar size

      SSU : constant Uint := UI_From_Int (System_Storage_Unit);

      CC     : Node_Id;
      Comp   : Node_Id;
      Num_CC : Natural;

   begin
      --  The processing done here used to depend on the Ada version, but the
      --  behavior has been changed by AI95-0133. However this AI is a Binding
      --  Interpretation, so we now implement it even in Ada 95 mode. But the
      --  original behavior from unamended Ada 95 is available for the sake of
      --  compatibility under the debugging switch -gnatd.p in Ada 95 mode.

      if Ada_Version < Ada_2005 and then Debug_Flag_Dot_P then
         Adjust_Record_For_Reverse_Bit_Order_Ada_95 (R);
         return;
      end if;

      --  For Ada 2005, we do machine scalar processing, as fully described In
      --  AI-133. This involves gathering all components which start at the
      --  same byte offset and processing them together. Same approach is still
      --  valid in later versions including Ada 2012.

      --  Note that component clauses found on record types may be inherited,
      --  in which case the layout of the component with such a clause still
      --  has to be done at this point. Therefore, the processing done here
      --  must exclusively rely on the Component_Clause of the component.

      --  This first loop through components does two things. First it deals
      --  with the case of components with component clauses whose length is
      --  greater than the maximum machine scalar size (either accepting them
      --  or rejecting as needed). Second, it counts the number of components
      --  with component clauses whose length does not exceed this maximum for
      --  later processing.

      Num_CC := 0;
      Comp   := First_Component_Or_Discriminant (R);
      while Present (Comp) loop
         CC := Component_Clause (Comp);

         if Present (CC) then
            declare
               Fbit : constant Uint := Static_Integer (First_Bit (CC));
               Lbit : constant Uint := Static_Integer (Last_Bit (CC));

            begin
               --  Case of component with last bit >= max machine scalar

               if Lbit >= Max_Machine_Scalar_Size then

                  --  This is allowed only if first bit is zero, and last bit
                  --  + 1 is a multiple of storage unit size.

                  if Fbit = 0 and then (Lbit + 1) mod SSU = 0 then

                     --  This is the case to give a warning if enabled

                     if Warn_On_Reverse_Bit_Order then
                        Error_Msg_N
                          ("info: multi-byte field specified with "
                           & "non-standard Bit_Order?.v?", CC);

                        if Bytes_Big_Endian then
                           Error_Msg_N
                             ("\bytes are not reversed "
                              & "(component is big-endian)?.v?", CC);
                        else
                           Error_Msg_N
                             ("\bytes are not reversed "
                              & "(component is little-endian)?.v?", CC);
                        end if;
                     end if;

                  --  Give error message for RM 13.5.1(10) violation

                  else
                     Error_Msg_FE
                       ("machine scalar rules not followed for&",
                        First_Bit (CC), Comp);

                     Error_Msg_Uint_1 := Lbit + 1;
                     Error_Msg_Uint_2 := Max_Machine_Scalar_Size;
                     Error_Msg_F
                       ("\last bit + 1 (^) exceeds maximum machine scalar "
                        & "size (^)", First_Bit (CC));

                     if (Lbit + 1) mod SSU /= 0 then
                        Error_Msg_Uint_1 := SSU;
                        Error_Msg_F
                          ("\and is not a multiple of Storage_Unit (^) "
                           & "(RM 13.5.1(10))", First_Bit (CC));

                     else
                        Error_Msg_Uint_1 := Fbit;
                        Error_Msg_F
                          ("\and first bit (^) is non-zero "
                           & "(RM 13.4.1(10))", First_Bit (CC));
                     end if;
                  end if;

               --  OK case of machine scalar related component clause. For now,
               --  just count them.

               else
                  Num_CC := Num_CC + 1;
               end if;
            end;
         end if;

         Next_Component_Or_Discriminant (Comp);
      end loop;

      --  We need to sort the component clauses on the basis of the Position
      --  values in the clause, so we can group clauses with the same Position
      --  together to determine the relevant machine scalar size.

      Sort_CC : declare
         Comps : array (0 .. Num_CC) of Entity_Id;
         --  Array to collect component and discriminant entities. The data
         --  starts at index 1, the 0'th entry is for the sort routine.

         function CP_Lt (Op1, Op2 : Natural) return Boolean;
         --  Compare routine for Sort

         procedure CP_Move (From : Natural; To : Natural);
         --  Move routine for Sort

         package Sorting is new GNAT.Heap_Sort_G (CP_Move, CP_Lt);

         MaxL : Uint;
         --  Maximum last bit value of any component in this set

         MSS : Uint;
         --  Corresponding machine scalar size

         Start : Natural;
         Stop  : Natural;
         --  Start and stop positions in the component list of the set of
         --  components with the same starting position (that constitute
         --  components in a single machine scalar).

         -----------
         -- CP_Lt --
         -----------

         function CP_Lt (Op1, Op2 : Natural) return Boolean is
         begin
            return
              Position (Component_Clause (Comps (Op1))) <
              Position (Component_Clause (Comps (Op2)));
         end CP_Lt;

         -------------
         -- CP_Move --
         -------------

         procedure CP_Move (From : Natural; To : Natural) is
         begin
            Comps (To) := Comps (From);
         end CP_Move;

      --  Start of processing for Sort_CC

      begin
         --  Collect the machine scalar relevant component clauses

         Num_CC := 0;
         Comp   := First_Component_Or_Discriminant (R);
         while Present (Comp) loop
            declare
               CC : constant Node_Id := Component_Clause (Comp);

            begin
               --  Collect only component clauses whose last bit is less than
               --  machine scalar size. Any component clause whose last bit
               --  exceeds this value does not take part in machine scalar
               --  layout considerations. The test for Error_Posted makes sure
               --  we exclude component clauses for which we already posted an
               --  error.

               if Present (CC)
                 and then not Error_Posted (Last_Bit (CC))
                 and then Static_Integer (Last_Bit (CC)) <
                                              Max_Machine_Scalar_Size
               then
                  Num_CC := Num_CC + 1;
                  Comps (Num_CC) := Comp;
               end if;
            end;

            Next_Component_Or_Discriminant (Comp);
         end loop;

         --  Sort by ascending position number

         Sorting.Sort (Num_CC);

         --  We now have all the components whose size does not exceed the max
         --  machine scalar value, sorted by starting position. In this loop we
         --  gather groups of clauses starting at the same position, to process
         --  them in accordance with AI-133.

         Stop := 0;
         while Stop < Num_CC loop
            Start := Stop + 1;
            Stop  := Start;
            MaxL  :=
              Static_Integer
                (Last_Bit (Component_Clause (Comps (Start))));
            while Stop < Num_CC loop
               if Static_Integer
                    (Position (Component_Clause (Comps (Stop + 1)))) =
                  Static_Integer
                    (Position (Component_Clause (Comps (Stop))))
               then
                  Stop := Stop + 1;
                  MaxL :=
                    UI_Max
                      (MaxL,
                       Static_Integer
                         (Last_Bit
                            (Component_Clause (Comps (Stop)))));
               else
                  exit;
               end if;
            end loop;

            --  Now we have a group of component clauses from Start to Stop
            --  whose positions are identical, and MaxL is the maximum last
            --  bit value of any of these components.

            --  We need to determine the corresponding machine scalar size.
            --  This loop assumes that machine scalar sizes are even, and that
            --  each possible machine scalar has twice as many bits as the next
            --  smaller one.

            MSS := Max_Machine_Scalar_Size;
            while MSS mod 2 = 0
              and then (MSS / 2) >= SSU
              and then (MSS / 2) > MaxL
            loop
               MSS := MSS / 2;
            end loop;

            --  Here is where we fix up the Component_Bit_Offset value to
            --  account for the reverse bit order. Some examples of what needs
            --  to be done for the case of a machine scalar size of 8 are:

            --    First_Bit .. Last_Bit     Component_Bit_Offset
            --      old          new          old       new

            --     0 .. 0       7 .. 7         0         7
            --     0 .. 1       6 .. 7         0         6
            --     0 .. 2       5 .. 7         0         5
            --     0 .. 7       0 .. 7         0         4

            --     1 .. 1       6 .. 6         1         6
            --     1 .. 4       3 .. 6         1         3
            --     4 .. 7       0 .. 3         4         0

            --  The rule is that the first bit is obtained by subtracting the
            --  old ending bit from machine scalar size - 1.

            for C in Start .. Stop loop
               declare
                  Comp : constant Entity_Id := Comps (C);
                  CC   : constant Node_Id   := Component_Clause (Comp);

                  FB   : constant Uint := Static_Integer (First_Bit (CC));
                  LB   : constant Uint := Static_Integer (Last_Bit (CC));
                  NFB  : constant Uint := MSS - 1 - LB;
                  NLB  : constant Uint := NFB + LB - FB;
                  Pos  : constant Uint := Static_Integer (Position (CC));

               begin
                  --  Do not warn for the artificial clause built for the tag
                  --  in Check_Record_Representation_Clause if it is inherited.

                  if Warn_On_Reverse_Bit_Order
                    and then Chars (Comp) /= Name_uTag
                  then
                     Error_Msg_Uint_1 := MSS;
                     Error_Msg_N
                       ("info: reverse bit order in machine scalar of "
                        & "length^?.v?", First_Bit (CC));
                     Error_Msg_Uint_1 := NFB;
                     Error_Msg_Uint_2 := NLB;

                     if Bytes_Big_Endian then
                        Error_Msg_NE
                          ("\big-endian range for component & is ^ .. ^?.v?",
                           First_Bit (CC), Comp);
                     else
                        Error_Msg_NE
                          ("\little-endian range for component " &
                           "& is ^ .. ^?.v?",
                           First_Bit (CC), Comp);
                     end if;
                  end if;

                  Set_Component_Bit_Offset (Comp, Pos * SSU + NFB);
                  Set_Esize                (Comp, 1 + (NLB - NFB));
                  Set_Normalized_First_Bit (Comp, NFB mod SSU);
                  Set_Normalized_Position  (Comp, Pos + NFB / SSU);
               end;
            end loop;
         end loop;
      end Sort_CC;
   end Adjust_Record_For_Reverse_Bit_Order;

   ------------------------------------------------
   -- Adjust_Record_For_Reverse_Bit_Order_Ada_95 --
   ------------------------------------------------

   procedure Adjust_Record_For_Reverse_Bit_Order_Ada_95 (R : Entity_Id) is
      CC   : Node_Id;
      Comp : Node_Id;

   begin
      --  For Ada 95, we just renumber bits within a storage unit. We do the
      --  same for Ada 83 mode, since we recognize the Bit_Order attribute in
      --  Ada 83, and are free to add this extension.

      Comp := First_Component_Or_Discriminant (R);
      while Present (Comp) loop
         CC := Component_Clause (Comp);

         --  If component clause is present, then deal with the non-default
         --  bit order case for Ada 95 mode.

         --  We only do this processing for the base type, and in fact that
         --  is important, since otherwise if there are record subtypes, we
         --  could reverse the bits once for each subtype, which is wrong.

         if Present (CC) and then Ekind (R) = E_Record_Type then
            declare
               CFB : constant Uint    := Component_Bit_Offset (Comp);
               CSZ : constant Uint    := Esize (Comp);
               CLC : constant Node_Id := Component_Clause (Comp);
               Pos : constant Node_Id := Position (CLC);
               FB  : constant Node_Id := First_Bit (CLC);

               Storage_Unit_Offset : constant Uint :=
                                       CFB / System_Storage_Unit;

               Start_Bit : constant Uint :=
                             CFB mod System_Storage_Unit;

            begin
               --  Cases where field goes over storage unit boundary

               if Start_Bit + CSZ > System_Storage_Unit then

                  --  Allow multi-byte field but generate warning

                  if Start_Bit mod System_Storage_Unit = 0
                    and then CSZ mod System_Storage_Unit = 0
                  then
                     Error_Msg_N
                       ("info: multi-byte field specified with non-standard "
                        & "Bit_Order?.v?", CLC);

                     if Bytes_Big_Endian then
                        Error_Msg_N
                          ("\bytes are not reversed "
                           & "(component is big-endian)?.v?", CLC);
                     else
                        Error_Msg_N
                          ("\bytes are not reversed "
                           & "(component is little-endian)?.v?", CLC);
                     end if;

                  --  Do not allow non-contiguous field

                  else
                     Error_Msg_N
                       ("attempt to specify non-contiguous field not "
                        & "permitted", CLC);
                     Error_Msg_N
                       ("\caused by non-standard Bit_Order specified in "
                        & "legacy Ada 95 mode", CLC);
                  end if;

               --  Case where field fits in one storage unit

               else
                  --  Give warning if suspicious component clause

                  if Intval (FB) >= System_Storage_Unit
                    and then Warn_On_Reverse_Bit_Order
                  then
                     Error_Msg_N
                       ("info: Bit_Order clause does not affect byte "
                        & "ordering?.v?", Pos);
                     Error_Msg_Uint_1 :=
                       Intval (Pos) + Intval (FB) /
                       System_Storage_Unit;
                     Error_Msg_N
                       ("info: position normalized to ^ before bit order "
                        & "interpreted?.v?", Pos);
                  end if;

                  --  Here is where we fix up the Component_Bit_Offset value
                  --  to account for the reverse bit order. Some examples of
                  --  what needs to be done are:

                  --    First_Bit .. Last_Bit     Component_Bit_Offset
                  --      old          new          old       new

                  --     0 .. 0       7 .. 7         0         7
                  --     0 .. 1       6 .. 7         0         6
                  --     0 .. 2       5 .. 7         0         5
                  --     0 .. 7       0 .. 7         0         4

                  --     1 .. 1       6 .. 6         1         6
                  --     1 .. 4       3 .. 6         1         3
                  --     4 .. 7       0 .. 3         4         0

                  --  The rule is that the first bit is obtained by subtracting
                  --  the old ending bit from storage_unit - 1.

                  Set_Component_Bit_Offset (Comp,
                    (Storage_Unit_Offset * System_Storage_Unit) +
                      (System_Storage_Unit - 1) -
                      (Start_Bit + CSZ - 1));

                  Set_Normalized_Position (Comp,
                    Component_Bit_Offset (Comp) / System_Storage_Unit);

                  Set_Normalized_First_Bit (Comp,
                    Component_Bit_Offset (Comp) mod System_Storage_Unit);
               end if;
            end;
         end if;

         Next_Component_Or_Discriminant (Comp);
      end loop;
   end Adjust_Record_For_Reverse_Bit_Order_Ada_95;

   -------------------------------------
   -- Alignment_Check_For_Size_Change --
   -------------------------------------

   procedure Alignment_Check_For_Size_Change (Typ : Entity_Id; Size : Uint) is
   begin
      --  If the alignment is known, and not set by a rep clause, and is
      --  inconsistent with the size being set, then reset it to unknown,
      --  we assume in this case that the size overrides the inherited
      --  alignment, and that the alignment must be recomputed.

      if Known_Alignment (Typ)
        and then not Has_Alignment_Clause (Typ)
        and then Present (Size)
        and then Size mod (Alignment (Typ) * SSU) /= 0
      then
         Reinit_Alignment (Typ);
      end if;
   end Alignment_Check_For_Size_Change;

   -----------------------------------
   -- All_Membership_Choices_Static --
   -----------------------------------

   function All_Membership_Choices_Static (Expr : Node_Id) return Boolean is
      pragma Assert (Nkind (Expr) in N_Membership_Test);
   begin
      pragma Assert
        (Present (Right_Opnd (Expr))
           xor
         Present (Alternatives (Expr)));

      if Present (Right_Opnd (Expr)) then
         return Is_Static_Choice (Right_Opnd (Expr));
      else
         return All_Static_Choices (Alternatives (Expr));
      end if;
   end All_Membership_Choices_Static;

   ------------------------
   -- All_Static_Choices --
   ------------------------

   function All_Static_Choices (L : List_Id) return Boolean is
      N : Node_Id;

   begin
      N := First (L);
      while Present (N) loop
         if not Is_Static_Choice (N) then
            return False;
         end if;

         Next (N);
      end loop;

      return True;
   end All_Static_Choices;

   -------------------------------------
   -- Analyze_Aspects_At_Freeze_Point --
   -------------------------------------

   procedure Analyze_Aspects_At_Freeze_Point (E : Entity_Id) is
      procedure Analyze_Aspect_Default_Value (ASN : Node_Id);
      --  This routine analyzes an Aspect_Default_[Component_]Value denoted by
      --  the aspect specification node ASN.

      procedure Check_Aspect_Too_Late (N : Node_Id);
      --  This procedure is similar to Rep_Item_Too_Late for representation
      --  aspects that apply to type and that do not have a corresponding
      --  pragma.
      --  Used to check in particular that the expression associated with
      --  aspect node N for the given type (entity) of the aspect does not
      --  appear too late according to the rules in RM 13.1(9) and 13.1(10).

      procedure Inherit_Delayed_Rep_Aspects (ASN : Node_Id);
      --  As discussed in the spec of Aspects (see Aspect_Delay declaration),
      --  a derived type can inherit aspects from its parent which have been
      --  specified at the time of the derivation using an aspect, as in:
      --
      --    type A is range 1 .. 10
      --      with Size => Not_Defined_Yet;
      --    ..
      --    type B is new A;
      --    ..
      --    Not_Defined_Yet : constant := 64;
      --
      --  In this example, the Size of A is considered to be specified prior
      --  to the derivation, and thus inherited, even though the value is not
      --  known at the time of derivation. To deal with this, we use two entity
      --  flags. The flag Has_Derived_Rep_Aspects is set in the parent type (A
      --  here), and then the flag May_Inherit_Delayed_Rep_Aspects is set in
      --  the derived type (B here). If this flag is set when the derived type
      --  is frozen, then this procedure is called to ensure proper inheritance
      --  of all delayed aspects from the parent type. The derived type is E,
      --  the argument to Analyze_Aspects_At_Freeze_Point. ASN is the first
      --  aspect specification node in the Rep_Item chain for the parent type.

      procedure Make_Pragma_From_Boolean_Aspect (ASN : Node_Id);
      --  Given an aspect specification node ASN whose expression is an
      --  optional Boolean, this routines creates the corresponding pragma
      --  at the freezing point.

      ----------------------------------
      -- Analyze_Aspect_Default_Value --
      ----------------------------------

      procedure Analyze_Aspect_Default_Value (ASN : Node_Id) is
         Ent  : constant Entity_Id := Entity (ASN);
         Expr : constant Node_Id   := Expression (ASN);

      begin
         Set_Has_Default_Aspect (Base_Type (Ent));

         if Is_Scalar_Type (Ent) then
            Set_Default_Aspect_Value (Base_Type (Ent), Expr);
         else
            Set_Default_Aspect_Component_Value (Base_Type (Ent), Expr);
         end if;

         Check_Aspect_Too_Late (ASN);
      end Analyze_Aspect_Default_Value;

      ---------------------------
      -- Check_Aspect_Too_Late --
      ---------------------------

      procedure Check_Aspect_Too_Late (N : Node_Id) is
         Typ  : constant Entity_Id := Entity (N);
         Expr : constant Node_Id   := Expression (N);

         function Find_Type_Reference
           (Typ : Entity_Id; Expr : Node_Id) return Boolean;
         --  Return True if a reference to type Typ is found in the expression
         --  Expr.

         -------------------------
         -- Find_Type_Reference --
         -------------------------

         function Find_Type_Reference
           (Typ : Entity_Id; Expr : Node_Id) return Boolean
         is
            function Find_Type (N : Node_Id) return Traverse_Result;
            --  Set Found to True if N refers to Typ

            ---------------
            -- Find_Type --
            ---------------

            function Find_Type (N : Node_Id) return Traverse_Result is
            begin
               if N = Typ
                 or else (Nkind (N) in N_Identifier | N_Expanded_Name
                           and then Present (Entity (N))
                           and then Entity (N) = Typ)
               then
                  return Abandon;
               else
                  return OK;
               end if;
            end Find_Type;

            function Search_Type_Reference is new Traverse_Func (Find_Type);

         begin
            return Search_Type_Reference (Expr) = Abandon;
         end Find_Type_Reference;

         Parent_Type : Entity_Id;

      begin
         --  Ensure Expr is analyzed so that e.g. all types are properly
         --  resolved for Find_Type_Reference.

         Analyze (Expr);

         --  A self-referential aspect is illegal if it forces freezing the
         --  entity before the corresponding aspect has been analyzed.

         if Find_Type_Reference (Typ, Expr) then
            Error_Msg_NE
              ("aspect specification causes premature freezing of&", N, Typ);
         end if;

         --  For representation aspects, check for case of untagged derived
         --  type whose parent either has primitive operations (pre Ada 2022),
         --  or is a by-reference type (RM 13.1(10)).
         --  Strictly speaking the check also applies to Ada 2012 but it is
         --  really too constraining for existing code already, so relax it.
         --  ??? Confirming aspects should be allowed here.

         if Is_Representation_Aspect (Get_Aspect_Id (N))
           and then Is_Derived_Type (Typ)
           and then not Is_Tagged_Type (Typ)
         then
            Parent_Type := Etype (Base_Type (Typ));

            if Ada_Version <= Ada_2012
              and then Has_Primitive_Operations (Parent_Type)
            then
               Error_Msg_N
                 ("|representation aspect not permitted before Ada 2022: " &
                  "use -gnat2022!", N);
               Error_Msg_NE
                 ("\parent type & has primitive operations!", N, Parent_Type);

            elsif Is_By_Reference_Type (Parent_Type) then
               No_Type_Rep_Item (N);
               Error_Msg_NE
                 ("\parent type & is a by-reference type!", N, Parent_Type);
            end if;
         end if;
      end Check_Aspect_Too_Late;

      ---------------------------------
      -- Inherit_Delayed_Rep_Aspects --
      ---------------------------------

      procedure Inherit_Delayed_Rep_Aspects (ASN : Node_Id) is
         A_Id : constant Aspect_Id := Get_Aspect_Id (ASN);
         P    : constant Entity_Id := Entity (ASN);
         --  Entity for parent type

         N : Node_Id;
         --  Item from Rep_Item chain

         A : Aspect_Id;

      begin
         --  Loop through delayed aspects for the parent type

         N := ASN;
         while Present (N) loop
            if Nkind (N) = N_Aspect_Specification then
               exit when Entity (N) /= P;

               if Is_Delayed_Aspect (N) then
                  A := Get_Aspect_Id (Chars (Identifier (N)));

                  --  Process delayed rep aspect. For Boolean attributes it is
                  --  not possible to cancel an attribute once set (the attempt
                  --  to use an aspect with xxx => False is an error) for a
                  --  derived type. So for those cases, we do not have to check
                  --  if a clause has been given for the derived type, since it
                  --  is harmless to set it again if it is already set.

                  case A is

                     --  Alignment

                     when Aspect_Alignment =>
                        if not Has_Alignment_Clause (E) then
                           Set_Alignment (E, Alignment (P));
                        end if;

                     --  Atomic

                     when Aspect_Atomic =>
                        if Is_Atomic (P) then
                           Set_Is_Atomic (E);
                        end if;

                     --  Atomic_Components

                     when Aspect_Atomic_Components =>
                        if Has_Atomic_Components (P) then
                           Set_Has_Atomic_Components (Base_Type (E));
                        end if;

                     --  Bit_Order

                     when Aspect_Bit_Order =>
                        if Is_Record_Type (E)
                          and then No (Get_Attribute_Definition_Clause
                                         (E, Attribute_Bit_Order))
                          and then Reverse_Bit_Order (P)
                        then
                           Set_Reverse_Bit_Order (Base_Type (E));
                        end if;

                     --  Component_Size

                     when Aspect_Component_Size =>
                        if Is_Array_Type (E)
                          and then not Has_Component_Size_Clause (E)
                        then
                           Set_Component_Size
                             (Base_Type (E), Component_Size (P));
                        end if;

                     --  Machine_Radix

                     when Aspect_Machine_Radix =>
                        if Is_Decimal_Fixed_Point_Type (E)
                          and then not Has_Machine_Radix_Clause (E)
                        then
                           Set_Machine_Radix_10 (E, Machine_Radix_10 (P));
                        end if;

                     --  Object_Size (also Size which also sets Object_Size)

                     when Aspect_Object_Size
                        | Aspect_Size
                     =>
                        if not Has_Size_Clause (E)
                          and then
                            No (Get_Attribute_Definition_Clause
                                  (E, Attribute_Object_Size))
                        then
                           Set_Esize (E, Esize (P));
                        end if;

                     --  Pack

                     when Aspect_Pack =>
                        if not Is_Packed (E) then
                           Set_Is_Packed (Base_Type (E));

                           if Is_Bit_Packed_Array (P) then
                              Set_Is_Bit_Packed_Array (Base_Type (E));
                              Set_Packed_Array_Impl_Type
                                (E, Packed_Array_Impl_Type (P));
                           end if;
                        end if;

                     --  Scalar_Storage_Order

                     when Aspect_Scalar_Storage_Order =>
                        if (Is_Record_Type (E) or else Is_Array_Type (E))
                          and then No (Get_Attribute_Definition_Clause
                                         (E, Attribute_Scalar_Storage_Order))
                          and then Reverse_Storage_Order (P)
                        then
                           Set_Reverse_Storage_Order (Base_Type (E));

                           --  Clear default SSO indications, since the aspect
                           --  overrides the default.

                           Set_SSO_Set_Low_By_Default  (Base_Type (E), False);
                           Set_SSO_Set_High_By_Default (Base_Type (E), False);
                        end if;

                     --  Small

                     when Aspect_Small =>
                        if Is_Fixed_Point_Type (E)
                          and then not Has_Small_Clause (E)
                        then
                           Set_Small_Value (E, Small_Value (P));
                        end if;

                     --  Storage_Size

                     when Aspect_Storage_Size =>
                        if (Is_Access_Type (E) or else Is_Task_Type (E))
                          and then not Has_Storage_Size_Clause (E)
                        then
                           Set_Storage_Size_Variable
                             (Base_Type (E), Storage_Size_Variable (P));
                        end if;

                     --  Value_Size

                     when Aspect_Value_Size =>

                        --  Value_Size is never inherited, it is either set by
                        --  default, or it is explicitly set for the derived
                        --  type. So nothing to do here.

                        null;

                     --  Volatile

                     when Aspect_Volatile =>
                        if Is_Volatile (P) then
                           Set_Is_Volatile (E);
                        end if;

                     --  Volatile_Full_Access (also Full_Access_Only)

                     when Aspect_Volatile_Full_Access
                        | Aspect_Full_Access_Only
                     =>
                        if Is_Volatile_Full_Access (P) then
                           Set_Is_Volatile_Full_Access (E);
                        end if;

                     --  Volatile_Components

                     when Aspect_Volatile_Components =>
                        if Has_Volatile_Components (P) then
                           Set_Has_Volatile_Components (Base_Type (E));
                        end if;

                     --  That should be all the Rep Aspects

                     when others =>
                        pragma Assert (Aspect_Delay (A_Id) /= Rep_Aspect);
                        null;
                  end case;
               end if;
            end if;

            Next_Rep_Item (N);
         end loop;
      end Inherit_Delayed_Rep_Aspects;

      -------------------------------------
      -- Make_Pragma_From_Boolean_Aspect --
      -------------------------------------

      procedure Make_Pragma_From_Boolean_Aspect (ASN : Node_Id) is
         Ident  : constant Node_Id    := Identifier (ASN);
         A_Name : constant Name_Id    := Chars (Ident);
         A_Id   : constant Aspect_Id  := Get_Aspect_Id (A_Name);
         Ent    : constant Entity_Id  := Entity (ASN);
         Expr   : constant Node_Id    := Expression (ASN);
         Loc    : constant Source_Ptr := Sloc (ASN);

         procedure Check_False_Aspect_For_Derived_Type;
         --  This procedure checks for the case of a false aspect for a derived
         --  type, which improperly tries to cancel an aspect inherited from
         --  the parent.

         -----------------------------------------
         -- Check_False_Aspect_For_Derived_Type --
         -----------------------------------------

         procedure Check_False_Aspect_For_Derived_Type is
            Par : Node_Id;

         begin
            --  We are only checking derived types

            if not Is_Derived_Type (E) then
               return;
            end if;

            Par := Nearest_Ancestor (E);

            case A_Id is
               when Aspect_Atomic
                  | Aspect_Shared
               =>
                  if not Is_Atomic (Par) then
                     return;
                  end if;

               when Aspect_Atomic_Components =>
                  if not Has_Atomic_Components (Par) then
                     return;
                  end if;

               when Aspect_Discard_Names =>
                  if not Discard_Names (Par) then
                     return;
                  end if;

               when Aspect_Pack =>
                  if not Is_Packed (Par) then
                     return;
                  end if;

               when Aspect_Unchecked_Union =>
                  if not Is_Unchecked_Union (Par) then
                     return;
                  end if;

               when Aspect_Volatile =>
                  if not Is_Volatile (Par) then
                     return;
                  end if;

               when Aspect_Volatile_Components =>
                  if not Has_Volatile_Components (Par) then
                     return;
                  end if;

               when Aspect_Volatile_Full_Access
                  | Aspect_Full_Access_Only
               =>
                  if not Is_Volatile_Full_Access (Par) then
                     return;
                  end if;

               when others =>
                  return;
            end case;

            --  Fall through means we are canceling an inherited aspect

            Error_Msg_Name_1 := A_Name;
            Error_Msg_NE
              ("derived type& inherits aspect%, cannot cancel", Expr, E);
         end Check_False_Aspect_For_Derived_Type;

         --  Local variables

         Prag   : Node_Id;
         P_Name : Name_Id;

      --  Start of processing for Make_Pragma_From_Boolean_Aspect

      begin
         if Present (Expr) and then Is_False (Static_Boolean (Expr)) then
            Check_False_Aspect_For_Derived_Type;

         else
            --  There is no Full_Access_Only pragma so use VFA instead

            if A_Name = Name_Full_Access_Only then
               P_Name := Name_Volatile_Full_Access;
            else
               P_Name := A_Name;
            end if;

            Prag :=
              Make_Pragma (Loc,
                Pragma_Identifier            =>
                  Make_Identifier (Sloc (Ident), P_Name),
                Pragma_Argument_Associations => New_List (
                  Make_Pragma_Argument_Association (Sloc (Ident),
                    Expression => New_Occurrence_Of (Ent, Sloc (Ident)))));

            Set_From_Aspect_Specification (Prag, True);
            Set_Corresponding_Aspect (Prag, ASN);
            Set_Aspect_Rep_Item (ASN, Prag);
            Set_Is_Delayed_Aspect (Prag);
            Set_Parent (Prag, ASN);
         end if;
      end Make_Pragma_From_Boolean_Aspect;

      --  Local variables

      A_Id  : Aspect_Id;
      ASN   : Node_Id;
      Ritem : Node_Id;

   --  Start of processing for Analyze_Aspects_At_Freeze_Point

   begin
      --  Must be visible in current scope, but if this is a type from a nested
      --  package it may be frozen from an object declaration in the enclosing
      --  scope, so install the package declarations to complete the analysis
      --  of the aspects, if any. If the package itself is frozen the type will
      --  have been frozen as well.

      if not Scope_Within_Or_Same (Current_Scope, Scope (E)) then
         if Is_Type (E) and then From_Nested_Package (E) then
            declare
               Pack : constant Entity_Id := Scope (E);

            begin
               Push_Scope (Pack);
               Install_Visible_Declarations (Pack);
               Install_Private_Declarations (Pack);
               Analyze_Aspects_At_Freeze_Point (E);

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

               End_Package_Scope (Pack);
               return;
            end;

         --  Aspects from other entities in different contexts are analyzed
         --  elsewhere.

         else
            return;
         end if;
      end if;

      --  Look for aspect specification entries for this entity

      ASN := First_Rep_Item (E);
      while Present (ASN) loop
         if Nkind (ASN) = N_Aspect_Specification then
            exit when Entity (ASN) /= E;

            if Is_Delayed_Aspect (ASN) then
               A_Id := Get_Aspect_Id (ASN);

               case A_Id is

                  --  For aspects whose expression is an optional Boolean, make
                  --  the corresponding pragma at the freeze point.

                  when Boolean_Aspects
                     | Library_Unit_Aspects
                  =>
                     --  Aspects Export and Import require special handling.
                     --  Both are by definition Boolean and may benefit from
                     --  forward references, however their expressions are
                     --  treated as static. In addition, the syntax of their
                     --  corresponding pragmas requires extra "pieces" which
                     --  may also contain forward references. To account for
                     --  all of this, the corresponding pragma is created by
                     --  Analyze_Aspect_Export_Import, but is not analyzed as
                     --  the complete analysis must happen now.

                     --  Aspect Full_Access_Only must be analyzed last so that
                     --  aspects Volatile and Atomic, if any, are analyzed.

                     --  Skip creation of pragma Preelaborable_Initialization
                     --  in the case where the aspect has an expression,
                     --  because the pragma is only needed for setting flag
                     --  Known_To_Have_Preelab_Init, which is set by other
                     --  means following resolution of the aspect expression.

                     if A_Id not in Aspect_Export
                                  | Aspect_Full_Access_Only
                                  | Aspect_Import
                       and then (A_Id /= Aspect_Preelaborable_Initialization
                                  or else not Present (Expression (ASN)))
                     then
                        Make_Pragma_From_Boolean_Aspect (ASN);
                     end if;

                  --  Special handling for aspects that don't correspond to
                  --  pragmas/attributes.

                  when Aspect_Default_Value
                     | Aspect_Default_Component_Value
                  =>
                     --  Do not inherit aspect for anonymous base type of a
                     --  scalar or array type, because they apply to the first
                     --  subtype of the type, and will be processed when that
                     --  first subtype is frozen.

                     if Is_Derived_Type (E)
                       and then not Comes_From_Source (E)
                       and then E /= First_Subtype (E)
                     then
                        null;
                     else
                        Analyze_Aspect_Default_Value (ASN);
                     end if;

                  --  Ditto for iterator aspects, because the corresponding
                  --  attributes may not have been analyzed yet.

                  when Aspect_Constant_Indexing
                     | Aspect_Default_Iterator
                     | Aspect_Iterator_Element
                     | Aspect_Variable_Indexing
                  =>
                     Analyze (Expression (ASN));

                     if Etype (Expression (ASN)) = Any_Type then
                        Error_Msg_NE
                          ("\aspect must be fully defined before & is frozen",
                           ASN, E);
                     end if;

                  when Aspect_Integer_Literal
                     | Aspect_Real_Literal
                     | Aspect_String_Literal
                  =>
                     Validate_Literal_Aspect (E, ASN);

                  when Aspect_Iterable =>
                     Validate_Iterable_Aspect (E, ASN);

                  when Aspect_Designated_Storage_Model =>
                     Analyze_And_Resolve (Expression (ASN));

                     if not Is_Entity_Name (Expression (ASN))
                       or else not Is_Object (Entity (Expression (ASN)))
                       or else
                         not Present (Find_Aspect (Etype (Expression (ASN)),
                                                   Aspect_Storage_Model_Type))
                     then
                        Error_Msg_N
                          ("must specify name of stand-alone object of type "
                            & "with aspect Storage_Model_Type",
                           Expression (ASN));

                     --  Set access type's Associated_Storage_Pool to denote
                     --  the Storage_Model_Type object given for the aspect
                     --  (even though that isn't actually an Ada storage pool).

                     else
                        Set_Associated_Storage_Pool
                          (E, Entity (Expression (ASN)));
                     end if;

                  when Aspect_Storage_Model_Type =>
                     Validate_Storage_Model_Type_Aspect (E, ASN);

                  when Aspect_Aggregate =>
                     null;

                  when others =>
                     null;
               end case;

               Ritem := Aspect_Rep_Item (ASN);

               if Present (Ritem) then
                  Analyze (Ritem);
               end if;
            end if;
         end if;

         Next_Rep_Item (ASN);
      end loop;

      --  Make a second pass for a Full_Access_Only entry

      ASN := First_Rep_Item (E);
      while Present (ASN) loop
         if Nkind (ASN) = N_Aspect_Specification then
            exit when Entity (ASN) /= E;

            if Get_Aspect_Id (ASN) = Aspect_Full_Access_Only then
               Make_Pragma_From_Boolean_Aspect (ASN);
               Ritem := Aspect_Rep_Item (ASN);
               if Present (Ritem) then
                  Analyze (Ritem);
               end if;
            end if;
         end if;

         Next_Rep_Item (ASN);
      end loop;

      --  This is where we inherit delayed rep aspects from our parent. Note
      --  that if we fell out of the above loop with ASN non-empty, it means
      --  we hit an aspect for an entity other than E, and it must be the
      --  type from which we were derived.

      if May_Inherit_Delayed_Rep_Aspects (E) then
         Inherit_Delayed_Rep_Aspects (ASN);
      end if;

      if In_Instance
        and then E /= Base_Type (E)
        and then Is_First_Subtype (E)
      then
         Inherit_Rep_Item_Chain (Base_Type (E), E);
      end if;
   end Analyze_Aspects_At_Freeze_Point;

   -----------------------------------
   -- Analyze_Aspect_Specifications --
   -----------------------------------

   procedure Analyze_Aspect_Specifications (N : Node_Id; E : Entity_Id) is
      pragma Assert (Present (E));

      procedure Decorate (Asp : Node_Id; Prag : Node_Id);
      --  Establish linkages between an aspect and its corresponding pragma

      procedure Insert_Pragma
        (Prag        : Node_Id;
         Is_Instance : Boolean := False);
      --  Subsidiary to the analysis of aspects
      --    Abstract_State
      --    Attach_Handler
      --    Contract_Cases
      --    Depends
      --    Ghost
      --    Global
      --    Initial_Condition
      --    Initializes
      --    Post
      --    Pre
      --    Refined_Depends
      --    Refined_Global
      --    Refined_State
      --    SPARK_Mode
      --    Subprogram_Variant
      --    Warnings
      --  Insert pragma Prag such that it mimics the placement of a source
      --  pragma of the same kind. Flag Is_Generic should be set when the
      --  context denotes a generic instance.

      --------------
      -- Decorate --
      --------------

      procedure Decorate (Asp : Node_Id; Prag : Node_Id) is
      begin
         Set_Aspect_Rep_Item           (Asp, Prag);
         Set_Corresponding_Aspect      (Prag, Asp);
         Set_From_Aspect_Specification (Prag);
         Set_Parent                    (Prag, Asp);
      end Decorate;

      -------------------
      -- Insert_Pragma --
      -------------------

      procedure Insert_Pragma
        (Prag        : Node_Id;
         Is_Instance : Boolean := False)
      is
         Aux      : Node_Id;
         Decl     : Node_Id;
         Decls    : List_Id;
         Def      : Node_Id;
         Inserted : Boolean := False;

      begin
         --  When the aspect appears on an entry, package, protected unit,
         --  subprogram, or task unit body, insert the generated pragma at the
         --  top of the body declarations to emulate the behavior of a source
         --  pragma.

         --    package body Pack with Aspect is

         --    package body Pack is
         --       pragma Prag;

         if Nkind (N) in N_Entry_Body
                       | N_Package_Body
                       | N_Protected_Body
                       | N_Subprogram_Body
                       | N_Task_Body
         then
            Decls := Declarations (N);

            if No (Decls) then
               Decls := New_List;
               Set_Declarations (N, Decls);
            end if;

            Prepend_To (Decls, Prag);

         --  When the aspect is associated with a [generic] package declaration
         --  insert the generated pragma at the top of the visible declarations
         --  to emulate the behavior of a source pragma.

         --    package Pack with Aspect is

         --    package Pack is
         --       pragma Prag;

         elsif Nkind (N) in N_Generic_Package_Declaration
                          | N_Package_Declaration
         then
            Decls := Visible_Declarations (Specification (N));

            if No (Decls) then
               Decls := New_List;
               Set_Visible_Declarations (Specification (N), Decls);
            end if;

            --  The visible declarations of a generic instance have the
            --  following structure:

            --    <renamings of generic formals>
            --    <renamings of internally-generated spec and body>
            --    <first source declaration>

            --  Insert the pragma before the first source declaration by
            --  skipping the instance "header" to ensure proper visibility of
            --  all formals.

            if Is_Instance then
               Decl := First (Decls);
               while Present (Decl) loop
                  if Comes_From_Source (Decl) then
                     Insert_Before (Decl, Prag);
                     Inserted := True;
                     exit;
                  else
                     Next (Decl);
                  end if;
               end loop;

               --  The pragma is placed after the instance "header"

               if not Inserted then
                  Append_To (Decls, Prag);
               end if;

            --  Otherwise this is not a generic instance

            else
               Prepend_To (Decls, Prag);
            end if;

         --  When the aspect is associated with a protected unit declaration,
         --  insert the generated pragma at the top of the visible declarations
         --  the emulate the behavior of a source pragma.

         --    protected [type] Prot with Aspect is

         --    protected [type] Prot is
         --       pragma Prag;

         elsif Nkind (N) = N_Protected_Type_Declaration then
            Def := Protected_Definition (N);

            if No (Def) then
               Def :=
                 Make_Protected_Definition (Sloc (N),
                   Visible_Declarations => New_List,
                   End_Label            => Empty);

               Set_Protected_Definition (N, Def);
            end if;

            Decls := Visible_Declarations (Def);

            if No (Decls) then
               Decls := New_List;
               Set_Visible_Declarations (Def, Decls);
            end if;

            Prepend_To (Decls, Prag);

         --  When the aspect is associated with a task unit declaration, insert
         --  insert the generated pragma at the top of the visible declarations
         --  the emulate the behavior of a source pragma.

         --    task [type] Prot with Aspect is

         --    task [type] Prot is
         --       pragma Prag;

         elsif Nkind (N) = N_Task_Type_Declaration then
            Def := Task_Definition (N);

            if No (Def) then
               Def :=
                 Make_Task_Definition (Sloc (N),
                   Visible_Declarations => New_List,
                   End_Label            => Empty);

               Set_Task_Definition (N, Def);
            end if;

            Decls := Visible_Declarations (Def);

            if No (Decls) then
               Decls := New_List;
               Set_Visible_Declarations (Def, Decls);
            end if;

            Prepend_To (Decls, Prag);

         --  When the context is a library unit, the pragma is added to the
         --  Pragmas_After list.

         elsif Nkind (Parent (N)) = N_Compilation_Unit then
            Aux := Aux_Decls_Node (Parent (N));

            if No (Pragmas_After (Aux)) then
               Set_Pragmas_After (Aux, New_List);
            end if;

            Prepend (Prag, Pragmas_After (Aux));

         --  Default, the pragma is inserted after the context

         else
            Insert_After (N, Prag);
         end if;
      end Insert_Pragma;

      --  Local variables

      Aspect : Node_Id;
      Aitem  : Node_Id := Empty;
      Ent    : Node_Id;

      L : constant List_Id := Aspect_Specifications (N);
      pragma Assert (Present (L));

      Ins_Node : Node_Id := N;
      --  Insert pragmas/attribute definition clause after this node when no
      --  delayed analysis is required.

   --  Start of processing for Analyze_Aspect_Specifications

   begin
      --  The general processing involves building an attribute definition
      --  clause or a pragma node that corresponds to the aspect. Then in order
      --  to delay the evaluation of this aspect to the freeze point, we attach
      --  the corresponding pragma/attribute definition clause to the aspect
      --  specification node, which is then placed in the Rep Item chain. In
      --  this case we mark the entity by setting the flag Has_Delayed_Aspects
      --  and we evaluate the rep item at the freeze point. When the aspect
      --  doesn't have a corresponding pragma/attribute definition clause, then
      --  its analysis is simply delayed at the freeze point.

      --  Some special cases don't require delay analysis, thus the aspect is
      --  analyzed right now.

      --  Note that there is a special handling for Pre, Post, Test_Case,
      --  Contract_Cases and Subprogram_Variant aspects. In these cases, we do
      --  not have to worry about delay issues, since the pragmas themselves
      --  deal with delay of visibility for the expression analysis. Thus, we
      --  just insert the pragma after the node N.

      --  Loop through aspects

      Aspect := First (L);
      Aspect_Loop : while Present (Aspect) loop
         Analyze_One_Aspect : declare

            Aspect_Exit : exception;
            --  This exception is used to exit aspect processing completely. It
            --  is used when an error is detected, and no further processing is
            --  required. It is also used if an earlier error has left the tree
            --  in a state where the aspect should not be processed.

            Expr : constant Node_Id    := Expression (Aspect);
            Id   : constant Node_Id    := Identifier (Aspect);
            Loc  : constant Source_Ptr := Sloc (Aspect);
            Nam  : constant Name_Id    := Chars (Id);
            A_Id : constant Aspect_Id  := Get_Aspect_Id (Nam);
            Anod : Node_Id;

            Delay_Required : Boolean;
            --  Set False if delay is not required

            Eloc : Source_Ptr := No_Location;
            --  Source location of expression, modified when we split PPC's. It
            --  is set below when Expr is present.

            procedure Analyze_Aspect_Convention;
            --  Perform analysis of aspect Convention

            procedure Analyze_Aspect_Disable_Controlled;
            --  Perform analysis of aspect Disable_Controlled

            procedure Analyze_Aspect_Export_Import;
            --  Perform analysis of aspects Export or Import

            procedure Analyze_Aspect_External_Link_Name;
            --  Perform analysis of aspects External_Name or Link_Name

            procedure Analyze_Aspect_Implicit_Dereference;
            --  Perform analysis of the Implicit_Dereference aspects

            procedure Analyze_Aspect_Relaxed_Initialization;
            --  Perform analysis of aspect Relaxed_Initialization

            procedure Analyze_Aspect_Yield;
            --  Perform analysis of aspect Yield

            procedure Analyze_Aspect_Static;
            --  Ada 2022 (AI12-0075): Perform analysis of aspect Static

            procedure Check_Expr_Is_OK_Static_Expression
              (Expr : Node_Id;
               Typ  : Entity_Id := Empty);
            --  Check the specified expression Expr to make sure that it is a
            --  static expression of the given type (i.e. it will be analyzed
            --  and resolved using this type, which can be any valid argument
            --  to Resolve, e.g. Any_Integer is OK). If not, give an error
            --  and raise Aspect_Exit. If Typ is left Empty, then any static
            --  expression is allowed. Includes checking that the expression
            --  does not raise Constraint_Error.

            function Directly_Specified
              (Id : Entity_Id; A : Aspect_Id) return Boolean;
            --  Returns True if the given aspect is directly (as opposed to
            --  via any form of inheritance) specified for the given entity.

            function Make_Aitem_Pragma
              (Pragma_Argument_Associations : List_Id;
               Pragma_Name                  : Name_Id) return Node_Id;
            --  This is a wrapper for Make_Pragma used for converting aspects
            --  to pragmas. It takes care of Sloc (set from Loc) and building
            --  the pragma identifier from the given name. In addition the
            --  flags Class_Present and Split_PPC are set from the aspect
            --  node, as well as Is_Ignored. This routine also sets the
            --  From_Aspect_Specification in the resulting pragma node to
            --  True, and sets Corresponding_Aspect to point to the aspect.
            --  The resulting pragma is assigned to Aitem.

            -------------------------------
            -- Analyze_Aspect_Convention --
            -------------------------------

            procedure Analyze_Aspect_Convention is
               Conv    : Node_Id;
               Dummy_1 : Node_Id;
               Dummy_2 : Node_Id;
               Dummy_3 : Node_Id;
               Expo    : Node_Id;
               Imp     : Node_Id;

            begin
               --  Obtain all interfacing aspects that apply to the related
               --  entity.

               Get_Interfacing_Aspects
                 (Iface_Asp => Aspect,
                  Conv_Asp  => Dummy_1,
                  EN_Asp    => Dummy_2,
                  Expo_Asp  => Expo,
                  Imp_Asp   => Imp,
                  LN_Asp    => Dummy_3,
                  Do_Checks => True);

               --  The related entity is subject to aspect Export or Import.
               --  Do not process Convention now because it must be analysed
               --  as part of Export or Import.

               if Present (Expo) or else Present (Imp) then
                  return;

               --  Otherwise Convention appears by itself

               else
                  --  The aspect specifies a particular convention

                  if Present (Expr) then
                     Conv := New_Copy_Tree (Expr);

                  --  Otherwise assume convention Ada

                  else
                     Conv := Make_Identifier (Loc, Name_Ada);
                  end if;

                  --  Generate:
                  --    pragma Convention (<Conv>, <E>);

                  Aitem := Make_Aitem_Pragma
                    (Pragma_Name => Name_Convention,
                     Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Conv),
                       Make_Pragma_Argument_Association (Loc,
                         Expression => New_Occurrence_Of (E, Loc))));

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
               end if;
            end Analyze_Aspect_Convention;

            ---------------------------------------
            -- Analyze_Aspect_Disable_Controlled --
            ---------------------------------------

            procedure Analyze_Aspect_Disable_Controlled is
            begin
               --  The aspect applies only to controlled records

               if not (Ekind (E) = E_Record_Type
                        and then Is_Controlled_Active (E))
               then
                  Error_Msg_N
                    ("aspect % requires controlled record type", Aspect);
                  return;
               end if;

               --  Preanalyze the expression (if any) when the aspect resides
               --  in a generic unit.

               if Inside_A_Generic then
                  if Present (Expr) then
                     Preanalyze_And_Resolve (Expr, Any_Boolean);
                  end if;

               --  Otherwise the aspect resides in a nongeneric context

               else
                  --  A controlled record type loses its controlled semantics
                  --  when the expression statically evaluates to True.

                  if Present (Expr) then
                     Analyze_And_Resolve (Expr, Any_Boolean);

                     if Is_OK_Static_Expression (Expr) then
                        if Is_True (Static_Boolean (Expr)) then
                           Set_Disable_Controlled (E);
                        end if;

                     --  Otherwise the expression is not static

                     else
                        Error_Msg_N
                          ("expression of aspect % must be static", Aspect);
                     end if;

                  --  Otherwise the aspect appears without an expression and
                  --  defaults to True.

                  else
                     Set_Disable_Controlled (E);
                  end if;
               end if;
            end Analyze_Aspect_Disable_Controlled;

            ----------------------------------
            -- Analyze_Aspect_Export_Import --
            ----------------------------------

            procedure Analyze_Aspect_Export_Import is
               Dummy_1 : Node_Id;
               Dummy_2 : Node_Id;
               Dummy_3 : Node_Id;
               Expo    : Node_Id;
               Imp     : Node_Id;

            begin
               --  Obtain all interfacing aspects that apply to the related
               --  entity.

               Get_Interfacing_Aspects
                 (Iface_Asp => Aspect,
                  Conv_Asp  => Dummy_1,
                  EN_Asp    => Dummy_2,
                  Expo_Asp  => Expo,
                  Imp_Asp   => Imp,
                  LN_Asp    => Dummy_3,
                  Do_Checks => True);

               --  The related entity cannot be subject to both aspects Export
               --  and Import.

               if Present (Expo) and then Present (Imp) then
                  Error_Msg_N
                    ("incompatible interfacing aspects given for &", E);
                  Error_Msg_Sloc := Sloc (Expo);
                  Error_Msg_N ("\aspect Export #", E);
                  Error_Msg_Sloc := Sloc (Imp);
                  Error_Msg_N ("\aspect Import #", E);
               end if;

               --  A variable is most likely modified from the outside. Take
               --  the optimistic approach to avoid spurious errors.

               if Ekind (E) = E_Variable then
                  Set_Never_Set_In_Source (E, False);
               end if;

               --  Resolve the expression of an Import or Export here, and
               --  require it to be of type Boolean and static. This is not
               --  quite right, because in general this should be delayed,
               --  but that seems tricky for these, because normally Boolean
               --  aspects are replaced with pragmas at the freeze point in
               --  Make_Pragma_From_Boolean_Aspect.

               if not Present (Expr)
                 or else Is_True (Static_Boolean (Expr))
               then
                  if A_Id = Aspect_Import then
                     Set_Has_Completion (E);
                     Set_Is_Imported (E);

                     --  An imported object cannot be explicitly initialized

                     if Nkind (N) = N_Object_Declaration
                       and then Present (Expression (N))
                     then
                        Error_Msg_N
                          ("imported entities cannot be initialized "
                           & "(RM B.1(24))", Expression (N));
                     end if;

                  else
                     pragma Assert (A_Id = Aspect_Export);
                     Set_Is_Exported (E);
                  end if;

                  --  Create the proper form of pragma Export or Import taking
                  --  into account Conversion, External_Name, and Link_Name.

                  Aitem := Build_Export_Import_Pragma (Aspect, E);

               --  Otherwise the expression is either False or erroneous. There
               --  is no corresponding pragma.

               else
                  Aitem := Empty;
               end if;
            end Analyze_Aspect_Export_Import;

            ---------------------------------------
            -- Analyze_Aspect_External_Link_Name --
            ---------------------------------------

            procedure Analyze_Aspect_External_Link_Name is
               Dummy_1 : Node_Id;
               Dummy_2 : Node_Id;
               Dummy_3 : Node_Id;
               Expo    : Node_Id;
               Imp     : Node_Id;

            begin
               --  Obtain all interfacing aspects that apply to the related
               --  entity.

               Get_Interfacing_Aspects
                 (Iface_Asp => Aspect,
                  Conv_Asp  => Dummy_1,
                  EN_Asp    => Dummy_2,
                  Expo_Asp  => Expo,
                  Imp_Asp   => Imp,
                  LN_Asp    => Dummy_3,
                  Do_Checks => True);

               --  Ensure that aspect External_Name applies to aspect Export or
               --  Import.

               if A_Id = Aspect_External_Name then
                  if No (Expo) and then No (Imp) then
                     Error_Msg_N
                       ("aspect External_Name requires aspect Import or "
                        & "Export", Aspect);
                  end if;

               --  Otherwise ensure that aspect Link_Name applies to aspect
               --  Export or Import.

               else
                  pragma Assert (A_Id = Aspect_Link_Name);
                  if No (Expo) and then No (Imp) then
                     Error_Msg_N
                       ("aspect Link_Name requires aspect Import or Export",
                        Aspect);
                  end if;
               end if;
            end Analyze_Aspect_External_Link_Name;

            -----------------------------------------
            -- Analyze_Aspect_Implicit_Dereference --
            -----------------------------------------

            procedure Analyze_Aspect_Implicit_Dereference is
            begin
               if not Is_Type (E) or else not Has_Discriminants (E) then
                  Error_Msg_N
                    ("aspect must apply to a type with discriminants", Expr);

               elsif not Is_Entity_Name (Expr) then
                  Error_Msg_N
                    ("aspect must name a discriminant of current type", Expr);

               else
                  --  Discriminant type be an anonymous access type or an
                  --  anonymous access to subprogram.

                  --  Missing synchronized types???

                  declare
                     Disc : Entity_Id := First_Discriminant (E);
                  begin
                     while Present (Disc) loop
                        if Chars (Expr) = Chars (Disc)
                          and then Ekind (Etype (Disc)) in
                            E_Anonymous_Access_Subprogram_Type |
                            E_Anonymous_Access_Type
                        then
                           Set_Has_Implicit_Dereference (E);
                           Set_Has_Implicit_Dereference (Disc);
                           exit;
                        end if;

                        Next_Discriminant (Disc);
                     end loop;

                     --  Error if no proper access discriminant

                     if Present (Disc) then
                        --  For a type extension, check whether parent has
                        --  a reference discriminant, to verify that use is
                        --  proper.

                        if Is_Derived_Type (E)
                          and then Has_Discriminants (Etype (E))
                        then
                           declare
                              Parent_Disc : constant Entity_Id :=
                                Get_Reference_Discriminant (Etype (E));
                           begin
                              if Present (Parent_Disc)
                                and then Corresponding_Discriminant (Disc) /=
                                           Parent_Disc
                              then
                                 Error_Msg_N
                                   ("reference discriminant does not match "
                                      & "discriminant of parent type", Expr);
                              end if;
                           end;
                        end if;

                     else
                        Error_Msg_NE
                          ("not an access discriminant of&", Expr, E);
                     end if;
                  end;
               end if;

            end Analyze_Aspect_Implicit_Dereference;

            -------------------------------------------
            -- Analyze_Aspect_Relaxed_Initialization --
            -------------------------------------------

            procedure Analyze_Aspect_Relaxed_Initialization is
               procedure Analyze_Relaxed_Parameter
                 (Subp_Id : Entity_Id;
                  Param   : Node_Id;
                  Seen    : in out Elist_Id);
               --  Analyze parameter that appears in the expression of the
               --  aspect Relaxed_Initialization.

               -------------------------------
               -- Analyze_Relaxed_Parameter --
               -------------------------------

               procedure Analyze_Relaxed_Parameter
                 (Subp_Id : Entity_Id;
                  Param   : Node_Id;
                  Seen    : in out Elist_Id)
               is
               begin
                  --  Set name of the aspect for error messages
                  Error_Msg_Name_1 := Nam;

                  --  The relaxed parameter is a formal parameter

                  if Nkind (Param) in N_Identifier | N_Expanded_Name then
                     Analyze (Param);

                     declare
                        Item : constant Entity_Id := Entity (Param);
                     begin
                        --  It must be a formal of the analyzed subprogram

                        if Scope (Item) = Subp_Id then

                           pragma Assert (Is_Formal (Item));

                           --  It must not have scalar or access type

                           if Is_Elementary_Type (Etype (Item)) then
                              Error_Msg_N ("illegal aspect % item", Param);
                              Error_Msg_N
                                ("\item must not have elementary type", Param);
                           end if;

                           --  Detect duplicated items

                           if Contains (Seen, Item) then
                              Error_Msg_N ("duplicate aspect % item", Param);
                           else
                              Append_New_Elmt (Item, Seen);
                           end if;
                        else
                           Error_Msg_N ("illegal aspect % item", Param);
                        end if;
                     end;

                  --  The relaxed parameter is the function's Result attribute

                  elsif Is_Attribute_Result (Param) then
                     Analyze (Param);

                     declare
                        Pref : constant Node_Id := Prefix (Param);
                     begin
                        if Present (Pref)
                          and then
                            Nkind (Pref) in N_Identifier | N_Expanded_Name
                          and then
                            Entity (Pref) = Subp_Id
                        then
                           --  Function result must not have scalar or access
                           --  type.

                           if Is_Elementary_Type (Etype (Pref)) then
                              Error_Msg_N ("illegal aspect % item", Param);
                              Error_Msg_N
                                ("\function result must not have elementary"
                                 & " type", Param);
                           end if;

                           --  Detect duplicated items

                           if Contains (Seen, Subp_Id) then
                              Error_Msg_N ("duplicate aspect % item", Param);
                           else
                              Append_New_Elmt (Entity (Pref), Seen);
                           end if;

                        else
                           Error_Msg_N ("illegal aspect % item", Param);
                        end if;
                     end;
                  else
                     Error_Msg_N ("illegal aspect % item", Param);
                  end if;
               end Analyze_Relaxed_Parameter;

               --  Local variables

               Seen : Elist_Id := No_Elist;
               --  Items that appear in the relaxed initialization aspect
               --  expression of a subprogram; for detecting duplicates.

               Restore_Scope : Boolean;
               --  Will be set to True if we need to restore the scope table
               --  after analyzing the aspect expression.

               Prev_Id : Entity_Id;

            --  Start of processing for Analyze_Aspect_Relaxed_Initialization

            begin
               --  Set name of the aspect for error messages
               Error_Msg_Name_1 := Nam;

               --  Annotation of a type; no aspect expression is allowed.
               --  For a private type, the aspect must be attached to the
               --  partial view.
               --
               --  ??? Once the exact rule for this aspect is ready, we will
               --  likely reject concurrent types, etc., so let's keep the code
               --  for types and variable separate.

               if Is_First_Subtype (E) then
                  Prev_Id := Incomplete_Or_Partial_View (E);
                  if Present (Prev_Id) then

                     --  Aspect may appear on the full view of an incomplete
                     --  type because the incomplete declaration cannot have
                     --  any aspects.

                     if Ekind (Prev_Id) = E_Incomplete_Type then
                        null;
                     else
                        Error_Msg_N ("aspect % must apply to partial view", N);
                     end if;

                  elsif Present (Expr) then
                     Error_Msg_N ("illegal aspect % expression", Expr);
                  end if;

               --  Annotation of a variable; no aspect expression is allowed

               elsif Ekind (E) = E_Variable then
                  if Present (Expr) then
                     Error_Msg_N ("illegal aspect % expression", Expr);
                  end if;

               --  Annotation of a constant; no aspect expression is allowed.
               --  For a deferred constant, the aspect must be attached to the
               --  partial view.

               elsif Ekind (E) = E_Constant then
                  if Present (Incomplete_Or_Partial_View (E)) then
                     Error_Msg_N
                       ("aspect % must apply to deferred constant", N);

                  elsif Present (Expr) then
                     Error_Msg_N ("illegal aspect % expression", Expr);
                  end if;

               --  Annotation of a subprogram; aspect expression is required

               elsif Is_Subprogram_Or_Entry (E)
                 or else Is_Generic_Subprogram (E)
               then
                  if Present (Expr) then

                     --  If we analyze subprogram body that acts as its own
                     --  spec, then the subprogram itself and its formals are
                     --  already installed; otherwise, we need to install them,
                     --  as they must be visible when analyzing the aspect
                     --  expression.

                     if In_Open_Scopes (E) then
                        Restore_Scope := False;
                     else
                        Restore_Scope := True;
                        Push_Scope (E);

                        --  Only formals of the subprogram itself can appear
                        --  in Relaxed_Initialization aspect expression, not
                        --  formals of the enclosing generic unit. (This is
                        --  different than in Precondition or Depends aspects,
                        --  where both kinds of formals are allowed.)

                        Install_Formals (E);
                     end if;

                     --  Aspect expression is either an aggregate with list of
                     --  parameters (and possibly the Result attribute for a
                     --  function).

                     if Nkind (Expr) = N_Aggregate then

                        --  Component associations in the aggregate must be a
                        --  parameter name followed by a static boolean
                        --  expression.

                        if Present (Component_Associations (Expr)) then
                           declare
                              Assoc : Node_Id :=
                                First (Component_Associations (Expr));
                           begin
                              while Present (Assoc) loop
                                 if List_Length (Choices (Assoc)) = 1 then
                                    Analyze_Relaxed_Parameter
                                      (E, First (Choices (Assoc)), Seen);

                                    if Inside_A_Generic then
                                       Preanalyze_And_Resolve
                                         (Expression (Assoc), Any_Boolean);
                                    else
                                       Analyze_And_Resolve
                                         (Expression (Assoc), Any_Boolean);
                                    end if;

                                    if not Is_OK_Static_Expression
                                      (Expression (Assoc))
                                    then
                                       Error_Msg_Name_1 := Nam;
                                       Error_Msg_N
                                         ("expression of aspect %" &
                                          "must be static", Aspect);
                                    end if;

                                 else
                                    Error_Msg_Name_1 := Nam;
                                    Error_Msg_N
                                      ("illegal aspect % expression", Expr);
                                 end if;
                                 Next (Assoc);
                              end loop;
                           end;
                        end if;

                        --  Expressions of the aggregate are parameter names

                        if Present (Expressions (Expr)) then
                           declare
                              Param : Node_Id := First (Expressions (Expr));

                           begin
                              while Present (Param) loop
                                 Analyze_Relaxed_Parameter (E, Param, Seen);
                                 Next (Param);
                              end loop;
                           end;
                        end if;

                        --  Mark the aggregate expression itself as analyzed;
                        --  its subexpressions were marked when they themselves
                        --  were analyzed.

                        Set_Analyzed (Expr);

                     --  Otherwise, it is a single name of a subprogram
                     --  parameter (or possibly the Result attribute for
                     --  a function).

                     else
                        Analyze_Relaxed_Parameter (E, Expr, Seen);
                     end if;

                     if Restore_Scope then
                        End_Scope;
                     end if;
                  else
                     Error_Msg_N ("missing expression for aspect %", N);
                  end if;

               else
                  Error_Msg_N ("inappropriate entity for aspect %", E);
               end if;
            end Analyze_Aspect_Relaxed_Initialization;

            ---------------------------
            -- Analyze_Aspect_Static --
            ---------------------------

            procedure Analyze_Aspect_Static is
               function Has_Convention_Intrinsic (L : List_Id) return Boolean;
               --  Return True if L contains a pragma argument association
               --  node representing a convention Intrinsic.

               ------------------------------
               -- Has_Convention_Intrinsic --
               ------------------------------

               function Has_Convention_Intrinsic
                 (L : List_Id) return Boolean
               is
                  Arg : Node_Id := First (L);
               begin
                  while Present (Arg) loop
                     if Nkind (Arg) = N_Pragma_Argument_Association
                       and then Chars (Arg) = Name_Convention
                       and then Chars (Expression (Arg)) = Name_Intrinsic
                     then
                        return True;
                     end if;

                     Next (Arg);
                  end loop;

                  return False;
               end Has_Convention_Intrinsic;

               Is_Imported_Intrinsic : Boolean;

            begin
               if Ada_Version < Ada_2022 then
                  Error_Msg_Ada_2022_Feature ("aspect %", Sloc (Aspect));
                  return;
               end if;

               Is_Imported_Intrinsic := Is_Imported (E)
                 and then
                   Has_Convention_Intrinsic
                     (Pragma_Argument_Associations (Import_Pragma (E)));

               --  The aspect applies only to expression functions that
               --  statisfy the requirements for a static expression function
               --  (such as having an expression that is predicate-static) as
               --  well as Intrinsic imported functions as a -gnatX extension.

               if not Is_Expression_Function (E)
                 and then
                   not (Extensions_Allowed and then Is_Imported_Intrinsic)
               then
                  if Extensions_Allowed then
                     Error_Msg_N
                       ("aspect % requires intrinsic or expression function",
                        Aspect);

                  elsif Is_Imported_Intrinsic then
                     Error_Msg_N
                       ("aspect % on intrinsic function is an extension: " &
                        "use -gnatX",
                        Aspect);

                  else
                     Error_Msg_N
                       ("aspect % requires expression function", Aspect);
                  end if;

                  return;

               --  Ada 2022 (AI12-0075): Check that the function satisfies
               --  several requirements of static functions as specified in
               --  RM 6.8(5.1-5.8). Note that some of the requirements given
               --  there are checked elsewhere.

               else
                  --  The expression of the expression function must be a
                  --  potentially static expression (RM 2022 6.8(3.2-3.4)).
                  --  That's checked in Sem_Ch6.Analyze_Expression_Function.

                  --  The function must not contain any calls to itself, which
                  --  is checked in Sem_Res.Resolve_Call.

                  --  Each formal must be of mode in and have a static subtype

                  declare
                     Formal : Entity_Id := First_Formal (E);
                  begin
                     while Present (Formal) loop
                        if Ekind (Formal) /= E_In_Parameter then
                           Error_Msg_N
                             ("aspect % requires formals of mode IN",
                              Aspect);

                           return;
                        end if;

                        if not Is_Static_Subtype (Etype (Formal)) then
                           Error_Msg_N
                             ("aspect % requires formals with static subtypes",
                              Aspect);

                           return;
                        end if;

                        Next_Formal (Formal);
                     end loop;
                  end;

                  --  The function's result subtype must be a static subtype

                  if not Is_Static_Subtype (Etype (E)) then
                     Error_Msg_N
                       ("aspect % requires function with result of "
                        & "a static subtype",
                        Aspect);

                     return;
                  end if;

                  --  Check that the function does not have any applicable
                  --  precondition or postcondition expression.

                  for Asp in Pre_Post_Aspects loop
                     if Has_Aspect (E, Asp) then
                        Error_Msg_Name_1 := Aspect_Names (Asp);
                        Error_Msg_N
                          ("aspect % is not allowed for a static "
                           & "expression function",
                           Find_Aspect (E, Asp));

                        return;
                     end if;
                  end loop;

                  --  ??? Must check that "for result type R, if the
                  --  function is a boundary entity for type R (see 7.3.2),
                  --  no type invariant applies to type R; if R has a
                  --  component type C, a similar rule applies to C."
               end if;

               --  When the expression is present, it must be static. If it
               --  evaluates to True, the expression function is treated as
               --  a static function. Otherwise the aspect appears without
               --  an expression and defaults to True.

               if Present (Expr) then
                  --  Preanalyze the expression when the aspect resides in a
                  --  generic unit. (Is this generic-related code necessary
                  --  for this aspect? It's modeled on what's done for aspect
                  --  Disable_Controlled. ???)

                  if Inside_A_Generic then
                     Preanalyze_And_Resolve (Expr, Any_Boolean);

                  --  Otherwise the aspect resides in a nongeneric context

                  else
                     Analyze_And_Resolve (Expr, Any_Boolean);

                     --  Error if the boolean expression is not static

                     if not Is_OK_Static_Expression (Expr) then
                        Error_Msg_N
                          ("expression of aspect % must be static", Aspect);
                     end if;
                  end if;
               end if;
            end Analyze_Aspect_Static;

            --------------------------
            -- Analyze_Aspect_Yield --
            --------------------------

            procedure Analyze_Aspect_Yield is
               Expr_Value : Boolean := False;

            begin
               --  Check valid declarations for 'Yield

               if Nkind (N) in N_Abstract_Subprogram_Declaration
                             | N_Entry_Declaration
                             | N_Generic_Subprogram_Declaration
                             | N_Subprogram_Declaration
                             | N_Formal_Subprogram_Declaration
                 and then not Within_Protected_Type (E)
               then
                  null;

               elsif Within_Protected_Type (E) then
                  Error_Msg_N
                    ("aspect% not applicable to protected operation", Id);
                  return;

               else
                  Error_Msg_N
                    ("aspect% only applicable to subprogram and entry "
                     & "declarations", Id);
                  return;
               end if;

               --  Evaluate its static expression (if available); otherwise it
               --  defaults to True.

               if No (Expr) then
                  Expr_Value := True;

               --  Otherwise it must have a static boolean expression

               else
                  if Inside_A_Generic then
                     Preanalyze_And_Resolve (Expr, Any_Boolean);
                  else
                     Analyze_And_Resolve (Expr, Any_Boolean);
                  end if;

                  if Is_OK_Static_Expression (Expr) then
                     if Is_True (Static_Boolean (Expr)) then
                        Expr_Value := True;
                     end if;
                  else
                     Error_Msg_N
                       ("expression of aspect % must be static", Aspect);
                  end if;
               end if;

               if Expr_Value then
                  Set_Has_Yield_Aspect (E);
               end if;

               --  If the Yield aspect is specified for a dispatching
               --  subprogram that inherits the aspect, the specified
               --  value shall be confirming.

               if Present (Expr)
                 and then Is_Dispatching_Operation (E)
                 and then Present (Overridden_Operation (E))
                 and then Has_Yield_Aspect (Overridden_Operation (E))
                            /= Is_True (Static_Boolean (Expr))
               then
                  Error_Msg_N ("specification of inherited aspect% can only " &
                               "confirm parent value", Id);
               end if;
            end Analyze_Aspect_Yield;

            ----------------------------------------
            -- Check_Expr_Is_OK_Static_Expression --
            ----------------------------------------

            procedure Check_Expr_Is_OK_Static_Expression
              (Expr : Node_Id;
               Typ  : Entity_Id := Empty)
            is
            begin
               if Present (Typ) then
                  Analyze_And_Resolve (Expr, Typ);
               else
                  Analyze_And_Resolve (Expr);
               end if;

               --  An expression cannot be considered static if its resolution
               --  failed or if it's erroneous. Stop the analysis of the
               --  related aspect.

               if Etype (Expr) = Any_Type or else Error_Posted (Expr) then
                  raise Aspect_Exit;

               elsif Is_OK_Static_Expression (Expr) then
                  return;

               --  Finally, we have a real error

               else
                  Error_Msg_Name_1 := Nam;
                  Flag_Non_Static_Expr
                    ("entity for aspect% must be a static expression",
                     Expr);
                  raise Aspect_Exit;
               end if;
            end Check_Expr_Is_OK_Static_Expression;

            ------------------------
            -- Directly_Specified --
            ------------------------

            function Directly_Specified
              (Id : Entity_Id; A : Aspect_Id) return Boolean
            is
               Aspect_Spec : constant Node_Id := Find_Aspect (Id, A);
            begin
               return Present (Aspect_Spec) and then Entity (Aspect_Spec) = Id;
            end Directly_Specified;

            -----------------------
            -- Make_Aitem_Pragma --
            -----------------------

            function Make_Aitem_Pragma
              (Pragma_Argument_Associations : List_Id;
               Pragma_Name                  : Name_Id) return Node_Id
            is
               Args  : List_Id := Pragma_Argument_Associations;
               Aitem : Node_Id;

            begin
               --  We should never get here if aspect was disabled

               pragma Assert (not Is_Disabled (Aspect));

               --  Certain aspects allow for an optional name or expression. Do
               --  not generate a pragma with empty argument association list.

               if No (Args) or else No (Expression (First (Args))) then
                  Args := No_List;
               end if;

               --  Build the pragma

               Aitem :=
                 Make_Pragma (Loc,
                   Pragma_Argument_Associations => Args,
                   Pragma_Identifier =>
                     Make_Identifier (Sloc (Id), Pragma_Name),
                   Class_Present     => Class_Present (Aspect),
                   Split_PPC         => Split_PPC (Aspect));

               --  Set additional semantic fields

               if Is_Ignored (Aspect) then
                  Set_Is_Ignored (Aitem);
               elsif Is_Checked (Aspect) then
                  Set_Is_Checked (Aitem);
               end if;

               Set_Corresponding_Aspect (Aitem, Aspect);
               Set_From_Aspect_Specification (Aitem);

               return Aitem;
            end Make_Aitem_Pragma;

         --  Start of processing for Analyze_One_Aspect

         begin
            --  Skip aspect if already analyzed, to avoid looping in some cases

            if Analyzed (Aspect) then
               goto Continue;
            end if;

            --  Skip looking at aspect if it is totally disabled. Just mark it
            --  as such for later reference in the tree. This also sets the
            --  Is_Ignored and Is_Checked flags appropriately.

            Check_Applicable_Policy (Aspect);

            if Is_Disabled (Aspect) then
               goto Continue;
            end if;

            --  Set the source location of expression, used in the case of
            --  a failed precondition/postcondition or invariant. Note that
            --  the source location of the expression is not usually the best
            --  choice here. For example, it gets located on the last AND
            --  keyword in a chain of boolean expressiond AND'ed together.
            --  It is best to put the message on the first character of the
            --  assertion, which is the effect of the First_Node call here.

            if Present (Expr) then
               Eloc := Sloc (First_Node (Expr));
            end if;

            --  Check restriction No_Implementation_Aspect_Specifications

            if Implementation_Defined_Aspect (A_Id) then
               Check_Restriction
                 (No_Implementation_Aspect_Specifications, Aspect);
            end if;

            --  Check restriction No_Specification_Of_Aspect

            Check_Restriction_No_Specification_Of_Aspect (Aspect);

            --  Mark aspect analyzed (actual analysis is delayed till later)

            Set_Analyzed (Aspect);
            Set_Entity (Aspect, E);

            --  Build the reference to E that will be used in the built pragmas

            Ent := New_Occurrence_Of (E, Sloc (Id));

            if A_Id in Aspect_Attach_Handler | Aspect_Interrupt_Handler then

               --  Treat the specification as a reference to the protected
               --  operation, which might otherwise appear unreferenced and
               --  generate spurious warnings.

               Generate_Reference (E, Id);
            end if;

            --  Check for duplicate aspect. Note that the Comes_From_Source
            --  test allows duplicate Pre/Post's that we generate internally
            --  to escape being flagged here.

            if No_Duplicates_Allowed (A_Id) then
               Anod := First (L);
               while Anod /= Aspect loop
                  if Comes_From_Source (Aspect)
                    and then Same_Aspect (A_Id, Get_Aspect_Id (Anod))
                  then
                     Error_Msg_Name_1 := Nam;
                     Error_Msg_Sloc := Sloc (Anod);

                     --  Case of same aspect specified twice

                     if Class_Present (Anod) = Class_Present (Aspect) then
                        if not Class_Present (Anod) then
                           Error_Msg_NE
                             ("aspect% for & previously given#",
                              Id, E);
                        else
                           Error_Msg_NE
                             ("aspect `%''Class` for & previously given#",
                              Id, E);
                        end if;
                     end if;
                  end if;

                  Next (Anod);
               end loop;
            end if;

            --  Check some general restrictions on language defined aspects

            if not Implementation_Defined_Aspect (A_Id)
              or else A_Id in Aspect_Async_Readers
                            | Aspect_Async_Writers
                            | Aspect_Effective_Reads
                            | Aspect_Effective_Writes
                            | Aspect_Preelaborable_Initialization
            then
               Error_Msg_Name_1 := Nam;

               --  Not allowed for renaming declarations. Examine the original
               --  node because a subprogram renaming may have been rewritten
               --  as a body.

               if Nkind (Original_Node (N)) in N_Renaming_Declaration then
                  Error_Msg_N
                    ("aspect % not allowed for renaming declaration",
                     Aspect);
               end if;

               --  Not allowed for formal type declarations in previous
               --  versions of the language. Allowed for them only for
               --  shared variable control aspects.

               --  Original node is used in case expansion rewrote the node -
               --  as is the case with generic derived types.

               if Nkind (Original_Node (N)) = N_Formal_Type_Declaration then
                  if Ada_Version < Ada_2022 then
                     Error_Msg_N
                       ("aspect % not allowed for formal type declaration",
                        Aspect);

                  elsif A_Id not in Aspect_Atomic
                                  | Aspect_Volatile
                                  | Aspect_Independent
                                  | Aspect_Atomic_Components
                                  | Aspect_Independent_Components
                                  | Aspect_Volatile_Components
                                  | Aspect_Async_Readers
                                  | Aspect_Async_Writers
                                  | Aspect_Effective_Reads
                                  | Aspect_Effective_Writes
                                  | Aspect_Preelaborable_Initialization
                  then
                     Error_Msg_N
                       ("aspect % not allowed for formal type declaration",
                        Aspect);
                  end if;
               end if;
            end if;

            --  Copy expression for later processing by the procedures
            --  Check_Aspect_At_[Freeze_Point | End_Of_Declarations]

            --  The expression may be a subprogram name, and can
            --  be an operator name that appears as a string, but
            --  requires its own analysis procedure (see sem_ch6).

            if Nkind (Expr) = N_Operator_Symbol then
               Set_Entity (Id, Expr);
            else
               Set_Entity (Id, New_Copy_Tree (Expr));
            end if;

            --  Set Delay_Required as appropriate to aspect

            case Aspect_Delay (A_Id) is
               when Always_Delay =>
                  --  For Boolean aspects, do not delay if no expression

                  if A_Id in Boolean_Aspects | Library_Unit_Aspects then
                     Delay_Required := Present (Expr);
                  else
                     Delay_Required := True;
                  end if;

               when Never_Delay =>
                  Delay_Required := False;

               when Rep_Aspect =>

                  --  For Boolean aspects, do not delay if no expression except
                  --  for Full_Access_Only because we need to process it after
                  --  Volatile and Atomic, which can be independently delayed.

                  if A_Id in Boolean_Aspects
                    and then A_Id /= Aspect_Full_Access_Only
                    and then No (Expr)
                  then
                     Delay_Required := False;

                  --  For non-Boolean aspects, if the expression has the form
                  --  of an integer literal, then do not delay, since we know
                  --  the value cannot change. This optimization catches most
                  --  rep clause cases.

                  elsif A_Id not in Boolean_Aspects
                    and then Present (Expr)
                    and then Nkind (Expr) = N_Integer_Literal
                  then
                     Delay_Required := False;

                  --  For Alignment and various Size aspects, do not delay for
                  --  an attribute reference whose prefix is Standard, for
                  --  example Standard'Maximum_Alignment or Standard'Word_Size.

                  elsif A_Id in Aspect_Alignment
                              | Aspect_Component_Size
                              | Aspect_Object_Size
                              | Aspect_Size
                              | Aspect_Value_Size
                    and then Present (Expr)
                    and then Nkind (Expr) = N_Attribute_Reference
                    and then Nkind (Prefix (Expr)) = N_Identifier
                    and then Chars (Prefix (Expr)) = Name_Standard
                  then
                     Delay_Required := False;

                  --  All other cases are delayed

                  else
                     Delay_Required := True;
                     Set_Has_Delayed_Rep_Aspects (E);
                  end if;
            end case;

            if Delay_Required

               and then (A_Id = Aspect_Stable_Properties
                          or else A_Id = Aspect_Designated_Storage_Model
                          or else A_Id = Aspect_Storage_Model_Type)
               --  ??? It seems like we should do this for all aspects, not
               --  just these, but that causes as-yet-undiagnosed regressions.

            then
               Set_Has_Delayed_Aspects (E);
               Set_Is_Delayed_Aspect (Aspect);
            end if;

            --  Check 13.1(9.2/5): A representation aspect of a subtype or type
            --  shall not be specified (whether by a representation item or an
            --  aspect_specification) before the type is completely defined
            --  (see 3.11.1).

            if Is_Representation_Aspect (A_Id)
              and then Rep_Item_Too_Early (E, N)
            then
               goto Continue;
            end if;

            --  Processing based on specific aspect

            case A_Id is
               when Aspect_Unimplemented =>
                  null; -- ??? temp for now

               --  No_Aspect should be impossible

               when No_Aspect =>
                  raise Program_Error;

               --  Case 1: Aspects corresponding to attribute definition
               --  clauses.

               when Aspect_Address
                  | Aspect_Alignment
                  | Aspect_Bit_Order
                  | Aspect_Component_Size
                  | Aspect_Constant_Indexing
                  | Aspect_Default_Iterator
                  | Aspect_Dispatching_Domain
                  | Aspect_External_Tag
                  | Aspect_Input
                  | Aspect_Iterable
                  | Aspect_Iterator_Element
                  | Aspect_Machine_Radix
                  | Aspect_Object_Size
                  | Aspect_Output
                  | Aspect_Put_Image
                  | Aspect_Read
                  | Aspect_Scalar_Storage_Order
                  | Aspect_Simple_Storage_Pool
                  | Aspect_Size
                  | Aspect_Small
                  | Aspect_Storage_Pool
                  | Aspect_Stream_Size
                  | Aspect_Value_Size
                  | Aspect_Variable_Indexing
                  | Aspect_Write
               =>
                  --  Indexing aspects apply only to tagged type

                  if A_Id in Aspect_Constant_Indexing
                           | Aspect_Variable_Indexing
                    and then not (Is_Type (E)
                                   and then Is_Tagged_Type (E))
                  then
                     Error_Msg_N
                       ("indexing aspect can only apply to a tagged type",
                        Aspect);
                     goto Continue;
                  end if;

                  --  For the case of aspect Address, we don't consider that we
                  --  know the entity is never set in the source, since it is
                  --  is likely aliasing is occurring.

                  --  Note: one might think that the analysis of the resulting
                  --  attribute definition clause would take care of that, but
                  --  that's not the case since it won't be from source.

                  if A_Id = Aspect_Address then
                     Set_Never_Set_In_Source (E, False);
                  end if;

                  --  Correctness of the profile of a stream operation is
                  --  verified at the freeze point, but we must detect the
                  --  illegal specification of this aspect for a subtype now,
                  --  to prevent malformed rep_item chains.

                  if A_Id in Aspect_Input
                           | Aspect_Output
                           | Aspect_Read
                           | Aspect_Write
                  then
                     if not Is_First_Subtype (E) then
                        Error_Msg_N
                          ("local name must be a first subtype", Aspect);
                        goto Continue;

                     --  If stream aspect applies to the class-wide type,
                     --  the generated attribute definition applies to the
                     --  class-wide type as well.

                     elsif Class_Present (Aspect) then
                        Ent :=
                          Make_Attribute_Reference (Loc,
                            Prefix         => Ent,
                            Attribute_Name => Name_Class);
                     end if;
                  end if;

                  --  Construct the attribute_definition_clause. The expression
                  --  in the aspect specification is simply shared with the
                  --  constructed attribute, because it will be fully analyzed
                  --  when the attribute is processed.

                  Aitem :=
                    Make_Attribute_Definition_Clause (Loc,
                      Name       => Ent,
                      Chars      => Nam,
                      Expression => Relocate_Node (Expr));

                  --  If the address is specified, then we treat the entity as
                  --  referenced, to avoid spurious warnings. This is analogous
                  --  to what is done with an attribute definition clause, but
                  --  here we don't want to generate a reference because this
                  --  is the point of definition of the entity.

                  if A_Id = Aspect_Address then
                     Set_Referenced (E);
                  end if;

               --  Case 2: Aspects corresponding to pragmas

               --  Case 2a: Aspects corresponding to pragmas with two
               --  arguments, where the first argument is a local name
               --  referring to the entity, and the second argument is the
               --  aspect definition expression.

               --  Linker_Section

               when Aspect_Linker_Section =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => New_Occurrence_Of (E, Loc)),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Linker_Section);

                  --  Linker_Section does not need delaying, as its argument
                  --  must be a static string. Furthermore, if applied to
                  --  an object with an explicit initialization, the object
                  --  must be frozen in order to elaborate the initialization
                  --  code. (This is already done for types with implicit
                  --  initialization, such as protected types.)

                  if Nkind (N) = N_Object_Declaration
                    and then Has_Init_Expression (N)
                  then
                     Delay_Required := False;
                  end if;

               --  Synchronization

               --  Corresponds to pragma Implemented, construct the pragma

               when Aspect_Synchronization =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => New_Occurrence_Of (E, Loc)),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Implemented);

               --  Attach_Handler

               when Aspect_Attach_Handler =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Sloc (Ent),
                         Expression => Ent),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Attach_Handler);

                  --  We need to insert this pragma into the tree to get proper
                  --  processing and to look valid from a placement viewpoint.

                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Dynamic_Predicate, Predicate, Static_Predicate

               when Aspect_Dynamic_Predicate
                  | Aspect_Predicate
                  | Aspect_Static_Predicate
               =>
                  --  These aspects apply only to subtypes

                  if not Is_Type (E) then
                     Error_Msg_N
                       ("predicate can only be specified for a subtype",
                        Aspect);
                     goto Continue;

                  elsif Is_Incomplete_Type (E) then
                     Error_Msg_N
                       ("predicate cannot apply to incomplete view", Aspect);

                  elsif Is_Generic_Type (E) then
                     Error_Msg_N
                       ("predicate cannot apply to formal type", Aspect);
                     goto Continue;
                  end if;

                  --  Construct the pragma (always a pragma Predicate, with
                  --  flags recording whether it is static/dynamic). We also
                  --  set flags recording this in the type itself.

                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Sloc (Ent),
                         Expression => Ent),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name => Name_Predicate);

                  --  Mark type has predicates, and remember what kind of
                  --  aspect lead to this predicate (we need this to access
                  --  the right set of check policies later on).

                  Set_Has_Predicates (E);

                  if A_Id = Aspect_Dynamic_Predicate then
                     Set_Has_Dynamic_Predicate_Aspect (E);

                     --  If the entity has a dynamic predicate, any inherited
                     --  static predicate becomes dynamic as well, and the
                     --  predicate function includes the conjunction of both.

                     Set_Has_Static_Predicate_Aspect (E, False);

                  elsif A_Id = Aspect_Static_Predicate then
                     Set_Has_Static_Predicate_Aspect (E);
                  end if;

                  --  If the type is private, indicate that its completion
                  --  has a freeze node, because that is the one that will
                  --  be visible at freeze time.

                  if Is_Private_Type (E) and then Present (Full_View (E)) then
                     Set_Has_Predicates (Full_View (E));

                     if A_Id = Aspect_Dynamic_Predicate then
                        Set_Has_Dynamic_Predicate_Aspect (Full_View (E));
                     elsif A_Id = Aspect_Static_Predicate then
                        Set_Has_Static_Predicate_Aspect (Full_View (E));
                     end if;

                     Set_Has_Delayed_Aspects (Full_View (E));
                     Ensure_Freeze_Node (Full_View (E));

                     --  If there is an Underlying_Full_View, also create a
                     --  freeze node for that one.

                     if Is_Private_Type (Full_View (E)) then
                        declare
                           U_Full : constant Entity_Id :=
                             Underlying_Full_View (Full_View (E));
                        begin
                           if Present (U_Full) then
                              Set_Has_Delayed_Aspects (U_Full);
                              Ensure_Freeze_Node (U_Full);
                           end if;
                        end;
                     end if;
                  end if;

               --  Predicate_Failure

               when Aspect_Predicate_Failure =>

                  --  This aspect applies only to subtypes

                  if not Is_Type (E) then
                     Error_Msg_N
                       ("predicate can only be specified for a subtype",
                        Aspect);
                     goto Continue;

                  elsif Is_Incomplete_Type (E) then
                     Error_Msg_N
                       ("predicate cannot apply to incomplete view", Aspect);
                     goto Continue;

                  elsif not Has_Predicates (E) then
                     Error_Msg_N
                       ("Predicate_Failure requires previous predicate" &
                        " specification", Aspect);
                     goto Continue;

                  elsif not (Directly_Specified (E, Aspect_Dynamic_Predicate)
                    or else Directly_Specified (E, Aspect_Static_Predicate)
                    or else Directly_Specified (E, Aspect_Predicate))
                  then
                     Error_Msg_N
                       ("Predicate_Failure requires accompanying" &
                        " noninherited predicate specification", Aspect);
                     goto Continue;
                  end if;

                  --  Construct the pragma

                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Sloc (Ent),
                         Expression => Ent),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name => Name_Predicate_Failure);

               --  Case 2b: Aspects corresponding to pragmas with two
               --  arguments, where the second argument is a local name
               --  referring to the entity, and the first argument is the
               --  aspect definition expression.

               --  Convention

               when Aspect_Convention =>
                  Analyze_Aspect_Convention;
                  goto Continue;

               --  External_Name, Link_Name

               when Aspect_External_Name
                  | Aspect_Link_Name
               =>
                  Analyze_Aspect_External_Link_Name;
                  goto Continue;

               --  CPU, Interrupt_Priority, Priority

               --  These three aspects can be specified for a subprogram spec
               --  or body, in which case we analyze the expression and export
               --  the value of the aspect.

               --  Previously, we generated an equivalent pragma for bodies
               --  (note that the specs cannot contain these pragmas). The
               --  pragma was inserted ahead of local declarations, rather than
               --  after the body. This leads to a certain duplication between
               --  the processing performed for the aspect and the pragma, but
               --  given the straightforward handling required it is simpler
               --  to duplicate than to translate the aspect in the spec into
               --  a pragma in the declarative part of the body.

               when Aspect_CPU
                  | Aspect_Interrupt_Priority
                  | Aspect_Priority
               =>
                  --  Verify the expression is static when Static_Priorities is
                  --  enabled.

                  if not Is_OK_Static_Expression (Expr) then
                     Check_Restriction (Static_Priorities, Expr);
                  end if;

                  if Nkind (N) in N_Subprogram_Body | N_Subprogram_Declaration
                  then
                     --  Analyze the aspect expression

                     Analyze_And_Resolve (Expr, Standard_Integer);

                     --  Interrupt_Priority aspect not allowed for main
                     --  subprograms. RM D.1 does not forbid this explicitly,
                     --  but RM J.15.11(6/3) does not permit pragma
                     --  Interrupt_Priority for subprograms.

                     if A_Id = Aspect_Interrupt_Priority then
                        Error_Msg_N
                          ("Interrupt_Priority aspect cannot apply to "
                           & "subprogram", Expr);

                     --  The expression must be static

                     elsif not Is_OK_Static_Expression (Expr) then
                        Flag_Non_Static_Expr
                          ("aspect requires static expression!", Expr);

                     --  Check whether this is the main subprogram. Issue a
                     --  warning only if it is obviously not a main program
                     --  (when it has parameters or when the subprogram is
                     --  within a package).

                     elsif Present (Parameter_Specifications
                                      (Specification (N)))
                       or else not Is_Compilation_Unit (Defining_Entity (N))
                     then
                        --  See RM D.1(14/3) and D.16(12/3)

                        Error_Msg_N
                          ("aspect applied to subprogram other than the "
                           & "main subprogram has no effect??", Expr);

                     --  Otherwise check in range and export the value

                     --  For the CPU aspect

                     elsif A_Id = Aspect_CPU then
                        if Is_In_Range (Expr, RTE (RE_CPU_Range)) then

                           --  Value is correct so we export the value to make
                           --  it available at execution time.

                           Set_Main_CPU
                             (Main_Unit, UI_To_Int (Expr_Value (Expr)));

                        else
                           Error_Msg_N
                             ("main subprogram 'C'P'U is out of range", Expr);
                        end if;

                     --  For the Priority aspect

                     elsif A_Id = Aspect_Priority then
                        if Is_In_Range (Expr, RTE (RE_Priority)) then

                           --  Value is correct so we export the value to make
                           --  it available at execution time.

                           Set_Main_Priority
                             (Main_Unit, UI_To_Int (Expr_Value (Expr)));

                        --  Ignore pragma if Relaxed_RM_Semantics to support
                        --  other targets/non GNAT compilers.

                        elsif not Relaxed_RM_Semantics then
                           Error_Msg_N
                             ("main subprogram priority is out of range",
                              Expr);
                        end if;
                     end if;

                     --  Load an arbitrary entity from System.Tasking.Stages
                     --  or System.Tasking.Restricted.Stages (depending on
                     --  the supported profile) to make sure that one of these
                     --  packages is implicitly with'ed, since we need to have
                     --  the tasking run time active for the pragma Priority to
                     --  have any effect. Previously we with'ed the package
                     --  System.Tasking, but this package does not trigger the
                     --  required initialization of the run-time library.

                     if Restricted_Profile then
                        Discard_Node (RTE (RE_Activate_Restricted_Tasks));
                     else
                        Discard_Node (RTE (RE_Activate_Tasks));
                     end if;

                     --  Handling for these aspects in subprograms is complete

                     goto Continue;

                  --  For task and protected types pass the aspect as an
                  --  attribute.

                  else
                     Aitem :=
                       Make_Attribute_Definition_Clause (Loc,
                         Name       => Ent,
                         Chars      => Nam,
                         Expression => Relocate_Node (Expr));
                  end if;

               --  Suppress/Unsuppress

               when Aspect_Suppress
                  | Aspect_Unsuppress
               =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr)),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => New_Occurrence_Of (E, Loc))),
                     Pragma_Name                  => Nam);

                  Delay_Required := False;

               --  Warnings

               when Aspect_Warnings =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr)),
                       Make_Pragma_Argument_Association (Loc,
                         Expression => New_Occurrence_Of (E, Loc))),
                     Pragma_Name                  => Name_Warnings);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Case 2c: Aspects corresponding to pragmas with three
               --  arguments.

               --  Invariant aspects have a first argument that references the
               --  entity, a second argument that is the expression and a third
               --  argument that is an appropriate message.

               --  Invariant, Type_Invariant

               when Aspect_Invariant
                  | Aspect_Type_Invariant
               =>
                  --  Analysis of the pragma will verify placement legality:
                  --  an invariant must apply to a private type, or appear in
                  --  the private part of a spec and apply to a completion.

                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Sloc (Ent),
                         Expression => Ent),
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Invariant);

                  --  Add message unless exception messages are suppressed

                  if not Opt.Exception_Locations_Suppressed then
                     Append_To (Pragma_Argument_Associations (Aitem),
                       Make_Pragma_Argument_Association (Eloc,
                         Chars      => Name_Message,
                         Expression =>
                           Make_String_Literal (Eloc,
                             Strval => "failed invariant from "
                                       & Build_Location_String (Eloc))));
                  end if;

                  --  For Invariant case, insert immediately after the entity
                  --  declaration. We do not have to worry about delay issues
                  --  since the pragma processing takes care of this.

                  Delay_Required := False;

               --  Case 2d : Aspects that correspond to a pragma with one
               --  argument.

               --  Abstract_State

               --  Aspect Abstract_State introduces implicit declarations for
               --  all state abstraction entities it defines. To emulate this
               --  behavior, insert the pragma at the beginning of the visible
               --  declarations of the related package so that it is analyzed
               --  immediately.

               when Aspect_Abstract_State => Abstract_State : declare
                  Context : Node_Id := N;

               begin
                  --  When aspect Abstract_State appears on a generic package,
                  --  it is propagated to the package instance. The context in
                  --  this case is the instance spec.

                  if Nkind (Context) = N_Package_Instantiation then
                     Context := Instance_Spec (Context);
                  end if;

                  if Nkind (Context) in N_Generic_Package_Declaration
                                      | N_Package_Declaration
                  then
                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => New_List (
                          Make_Pragma_Argument_Association (Loc,
                            Expression => Relocate_Node (Expr))),
                        Pragma_Name                  => Name_Abstract_State);

                     Decorate (Aspect, Aitem);
                     Insert_Pragma
                       (Prag        => Aitem,
                        Is_Instance =>
                          Is_Generic_Instance (Defining_Entity (Context)));

                  else
                     Error_Msg_NE
                       ("aspect & must apply to a package declaration",
                        Aspect, Id);
                  end if;

                  goto Continue;
               end Abstract_State;

               --  Aspect Async_Readers is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related object declaration.

               when Aspect_Async_Readers =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Async_Readers);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Async_Writers is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related object declaration.

               when Aspect_Async_Writers =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Async_Writers);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Constant_After_Elaboration is never delayed because
               --  it is equivalent to a source pragma which appears after the
               --  related object declaration.

               when Aspect_Constant_After_Elaboration =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  =>
                       Name_Constant_After_Elaboration);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Default_Internal_Condition is never delayed because
               --  it is equivalent to a source pragma which appears after the
               --  related private type. To deal with forward references, the
               --  generated pragma is stored in the rep chain of the related
               --  private type as types do not carry contracts. The pragma is
               --  wrapped inside of a procedure at the freeze point of the
               --  private type's full view.

               --  A type entity argument is appended to facilitate inheriting
               --  the aspect from parent types (see Build_DIC_Procedure_Body),
               --  though that extra argument isn't documented for the pragma.

               when Aspect_Default_Initial_Condition =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr)),
                       Make_Pragma_Argument_Association (Sloc (Ent),
                         Expression => Ent)),
                     Pragma_Name                  =>
                       Name_Default_Initial_Condition);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Default_Storage_Pool

               when Aspect_Default_Storage_Pool =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  =>
                       Name_Default_Storage_Pool);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Depends

               --  Aspect Depends is never delayed because it is equivalent to
               --  a source pragma which appears after the related subprogram.
               --  To deal with forward references, the generated pragma is
               --  stored in the contract of the related subprogram and later
               --  analyzed at the end of the declarative region. See routine
               --  Analyze_Depends_In_Decl_Part for details.

               when Aspect_Depends =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Depends);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Effective_Reads is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related object declaration.

               when Aspect_Effective_Reads =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Effective_Reads);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Effective_Writes is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related object declaration.

               when Aspect_Effective_Writes =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Effective_Writes);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Extensions_Visible is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related subprogram.

               when Aspect_Extensions_Visible =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Extensions_Visible);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect Ghost is never delayed because it is equivalent to a
               --  source pragma which appears at the top of [generic] package
               --  declarations or after an object, a [generic] subprogram, or
               --  a type declaration.

               when Aspect_Ghost =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Ghost);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Global

               --  Aspect Global is never delayed because it is equivalent to
               --  a source pragma which appears after the related subprogram.
               --  To deal with forward references, the generated pragma is
               --  stored in the contract of the related subprogram and later
               --  analyzed at the end of the declarative region. See routine
               --  Analyze_Global_In_Decl_Part for details.

               when Aspect_Global =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Global);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Initial_Condition

               --  Aspect Initial_Condition is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related package. To deal with forward references, the
               --  generated pragma is stored in the contract of the related
               --  package and later analyzed at the end of the declarative
               --  region. See routine Analyze_Initial_Condition_In_Decl_Part
               --  for details.

               when Aspect_Initial_Condition => Initial_Condition : declare
                  Context : Node_Id := N;

               begin
                  --  When aspect Initial_Condition appears on a generic
                  --  package, it is propagated to the package instance. The
                  --  context in this case is the instance spec.

                  if Nkind (Context) = N_Package_Instantiation then
                     Context := Instance_Spec (Context);
                  end if;

                  if Nkind (Context) in N_Generic_Package_Declaration
                                      | N_Package_Declaration
                  then
                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => New_List (
                          Make_Pragma_Argument_Association (Loc,
                            Expression => Relocate_Node (Expr))),
                        Pragma_Name                  =>
                          Name_Initial_Condition);

                     Decorate (Aspect, Aitem);
                     Insert_Pragma
                       (Prag        => Aitem,
                        Is_Instance =>
                          Is_Generic_Instance (Defining_Entity (Context)));

                  --  Otherwise the context is illegal

                  else
                     Error_Msg_NE
                       ("aspect & must apply to a package declaration",
                        Aspect, Id);
                  end if;

                  goto Continue;
               end Initial_Condition;

               --  Initializes

               --  Aspect Initializes is never delayed because it is equivalent
               --  to a source pragma appearing after the related package. To
               --  deal with forward references, the generated pragma is stored
               --  in the contract of the related package and later analyzed at
               --  the end of the declarative region. For details, see routine
               --  Analyze_Initializes_In_Decl_Part.

               when Aspect_Initializes => Initializes : declare
                  Context : Node_Id := N;

               begin
                  --  When aspect Initializes appears on a generic package,
                  --  it is propagated to the package instance. The context
                  --  in this case is the instance spec.

                  if Nkind (Context) = N_Package_Instantiation then
                     Context := Instance_Spec (Context);
                  end if;

                  if Nkind (Context) in N_Generic_Package_Declaration
                                      | N_Package_Declaration
                  then
                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => New_List (
                          Make_Pragma_Argument_Association (Loc,
                            Expression => Relocate_Node (Expr))),
                        Pragma_Name                  => Name_Initializes);

                     Decorate (Aspect, Aitem);
                     Insert_Pragma
                       (Prag        => Aitem,
                        Is_Instance =>
                          Is_Generic_Instance (Defining_Entity (Context)));

                  --  Otherwise the context is illegal

                  else
                     Error_Msg_NE
                       ("aspect & must apply to a package declaration",
                        Aspect, Id);
                  end if;

                  goto Continue;
               end Initializes;

               --  Max_Entry_Queue_Depth

               when Aspect_Max_Entry_Queue_Depth =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name => Name_Max_Entry_Queue_Depth);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Max_Entry_Queue_Length

               when Aspect_Max_Entry_Queue_Length =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name => Name_Max_Entry_Queue_Length);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Max_Queue_Length

               when Aspect_Max_Queue_Length =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Max_Queue_Length);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Aspect No_Caching is never delayed because it is equivalent
               --  to a source pragma which appears after the related object
               --  declaration.

               when Aspect_No_Caching =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_No_Caching);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  No_Controlled_Parts, No_Task_Parts

               when Aspect_No_Controlled_Parts | Aspect_No_Task_Parts =>

                  --  Check appropriate type argument

                  if not Is_Type (E) then
                     Error_Msg_N
                       ("aspect % can only be applied to types", E);
                  end if;

                  --  Disallow subtypes

                  if Nkind (Declaration_Node (E)) = N_Subtype_Declaration then
                     Error_Msg_N
                       ("aspect % cannot be applied to subtypes", E);
                  end if;

                  --  Resolve the expression to a boolean

                  if Present (Expr) then
                     Check_Expr_Is_OK_Static_Expression (Expr, Any_Boolean);
                  end if;

                  goto Continue;

               --  Obsolescent

               when Aspect_Obsolescent => declare
                  Args : List_Id;

               begin
                  if No (Expr) then
                     Args := No_List;
                  else
                     Args := New_List (
                       Make_Pragma_Argument_Association (Sloc (Expr),
                         Expression => Relocate_Node (Expr)));
                  end if;

                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => Args,
                     Pragma_Name                  => Name_Obsolescent);
               end;

               --  Part_Of

               when Aspect_Part_Of =>
                  if Nkind (N) in N_Object_Declaration
                                | N_Package_Instantiation
                    or else Is_Single_Concurrent_Type_Declaration (N)
                  then
                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => New_List (
                          Make_Pragma_Argument_Association (Loc,
                            Expression => Relocate_Node (Expr))),
                        Pragma_Name                  => Name_Part_Of);

                     Decorate (Aspect, Aitem);
                     Insert_Pragma (Aitem);

                  else
                     Error_Msg_NE
                       ("aspect & must apply to package instantiation, "
                        & "object, single protected type or single task type",
                        Aspect, Id);
                  end if;

                  goto Continue;

               --  SPARK_Mode

               when Aspect_SPARK_Mode =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_SPARK_Mode);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Refined_Depends

               --  Aspect Refined_Depends is never delayed because it is
               --  equivalent to a source pragma which appears in the
               --  declarations of the related subprogram body. To deal with
               --  forward references, the generated pragma is stored in the
               --  contract of the related subprogram body and later analyzed
               --  at the end of the declarative region. For details, see
               --  routine Analyze_Refined_Depends_In_Decl_Part.

               when Aspect_Refined_Depends =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Refined_Depends);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Refined_Global

               --  Aspect Refined_Global is never delayed because it is
               --  equivalent to a source pragma which appears in the
               --  declarations of the related subprogram body. To deal with
               --  forward references, the generated pragma is stored in the
               --  contract of the related subprogram body and later analyzed
               --  at the end of the declarative region. For details, see
               --  routine Analyze_Refined_Global_In_Decl_Part.

               when Aspect_Refined_Global =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Refined_Global);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Refined_Post

               when Aspect_Refined_Post =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Refined_Post);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Refined_State

               when Aspect_Refined_State =>

                  --  The corresponding pragma for Refined_State is inserted in
                  --  the declarations of the related package body. This action
                  --  synchronizes both the source and from-aspect versions of
                  --  the pragma.

                  if Nkind (N) = N_Package_Body then
                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => New_List (
                          Make_Pragma_Argument_Association (Loc,
                            Expression => Relocate_Node (Expr))),
                        Pragma_Name                  => Name_Refined_State);

                     Decorate (Aspect, Aitem);
                     Insert_Pragma (Aitem);

                  --  Otherwise the context is illegal

                  else
                     Error_Msg_NE
                       ("aspect & must apply to a package body", Aspect, Id);
                  end if;

                  goto Continue;

               --  Relative_Deadline

               when Aspect_Relative_Deadline =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                      Pragma_Name                 => Name_Relative_Deadline);

                  --  If the aspect applies to a task, the corresponding pragma
                  --  must appear within its declarations, not after.

                  if Nkind (N) = N_Task_Type_Declaration then
                     declare
                        Def : Node_Id;
                        V   : List_Id;

                     begin
                        if No (Task_Definition (N)) then
                           Set_Task_Definition (N,
                             Make_Task_Definition (Loc,
                                Visible_Declarations => New_List,
                                End_Label => Empty));
                        end if;

                        Def := Task_Definition (N);
                        V  := Visible_Declarations (Def);
                        if not Is_Empty_List (V) then
                           Insert_Before (First (V), Aitem);

                        else
                           Set_Visible_Declarations (Def, New_List (Aitem));
                        end if;

                        goto Continue;
                     end;
                  end if;

               --  Relaxed_Initialization

               when Aspect_Relaxed_Initialization =>
                  Analyze_Aspect_Relaxed_Initialization;
                  goto Continue;

               --  Secondary_Stack_Size

               --  Aspect Secondary_Stack_Size needs to be converted into a
               --  pragma for two reasons: the attribute is not analyzed until
               --  after the expansion of the task type declaration and the
               --  attribute does not have visibility on the discriminant.

               when Aspect_Secondary_Stack_Size =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  =>
                       Name_Secondary_Stack_Size);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Volatile_Function

               --  Aspect Volatile_Function is never delayed because it is
               --  equivalent to a source pragma which appears after the
               --  related subprogram.

               when Aspect_Volatile_Function =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Volatile_Function);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Case 2e: Annotate aspect

               when Aspect_Annotate | Aspect_GNAT_Annotate =>
                  declare
                     Args  : List_Id;
                     Pargs : List_Id;
                     Arg   : Node_Id;

                  begin
                     --  The argument can be a single identifier

                     if Nkind (Expr) = N_Identifier then

                        --  One level of parens is allowed

                        if Paren_Count (Expr) > 1 then
                           Error_Msg_F ("extra parentheses ignored", Expr);
                        end if;

                        Set_Paren_Count (Expr, 0);

                        --  Add the single item to the list

                        Args := New_List (Expr);

                     --  Otherwise we must have an aggregate

                     elsif Nkind (Expr) = N_Aggregate then

                        --  Must be positional

                        if Present (Component_Associations (Expr)) then
                           Error_Msg_F
                             ("purely positional aggregate required", Expr);
                           goto Continue;
                        end if;

                        --  Must not be parenthesized

                        if Paren_Count (Expr) /= 0 then
                           Error_Msg_F -- CODEFIX
                             ("redundant parentheses", Expr);
                        end if;

                        --  List of arguments is list of aggregate expressions

                        Args := Expressions (Expr);

                     --  Anything else is illegal

                     else
                        Error_Msg_F ("wrong form for Annotate aspect", Expr);
                        goto Continue;
                     end if;

                     --  Prepare pragma arguments

                     Pargs := New_List;
                     Arg := First (Args);
                     while Present (Arg) loop
                        Append_To (Pargs,
                          Make_Pragma_Argument_Association (Sloc (Arg),
                            Expression => Relocate_Node (Arg)));
                        Next (Arg);
                     end loop;

                     Append_To (Pargs,
                       Make_Pragma_Argument_Association (Sloc (Ent),
                         Chars      => Name_Entity,
                         Expression => Ent));

                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => Pargs,
                        Pragma_Name                  => Name_Annotate);
                  end;

               --  Case 3 : Aspects that don't correspond to pragma/attribute
               --  definition clause.

               --  Case 3a: The aspects listed below don't correspond to
               --  pragmas/attributes but do require delayed analysis.

               when Aspect_Default_Value | Aspect_Default_Component_Value =>
                  Error_Msg_Name_1 := Nam;

                  if not Is_Type (E) then
                     Error_Msg_N ("aspect% can only apply to a type", Id);
                     goto Continue;

                  elsif not Is_First_Subtype (E) then
                     Error_Msg_N ("aspect% cannot apply to subtype", Id);
                     goto Continue;

                  elsif A_Id = Aspect_Default_Value
                    and then not Is_Scalar_Type (E)
                  then
                     Error_Msg_N
                       ("aspect% can only be applied to scalar type", Id);
                     goto Continue;

                  elsif A_Id = Aspect_Default_Component_Value then
                     if not Is_Array_Type (E) then
                        Error_Msg_N
                          ("aspect% can only be applied to array type", Id);
                        goto Continue;

                     elsif not Is_Scalar_Type (Component_Type (E)) then
                        Error_Msg_N ("aspect% requires scalar components", Id);
                        goto Continue;
                     end if;
                  end if;

                  Aitem := Empty;

               when Aspect_Aggregate =>
                  Validate_Aspect_Aggregate (Expr);
                  Record_Rep_Item (E, Aspect);
                  goto Continue;

               when Aspect_Stable_Properties =>
                  Validate_Aspect_Stable_Properties
                    (E, Expr, Class_Present => Class_Present (Aspect));
                  Record_Rep_Item (E, Aspect);
                  goto Continue;

               when Aspect_Designated_Storage_Model =>
                  if not Extensions_Allowed then
                     Error_Msg_N
                       ("aspect only allowed if extensions enabled",
                        Aspect);
                     Error_Msg_N
                       ("\unit must be compiled with -gnatX switch", Aspect);

                  elsif not Is_Type (E)
                    or else Ekind (E) /= E_Access_Type
                  then
                     Error_Msg_N
                       ("can only be specified for pool-specific access type",
                        Aspect);
                  end if;

                  Record_Rep_Item (E, Aspect);
                  goto Continue;

               when Aspect_Storage_Model_Type =>
                  if not Extensions_Allowed then
                     Error_Msg_N
                       ("aspect only allowed if extensions enabled",
                        Aspect);
                     Error_Msg_N
                       ("\unit must be compiled with -gnatX switch", Aspect);

                  elsif not Is_Type (E)
                    or else not Is_Immutably_Limited_Type (E)
                  then
                     Error_Msg_N
                       ("can only be specified for immutably limited type",
                        Aspect);
                  end if;

                  Record_Rep_Item (E, Aspect);
                  goto Continue;

               when Aspect_Integer_Literal
                  | Aspect_Real_Literal
                  | Aspect_String_Literal
               =>

                  if not Is_First_Subtype (E) then
                     Error_Msg_N
                       ("may only be specified for a first subtype", Aspect);
                     goto Continue;
                  end if;

                  if Ada_Version < Ada_2022 then
                     Check_Restriction
                       (No_Implementation_Aspect_Specifications, N);
                  end if;

                  Aitem := Empty;

               --  Case 3b: The aspects listed below don't correspond to
               --  pragmas/attributes and don't need delayed analysis.

               --  Implicit_Dereference

               --  For Implicit_Dereference, External_Name and Link_Name, only
               --  the legality checks are done during the analysis, thus no
               --  delay is required.

               when Aspect_Implicit_Dereference =>
                  Analyze_Aspect_Implicit_Dereference;
                  goto Continue;

               --  Dimension

               when Aspect_Dimension =>
                  Analyze_Aspect_Dimension (N, Id, Expr);
                  goto Continue;

               --  Dimension_System

               when Aspect_Dimension_System =>
                  Analyze_Aspect_Dimension_System (N, Id, Expr);
                  goto Continue;

               --  Case 4: Aspects requiring special handling

               --  Pre/Post/Test_Case/Contract_Cases/Subprogram_Variant whose
               --  corresponding pragmas take care of the delay.

               --  Pre/Post

               --  Aspects Pre/Post generate Precondition/Postcondition pragmas
               --  with a first argument that is the expression, and a second
               --  argument that is an informative message if the test fails.
               --  This is inserted right after the declaration, to get the
               --  required pragma placement. The processing for the pragmas
               --  takes care of the required delay.

               when Pre_Post_Aspects => Pre_Post : declare
                  Pname : Name_Id;

               begin
                  if A_Id in Aspect_Pre | Aspect_Precondition then
                     Pname := Name_Precondition;
                  else
                     Pname := Name_Postcondition;
                  end if;

                  --  Check that the class-wide predicate cannot be applied to
                  --  an operation of a synchronized type. AI12-0182 forbids
                  --  these altogether, while earlier language semantics made
                  --  them legal on tagged synchronized types.

                  --  Other legality checks are performed when analyzing the
                  --  contract of the operation.

                  if Class_Present (Aspect)
                    and then Is_Concurrent_Type (Current_Scope)
                    and then Ekind (E) in E_Entry | E_Function | E_Procedure
                  then
                     Error_Msg_Name_1 := Original_Aspect_Pragma_Name (Aspect);
                     Error_Msg_N
                       ("aspect % can only be specified for a primitive "
                        & "operation of a tagged type", Aspect);

                     goto Continue;
                  end if;

                  --  Remember class-wide conditions; they will be merged
                  --  with inherited conditions.

                  if Class_Present (Aspect)
                    and then A_Id in Aspect_Pre | Aspect_Post
                    and then Is_Subprogram (E)
                    and then not Is_Ignored_Ghost_Entity (E)
                  then
                     if A_Id = Aspect_Pre then
                        if Is_Ignored (Aspect) then
                           Set_Ignored_Class_Preconditions (E,
                             New_Copy_Tree (Expr));
                        else
                           Set_Class_Preconditions (E, New_Copy_Tree (Expr));
                        end if;

                     --  Postconditions may split into separate aspects, and we
                     --  remember the expression before such split (i.e. when
                     --  the first postcondition is processed).

                     elsif No (Class_Postconditions (E))
                       and then No (Ignored_Class_Postconditions (E))
                     then
                        if Is_Ignored (Aspect) then
                           Set_Ignored_Class_Postconditions (E,
                             New_Copy_Tree (Expr));
                        else
                           Set_Class_Postconditions (E, New_Copy_Tree (Expr));
                        end if;
                     end if;
                  end if;

                  --  If the expressions is of the form A and then B, then
                  --  we generate separate Pre/Post aspects for the separate
                  --  clauses. Since we allow multiple pragmas, there is no
                  --  problem in allowing multiple Pre/Post aspects internally.
                  --  These should be treated in reverse order (B first and
                  --  A second) since they are later inserted just after N in
                  --  the order they are treated. This way, the pragma for A
                  --  ends up preceding the pragma for B, which may have an
                  --  importance for the error raised (either constraint error
                  --  or precondition error).

                  --  We do not do this for Pre'Class, since we have to put
                  --  these conditions together in a complex OR expression.

                  --  We don't do this in GNATprove mode, because it brings no
                  --  benefit for proof and causes annoyance for flow analysis,
                  --  which prefers to be as close to the original source code
                  --  as possible. Also we don't do this when analyzing generic
                  --  units since it causes spurious visibility errors in the
                  --  preanalysis of instantiations.

                  if not GNATprove_Mode
                    and then (Pname = Name_Postcondition
                               or else not Class_Present (Aspect))
                    and then not Inside_A_Generic
                  then
                     while Nkind (Expr) = N_And_Then loop
                        Insert_After (Aspect,
                          Make_Aspect_Specification (Sloc (Left_Opnd (Expr)),
                            Identifier    => Identifier (Aspect),
                            Expression    => Relocate_Node (Left_Opnd (Expr)),
                            Class_Present => Class_Present (Aspect),
                            Split_PPC     => True));
                        Rewrite (Expr, Relocate_Node (Right_Opnd (Expr)));
                        Eloc := Sloc (Expr);
                     end loop;
                  end if;

                  --  Build the precondition/postcondition pragma

                  --  We use Relocate_Node here rather than New_Copy_Tree
                  --  because subsequent visibility analysis of the aspect
                  --  depends on this sharing. This should be cleaned up???

                  --  If the context is generic, we want to preserve the
                  --  original tree, and simply share it between aspect and
                  --  generated attribute. This parallels what is done in
                  --  sem_prag.adb (see Get_Argument).

                  declare
                     New_Expr : Node_Id;

                  begin
                     if Inside_A_Generic then
                        New_Expr := Expr;
                     else
                        New_Expr := Relocate_Node (Expr);
                     end if;

                     Aitem := Make_Aitem_Pragma
                       (Pragma_Argument_Associations => New_List (
                          Make_Pragma_Argument_Association (Eloc,
                            Chars      => Name_Check,
                            Expression => New_Expr)),
                          Pragma_Name                => Pname);
                  end;

                  --  Add message unless exception messages are suppressed

                  if not Opt.Exception_Locations_Suppressed then
                     Append_To (Pragma_Argument_Associations (Aitem),
                       Make_Pragma_Argument_Association (Eloc,
                         Chars      => Name_Message,
                         Expression =>
                           Make_String_Literal (Eloc,
                             Strval => "failed "
                                       & Get_Name_String (Pname)
                                       & " from "
                                       & Build_Location_String (Eloc))));
                  end if;

                  Set_Is_Delayed_Aspect (Aspect);

                  --  For Pre/Post cases, insert immediately after the entity
                  --  declaration, since that is the required pragma placement.
                  --  Note that for these aspects, we do not have to worry
                  --  about delay issues, since the pragmas themselves deal
                  --  with delay of visibility for the expression analysis.

                  Insert_Pragma (Aitem);

                  goto Continue;
               end Pre_Post;

               --  Test_Case

               when Aspect_Test_Case => Test_Case : declare
                  Args      : List_Id;
                  Comp_Expr : Node_Id;
                  Comp_Assn : Node_Id;

               begin
                  Args := New_List;

                  if Nkind (Parent (N)) = N_Compilation_Unit then
                     Error_Msg_Name_1 := Nam;
                     Error_Msg_N ("incorrect placement of aspect %", E);
                     goto Continue;
                  end if;

                  if Nkind (Expr) /= N_Aggregate
                    or else Null_Record_Present (Expr)
                  then
                     Error_Msg_Name_1 := Nam;
                     Error_Msg_NE
                       ("wrong syntax for aspect % for &", Id, E);
                     goto Continue;
                  end if;

                  --  Check that the expression is a proper aggregate (no
                  --  parentheses).

                  if Paren_Count (Expr) /= 0 then
                     Error_Msg_F -- CODEFIX
                       ("redundant parentheses", Expr);
                     goto Continue;
                  end if;

                  --  Create the list of arguments for building the Test_Case
                  --  pragma.

                  Comp_Expr := First (Expressions (Expr));
                  while Present (Comp_Expr) loop
                     Append_To (Args,
                       Make_Pragma_Argument_Association (Sloc (Comp_Expr),
                         Expression => Relocate_Node (Comp_Expr)));
                     Next (Comp_Expr);
                  end loop;

                  Comp_Assn := First (Component_Associations (Expr));
                  while Present (Comp_Assn) loop
                     if List_Length (Choices (Comp_Assn)) /= 1
                       or else
                         Nkind (First (Choices (Comp_Assn))) /= N_Identifier
                     then
                        Error_Msg_Name_1 := Nam;
                        Error_Msg_NE
                          ("wrong syntax for aspect % for &", Id, E);
                        goto Continue;
                     end if;

                     Append_To (Args,
                       Make_Pragma_Argument_Association (Sloc (Comp_Assn),
                         Chars      => Chars (First (Choices (Comp_Assn))),
                         Expression =>
                           Relocate_Node (Expression (Comp_Assn))));
                     Next (Comp_Assn);
                  end loop;

                  --  Build the test-case pragma

                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => Args,
                     Pragma_Name                  => Name_Test_Case);
               end Test_Case;

               --  Contract_Cases

               when Aspect_Contract_Cases =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Contract_Cases);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Subprogram_Variant

               when Aspect_Subprogram_Variant =>
                  Aitem := Make_Aitem_Pragma
                    (Pragma_Argument_Associations => New_List (
                       Make_Pragma_Argument_Association (Loc,
                         Expression => Relocate_Node (Expr))),
                     Pragma_Name                  => Name_Subprogram_Variant);

                  Decorate (Aspect, Aitem);
                  Insert_Pragma (Aitem);
                  goto Continue;

               --  Case 5: Special handling for aspects with an optional
               --  boolean argument.

               --  In the delayed case, the corresponding pragma cannot be
               --  generated yet because the evaluation of the boolean needs
               --  to be delayed till the freeze point.

               when Boolean_Aspects
                  | Library_Unit_Aspects
               =>
                  Set_Is_Boolean_Aspect (Aspect);

                  --  Lock_Free aspect only apply to protected objects

                  if A_Id = Aspect_Lock_Free then
                     if Ekind (E) /= E_Protected_Type then
                        Error_Msg_Name_1 := Nam;
                        Error_Msg_N
                          ("aspect % only applies to a protected type " &
                           "or object",
                           Aspect);

                     else
                        --  Set the Uses_Lock_Free flag to True if there is no
                        --  expression or if the expression is True. The
                        --  evaluation of this aspect should be delayed to the
                        --  freeze point if we wanted to handle the corner case
                        --  of "true" or "false" being redefined.

                        if No (Expr)
                          or else Is_True (Static_Boolean (Expr))
                        then
                           Set_Uses_Lock_Free (E);
                        end if;

                        Record_Rep_Item (E, Aspect);
                     end if;

                     goto Continue;

                  elsif A_Id in Aspect_Export | Aspect_Import then
                     Analyze_Aspect_Export_Import;

                  --  Disable_Controlled

                  elsif A_Id = Aspect_Disable_Controlled then
                     Analyze_Aspect_Disable_Controlled;
                     goto Continue;

                  --  Ada 2022 (AI12-0129): Exclusive_Functions

                  elsif A_Id = Aspect_Exclusive_Functions then
                     if Ekind (E) /= E_Protected_Type then
                        Error_Msg_Name_1 := Nam;
                        Error_Msg_N
                          ("aspect % only applies to a protected type " &
                           "or object",
                           Aspect);
                     end if;

                     goto Continue;

                  --  Ada 2022 (AI12-0363): Full_Access_Only

                  elsif A_Id = Aspect_Full_Access_Only then
                     Error_Msg_Ada_2022_Feature ("aspect %", Sloc (Aspect));

                  --  Ada 2022 (AI12-0075): static expression functions

                  elsif A_Id = Aspect_Static then
                     Analyze_Aspect_Static;
                     goto Continue;

                  --  Ada 2022 (AI12-0279)

                  elsif A_Id = Aspect_Yield then
                     Analyze_Aspect_Yield;
                     goto Continue;
                  end if;

                  --  Library unit aspects require special handling in the case
                  --  of a package declaration, the pragma needs to be inserted
                  --  in the list of declarations for the associated package.
                  --  There is no issue of visibility delay for these aspects.

                  if A_Id in Library_Unit_Aspects
                    and then
                      Nkind (N) in N_Package_Declaration
                                 | N_Generic_Package_Declaration
                    and then Nkind (Parent (N)) /= N_Compilation_Unit

                    --  Aspect is legal on a local instantiation of a library-
                    --  level generic unit.

                    and then not Is_Generic_Instance (Defining_Entity (N))
                  then
                     Error_Msg_N
                       ("incorrect context for library unit aspect&", Id);
                     goto Continue;
                  end if;

                  --  Cases where we do not delay

                  if not Delay_Required then

                     --  Exclude aspects Export and Import because their pragma
                     --  syntax does not map directly to a Boolean aspect.

                     if A_Id not in Aspect_Export | Aspect_Import then
                        Aitem := Make_Aitem_Pragma
                          (Pragma_Argument_Associations => New_List (
                             Make_Pragma_Argument_Association (Sloc (Ent),
                               Expression => Ent)),
                           Pragma_Name                  => Nam);
                     end if;

                  --  In general cases, the corresponding pragma/attribute
                  --  definition clause will be inserted later at the freezing
                  --  point, and we do not need to build it now.

                  else
                     Aitem := Empty;
                  end if;

               --  Storage_Size

               --  This is special because for access types we need to generate
               --  an attribute definition clause. This also works for single
               --  task declarations, but it does not work for task type
               --  declarations, because we have the case where the expression
               --  references a discriminant of the task type. That can't use
               --  an attribute definition clause because we would not have
               --  visibility on the discriminant. For that case we must
               --  generate a pragma in the task definition.

               when Aspect_Storage_Size =>

                  --  Task type case

                  if Ekind (E) = E_Task_Type then
                     declare
                        Decl : constant Node_Id := Declaration_Node (E);

                     begin
                        pragma Assert (Nkind (Decl) = N_Task_Type_Declaration);

                        --  If no task definition, create one

                        if No (Task_Definition (Decl)) then
                           Set_Task_Definition (Decl,
                             Make_Task_Definition (Loc,
                               Visible_Declarations => Empty_List,
                               End_Label            => Empty));
                        end if;

                        --  Create a pragma and put it at the start of the task
                        --  definition for the task type declaration.

                        Aitem := Make_Aitem_Pragma
                          (Pragma_Argument_Associations => New_List (
                             Make_Pragma_Argument_Association (Loc,
                               Expression => Relocate_Node (Expr))),
                           Pragma_Name                  => Name_Storage_Size);

                        Prepend
                          (Aitem,
                           Visible_Declarations (Task_Definition (Decl)));
                        goto Continue;
                     end;

                  --  All other cases, generate attribute definition

                  else
                     Aitem :=
                       Make_Attribute_Definition_Clause (Loc,
                         Name       => Ent,
                         Chars      => Name_Storage_Size,
                         Expression => Relocate_Node (Expr));
                  end if;
            end case;

            --  Attach the corresponding pragma/attribute definition clause to
            --  the aspect specification node.

            if Present (Aitem) then
               Set_From_Aspect_Specification (Aitem);
            end if;

            --  For an aspect that applies to a type, indicate whether it
            --  appears on a partial view of the type.

            if Is_Type (E)
              and then Is_Private_Type (E)
            then
               Set_Aspect_On_Partial_View (Aspect);
            end if;

            --  In the context of a compilation unit, we directly put the
            --  pragma in the Pragmas_After list of the N_Compilation_Unit_Aux
            --  node (no delay is required here) except for aspects on a
            --  subprogram body (see below) and a generic package, for which we
            --  need to introduce the pragma before building the generic copy
            --  (see sem_ch12), and for package instantiations, where the
            --  library unit pragmas are better handled early.

            if Nkind (Parent (N)) = N_Compilation_Unit
              and then (Present (Aitem) or else Is_Boolean_Aspect (Aspect))
            then
               declare
                  Aux : constant Node_Id := Aux_Decls_Node (Parent (N));

               begin
                  pragma Assert (Nkind (Aux) = N_Compilation_Unit_Aux);

                  --  For a Boolean aspect, create the corresponding pragma if
                  --  no expression or if the value is True.

                  if Is_Boolean_Aspect (Aspect) and then No (Aitem) then
                     if Is_True (Static_Boolean (Expr)) then
                        Aitem := Make_Aitem_Pragma
                          (Pragma_Argument_Associations => New_List (
                             Make_Pragma_Argument_Association (Sloc (Ent),
                               Expression => Ent)),
                           Pragma_Name                  => Nam);

                        Set_From_Aspect_Specification (Aitem, True);
                        Set_Corresponding_Aspect (Aitem, Aspect);

                     else
                        goto Continue;
                     end if;
                  end if;

                  --  If the aspect is on a subprogram body (relevant aspect
                  --  is Inline), add the pragma in front of the declarations.

                  if Nkind (N) = N_Subprogram_Body then
                     if No (Declarations (N)) then
                        Set_Declarations (N, New_List);
                     end if;

                     Prepend (Aitem, Declarations (N));

                  elsif Nkind (N) = N_Generic_Package_Declaration then
                     if No (Visible_Declarations (Specification (N))) then
                        Set_Visible_Declarations (Specification (N), New_List);
                     end if;

                     Prepend (Aitem,
                       Visible_Declarations (Specification (N)));

                  elsif Nkind (N) = N_Package_Instantiation then
                     declare
                        Spec : constant Node_Id :=
                                 Specification (Instance_Spec (N));
                     begin
                        if No (Visible_Declarations (Spec)) then
                           Set_Visible_Declarations (Spec, New_List);
                        end if;

                        Prepend (Aitem, Visible_Declarations (Spec));
                     end;

                  else
                     if No (Pragmas_After (Aux)) then
                        Set_Pragmas_After (Aux, New_List);
                     end if;

                     Append (Aitem, Pragmas_After (Aux));
                  end if;

                  goto Continue;
               end;
            end if;

            --  The evaluation of the aspect is delayed to the freezing point.
            --  The pragma or attribute clause if there is one is then attached
            --  to the aspect specification which is put in the rep item list.

            if Delay_Required then
               if Present (Aitem) then
                  Set_Is_Delayed_Aspect (Aitem);
                  Set_Aspect_Rep_Item (Aspect, Aitem);
                  Set_Parent (Aitem, Aspect);
               end if;

               Set_Is_Delayed_Aspect (Aspect);

               --  In the case of Default_Value, link the aspect to base type
               --  as well, even though it appears on a first subtype. This is
               --  mandated by the semantics of the aspect. Do not establish
               --  the link when processing the base type itself as this leads
               --  to a rep item circularity.

               if A_Id = Aspect_Default_Value and then Base_Type (E) /= E then
                  Set_Has_Delayed_Aspects (Base_Type (E));
                  Record_Rep_Item (Base_Type (E), Aspect);
               end if;

               Set_Has_Delayed_Aspects (E);
               Record_Rep_Item (E, Aspect);

            --  When delay is not required and the context is a package or a
            --  subprogram body, insert the pragma in the body declarations.

            elsif Nkind (N) in N_Package_Body | N_Subprogram_Body then
               if No (Declarations (N)) then
                  Set_Declarations (N, New_List);
               end if;

               --  The pragma is added before source declarations

               Prepend_To (Declarations (N), Aitem);

            --  When delay is not required and the context is not a compilation
            --  unit, we simply insert the pragma/attribute definition clause
            --  in sequence.

            elsif Present (Aitem) then
               Insert_After (Ins_Node, Aitem);
               Ins_Node := Aitem;
            end if;

            <<Continue>>

            --  If a nonoverridable aspect is explicitly specified for a
            --  derived type, then check consistency with the parent type.

            if A_Id in Nonoverridable_Aspect_Id
              and then Nkind (N) = N_Full_Type_Declaration
              and then Nkind (Type_Definition (N)) = N_Derived_Type_Definition
              and then not In_Instance_Body
            then
               declare
                  Parent_Type      : constant Entity_Id := Etype (E);
                  Inherited_Aspect : constant Node_Id :=
                    Find_Aspect (Parent_Type, A_Id);
               begin
                  if Present (Inherited_Aspect)
                    and then not Is_Confirming
                                   (A_Id, Inherited_Aspect, Aspect)
                  then
                     Error_Msg_Name_1 := Aspect_Names (A_Id);
                     Error_Msg_Sloc := Sloc (Inherited_Aspect);

                     Error_Msg_N
                       ("overriding aspect specification for "
                          & "nonoverridable aspect % does not confirm "
                          & "aspect specification inherited from #",
                        Aspect);
                  end if;
               end;
            end if;
         exception
            when Aspect_Exit => null;
         end Analyze_One_Aspect;

         Next (Aspect);
      end loop Aspect_Loop;

      if Has_Delayed_Aspects (E) then
         Ensure_Freeze_Node (E);
      end if;
   end Analyze_Aspect_Specifications;

   ------------------------------------------------
   -- Analyze_Aspects_On_Subprogram_Body_Or_Stub --
   ------------------------------------------------

   procedure Analyze_Aspects_On_Subprogram_Body_Or_Stub (N : Node_Id) is
      Body_Id : constant Entity_Id := Defining_Entity (N);

      procedure Diagnose_Misplaced_Aspects (Spec_Id : Entity_Id);
      --  Body [stub] N has aspects, but they are not properly placed. Emit an
      --  error message depending on the aspects involved. Spec_Id denotes the
      --  entity of the corresponding spec.

      --------------------------------
      -- Diagnose_Misplaced_Aspects --
      --------------------------------

      procedure Diagnose_Misplaced_Aspects (Spec_Id : Entity_Id) is
         procedure Misplaced_Aspect_Error
           (Asp     : Node_Id;
            Ref_Nam : Name_Id);
         --  Emit an error message concerning misplaced aspect Asp. Ref_Nam is
         --  the name of the refined version of the aspect.

         ----------------------------
         -- Misplaced_Aspect_Error --
         ----------------------------

         procedure Misplaced_Aspect_Error
           (Asp     : Node_Id;
            Ref_Nam : Name_Id)
         is
            Asp_Nam : constant Name_Id   := Chars (Identifier (Asp));
            Asp_Id  : constant Aspect_Id := Get_Aspect_Id (Asp_Nam);

         begin
            --  The corresponding spec already contains the aspect in question
            --  and the one appearing on the body must be the refined form:

            --    procedure P with Global ...;
            --    procedure P with Global ... is ... end P;
            --                     ^
            --                     Refined_Global

            if Has_Aspect (Spec_Id, Asp_Id) then
               Error_Msg_Name_1 := Asp_Nam;

               --  Subunits cannot carry aspects that apply to a subprogram
               --  declaration.

               if Nkind (Parent (N)) = N_Subunit then
                  Error_Msg_N ("aspect % cannot apply to a subunit", Asp);

               --  Otherwise suggest the refined form

               else
                  Error_Msg_Name_2 := Ref_Nam;
                  Error_Msg_N ("aspect % should be %", Asp);
               end if;

            --  Otherwise the aspect must appear on the spec, not on the body

            --    procedure P;
            --    procedure P with Global ... is ... end P;

            else
               Error_Msg_N
                 ("aspect specification must appear on initial declaration",
                  Asp);
            end if;
         end Misplaced_Aspect_Error;

         --  Local variables

         Asp     : Node_Id;
         Asp_Nam : Name_Id;

      --  Start of processing for Diagnose_Misplaced_Aspects

      begin
         --  Iterate over the aspect specifications and emit specific errors
         --  where applicable.

         Asp := First (Aspect_Specifications (N));
         while Present (Asp) loop
            Asp_Nam := Chars (Identifier (Asp));

            --  Do not emit errors on aspects that can appear on a subprogram
            --  body. This scenario occurs when the aspect specification list
            --  contains both misplaced and properly placed aspects.

            if Aspect_On_Body_Or_Stub_OK (Get_Aspect_Id (Asp_Nam)) then
               null;

            --  Special diagnostics for SPARK aspects

            elsif Asp_Nam = Name_Depends then
               Misplaced_Aspect_Error (Asp, Name_Refined_Depends);

            elsif Asp_Nam = Name_Global then
               Misplaced_Aspect_Error (Asp, Name_Refined_Global);

            elsif Asp_Nam = Name_Post then
               Misplaced_Aspect_Error (Asp, Name_Refined_Post);

            --  Otherwise a language-defined aspect is misplaced

            else
               Error_Msg_N
                 ("aspect specification must appear on initial declaration",
                  Asp);
            end if;

            Next (Asp);
         end loop;
      end Diagnose_Misplaced_Aspects;

      --  Local variables

      Spec_Id : constant Entity_Id := Unique_Defining_Entity (N);

   --  Start of processing for Analyze_Aspects_On_Subprogram_Body_Or_Stub

   begin
      --  Language-defined aspects cannot be associated with a subprogram body
      --  [stub] if the subprogram has a spec. Certain implementation defined
      --  aspects are allowed to break this rule (for all applicable cases, see
      --  table Aspects.Aspect_On_Body_Or_Stub_OK).

      if Spec_Id /= Body_Id and then not Aspects_On_Body_Or_Stub_OK (N) then
         Diagnose_Misplaced_Aspects (Spec_Id);
      else
         Analyze_Aspect_Specifications (N, Body_Id);
      end if;
   end Analyze_Aspects_On_Subprogram_Body_Or_Stub;

   -----------------------
   -- Analyze_At_Clause --
   -----------------------

   --  An at clause is replaced by the corresponding Address attribute
   --  definition clause that is the preferred approach in Ada 95.

   procedure Analyze_At_Clause (N : Node_Id) is
      CS : constant Boolean := Comes_From_Source (N);

   begin
      --  This is an obsolescent feature

      Check_Restriction (No_Obsolescent_Features, N);

      if Warn_On_Obsolescent_Feature then
         Error_Msg_N
           ("?j?at clause is an obsolescent feature (RM J.7(2))", N);
         Error_Msg_N
           ("\?j?use address attribute definition clause instead", N);
      end if;

      --  Rewrite as address clause

      Rewrite (N,
        Make_Attribute_Definition_Clause (Sloc (N),
          Name       => Identifier (N),
          Chars      => Name_Address,
          Expression => Expression (N)));

      --  We preserve Comes_From_Source, since logically the clause still comes
      --  from the source program even though it is changed in form.

      Set_Comes_From_Source (N, CS);

      --  Analyze rewritten clause

      Analyze_Attribute_Definition_Clause (N);
   end Analyze_At_Clause;

   -----------------------------------------
   -- Analyze_Attribute_Definition_Clause --
   -----------------------------------------

   procedure Analyze_Attribute_Definition_Clause (N : Node_Id) is
      Loc   : constant Source_Ptr   := Sloc (N);
      Nam   : constant Node_Id      := Name (N);
      Attr  : constant Name_Id      := Chars (N);
      Expr  : constant Node_Id      := Expression (N);
      Id    : constant Attribute_Id := Get_Attribute_Id (Attr);

      Ent : Entity_Id;
      --  The entity of Nam after it is analyzed. In the case of an incomplete
      --  type, this is the underlying type.

      U_Ent : Entity_Id;
      --  The underlying entity to which the attribute applies. Generally this
      --  is the Underlying_Type of Ent, except in the case where the clause
      --  applies to the full view of an incomplete or private type, in which
      --  case U_Ent is just a copy of Ent.

      FOnly : Boolean := False;
      --  Reset to True for subtype specific attribute (Alignment, Size)
      --  and for stream attributes, i.e. those cases where in the call to
      --  Rep_Item_Too_Late, FOnly is set True so that only the freezing rules
      --  are checked. Note that the case of stream attributes is not clear
      --  from the RM, but see AI95-00137. Also, the RM seems to disallow
      --  Storage_Size for derived task types, but that is also clearly
      --  unintentional.

      procedure Analyze_Put_Image_TSS_Definition;

      procedure Analyze_Stream_TSS_Definition (TSS_Nam : TSS_Name_Type);
      --  Common processing for 'Read, 'Write, 'Input and 'Output attribute
      --  definition clauses.

      function Duplicate_Clause return Boolean;
      --  This routine checks if the aspect for U_Ent being given by attribute
      --  definition clause N is for an aspect that has already been specified,
      --  and if so gives an error message. If there is a duplicate, True is
      --  returned, otherwise there is no error, and False is returned. Size
      --  and Value_Size are considered to conflict, but for compatibility,
      --  this is merely a warning.

      procedure Check_Indexing_Functions;
      --  Check that the function in Constant_Indexing or Variable_Indexing
      --  attribute has the proper type structure. If the name is overloaded,
      --  check that some interpretation is legal.

      procedure Check_Iterator_Functions;
      --  Check that there is a single function in Default_Iterator attribute
      --  that has the proper type structure.

      function Check_Primitive_Function (Subp : Entity_Id) return Boolean;
      --  Common legality check for the previous two

      -----------------------------------
      -- Analyze_Put_Image_TSS_Definition --
      -----------------------------------

      procedure Analyze_Put_Image_TSS_Definition is
         Subp : Entity_Id := Empty;
         I    : Interp_Index;
         It   : Interp;
         Pnam : Entity_Id;

         function Has_Good_Profile
           (Subp   : Entity_Id;
            Report : Boolean := False) return Boolean;
         --  Return true if the entity is a subprogram with an appropriate
         --  profile for the attribute being defined. If result is False and
         --  Report is True, function emits appropriate error.

         ----------------------
         -- Has_Good_Profile --
         ----------------------

         function Has_Good_Profile
           (Subp   : Entity_Id;
            Report : Boolean := False) return Boolean
         is
            F              : Entity_Id;
            Typ            : Entity_Id;

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

            F := First_Formal (Subp);

            if No (F) then
               return False;
            end if;

            if Base_Type (Etype (F))
              /= Class_Wide_Type (RTE (RE_Root_Buffer_Type))
            then
               if Report then
                  Error_Msg_N
                    ("wrong type for Put_Image procedure''s first parameter",
                     Parameter_Type (Parent (F)));
               end if;

               return False;
            end if;

            if Parameter_Mode (F) /= E_In_Out_Parameter then
               if Report then
                  Error_Msg_N
                    ("wrong mode for Put_Image procedure''s first parameter",
                     Parent (F));
               end if;

               return False;
            end if;

            Next_Formal (F);

            Typ := Etype (F);

            --  Verify that the prefix of the attribute and the local name for
            --  the type of the formal match.

            if Base_Type (Typ) /= Base_Type (Ent) then
               if Report then
                  Error_Msg_N
                    ("wrong type for Put_Image procedure''s second parameter",
                     Parameter_Type (Parent (F)));
               end if;

               return False;
            end if;

            if Parameter_Mode (F) /= E_In_Parameter then
               if Report then
                  Error_Msg_N
                    ("wrong mode for Put_Image procedure''s second parameter",
                     Parent (F));
               end if;

               return False;
            end if;

            if Present (Next_Formal (F)) then
               return False;
            end if;

            return True;
         end Has_Good_Profile;

      --  Start of processing for Analyze_Put_Image_TSS_Definition

      begin
         if not Is_Type (U_Ent) then
            Error_Msg_N ("local name must be a subtype", Nam);
            return;

         elsif not Is_First_Subtype (U_Ent) then
            Error_Msg_N ("local name must be a first subtype", Nam);
            return;
         end if;

         Pnam := TSS (Base_Type (U_Ent), TSS_Put_Image);

         --  If Pnam is present, it can be either inherited from an ancestor
         --  type (in which case it is legal to redefine it for this type), or
         --  be a previous definition of the attribute for the same type (in
         --  which case it is illegal).

         --  In the first case, it will have been analyzed already, and we can
         --  check that its profile does not match the expected profile for the
         --  Put_Image attribute of U_Ent. In the second case, either Pnam has
         --  been analyzed (and has the expected profile), or it has not been
         --  analyzed yet (case of a type that has not been frozen yet and for
         --  which Put_Image has been set using Set_TSS).

         if Present (Pnam)
           and then (No (First_Entity (Pnam)) or else Has_Good_Profile (Pnam))
         then
            Error_Msg_Sloc := Sloc (Pnam);
            Error_Msg_Name_1 := Attr;
            Error_Msg_N ("% attribute already defined #", Nam);
            return;
         end if;

         Analyze (Expr);

         if Is_Entity_Name (Expr) then
            if not Is_Overloaded (Expr) then
               if Has_Good_Profile (Entity (Expr), Report => True) then
                  Subp := Entity (Expr);
               end if;

            else
               Get_First_Interp (Expr, I, It);
               while Present (It.Nam) loop
                  if Has_Good_Profile (It.Nam) then
                     Subp := It.Nam;
                     exit;
                  end if;

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

         if Present (Subp) then
            if Is_Abstract_Subprogram (Subp) then
               Error_Msg_N ("Put_Image subprogram must not be abstract", Expr);
               return;
            end if;

            Set_Entity (Expr, Subp);
            Set_Etype (Expr, Etype (Subp));

            New_Put_Image_Subprogram (N, U_Ent, Subp);

         else
            Error_Msg_Name_1 := Attr;
            Error_Msg_N ("incorrect expression for% attribute", Expr);
         end if;
      end Analyze_Put_Image_TSS_Definition;

      -----------------------------------
      -- Analyze_Stream_TSS_Definition --
      -----------------------------------

      procedure Analyze_Stream_TSS_Definition (TSS_Nam : TSS_Name_Type) is
         Subp : Entity_Id := Empty;
         I    : Interp_Index;
         It   : Interp;
         Pnam : Entity_Id;

         Is_Read : constant Boolean := (TSS_Nam = TSS_Stream_Read);
         --  True for Read attribute, False for other attributes

         function Has_Good_Profile
           (Subp   : Entity_Id;
            Report : Boolean := False) return Boolean;
         --  Return true if the entity is a subprogram with an appropriate
         --  profile for the attribute being defined. If result is False and
         --  Report is True, function emits appropriate error.

         ----------------------
         -- Has_Good_Profile --
         ----------------------

         function Has_Good_Profile
           (Subp   : Entity_Id;
            Report : Boolean := False) return Boolean
         is
            Expected_Ekind : constant array (Boolean) of Entity_Kind :=
                               (False => E_Procedure, True => E_Function);
            Is_Function    : constant Boolean := (TSS_Nam = TSS_Stream_Input);
            F              : Entity_Id;
            Typ            : Entity_Id;

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

            F := First_Formal (Subp);

            if No (F)
              or else Ekind (Etype (F)) /= E_Anonymous_Access_Type
              or else Base_Type (Designated_Type (Etype (F))) /=
                        Class_Wide_Type (RTE (RE_Root_Stream_Type))
            then
               return False;
            end if;

            if not Is_Function then
               Next_Formal (F);

               declare
                  Expected_Mode : constant array (Boolean) of Entity_Kind :=
                                    (False => E_In_Parameter,
                                     True  => E_Out_Parameter);
               begin
                  if Parameter_Mode (F) /= Expected_Mode (Is_Read) then
                     return False;
                  end if;
               end;

               Typ := Etype (F);

            else
               Typ := Etype (Subp);
            end if;

            --  Verify that the prefix of the attribute and the local name for
            --  the type of the formal match.

            if Base_Type (Typ) /= Base_Type (Ent) then
               return False;
            end if;

            if Present (Next_Formal (F)) then
               return False;

            elsif not Is_Scalar_Type (Typ)
              and then not Is_First_Subtype (Typ)
              and then not Is_Class_Wide_Type (Typ)
            then
               if Report and not Is_First_Subtype (Typ) then
                  Error_Msg_N
                    ("subtype of formal in stream operation must be a first "
                     & "subtype", Parameter_Type (Parent (F)));
               end if;

               return False;

            else
               return True;
            end if;
         end Has_Good_Profile;

      --  Start of processing for Analyze_Stream_TSS_Definition

      begin
         FOnly := True;

         if not Is_Type (U_Ent) then
            Error_Msg_N ("local name must be a subtype", Nam);
            return;

         elsif not Is_First_Subtype (U_Ent) then
            Error_Msg_N ("local name must be a first subtype", Nam);
            return;
         end if;

         Pnam := TSS (Base_Type (U_Ent), TSS_Nam);

         --  If Pnam is present, it can be either inherited from an ancestor
         --  type (in which case it is legal to redefine it for this type), or
         --  be a previous definition of the attribute for the same type (in
         --  which case it is illegal).

         --  In the first case, it will have been analyzed already, and we
         --  can check that its profile does not match the expected profile
         --  for a stream attribute of U_Ent. In the second case, either Pnam
         --  has been analyzed (and has the expected profile), or it has not
         --  been analyzed yet (case of a type that has not been frozen yet
         --  and for which the stream attribute has been set using Set_TSS).

         if Present (Pnam)
           and then (No (First_Entity (Pnam)) or else Has_Good_Profile (Pnam))
         then
            Error_Msg_Sloc := Sloc (Pnam);
            Error_Msg_Name_1 := Attr;
            Error_Msg_N ("% attribute already defined #", Nam);
            return;
         end if;

         Analyze (Expr);

         if Is_Entity_Name (Expr) then
            if not Is_Overloaded (Expr) then
               if Has_Good_Profile (Entity (Expr), Report => True) then
                  Subp := Entity (Expr);
               end if;

            else
               Get_First_Interp (Expr, I, It);
               while Present (It.Nam) loop
                  if Has_Good_Profile (It.Nam) then
                     Subp := It.Nam;
                     exit;
                  end if;

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

         if Present (Subp) then
            if Is_Abstract_Subprogram (Subp) then
               Error_Msg_N ("stream subprogram must not be abstract", Expr);
               return;

            --  A stream subprogram for an interface type must be a null
            --  procedure (RM 13.13.2 (38/3)). Note that the class-wide type
            --  of an interface is not an interface type (3.9.4 (6.b/2)).

            elsif Is_Interface (U_Ent)
              and then not Is_Class_Wide_Type (U_Ent)
              and then not Inside_A_Generic
              and then
                (Ekind (Subp) = E_Function
                  or else
                    not Null_Present
                          (Specification
                             (Unit_Declaration_Node (Ultimate_Alias (Subp)))))
            then
               Error_Msg_N
                 ("stream subprogram for interface type must be null "
                  & "procedure", Expr);
            end if;

            Set_Entity (Expr, Subp);
            Set_Etype (Expr, Etype (Subp));

            New_Stream_Subprogram (N, U_Ent, Subp, TSS_Nam);

         else
            Error_Msg_Name_1 := Attr;

            if Is_Class_Wide_Type (Base_Type (Ent)) then
               Error_Msg_N
                 ("incorrect expression for class-wide% attribute", Expr);
            else
               Error_Msg_N ("incorrect expression for% attribute", Expr);
            end if;
         end if;
      end Analyze_Stream_TSS_Definition;

      ------------------------------
      -- Check_Indexing_Functions --
      ------------------------------

      procedure Check_Indexing_Functions is
         Indexing_Found : Boolean := False;

         procedure Check_Inherited_Indexing;
         --  For a derived type, check that for a derived type, a specification
         --  of an indexing aspect can only be confirming, i.e. uses the same
         --  name as in the parent type.
         --  AI12-0160: Verify that an indexing cannot be specified for
         --  a derived type unless it is specified for the parent.

         procedure Check_One_Function (Subp : Entity_Id);
         --  Check one possible interpretation. Sets Indexing_Found True if a
         --  legal indexing function is found.

         procedure Illegal_Indexing (Msg : String);
         --  Diagnose illegal indexing function if not overloaded. In the
         --  overloaded case indicate that no legal interpretation  exists.

         ------------------------------
         -- Check_Inherited_Indexing --
         ------------------------------

         procedure Check_Inherited_Indexing is
            Inherited      : Node_Id;
            Other_Indexing : Node_Id;

         begin
            if Attr = Name_Constant_Indexing then
               Inherited :=
                 Find_Aspect (Etype (Ent), Aspect_Constant_Indexing);
               Other_Indexing :=
                 Find_Aspect (Etype (Ent), Aspect_Variable_Indexing);

            else pragma Assert (Attr = Name_Variable_Indexing);
               Inherited :=
                  Find_Aspect (Etype (Ent), Aspect_Variable_Indexing);
               Other_Indexing :=
                 Find_Aspect (Etype (Ent), Aspect_Constant_Indexing);
            end if;

            if Present (Inherited) then
               if Debug_Flag_Dot_XX then
                  null;

               --  OK if current attribute_definition_clause is expansion of
               --  inherited aspect.

               elsif Aspect_Rep_Item (Inherited) = N then
                  null;

               --  Check if this is a confirming specification. The name
               --  may be overloaded between the parent operation and the
               --  inherited one, so we check that the Chars fields match.

               elsif Is_Entity_Name (Expression (Inherited))
                 and then Chars (Entity (Expression (Inherited))) =
                    Chars (Entity (Expression (N)))
               then
                  Indexing_Found := True;

               --  Indicate the operation that must be overridden, rather than
               --  redefining the indexing aspect.

               else
                  Illegal_Indexing
                    ("indexing function already inherited from parent type");
                  Error_Msg_NE
                    ("!override & instead",
                     N, Entity (Expression (Inherited)));
               end if;

            --  If not inherited and the parent has another indexing function
            --  this is illegal, because it leads to inconsistent results in
            --  class-wide calls.

            elsif Present (Other_Indexing) then
               Error_Msg_N
                 ("cannot specify indexing operation on derived type"
                   & " if not specified for parent", N);
            end if;
         end Check_Inherited_Indexing;

         ------------------------
         -- Check_One_Function --
         ------------------------

         procedure Check_One_Function (Subp : Entity_Id) is
            Default_Element : Node_Id;
            Ret_Type        : constant Entity_Id := Etype (Subp);

         begin
            if not Is_Overloadable (Subp) then
               Illegal_Indexing ("illegal indexing function for type&");
               return;

            elsif Scope (Subp) /= Scope (Ent) then
               if Nkind (Expr) = N_Expanded_Name then

                  --  Indexing function can't be declared elsewhere

                  Illegal_Indexing
                    ("indexing function must be declared"
                      & " in scope of type&");
               end if;

               if Is_Derived_Type (Ent) then
                  Check_Inherited_Indexing;
               end if;

               return;

            elsif No (First_Formal (Subp)) then
               Illegal_Indexing
                 ("Indexing requires a function that applies to type&");
               return;

            elsif No (Next_Formal (First_Formal (Subp))) then
               Illegal_Indexing
                 ("indexing function must have at least two parameters");
               return;

            elsif Is_Derived_Type (Ent) then
               Check_Inherited_Indexing;
            end if;

            if not Check_Primitive_Function (Subp) then
               Illegal_Indexing
                 ("Indexing aspect requires a function that applies to type&");
               return;
            end if;

            --  If partial declaration exists, verify that it is not tagged.

            if Ekind (Current_Scope) = E_Package
              and then Has_Private_Declaration (Ent)
              and then From_Aspect_Specification (N)
              and then
                List_Containing (Parent (Ent)) =
                  Private_Declarations
                    (Specification (Unit_Declaration_Node (Current_Scope)))
              and then Nkind (N) = N_Attribute_Definition_Clause
            then
               declare
                  Decl : Node_Id;

               begin
                  Decl :=
                     First (Visible_Declarations
                              (Specification
                                 (Unit_Declaration_Node (Current_Scope))));

                  while Present (Decl) loop
                     if Nkind (Decl) = N_Private_Type_Declaration
                       and then Ent = Full_View (Defining_Identifier (Decl))
                       and then Tagged_Present (Decl)
                       and then No (Aspect_Specifications (Decl))
                     then
                        Illegal_Indexing
                          ("Indexing aspect cannot be specified on full view "
                           & "if partial view is tagged");
                        return;
                     end if;

                     Next (Decl);
                  end loop;
               end;
            end if;

            --  An indexing function must return either the default element of
            --  the container, or a reference type. For variable indexing it
            --  must be the latter.

            Default_Element :=
              Find_Value_Of_Aspect
               (Etype (First_Formal (Subp)), Aspect_Iterator_Element);

            if Present (Default_Element) then
               Analyze (Default_Element);
            end if;

            --  For variable_indexing the return type must be a reference type

            if Attr = Name_Variable_Indexing then
               if not Has_Implicit_Dereference (Ret_Type) then
                  Illegal_Indexing
                     ("variable indexing must return a reference type");
                  return;

               elsif Is_Access_Constant
                       (Etype (First_Discriminant (Ret_Type)))
               then
                  Illegal_Indexing
                    ("variable indexing must return an access to variable");
                  return;
               end if;

            else
               if Has_Implicit_Dereference (Ret_Type)
                 and then not
                   Is_Access_Constant
                     (Etype (Get_Reference_Discriminant (Ret_Type)))
               then
                  Illegal_Indexing
                    ("constant indexing must return an access to constant");
                  return;

               elsif Is_Access_Type (Etype (First_Formal (Subp)))
                 and then not Is_Access_Constant (Etype (First_Formal (Subp)))
               then
                  Illegal_Indexing
                    ("constant indexing must apply to an access to constant");
                  return;
               end if;
            end if;

            --  All checks succeeded

            Indexing_Found := True;
         end Check_One_Function;

         -----------------------
         --  Illegal_Indexing --
         -----------------------

         procedure Illegal_Indexing (Msg : String) is
         begin
            Error_Msg_NE (Msg, N, Ent);
         end Illegal_Indexing;

      --  Start of processing for Check_Indexing_Functions

      begin
         if In_Instance then
            Check_Inherited_Indexing;
         end if;

         Analyze (Expr);

         if not Is_Overloaded (Expr) then
            Check_One_Function (Entity (Expr));

         else
            declare
               I  : Interp_Index;
               It : Interp;

            begin
               Indexing_Found := False;
               Get_First_Interp (Expr, I, It);
               while Present (It.Nam) loop

                  --  Note that analysis will have added the interpretation
                  --  that corresponds to the dereference. We only check the
                  --  subprogram itself. Ignore homonyms that may come from
                  --  derived types in the context.

                  if Is_Overloadable (It.Nam)
                    and then Comes_From_Source (It.Nam)
                  then
                     Check_One_Function (It.Nam);
                  end if;

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

         if not Indexing_Found and then not Error_Posted (N) then
            Error_Msg_NE
              ("aspect Indexing requires a local function that applies to "
               & "type&", Expr, Ent);
         end if;
      end Check_Indexing_Functions;

      ------------------------------
      -- Check_Iterator_Functions --
      ------------------------------

      procedure Check_Iterator_Functions is
         function Valid_Default_Iterator (Subp : Entity_Id) return Boolean;
         --  Check one possible interpretation for validity

         ----------------------------
         -- Valid_Default_Iterator --
         ----------------------------

         function Valid_Default_Iterator (Subp : Entity_Id) return Boolean is
            Root_T : constant Entity_Id := Root_Type (Etype (Etype (Subp)));
            Formal : Entity_Id;

         begin
            if not Check_Primitive_Function (Subp) then
               return False;

            --  The return type must be derived from a type in an instance
            --  of Iterator.Interfaces, and thus its root type must have a
            --  predefined name.

            elsif Chars (Root_T) /= Name_Forward_Iterator
             and then Chars (Root_T) /= Name_Reversible_Iterator
            then
               return False;

            else
               Formal := First_Formal (Subp);
            end if;

            --  False if any subsequent formal has no default expression

            Next_Formal (Formal);
            while Present (Formal) loop
               if No (Expression (Parent (Formal))) then
                  return False;
               end if;

               Next_Formal (Formal);
            end loop;

            --  True if all subsequent formals have default expressions

            return True;
         end Valid_Default_Iterator;

      --  Start of processing for Check_Iterator_Functions

      begin
         Analyze (Expr);

         if not Is_Entity_Name (Expr) then
            Error_Msg_N ("aspect Iterator must be a function name", Expr);
         end if;

         if not Is_Overloaded (Expr) then
            if Entity (Expr) /= Any_Id
              and then not Check_Primitive_Function (Entity (Expr))
            then
               Error_Msg_NE
                 ("aspect Indexing requires a function that applies to type&",
                  Entity (Expr), Ent);
            end if;

            --  Flag the default_iterator as well as the denoted function.

            if not Valid_Default_Iterator (Entity (Expr)) then
               Error_Msg_N ("improper function for default iterator!", Expr);
            end if;

         else
            declare
               Default : Entity_Id := Empty;
               I       : Interp_Index;
               It      : Interp;

            begin
               Get_First_Interp (Expr, I, It);
               while Present (It.Nam) loop
                  if not Check_Primitive_Function (It.Nam)
                    or else not Valid_Default_Iterator (It.Nam)
                  then
                     Remove_Interp (I);

                  elsif Present (Default) then

                     --  An explicit one should override an implicit one

                     if Comes_From_Source (Default) =
                          Comes_From_Source (It.Nam)
                     then
                        Error_Msg_N ("default iterator must be unique", Expr);
                        Error_Msg_Sloc := Sloc (Default);
                        Error_Msg_N ("\\possible interpretation#", Expr);
                        Error_Msg_Sloc := Sloc (It.Nam);
                        Error_Msg_N ("\\possible interpretation#", Expr);

                     elsif Comes_From_Source (It.Nam) then
                        Default := It.Nam;
                     end if;
                  else
                     Default := It.Nam;
                  end if;

                  Get_Next_Interp (I, It);
               end loop;

               if Present (Default) then
                  Set_Entity (Expr, Default);
                  Set_Is_Overloaded (Expr, False);
               else
                  Error_Msg_N
                    ("no interpretation is a valid default iterator!", Expr);
               end if;
            end;
         end if;
      end Check_Iterator_Functions;

      -------------------------------
      -- Check_Primitive_Function  --
      -------------------------------

      function Check_Primitive_Function (Subp : Entity_Id) return Boolean is
         Ctrl : Entity_Id;

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

         if No (First_Formal (Subp)) then
            return False;
         else
            Ctrl := Etype (First_Formal (Subp));
         end if;

         --  To be a primitive operation subprogram has to be in same scope.

         if Scope (Ctrl) /= Scope (Subp) then
            return False;
         end if;

         --  Type of formal may be the class-wide type, an access to such,
         --  or an incomplete view.

         if Ctrl = Ent
           or else Ctrl = Class_Wide_Type (Ent)
           or else
             (Ekind (Ctrl) = E_Anonymous_Access_Type
               and then (Designated_Type (Ctrl) = Ent
                           or else
                         Designated_Type (Ctrl) = Class_Wide_Type (Ent)))
           or else
             (Ekind (Ctrl) = E_Incomplete_Type
               and then Full_View (Ctrl) = Ent)
         then
            null;
         else
            return False;
         end if;

         return True;
      end Check_Primitive_Function;

      ----------------------
      -- Duplicate_Clause --
      ----------------------

      function Duplicate_Clause return Boolean is

         function Check_One_Attr (Attr_1, Attr_2 : Name_Id) return Boolean;
         --  Check for one attribute; Attr_1 is the attribute_designator we are
         --  looking for. Attr_2 is the attribute_designator of the current
         --  node. Normally, this is called just once by Duplicate_Clause, with
         --  Attr_1 = Attr_2. However, it needs to be called twice for Size and
         --  Value_Size, because these mean the same thing. For compatibility,
         --  we allow specifying both Size and Value_Size, but only if the two
         --  sizes are equal.

         --------------------
         -- Check_One_Attr --
         --------------------

         function Check_One_Attr (Attr_1, Attr_2 : Name_Id) return Boolean is
            A : constant Node_Id :=
              Get_Rep_Item (U_Ent, Attr_1, Check_Parents => False);
         begin
            if Present (A) then
               if Attr_1 = Attr_2 then
                  Error_Msg_Name_1 := Attr_1;
                  Error_Msg_Sloc := Sloc (A);
                  Error_Msg_NE ("aspect% for & previously given#", N, U_Ent);

               else
                  pragma Assert (Attr_1 in Name_Size | Name_Value_Size);
                  pragma Assert (Attr_2 in Name_Size | Name_Value_Size);

                  Error_Msg_Name_1 := Attr_2;
                  Error_Msg_Name_2 := Attr_1;
                  Error_Msg_Sloc := Sloc (A);
                  Error_Msg_NE ("?% for & conflicts with % #", N, U_Ent);
               end if;

               return True;
            end if;

            return False;
         end Check_One_Attr;

      --  Start of processing for Duplicate_Clause

      begin
         --  Nothing to do if this attribute definition clause comes from
         --  an aspect specification, since we could not be duplicating an
         --  explicit clause, and we dealt with the case of duplicated aspects
         --  in Analyze_Aspect_Specifications.

         if From_Aspect_Specification (N) then
            return False;
         end if;

         --  Special cases for Size and Value_Size

         if (Chars (N) = Name_Size
               and then Check_One_Attr (Name_Value_Size, Name_Size))
           or else
            (Chars (N) = Name_Value_Size
               and then Check_One_Attr (Name_Size, Name_Value_Size))
         then
            return True;
         end if;

         --  Normal case (including Size and Value_Size)

         return Check_One_Attr (Chars (N), Chars (N));
      end Duplicate_Clause;

   --  Start of processing for Analyze_Attribute_Definition_Clause

   begin
      --  The following code is a defense against recursion. Not clear that
      --  this can happen legitimately, but perhaps some error situations can
      --  cause it, and we did see this recursion during testing.

      if Analyzed (N) then
         return;
      else
         Set_Analyzed (N, True);
      end if;

      Check_Restriction_No_Use_Of_Attribute (N);

      if Is_Aspect_Id (Chars (N)) then
         --  6.1/3 No_Specification_of_Aspect: Identifies an aspect for which
         --    no aspect_specification, attribute_definition_clause, or pragma
         --    is given.
         Check_Restriction_No_Specification_Of_Aspect (N);
      end if;

      --  Ignore some selected attributes in CodePeer mode since they are not
      --  relevant in this context.

      if CodePeer_Mode then
         case Id is

            --  Ignore Component_Size in CodePeer mode, to avoid changing the
            --  internal representation of types by implicitly packing them.

            when Attribute_Component_Size =>
               Rewrite (N, Make_Null_Statement (Sloc (N)));
               return;

            when others =>
               null;
         end case;
      end if;

      --  Process Ignore_Rep_Clauses option

      if Ignore_Rep_Clauses then
         case Id is

            --  The following should be ignored. They do not affect legality
            --  and may be target dependent. The basic idea of -gnatI is to
            --  ignore any rep clauses that may be target dependent but do not
            --  affect legality (except possibly to be rejected because they
            --  are incompatible with the compilation target).

            when Attribute_Alignment
               | Attribute_Bit_Order
               | Attribute_Component_Size
               | Attribute_Default_Scalar_Storage_Order
               | Attribute_Machine_Radix
               | Attribute_Object_Size
               | Attribute_Scalar_Storage_Order
               | Attribute_Size
               | Attribute_Small
               | Attribute_Stream_Size
               | Attribute_Value_Size
            =>
               Kill_Rep_Clause (N);
               return;

            --  The following should not be ignored, because in the first place
            --  they are reasonably portable, and should not cause problems
            --  in compiling code from another target, and also they do affect
            --  legality, e.g. failing to provide a stream attribute for a type
            --  may make a program illegal.

            when Attribute_External_Tag
               | Attribute_Input
               | Attribute_Output
               | Attribute_Put_Image
               | Attribute_Read
               | Attribute_Simple_Storage_Pool
               | Attribute_Storage_Pool
               | Attribute_Storage_Size
               | Attribute_Write
            =>
               null;

            --  We do not do anything here with address clauses, they will be
            --  removed by Freeze later on, but for now, it works better to
            --  keep them in the tree.

            when Attribute_Address =>
               null;

            --  Other cases are errors ("attribute& cannot be set with
            --  definition clause"), which will be caught below.

            when others =>
               null;
         end case;
      end if;

      Analyze (Nam);
      Ent := Entity (Nam);

      if Rep_Item_Too_Early (Ent, N) then
         return;
      end if;

      --  Rep clause applies to (underlying) full view of private or incomplete
      --  type if we have one (if not, this is a premature use of the type).
      --  However, some semantic checks need to be done on the specified entity
      --  i.e. the private view, so we save it in Ent.

      if Is_Private_Type (Ent)
        and then Is_Derived_Type (Ent)
        and then not Is_Tagged_Type (Ent)
        and then No (Full_View (Ent))
        and then No (Underlying_Full_View (Ent))
      then
         U_Ent := Ent;

      elsif Ekind (Ent) = E_Incomplete_Type then

         --  The attribute applies to the full view, set the entity of the
         --  attribute definition accordingly.

         Ent := Underlying_Type (Ent);
         U_Ent := Ent;
         Set_Entity (Nam, Ent);

      else
         U_Ent := Underlying_Type (Ent);
      end if;

      --  Avoid cascaded error

      if Etype (Nam) = Any_Type then
         return;

      --  Must be declared in current scope or in case of an aspect
      --  specification, must be visible in current scope.

      elsif Scope (Ent) /= Current_Scope
        and then
          not (From_Aspect_Specification (N)
                and then Scope_Within_Or_Same (Current_Scope, Scope (Ent)))
      then
         Error_Msg_N ("entity must be declared in this scope", Nam);
         return;

      --  Must not be a source renaming (we do have some cases where the
      --  expander generates a renaming, and those cases are OK, in such
      --  cases any attribute applies to the renamed object as well).

      elsif Is_Object (Ent)
        and then Present (Renamed_Object (Ent))
      then
         --  In the case of a renamed object from source, this is an error
         --  unless the object is an aggregate and the renaming is created
         --  for an object declaration.

         if Comes_From_Source (Renamed_Object (Ent))
           and then Nkind (Renamed_Object (Ent)) /= N_Aggregate
         then
            Get_Name_String (Chars (N));
            Error_Msg_Strlen := Name_Len;
            Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
            Error_Msg_N
              ("~ clause not allowed for a renaming declaration "
               & "(RM 13.1(6))", Nam);
            return;

         --  For the case of a compiler generated renaming, the attribute
         --  definition clause applies to the renamed object created by the
         --  expander. The easiest general way to handle this is to create a
         --  copy of the attribute definition clause for this object.

         elsif Is_Entity_Name (Renamed_Object (Ent)) then
            Insert_Action (N,
              Make_Attribute_Definition_Clause (Loc,
                Name       =>
                  New_Occurrence_Of (Entity (Renamed_Object (Ent)), Loc),
                Chars      => Chars (N),
                Expression => Duplicate_Subexpr (Expression (N))));

         --  If the renamed object is not an entity, it must be a dereference
         --  of an unconstrained function call, and we must introduce a new
         --  declaration to capture the expression. This is needed in the case
         --  of 'Alignment, where the original declaration must be rewritten.

         else
            pragma Assert
              (Nkind (Renamed_Object (Ent)) = N_Explicit_Dereference);
            null;
         end if;

      --  If no underlying entity, use entity itself, applies to some
      --  previously detected error cases ???

      elsif No (U_Ent) then
         U_Ent := Ent;

      --  Cannot specify for a subtype (exception Object/Value_Size)

      elsif Is_Type (U_Ent)
        and then not Is_First_Subtype (U_Ent)
        and then Id /= Attribute_Object_Size
        and then Id /= Attribute_Value_Size
        and then not From_At_Mod (N)
      then
         Error_Msg_N ("cannot specify attribute for subtype", Nam);
         return;
      end if;

      Set_Entity (N, U_Ent);

      --  Switch on particular attribute

      case Id is

         -------------
         -- Address --
         -------------

         --  Address attribute definition clause

         when Attribute_Address => Address : begin

            --  A little error check, catch for X'Address use X'Address;

            if Nkind (Nam) = N_Identifier
              and then Nkind (Expr) = N_Attribute_Reference
              and then Attribute_Name (Expr) = Name_Address
              and then Nkind (Prefix (Expr)) = N_Identifier
              and then Chars (Nam) = Chars (Prefix (Expr))
            then
               Error_Msg_NE
                 ("address for & is self-referencing", Prefix (Expr), Ent);
               return;
            end if;

            --  Not that special case, carry on with analysis of expression

            Analyze_And_Resolve (Expr, RTE (RE_Address));

            --  Even when ignoring rep clauses we need to indicate that the
            --  entity has an address clause and thus it is legal to declare
            --  it imported. Freeze will get rid of the address clause later.
            --  Also call Set_Address_Taken to indicate that an address clause
            --  was present, even if we are about to remove it.

            if Ignore_Rep_Clauses then
               Set_Address_Taken (U_Ent);

               if Ekind (U_Ent) in E_Variable | E_Constant then
                  Record_Rep_Item (U_Ent, N);
               end if;

               return;
            end if;

            if Duplicate_Clause then
               null;

            --  Case of address clause for subprogram

            elsif Is_Subprogram (U_Ent) then
               if Has_Homonym (U_Ent) then
                  Error_Msg_N
                    ("address clause cannot be given for overloaded "
                     & "subprogram", Nam);
                  return;
               end if;

               --  For subprograms, all address clauses are permitted, and we
               --  mark the subprogram as having a deferred freeze so that Gigi
               --  will not elaborate it too soon.

               --  Above needs more comments, what is too soon about???

               Set_Has_Delayed_Freeze (U_Ent);

            --  Case of address clause for entry

            elsif Ekind (U_Ent) = E_Entry then
               if Nkind (Parent (N)) = N_Task_Body then
                  Error_Msg_N
                    ("entry address must be specified in task spec", Nam);
                  return;
               end if;

               --  For entries, we require a constant address

               Check_Constant_Address_Clause (Expr, U_Ent);

               --  Special checks for task types

               if Is_Task_Type (Scope (U_Ent))
                 and then Comes_From_Source (Scope (U_Ent))
               then
                  Error_Msg_N
                    ("??entry address declared for entry in task type", N);
                  Error_Msg_N
                    ("\??only one task can be declared of this type", N);
               end if;

               --  Entry address clauses are obsolescent

               Check_Restriction (No_Obsolescent_Features, N);

               if Warn_On_Obsolescent_Feature then
                  Error_Msg_N
                    ("?j?attaching interrupt to task entry is an obsolescent "
                     & "feature (RM J.7.1)", N);
                  Error_Msg_N
                    ("\?j?use interrupt procedure instead", N);
               end if;

            --  Case of an address clause for a class-wide object, which is
            --  considered erroneous.

            elsif Is_Class_Wide_Type (Etype (U_Ent)) then
               Error_Msg_NE
                 ("??class-wide object & must not be overlaid", Nam, U_Ent);
               Error_Msg_N
                 ("\??Program_Error will be raised at run time", Nam);
               Insert_Action (Declaration_Node (U_Ent),
                 Make_Raise_Program_Error (Loc,
                   Reason => PE_Overlaid_Controlled_Object));
               return;

            --  Case of address clause for an object

            elsif Ekind (U_Ent) in E_Constant | E_Variable then
               declare
                  Expr  : constant Node_Id := Expression (N);
                  O_Ent : Entity_Id;
                  Off   : Boolean;

               begin
                  --  Exported variables cannot have an address clause, because
                  --  this cancels the effect of the pragma Export.

                  if Is_Exported (U_Ent) then
                     Error_Msg_N
                       ("cannot export object with address clause", Nam);
                     return;
                  end if;

                  Find_Overlaid_Entity (N, O_Ent, Off);

                  if Present (O_Ent) then

                     --  If the object overlays a constant object, mark it so

                     if Is_Constant_Object (O_Ent) then
                        Set_Overlays_Constant (U_Ent);
                     end if;

                     --  If the address clause is of the form:

                     --    for X'Address use Y'Address;

                     --  or

                     --    C : constant Address := Y'Address;
                     --    ...
                     --    for X'Address use C;

                     --  then we make an entry in the table to check the size
                     --  and alignment of the overlaying variable. But we defer
                     --  this check till after code generation to take full
                     --  advantage of the annotation done by the back end.

                     --  If the entity has a generic type, the check will be
                     --  performed in the instance if the actual type justifies
                     --  it, and we do not insert the clause in the table to
                     --  prevent spurious warnings.

                     --  Note: we used to test Comes_From_Source and only give
                     --  this warning for source entities, but we have removed
                     --  this test. It really seems bogus to generate overlays
                     --  that would trigger this warning in generated code.
                     --  Furthermore, by removing the test, we handle the
                     --  aspect case properly.

                     if Is_Object (O_Ent)
                       and then not Is_Generic_Formal (O_Ent)
                       and then not Is_Generic_Type (Etype (U_Ent))
                       and then Address_Clause_Overlay_Warnings
                     then
                        Register_Address_Clause_Check
                          (N, U_Ent, No_Uint, O_Ent, Off);
                     end if;

                     --  If the overlay changes the storage order, warn since
                     --  the construct is not really supported by the back end.
                     --  Also mark the entity as being volatile to block the
                     --  optimizer, even if there is no warranty on the result.

                     if (Is_Record_Type (Etype (U_Ent))
                          or else Is_Array_Type (Etype (U_Ent)))
                       and then (Is_Record_Type (Etype (O_Ent))
                                  or else Is_Array_Type (Etype (O_Ent)))
                       and then Reverse_Storage_Order (Etype (U_Ent)) /=
                                Reverse_Storage_Order (Etype (O_Ent))
                     then
                        Error_Msg_N
                          ("??overlay changes scalar storage order", Expr);
                        Set_Treat_As_Volatile (U_Ent);
                     end if;

                  else
                     --  If this is not an overlay, mark a variable as being
                     --  volatile to prevent unwanted optimizations. It's a
                     --  conservative interpretation of RM 13.3(19) for the
                     --  cases where the compiler cannot detect potential
                     --  aliasing issues easily and it also covers the case
                     --  of an absolute address where the volatile aspect is
                     --  kind of implicit.

                     if Ekind (U_Ent) = E_Variable then
                        Set_Treat_As_Volatile (U_Ent);
                     end if;

                     --  Make an entry in the table for an absolute address as
                     --  above to check that the value is compatible with the
                     --  alignment of the object.

                     declare
                        Addr : constant Node_Id := Address_Value (Expr);
                     begin
                        if Compile_Time_Known_Value (Addr)
                          and then Address_Clause_Overlay_Warnings
                        then
                           Register_Address_Clause_Check
                             (N, U_Ent, Expr_Value (Addr), Empty, False);
                        end if;
                     end;
                  end if;

                  --  Issue an unconditional warning for a constant overlaying
                  --  a variable. For the reverse case, we will issue it only
                  --  if the variable is modified.
                  --  Within a generic unit an In_Parameter is a constant.
                  --  It can be instantiated with a variable, in which case
                  --  there will be a warning on the instance.

                  if Ekind (U_Ent) = E_Constant
                    and then Present (O_Ent)
                    and then Ekind (O_Ent) /= E_Generic_In_Parameter
                    and then not Overlays_Constant (U_Ent)
                    and then Address_Clause_Overlay_Warnings
                  then
                     Error_Msg_N ("??constant overlays a variable", Expr);

                  --  Imported variables can have an address clause, but then
                  --  the import is pretty meaningless except to suppress
                  --  initializations, so we do not need such variables to
                  --  be statically allocated (and in fact it causes trouble
                  --  if the address clause is a local value).

                  elsif Is_Imported (U_Ent) then
                     Set_Is_Statically_Allocated (U_Ent, False);
                  end if;

                  --  We mark a possible modification of a variable with an
                  --  address clause, since it is likely aliasing is occurring.

                  Note_Possible_Modification (Nam, Sure => False);

                  --  Legality checks on the address clause for initialized
                  --  objects is deferred until the freeze point, because
                  --  a subsequent pragma might indicate that the object
                  --  is imported and thus not initialized. Also, the address
                  --  clause might involve entities that have yet to be
                  --  elaborated.

                  Set_Has_Delayed_Freeze (U_Ent);

                  --  If an initialization call has been generated for this
                  --  object, it needs to be deferred to after the freeze node
                  --  we have just now added, otherwise GIGI will see a
                  --  reference to the variable (as actual to the IP call)
                  --  before its definition.

                  declare
                     Init_Call : constant Node_Id :=
                                   Remove_Init_Call (U_Ent, N);

                  begin
                     if Present (Init_Call) then
                        Append_Freeze_Action (U_Ent, Init_Call);

                        --  Reset Initialization_Statements pointer so that
                        --  if there is a pragma Import further down, it can
                        --  clear any default initialization.

                        Set_Initialization_Statements (U_Ent, Init_Call);
                     end if;
                  end;

                  --  Entity has delayed freeze, so we will generate an
                  --  alignment check at the freeze point unless suppressed.

                  if not Range_Checks_Suppressed (U_Ent)
                    and then not Alignment_Checks_Suppressed (U_Ent)
                  then
                     Set_Check_Address_Alignment (N);
                  end if;

                  --  Kill the size check code, since we are not allocating
                  --  the variable, it is somewhere else.

                  Kill_Size_Check_Code (U_Ent);
               end;

            --  Not a valid entity for an address clause

            else
               Error_Msg_N ("address cannot be given for &", Nam);
            end if;
         end Address;

         ---------------
         -- Alignment --
         ---------------

         --  Alignment attribute definition clause

         when Attribute_Alignment => Alignment : declare
            Align     : constant Uint := Get_Alignment_Value (Expr);
            Max_Align : constant Uint := UI_From_Int (Maximum_Alignment);

         begin
            FOnly := True;

            if not Is_Type (U_Ent)
              and then Ekind (U_Ent) /= E_Variable
              and then Ekind (U_Ent) /= E_Constant
            then
               Error_Msg_N ("alignment cannot be given for &", Nam);

            elsif Duplicate_Clause then
               null;

            elsif Present (Align) then
               Set_Has_Alignment_Clause (U_Ent);

               --  Tagged type case, check for attempt to set alignment to a
               --  value greater than Max_Align, and reset if so.

               if Is_Tagged_Type (U_Ent) and then Align > Max_Align then
                  Error_Msg_N
                    ("alignment for & set to Maximum_Aligment??", Nam);
                  Set_Alignment (U_Ent, Max_Align);

               --  All other cases

               else
                  Set_Alignment (U_Ent, Align);
               end if;

               --  For an array type, U_Ent is the first subtype. In that case,
               --  also set the alignment of the anonymous base type so that
               --  other subtypes (such as the itypes for aggregates of the
               --  type) also receive the expected alignment.

               if Is_Array_Type (U_Ent) then
                  Set_Alignment (Base_Type (U_Ent), Align);
               end if;
            end if;
         end Alignment;

         ---------------
         -- Bit_Order --
         ---------------

         --  Bit_Order attribute definition clause

         when Attribute_Bit_Order =>
            if not Is_Record_Type (U_Ent) then
               Error_Msg_N
                 ("Bit_Order can only be defined for record type", Nam);

            elsif Is_Tagged_Type (U_Ent) and then Is_Derived_Type (U_Ent) then
               Error_Msg_N
                 ("Bit_Order cannot be defined for record extensions", Nam);

            elsif Duplicate_Clause then
               null;

            else
               Analyze_And_Resolve (Expr, RTE (RE_Bit_Order));

               if Etype (Expr) = Any_Type then
                  return;

               elsif not Is_OK_Static_Expression (Expr) then
                  Flag_Non_Static_Expr
                    ("Bit_Order requires static expression!", Expr);

               elsif (Expr_Value (Expr) = 0) /= Bytes_Big_Endian then
                  Set_Reverse_Bit_Order (Base_Type (U_Ent), True);
               end if;
            end if;

         --------------------
         -- Component_Size --
         --------------------

         --  Component_Size attribute definition clause

         when Attribute_Component_Size => Component_Size_Case : declare
            Csize    : constant Uint := Static_Integer (Expr);
            Ctyp     : Entity_Id;
            Btype    : Entity_Id;
            Biased   : Boolean;
            New_Ctyp : Entity_Id;
            Decl     : Node_Id;

         begin
            if not Is_Array_Type (U_Ent) then
               Error_Msg_N ("component size requires array type", Nam);
               return;
            end if;

            Btype := Base_Type (U_Ent);
            Ctyp  := Component_Type (Btype);

            if Duplicate_Clause then
               null;

            elsif Rep_Item_Too_Early (Btype, N) then
               null;

            elsif Present (Csize) then
               Check_Size (Expr, Ctyp, Csize, Biased);

               --  For the biased case, build a declaration for a subtype that
               --  will be used to represent the biased subtype that reflects
               --  the biased representation of components. We need the subtype
               --  to get proper conversions on referencing elements of the
               --  array.

               if Biased then
                  New_Ctyp :=
                    Make_Defining_Identifier (Loc,
                      Chars =>
                        New_External_Name (Chars (U_Ent), 'C', 0, 'T'));

                  Decl :=
                    Make_Subtype_Declaration (Loc,
                      Defining_Identifier => New_Ctyp,
                      Subtype_Indication  =>
                        New_Occurrence_Of (Component_Type (Btype), Loc));

                  Set_Parent (Decl, N);
                  Analyze (Decl, Suppress => All_Checks);

                  Set_Has_Delayed_Freeze        (New_Ctyp, False);
                  Reinit_Esize                  (New_Ctyp);
                  Set_RM_Size                   (New_Ctyp, Csize);
                  Reinit_Alignment              (New_Ctyp);
                  Set_Is_Itype                  (New_Ctyp, True);
                  Set_Associated_Node_For_Itype (New_Ctyp, U_Ent);

                  Set_Component_Type (Btype, New_Ctyp);
                  Set_Biased (New_Ctyp, N, "component size clause");
               end if;

               Set_Component_Size (Btype, Csize);

               --  Deal with warning on overridden size

               if Warn_On_Overridden_Size
                 and then Has_Size_Clause (Ctyp)
                 and then RM_Size (Ctyp) /= Csize
               then
                  Error_Msg_NE
                    ("component size overrides size clause for&?.s?", N, Ctyp);
               end if;

               Set_Has_Component_Size_Clause (Btype, True);
               Set_Has_Non_Standard_Rep (Btype, True);
            end if;
         end Component_Size_Case;

         -----------------------
         -- Constant_Indexing --
         -----------------------

         when Attribute_Constant_Indexing =>
            Check_Indexing_Functions;

         ---------
         -- CPU --
         ---------

         when Attribute_CPU =>
            pragma Assert (From_Aspect_Specification (N));
            --  The parser forbids this clause in source code, so it must have
            --  come from an aspect specification.

            if not Is_Task_Type (U_Ent) then
               Error_Msg_N ("'C'P'U can only be defined for task", Nam);

            elsif Duplicate_Clause then
               null;

            else
               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               --  The visibility to the components must be established
               --  and restored before and after analysis.

               Push_Type (U_Ent);
               Preanalyze_Spec_Expression (Expr, RTE (RE_CPU_Range));
               Pop_Type (U_Ent);

               --  AI12-0117-1, "Restriction No_Tasks_Unassigned_To_CPU":
               --  If the expression is static, and its value is
               --  System.Multiprocessors.Not_A_Specific_CPU (i.e. zero) then
               --  that's a violation of No_Tasks_Unassigned_To_CPU. It might
               --  seem better to refer to Not_A_Specific_CPU here, but that
               --  involves a lot of horsing around with Rtsfind, and this
               --  value is not going to change, so it's better to hardwire
               --  Uint_0.
               --
               --  AI12-0055-1, "All properties of a usage profile are defined
               --  by pragmas": If the expression is nonstatic, that's a
               --  violation of No_Dynamic_CPU_Assignment.

               if Is_OK_Static_Expression (Expr) then
                  if Expr_Value (Expr) = Uint_0 then
                     Check_Restriction (No_Tasks_Unassigned_To_CPU, Expr);
                  end if;
               else
                  Check_Restriction (No_Dynamic_CPU_Assignment, Expr);
               end if;
            end if;

         ----------------------
         -- Default_Iterator --
         ----------------------

         when Attribute_Default_Iterator => Default_Iterator : declare
            Func : Entity_Id;
            Typ  : Entity_Id;

         begin
            --  If target type is untagged, further checks are irrelevant

            if not Is_Tagged_Type (U_Ent) then
               Error_Msg_N
                 ("aspect Default_Iterator applies to tagged type", Nam);
               return;
            end if;

            Check_Iterator_Functions;

            Analyze (Expr);

            if not Is_Entity_Name (Expr)
              or else Ekind (Entity (Expr)) /= E_Function
            then
               Error_Msg_N ("aspect Iterator must be a function", Expr);
               return;
            else
               Func := Entity (Expr);
            end if;

            --  The type of the first parameter must be T, T'class, or a
            --  corresponding access type (5.5.1 (8/3). If function is
            --  parameterless label type accordingly.

            if No (First_Formal (Func)) then
               Typ := Any_Type;
            else
               Typ := Etype (First_Formal (Func));
            end if;

            if Typ = U_Ent
              or else Typ = Class_Wide_Type (U_Ent)
              or else (Is_Access_Type (Typ)
                        and then Designated_Type (Typ) = U_Ent)
              or else (Is_Access_Type (Typ)
                        and then Designated_Type (Typ) =
                                          Class_Wide_Type (U_Ent))
            then
               null;

            else
               Error_Msg_NE
                 ("Default_Iterator must be a primitive of&", Func, U_Ent);
            end if;
         end Default_Iterator;

         ------------------------
         -- Dispatching_Domain --
         ------------------------

         when Attribute_Dispatching_Domain =>
            pragma Assert (From_Aspect_Specification (N));
            --  The parser forbids this clause in source code, so it must have
            --  come from an aspect specification.

            if not Is_Task_Type (U_Ent) then
               Error_Msg_N
                 ("Dispatching_Domain can only be defined for task", Nam);

            elsif Duplicate_Clause then
               null;

            else
               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               --  The visibility to the components must be restored

               Push_Type (U_Ent);

               Preanalyze_Spec_Expression
                 (Expr, RTE (RE_Dispatching_Domain));

               Pop_Type (U_Ent);
            end if;

         ------------------
         -- External_Tag --
         ------------------

         when Attribute_External_Tag =>
            if not Is_Tagged_Type (U_Ent) then
               Error_Msg_N ("should be a tagged type", Nam);
            end if;

            if Duplicate_Clause then
               null;

            else
               Analyze_And_Resolve (Expr, Standard_String);

               if not Is_OK_Static_Expression (Expr) then
                  Flag_Non_Static_Expr
                    ("static string required for tag name!", Nam);
               end if;

               if not Is_Library_Level_Entity (U_Ent) then
                  Error_Msg_NE
                    ("??non-unique external tag supplied for &", N, U_Ent);
                  Error_Msg_N
                    ("\??same external tag applies to all subprogram calls",
                     N);
                  Error_Msg_N
                    ("\??corresponding internal tag cannot be obtained", N);
               end if;
            end if;

         --------------------------
         -- Implicit_Dereference --
         --------------------------

         when Attribute_Implicit_Dereference =>

            --  Legality checks already performed at the point of the type
            --  declaration, aspect is not delayed.

            null;

         -----------
         -- Input --
         -----------

         when Attribute_Input =>
            Analyze_Stream_TSS_Definition (TSS_Stream_Input);
            Set_Has_Specified_Stream_Input (Ent);

         ------------------------
         -- Interrupt_Priority --
         ------------------------

         when Attribute_Interrupt_Priority =>
            pragma Assert (From_Aspect_Specification (N));
            --  The parser forbids this clause in source code, so it must have
            --  come from an aspect specification.

            if not Is_Concurrent_Type (U_Ent) then
               Error_Msg_N
                 ("Interrupt_Priority can only be defined for task and "
                  & "protected object", Nam);

            elsif Duplicate_Clause then
               null;

            else
               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               --  The visibility to the components must be restored

               Push_Type (U_Ent);

               Preanalyze_Spec_Expression
                 (Expr, RTE (RE_Interrupt_Priority));

               Pop_Type (U_Ent);

               --  Check the No_Task_At_Interrupt_Priority restriction

               if Is_Task_Type (U_Ent) then
                  Check_Restriction (No_Task_At_Interrupt_Priority, N);
               end if;
            end if;

         --------------
         -- Iterable --
         --------------

         when Attribute_Iterable =>
            Analyze (Expr);

            if Nkind (Expr) /= N_Aggregate then
               Error_Msg_N ("aspect Iterable must be an aggregate", Expr);
            end if;

            declare
               Assoc : Node_Id;

            begin
               Assoc := First (Component_Associations (Expr));
               while Present (Assoc) loop
                  Analyze (Expression (Assoc));

                  if not Is_Entity_Name (Expression (Assoc)) then
                     Error_Msg_N ("value must be a function", Assoc);
                  end if;

                  Next (Assoc);
               end loop;
            end;

         ----------------------
         -- Iterator_Element --
         ----------------------

         when Attribute_Iterator_Element =>
            Analyze (Expr);

            if not Is_Entity_Name (Expr)
              or else not Is_Type (Entity (Expr))
            then
               Error_Msg_N ("aspect Iterator_Element must be a type", Expr);
               return;
            end if;

         -------------------
         -- Machine_Radix --
         -------------------

         --  Machine radix attribute definition clause

         when Attribute_Machine_Radix => Machine_Radix : declare
            Radix : constant Uint := Static_Integer (Expr);

         begin
            if not Is_Decimal_Fixed_Point_Type (U_Ent) then
               Error_Msg_N ("decimal fixed-point type expected for &", Nam);

            elsif Duplicate_Clause then
               null;

            elsif Present (Radix) then
               Set_Has_Machine_Radix_Clause (U_Ent);
               Set_Has_Non_Standard_Rep (Base_Type (U_Ent));

               if Radix = 2 then
                  null;

               elsif Radix = 10 then
                  Set_Machine_Radix_10 (U_Ent);

               else
                  Error_Msg_N ("machine radix value must be 2 or 10", Expr);
               end if;
            end if;
         end Machine_Radix;

         -----------------
         -- Object_Size --
         -----------------

         --  Object_Size attribute definition clause

         when Attribute_Object_Size => Object_Size : declare
            Size : constant Uint := Static_Integer (Expr);

            Biased : Boolean;
            pragma Warnings (Off, Biased);

         begin
            if not Is_Type (U_Ent) then
               Error_Msg_N ("Object_Size cannot be given for &", Nam);

            elsif Duplicate_Clause then
               null;

            else
               Check_Size (Expr, U_Ent, Size, Biased);

               if No (Size) or else Size <= 0 then
                  Error_Msg_N ("Object_Size must be positive", Expr);

               elsif Is_Scalar_Type (U_Ent) then
                  if Size /= 8 and then Size /= 16 and then Size /= 32
                    and then UI_Mod (Size, 64) /= 0
                  then
                     Error_Msg_N
                       ("Object_Size must be 8, 16, 32, or multiple of 64",
                        Expr);
                  end if;

               elsif Size mod 8 /= 0 then
                  Error_Msg_N ("Object_Size must be a multiple of 8", Expr);
               end if;

               Set_Esize (U_Ent, Size);
               Set_Has_Object_Size_Clause (U_Ent);
               Alignment_Check_For_Size_Change (U_Ent, Size);
            end if;
         end Object_Size;

         ------------
         -- Output --
         ------------

         when Attribute_Output =>
            Analyze_Stream_TSS_Definition (TSS_Stream_Output);
            Set_Has_Specified_Stream_Output (Ent);

         --------------
         -- Priority --
         --------------

         when Attribute_Priority =>

            --  Priority attribute definition clause not allowed except from
            --  aspect specification.

            if From_Aspect_Specification (N) then
               if not (Is_Concurrent_Type (U_Ent)
                        or else Ekind (U_Ent) = E_Procedure)
               then
                  Error_Msg_N
                    ("Priority can only be defined for task and protected "
                     & "object", Nam);

               elsif Duplicate_Clause then
                  null;

               else
                  --  The expression must be analyzed in the special manner
                  --  described in "Handling of Default and Per-Object
                  --  Expressions" in sem.ads.

                  --  The visibility to the components must be restored

                  Push_Type (U_Ent);
                  Preanalyze_Spec_Expression (Expr, Standard_Integer);
                  Pop_Type (U_Ent);

                  if not Is_OK_Static_Expression (Expr) then
                     Check_Restriction (Static_Priorities, Expr);
                  end if;
               end if;

            else
               Error_Msg_N
                 ("attribute& cannot be set with definition clause", N);
            end if;

         ---------------
         -- Put_Image --
         ---------------

         when Attribute_Put_Image =>
            Analyze_Put_Image_TSS_Definition;

         ----------
         -- Read --
         ----------

         when Attribute_Read =>
            Analyze_Stream_TSS_Definition (TSS_Stream_Read);
            Set_Has_Specified_Stream_Read (Ent);

         --------------------------
         -- Scalar_Storage_Order --
         --------------------------

         --  Scalar_Storage_Order attribute definition clause

         when Attribute_Scalar_Storage_Order =>
            if not (Is_Record_Type (U_Ent) or else Is_Array_Type (U_Ent)) then
               Error_Msg_N
                 ("Scalar_Storage_Order can only be defined for record or "
                  & "array type", Nam);

            elsif Duplicate_Clause then
               null;

            else
               Analyze_And_Resolve (Expr, RTE (RE_Bit_Order));

               if Etype (Expr) = Any_Type then
                  return;

               elsif not Is_OK_Static_Expression (Expr) then
                  Flag_Non_Static_Expr
                    ("Scalar_Storage_Order requires static expression!", Expr);

               elsif (Expr_Value (Expr) = 0) /= Bytes_Big_Endian then

                  --  Here for the case of a non-default (i.e. non-confirming)
                  --  Scalar_Storage_Order attribute definition.

                  if Support_Nondefault_SSO_On_Target then
                     Set_Reverse_Storage_Order (Base_Type (U_Ent), True);
                  else
                     Error_Msg_N
                       ("non-default Scalar_Storage_Order not supported on "
                        & "target", Expr);
                  end if;
               end if;

               --  Clear SSO default indications since explicit setting of the
               --  order overrides the defaults.

               Set_SSO_Set_Low_By_Default  (Base_Type (U_Ent), False);
               Set_SSO_Set_High_By_Default (Base_Type (U_Ent), False);
            end if;

         ------------------------
         -- Size or Value_Size --
         ------------------------

         --  Size or Value_Size attribute definition clause. These are treated
         --  the same, except that Size is allowed on objects, and Value_Size
         --  is allowed on nonfirst subtypes. First subtypes allow both Size
         --  and Value_Size; the treatment is the same for both.

         when Attribute_Size | Attribute_Value_Size => Size : declare
            Size   : constant Uint := Static_Integer (Expr);

            Attr_Name : constant String :=
              (if Id = Attribute_Size then "size"
               elsif Id = Attribute_Value_Size then "value size"
               else ""); -- can't happen
            --  Name of the attribute for printing in messages

            OK_Prefix : constant Boolean :=
              (if Id = Attribute_Size then
                Ekind (U_Ent) in Type_Kind | Constant_Or_Variable_Kind
               elsif Id = Attribute_Value_Size then
                Ekind (U_Ent) in Type_Kind
               else False); -- can't happen
            --  For X'Size, X can be a type or object; for X'Value_Size,
            --  X can be a type. Note that we already checked that 'Size
            --  can be specified only for a first subtype.

         begin
            FOnly := True;

            if not OK_Prefix then
               Error_Msg_N (Attr_Name & " cannot be given for &", Nam);

            elsif Duplicate_Clause then
               null;

            elsif Is_Array_Type (U_Ent)
              and then not Is_Constrained (U_Ent)
            then
               Error_Msg_N
                 (Attr_Name & " cannot be given for unconstrained array", Nam);

            elsif Present (Size) then
               declare
                  Etyp : constant Entity_Id :=
                    (if Is_Type (U_Ent) then U_Ent else Etype (U_Ent));

               begin
                  --  Check size, note that Gigi is in charge of checking that
                  --  the size of an array or record type is OK. Also we do not
                  --  check the size in the ordinary fixed-point case, since
                  --  it is too early to do so (there may be subsequent small
                  --  clause that affects the size). We can check the size if
                  --  a small clause has already been given.

                  if not Is_Ordinary_Fixed_Point_Type (U_Ent)
                    or else Has_Small_Clause (U_Ent)
                  then
                     declare
                        Biased : Boolean;
                     begin
                        Check_Size (Expr, Etyp, Size, Biased);
                        Set_Biased (U_Ent, N, Attr_Name & " clause", Biased);
                     end;
                  end if;

                  --  For types, set RM_Size and Esize if appropriate

                  if Is_Type (U_Ent) then
                     Set_RM_Size (U_Ent, Size);

                     --  If we are specifying the Size or Value_Size of a
                     --  first subtype, then for elementary types, increase
                     --  Object_Size to power of 2, but not less than a storage
                     --  unit in any case (normally this means it will be byte
                     --  addressable).

                     --  For all other types, nothing else to do, we leave
                     --  Esize (object size) unset; the back end will set it
                     --  from the size and alignment in an appropriate manner.

                     --  In both cases, we check whether the alignment must be
                     --  reset in the wake of the size change.

                     --  For nonfirst subtypes ('Value_Size only), we do
                     --  nothing here.

                     if Is_First_Subtype (U_Ent) then
                        if Is_Elementary_Type (U_Ent) then
                           if Size <= System_Storage_Unit then
                              Set_Esize
                                (U_Ent, UI_From_Int (System_Storage_Unit));
                           elsif Size <= 16 then
                              Set_Esize (U_Ent, Uint_16);
                           elsif Size <= 32 then
                              Set_Esize (U_Ent, Uint_32);
                           else
                              Set_Esize (U_Ent, (Size + 63) / 64 * 64);
                           end if;

                           Alignment_Check_For_Size_Change
                             (U_Ent, Esize (U_Ent));
                        else
                           Alignment_Check_For_Size_Change (U_Ent, Size);
                        end if;
                     end if;

                  --  For Object'Size, set Esize only

                  else
                     if Is_Elementary_Type (Etyp)
                       and then Size /= System_Storage_Unit
                       and then Size /= 16
                       and then Size /= 32
                       and then Size /= 64
                       and then Size /= System_Max_Integer_Size
                     then
                        Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
                        Error_Msg_Uint_2 :=
                          UI_From_Int (System_Max_Integer_Size);
                        Error_Msg_N
                          ("size for primitive object must be a power of 2 in "
                           & "the range ^-^", N);
                     end if;

                     Set_Esize (U_Ent, Size);
                  end if;

                  Set_Has_Size_Clause (U_Ent);
               end;
            end if;
         end Size;

         -----------
         -- Small --
         -----------

         --  Small attribute definition clause

         when Attribute_Small => Small : declare
            Implicit_Base : constant Entity_Id := Base_Type (U_Ent);
            Small         : Ureal;

         begin
            Analyze_And_Resolve (Expr, Any_Real);

            if Etype (Expr) = Any_Type then
               return;

            elsif not Is_OK_Static_Expression (Expr) then
               Flag_Non_Static_Expr
                 ("small requires static expression!", Expr);
               return;

            else
               Small := Expr_Value_R (Expr);

               if Small <= Ureal_0 then
                  Error_Msg_N ("small value must be greater than zero", Expr);
                  return;
               end if;

            end if;

            if not Is_Ordinary_Fixed_Point_Type (U_Ent) then
               Error_Msg_N
                 ("small requires an ordinary fixed point type", Nam);

            elsif Has_Small_Clause (U_Ent) then
               Error_Msg_N ("small already given for &", Nam);

            elsif Small > Delta_Value (U_Ent) then
               Error_Msg_N
                 ("small value must not be greater than delta value", Nam);

            else
               Set_Small_Value (U_Ent, Small);
               Set_Small_Value (Implicit_Base, Small);
               Set_Has_Small_Clause (U_Ent);
               Set_Has_Small_Clause (Implicit_Base);
               Set_Has_Non_Standard_Rep (Implicit_Base);
            end if;
         end Small;

         ------------------
         -- Storage_Pool --
         ------------------

         --  Storage_Pool attribute definition clause

         when Attribute_Simple_Storage_Pool
            | Attribute_Storage_Pool
         =>
         Storage_Pool : declare
            Pool : Entity_Id;
            T    : Entity_Id;

            procedure Associate_Storage_Pool
              (Ent : Entity_Id; Pool : Entity_Id);
            --  Associate Pool to Ent and perform legality checks on subpools

            ----------------------------
            -- Associate_Storage_Pool --
            ----------------------------

            procedure Associate_Storage_Pool
              (Ent : Entity_Id; Pool : Entity_Id)
            is
               function Object_From (Pool : Entity_Id) return Entity_Id;
               --  Return the entity of which Pool is a part of

               -----------------
               -- Object_From --
               -----------------

               function Object_From
                 (Pool : Entity_Id) return Entity_Id
               is
                  N : Node_Id := Pool;
               begin
                  if Present (Renamed_Object (Pool)) then
                     N := Renamed_Object (Pool);
                  end if;

                  while Present (N) loop
                     case Nkind (N) is
                        when N_Defining_Identifier =>
                           return N;

                        when N_Identifier | N_Expanded_Name =>
                           return Entity (N);

                        when N_Indexed_Component | N_Selected_Component |
                             N_Explicit_Dereference
                        =>
                           N := Prefix (N);

                        when N_Type_Conversion =>
                           N := Expression (N);

                        when others =>
                           --  ??? we probably should handle more cases but
                           --  this is good enough in practice for this check
                           --  on a corner case.

                           return Empty;
                     end case;
                  end loop;

                  return Empty;
               end Object_From;

               Obj : Entity_Id;

            begin
               Set_Associated_Storage_Pool (Ent, Pool);

               --  Check RM 13.11.4(22-23/3): a specification of a storage pool
               --  is illegal if the storage pool supports subpools and:
               --  (A) The access type is a general access type.
               --  (B) The access type is statically deeper than the storage
               --      pool object;
               --  (C) The storage pool object is a part of a formal parameter;
               --  (D) The storage pool object is a part of the dereference of
               --      a non-library level general access type;

               if Ada_Version >= Ada_2012
                 and then RTU_Loaded (System_Storage_Pools_Subpools)
                 and then
                   Is_Ancestor (RTE (RE_Root_Storage_Pool_With_Subpools),
                                Etype (Pool))
               then
                  --  check (A)

                  if Ekind (Etype (Ent)) = E_General_Access_Type then
                     Error_Msg_N
                       ("subpool cannot be used on general access type", Ent);
                  end if;

                  --  check (B)

                  if Type_Access_Level (Ent)
                       > Static_Accessibility_Level
                           (Pool, Object_Decl_Level)
                  then
                     Error_Msg_N
                       ("subpool access type has deeper accessibility "
                        & "level than pool", Ent);
                     return;
                  end if;

                  Obj := Object_From (Pool);

                  --  check (C)

                  if Present (Obj) and then Is_Formal (Obj) then
                     Error_Msg_N
                       ("subpool cannot be part of a parameter", Ent);
                     return;
                  end if;

                  --  check (D)

                  if Present (Obj)
                    and then Ekind (Etype (Obj)) = E_General_Access_Type
                    and then not Is_Library_Level_Entity (Etype (Obj))
                  then
                     Error_Msg_N
                       ("subpool cannot be part of the dereference of a " &
                        "nested general access type", Ent);
                     return;
                  end if;
               end if;
            end Associate_Storage_Pool;

         begin
            if Ekind (U_Ent) = E_Access_Subprogram_Type then
               Error_Msg_N
                 ("storage pool cannot be given for access-to-subprogram type",
                  Nam);
               return;

            elsif Ekind (U_Ent) not in E_Access_Type | E_General_Access_Type
            then
               Error_Msg_N
                 ("storage pool can only be given for access types", Nam);
               return;

            elsif Is_Derived_Type (U_Ent) then
               Error_Msg_N
                 ("storage pool cannot be given for a derived access type",
                  Nam);

            elsif Duplicate_Clause then
               return;

            elsif Present (Associated_Storage_Pool (U_Ent)) then
               Error_Msg_N ("storage pool already given for &", Nam);
               return;
            end if;

            --  Check for Storage_Size previously given

            declare
               SS : constant Node_Id :=
                      Get_Attribute_Definition_Clause
                        (U_Ent, Attribute_Storage_Size);
            begin
               if Present (SS) then
                  Check_Pool_Size_Clash (U_Ent, N, SS);
               end if;
            end;

            --  Storage_Pool case

            if Id = Attribute_Storage_Pool then
               Analyze_And_Resolve
                 (Expr, Class_Wide_Type (RTE (RE_Root_Storage_Pool)));

            --  In the Simple_Storage_Pool case, we allow a variable of any
            --  simple storage pool type, so we Resolve without imposing an
            --  expected type.

            else
               Analyze_And_Resolve (Expr);

               if not Present (Get_Rep_Pragma
                                 (Etype (Expr), Name_Simple_Storage_Pool_Type))
               then
                  Error_Msg_N
                    ("expression must be of a simple storage pool type", Expr);
               end if;
            end if;

            if not Denotes_Variable (Expr) then
               Error_Msg_N ("storage pool must be a variable", Expr);
               return;
            end if;

            if Nkind (Expr) = N_Type_Conversion then
               T := Etype (Expression (Expr));
            else
               T := Etype (Expr);
            end if;

            --  The Stack_Bounded_Pool is used internally for implementing
            --  access types with a Storage_Size. Since it only work properly
            --  when used on one specific type, we need to check that it is not
            --  hijacked improperly:

            --    type T is access Integer;
            --    for T'Storage_Size use n;
            --    type Q is access Float;
            --    for Q'Storage_Size use T'Storage_Size; -- incorrect

            if Is_RTE (Base_Type (T), RE_Stack_Bounded_Pool) then
               Error_Msg_N ("non-shareable internal Pool", Expr);
               return;
            end if;

            --  Validate_Remote_Access_To_Class_Wide_Type for attribute
            --  Storage_Pool since this attribute cannot be defined for such
            --  types (RM E.2.2(17)).

            Validate_Remote_Access_To_Class_Wide_Type (N);

            --  If the argument is a name that is not an entity name, then
            --  we construct a renaming operation to define an entity of
            --  type storage pool.

            if not Is_Entity_Name (Expr)
              and then Is_Object_Reference (Expr)
            then
               Pool := Make_Temporary (Loc, 'P', Expr);

               declare
                  Rnode : constant Node_Id :=
                            Make_Object_Renaming_Declaration (Loc,
                              Defining_Identifier => Pool,
                              Subtype_Mark        =>
                                New_Occurrence_Of (Etype (Expr), Loc),
                              Name                => Expr);

               begin
                  --  If the attribute definition clause comes from an aspect
                  --  clause, then insert the renaming before the associated
                  --  entity's declaration, since the attribute clause has
                  --  not yet been appended to the declaration list.

                  if From_Aspect_Specification (N) then
                     Insert_Before (Parent (Entity (N)), Rnode);
                  else
                     Insert_Before (N, Rnode);
                  end if;

                  Analyze (Rnode);
                  Associate_Storage_Pool (U_Ent, Pool);
               end;

            elsif Is_Entity_Name (Expr) then
               Pool := Entity (Expr);

               --  If pool is a renamed object, get original one. This can
               --  happen with an explicit renaming, and within instances.

               while Present (Renamed_Object (Pool))
                 and then Is_Entity_Name (Renamed_Object (Pool))
               loop
                  Pool := Entity (Renamed_Object (Pool));
               end loop;

               if Present (Renamed_Object (Pool))
                 and then Nkind (Renamed_Object (Pool)) = N_Type_Conversion
                 and then Is_Entity_Name (Expression (Renamed_Object (Pool)))
               then
                  Pool := Entity (Expression (Renamed_Object (Pool)));
               end if;

               Associate_Storage_Pool (U_Ent, Pool);

            elsif Nkind (Expr) = N_Type_Conversion
              and then Is_Entity_Name (Expression (Expr))
              and then Nkind (Original_Node (Expr)) = N_Attribute_Reference
            then
               Pool := Entity (Expression (Expr));
               Associate_Storage_Pool (U_Ent, Pool);

            else
               Error_Msg_N ("incorrect reference to a Storage Pool", Expr);
               return;
            end if;
         end Storage_Pool;

         ------------------
         -- Storage_Size --
         ------------------

         --  Storage_Size attribute definition clause

         when Attribute_Storage_Size => Storage_Size : declare
            Btype : constant Entity_Id := Base_Type (U_Ent);

         begin
            if Is_Task_Type (U_Ent) then

               --  Check obsolescent (but never obsolescent if from aspect)

               if not From_Aspect_Specification (N) then
                  Check_Restriction (No_Obsolescent_Features, N);

                  if Warn_On_Obsolescent_Feature then
                     Error_Msg_N
                       ("?j?storage size clause for task is an obsolescent "
                        & "feature (RM J.9)", N);
                     Error_Msg_N ("\?j?use Storage_Size pragma instead", N);
                  end if;
               end if;

               FOnly := True;
            end if;

            if not Is_Access_Type (U_Ent)
              and then Ekind (U_Ent) /= E_Task_Type
            then
               Error_Msg_N ("storage size cannot be given for &", Nam);

            elsif Is_Access_Type (U_Ent) and Is_Derived_Type (U_Ent) then
               Error_Msg_N
                 ("storage size cannot be given for a derived access type",
                  Nam);

            elsif Duplicate_Clause then
               null;

            else
               --  Validate_Remote_Access_To_Class_Wide_Type for attribute
               --  Storage_Size since this attribute cannot be defined for such
               --  types (RM E.2.2(17)).

               Validate_Remote_Access_To_Class_Wide_Type (N);

               Analyze_And_Resolve (Expr, Any_Integer);

               if Is_Access_Type (U_Ent) then

                  --  Check for Storage_Pool previously given

                  declare
                     SP : constant Node_Id :=
                            Get_Attribute_Definition_Clause
                              (U_Ent, Attribute_Storage_Pool);

                  begin
                     if Present (SP) then
                        Check_Pool_Size_Clash (U_Ent, SP, N);
                     end if;
                  end;

                  --  Special case of for x'Storage_Size use 0

                  if Is_OK_Static_Expression (Expr)
                    and then Expr_Value (Expr) = 0
                  then
                     Set_No_Pool_Assigned (Btype);
                  end if;
               end if;

               Set_Has_Storage_Size_Clause (Btype);
            end if;
         end Storage_Size;

         -----------------
         -- Stream_Size --
         -----------------

         when Attribute_Stream_Size => Stream_Size : declare
            Size : constant Uint := Static_Integer (Expr);

         begin
            if Ada_Version <= Ada_95 then
               Check_Restriction (No_Implementation_Attributes, N);
            end if;

            if Duplicate_Clause then
               null;

            elsif Is_Elementary_Type (U_Ent) then
               --  Size will be empty if we already detected an error
               --  (e.g. Expr is of the wrong type); we might as well
               --  give the useful hint below even in that case.

               if No (Size) or else
                 (Size /= System_Storage_Unit
                  and then Size /= System_Storage_Unit * 2
                  and then Size /= System_Storage_Unit * 3
                  and then Size /= System_Storage_Unit * 4
                  and then Size /= System_Storage_Unit * 8)
               then
                  Error_Msg_N
                    ("stream size for elementary type must be 8, 16, 24, " &
                     "32 or 64", N);

               elsif Known_RM_Size (U_Ent) and then RM_Size (U_Ent) > Size then
                  Error_Msg_Uint_1 := RM_Size (U_Ent);
                  Error_Msg_N
                    ("stream size for elementary type must be 8, 16, 24, " &
                     "32 or 64 and at least ^", N);
               end if;

               Set_Has_Stream_Size_Clause (U_Ent);

            else
               Error_Msg_N ("Stream_Size cannot be given for &", Nam);
            end if;
         end Stream_Size;

         -----------------------
         -- Variable_Indexing --
         -----------------------

         when Attribute_Variable_Indexing =>
            Check_Indexing_Functions;

         -----------
         -- Write --
         -----------

         when Attribute_Write =>
            Analyze_Stream_TSS_Definition (TSS_Stream_Write);
            Set_Has_Specified_Stream_Write (Ent);

         --  All other attributes cannot be set

         when others =>
            Error_Msg_N
              ("attribute& cannot be set with definition clause", N);
      end case;

      --  The test for the type being frozen must be performed after any
      --  expression the clause has been analyzed since the expression itself
      --  might cause freezing that makes the clause illegal.

      if Rep_Item_Too_Late (U_Ent, N, FOnly) then
         return;
      end if;
   end Analyze_Attribute_Definition_Clause;

   ----------------------------
   -- Analyze_Code_Statement --
   ----------------------------

   procedure Analyze_Code_Statement (N : Node_Id) is
      HSS   : constant Node_Id   := Parent (N);
      SBody : constant Node_Id   := Parent (HSS);
      Subp  : constant Entity_Id := Current_Scope;
      Stmt  : Node_Id;
      Decl  : Node_Id;
      StmtO : Node_Id;
      DeclO : Node_Id;

   begin
      --  Accept foreign code statements for CodePeer. The analysis is skipped
      --  to avoid rejecting unrecognized constructs.

      if CodePeer_Mode then
         Set_Analyzed (N);
         return;
      end if;

      --  Analyze and check we get right type, note that this implements the
      --  requirement (RM 13.8(1)) that Machine_Code be with'ed, since that is
      --  the only way that Asm_Insn could possibly be visible.

      Analyze_And_Resolve (Expression (N));

      if Etype (Expression (N)) = Any_Type then
         return;
      elsif not Is_RTE (Etype (Expression (N)), RE_Asm_Insn) then
         Error_Msg_N ("incorrect type for code statement", N);
         return;
      end if;

      Check_Code_Statement (N);

      --  Make sure we appear in the handled statement sequence of a subprogram
      --  (RM 13.8(3)).

      if Nkind (HSS) /= N_Handled_Sequence_Of_Statements
        or else Nkind (SBody) /= N_Subprogram_Body
      then
         Error_Msg_N
           ("code statement can only appear in body of subprogram", N);
         return;
      end if;

      --  Do remaining checks (RM 13.8(3)) if not already done

      if not Is_Machine_Code_Subprogram (Subp) then
         Set_Is_Machine_Code_Subprogram (Subp);

         --  No exception handlers allowed

         if Present (Exception_Handlers (HSS)) then
            Error_Msg_N
              ("exception handlers not permitted in machine code subprogram",
               First (Exception_Handlers (HSS)));
         end if;

         --  No declarations other than use clauses and pragmas (we allow
         --  certain internally generated declarations as well).

         Decl := First (Declarations (SBody));
         while Present (Decl) loop
            DeclO := Original_Node (Decl);
            if Comes_From_Source (DeclO)
              and Nkind (DeclO) not in N_Pragma
                                     | N_Use_Package_Clause
                                     | N_Use_Type_Clause
                                     | N_Implicit_Label_Declaration
            then
               Error_Msg_N
                 ("this declaration is not allowed in machine code subprogram",
                  DeclO);
            end if;

            Next (Decl);
         end loop;

         --  No statements other than code statements, pragmas, and labels.
         --  Again we allow certain internally generated statements.

         --  In Ada 2012, qualified expressions are names, and the code
         --  statement is initially parsed as a procedure call.

         Stmt := First (Statements (HSS));
         while Present (Stmt) loop
            StmtO := Original_Node (Stmt);

            --  A procedure call transformed into a code statement is OK

            if Ada_Version >= Ada_2012
              and then Nkind (StmtO) = N_Procedure_Call_Statement
              and then Nkind (Name (StmtO)) = N_Qualified_Expression
            then
               null;

            elsif Comes_From_Source (StmtO)
              and then Nkind (StmtO) not in
                         N_Pragma | N_Label | N_Code_Statement
            then
               Error_Msg_N
                 ("this statement is not allowed in machine code subprogram",
                  StmtO);
            end if;

            Next (Stmt);
         end loop;
      end if;
   end Analyze_Code_Statement;

   -----------------------------------------------
   -- Analyze_Enumeration_Representation_Clause --
   -----------------------------------------------

   procedure Analyze_Enumeration_Representation_Clause (N : Node_Id) is
      Ident    : constant Node_Id := Identifier (N);
      Aggr     : constant Node_Id := Array_Aggregate (N);
      Enumtype : Entity_Id;
      Elit     : Entity_Id;
      Expr     : Node_Id;
      Assoc    : Node_Id;
      Choice   : Node_Id;
      Val      : Uint;

      Err : Boolean := False;
      --  Set True to avoid cascade errors and crashes on incorrect source code

      Lo : constant Uint := Expr_Value (Type_Low_Bound (Universal_Integer));
      Hi : constant Uint := Expr_Value (Type_High_Bound (Universal_Integer));
      --  Allowed range of universal integer (= allowed range of enum lit vals)

      Min : Uint;
      Max : Uint;
      --  Minimum and maximum values of entries

      Max_Node : Node_Id := Empty; -- init to avoid warning
      --  Pointer to node for literal providing max value

   begin
      if Ignore_Rep_Clauses then
         Kill_Rep_Clause (N);
         return;
      end if;

      --  Ignore enumeration rep clauses by default in CodePeer mode,
      --  unless -gnatd.I is specified, as a work around for potential false
      --  positive messages.

      if CodePeer_Mode and not Debug_Flag_Dot_II then
         return;
      end if;

      --  First some basic error checks

      Find_Type (Ident);
      Enumtype := Entity (Ident);

      if Enumtype = Any_Type
        or else Rep_Item_Too_Early (Enumtype, N)
      then
         return;
      else
         Enumtype := Underlying_Type (Enumtype);
      end if;

      if not Is_Enumeration_Type (Enumtype) then
         Error_Msg_NE
           ("enumeration type required, found}",
            Ident, First_Subtype (Enumtype));
         return;
      end if;

      --  Ignore rep clause on generic actual type. This will already have
      --  been flagged on the template as an error, and this is the safest
      --  way to ensure we don't get a junk cascaded message in the instance.

      if Is_Generic_Actual_Type (Enumtype) then
         return;

      --  Type must be in current scope

      elsif Scope (Enumtype) /= Current_Scope then
         Error_Msg_N ("type must be declared in this scope", Ident);
         return;

      --  Type must be a first subtype

      elsif not Is_First_Subtype (Enumtype) then
         Error_Msg_N ("cannot give enumeration rep clause for subtype", N);
         return;

      --  Ignore duplicate rep clause

      elsif Has_Enumeration_Rep_Clause (Enumtype) then
         Error_Msg_N ("duplicate enumeration rep clause ignored", N);
         return;

      --  Don't allow rep clause for standard [wide_[wide_]]character

      elsif Is_Standard_Character_Type (Enumtype) then
         Error_Msg_N ("enumeration rep clause not allowed for this type", N);
         return;

      --  Check that the expression is a proper aggregate (no parentheses)

      elsif Paren_Count (Aggr) /= 0 then
         Error_Msg_F
           ("extra parentheses surrounding aggregate not allowed", Aggr);
         return;

      --  Reject the mixing of named and positional entries in the aggregate

      elsif Present (Expressions (Aggr))
        and then Present (Component_Associations (Aggr))
      then
         Error_Msg_N ("cannot mix positional and named entries in "
                       & "enumeration rep clause", N);
         return;

      --  All tests passed, so set rep clause in place

      else
         Set_Has_Enumeration_Rep_Clause (Enumtype);
         Set_Has_Enumeration_Rep_Clause (Base_Type (Enumtype));
      end if;

      --  Now we process the aggregate. Note that we don't use the normal
      --  aggregate code for this purpose, because we don't want any of the
      --  normal expansion activities, and a number of special semantic
      --  rules apply (including the component type being any integer type)

      Elit := First_Literal (Enumtype);

      --  Process positional entries

      if Present (Expressions (Aggr)) then
         Expr := First (Expressions (Aggr));
         while Present (Expr) loop
            if No (Elit) then
               Error_Msg_N ("too many entries in aggregate", Expr);
               return;
            end if;

            Val := Static_Integer (Expr);

            --  Err signals that we found some incorrect entries processing
            --  the list. The final checks for completeness and ordering are
            --  skipped in this case.

            if No (Val) then
               Err := True;

            elsif Val < Lo or else Hi < Val then
               Error_Msg_N ("value outside permitted range", Expr);
               Err := True;

            else
               Set_Enumeration_Rep (Elit, Val);
               Set_Enumeration_Rep_Expr (Elit, Expr);
            end if;

            Next (Expr);
            Next (Elit);
         end loop;

      --  Process named entries

      elsif Present (Component_Associations (Aggr)) then
         Assoc := First (Component_Associations (Aggr));
         while Present (Assoc) loop
            Choice := First (Choices (Assoc));

            if Present (Next (Choice)) then
               Error_Msg_N
                 ("multiple choice not allowed here", Next (Choice));
               Err := True;
            end if;

            if Nkind (Choice) = N_Others_Choice then
               Error_Msg_N ("OTHERS choice not allowed here", Choice);
               Err := True;

            elsif Nkind (Choice) = N_Range then

               --  ??? should allow zero/one element range here

               Error_Msg_N ("range not allowed here", Choice);
               Err := True;

            else
               Analyze_And_Resolve (Choice, Enumtype);

               if Error_Posted (Choice) then
                  Err := True;
               end if;

               if not Err then
                  if Is_Entity_Name (Choice)
                    and then Is_Type (Entity (Choice))
                  then
                     Error_Msg_N ("subtype name not allowed here", Choice);
                     Err := True;

                     --  ??? should allow static subtype with zero/one entry

                  elsif Etype (Choice) = Base_Type (Enumtype) then
                     if not Is_OK_Static_Expression (Choice) then
                        Flag_Non_Static_Expr
                          ("non-static expression used for choice!", Choice);
                        Err := True;

                     else
                        Elit := Expr_Value_E (Choice);

                        if Present (Enumeration_Rep_Expr (Elit)) then
                           Error_Msg_Sloc :=
                             Sloc (Enumeration_Rep_Expr (Elit));
                           Error_Msg_NE
                             ("representation for& previously given#",
                              Choice, Elit);
                           Err := True;
                        end if;

                        Set_Enumeration_Rep_Expr (Elit, Expression (Assoc));

                        Expr := Expression (Assoc);
                        Val := Static_Integer (Expr);

                        if No (Val) then
                           Err := True;

                        elsif Val < Lo or else Hi < Val then
                           Error_Msg_N ("value outside permitted range", Expr);
                           Err := True;

                        else
                           Set_Enumeration_Rep (Elit, Val);
                        end if;
                     end if;
                  end if;
               end if;
            end if;

            Next (Assoc);
         end loop;
      end if;

      --  Aggregate is fully processed. Now we check that a full set of
      --  representations was given, and that they are in range and in order.
      --  These checks are only done if no other errors occurred.

      if not Err then
         Min  := No_Uint;
         Max  := No_Uint;

         Elit := First_Literal (Enumtype);
         while Present (Elit) loop
            if No (Enumeration_Rep_Expr (Elit)) then
               Error_Msg_NE ("missing representation for&!", N, Elit);

            else
               Val := Enumeration_Rep (Elit);

               if No (Min) then
                  Min := Val;
               end if;

               if Present (Val) then
                  if Present (Max) and then Val <= Max then
                     Error_Msg_NE
                       ("enumeration value for& not ordered!",
                        Enumeration_Rep_Expr (Elit), Elit);
                  end if;

                  Max_Node := Enumeration_Rep_Expr (Elit);
                  Max := Val;
               end if;

               --  If there is at least one literal whose representation is not
               --  equal to the Pos value, then note that this enumeration type
               --  has a non-standard representation.

               if Val /= Enumeration_Pos (Elit) then
                  Set_Has_Non_Standard_Rep (Base_Type (Enumtype));
               end if;
            end if;

            Next (Elit);
         end loop;

         --  Now set proper size information

         declare
            Minsize : Uint := UI_From_Int (Minimum_Size (Enumtype));

         begin
            if Has_Size_Clause (Enumtype) then

               --  All OK, if size is OK now

               if RM_Size (Enumtype) >= Minsize then
                  null;

               else
                  --  Try if we can get by with biasing

                  Minsize :=
                    UI_From_Int (Minimum_Size (Enumtype, Biased => True));

                  --  Error message if even biasing does not work

                  if RM_Size (Enumtype) < Minsize then
                     Error_Msg_Uint_1 := RM_Size (Enumtype);
                     Error_Msg_Uint_2 := Max;
                     Error_Msg_N
                       ("previously given size (^) is too small "
                        & "for this value (^)", Max_Node);

                  --  If biasing worked, indicate that we now have biased rep

                  else
                     Set_Biased
                       (Enumtype, Size_Clause (Enumtype), "size clause");
                  end if;
               end if;

            else
               Set_RM_Size    (Enumtype, Minsize);
               Set_Enum_Esize (Enumtype);
            end if;

            Set_RM_Size (Base_Type (Enumtype), RM_Size   (Enumtype));
            Set_Esize   (Base_Type (Enumtype), Esize     (Enumtype));

            Copy_Alignment (To => Base_Type (Enumtype), From => Enumtype);
         end;
      end if;

      --  We repeat the too late test in case it froze itself

      if Rep_Item_Too_Late (Enumtype, N) then
         null;
      end if;
   end Analyze_Enumeration_Representation_Clause;

   ----------------------------
   -- Analyze_Free_Statement --
   ----------------------------

   procedure Analyze_Free_Statement (N : Node_Id) is
   begin
      Analyze (Expression (N));
   end Analyze_Free_Statement;

   ---------------------------
   -- Analyze_Freeze_Entity --
   ---------------------------

   procedure Analyze_Freeze_Entity (N : Node_Id) is
   begin
      Freeze_Entity_Checks (N);
   end Analyze_Freeze_Entity;

   -----------------------------------
   -- Analyze_Freeze_Generic_Entity --
   -----------------------------------

   procedure Analyze_Freeze_Generic_Entity (N : Node_Id) is
      E : constant Entity_Id := Entity (N);

   begin
      if not Is_Frozen (E) and then Has_Delayed_Aspects (E) then
         Analyze_Aspects_At_Freeze_Point (E);
      end if;

      Freeze_Entity_Checks (N);
   end Analyze_Freeze_Generic_Entity;

   ------------------------------------------
   -- Analyze_Record_Representation_Clause --
   ------------------------------------------

   --  Note: we check as much as we can here, but we can't do any checks
   --  based on the position values (e.g. overlap checks) until freeze time
   --  because especially in Ada 2005 (machine scalar mode), the processing
   --  for non-standard bit order can substantially change the positions.
   --  See procedure Check_Record_Representation_Clause (called from Freeze)
   --  for the remainder of this processing.

   procedure Analyze_Record_Representation_Clause (N : Node_Id) is
      Ident   : constant Node_Id := Identifier (N);
      Biased  : Boolean;
      CC      : Node_Id;
      Comp    : Entity_Id;
      Fbit    : Uint;
      Lbit    : Uint;
      Ocomp   : Entity_Id;
      Posit   : Uint;
      Rectype : Entity_Id;
      Recdef  : Node_Id;

      function Is_Inherited (Comp : Entity_Id) return Boolean;
      --  True if Comp is an inherited component in a record extension

      ------------------
      -- Is_Inherited --
      ------------------

      function Is_Inherited (Comp : Entity_Id) return Boolean is
         Comp_Base : Entity_Id;

      begin
         if Ekind (Rectype) = E_Record_Subtype then
            Comp_Base := Original_Record_Component (Comp);
         else
            Comp_Base := Comp;
         end if;

         return Comp_Base /= Original_Record_Component (Comp_Base);
      end Is_Inherited;

      --  Local variables

      Is_Record_Extension : Boolean;
      --  True if Rectype is a record extension

      CR_Pragma : Node_Id := Empty;
      --  Points to N_Pragma node if Complete_Representation pragma present

   --  Start of processing for Analyze_Record_Representation_Clause

   begin
      if Ignore_Rep_Clauses then
         Kill_Rep_Clause (N);
         return;
      end if;

      Find_Type (Ident);
      Rectype := Entity (Ident);

      if Rectype = Any_Type or else Rep_Item_Too_Early (Rectype, N) then
         return;
      else
         Rectype := Underlying_Type (Rectype);
      end if;

      --  First some basic error checks

      if not Is_Record_Type (Rectype) then
         Error_Msg_NE
           ("record type required, found}", Ident, First_Subtype (Rectype));
         return;

      elsif Scope (Rectype) /= Current_Scope then
         Error_Msg_N ("type must be declared in this scope", N);
         return;

      elsif not Is_First_Subtype (Rectype) then
         Error_Msg_N ("cannot give record rep clause for subtype", N);
         return;

      elsif Has_Record_Rep_Clause (Rectype) then
         Error_Msg_N ("duplicate record rep clause ignored", N);
         return;

      elsif Rep_Item_Too_Late (Rectype, N) then
         return;
      end if;

      --  We know we have a first subtype, now possibly go to the anonymous
      --  base type to determine whether Rectype is a record extension.

      Recdef := Type_Definition (Declaration_Node (Base_Type (Rectype)));
      Is_Record_Extension :=
        Nkind (Recdef) = N_Derived_Type_Definition
          and then Present (Record_Extension_Part (Recdef));

      if Present (Mod_Clause (N)) then
         declare
            M      : constant Node_Id := Mod_Clause (N);
            P      : constant List_Id := Pragmas_Before (M);
            Ignore : Uint;

         begin
            Check_Restriction (No_Obsolescent_Features, Mod_Clause (N));

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("?j?mod clause is an obsolescent feature (RM J.8)", N);
               Error_Msg_N
                 ("\?j?use alignment attribute definition clause instead", N);
            end if;

            if Present (P) then
               Analyze_List (P);
            end if;

            --  Get the alignment value to perform error checking

            Ignore := Get_Alignment_Value (Expression (M));
         end;
      end if;

      --  For untagged types, clear any existing component clauses for the
      --  type. If the type is derived, this is what allows us to override
      --  a rep clause for the parent. For type extensions, the representation
      --  of the inherited components is inherited, so we want to keep previous
      --  component clauses for completeness.

      if not Is_Tagged_Type (Rectype) then
         Comp := First_Component_Or_Discriminant (Rectype);
         while Present (Comp) loop
            Set_Component_Clause (Comp, Empty);
            Next_Component_Or_Discriminant (Comp);
         end loop;
      end if;

      --  All done if no component clauses

      CC := First (Component_Clauses (N));

      if No (CC) then
         return;
      end if;

      --  A representation like this applies to the base type

      Set_Has_Record_Rep_Clause (Base_Type (Rectype));
      Set_Has_Non_Standard_Rep  (Base_Type (Rectype));
      Set_Has_Specified_Layout  (Base_Type (Rectype));

      --  Process the component clauses

      while Present (CC) loop

         --  Pragma

         if Nkind (CC) = N_Pragma then
            Analyze (CC);

            --  The only pragma of interest is Complete_Representation

            if Pragma_Name (CC) = Name_Complete_Representation then
               CR_Pragma := CC;
            end if;

         --  Processing for real component clause

         else
            Posit := Static_Integer (Position  (CC));
            Fbit  := Static_Integer (First_Bit (CC));
            Lbit  := Static_Integer (Last_Bit  (CC));

            if Present (Posit)
              and then Present (Fbit)
              and then Present (Lbit)
            then
               if Posit < 0 then
                  Error_Msg_N ("position cannot be negative", Position (CC));

               elsif Fbit < 0 then
                  Error_Msg_N ("first bit cannot be negative", First_Bit (CC));

               --  The Last_Bit specified in a component clause must not be
               --  less than the First_Bit minus one (RM-13.5.1(10)).

               elsif Lbit < Fbit - 1 then
                  Error_Msg_N
                    ("last bit cannot be less than first bit minus one",
                     Last_Bit (CC));

               --  Values look OK, so find the corresponding record component
               --  Even though the syntax allows an attribute reference for
               --  implementation-defined components, GNAT does not allow the
               --  tag to get an explicit position.

               elsif Nkind (Component_Name (CC)) = N_Attribute_Reference then
                  if Attribute_Name (Component_Name (CC)) = Name_Tag then
                     Error_Msg_N ("position of tag cannot be specified", CC);
                  else
                     Error_Msg_N ("illegal component name", CC);
                  end if;

               else
                  Comp := First_Entity (Rectype);
                  while Present (Comp) loop
                     exit when Chars (Comp) = Chars (Component_Name (CC));
                     Next_Entity (Comp);
                  end loop;

                  if No (Comp) then

                     --  Maybe component of base type that is absent from
                     --  statically constrained first subtype.

                     Comp := First_Entity (Base_Type (Rectype));
                     while Present (Comp) loop
                        exit when Chars (Comp) = Chars (Component_Name (CC));
                        Next_Entity (Comp);
                     end loop;
                  end if;

                  if No (Comp) then
                     Error_Msg_N
                       ("component clause is for non-existent field", CC);

                  --  Ada 2012 (AI05-0026): Any name that denotes a
                  --  discriminant of an object of an unchecked union type
                  --  shall not occur within a record_representation_clause.

                  --  The general restriction of using record rep clauses on
                  --  Unchecked_Union types has now been lifted. Since it is
                  --  possible to introduce a record rep clause which mentions
                  --  the discriminant of an Unchecked_Union in non-Ada 2012
                  --  code, this check is applied to all versions of the
                  --  language.

                  elsif Ekind (Comp) = E_Discriminant
                    and then Is_Unchecked_Union (Rectype)
                  then
                     Error_Msg_N
                       ("cannot reference discriminant of unchecked union",
                        Component_Name (CC));

                  elsif Is_Record_Extension and then Is_Inherited (Comp) then
                     Error_Msg_NE
                       ("component clause not allowed for inherited "
                        & "component&", CC, Comp);

                  elsif Present (Component_Clause (Comp)) then

                     --  Diagnose duplicate rep clause, or check consistency
                     --  if this is an inherited component. In a double fault,
                     --  there may be a duplicate inconsistent clause for an
                     --  inherited component.

                     if Scope (Original_Record_Component (Comp)) = Rectype
                       or else Parent (Component_Clause (Comp)) = N
                     then
                        Error_Msg_Sloc := Sloc (Component_Clause (Comp));
                        Error_Msg_N ("component clause previously given#", CC);

                     else
                        declare
                           Rep1 : constant Node_Id := Component_Clause (Comp);
                        begin
                           if Intval (Position (Rep1)) /=
                                                   Intval (Position (CC))
                             or else Intval (First_Bit (Rep1)) /=
                                                   Intval (First_Bit (CC))
                             or else Intval (Last_Bit (Rep1)) /=
                                                   Intval (Last_Bit (CC))
                           then
                              Error_Msg_N
                                ("component clause inconsistent with "
                                 & "representation of ancestor", CC);

                           elsif Warn_On_Redundant_Constructs then
                              Error_Msg_N
                                ("?r?redundant confirming component clause "
                                 & "for component!", CC);
                           end if;
                        end;
                     end if;

                  --  Normal case where this is the first component clause we
                  --  have seen for this entity, so set it up properly.

                  else
                     --  Make reference for field in record rep clause and set
                     --  appropriate entity field in the field identifier.

                     Generate_Reference
                       (Comp, Component_Name (CC), Set_Ref => False);
                     Set_Entity_With_Checks (Component_Name (CC), Comp);

                     --  Update Fbit and Lbit to the actual bit number

                     Fbit := Fbit + UI_From_Int (SSU) * Posit;
                     Lbit := Lbit + UI_From_Int (SSU) * Posit;

                     if Has_Size_Clause (Rectype)
                       and then RM_Size (Rectype) <= Lbit
                     then
                        Error_Msg_Uint_1 := RM_Size (Rectype);
                        Error_Msg_Uint_2 := Lbit + 1;
                        Error_Msg_N ("bit number out of range of specified "
                           & "size (expected ^, got ^)",
                           Last_Bit (CC));
                     else
                        Set_Component_Clause     (Comp, CC);
                        Set_Component_Bit_Offset (Comp, Fbit);
                        Set_Esize                (Comp, 1 + (Lbit - Fbit));
                        Set_Normalized_First_Bit (Comp, Fbit mod SSU);
                        Set_Normalized_Position  (Comp, Fbit / SSU);

                        if Warn_On_Overridden_Size
                          and then Has_Size_Clause (Etype (Comp))
                          and then RM_Size (Etype (Comp)) /= Esize (Comp)
                        then
                           Error_Msg_NE
                             ("?.s?component size overrides size clause for&",
                              Component_Name (CC), Etype (Comp));
                        end if;

                        Check_Size
                          (Component_Name (CC),
                           Etype (Comp),
                           Esize (Comp),
                           Biased);

                        Set_Biased
                          (Comp, First_Node (CC), "component clause", Biased);

                        --  This information is also set in the corresponding
                        --  component of the base type, found by accessing the
                        --  Original_Record_Component link if it is present.

                        Ocomp := Original_Record_Component (Comp);

                        if Present (Ocomp) and then Ocomp /= Comp then
                           Set_Component_Clause     (Ocomp, CC);
                           Set_Component_Bit_Offset (Ocomp, Fbit);
                           Set_Esize                (Ocomp, 1 + (Lbit - Fbit));
                           Set_Normalized_First_Bit (Ocomp, Fbit mod SSU);
                           Set_Normalized_Position  (Ocomp, Fbit / SSU);

                           --  Note: we don't use Set_Biased here, because we
                           --  already gave a warning above if needed, and we
                           --  would get a duplicate for the same name here.

                           Set_Has_Biased_Representation
                             (Ocomp, Has_Biased_Representation (Comp));
                        end if;

                        if Esize (Comp) < 0 then
                           Error_Msg_N ("component size is negative", CC);
                        end if;
                     end if;
                  end if;
               end if;
            end if;
         end if;

         Next (CC);
      end loop;

      --  Check missing components if Complete_Representation pragma appeared

      if Present (CR_Pragma) then
         Comp := First_Component_Or_Discriminant (Rectype);
         while Present (Comp) loop
            if No (Component_Clause (Comp)) then
               Error_Msg_NE
                 ("missing component clause for &", CR_Pragma, Comp);
            end if;

            Next_Component_Or_Discriminant (Comp);
         end loop;

      --  Give missing components warning if required

      elsif Warn_On_Unrepped_Components then
         declare
            Num_Repped_Components   : Nat := 0;
            Num_Unrepped_Components : Nat := 0;

         begin
            --  First count number of repped and unrepped components

            Comp := First_Component_Or_Discriminant (Rectype);
            while Present (Comp) loop
               if Present (Component_Clause (Comp)) then
                  Num_Repped_Components := Num_Repped_Components + 1;
               else
                  Num_Unrepped_Components := Num_Unrepped_Components + 1;
               end if;

               Next_Component_Or_Discriminant (Comp);
            end loop;

            --  We are only interested in the case where there is at least one
            --  unrepped component, and at least half the components have rep
            --  clauses. We figure that if less than half have them, then the
            --  partial rep clause is really intentional. If the component
            --  type has no underlying type set at this point (as for a generic
            --  formal type), we don't know enough to give a warning on the
            --  component.

            if Num_Unrepped_Components > 0
              and then Num_Unrepped_Components < Num_Repped_Components
            then
               Comp := First_Component_Or_Discriminant (Rectype);
               while Present (Comp) loop
                  if No (Component_Clause (Comp))
                    and then Comes_From_Source (Comp)
                    and then Present (Underlying_Type (Etype (Comp)))
                    and then (Is_Scalar_Type (Underlying_Type (Etype (Comp)))
                               or else Size_Known_At_Compile_Time
                                         (Underlying_Type (Etype (Comp))))
                    and then not Has_Warnings_Off (Rectype)

                    --  Ignore discriminant in unchecked union, since it is
                    --  not there, and cannot have a component clause.

                    and then (not Is_Unchecked_Union (Rectype)
                               or else Ekind (Comp) /= E_Discriminant)
                  then
                     Error_Msg_Sloc := Sloc (Comp);
                     Error_Msg_NE
                       ("?.c?no component clause given for & declared #",
                        N, Comp);
                  end if;

                  Next_Component_Or_Discriminant (Comp);
               end loop;
            end if;
         end;
      end if;
   end Analyze_Record_Representation_Clause;

   -------------------------------------
   -- Build_Discrete_Static_Predicate --
   -------------------------------------

   procedure Build_Discrete_Static_Predicate
     (Typ  : Entity_Id;
      Expr : Node_Id;
      Nam  : Name_Id)
   is
      Loc : constant Source_Ptr := Sloc (Expr);

      Btyp : constant Entity_Id := Base_Type (Typ);

      BLo : constant Uint := Expr_Value (Type_Low_Bound  (Btyp));
      BHi : constant Uint := Expr_Value (Type_High_Bound (Btyp));
      --  Low bound and high bound value of base type of Typ

      TLo : Uint;
      THi : Uint;
      --  Bounds for constructing the static predicate. We use the bound of the
      --  subtype if it is static, otherwise the corresponding base type bound.
      --  Note: a non-static subtype can have a static predicate.

      type REnt is record
         Lo, Hi : Uint;
      end record;
      --  One entry in a Rlist value, a single REnt (range entry) value denotes
      --  one range from Lo to Hi. To represent a single value range Lo = Hi =
      --  value.

      type RList is array (Nat range <>) of REnt;
      --  A list of ranges. The ranges are sorted in increasing order, and are
      --  disjoint (there is a gap of at least one value between each range in
      --  the table). A value is in the set of ranges in Rlist if it lies
      --  within one of these ranges.

      False_Range : constant RList :=
        RList'(1 .. 0 => REnt'(No_Uint, No_Uint));
      --  An empty set of ranges represents a range list that can never be
      --  satisfied, since there are no ranges in which the value could lie,
      --  so it does not lie in any of them. False_Range is a canonical value
      --  for this empty set, but general processing should test for an Rlist
      --  with length zero (see Is_False predicate), since other null ranges
      --  may appear which must be treated as False.

      True_Range : constant RList := RList'(1 => REnt'(BLo, BHi));
      --  Range representing True, value must be in the base range

      function "and" (Left : RList; Right : RList) return RList;
      --  And's together two range lists, returning a range list. This is a set
      --  intersection operation.

      function "or" (Left : RList; Right : RList) return RList;
      --  Or's together two range lists, returning a range list. This is a set
      --  union operation.

      function "not" (Right : RList) return RList;
      --  Returns complement of a given range list, i.e. a range list
      --  representing all the values in TLo .. THi that are not in the input
      --  operand Right.

      function Build_Val (V : Uint) return Node_Id;
      --  Return an analyzed N_Identifier node referencing this value, suitable
      --  for use as an entry in the Static_Discrete_Predicate list. This node
      --  is typed with the base type.

      function Build_Range (Lo : Uint; Hi : Uint) return Node_Id;
      --  Return an analyzed N_Range node referencing this range, suitable for
      --  use as an entry in the Static_Discrete_Predicate list. This node is
      --  typed with the base type.

      function Get_RList
        (Exp    : Node_Id;
         Static : access Boolean) return RList;
      --  This is a recursive routine that converts the given expression into a
      --  list of ranges, suitable for use in building the static predicate.
      --  Static.all will be set to False if the expression is found to be non
      --  static. Note that Static.all should be set to True by the caller.

      function Is_False (R : RList) return Boolean;
      pragma Inline (Is_False);
      --  Returns True if the given range list is empty, and thus represents a
      --  False list of ranges that can never be satisfied.

      function Is_True (R : RList) return Boolean;
      --  Returns True if R trivially represents the True predicate by having a
      --  single range from BLo to BHi.

      function Is_Type_Ref (N : Node_Id) return Boolean;
      pragma Inline (Is_Type_Ref);
      --  Returns if True if N is a reference to the type for the predicate in
      --  the expression (i.e. if it is an identifier whose Chars field matches
      --  the Nam given in the call). N must not be parenthesized, if the type
      --  name appears in parens, this routine will return False.

      function Lo_Val (N : Node_Id) return Uint;
      --  Given an entry from a Static_Discrete_Predicate list that is either
      --  a static expression or static range, gets either the expression value
      --  or the low bound of the range.

      function Hi_Val (N : Node_Id) return Uint;
      --  Given an entry from a Static_Discrete_Predicate list that is either
      --  a static expression or static range, gets either the expression value
      --  or the high bound of the range.

      function Membership_Entry
        (N : Node_Id; Static : access Boolean) return RList;
      --  Given a single membership entry (range, value, or subtype), returns
      --  the corresponding range list. Set Static.all to False if not static.

      function Membership_Entries
        (N : Node_Id; Static : access Boolean) return RList;
      --  Given an element on an alternatives list of a membership operation,
      --  returns the range list corresponding to this entry and all following
      --  entries (i.e. returns the "or" of this list of values).
      --  Set Static.all to False if not static.

      function Stat_Pred
        (Typ    : Entity_Id;
         Static : access Boolean) return RList;
      --  Given a type, if it has a static predicate, then set Result to the
      --  predicate as a range list, otherwise set Static.all to False.

      -----------
      -- "and" --
      -----------

      function "and" (Left : RList; Right : RList) return RList is
         FEnt : REnt;
         --  First range of result

         SLeft : Nat := Left'First;
         --  Start of rest of left entries

         SRight : Nat := Right'First;
         --  Start of rest of right entries

      begin
         --  If either range is True, return the other

         if Is_True (Left) then
            return Right;
         elsif Is_True (Right) then
            return Left;
         end if;

         --  If either range is False, return False

         if Is_False (Left) or else Is_False (Right) then
            return False_Range;
         end if;

         --  Loop to remove entries at start that are disjoint, and thus just
         --  get discarded from the result entirely.

         loop
            --  If no operands left in either operand, result is false

            if SLeft > Left'Last or else SRight > Right'Last then
               return False_Range;

            --  Discard first left operand entry if disjoint with right

            elsif Left (SLeft).Hi < Right (SRight).Lo then
               SLeft := SLeft + 1;

            --  Discard first right operand entry if disjoint with left

            elsif Right (SRight).Hi < Left (SLeft).Lo then
               SRight := SRight + 1;

            --  Otherwise we have an overlapping entry

            else
               exit;
            end if;
         end loop;

         --  Now we have two non-null operands, and first entries overlap. The
         --  first entry in the result will be the overlapping part of these
         --  two entries.

         FEnt := REnt'(Lo => UI_Max (Left (SLeft).Lo, Right (SRight).Lo),
                       Hi => UI_Min (Left (SLeft).Hi, Right (SRight).Hi));

         --  Now we can remove the entry that ended at a lower value, since its
         --  contribution is entirely contained in Fent.

         if Left (SLeft).Hi <= Right (SRight).Hi then
            SLeft := SLeft + 1;
         else
            SRight := SRight + 1;
         end if;

         --  Compute result by concatenating this first entry with the "and" of
         --  the remaining parts of the left and right operands. Note that if
         --  either of these is empty, "and" will yield empty, so that we will
         --  end up with just Fent, which is what we want in that case.

         return
           FEnt & (Left (SLeft .. Left'Last) and Right (SRight .. Right'Last));
      end "and";

      -----------
      -- "not" --
      -----------

      function "not" (Right : RList) return RList is
      begin
         --  Return True if False range

         if Is_False (Right) then
            return True_Range;
         end if;

         --  Return False if True range

         if Is_True (Right) then
            return False_Range;
         end if;

         --  Here if not trivial case

         declare
            Result : RList (1 .. Right'Length + 1);
            --  May need one more entry for gap at beginning and end

            Count : Nat := 0;
            --  Number of entries stored in Result

         begin
            --  Gap at start

            if Right (Right'First).Lo > TLo then
               Count := Count + 1;
               Result (Count) := REnt'(TLo, Right (Right'First).Lo - 1);
            end if;

            --  Gaps between ranges

            for J in Right'First .. Right'Last - 1 loop
               Count := Count + 1;
               Result (Count) := REnt'(Right (J).Hi + 1, Right (J + 1).Lo - 1);
            end loop;

            --  Gap at end

            if Right (Right'Last).Hi < THi then
               Count := Count + 1;
               Result (Count) := REnt'(Right (Right'Last).Hi + 1, THi);
            end if;

            return Result (1 .. Count);
         end;
      end "not";

      ----------
      -- "or" --
      ----------

      function "or" (Left : RList; Right : RList) return RList is
         FEnt : REnt;
         --  First range of result

         SLeft : Nat := Left'First;
         --  Start of rest of left entries

         SRight : Nat := Right'First;
         --  Start of rest of right entries

      begin
         --  If either range is True, return True

         if Is_True (Left) or else Is_True (Right) then
            return True_Range;
         end if;

         --  If either range is False (empty), return the other

         if Is_False (Left) then
            return Right;
         elsif Is_False (Right) then
            return Left;
         end if;

         --  Initialize result first entry from left or right operand depending
         --  on which starts with the lower range.

         if Left (SLeft).Lo < Right (SRight).Lo then
            FEnt := Left (SLeft);
            SLeft := SLeft + 1;
         else
            FEnt := Right (SRight);
            SRight := SRight + 1;
         end if;

         --  This loop eats ranges from left and right operands that are
         --  contiguous with the first range we are gathering.

         loop
            --  Eat first entry in left operand if contiguous or overlapped by
            --  gathered first operand of result.

            if SLeft <= Left'Last
              and then Left (SLeft).Lo <= FEnt.Hi + 1
            then
               FEnt.Hi := UI_Max (FEnt.Hi, Left (SLeft).Hi);
               SLeft := SLeft + 1;

            --  Eat first entry in right operand if contiguous or overlapped by
            --  gathered right operand of result.

            elsif SRight <= Right'Last
              and then Right (SRight).Lo <= FEnt.Hi + 1
            then
               FEnt.Hi := UI_Max (FEnt.Hi, Right (SRight).Hi);
               SRight := SRight + 1;

            --  All done if no more entries to eat

            else
               exit;
            end if;
         end loop;

         --  Obtain result as the first entry we just computed, concatenated
         --  to the "or" of the remaining results (if one operand is empty,
         --  this will just concatenate with the other

         return
           FEnt & (Left (SLeft .. Left'Last) or Right (SRight .. Right'Last));
      end "or";

      -----------------
      -- Build_Range --
      -----------------

      function Build_Range (Lo : Uint; Hi : Uint) return Node_Id is
         Result : Node_Id;
      begin
         Result :=
           Make_Range (Loc,
              Low_Bound  => Build_Val (Lo),
              High_Bound => Build_Val (Hi));
         Set_Etype (Result, Btyp);
         Set_Analyzed (Result);
         return Result;
      end Build_Range;

      ---------------
      -- Build_Val --
      ---------------

      function Build_Val (V : Uint) return Node_Id is
         Result : Node_Id;

      begin
         if Is_Enumeration_Type (Typ) then
            Result := Get_Enum_Lit_From_Pos (Typ, V, Loc);
         else
            Result := Make_Integer_Literal (Loc, V);
         end if;

         Set_Etype (Result, Btyp);
         Set_Is_Static_Expression (Result);
         Set_Analyzed (Result);
         return Result;
      end Build_Val;

      ---------------
      -- Get_RList --
      ---------------

      function Get_RList
        (Exp    : Node_Id;
         Static : access Boolean) return RList
      is
         Op  : Node_Kind;
         Val : Uint;

      begin
         --  Static expression can only be true or false

         if Is_OK_Static_Expression (Exp) then
            if Expr_Value (Exp) = 0 then
               return False_Range;
            else
               return True_Range;
            end if;
         end if;

         --  Otherwise test node type

         Op := Nkind (Exp);

         case Op is

            --  And

            when N_And_Then
               | N_Op_And
            =>
               return Get_RList (Left_Opnd (Exp), Static)
                        and
                      Get_RList (Right_Opnd (Exp), Static);

            --  Or

            when N_Op_Or
               | N_Or_Else
            =>
               return Get_RList (Left_Opnd (Exp), Static)
                        or
                      Get_RList (Right_Opnd (Exp), Static);

            --  Not

            when N_Op_Not =>
               return not Get_RList (Right_Opnd (Exp), Static);

               --  Comparisons of type with static value

            when N_Op_Compare =>

               --  Type is left operand

               if Is_Type_Ref (Left_Opnd (Exp))
                 and then Is_OK_Static_Expression (Right_Opnd (Exp))
               then
                  Val := Expr_Value (Right_Opnd (Exp));

               --  Typ is right operand

               elsif Is_Type_Ref (Right_Opnd (Exp))
                 and then Is_OK_Static_Expression (Left_Opnd (Exp))
               then
                  Val := Expr_Value (Left_Opnd (Exp));

                  --  Invert sense of comparison

                  case Op is
                     when N_Op_Gt => Op := N_Op_Lt;
                     when N_Op_Lt => Op := N_Op_Gt;
                     when N_Op_Ge => Op := N_Op_Le;
                     when N_Op_Le => Op := N_Op_Ge;
                     when others  => null;
                  end case;

               --  Other cases are non-static

               else
                  Static.all := False;
                  return False_Range;
               end if;

               --  Construct range according to comparison operation

               case Op is
                  when N_Op_Eq =>
                     return RList'(1 => REnt'(Val, Val));

                  when N_Op_Ge =>
                     return RList'(1 => REnt'(Val, BHi));

                  when N_Op_Gt =>
                     return RList'(1 => REnt'(Val + 1, BHi));

                  when N_Op_Le =>
                     return RList'(1 => REnt'(BLo, Val));

                  when N_Op_Lt =>
                     return RList'(1 => REnt'(BLo, Val - 1));

                  when N_Op_Ne =>
                     return RList'(REnt'(BLo, Val - 1), REnt'(Val + 1, BHi));

                  when others  =>
                     raise Program_Error;
               end case;

            --  Membership (IN)

            when N_In =>
               if not Is_Type_Ref (Left_Opnd (Exp)) then
                  Static.all := False;
                  return False_Range;
               end if;

               if Present (Right_Opnd (Exp)) then
                  return Membership_Entry (Right_Opnd (Exp), Static);
               else
                  return Membership_Entries
                           (First (Alternatives (Exp)), Static);
               end if;

            --  Negative membership (NOT IN)

            when N_Not_In =>
               if not Is_Type_Ref (Left_Opnd (Exp)) then
                  Static.all := False;
                  return False_Range;
               end if;

               if Present (Right_Opnd (Exp)) then
                  return not Membership_Entry (Right_Opnd (Exp), Static);
               else
                  return not Membership_Entries
                               (First (Alternatives (Exp)), Static);
               end if;

            --  Function call, may be call to static predicate

            when N_Function_Call =>
               if Is_Entity_Name (Name (Exp)) then
                  declare
                     Ent : constant Entity_Id := Entity (Name (Exp));
                  begin
                     if Is_Predicate_Function (Ent)
                          or else
                        Is_Predicate_Function_M (Ent)
                     then
                        return Stat_Pred (Etype (First_Formal (Ent)), Static);
                     end if;
                  end;
               end if;

               --  Other function call cases are non-static

               Static.all := False;
               return False_Range;

            --  Qualified expression, dig out the expression

            when N_Qualified_Expression =>
               return Get_RList (Expression (Exp), Static);

            when N_Case_Expression =>
               declare
                  Alt     : Node_Id;
                  Choices : List_Id;
                  Dep     : Node_Id;

               begin
                  if not Is_Entity_Name (Expression (Expr))
                    or else Etype (Expression (Expr)) /= Typ
                  then
                     Error_Msg_N
                       ("expression must denote subtype", Expression (Expr));
                     return False_Range;
                  end if;

                  --  Collect discrete choices in all True alternatives

                  Choices := New_List;
                  Alt := First (Alternatives (Exp));
                  while Present (Alt) loop
                     Dep := Expression (Alt);

                     if not Is_OK_Static_Expression (Dep) then
                        Static.all := False;
                        return False_Range;

                     elsif Is_True (Expr_Value (Dep)) then
                        Append_List_To (Choices,
                          New_Copy_List (Discrete_Choices (Alt)));
                     end if;

                     Next (Alt);
                  end loop;

                  return Membership_Entries (First (Choices), Static);
               end;

            --  Expression with actions: if no actions, dig out expression

            when N_Expression_With_Actions =>
               if Is_Empty_List (Actions (Exp)) then
                  return Get_RList (Expression (Exp), Static);
               else
                  Static.all := False;
                  return False_Range;
               end if;

            --  Xor operator

            when N_Op_Xor =>
               return (Get_RList (Left_Opnd (Exp), Static)
                        and not Get_RList (Right_Opnd (Exp), Static))
                 or   (Get_RList (Right_Opnd (Exp), Static)
                        and not Get_RList (Left_Opnd (Exp), Static));

            --  Any other node type is non-static

            when others =>
               Static.all := False;
               return False_Range;
         end case;
      end Get_RList;

      ------------
      -- Hi_Val --
      ------------

      function Hi_Val (N : Node_Id) return Uint is
      begin
         if Is_OK_Static_Expression (N) then
            return Expr_Value (N);
         else
            pragma Assert (Nkind (N) = N_Range);
            return Expr_Value (High_Bound (N));
         end if;
      end Hi_Val;

      --------------
      -- Is_False --
      --------------

      function Is_False (R : RList) return Boolean is
      begin
         return R'Length = 0;
      end Is_False;

      -------------
      -- Is_True --
      -------------

      function Is_True (R : RList) return Boolean is
      begin
         return R'Length = 1
           and then R (R'First).Lo = BLo
           and then R (R'First).Hi = BHi;
      end Is_True;

      -----------------
      -- Is_Type_Ref --
      -----------------

      function Is_Type_Ref (N : Node_Id) return Boolean is
      begin
         return Nkind (N) = N_Identifier
           and then Chars (N) = Nam
           and then Paren_Count (N) = 0;
      end Is_Type_Ref;

      ------------
      -- Lo_Val --
      ------------

      function Lo_Val (N : Node_Id) return Uint is
      begin
         if Is_OK_Static_Expression (N) then
            return Expr_Value (N);
         else
            pragma Assert (Nkind (N) = N_Range);
            return Expr_Value (Low_Bound (N));
         end if;
      end Lo_Val;

      ------------------------
      -- Membership_Entries --
      ------------------------

      function Membership_Entries
        (N : Node_Id; Static : access Boolean) return RList is
      begin
         if No (Next (N)) then
            return Membership_Entry (N, Static);
         else
            return Membership_Entry (N, Static)
              or Membership_Entries (Next (N), Static);
         end if;
      end Membership_Entries;

      ----------------------
      -- Membership_Entry --
      ----------------------

      function Membership_Entry
        (N : Node_Id; Static : access Boolean) return RList
      is
         Val : Uint;
         SLo : Uint;
         SHi : Uint;

      begin
         --  Range case

         if Nkind (N) = N_Range then
            if not Is_OK_Static_Expression (Low_Bound  (N))
                 or else
               not Is_OK_Static_Expression (High_Bound (N))
            then
               Static.all := False;
               return False_Range;
            else
               SLo := Expr_Value (Low_Bound  (N));
               SHi := Expr_Value (High_Bound (N));
               return RList'(1 => REnt'(SLo, SHi));
            end if;

         --  Others case

         elsif Nkind (N) = N_Others_Choice then
            declare
               Choices    : constant List_Id := Others_Discrete_Choices (N);
               Choice     : Node_Id;
               Range_List : RList (1 .. List_Length (Choices));

            begin
               Choice := First (Choices);

               for J in Range_List'Range loop
                  Range_List (J) := REnt'(Lo_Val (Choice), Hi_Val (Choice));
                  Next (Choice);
               end loop;

               return Range_List;
            end;

         --  Static expression case

         elsif Is_OK_Static_Expression (N) then
            Val := Expr_Value (N);
            return RList'(1 => REnt'(Val, Val));

         --  Identifier (other than static expression) case

         else pragma Assert (Nkind (N) in N_Expanded_Name | N_Identifier);

            --  Type case

            if Is_Type (Entity (N)) then

               --  If type has predicates, process them

               if Has_Predicates (Entity (N)) then
                  return Stat_Pred (Entity (N), Static);

               --  For static subtype without predicates, get range

               elsif Is_OK_Static_Subtype (Entity (N)) then
                  SLo := Expr_Value (Type_Low_Bound  (Entity (N)));
                  SHi := Expr_Value (Type_High_Bound (Entity (N)));
                  return RList'(1 => REnt'(SLo, SHi));

               --  Any other type makes us non-static

               else
                  Static.all := False;
                  return False_Range;
               end if;

            --  Any other kind of identifier in predicate (e.g. a non-static
            --  expression value) means this is not a static predicate.

            else
               Static.all := False;
               return False_Range;
            end if;
         end if;
      end Membership_Entry;

      ---------------
      -- Stat_Pred --
      ---------------

      function Stat_Pred
        (Typ    : Entity_Id;
         Static : access Boolean) return RList is
      begin
         --  Not static if type does not have static predicates

         if not Has_Static_Predicate (Typ) then
            Static.all := False;
            return False_Range;
         end if;

         --  Otherwise we convert the predicate list to a range list

         declare
            Spred  : constant List_Id := Static_Discrete_Predicate (Typ);
            Result : RList (1 .. List_Length (Spred));
            P      : Node_Id;

         begin
            P := First (Static_Discrete_Predicate (Typ));
            for J in Result'Range loop
               Result (J) := REnt'(Lo_Val (P), Hi_Val (P));
               Next (P);
            end loop;

            return Result;
         end;
      end Stat_Pred;

   --  Start of processing for Build_Discrete_Static_Predicate

   begin
      --  Establish bounds for the predicate

      if Compile_Time_Known_Value (Type_Low_Bound (Typ)) then
         TLo := Expr_Value (Type_Low_Bound (Typ));
      else
         TLo := BLo;
      end if;

      if Compile_Time_Known_Value (Type_High_Bound (Typ)) then
         THi := Expr_Value (Type_High_Bound (Typ));
      else
         THi := BHi;
      end if;

      --  Analyze the expression to see if it is a static predicate

      declare
         Static : aliased Boolean := True;
         Ranges : constant RList := Get_RList (Expr, Static'Access);
         --  Range list from expression if it is static

         Plist : List_Id;

      begin
         --  If non-static, return doing nothing

         if not Static then
            return;
         end if;

         --  Convert range list into a form for the static predicate. In the
         --  Ranges array, we just have raw ranges, these must be converted
         --  to properly typed and analyzed static expressions or range nodes.

         --  Note: here we limit ranges to the ranges of the subtype, so that
         --  a predicate is always false for values outside the subtype. That
         --  seems fine, such values are invalid anyway, and considering them
         --  to fail the predicate seems allowed and friendly, and furthermore
         --  simplifies processing for case statements and loops.

         Plist := New_List;

         for J in Ranges'Range loop
            declare
               Lo : Uint := Ranges (J).Lo;
               Hi : Uint := Ranges (J).Hi;

            begin
               --  Ignore completely out of range entry

               if Hi < TLo or else Lo > THi then
                  null;

               --  Otherwise process entry

               else
                  --  Adjust out of range value to subtype range

                  if Lo < TLo then
                     Lo := TLo;
                  end if;

                  if Hi > THi then
                     Hi := THi;
                  end if;

                  --  Convert range into required form

                  Append_To (Plist, Build_Range (Lo, Hi));
               end if;
            end;
         end loop;

         --  Processing was successful and all entries were static, so now we
         --  can store the result as the predicate list.

         Set_Static_Discrete_Predicate (Typ, Plist);

         --  Within a generic the predicate functions themselves need not
         --  be constructed.

         if Inside_A_Generic then
            return;
         end if;

         --  The processing for static predicates put the expression into
         --  canonical form as a series of ranges. It also eliminated
         --  duplicates and collapsed and combined ranges. We might as well
         --  replace the alternatives list of the right operand of the
         --  membership test with the static predicate list, which will
         --  usually be more efficient.

         declare
            New_Alts : constant List_Id := New_List;
            Old_Node : Node_Id;
            New_Node : Node_Id;

         begin
            Old_Node := First (Plist);
            while Present (Old_Node) loop
               New_Node := New_Copy (Old_Node);

               if Nkind (New_Node) = N_Range then
                  Set_Low_Bound  (New_Node, New_Copy (Low_Bound  (Old_Node)));
                  Set_High_Bound (New_Node, New_Copy (High_Bound (Old_Node)));
               end if;

               Append_To (New_Alts, New_Node);
               Next (Old_Node);
            end loop;

            --  If empty list, replace by False

            if Is_Empty_List (New_Alts) then
               Rewrite (Expr, New_Occurrence_Of (Standard_False, Loc));

               --  Else replace by set membership test

            else
               Rewrite (Expr,
                 Make_In (Loc,
                   Left_Opnd    => Make_Identifier (Loc, Nam),
                   Right_Opnd   => Empty,
                   Alternatives => New_Alts));

               --  Resolve new expression in function context

               Install_Formals (Predicate_Function (Typ));
               Push_Scope (Predicate_Function (Typ));
               Analyze_And_Resolve (Expr, Standard_Boolean);
               Pop_Scope;
            end if;
         end;
      end;
   end Build_Discrete_Static_Predicate;

   --------------------------------
   -- Build_Export_Import_Pragma --
   --------------------------------

   function Build_Export_Import_Pragma
     (Asp : Node_Id;
      Id  : Entity_Id) return Node_Id
   is
      Asp_Id : constant Aspect_Id  := Get_Aspect_Id (Asp);
      Expr   : constant Node_Id    := Expression (Asp);
      Loc    : constant Source_Ptr := Sloc (Asp);

      Args     : List_Id;
      Conv     : Node_Id;
      Conv_Arg : Node_Id;
      Dummy_1  : Node_Id;
      Dummy_2  : Node_Id;
      EN       : Node_Id;
      LN       : Node_Id;
      Prag     : Node_Id;

      Create_Pragma : Boolean := False;
      --  This flag is set when the aspect form is such that it warrants the
      --  creation of a corresponding pragma.

   begin
      if Present (Expr) then
         if Error_Posted (Expr) then
            null;

         elsif Is_True (Expr_Value (Expr)) then
            Create_Pragma := True;
         end if;

      --  Otherwise the aspect defaults to True

      else
         Create_Pragma := True;
      end if;

      --  Nothing to do when the expression is False or is erroneous

      if not Create_Pragma then
         return Empty;
      end if;

      --  Obtain all interfacing aspects that apply to the related entity

      Get_Interfacing_Aspects
        (Iface_Asp => Asp,
         Conv_Asp  => Conv,
         EN_Asp    => EN,
         Expo_Asp  => Dummy_1,
         Imp_Asp   => Dummy_2,
         LN_Asp    => LN);

      Args := New_List;

      --  Handle the convention argument

      if Present (Conv) then
         Conv_Arg := New_Copy_Tree (Expression (Conv));

      --  Assume convention "Ada' when aspect Convention is missing

      else
         Conv_Arg := Make_Identifier (Loc, Name_Ada);
      end if;

      Append_To (Args,
        Make_Pragma_Argument_Association (Loc,
          Chars      => Name_Convention,
          Expression => Conv_Arg));

      --  Handle the entity argument

      Append_To (Args,
        Make_Pragma_Argument_Association (Loc,
          Chars      => Name_Entity,
          Expression => New_Occurrence_Of (Id, Loc)));

      --  Handle the External_Name argument

      if Present (EN) then
         Append_To (Args,
           Make_Pragma_Argument_Association (Loc,
             Chars      => Name_External_Name,
             Expression => New_Copy_Tree (Expression (EN))));
      end if;

      --  Handle the Link_Name argument

      if Present (LN) then
         Append_To (Args,
           Make_Pragma_Argument_Association (Loc,
             Chars      => Name_Link_Name,
             Expression => New_Copy_Tree (Expression (LN))));
      end if;

      --  Generate:
      --    pragma Export/Import
      --      (Convention    => <Conv>/Ada,
      --       Entity        => <Id>,
      --      [External_Name => <EN>,]
      --      [Link_Name     => <LN>]);

      Prag :=
        Make_Pragma (Loc,
          Pragma_Identifier            =>
            Make_Identifier (Loc, Chars (Identifier (Asp))),
          Pragma_Argument_Associations => Args);

      --  Decorate the relevant aspect and the pragma

      Set_Aspect_Rep_Item (Asp, Prag);

      Set_Corresponding_Aspect      (Prag, Asp);
      Set_From_Aspect_Specification (Prag);
      Set_Parent                    (Prag, Asp);

      if Asp_Id = Aspect_Import and then Is_Subprogram (Id) then
         Set_Import_Pragma (Id, Prag);
      end if;

      return Prag;
   end Build_Export_Import_Pragma;

   -------------------------------
   -- Build_Predicate_Functions --
   -------------------------------

   --  The functions that are constructed here have the form:

   --    function typPredicate (Ixxx : typ) return Boolean is
   --    begin
   --       return
   --          typ1Predicate (typ1 (Ixxx))
   --          and then typ2Predicate (typ2 (Ixxx))
   --          and then ...
   --          and then exp1 and then exp2 and then ...;
   --    end typPredicate;

   --  Here exp1, and exp2 are expressions from Predicate pragmas. Note that
   --  this is the point at which these expressions get analyzed, providing the
   --  required delay, and typ1, typ2, are entities from which predicates are
   --  inherited. Note that we do NOT generate Check pragmas, that's because we
   --  use this function even if checks are off, e.g. for membership tests.

   --  Note that the inherited predicates are evaluated first, as required by
   --  AI12-0071-1.

   --  Note that Sem_Eval.Real_Or_String_Static_Predicate_Matches depends on
   --  the form of this return expression.

   --  If the expression has at least one Raise_Expression, then we also build
   --  the typPredicateM version of the function, in which any occurrence of a
   --  Raise_Expression is converted to "return False".

   --  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 Build_Predicate_Functions (Typ : Entity_Id; N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (Typ);

      Expr : Node_Id;
      --  This is the expression for the result of the function. It is
      --  is build by connecting the component predicates with AND THEN.

      Expr_M : Node_Id := Empty; -- init to avoid warning
      --  This is the corresponding return expression for the Predicate_M
      --  function. It differs in that raise expressions are marked for
      --  special expansion (see Process_REs).

      Object_Name : Name_Id;
      --  Name for argument of Predicate procedure. Note that we use the same
      --  name for both predicate functions. That way the reference within the
      --  predicate expression is the same in both functions.

      Object_Entity : Entity_Id;
      --  Entity for argument of Predicate procedure

      Object_Entity_M : Entity_Id;
      --  Entity for argument of separate Predicate procedure when exceptions
      --  are present in expression.

      FDecl : Node_Id;
      --  The function declaration

      SId : Entity_Id;
      --  Its entity

      Raise_Expression_Present : Boolean := False;
      --  Set True if Expr has at least one Raise_Expression

      procedure Add_Condition (Cond : Node_Id);
      --  Append Cond to Expr using "and then" (or just copy Cond to Expr if
      --  Expr is empty).

      procedure Add_Predicates;
      --  Appends expressions for any Predicate pragmas in the rep item chain
      --  Typ to Expr. Note that we look only at items for this exact entity.
      --  Inheritance of predicates for the parent type is done by calling the
      --  Predicate_Function of the parent type, using Add_Call above.

      procedure Add_Call (T : Entity_Id);
      --  Includes a call to the predicate function for type T in Expr if
      --  Predicate_Function (T) is non-empty.

      function Process_RE (N : Node_Id) return Traverse_Result;
      --  Used in Process REs, tests if node N is a raise expression, and if
      --  so, marks it to be converted to return False.

      procedure Process_REs is new Traverse_Proc (Process_RE);
      --  Marks any raise expressions in Expr_M to return False

      function Test_RE (N : Node_Id) return Traverse_Result;
      --  Used in Test_REs, tests one node for being a raise expression, and if
      --  so sets Raise_Expression_Present True.

      procedure Test_REs is new Traverse_Proc (Test_RE);
      --  Tests to see if Expr contains any raise expressions

      --------------
      -- Add_Call --
      --------------

      procedure Add_Call (T : Entity_Id) is
         Exp : Node_Id;

      begin
         if Present (Predicate_Function (T)) then
            pragma Assert (Has_Predicates (Typ));

            --  Build the call to the predicate function of T. The type may be
            --  derived, so use an unchecked conversion for the actual.

            Exp :=
              Make_Predicate_Call
                (Typ  => T,
                 Expr =>
                   Unchecked_Convert_To (T,
                     Make_Identifier (Loc, Object_Name)));

            --  "and"-in the call to evolving expression

            Add_Condition (Exp);

            --  Output info message on inheritance if required. Note we do not
            --  give this information for generic actual types, since it is
            --  unwelcome noise in that case in instantiations. We also
            --  generally suppress the message in instantiations, and also
            --  if it involves internal names.

            if Opt.List_Inherited_Aspects
              and then not Is_Generic_Actual_Type (Typ)
              and then Instantiation_Depth (Sloc (Typ)) = 0
              and then not Is_Internal_Name (Chars (T))
              and then not Is_Internal_Name (Chars (Typ))
            then
               Error_Msg_Sloc := Sloc (Predicate_Function (T));
               Error_Msg_Node_2 := T;
               Error_Msg_N ("info: & inherits predicate from & #?.l?", Typ);
            end if;
         end if;
      end Add_Call;

      -------------------
      -- Add_Condition --
      -------------------

      procedure Add_Condition (Cond : Node_Id) is
      begin
         --  This is the first predicate expression

         if No (Expr) then
            Expr := Cond;

         --  Otherwise concatenate to the existing predicate expressions by
         --  using "and then".

         else
            Expr :=
              Make_And_Then (Loc,
                Left_Opnd  => Relocate_Node (Expr),
                Right_Opnd => Cond);
         end if;
      end Add_Condition;

      --------------------
      -- Add_Predicates --
      --------------------

      procedure Add_Predicates is
         procedure Add_Predicate (Prag : Node_Id);
         --  Concatenate the expression of predicate pragma Prag to Expr by
         --  using a short circuit "and then" operator.

         -------------------
         -- Add_Predicate --
         -------------------

         procedure Add_Predicate (Prag : Node_Id) is
            procedure Replace_Type_Reference (N : Node_Id);
            --  Replace a single occurrence N of the subtype name with a
            --  reference to the formal of the predicate function. N can be an
            --  identifier referencing the subtype, or a selected component,
            --  representing an appropriately qualified occurrence of the
            --  subtype name.

            procedure Replace_Type_References is
              new Replace_Type_References_Generic (Replace_Type_Reference);
            --  Traverse an expression changing every occurrence of an
            --  identifier whose name matches the name of the subtype with a
            --  reference to the formal parameter of the predicate function.

            ----------------------------
            -- Replace_Type_Reference --
            ----------------------------

            procedure Replace_Type_Reference (N : Node_Id) is
            begin
               Rewrite (N, Make_Identifier (Sloc (N), Object_Name));
               --  Use the Sloc of the usage name, not the defining name

               Set_Etype (N, Typ);
               Set_Entity (N, Object_Entity);
            end Replace_Type_Reference;

            --  Local variables

            Asp  : constant Node_Id := Corresponding_Aspect (Prag);
            Arg1 : Node_Id;
            Arg2 : Node_Id;

         --  Start of processing for Add_Predicate

         begin
            --  Mark corresponding SCO as enabled

            Set_SCO_Pragma_Enabled (Sloc (Prag));

            --  Extract the arguments of the pragma. The expression itself
            --  is copied for use in the predicate function, to preserve the
            --  original version for ASIS use.
            --  Is this still needed???

            Arg1 := First (Pragma_Argument_Associations (Prag));
            Arg2 := Next (Arg1);

            Arg1 := Get_Pragma_Arg (Arg1);
            Arg2 := New_Copy_Tree (Get_Pragma_Arg (Arg2));

            --  When the predicate pragma applies to the current type or its
            --  full view, replace all occurrences of the subtype name with
            --  references to the formal parameter of the predicate function.

            if Entity (Arg1) = Typ
              or else Full_View (Entity (Arg1)) = Typ
            then
               Replace_Type_References (Arg2, Typ);

               --  If the predicate pragma comes from an aspect, replace the
               --  saved expression because we need the subtype references
               --  replaced for the calls to Preanalyze_Spec_Expression in
               --  Check_Aspect_At_xxx routines.

               if Present (Asp) then
                  Set_Entity (Identifier (Asp), New_Copy_Tree (Arg2));
               end if;

               --  "and"-in the Arg2 condition to evolving expression

               Add_Condition (Relocate_Node (Arg2));
            end if;
         end Add_Predicate;

         --  Local variables

         Ritem : Node_Id;

      --  Start of processing for Add_Predicates

      begin
         Ritem := First_Rep_Item (Typ);

         --  If the type is private, check whether full view has inherited
         --  predicates.

         if Is_Private_Type (Typ)
           and then No (Ritem)
           and then Present (Full_View (Typ))
         then
            Ritem := First_Rep_Item (Full_View (Typ));
         end if;

         while Present (Ritem) loop
            if Nkind (Ritem) = N_Pragma
              and then Pragma_Name (Ritem) = Name_Predicate
            then
               Add_Predicate (Ritem);

            --  If the type is declared in an inner package it may be frozen
            --  outside of the package, and the generated pragma has not been
            --  analyzed yet, so capture the expression for the predicate
            --  function at this point.

            elsif Nkind (Ritem) = N_Aspect_Specification
              and then Present (Aspect_Rep_Item (Ritem))
              and then Scope_Depth (Scope (Typ)) > Scope_Depth (Current_Scope)
            then
               declare
                  Prag : constant Node_Id := Aspect_Rep_Item (Ritem);

               begin
                  if Nkind (Prag) = N_Pragma
                    and then Pragma_Name (Prag) = Name_Predicate
                  then
                     Add_Predicate (Prag);
                  end if;
               end;
            end if;

            Next_Rep_Item (Ritem);
         end loop;
      end Add_Predicates;

      ----------------
      -- Process_RE --
      ----------------

      function Process_RE (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Raise_Expression then
            Set_Convert_To_Return_False (N);
            return Skip;
         else
            return OK;
         end if;
      end Process_RE;

      -------------
      -- Test_RE --
      -------------

      function Test_RE (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Raise_Expression then
            Raise_Expression_Present := True;
            return Abandon;
         else
            return OK;
         end if;
      end Test_RE;

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

   --  Start of processing for Build_Predicate_Functions

   begin
      --  Return if already built, if type does not have predicates,
      --  or if type is a constructed subtype that will inherit a
      --  predicate function from its ancestor. In a generic context
      --  the predicated parent may not have a predicate function yet
      --  but we don't want to build a new one for the subtype. This can
      --  happen in an instance body which is nested within a generic
      --  unit, in which case Within_A_Generic may be false, SId is
      --  Empty, but uses of Typ will receive a predicate check in a
      --  context where expansion and tests are enabled.

      SId := Predicate_Function (Typ);
      if not Has_Predicates (Typ)
        or else (Present (SId) and then Has_Completion (SId))
        or else
          (Is_Itype (Typ)
           and then not Comes_From_Source (Typ)
           and then Ekind (Typ) in E_Array_Subtype
                                 | E_Record_Subtype
                                 | E_Record_Subtype_With_Private
           and then Present (Predicated_Parent (Typ)))
      then
         return;

      --  Do not generate predicate bodies within a generic unit. The
      --  expressions have been analyzed already, and the bodies play no role
      --  if not within an executable unit. However, if a static predicate is
      --  present it must be processed for legality checks such as case
      --  coverage in an expression.

      elsif Inside_A_Generic
        and then not Has_Static_Predicate_Aspect (Typ)
      then
         return;
      end if;

      --  The related type may be subject to pragma Ghost. Set the mode now to
      --  ensure that the predicate functions are properly marked as Ghost.

      Set_Ghost_Mode (Typ);

      --  Prepare to construct predicate expression

      Expr := Empty;

      if Present (SId) then
         FDecl := Unit_Declaration_Node (SId);

      else
         FDecl := Build_Predicate_Function_Declaration (Typ);
         SId   := Defining_Entity (FDecl);
      end if;

      --  Recover name of formal parameter of function that replaces references
      --  to the type in predicate expressions.

      Object_Entity :=
         Defining_Identifier
           (First (Parameter_Specifications (Specification (FDecl))));

      Object_Name     := Chars (Object_Entity);
      Object_Entity_M := Make_Defining_Identifier (Loc, Chars => Object_Name);

      --  Add predicates for ancestor if present. These must come before the
      --  ones for the current type, as required by AI12-0071-1.

      --  Looks like predicates aren't added for case of inheriting from
      --  multiple progenitors???

      declare
         Atyp : Entity_Id;
      begin
         Atyp := Nearest_Ancestor (Typ);

         --  The type may be private but the full view may inherit predicates

         if No (Atyp) and then Is_Private_Type (Typ) then
            Atyp := Nearest_Ancestor (Full_View (Typ));
         end if;

         if Present (Atyp) then
            Add_Call (Atyp);
         end if;
      end;

      --  Add Predicates for the current type

      Add_Predicates;

      --  Case where predicates are present

      if Present (Expr) then

         --  Test for raise expression present

         Test_REs (Expr);

         --  If raise expression is present, capture a copy of Expr for use
         --  in building the predicateM function version later on. For this
         --  copy we replace references to Object_Entity by Object_Entity_M.

         if Raise_Expression_Present then
            declare
               function Reset_Loop_Variable
                 (N : Node_Id) return Traverse_Result;

               procedure Reset_Loop_Variables is
                 new Traverse_Proc (Reset_Loop_Variable);

               ------------------------
               -- Reset_Loop_Variable --
               ------------------------

               function Reset_Loop_Variable
                 (N : Node_Id) return Traverse_Result
               is
               begin
                  if Nkind (N) = N_Iterator_Specification then
                     Set_Defining_Identifier (N,
                       Make_Defining_Identifier
                         (Sloc (N), Chars (Defining_Identifier (N))));
                  end if;

                  return OK;
               end Reset_Loop_Variable;

               --  Local variables

               Map : constant Elist_Id := New_Elmt_List;

            begin
               Append_Elmt (Object_Entity, Map);
               Append_Elmt (Object_Entity_M, Map);
               Expr_M := New_Copy_Tree (Expr, Map => Map);

               --  The unanalyzed expression will be copied and appear in
               --  both functions. Normally expressions do not declare new
               --  entities, but quantified expressions do, so we need to
               --  create new entities for their bound variables, to prevent
               --  multiple definitions in gigi.

               Reset_Loop_Variables (Expr_M);
            end;
         end if;

         --  Build the main predicate function

         declare
            SIdB : constant Entity_Id :=
              Make_Defining_Identifier (Loc,
                Chars => New_External_Name (Chars (Typ), "Predicate"));
            --  The entity for the function body

            Spec  : Node_Id;
            FBody : Node_Id;

         begin
            Mutate_Ekind (SIdB, E_Function);
            Set_Is_Predicate_Function (SIdB);

            --  Build function body

            Spec :=
              Make_Function_Specification (Loc,
                Defining_Unit_Name       => SIdB,
                Parameter_Specifications => New_List (
                  Make_Parameter_Specification (Loc,
                    Defining_Identifier =>
                      Make_Defining_Identifier (Loc, Object_Name),
                    Parameter_Type =>
                      New_Occurrence_Of (Typ, Loc))),
                Result_Definition        =>
                  New_Occurrence_Of (Standard_Boolean, Loc));

            FBody :=
              Make_Subprogram_Body (Loc,
                Specification              => Spec,
                Declarations               => Empty_List,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => New_List (
                      Make_Simple_Return_Statement (Loc,
                        Expression => Expr))));

            --  The declaration has been analyzed when created, and placed
            --  after type declaration. Insert body itself after freeze node,
            --  unless subprogram declaration is already there, in which case
            --  body better be placed afterwards.

            if FDecl = Next (N) then
               Insert_After_And_Analyze (FDecl, FBody);
            else
               Insert_After_And_Analyze (N, FBody);
            end if;

            --  The defining identifier of a quantified expression carries the
            --  scope in which the type appears, but when unnesting we need
            --  to indicate that its proper scope is the constructed predicate
            --  function. The quantified expressions have been converted into
            --  loops during analysis and expansion.

            declare
               function Reset_Quantified_Variable_Scope
                 (N : Node_Id) return Traverse_Result;

               procedure Reset_Quantified_Variables_Scope is
                 new Traverse_Proc (Reset_Quantified_Variable_Scope);

               -------------------------------------
               -- Reset_Quantified_Variable_Scope --
               -------------------------------------

               function Reset_Quantified_Variable_Scope
                 (N : Node_Id) return Traverse_Result is
               begin
                  if Nkind (N) in N_Iterator_Specification
                                | N_Loop_Parameter_Specification
                  then
                     Set_Scope (Defining_Identifier (N),
                       Predicate_Function (Typ));
                  end if;

                  return OK;
               end Reset_Quantified_Variable_Scope;

            begin
               if Unnest_Subprogram_Mode then
                  Reset_Quantified_Variables_Scope (Expr);
               end if;
            end;

            --  Within a generic unit, prevent a double analysis of the body
            --  which will not be marked analyzed yet. This will happen when
            --  the freeze node is created during the preanalysis of an
            --  expression function.

            if Inside_A_Generic then
               Set_Analyzed (FBody);
            end if;

            --  Static predicate functions are always side-effect free, and
            --  in most cases dynamic predicate functions are as well. Mark
            --  them as such whenever possible, so redundant predicate checks
            --  can be optimized. If there is a variable reference within the
            --  expression, the function is not pure.

            if Expander_Active then
               Set_Is_Pure (SId,
                 Side_Effect_Free (Expr, Variable_Ref => True));
               Set_Is_Inlined (SId);
            end if;
         end;

         --  Test for raise expressions present and if so build M version

         if Raise_Expression_Present then
            declare
               SId : constant Entity_Id :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Chars (Typ), "PredicateM"));
               --  The entity for the function spec

               SIdB : constant Entity_Id :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Chars (Typ), "PredicateM"));
               --  The entity for the function body

               Spec  : Node_Id;
               FBody : Node_Id;
               FDecl : Node_Id;
               BTemp : Entity_Id;

               CRec_Typ : Entity_Id;
               --  The corresponding record type of Full_Typ

               Full_Typ : Entity_Id;
               --  The full view of Typ

               Priv_Typ : Entity_Id;
               --  The partial view of Typ

               UFull_Typ : Entity_Id;
               --  The underlying full view of Full_Typ

            begin
               --  Mark any raise expressions for special expansion

               Process_REs (Expr_M);

               --  Build function declaration

               Mutate_Ekind (SId, E_Function);
               Set_Is_Predicate_Function_M (SId);
               Set_Predicate_Function_M (Typ, SId);

               --  Obtain all views of the input type

               Get_Views (Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);

               --  Associate the predicate function with all views

               Propagate_Predicate_Attributes (Priv_Typ,  From_Typ => Typ);
               Propagate_Predicate_Attributes (Full_Typ,  From_Typ => Typ);
               Propagate_Predicate_Attributes (UFull_Typ, From_Typ => Typ);
               Propagate_Predicate_Attributes (CRec_Typ,  From_Typ => Typ);

               Spec :=
                 Make_Function_Specification (Loc,
                   Defining_Unit_Name       => SId,
                   Parameter_Specifications => New_List (
                     Make_Parameter_Specification (Loc,
                       Defining_Identifier => Object_Entity_M,
                       Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
                   Result_Definition        =>
                     New_Occurrence_Of (Standard_Boolean, Loc));

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

               --  Build function body

               Spec :=
                 Make_Function_Specification (Loc,
                   Defining_Unit_Name       => SIdB,
                   Parameter_Specifications => New_List (
                     Make_Parameter_Specification (Loc,
                       Defining_Identifier =>
                         Make_Defining_Identifier (Loc, Object_Name),
                       Parameter_Type =>
                         New_Occurrence_Of (Typ, Loc))),
                   Result_Definition        =>
                     New_Occurrence_Of (Standard_Boolean, Loc));

               --  Build the body, we declare the boolean expression before
               --  doing the return, because we are not really confident of
               --  what happens if a return appears within a return.

               BTemp :=
                 Make_Temporary (Loc, 'B');

               FBody :=
                 Make_Subprogram_Body (Loc,
                   Specification              => Spec,

                   Declarations               => New_List (
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => BTemp,
                       Constant_Present    => True,
                         Object_Definition =>
                           New_Occurrence_Of (Standard_Boolean, Loc),
                         Expression        => Expr_M)),

                   Handled_Statement_Sequence =>
                     Make_Handled_Sequence_Of_Statements (Loc,
                       Statements => New_List (
                         Make_Simple_Return_Statement (Loc,
                           Expression => New_Occurrence_Of (BTemp, Loc)))));

               --  Insert declaration before freeze node and body after

               Insert_Before_And_Analyze (N, FDecl);
               Insert_After_And_Analyze  (N, FBody);

               --  Should quantified expressions be handled here as well ???
            end;
         end if;

         --  See if we have a static predicate. Note that the answer may be
         --  yes even if we have an explicit Dynamic_Predicate present.

         declare
            PS : Boolean;
            EN : Node_Id;

         begin
            if not Is_Scalar_Type (Typ) and then not Is_String_Type (Typ) then
               PS := False;
            else
               PS := Is_Predicate_Static (Expr, Object_Name);
            end if;

            --  Case where we have a predicate-static aspect

            if PS then

               --  We don't set Has_Static_Predicate_Aspect, since we can have
               --  any of the three cases (Predicate, Dynamic_Predicate, or
               --  Static_Predicate) generating a predicate with an expression
               --  that is predicate-static. We just indicate that we have a
               --  predicate that can be treated as static.

               Set_Has_Static_Predicate (Typ);

               --  For discrete subtype, build the static predicate list

               if Is_Discrete_Type (Typ) then
                  Build_Discrete_Static_Predicate (Typ, Expr, Object_Name);

                  --  If we don't get a static predicate list, it means that we
                  --  have a case where this is not possible, most typically in
                  --  the case where we inherit a dynamic predicate. We do not
                  --  consider this an error, we just leave the predicate as
                  --  dynamic. But if we do succeed in building the list, then
                  --  we mark the predicate as static.

                  if No (Static_Discrete_Predicate (Typ)) then
                     Set_Has_Static_Predicate (Typ, False);
                  end if;

               --  For real or string subtype, save predicate expression

               elsif Is_Real_Type (Typ) or else Is_String_Type (Typ) then
                  Set_Static_Real_Or_String_Predicate (Typ, Expr);
               end if;

            --  Case of dynamic predicate (expression is not predicate-static)

            else
               --  Again, we don't set Has_Dynamic_Predicate_Aspect, since that
               --  is only set if we have an explicit Dynamic_Predicate aspect
               --  given. Here we may simply have a Predicate aspect where the
               --  expression happens not to be predicate-static.

               --  Emit an error when the predicate is categorized as static
               --  but its expression is not predicate-static.

               --  First a little fiddling to get a nice location for the
               --  message. If the expression is of the form (A and then B),
               --  where A is an inherited predicate, then use the right
               --  operand for the Sloc. This avoids getting confused by a call
               --  to an inherited predicate with a less convenient source
               --  location.

               EN := Expr;
               while Nkind (EN) = N_And_Then
                 and then Nkind (Left_Opnd (EN)) = N_Function_Call
                 and then Is_Predicate_Function
                            (Entity (Name (Left_Opnd (EN))))
               loop
                  EN := Right_Opnd (EN);
               end loop;

               --  Now post appropriate message

               if Has_Static_Predicate_Aspect (Typ) then
                  if Is_Scalar_Type (Typ) or else Is_String_Type (Typ) then
                     Error_Msg_F
                       ("expression is not predicate-static (RM 3.2.4(16-22))",
                        EN);
                  else
                     Error_Msg_F
                       ("static predicate requires scalar or string type", EN);
                  end if;
               end if;
            end if;
         end;
      end if;

      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Build_Predicate_Functions;

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

   function Build_Predicate_Function_Declaration
     (Typ : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Typ);

      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

      Func_Decl : Node_Id;
      Func_Id   : Entity_Id;
      Spec      : Node_Id;

      CRec_Typ : Entity_Id;
      --  The corresponding record type of Full_Typ

      Full_Typ : Entity_Id;
      --  The full view of Typ

      Priv_Typ : Entity_Id;
      --  The partial view of Typ

      UFull_Typ : Entity_Id;
      --  The underlying full view of Full_Typ

   begin
      --  The related type may be subject to pragma Ghost. Set the mode now to
      --  ensure that the predicate functions are properly marked as Ghost.

      Set_Ghost_Mode (Typ);

      Func_Id :=
        Make_Defining_Identifier (Loc,
          Chars => New_External_Name (Chars (Typ), "Predicate"));

      Mutate_Ekind (Func_Id, E_Function);
      Set_Etype (Func_Id, Standard_Boolean);
      Set_Is_Internal (Func_Id);
      Set_Is_Predicate_Function (Func_Id);
      Set_Predicate_Function (Typ, Func_Id);

      --  The predicate function requires debug info when the predicates are
      --  subject to Source Coverage Obligations.

      if Opt.Generate_SCO then
         Set_Debug_Info_Needed (Func_Id);
      end if;

      --  Obtain all views of the input type

      Get_Views (Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);

      --  Associate the predicate function and various flags with all views

      Propagate_Predicate_Attributes (Priv_Typ,  From_Typ => Typ);
      Propagate_Predicate_Attributes (Full_Typ,  From_Typ => Typ);
      Propagate_Predicate_Attributes (UFull_Typ, From_Typ => Typ);
      Propagate_Predicate_Attributes (CRec_Typ,  From_Typ => Typ);

      Spec :=
        Make_Function_Specification (Loc,
          Defining_Unit_Name       => Func_Id,
          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier => Make_Temporary (Loc, 'I'),
              Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
          Result_Definition        =>
            New_Occurrence_Of (Standard_Boolean, Loc));

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

      Insert_After (Parent (Typ), Func_Decl);
      Analyze (Func_Decl);

      Restore_Ghost_Region (Saved_GM, Saved_IGR);

      return Func_Decl;
   end Build_Predicate_Function_Declaration;

   -----------------------------------------
   -- Check_Aspect_At_End_Of_Declarations --
   -----------------------------------------

   procedure Check_Aspect_At_End_Of_Declarations (ASN : Node_Id) is
      Ent   : constant Entity_Id := Entity     (ASN);
      Ident : constant Node_Id   := Identifier (ASN);
      A_Id  : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));

      End_Decl_Expr : constant Node_Id := Entity (Ident);
      --  Expression to be analyzed at end of declarations

      Freeze_Expr : constant Node_Id := Expression (ASN);
      --  Expression from call to Check_Aspect_At_Freeze_Point.

      T : constant Entity_Id :=
            (if Present (Freeze_Expr) and (A_Id /= Aspect_Stable_Properties)
             then Etype (Original_Node (Freeze_Expr))
             else Empty);
      --  Type required for preanalyze call. We use the original expression to
      --  get the proper type, to prevent cascaded errors when the expression
      --  is constant-folded. For Stable_Properties, the aspect value is
      --  not semantically an expression (although it is syntactically);
      --  in particular, it has no type.

      Err : Boolean;
      --  Set True if error

      --  On entry to this procedure, Entity (Ident) contains a copy of the
      --  original expression from the aspect, saved for this purpose, and
      --  but Expression (Ident) is a preanalyzed copy of the expression,
      --  preanalyzed just after the freeze point.

      procedure Check_Overloaded_Name;
      --  For aspects whose expression is simply a name, this routine checks if
      --  the name is overloaded or not. If so, it verifies there is an
      --  interpretation that matches the entity obtained at the freeze point,
      --  otherwise the compiler complains.

      ---------------------------
      -- Check_Overloaded_Name --
      ---------------------------

      procedure Check_Overloaded_Name is
      begin
         if not Is_Overloaded (End_Decl_Expr) then
            Err := not Is_Entity_Name (End_Decl_Expr)
                     or else Entity (End_Decl_Expr) /= Entity (Freeze_Expr);

         else
            Err := True;

            declare
               Index : Interp_Index;
               It    : Interp;

            begin
               Get_First_Interp (End_Decl_Expr, Index, It);
               while Present (It.Typ) loop
                  if It.Nam = Entity (Freeze_Expr) then
                     Err := False;
                     exit;
                  end if;

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

   --  Start of processing for Check_Aspect_At_End_Of_Declarations

   begin
      --  In an instance we do not perform the consistency check between freeze
      --  point and end of declarations, because it was done already in the
      --  analysis of the generic. Furthermore, the delayed analysis of an
      --  aspect of the instance may produce spurious errors when the generic
      --  is a child unit that references entities in the parent (which might
      --  not be in scope at the freeze point of the instance).

      if In_Instance then
         return;

      --  The enclosing scope may have been rewritten during expansion (.e.g. a
      --  task body is rewritten as a procedure) after this conformance check
      --  has been performed, so do not perform it again (it may not easily be
      --  done if full visibility of local entities is not available).

      elsif not Comes_From_Source (Current_Scope) then
         return;

      --  Case of aspects Dimension, Dimension_System and Synchronization

      elsif A_Id = Aspect_Synchronization then
         return;

      --  Case of stream attributes and Put_Image, just have to compare
      --  entities. However, the expression is just a possibly-overloaded
      --  name, so we need to verify that one of these interpretations is
      --  the one available at at the freeze point.

      elsif A_Id in Aspect_Input
                  | Aspect_Output
                  | Aspect_Read
                  | Aspect_Write
                  | Aspect_Put_Image
      then
         Analyze (End_Decl_Expr);
         Check_Overloaded_Name;

      elsif A_Id in Aspect_Variable_Indexing
                  | Aspect_Constant_Indexing
                  | Aspect_Default_Iterator
                  | Aspect_Iterator_Element
                  | Aspect_Integer_Literal
                  | Aspect_Real_Literal
                  | Aspect_String_Literal
      then
         --  Make type unfrozen before analysis, to prevent spurious errors
         --  about late attributes.

         Set_Is_Frozen (Ent, False);
         Analyze (End_Decl_Expr);
         Set_Is_Frozen (Ent, True);

         --  If the end of declarations comes before any other freeze point,
         --  the Freeze_Expr is not analyzed: no check needed.

         if Analyzed (Freeze_Expr) and then not In_Instance then
            Check_Overloaded_Name;
         else
            Err := False;
         end if;

      --  All other cases

      else
         --  In a generic context freeze nodes are not always generated, so
         --  analyze the expression now. If the aspect is for a type, we must
         --  also make its potential components accessible.

         if not Analyzed (Freeze_Expr) and then Inside_A_Generic then
            if A_Id in Aspect_Dynamic_Predicate | Aspect_Predicate |
                       Aspect_Static_Predicate
            then
               Push_Type (Ent);
               Preanalyze_Spec_Expression (Freeze_Expr, Standard_Boolean);
               Pop_Type (Ent);

            elsif A_Id = Aspect_Priority then
               Push_Type (Ent);
               Preanalyze_Spec_Expression (Freeze_Expr, Any_Integer);
               Pop_Type (Ent);

            else
               Preanalyze (Freeze_Expr);
            end if;
         end if;

         --  Indicate that the expression comes from an aspect specification,
         --  which is used in subsequent analysis even if expansion is off.

         if Present (End_Decl_Expr) then
            Set_Parent (End_Decl_Expr, ASN);
         end if;

         --  In a generic context the original aspect expressions have not
         --  been preanalyzed, so do it now. There are no conformance checks
         --  to perform in this case. As before, we have to make components
         --  visible for aspects that may reference them.

         if Present (Freeze_Expr) and then No (T) then
            if A_Id in Aspect_Dynamic_Predicate
                     | Aspect_Predicate
                     | Aspect_Priority
                     | Aspect_Static_Predicate
            then
               Push_Type (Ent);
               Check_Aspect_At_Freeze_Point (ASN);
               Pop_Type (Ent);

            else
               Check_Aspect_At_Freeze_Point (ASN);
            end if;
            return;

         --  The default values attributes may be defined in the private part,
         --  and the analysis of the expression may take place when only the
         --  partial view is visible. The expression must be scalar, so use
         --  the full view to resolve.

         elsif A_Id in Aspect_Default_Component_Value | Aspect_Default_Value
            and then Is_Private_Type (T)
         then
            Preanalyze_Spec_Expression (End_Decl_Expr, Full_View (T));

         --  The following aspect expressions may contain references to
         --  components and discriminants of the type.

         elsif A_Id in Aspect_CPU
                     | Aspect_Dynamic_Predicate
                     | Aspect_Predicate
                     | Aspect_Priority
                     | Aspect_Static_Predicate
         then
            Push_Type (Ent);
            Preanalyze_Spec_Expression (End_Decl_Expr, T);
            Pop_Type (Ent);

         elsif A_Id = Aspect_Predicate_Failure then
            Preanalyze_Spec_Expression (End_Decl_Expr, Standard_String);
         elsif Present (End_Decl_Expr) then
            Preanalyze_Spec_Expression (End_Decl_Expr, T);
         end if;

         Err :=
           not Fully_Conformant_Expressions
                 (End_Decl_Expr, Freeze_Expr, Report => True);
      end if;

      --  Output error message if error. Force error on aspect specification
      --  even if there is an error on the expression itself.

      if Err then
         Error_Msg_NE
           ("!visibility of aspect for& changes after freeze point",
            ASN, Ent);
         Error_Msg_NE
           ("info: & is frozen here, (RM 13.1.1 (13/3))??",
            Freeze_Node (Ent), Ent);
      end if;
   end Check_Aspect_At_End_Of_Declarations;

   ----------------------------------
   -- Check_Aspect_At_Freeze_Point --
   ----------------------------------

   procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id) is
      Ident : constant Node_Id := Identifier (ASN);
      --  Identifier (use Entity field to save expression)

      Expr : constant Node_Id := Expression (ASN);
      --  For cases where using Entity (Identifier) doesn't work

      A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));

      T : Entity_Id := Empty;
      --  Type required for preanalyze call

   begin
      --  On entry to this procedure, Entity (Ident) contains a copy of the
      --  original expression from the aspect, saved for this purpose.

      --  On exit from this procedure Entity (Ident) is unchanged, still
      --  containing that copy, but Expression (Ident) is a preanalyzed copy
      --  of the expression, preanalyzed just after the freeze point.

      --  Make a copy of the expression to be preanalyzed

      Set_Expression (ASN, New_Copy_Tree (Entity (Ident)));

      --  Find type for preanalyze call

      case A_Id is

         --  No_Aspect should be impossible

         when No_Aspect =>
            raise Program_Error;

         --  Aspects taking an optional boolean argument

         when Boolean_Aspects
            | Library_Unit_Aspects
         =>
            T := Standard_Boolean;

         --  Aspects corresponding to attribute definition clauses

         when Aspect_Address =>
            T := RTE (RE_Address);

         when Aspect_Attach_Handler =>
            T := RTE (RE_Interrupt_ID);

         when Aspect_Bit_Order
            | Aspect_Scalar_Storage_Order
         =>
            T := RTE (RE_Bit_Order);

         when Aspect_Convention =>
            return;

         when Aspect_CPU =>
            T := RTE (RE_CPU_Range);

         --  Default_Component_Value is resolved with the component type

         when Aspect_Default_Component_Value =>
            T := Component_Type (Entity (ASN));

         when Aspect_Default_Storage_Pool =>
            T := Class_Wide_Type (RTE (RE_Root_Storage_Pool));

         --  Default_Value is resolved with the type entity in question

         when Aspect_Default_Value =>
            T := Entity (ASN);

         when Aspect_Dispatching_Domain =>
            T := RTE (RE_Dispatching_Domain);

         when Aspect_External_Tag =>
            T := Standard_String;

         when Aspect_External_Name =>
            T := Standard_String;

         when Aspect_Link_Name =>
            T := Standard_String;

         when Aspect_Interrupt_Priority
            | Aspect_Priority
         =>
            T := Standard_Integer;

         when Aspect_Relative_Deadline =>
            T := RTE (RE_Time_Span);

         when Aspect_Secondary_Stack_Size =>
            T := Standard_Integer;

         when Aspect_Small =>

            --  Note that the expression can be of any real type (not just a
            --  real universal literal) as long as it is a static constant.

            T := Any_Real;

         --  For a simple storage pool, we have to retrieve the type of the
         --  pool object associated with the aspect's corresponding attribute
         --  definition clause.

         when Aspect_Simple_Storage_Pool =>
            T := Etype (Expression (Aspect_Rep_Item (ASN)));

         when Aspect_Storage_Pool =>
            T := Class_Wide_Type (RTE (RE_Root_Storage_Pool));

         when Aspect_Alignment
            | Aspect_Component_Size
            | Aspect_Machine_Radix
            | Aspect_Object_Size
            | Aspect_Size
            | Aspect_Storage_Size
            | Aspect_Stream_Size
            | Aspect_Value_Size
         =>
            T := Any_Integer;

         when Aspect_Linker_Section =>
            T := Standard_String;

         when Aspect_Synchronization =>
            return;

         --  Special case, the expression of these aspects is just an entity
         --  that does not need any resolution, so just analyze.

         when Aspect_Input
            | Aspect_Output
            | Aspect_Put_Image
            | Aspect_Read
            | Aspect_Warnings
            | Aspect_Write
         =>
            Analyze (Expression (ASN));
            return;

         --  Same for Iterator aspects, where the expression is a function
         --  name. Legality rules are checked separately.

         when Aspect_Constant_Indexing
            | Aspect_Default_Iterator
            | Aspect_Iterator_Element
            | Aspect_Variable_Indexing
         =>
            Analyze (Expression (ASN));
            return;

         --  Same for Literal aspects, where the expression is a function
         --  name. Legality rules are checked separately. Use Expr to avoid
         --  losing track of the previous resolution of Expression.

         when Aspect_Integer_Literal
            | Aspect_Real_Literal
            | Aspect_String_Literal
         =>
            Set_Entity (Expression (ASN), Entity (Expr));
            Set_Etype (Expression (ASN), Etype (Expr));
            Set_Is_Overloaded (Expression (ASN), False);
            Analyze (Expression (ASN));
            return;

         --  Ditto for Iterable, legality checks in Validate_Iterable_Aspect.

         when Aspect_Iterable =>
            T := Entity (ASN);

            declare
               Cursor : constant Entity_Id := Get_Cursor_Type (ASN, T);
               Assoc  : Node_Id;
               Expr   : Node_Id;

            begin
               if Cursor = Any_Type then
                  return;
               end if;

               Assoc := First (Component_Associations (Expression (ASN)));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Analyze (Expr);

                  if not Error_Posted (Expr) then
                     Resolve_Iterable_Operation
                       (Expr, Cursor, T, Chars (First (Choices (Assoc))));
                  end if;

                  Next (Assoc);
               end loop;
            end;

            return;

         when Aspect_Aggregate =>
            Resolve_Aspect_Aggregate (Entity (ASN), Expression (ASN));
            return;

         when Aspect_Stable_Properties =>
            Resolve_Aspect_Stable_Properties
              (Entity (ASN), Expression (ASN),
               Class_Present => Class_Present (ASN));
            return;

         --  Invariant/Predicate take boolean expressions

         when Aspect_Dynamic_Predicate
            | Aspect_Invariant
            | Aspect_Predicate
            | Aspect_Static_Predicate
            | Aspect_Type_Invariant
         =>
            T := Standard_Boolean;

         when Aspect_Predicate_Failure =>
            T := Standard_String;

         --  Here is the list of aspects that don't require delay analysis

         when Aspect_Designated_Storage_Model =>
            return;

         when Aspect_Storage_Model_Type =>
            T := Entity (ASN);

            declare
               Assoc     : Node_Id;
               Expr      : Node_Id;
               Addr_Type : Entity_Id := Empty;

            begin
               Assoc := First (Component_Associations (Expression (ASN)));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Analyze (Expr);

                  if not Error_Posted (Expr) then
                     Resolve_Storage_Model_Type_Argument
                       (Expr, T, Addr_Type, Chars (First (Choices (Assoc))));
                  end if;

                  Next (Assoc);
               end loop;
            end;

            return;

         when Aspect_Abstract_State
            | Aspect_Annotate
            | Aspect_Async_Readers
            | Aspect_Async_Writers
            | Aspect_Constant_After_Elaboration
            | Aspect_Contract_Cases
            | Aspect_Default_Initial_Condition
            | Aspect_Depends
            | Aspect_Dimension
            | Aspect_Dimension_System
            | Aspect_Effective_Reads
            | Aspect_Effective_Writes
            | Aspect_Extensions_Visible
            | Aspect_Ghost
            | Aspect_Global
            | Aspect_GNAT_Annotate
            | Aspect_Implicit_Dereference
            | Aspect_Initial_Condition
            | Aspect_Initializes
            | Aspect_Max_Entry_Queue_Depth
            | Aspect_Max_Entry_Queue_Length
            | Aspect_Max_Queue_Length
            | Aspect_No_Caching
            | Aspect_No_Controlled_Parts
            | Aspect_No_Task_Parts
            | Aspect_Obsolescent
            | Aspect_Part_Of
            | Aspect_Post
            | Aspect_Postcondition
            | Aspect_Pre
            | Aspect_Precondition
            | Aspect_Refined_Depends
            | Aspect_Refined_Global
            | Aspect_Refined_Post
            | Aspect_Refined_State
            | Aspect_Relaxed_Initialization
            | Aspect_SPARK_Mode
            | Aspect_Subprogram_Variant
            | Aspect_Suppress
            | Aspect_Test_Case
            | Aspect_Unimplemented
            | Aspect_Unsuppress
            | Aspect_Volatile_Function
         =>
            raise Program_Error;

      end case;

      --  Do the preanalyze call

      if Present (Expression (ASN)) then
         Preanalyze_Spec_Expression (Expression (ASN), T);
      end if;
   end Check_Aspect_At_Freeze_Point;

   -----------------------------------
   -- Check_Constant_Address_Clause --
   -----------------------------------

   procedure Check_Constant_Address_Clause
     (Expr  : Node_Id;
      U_Ent : Entity_Id)
   is
      procedure Check_At_Constant_Address (Nod : Node_Id);
      --  Checks that the given node N represents a name whose 'Address is
      --  constant (in the same sense as OK_Constant_Address_Clause, i.e. the
      --  address value is the same at the point of declaration of U_Ent and at
      --  the time of elaboration of the address clause.

      procedure Check_Expr_Constants (Nod : Node_Id);
      --  Checks that Nod meets the requirements for a constant address clause
      --  in the sense of the enclosing procedure.

      procedure Check_List_Constants (Lst : List_Id);
      --  Check that all elements of list Lst meet the requirements for a
      --  constant address clause in the sense of the enclosing procedure.

      -------------------------------
      -- Check_At_Constant_Address --
      -------------------------------

      procedure Check_At_Constant_Address (Nod : Node_Id) is
      begin
         if Is_Entity_Name (Nod) then
            if Present (Address_Clause (Entity ((Nod)))) then
               Error_Msg_NE
                 ("invalid address clause for initialized object &!",
                  Nod, U_Ent);
               Error_Msg_NE
                 ("address for& cannot depend on another address clause! "
                  & "(RM 13.1(22))!", Nod, U_Ent);

            elsif In_Same_Source_Unit (Entity (Nod), U_Ent)
              and then Sloc (U_Ent) < Sloc (Entity (Nod))
            then
               Error_Msg_NE
                 ("invalid address clause for initialized object &!",
                  Nod, U_Ent);
               Error_Msg_Node_2 := U_Ent;
               Error_Msg_NE
                 ("\& must be defined before & (RM 13.1(22))!",
                  Nod, Entity (Nod));
            end if;

         elsif Nkind (Nod) = N_Selected_Component then
            declare
               T : constant Entity_Id := Etype (Prefix (Nod));

            begin
               if (Is_Record_Type (T)
                    and then Has_Discriminants (T))
                 or else
                  (Is_Access_Type (T)
                    and then Is_Record_Type (Designated_Type (T))
                    and then Has_Discriminants (Designated_Type (T)))
               then
                  Error_Msg_NE
                    ("invalid address clause for initialized object &!",
                     Nod, U_Ent);
                  Error_Msg_N
                    ("\address cannot depend on component of discriminated "
                     & "record (RM 13.1(22))!", Nod);
               else
                  Check_At_Constant_Address (Prefix (Nod));
               end if;
            end;

         elsif Nkind (Nod) = N_Indexed_Component then
            Check_At_Constant_Address (Prefix (Nod));
            Check_List_Constants (Expressions (Nod));

         else
            Check_Expr_Constants (Nod);
         end if;
      end Check_At_Constant_Address;

      --------------------------
      -- Check_Expr_Constants --
      --------------------------

      procedure Check_Expr_Constants (Nod : Node_Id) is
         Loc_U_Ent : constant Source_Ptr := Sloc (U_Ent);
         Ent       : Entity_Id           := Empty;

      begin
         if Nkind (Nod) in N_Has_Etype
           and then Etype (Nod) = Any_Type
         then
            return;
         end if;

         case Nkind (Nod) is
            when N_Empty
               | N_Error
            =>
               return;

            when N_Expanded_Name
               | N_Identifier
            =>
               Ent := Entity (Nod);

               --  We need to look at the original node if it is different
               --  from the node, since we may have rewritten things and
               --  substituted an identifier representing the rewrite.

               if Is_Rewrite_Substitution (Nod) then
                  Check_Expr_Constants (Original_Node (Nod));

                  --  If the node is an object declaration without initial
                  --  value, some code has been expanded, and the expression
                  --  is not constant, even if the constituents might be
                  --  acceptable, as in A'Address + offset.

                  if Ekind (Ent) = E_Variable
                    and then
                      Nkind (Declaration_Node (Ent)) = N_Object_Declaration
                    and then
                      No (Expression (Declaration_Node (Ent)))
                  then
                     Error_Msg_NE
                       ("invalid address clause for initialized object &!",
                        Nod, U_Ent);

                  --  If entity is constant, it may be the result of expanding
                  --  a check. We must verify that its declaration appears
                  --  before the object in question, else we also reject the
                  --  address clause.

                  elsif Ekind (Ent) = E_Constant
                    and then In_Same_Source_Unit (Ent, U_Ent)
                    and then Sloc (Ent) > Loc_U_Ent
                  then
                     Error_Msg_NE
                       ("invalid address clause for initialized object &!",
                        Nod, U_Ent);
                  end if;

                  return;
               end if;

               --  Otherwise look at the identifier and see if it is OK

               if Is_Named_Number (Ent) or else Is_Type (Ent) then
                  return;

               elsif Ekind (Ent) in E_Constant | E_In_Parameter then

                  --  This is the case where we must have Ent defined before
                  --  U_Ent. Clearly if they are in different units this
                  --  requirement is met since the unit containing Ent is
                  --  already processed.

                  if not In_Same_Source_Unit (Ent, U_Ent) then
                     return;

                  --  Otherwise location of Ent must be before the location
                  --  of U_Ent, that's what prior defined means.

                  elsif Sloc (Ent) < Loc_U_Ent then
                     return;

                  else
                     Error_Msg_NE
                       ("invalid address clause for initialized object &!",
                        Nod, U_Ent);
                     Error_Msg_Node_2 := U_Ent;
                     Error_Msg_NE
                       ("\& must be defined before & (RM 13.1(22))!",
                        Nod, Ent);
                  end if;

               elsif Nkind (Original_Node (Nod)) = N_Function_Call then
                  Check_Expr_Constants (Original_Node (Nod));

               else
                  Error_Msg_NE
                    ("invalid address clause for initialized object &!",
                     Nod, U_Ent);

                  if Comes_From_Source (Ent) then
                     Error_Msg_NE
                       ("\reference to variable& not allowed"
                          & " (RM 13.1(22))!", Nod, Ent);
                  else
                     Error_Msg_N
                       ("non-static expression not allowed"
                          & " (RM 13.1(22))!", Nod);
                  end if;
               end if;

            when N_Integer_Literal   =>

               --  If this is a rewritten unchecked conversion, in a system
               --  where Address is an integer type, always use the base type
               --  for a literal value. This is user-friendly and prevents
               --  order-of-elaboration issues with instances of unchecked
               --  conversion.

               if Nkind (Original_Node (Nod)) = N_Function_Call then
                  Set_Etype (Nod, Base_Type (Etype (Nod)));
               end if;

            when N_Character_Literal
               | N_Real_Literal
               | N_String_Literal
            =>
               return;

            when N_Range =>
               Check_Expr_Constants (Low_Bound (Nod));
               Check_Expr_Constants (High_Bound (Nod));

            when N_Explicit_Dereference =>
               Check_Expr_Constants (Prefix (Nod));

            when N_Indexed_Component =>
               Check_Expr_Constants (Prefix (Nod));
               Check_List_Constants (Expressions (Nod));

            when N_Slice =>
               Check_Expr_Constants (Prefix (Nod));
               Check_Expr_Constants (Discrete_Range (Nod));

            when N_Selected_Component =>
               Check_Expr_Constants (Prefix (Nod));

            when N_Attribute_Reference =>
               if Attribute_Name (Nod) in Name_Address
                                        | Name_Access
                                        | Name_Unchecked_Access
                                        | Name_Unrestricted_Access
               then
                  Check_At_Constant_Address (Prefix (Nod));

               --  Normally, System'To_Address will have been transformed into
               --  an Unchecked_Conversion, but in -gnatc mode, it will not,
               --  and we don't want to give an error, because the whole point
               --  of 'To_Address is that it is static.

               elsif Attribute_Name (Nod) = Name_To_Address then
                  pragma Assert (Operating_Mode = Check_Semantics);
                  null;

               else
                  Check_Expr_Constants (Prefix (Nod));
                  Check_List_Constants (Expressions (Nod));
               end if;

            when N_Aggregate =>
               Check_List_Constants (Component_Associations (Nod));
               Check_List_Constants (Expressions (Nod));

            when N_Component_Association =>
               Check_Expr_Constants (Expression (Nod));

            when N_Extension_Aggregate =>
               Check_Expr_Constants (Ancestor_Part (Nod));
               Check_List_Constants (Component_Associations (Nod));
               Check_List_Constants (Expressions (Nod));

            when N_Null =>
               return;

            when N_Binary_Op
               | N_Membership_Test
               | N_Short_Circuit
            =>
               Check_Expr_Constants (Left_Opnd (Nod));
               Check_Expr_Constants (Right_Opnd (Nod));

            when N_Unary_Op =>
               Check_Expr_Constants (Right_Opnd (Nod));

            when N_Allocator
               | N_Qualified_Expression
               | N_Type_Conversion
               | N_Unchecked_Type_Conversion
            =>
               Check_Expr_Constants (Expression (Nod));

            when N_Function_Call =>
               if not Is_Pure (Entity (Name (Nod))) then
                  Error_Msg_NE
                    ("invalid address clause for initialized object &!",
                     Nod, U_Ent);

                  Error_Msg_NE
                    ("\function & is not pure (RM 13.1(22))!",
                     Nod, Entity (Name (Nod)));

               else
                  Check_List_Constants (Parameter_Associations (Nod));
               end if;

            when N_Parameter_Association =>
               Check_Expr_Constants (Explicit_Actual_Parameter (Nod));

            when others =>
               Error_Msg_NE
                 ("invalid address clause for initialized object &!",
                  Nod, U_Ent);
               Error_Msg_NE
                 ("\must be constant defined before& (RM 13.1(22))!",
                  Nod, U_Ent);
         end case;
      end Check_Expr_Constants;

      --------------------------
      -- Check_List_Constants --
      --------------------------

      procedure Check_List_Constants (Lst : List_Id) is
         Nod1 : Node_Id;

      begin
         if Present (Lst) then
            Nod1 := First (Lst);
            while Present (Nod1) loop
               Check_Expr_Constants (Nod1);
               Next (Nod1);
            end loop;
         end if;
      end Check_List_Constants;

   --  Start of processing for Check_Constant_Address_Clause

   begin
      --  If rep_clauses are to be ignored, no need for legality checks. In
      --  particular, no need to pester user about rep clauses that violate the
      --  rule on constant addresses, given that these clauses will be removed
      --  by Freeze before they reach the back end. Similarly in CodePeer mode,
      --  we want to relax these checks.

      if not Ignore_Rep_Clauses and not CodePeer_Mode then
         Check_Expr_Constants (Expr);
      end if;
   end Check_Constant_Address_Clause;

   ---------------------------
   -- Check_Pool_Size_Clash --
   ---------------------------

   procedure Check_Pool_Size_Clash (Ent : Entity_Id; SP, SS : Node_Id) is
      Post : Node_Id;

   begin
      --  We need to find out which one came first. Note that in the case of
      --  aspects mixed with pragmas there are cases where the processing order
      --  is reversed, which is why we do the check here.

      if Sloc (SP) < Sloc (SS) then
         Error_Msg_Sloc := Sloc (SP);
         Post := SS;
         Error_Msg_NE ("Storage_Pool previously given for&#", Post, Ent);

      else
         Error_Msg_Sloc := Sloc (SS);
         Post := SP;
         Error_Msg_NE ("Storage_Size previously given for&#", Post, Ent);
      end if;

      Error_Msg_N
        ("\cannot have Storage_Size and Storage_Pool (RM 13.11(3))", Post);
   end Check_Pool_Size_Clash;

   ----------------------------------------
   -- Check_Record_Representation_Clause --
   ----------------------------------------

   procedure Check_Record_Representation_Clause (N : Node_Id) is
      Loc     : constant Source_Ptr := Sloc (N);
      Ident   : constant Node_Id    := Identifier (N);
      Rectype : Entity_Id;
      Fent    : Entity_Id;
      CC      : Node_Id;
      Fbit    : Uint := No_Uint;
      Lbit    : Uint := No_Uint;
      Hbit    : Uint := Uint_0;
      Comp    : Entity_Id;
      Pcomp   : Entity_Id;

      Max_Bit_So_Far : Uint;
      --  Records the maximum bit position so far. If all field positions
      --  are monotonically increasing, then we can skip the circuit for
      --  checking for overlap, since no overlap is possible.

      Tagged_Parent : Entity_Id := Empty;
      --  This is set in the case of an extension for which we have either a
      --  size clause or Is_Fully_Repped_Tagged_Type True (indicating that all
      --  components are positioned by record representation clauses) on the
      --  parent type. In this case we check for overlap between components of
      --  this tagged type and the parent component. Tagged_Parent will point
      --  to this parent type. For all other cases, Tagged_Parent is Empty.

      Parent_Last_Bit : Uint := No_Uint; -- init to avoid warning
      --  Relevant only if Tagged_Parent is set, Parent_Last_Bit indicates the
      --  last bit position for any field in the parent type. We only need to
      --  check overlap for fields starting below this point.

      Overlap_Check_Required : Boolean;
      --  Used to keep track of whether or not an overlap check is required

      Overlap_Detected : Boolean := False;
      --  Set True if an overlap is detected

      Ccount : Natural := 0;
      --  Number of component clauses in record rep clause

      procedure Check_Component_Overlap (C1_Ent, C2_Ent : Entity_Id);
      --  Given two entities for record components or discriminants, checks
      --  if they have overlapping component clauses and issues errors if so.

      procedure Find_Component;
      --  Finds component entity corresponding to current component clause (in
      --  CC), and sets Comp to the entity, and Fbit/Lbit to the zero origin
      --  start/stop bits for the field. If there is no matching component or
      --  if the matching component does not have a component clause, then
      --  that's an error and Comp is set to Empty, but no error message is
      --  issued, since the message was already given. Comp is also set to
      --  Empty if the current "component clause" is in fact a pragma.

      procedure Record_Hole_Check
        (Rectype : Entity_Id; After_Last : out Uint; Warn : Boolean);
      --  Checks for gaps in the given Rectype. Compute After_Last, the bit
      --  number after the last component. Warn is True on the initial call,
      --  and warnings are given for gaps. For a type extension, this is called
      --  recursively to compute After_Last for the parent type; in this case
      --  Warn is False and the warnings are suppressed.

      procedure Component_Order_Check (Rectype : Entity_Id);
      --  Check that the order of component clauses agrees with the order of
      --  component declarations, and that the component clauses are given in
      --  increasing order of bit offset.

      -----------------------------
      -- Check_Component_Overlap --
      -----------------------------

      procedure Check_Component_Overlap (C1_Ent, C2_Ent : Entity_Id) is
         CC1 : constant Node_Id := Component_Clause (C1_Ent);
         CC2 : constant Node_Id := Component_Clause (C2_Ent);

      begin
         if Present (CC1) and then Present (CC2) then

            --  Exclude odd case where we have two tag components in the same
            --  record, both at location zero. This seems a bit strange, but
            --  it seems to happen in some circumstances, perhaps on an error.

            if Chars (C1_Ent) = Name_uTag then
               return;
            end if;

            --  Here we check if the two fields overlap

            declare
               S1 : constant Uint := Component_Bit_Offset (C1_Ent);
               S2 : constant Uint := Component_Bit_Offset (C2_Ent);
               E1 : constant Uint := S1 + Esize (C1_Ent);
               E2 : constant Uint := S2 + Esize (C2_Ent);

            begin
               if E2 <= S1 or else E1 <= S2 then
                  null;
               else
                  Error_Msg_Node_2 := Component_Name (CC2);
                  Error_Msg_Sloc := Sloc (Error_Msg_Node_2);
                  Error_Msg_Node_1 := Component_Name (CC1);
                  Error_Msg_N
                    ("component& overlaps & #", Component_Name (CC1));
                  Overlap_Detected := True;
               end if;
            end;
         end if;
      end Check_Component_Overlap;

      ---------------------------
      -- Component_Order_Check --
      ---------------------------

      procedure Component_Order_Check (Rectype : Entity_Id) is
         Comp : Entity_Id := First_Component (Rectype);
         Clause : Node_Id := First (Component_Clauses (N));
         Prev_Bit_Offset : Uint := Uint_0;
         OOO : constant String :=
           "?_r?component clause out of order with respect to declaration";

      begin
         --  Step Comp through components and Clause through component clauses,
         --  skipping pragmas. We ignore discriminants and variant parts,
         --  because we get most of the benefit from the plain vanilla
         --  component cases, without the extra complexity. If we find a Comp
         --  and Clause that don't match, give a warning on both and quit. If
         --  we find two subsequent clauses out of order by bit layout, give
         --  warning and quit. On each iteration, Prev_Bit_Offset is the one
         --  from the previous iteration (or 0 to start).

         while Present (Comp) and then Present (Clause) loop
            if Nkind (Clause) = N_Component_Clause
              and then Ekind (Entity (Component_Name (Clause))) = E_Component
            then
               if Entity (Component_Name (Clause)) /= Comp then
                  Error_Msg_N (OOO, Comp);
                  Error_Msg_N (OOO, Clause);
                  exit;
               end if;

               if not Reverse_Bit_Order (Rectype)
                 and then not Reverse_Storage_Order (Rectype)
                 and then Component_Bit_Offset (Comp) < Prev_Bit_Offset
               then
                  Error_Msg_N ("?_r?memory layout out of order", Clause);
                  exit;
               end if;

               Prev_Bit_Offset := Component_Bit_Offset (Comp);
               Next_Component (Comp);
            end if;

            Next (Clause);
         end loop;
      end Component_Order_Check;

      --------------------
      -- Find_Component --
      --------------------

      procedure Find_Component is

         procedure Search_Component (R : Entity_Id);
         --  Search components of R for a match. If found, Comp is set

         ----------------------
         -- Search_Component --
         ----------------------

         procedure Search_Component (R : Entity_Id) is
         begin
            Comp := First_Component_Or_Discriminant (R);
            while Present (Comp) loop

               --  Ignore error of attribute name for component name (we
               --  already gave an error message for this, so no need to
               --  complain here)

               if Nkind (Component_Name (CC)) = N_Attribute_Reference then
                  null;
               else
                  exit when Chars (Comp) = Chars (Component_Name (CC));
               end if;

               Next_Component_Or_Discriminant (Comp);
            end loop;
         end Search_Component;

      --  Start of processing for Find_Component

      begin
         --  Return with Comp set to Empty if we have a pragma

         if Nkind (CC) = N_Pragma then
            Comp := Empty;
            return;
         end if;

         --  Search current record for matching component

         Search_Component (Rectype);

         --  If not found, maybe component of base type discriminant that is
         --  absent from statically constrained first subtype.

         if No (Comp) then
            Search_Component (Base_Type (Rectype));
         end if;

         --  If no component, or the component does not reference the component
         --  clause in question, then there was some previous error for which
         --  we already gave a message, so just return with Comp Empty.

         if No (Comp) or else Component_Clause (Comp) /= CC then
            Check_Error_Detected;
            Comp := Empty;

         --  Normal case where we have a component clause

         else
            Fbit := Component_Bit_Offset (Comp);
            Lbit := Fbit + Esize (Comp) - 1;
         end if;
      end Find_Component;

      -----------------------
      -- Record_Hole_Check --
      -----------------------

      procedure Record_Hole_Check
        (Rectype : Entity_Id; After_Last : out Uint; Warn : Boolean)
      is
         Decl : constant Node_Id := Declaration_Node (Base_Type (Rectype));
         --  Full declaration of record type

         procedure Check_Component_List
           (DS   : List_Id;
            CL   : Node_Id;
            Sbit : Uint;
            Abit : out Uint);
         --  Check component list CL for holes. DS is a list of discriminant
         --  specifications to be included in the consideration of components.
         --  Sbit is the starting bit, which is zero if there are no preceding
         --  components (before a variant part, or a parent type, or a tag
         --  field). If there are preceding components, Sbit is the bit just
         --  after the last such component. Abit is set to the bit just after
         --  the last component of DS and CL.

         --------------------------
         -- Check_Component_List --
         --------------------------

         procedure Check_Component_List
           (DS   : List_Id;
            CL   : Node_Id;
            Sbit : Uint;
            Abit : out Uint)
         is
            Compl : Integer;

         begin
            Compl := Integer (List_Length (Component_Items (CL)));

            if DS /= No_List then
               Compl := Compl + Integer (List_Length (DS));
            end if;

            declare
               Comps : array (Natural range 0 .. Compl) of Entity_Id;
               --  Gather components (zero entry is for sort routine)

               Ncomps : Natural := 0;
               --  Number of entries stored in Comps (starting at Comps (1))

               Citem : Node_Id;
               --  One component item or discriminant specification

               Nbit  : Uint;
               --  Starting bit for next component

               CEnt  : Entity_Id;
               --  Component entity

               Variant : Node_Id;
               --  One variant

               function Lt (Op1, Op2 : Natural) return Boolean;
               --  Compare routine for Sort

               procedure Move (From : Natural; To : Natural);
               --  Move routine for Sort

               package Sorting is new GNAT.Heap_Sort_G (Move, Lt);

               --------
               -- Lt --
               --------

               function Lt (Op1, Op2 : Natural) return Boolean is
                  K1 : constant Boolean :=
                    Known_Component_Bit_Offset (Comps (Op1));
                  K2 : constant Boolean :=
                    Known_Component_Bit_Offset (Comps (Op2));
                  --  Record representation clauses can be incomplete, so the
                  --  Component_Bit_Offsets can be unknown.
               begin
                  if K1 then
                     if K2 then
                        return Component_Bit_Offset (Comps (Op1))
                             < Component_Bit_Offset (Comps (Op2));
                     else
                        return True;
                     end if;
                  else
                     return K2;
                  end if;
               end Lt;

               ----------
               -- Move --
               ----------

               procedure Move (From : Natural; To : Natural) is
               begin
                  Comps (To) := Comps (From);
               end Move;

            begin
               --  Gather discriminants into Comp

               if DS /= No_List then
                  Citem := First (DS);
                  while Present (Citem) loop
                     if Nkind (Citem) = N_Discriminant_Specification then
                        declare
                           Ent : constant Entity_Id :=
                                   Defining_Identifier (Citem);
                        begin
                           if Ekind (Ent) = E_Discriminant then
                              Ncomps := Ncomps + 1;
                              Comps (Ncomps) := Ent;
                           end if;
                        end;
                     end if;

                     Next (Citem);
                  end loop;
               end if;

               --  Gather component entities into Comp

               Citem := First (Component_Items (CL));
               while Present (Citem) loop
                  if Nkind (Citem) = N_Component_Declaration then
                     Ncomps := Ncomps + 1;
                     Comps (Ncomps) := Defining_Identifier (Citem);
                  end if;

                  Next (Citem);
               end loop;

               --  Now sort the component entities based on the first bit.
               --  Note we already know there are no overlapping components.

               Sorting.Sort (Ncomps);

               --  Loop through entries checking for holes

               Nbit := Sbit;
               for J in 1 .. Ncomps loop
                  CEnt := Comps (J);
                  pragma Annotate (CodePeer, Modified, CEnt);

                  declare
                     CBO : constant Uint := Component_Bit_Offset (CEnt);

                  begin
                     --  Skip components with unknown offsets

                     if Present (CBO) and then CBO >= 0 then
                        Error_Msg_Uint_1 := CBO - Nbit;

                        if Warn and then Error_Msg_Uint_1 > 0 then
                           Error_Msg_NE
                             ("?.h?^-bit gap before component&",
                              Component_Name (Component_Clause (CEnt)),
                              CEnt);
                        end if;

                        Nbit := CBO + Esize (CEnt);
                     end if;
                  end;
               end loop;

               --  Set Abit to just after the last nonvariant component

               Abit := Nbit;

               --  Process variant parts recursively if present. Set Abit to
               --  the maximum for all variant parts.

               if Present (Variant_Part (CL)) then
                  declare
                     Var_Start : constant Uint := Nbit;
                  begin
                     Variant := First (Variants (Variant_Part (CL)));
                     while Present (Variant) loop
                        Check_Component_List
                          (No_List, Component_List (Variant), Var_Start, Nbit);
                        Next (Variant);
                        if Nbit > Abit then
                           Abit := Nbit;
                        end if;
                     end loop;
                  end;
               end if;
            end;
         end Check_Component_List;

         --  Local variables

         Sbit : Uint;
         --  Starting bit for call to Check_Component_List. Zero for an
         --  untagged type. The size of the Tag for a nonderived tagged
         --  type. Parent size for a type extension.

         Record_Definition : Node_Id;
         --  Record_Definition containing Component_List to pass to
         --  Check_Component_List.

      --  Start of processing for Record_Hole_Check

      begin
         if Is_Tagged_Type (Rectype) then
            Sbit := UI_From_Int (System_Address_Size);
         else
            Sbit := Uint_0;
         end if;

         After_Last := Uint_0;

         if Nkind (Decl) = N_Full_Type_Declaration then
            Record_Definition := Type_Definition (Decl);

            --  If we have a record extension, set Sbit to point after the last
            --  component of the parent type, by calling Record_Hole_Check
            --  recursively.

            if Nkind (Record_Definition) = N_Derived_Type_Definition then
               Record_Definition := Record_Extension_Part (Record_Definition);
               Record_Hole_Check (Underlying_Type (Parent_Subtype (Rectype)),
                                  After_Last => Sbit, Warn => False);
            end if;

            if Nkind (Record_Definition) = N_Record_Definition then
               Check_Component_List
                 (Discriminant_Specifications (Decl),
                  Component_List (Record_Definition),
                  Sbit, After_Last);
            end if;
         end if;
      end Record_Hole_Check;

   --  Start of processing for Check_Record_Representation_Clause

   begin
      Find_Type (Ident);
      Rectype := Entity (Ident);

      if Rectype = Any_Type then
         return;
      end if;

      Rectype := Underlying_Type (Rectype);

      --  See if we have a fully repped derived tagged type

      declare
         PS : constant Entity_Id := Parent_Subtype (Rectype);

      begin
         if Present (PS) and then Known_Static_RM_Size (PS) then
            Tagged_Parent := PS;
            Parent_Last_Bit := RM_Size (PS) - 1;

         elsif Present (PS) and then Is_Fully_Repped_Tagged_Type (PS) then
            Tagged_Parent := PS;

            --  Find maximum bit of any component of the parent type

            Parent_Last_Bit := UI_From_Int (System_Address_Size - 1);
            Pcomp := First_Component_Or_Discriminant (Tagged_Parent);
            while Present (Pcomp) loop
               if Present (Component_Bit_Offset (Pcomp))
                 and then Known_Static_Esize (Pcomp)
               then
                  Parent_Last_Bit :=
                    UI_Max
                      (Parent_Last_Bit,
                       Component_Bit_Offset (Pcomp) + Esize (Pcomp) - 1);
               end if;

               Next_Component_Or_Discriminant (Pcomp);
            end loop;
         end if;
      end;

      --  All done if no component clauses

      CC := First (Component_Clauses (N));

      if No (CC) then
         return;
      end if;

      --  If a tag is present, then create a component clause that places it
      --  at the start of the record (otherwise gigi may place it after other
      --  fields that have rep clauses).

      Fent := First_Entity (Rectype);

      if Nkind (Fent) = N_Defining_Identifier
        and then Chars (Fent) = Name_uTag
      then
         Set_Component_Bit_Offset    (Fent, Uint_0);
         Set_Normalized_Position     (Fent, Uint_0);
         Set_Normalized_First_Bit    (Fent, Uint_0);
         Set_Esize                   (Fent, UI_From_Int (System_Address_Size));

         Set_Component_Clause (Fent,
           Make_Component_Clause (Loc,
             Component_Name => Make_Identifier (Loc, Name_uTag),

             Position  => Make_Integer_Literal (Loc, Uint_0),
             First_Bit => Make_Integer_Literal (Loc, Uint_0),
             Last_Bit  =>
               Make_Integer_Literal (Loc,
                 UI_From_Int (System_Address_Size - 1))));

         Ccount := Ccount + 1;
      end if;

      Max_Bit_So_Far := Uint_Minus_1;
      Overlap_Check_Required := False;

      --  Process the component clauses

      while Present (CC) loop
         Find_Component;

         if Present (Comp) then
            Ccount := Ccount + 1;

            --  We need a full overlap check if record positions non-monotonic

            if Fbit <= Max_Bit_So_Far then
               Overlap_Check_Required := True;
            end if;

            Max_Bit_So_Far := Lbit;

            --  Check bit position out of range of specified size

            if Has_Size_Clause (Rectype)
              and then RM_Size (Rectype) <= Lbit
            then
               Error_Msg_Uint_1 := RM_Size (Rectype);
               Error_Msg_Uint_2 := Lbit + 1;
               Error_Msg_N ("bit number out of range of specified "
                  & "size (expected ^, got ^)",
                  Last_Bit (CC));

               --  Check for overlap with tag or parent component

            else
               if Is_Tagged_Type (Rectype)
                 and then Fbit < System_Address_Size
               then
                  Error_Msg_NE
                    ("component overlaps tag field of&",
                     Component_Name (CC), Rectype);
                  Overlap_Detected := True;

               elsif Present (Tagged_Parent)
                 and then Fbit <= Parent_Last_Bit
               then
                  Error_Msg_NE
                    ("component overlaps parent field of&",
                     Component_Name (CC), Rectype);
                  Overlap_Detected := True;
               end if;

               if Hbit < Lbit then
                  Hbit := Lbit;
               end if;
            end if;
         end if;

         Next (CC);
      end loop;

      --  Now that we have processed all the component clauses, check for
      --  overlap. We have to leave this till last, since the components can
      --  appear in any arbitrary order in the representation clause.

      --  We do not need this check if all specified ranges were monotonic,
      --  as recorded by Overlap_Check_Required being False at this stage.

      --  This first section checks if there are any overlapping entries at
      --  all. It does this by sorting all entries and then seeing if there are
      --  any overlaps. If there are none, then that is decisive, but if there
      --  are overlaps, they may still be OK (they may result from fields in
      --  different variants).

      if Overlap_Check_Required then
         Overlap_Check1 : declare

            OC_Fbit : array (0 .. Ccount) of Uint;
            --  First-bit values for component clauses, the value is the offset
            --  of the first bit of the field from start of record. The zero
            --  entry is for use in sorting.

            OC_Lbit : array (0 .. Ccount) of Uint;
            --  Last-bit values for component clauses, the value is the offset
            --  of the last bit of the field from start of record. The zero
            --  entry is for use in sorting.

            OC_Count : Natural := 0;
            --  Count of entries in OC_Fbit and OC_Lbit

            function OC_Lt (Op1, Op2 : Natural) return Boolean;
            --  Compare routine for Sort

            procedure OC_Move (From : Natural; To : Natural);
            --  Move routine for Sort

            package Sorting is new GNAT.Heap_Sort_G (OC_Move, OC_Lt);

            -----------
            -- OC_Lt --
            -----------

            function OC_Lt (Op1, Op2 : Natural) return Boolean is
            begin
               return OC_Fbit (Op1) < OC_Fbit (Op2);
            end OC_Lt;

            -------------
            -- OC_Move --
            -------------

            procedure OC_Move (From : Natural; To : Natural) is
            begin
               OC_Fbit (To) := OC_Fbit (From);
               OC_Lbit (To) := OC_Lbit (From);
            end OC_Move;

            --  Start of processing for Overlap_Check

         begin
            CC := First (Component_Clauses (N));
            while Present (CC) loop

               --  Exclude component clause already marked in error

               if not Error_Posted (CC) then
                  Find_Component;

                  if Present (Comp) then
                     OC_Count := OC_Count + 1;
                     OC_Fbit (OC_Count) := Fbit;
                     OC_Lbit (OC_Count) := Lbit;
                  end if;
               end if;

               Next (CC);
            end loop;

            Sorting.Sort (OC_Count);

            Overlap_Check_Required := False;
            for J in 1 .. OC_Count - 1 loop
               if OC_Lbit (J) >= OC_Fbit (J + 1) then
                  Overlap_Check_Required := True;
                  exit;
               end if;
            end loop;
         end Overlap_Check1;
      end if;

      --  If Overlap_Check_Required is still True, then we have to do the full
      --  scale overlap check, since we have at least two fields that do
      --  overlap, and we need to know if that is OK since they are in
      --  different variant, or whether we have a definite problem.

      if Overlap_Check_Required then
         Overlap_Check2 : declare
            C1_Ent, C2_Ent : Entity_Id;
            --  Entities of components being checked for overlap

            Clist : Node_Id;
            --  Component_List node whose Component_Items are being checked

            Citem : Node_Id;
            --  Component declaration for component being checked

         begin
            C1_Ent := First_Entity (Base_Type (Rectype));

            --  Loop through all components in record. For each component check
            --  for overlap with any of the preceding elements on the component
            --  list containing the component and also, if the component is in
            --  a variant, check against components outside the case structure.
            --  This latter test is repeated recursively up the variant tree.

            Main_Component_Loop : while Present (C1_Ent) loop
               if Ekind (C1_Ent) not in E_Component | E_Discriminant then
                  goto Continue_Main_Component_Loop;
               end if;

               --  Skip overlap check if entity has no declaration node. This
               --  happens with discriminants in constrained derived types.
               --  Possibly we are missing some checks as a result, but that
               --  does not seem terribly serious.

               if No (Declaration_Node (C1_Ent)) then
                  goto Continue_Main_Component_Loop;
               end if;

               Clist := Parent (List_Containing (Declaration_Node (C1_Ent)));

               --  Loop through component lists that need checking. Check the
               --  current component list and all lists in variants above us.

               Component_List_Loop : loop

                  --  If derived type definition, go to full declaration
                  --  If at outer level, check discriminants if there are any.

                  if Nkind (Clist) = N_Derived_Type_Definition then
                     Clist := Parent (Clist);
                  end if;

                  --  Outer level of record definition, check discriminants
                  --  but be careful not to flag a non-stored discriminant
                  --  and the stored discriminant it renames as overlapping.

                  if Nkind (Clist) in N_Full_Type_Declaration
                                    | N_Private_Type_Declaration
                  then
                     if Has_Discriminants (Defining_Identifier (Clist)) then
                        C2_Ent :=
                          First_Discriminant (Defining_Identifier (Clist));
                        while Present (C2_Ent) loop
                           exit when
                             Original_Record_Component (C1_Ent) =
                               Original_Record_Component (C2_Ent);
                           Check_Component_Overlap (C1_Ent, C2_Ent);
                           Next_Discriminant (C2_Ent);
                        end loop;
                     end if;

                     --  Record extension case

                  elsif Nkind (Clist) = N_Derived_Type_Definition then
                     Clist := Empty;

                     --  Otherwise check one component list

                  else
                     Citem := First (Component_Items (Clist));
                     while Present (Citem) loop
                        if Nkind (Citem) = N_Component_Declaration then
                           C2_Ent := Defining_Identifier (Citem);
                           exit when C1_Ent = C2_Ent;
                           Check_Component_Overlap (C1_Ent, C2_Ent);
                        end if;

                        Next (Citem);
                     end loop;
                  end if;

                  --  Check for variants above us (the parent of the Clist can
                  --  be a variant, in which case its parent is a variant part,
                  --  and the parent of the variant part is a component list
                  --  whose components must all be checked against the current
                  --  component for overlap).

                  if Nkind (Parent (Clist)) = N_Variant then
                     Clist := Parent (Parent (Parent (Clist)));

                     --  Check for possible discriminant part in record, this
                     --  is treated essentially as another level in the
                     --  recursion. For this case the parent of the component
                     --  list is the record definition, and its parent is the
                     --  full type declaration containing the discriminant
                     --  specifications.

                  elsif Nkind (Parent (Clist)) = N_Record_Definition then
                     Clist := Parent (Parent ((Clist)));

                     --  If neither of these two cases, we are at the top of
                     --  the tree.

                  else
                     exit Component_List_Loop;
                  end if;
               end loop Component_List_Loop;

               <<Continue_Main_Component_Loop>>
               Next_Entity (C1_Ent);

            end loop Main_Component_Loop;
         end Overlap_Check2;
      end if;

      --  Skip the following warnings if overlap was detected; programmer
      --  should fix the errors first. Also skip the warnings for types in
      --  generics, because their representation information is not fully
      --  computed.

      if not Overlap_Detected and then not In_Generic_Scope (Rectype) then
         --  Check for record holes (gaps)

         if Warn_On_Record_Holes then
            declare
               Ignore : Uint;
            begin
               Record_Hole_Check (Rectype, After_Last => Ignore, Warn => True);
            end;
         end if;

         --  Check for out-of-order component clauses

         if Warn_On_Component_Order then
            Component_Order_Check (Rectype);
         end if;
      end if;

      --  For records that have component clauses for all components, and whose
      --  size is less than or equal to 32, and which can be fully packed, we
      --  need to know the size in the front end to activate possible packed
      --  array processing where the component type is a record.

      --  At this stage Hbit + 1 represents the first unused bit from all the
      --  component clauses processed, so if the component clauses are
      --  complete, then this is the length of the record.

      --  For records longer than System.Storage_Unit, and for those where not
      --  all components have component clauses, the back end determines the
      --  length (it may for example be appropriate to round up the size
      --  to some convenient boundary, based on alignment considerations, etc).

      if not Known_RM_Size (Rectype)
        and then Hbit + 1 <= 32
        and then not Strict_Alignment (Rectype)
      then

         --  Nothing to do if at least one component has no component clause

         Comp := First_Component_Or_Discriminant (Rectype);
         while Present (Comp) loop
            exit when No (Component_Clause (Comp));
            Next_Component_Or_Discriminant (Comp);
         end loop;

         --  If we fall out of loop, all components have component clauses
         --  and so we can set the size to the maximum value.

         if No (Comp) then
            Set_RM_Size (Rectype, Hbit + 1);
         end if;
      end if;
   end Check_Record_Representation_Clause;

   ----------------
   -- Check_Size --
   ----------------

   procedure Check_Size
     (N      : Node_Id;
      T      : Entity_Id;
      Siz    : Uint;
      Biased : out Boolean)
   is
      procedure Size_Too_Small_Error (Min_Siz : Uint);
      --  Emit an error concerning illegal size Siz. Min_Siz denotes the
      --  minimum size.

      --------------------------
      -- Size_Too_Small_Error --
      --------------------------

      procedure Size_Too_Small_Error (Min_Siz : Uint) is
      begin
         Error_Msg_Uint_1 := Min_Siz;
         Error_Msg_NE (Size_Too_Small_Message, N, T);
      end Size_Too_Small_Error;

      --  Local variables

      UT : constant Entity_Id := Underlying_Type (T);
      M  : Uint;

   --  Start of processing for Check_Size

   begin
      Biased := False;

      --  Reject patently improper size values

      if Is_Elementary_Type (T)
        and then Siz > Int'Last
      then
         Error_Msg_N ("Size value too large for elementary type", N);

         if Nkind (Original_Node (N)) = N_Op_Expon then
            Error_Msg_N
              ("\maybe '* was meant, rather than '*'*", Original_Node (N));
         end if;
      end if;

      --  Dismiss generic types

      if Is_Generic_Type (T)
           or else
         Is_Generic_Type (UT)
           or else
         Is_Generic_Type (Root_Type (UT))
      then
         return;

      --  Guard against previous errors

      elsif No (UT) or else UT = Any_Type then
         Check_Error_Detected;
         return;

      --  Check case of bit packed array

      elsif Is_Array_Type (UT)
        and then Known_Static_Component_Size (UT)
        and then Is_Bit_Packed_Array (UT)
      then
         declare
            Asiz : Uint;
            Indx : Node_Id;
            Ityp : Entity_Id;

         begin
            Asiz := Component_Size (UT);
            Indx := First_Index (UT);
            loop
               Ityp := Etype (Indx);

               --  If non-static bound, then we are not in the business of
               --  trying to check the length, and indeed an error will be
               --  issued elsewhere, since sizes of non-static array types
               --  cannot be set implicitly or explicitly.

               if not Is_OK_Static_Subtype (Ityp) then
                  return;
               end if;

               --  Otherwise accumulate next dimension

               Asiz := Asiz * (Expr_Value (Type_High_Bound (Ityp)) -
                               Expr_Value (Type_Low_Bound  (Ityp)) +
                               Uint_1);

               Next_Index (Indx);
               exit when No (Indx);
            end loop;

            if Asiz <= Siz then
               return;

            else
               Size_Too_Small_Error (Asiz);
            end if;
         end;

      --  All other composite types are ignored

      elsif Is_Composite_Type (UT) then
         return;

      --  For fixed-point types, don't check minimum if type is not frozen,
      --  since we don't know all the characteristics of the type that can
      --  affect the size (e.g. a specified small) till freeze time.

      elsif Is_Fixed_Point_Type (UT) and then not Is_Frozen (UT) then
         null;

      --  Cases for which a minimum check is required

      else
         --  Ignore if specified size is correct for the type

         if Known_Esize (UT) and then Siz = Esize (UT) then
            return;
         end if;

         --  Otherwise get minimum size

         M := UI_From_Int (Minimum_Size (UT));

         if Siz < M then

            --  Size is less than minimum size, but one possibility remains
            --  that we can manage with the new size if we bias the type.

            M := UI_From_Int (Minimum_Size (UT, Biased => True));

            if Siz < M then
               Size_Too_Small_Error (M);
            else
               Biased := True;
            end if;
         end if;
      end if;
   end Check_Size;

   --------------------------
   -- Freeze_Entity_Checks --
   --------------------------

   procedure Freeze_Entity_Checks (N : Node_Id) is
      procedure Hide_Non_Overridden_Subprograms (Typ : Entity_Id);
      --  Inspect the primitive operations of type Typ and hide all pairs of
      --  implicitly declared non-overridden non-fully conformant homographs
      --  (Ada RM 8.3 12.3/2).

      -------------------------------------
      -- Hide_Non_Overridden_Subprograms --
      -------------------------------------

      procedure Hide_Non_Overridden_Subprograms (Typ : Entity_Id) is
         procedure Hide_Matching_Homographs
           (Subp_Id    : Entity_Id;
            Start_Elmt : Elmt_Id);
         --  Inspect a list of primitive operations starting with Start_Elmt
         --  and find matching implicitly declared non-overridden non-fully
         --  conformant homographs of Subp_Id. If found, all matches along
         --  with Subp_Id are hidden from all visibility.

         function Is_Non_Overridden_Or_Null_Procedure
           (Subp_Id : Entity_Id) return Boolean;
         --  Determine whether subprogram Subp_Id is implicitly declared non-
         --  overridden subprogram or an implicitly declared null procedure.

         ------------------------------
         -- Hide_Matching_Homographs --
         ------------------------------

         procedure Hide_Matching_Homographs
           (Subp_Id    : Entity_Id;
            Start_Elmt : Elmt_Id)
         is
            Prim      : Entity_Id;
            Prim_Elmt : Elmt_Id;

         begin
            Prim_Elmt := Start_Elmt;
            while Present (Prim_Elmt) loop
               Prim := Node (Prim_Elmt);

               --  The current primitive is implicitly declared non-overridden
               --  non-fully conformant homograph of Subp_Id. Both subprograms
               --  must be hidden from visibility.

               if Chars (Prim) = Chars (Subp_Id)
                 and then Is_Non_Overridden_Or_Null_Procedure (Prim)
                 and then not Fully_Conformant (Prim, Subp_Id)
               then
                  Set_Is_Hidden_Non_Overridden_Subpgm (Prim);
                  Set_Is_Immediately_Visible          (Prim, False);
                  Set_Is_Potentially_Use_Visible      (Prim, False);

                  Set_Is_Hidden_Non_Overridden_Subpgm (Subp_Id);
                  Set_Is_Immediately_Visible          (Subp_Id, False);
                  Set_Is_Potentially_Use_Visible      (Subp_Id, False);
               end if;

               Next_Elmt (Prim_Elmt);
            end loop;
         end Hide_Matching_Homographs;

         -----------------------------------------
         -- Is_Non_Overridden_Or_Null_Procedure --
         -----------------------------------------

         function Is_Non_Overridden_Or_Null_Procedure
           (Subp_Id : Entity_Id) return Boolean
         is
            Alias_Id : Entity_Id;

         begin
            --  The subprogram is inherited (implicitly declared), it does not
            --  override and does not cover a primitive of an interface.

            if Ekind (Subp_Id) in E_Function | E_Procedure
              and then Present (Alias (Subp_Id))
              and then No (Interface_Alias (Subp_Id))
              and then No (Overridden_Operation (Subp_Id))
            then
               Alias_Id := Alias (Subp_Id);

               if Requires_Overriding (Alias_Id) then
                  return True;

               elsif Nkind (Parent (Alias_Id)) = N_Procedure_Specification
                 and then Null_Present (Parent (Alias_Id))
               then
                  return True;
               end if;
            end if;

            return False;
         end Is_Non_Overridden_Or_Null_Procedure;

         --  Local variables

         Prim_Ops  : constant Elist_Id := Direct_Primitive_Operations (Typ);
         Prim      : Entity_Id;
         Prim_Elmt : Elmt_Id;

      --  Start of processing for Hide_Non_Overridden_Subprograms

      begin
         --  Inspect the list of primitives looking for non-overridden
         --  subprograms.

         if Present (Prim_Ops) then
            Prim_Elmt := First_Elmt (Prim_Ops);
            while Present (Prim_Elmt) loop
               Prim := Node (Prim_Elmt);
               Next_Elmt (Prim_Elmt);

               if Is_Non_Overridden_Or_Null_Procedure (Prim) then
                  Hide_Matching_Homographs
                    (Subp_Id    => Prim,
                     Start_Elmt => Prim_Elmt);
               end if;
            end loop;
         end if;
      end Hide_Non_Overridden_Subprograms;

      --  Local variables

      E : constant Entity_Id := Entity (N);

      Nongeneric_Case : constant Boolean := Nkind (N) = N_Freeze_Entity;
      --  True in nongeneric case. Some of the processing here is skipped
      --  for the generic case since it is not needed. Basically in the
      --  generic case, we only need to do stuff that might generate error
      --  messages or warnings.

   --  Start of processing for Freeze_Entity_Checks

   begin
      --  Remember that we are processing a freezing entity. Required to
      --  ensure correct decoration of internal entities associated with
      --  interfaces (see New_Overloaded_Entity).

      Inside_Freezing_Actions := Inside_Freezing_Actions + 1;

      --  For tagged types covering interfaces add internal entities that link
      --  the primitives of the interfaces with the primitives that cover them.
      --  Note: These entities were originally generated only when generating
      --  code because their main purpose was to provide support to initialize
      --  the secondary dispatch tables. They are also used to locate
      --  primitives covering interfaces when processing generics (see
      --  Derive_Subprograms).

      --  This is not needed in the generic case

      if Ada_Version >= Ada_2005
        and then Nongeneric_Case
        and then Ekind (E) = E_Record_Type
        and then Is_Tagged_Type (E)
        and then not Is_Interface (E)
        and then Has_Interfaces (E)
      then
         --  This would be a good common place to call the routine that checks
         --  overriding of interface primitives (and thus factorize calls to
         --  Check_Abstract_Overriding located at different contexts in the
         --  compiler). However, this is not possible because it causes
         --  spurious errors in case of late overriding.

         Add_Internal_Interface_Entities (E);
      end if;

      --  After all forms of overriding have been resolved, a tagged type may
      --  be left with a set of implicitly declared and possibly erroneous
      --  abstract subprograms, null procedures and subprograms that require
      --  overriding. If this set contains fully conformant homographs, then
      --  one is chosen arbitrarily (already done during resolution), otherwise
      --  all remaining non-fully conformant homographs are hidden from
      --  visibility (Ada RM 8.3 12.3/2).

      if Is_Tagged_Type (E) then
         Hide_Non_Overridden_Subprograms (E);
      end if;

      --  Check CPP types

      if Ekind (E) = E_Record_Type
        and then Is_CPP_Class (E)
        and then Is_Tagged_Type (E)
        and then Tagged_Type_Expansion
      then
         if CPP_Num_Prims (E) = 0 then

            --  If the CPP type has user defined components then it must import
            --  primitives from C++. This is required because if the C++ class
            --  has no primitives then the C++ compiler does not added the _tag
            --  component to the type.

            if First_Entity (E) /= Last_Entity (E) then
               Error_Msg_N
                 ("'C'P'P type must import at least one primitive from C++??",
                  E);
            end if;
         end if;

         --  Check that all its primitives are abstract or imported from C++.
         --  Check also availability of the C++ constructor.

         declare
            Has_Constructors : constant Boolean := Has_CPP_Constructors (E);
            Elmt             : Elmt_Id;
            Error_Reported   : Boolean := False;
            Prim             : Node_Id;

         begin
            Elmt := First_Elmt (Primitive_Operations (E));
            while Present (Elmt) loop
               Prim := Node (Elmt);

               if Comes_From_Source (Prim) then
                  if Is_Abstract_Subprogram (Prim) then
                     null;

                  elsif not Is_Imported (Prim)
                    or else Convention (Prim) /= Convention_CPP
                  then
                     Error_Msg_N
                       ("primitives of 'C'P'P types must be imported from C++ "
                        & "or abstract??", Prim);

                  elsif not Has_Constructors
                     and then not Error_Reported
                  then
                     Error_Msg_Name_1 := Chars (E);
                     Error_Msg_N
                       ("??'C'P'P constructor required for type %", Prim);
                     Error_Reported := True;
                  end if;
               end if;

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

      --  Check Ada derivation of CPP type

      if Expander_Active              -- why? losing errors in -gnatc mode???
        and then Present (Etype (E))  -- defend against errors
        and then Tagged_Type_Expansion
        and then Ekind (E) = E_Record_Type
        and then Etype (E) /= E
        and then Is_CPP_Class (Etype (E))
        and then CPP_Num_Prims (Etype (E)) > 0
        and then not Is_CPP_Class (E)
        and then not Has_CPP_Constructors (Etype (E))
      then
         --  If the parent has C++ primitives but it has no constructor then
         --  check that all the primitives are overridden in this derivation;
         --  otherwise the constructor of the parent is needed to build the
         --  dispatch table.

         declare
            Elmt : Elmt_Id;
            Prim : Node_Id;

         begin
            Elmt := First_Elmt (Primitive_Operations (E));
            while Present (Elmt) loop
               Prim := Node (Elmt);

               if not Is_Abstract_Subprogram (Prim)
                 and then No (Interface_Alias (Prim))
                 and then Find_Dispatching_Type (Ultimate_Alias (Prim)) /= E
               then
                  Error_Msg_Name_1 := Chars (Etype (E));
                  Error_Msg_N
                    ("'C'P'P constructor required for parent type %", E);
                  exit;
               end if;

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

      Inside_Freezing_Actions := Inside_Freezing_Actions - 1;

      --  If we have a type with predicates, build predicate function. This is
      --  not needed in the generic case, nor within e.g. TSS subprograms and
      --  other predefined primitives. For a derived type, ensure that the
      --  parent type is already frozen so that its predicate function has been
      --  constructed already. This is necessary if the parent is declared
      --  in a nested package and its own freeze point has not been reached.

      if Is_Type (E)
        and then Nongeneric_Case
        and then Has_Predicates (E)
        and then Predicate_Check_In_Scope (N)
      then
         declare
            Atyp : constant Entity_Id := Nearest_Ancestor (E);
         begin
            if Present (Atyp)
              and then Has_Predicates (Atyp)
              and then not Is_Frozen (Atyp)
            then
               Freeze_Before (N, Atyp);
            end if;
         end;

         Build_Predicate_Functions (E, N);
      end if;

      --  If type has delayed aspects, this is where we do the preanalysis at
      --  the freeze point, as part of the consistent visibility check. Note
      --  that this must be done after calling Build_Predicate_Functions or
      --  Build_Invariant_Procedure since these subprograms fix occurrences of
      --  the subtype name in the saved expression so that they will not cause
      --  trouble in the preanalysis.

      --  This is also not needed in the generic case

      if Nongeneric_Case
        and then Has_Delayed_Aspects (E)
        and then Scope (E) = Current_Scope
      then
         declare
            Ritem : Node_Id;

         begin
            --  Look for aspect specification entries for this entity

            Ritem := First_Rep_Item (E);
            while Present (Ritem) loop
               if Nkind (Ritem) = N_Aspect_Specification
                 and then Entity (Ritem) = E
                 and then Is_Delayed_Aspect (Ritem)
               then
                  if Get_Aspect_Id (Ritem) in Aspect_CPU
                                            | Aspect_Dynamic_Predicate
                                            | Aspect_Predicate
                                            | Aspect_Static_Predicate
                                            | Aspect_Priority
                  then
                    --  Retrieve the visibility to components and discriminants
                    --  in order to properly analyze the aspects.

                     Push_Type (E);
                     Check_Aspect_At_Freeze_Point (Ritem);

                     --  In the case of predicate aspects, there will be
                     --  a corresponding Predicate pragma associated with
                     --  the aspect, and the expression of the pragma also
                     --  needs to be analyzed at this point, to ensure that
                     --  Save_Global_References will capture global refs in
                     --  expressions that occur in generic bodies, for proper
                     --  later resolution of the pragma in instantiations.

                     if Is_Type (E)
                       and then Inside_A_Generic
                       and then Has_Predicates (E)
                       and then Present (Aspect_Rep_Item (Ritem))
                     then
                        declare
                           Pragma_Args : constant List_Id :=
                             Pragma_Argument_Associations
                               (Aspect_Rep_Item (Ritem));
                           Pragma_Expr : constant Node_Id :=
                             Expression (Next (First (Pragma_Args)));
                        begin
                           if Present (Pragma_Expr) then
                              Analyze_And_Resolve
                                (Pragma_Expr, Standard_Boolean);
                           end if;
                        end;
                     end if;

                     Pop_Type (E);

                  else
                     Check_Aspect_At_Freeze_Point (Ritem);
                  end if;

               --  A pragma Predicate should be checked like one of the
               --  corresponding aspects, wrt possible misuse of ghost
               --  entities.

               elsif Nkind (Ritem) = N_Pragma
                 and then No (Corresponding_Aspect (Ritem))
                 and then
                   Get_Pragma_Id (Pragma_Name (Ritem)) = Pragma_Predicate
               then
                  --  Retrieve the visibility to components and discriminants
                  --  in order to properly analyze the pragma.

                  declare
                     Arg : constant Node_Id :=
                        Next (First (Pragma_Argument_Associations (Ritem)));
                  begin
                     Push_Type (E);
                     Preanalyze_Spec_Expression
                       (Expression (Arg), Standard_Boolean);
                     Pop_Type (E);
                  end;
               end if;

               Next_Rep_Item (Ritem);
            end loop;
         end;

      end if;

      --  For a record type, deal with variant parts. This has to be delayed to
      --  this point, because of the issue of statically predicated subtypes,
      --  which we have to ensure are frozen before checking choices, since we
      --  need to have the static choice list set.

      if Is_Record_Type (E) then
         Check_Variant_Part : declare
            D  : constant Node_Id := Declaration_Node (E);
            T  : Node_Id;
            C  : Node_Id;
            VP : Node_Id;

            Others_Present : Boolean;
            pragma Warnings (Off, Others_Present);
            --  Indicates others present, not used in this case

            procedure Non_Static_Choice_Error (Choice : Node_Id);
            --  Error routine invoked by the generic instantiation below when
            --  the variant part has a non static choice.

            procedure Process_Declarations (Variant : Node_Id);
            --  Processes declarations associated with a variant. We analyzed
            --  the declarations earlier (in Sem_Ch3.Analyze_Variant_Part),
            --  but we still need the recursive call to Check_Choices for any
            --  nested variant to get its choices properly processed. This is
            --  also where we expand out the choices if expansion is active.

            package Variant_Choices_Processing is new
              Generic_Check_Choices
                (Process_Empty_Choice      => No_OP,
                 Process_Non_Static_Choice => Non_Static_Choice_Error,
                 Process_Associated_Node   => Process_Declarations);
            use Variant_Choices_Processing;

            -----------------------------
            -- Non_Static_Choice_Error --
            -----------------------------

            procedure Non_Static_Choice_Error (Choice : Node_Id) is
            begin
               Flag_Non_Static_Expr
                 ("choice given in variant part is not static!", Choice);
            end Non_Static_Choice_Error;

            --------------------------
            -- Process_Declarations --
            --------------------------

            procedure Process_Declarations (Variant : Node_Id) is
               CL : constant Node_Id := Component_List (Variant);
               VP : Node_Id;

            begin
               --  Check for static predicate present in this variant

               if Has_SP_Choice (Variant) then

                  --  Here we expand. You might expect to find this call in
                  --  Expand_N_Variant_Part, but that is called when we first
                  --  see the variant part, and we cannot do this expansion
                  --  earlier than the freeze point, since for statically
                  --  predicated subtypes, the predicate is not known till
                  --  the freeze point.

                  --  Furthermore, we do this expansion even if the expander
                  --  is not active, because other semantic processing, e.g.
                  --  for aggregates, requires the expanded list of choices.

                  --  If the expander is not active, then we can't just clobber
                  --  the list since it would invalidate the tree.
                  --  So we have to rewrite the variant part with a Rewrite
                  --  call that replaces it with a copy and clobber the copy.

                  if not Expander_Active then
                     declare
                        NewV : constant Node_Id := New_Copy (Variant);
                     begin
                        Set_Discrete_Choices
                          (NewV, New_Copy_List (Discrete_Choices (Variant)));
                        Rewrite (Variant, NewV);
                     end;
                  end if;

                  Expand_Static_Predicates_In_Choices (Variant);
               end if;

               --  We don't need to worry about the declarations in the variant
               --  (since they were analyzed by Analyze_Choices when we first
               --  encountered the variant), but we do need to take care of
               --  expansion of any nested variants.

               if not Null_Present (CL) then
                  VP := Variant_Part (CL);

                  if Present (VP) then
                     Check_Choices
                       (VP, Variants (VP), Etype (Name (VP)), Others_Present);
                  end if;
               end if;
            end Process_Declarations;

         --  Start of processing for Check_Variant_Part

         begin
            --  Find component list

            C := Empty;

            if Nkind (D) = N_Full_Type_Declaration then
               T := Type_Definition (D);

               if Nkind (T) = N_Record_Definition then
                  C := Component_List (T);

               elsif Nkind (T) = N_Derived_Type_Definition
                 and then Present (Record_Extension_Part (T))
               then
                  C := Component_List (Record_Extension_Part (T));
               end if;
            end if;

            --  Case of variant part present

            if Present (C) and then Present (Variant_Part (C)) then
               VP := Variant_Part (C);

               --  Check choices

               Check_Choices
                 (VP, Variants (VP), Etype (Name (VP)), Others_Present);

               --  If the last variant does not contain the Others choice,
               --  replace it with an N_Others_Choice node since Gigi always
               --  wants an Others. Note that we do not bother to call Analyze
               --  on the modified variant part, since its only effect would be
               --  to compute the Others_Discrete_Choices node laboriously, and
               --  of course we already know the list of choices corresponding
               --  to the others choice (it's the list we're replacing).

               --  We only want to do this if the expander is active, since
               --  we do not want to clobber the tree.

               if Expander_Active then
                  declare
                     Last_Var : constant Node_Id :=
                                     Last_Non_Pragma (Variants (VP));

                     Others_Node : Node_Id;

                  begin
                     if Nkind (First (Discrete_Choices (Last_Var))) /=
                                                            N_Others_Choice
                     then
                        Others_Node := Make_Others_Choice (Sloc (Last_Var));
                        Set_Others_Discrete_Choices
                          (Others_Node, Discrete_Choices (Last_Var));
                        Set_Discrete_Choices
                          (Last_Var, New_List (Others_Node));
                     end if;
                  end;
               end if;
            end if;
         end Check_Variant_Part;
      end if;

      if not In_Generic_Scope (E)
        and then Ekind (E) = E_Record_Type
        and then Is_Tagged_Type (E)
      then
         Process_Class_Conditions_At_Freeze_Point (E);
      end if;
   end Freeze_Entity_Checks;

   -------------------------
   -- Get_Alignment_Value --
   -------------------------

   function Get_Alignment_Value (Expr : Node_Id) return Uint is
      Align : constant Uint := Static_Integer (Expr);

   begin
      if No (Align) then
         return No_Uint;

      elsif Align < 0 then
         Error_Msg_N ("alignment value must be positive", Expr);
         return No_Uint;

      --  If Alignment is specified to be 0, we treat it the same as 1

      elsif Align = 0 then
         return Uint_1;

      else
         for J in Int range 0 .. 64 loop
            declare
               M : constant Uint := Uint_2 ** J;

            begin
               exit when M = Align;

               if M > Align then
                  Error_Msg_N ("alignment value must be power of 2", Expr);
                  return No_Uint;
               end if;
            end;
         end loop;

         return Align;
      end if;
   end Get_Alignment_Value;

   -----------------------------------
   -- Has_Compatible_Representation --
   -----------------------------------

   function Has_Compatible_Representation
     (Target_Type, Operand_Type : Entity_Id) return Boolean
   is
      T1 : constant Entity_Id := Underlying_Type (Target_Type);
      T2 : constant Entity_Id := Underlying_Type (Operand_Type);

   begin
      --  A quick check, if base types are the same, then we definitely have
      --  the same representation, because the subtype specific representation
      --  attributes (Size and Alignment) do not affect representation from
      --  the point of view of this test.

      if Base_Type (T1) = Base_Type (T2) then
         return True;

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

      --  If T2 is a generic actual it is declared as a subtype, so
      --  check against its base type.

      elsif Is_Generic_Actual_Type (T1)
        and then Has_Compatible_Representation (Base_Type (T1), T2)
      then
         return True;
      end if;

      --  Tagged types always have the same representation, because it is not
      --  possible to specify different representations for common fields.

      if Is_Tagged_Type (T1) then
         return True;
      end if;

      --  Representations are definitely different if conventions differ

      if Convention (T1) /= Convention (T2) then
         return False;
      end if;

      --  Representations are different if component alignments or scalar
      --  storage orders differ.

      if (Is_Record_Type (T1) or else Is_Array_Type (T1))
            and then
         (Is_Record_Type (T2) or else Is_Array_Type (T2))
        and then
         (Component_Alignment (T1) /= Component_Alignment (T2)
           or else Reverse_Storage_Order (T1) /= Reverse_Storage_Order (T2))
      then
         return False;
      end if;

      --  For arrays, the only real issue is component size. If we know the
      --  component size for both arrays, and it is the same, then that's
      --  good enough to know we don't have a change of representation.

      if Is_Array_Type (T1) then

         --  In a view conversion, if the target type is an array type having
         --  aliased components and the operand type is an array type having
         --  unaliased components, then a new object is created (4.6(58.3/4)).

         if Has_Aliased_Components (T1)
           and then not Has_Aliased_Components (T2)
         then
            return False;
         end if;

         if Known_Component_Size (T1)
           and then Known_Component_Size (T2)
           and then Component_Size (T1) = Component_Size (T2)
         then
            return True;
         end if;
      end if;

      --  For records, representations are different if reorderings differ

      if Is_Record_Type (T1)
        and then Is_Record_Type (T2)
        and then No_Reordering (T1) /= No_Reordering (T2)
      then
         return False;
      end if;

      --  Types definitely have same representation if neither has non-standard
      --  representation since default representations are always consistent.
      --  If only one has non-standard representation, and the other does not,
      --  then we consider that they do not have the same representation. They
      --  might, but there is no way of telling early enough.

      if Has_Non_Standard_Rep (T1) then
         if not Has_Non_Standard_Rep (T2) then
            return False;
         end if;
      else
         return not Has_Non_Standard_Rep (T2);
      end if;

      --  Here the two types both have non-standard representation, and we need
      --  to determine if they have the same non-standard representation.

      --  For arrays, we simply need to test if the component sizes are the
      --  same. Pragma Pack is reflected in modified component sizes, so this
      --  check also deals with pragma Pack.

      if Is_Array_Type (T1) then
         return Component_Size (T1) = Component_Size (T2);

      --  Case of record types

      elsif Is_Record_Type (T1) then

         --  Packed status must conform

         if Is_Packed (T1) /= Is_Packed (T2) then
            return False;

         --  Otherwise we must check components. Typ2 maybe a constrained
         --  subtype with fewer components, so we compare the components
         --  of the base types.

         else
            Record_Case : declare
               CD1, CD2 : Entity_Id;

               function Same_Rep return Boolean;
               --  CD1 and CD2 are either components or discriminants. This
               --  function tests whether they have the same representation.

               --------------
               -- Same_Rep --
               --------------

               function Same_Rep return Boolean is
               begin
                  if No (Component_Clause (CD1)) then
                     return No (Component_Clause (CD2));
                  else
                     --  Note: at this point, component clauses have been
                     --  normalized to the default bit order, so that the
                     --  comparison of Component_Bit_Offsets is meaningful.

                     return
                        Present (Component_Clause (CD2))
                          and then
                        Component_Bit_Offset (CD1) = Component_Bit_Offset (CD2)
                          and then
                        Esize (CD1) = Esize (CD2);
                  end if;
               end Same_Rep;

            --  Start of processing for Record_Case

            begin
               if Has_Discriminants (T1) then

                  --  The number of discriminants may be different if the
                  --  derived type has fewer (constrained by values). The
                  --  invisible discriminants retain the representation of
                  --  the original, so the discrepancy does not per se
                  --  indicate a different representation.

                  CD1 := First_Discriminant (T1);
                  CD2 := First_Discriminant (T2);
                  while Present (CD1) and then Present (CD2) loop
                     if not Same_Rep then
                        return False;
                     else
                        Next_Discriminant (CD1);
                        Next_Discriminant (CD2);
                     end if;
                  end loop;
               end if;

               CD1 := First_Component (Underlying_Type (Base_Type (T1)));
               CD2 := First_Component (Underlying_Type (Base_Type (T2)));
               while Present (CD1) loop
                  if not Same_Rep then
                     return False;
                  else
                     Next_Component (CD1);
                     Next_Component (CD2);
                  end if;
               end loop;

               return True;
            end Record_Case;
         end if;

      --  For enumeration types, we must check each literal to see if the
      --  representation is the same. Note that we do not permit enumeration
      --  representation clauses for Character and Wide_Character, so these
      --  cases were already dealt with.

      elsif Is_Enumeration_Type (T1) then
         Enumeration_Case : declare
            L1, L2 : Entity_Id;

         begin
            L1 := First_Literal (T1);
            L2 := First_Literal (T2);
            while Present (L1) loop
               if Enumeration_Rep (L1) /= Enumeration_Rep (L2) then
                  return False;
               else
                  Next_Literal (L1);
                  Next_Literal (L2);
               end if;
            end loop;

            return True;
         end Enumeration_Case;

      --  Any other types have the same representation for these purposes

      else
         return True;
      end if;
   end Has_Compatible_Representation;

   -------------------------------------
   -- Inherit_Aspects_At_Freeze_Point --
   -------------------------------------

   procedure Inherit_Aspects_At_Freeze_Point (Typ : Entity_Id) is
      function Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
        (Rep_Item : Node_Id) return Boolean;
      --  This routine checks if Rep_Item is either a pragma or an aspect
      --  specification node whose corresponding pragma (if any) is present in
      --  the Rep Item chain of the entity it has been specified to.

      --------------------------------------------------
      -- Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item --
      --------------------------------------------------

      function Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
        (Rep_Item : Node_Id) return Boolean
      is
      begin
         return
           Nkind (Rep_Item) = N_Pragma
             or else
           Present_In_Rep_Item (Entity (Rep_Item), Aspect_Rep_Item (Rep_Item));
      end Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item;

   --  Start of processing for Inherit_Aspects_At_Freeze_Point

   begin
      --  A representation item is either subtype-specific (Size and Alignment
      --  clauses) or type-related (all others). Subtype-specific aspects may
      --  differ for different subtypes of the same type (RM 13.1.8).

      --  A derived type inherits each type-related representation aspect of
      --  its parent type that was directly specified before the declaration of
      --  the derived type (RM 13.1.15).

      --  A derived subtype inherits each subtype-specific representation
      --  aspect of its parent subtype that was directly specified before the
      --  declaration of the derived type (RM 13.1.15).

      --  The general processing involves inheriting a representation aspect
      --  from a parent type whenever the first rep item (aspect specification,
      --  attribute definition clause, pragma) corresponding to the given
      --  representation aspect in the rep item chain of Typ, if any, isn't
      --  directly specified to Typ but to one of its parents.

      --  ??? Note that, for now, just a limited number of representation
      --  aspects have been inherited here so far. Many of them are
      --  still inherited in Sem_Ch3. This will be fixed soon. Here is
      --  a non- exhaustive list of aspects that likely also need to
      --  be moved to this routine: Alignment, Component_Alignment,
      --  Component_Size, Machine_Radix, Object_Size, Pack, Predicates,
      --  Preelaborable_Initialization, RM_Size and Small.

      --  In addition, Convention must be propagated from base type to subtype,
      --  because the subtype may have been declared on an incomplete view.

      if Nkind (Parent (Typ)) = N_Private_Extension_Declaration then
         return;
      end if;

      --  Ada_05/Ada_2005

      if not Has_Rep_Item (Typ, Name_Ada_05, Name_Ada_2005, False)
        and then Has_Rep_Item (Typ, Name_Ada_05, Name_Ada_2005)
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Ada_05, Name_Ada_2005))
      then
         Set_Is_Ada_2005_Only (Typ);
      end if;

      --  Ada_12/Ada_2012

      if not Has_Rep_Item (Typ, Name_Ada_12, Name_Ada_2012, False)
        and then Has_Rep_Item (Typ, Name_Ada_12, Name_Ada_2012)
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Ada_12, Name_Ada_2012))
      then
         Set_Is_Ada_2012_Only (Typ);
      end if;

      --  Ada_2022

      if not Has_Rep_Item (Typ, Name_Ada_2022, False)
        and then Has_Rep_Item (Typ, Name_Ada_2022)
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Ada_2022))
      then
         Set_Is_Ada_2022_Only (Typ);
      end if;

      --  Atomic/Shared

      if not Has_Rep_Item (Typ, Name_Atomic, Name_Shared, False)
        and then Has_Rep_Pragma (Typ, Name_Atomic, Name_Shared)
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Atomic, Name_Shared))
      then
         Set_Is_Atomic (Typ);
         Set_Is_Volatile (Typ);
         Set_Treat_As_Volatile (Typ);
      end if;

      --  Convention

      if Is_Record_Type (Typ)
        and then Typ /= Base_Type (Typ) and then Is_Frozen (Base_Type (Typ))
      then
         Set_Convention (Typ, Convention (Base_Type (Typ)));
      end if;

      --  Default_Component_Value

      --  Verify that there is no rep_item declared for the type, and there
      --  is one coming from an ancestor.

      if Is_Array_Type (Typ)
        and then Is_Base_Type (Typ)
        and then not Has_Rep_Item (Typ, Name_Default_Component_Value, False)
        and then Has_Rep_Item (Typ, Name_Default_Component_Value)
      then
         Set_Default_Aspect_Component_Value (Typ,
           Default_Aspect_Component_Value
             (Entity (Get_Rep_Item (Typ, Name_Default_Component_Value))));
      end if;

      --  Default_Value

      if Is_Scalar_Type (Typ)
        and then Is_Base_Type (Typ)
        and then not Has_Rep_Item (Typ, Name_Default_Value, False)
        and then Has_Rep_Item (Typ, Name_Default_Value)
      then
         Set_Has_Default_Aspect (Typ);
         Set_Default_Aspect_Value (Typ,
           Default_Aspect_Value
             (Entity (Get_Rep_Item (Typ, Name_Default_Value))));
      end if;

      --  Discard_Names

      if not Has_Rep_Item (Typ, Name_Discard_Names, False)
        and then Has_Rep_Item (Typ, Name_Discard_Names)
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Discard_Names))
      then
         Set_Discard_Names (Typ);
      end if;

      --  Volatile

      if not Has_Rep_Item (Typ, Name_Volatile, False)
        and then Has_Rep_Item (Typ, Name_Volatile)
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Volatile))
      then
         Set_Is_Volatile (Typ);
         Set_Treat_As_Volatile (Typ);
      end if;

      --  Volatile_Full_Access and Full_Access_Only

      if not Has_Rep_Item (Typ, Name_Volatile_Full_Access, False)
        and then not Has_Rep_Item (Typ, Name_Full_Access_Only, False)
        and then (Has_Rep_Item (Typ, Name_Volatile_Full_Access)
                    or else Has_Rep_Item (Typ, Name_Full_Access_Only))
        and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Volatile_Full_Access))
      then
         Set_Is_Volatile_Full_Access (Typ);
         Set_Is_Volatile (Typ);
         Set_Treat_As_Volatile (Typ);
      end if;

      --  Inheritance for derived types only

      if Is_Derived_Type (Typ) then
         declare
            Bas_Typ     : constant Entity_Id := Base_Type (Typ);
            Imp_Bas_Typ : constant Entity_Id := Implementation_Base_Type (Typ);

         begin
            --  Atomic_Components

            if not Has_Rep_Item (Typ, Name_Atomic_Components, False)
              and then Has_Rep_Item (Typ, Name_Atomic_Components)
              and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Atomic_Components))
            then
               Set_Has_Atomic_Components (Imp_Bas_Typ);
            end if;

            --  Volatile_Components

            if not Has_Rep_Item (Typ, Name_Volatile_Components, False)
              and then Has_Rep_Item (Typ, Name_Volatile_Components)
              and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Volatile_Components))
            then
               Set_Has_Volatile_Components (Imp_Bas_Typ);
            end if;

            --  Finalize_Storage_Only

            if not Has_Rep_Pragma (Typ, Name_Finalize_Storage_Only, False)
              and then Has_Rep_Pragma (Typ, Name_Finalize_Storage_Only)
            then
               Set_Finalize_Storage_Only (Bas_Typ);
            end if;

            --  Universal_Aliasing

            if not Has_Rep_Item (Typ, Name_Universal_Aliasing, False)
              and then Has_Rep_Item (Typ, Name_Universal_Aliasing)
              and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
                   (Get_Rep_Item (Typ, Name_Universal_Aliasing))
            then
               Set_Universal_Aliasing (Imp_Bas_Typ);
            end if;

            --  Bit_Order

            if Is_Record_Type (Typ) and then Typ = Bas_Typ then
               if not Has_Rep_Item (Typ, Name_Bit_Order, False)
                 and then Has_Rep_Item (Typ, Name_Bit_Order)
               then
                  Set_Reverse_Bit_Order (Bas_Typ,
                    Reverse_Bit_Order
                      (Implementation_Base_Type (Etype (Bas_Typ))));
               end if;
            end if;

            --  Scalar_Storage_Order

            if (Is_Record_Type (Typ) or else Is_Array_Type (Typ))
              and then Typ = Bas_Typ
            then
               --  For a type extension, always inherit from parent; otherwise
               --  inherit if no default applies. Note: we do not check for
               --  an explicit rep item on the parent type when inheriting,
               --  because the parent SSO may itself have been set by default.

               if not Has_Rep_Item (First_Subtype (Typ),
                                    Name_Scalar_Storage_Order, False)
                 and then (Is_Tagged_Type (Bas_Typ)
                            or else not (SSO_Set_Low_By_Default  (Bas_Typ)
                                           or else
                                         SSO_Set_High_By_Default (Bas_Typ)))
               then
                  Set_Reverse_Storage_Order (Bas_Typ,
                    Reverse_Storage_Order
                      (Implementation_Base_Type (Etype (Bas_Typ))));

                  --  Clear default SSO indications, since the inherited aspect
                  --  which was set explicitly overrides the default.

                  Set_SSO_Set_Low_By_Default  (Bas_Typ, False);
                  Set_SSO_Set_High_By_Default (Bas_Typ, False);
               end if;
            end if;
         end;
      end if;
   end Inherit_Aspects_At_Freeze_Point;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      Address_Clause_Checks.Init;
      Unchecked_Conversions.Init;

      --  The following might be needed in the future for some non-GCC back
      --  ends:
      --  if AAMP_On_Target then
      --     Independence_Checks.Init;
      --  end if;
   end Initialize;

   ---------------------------
   -- Install_Discriminants --
   ---------------------------

   procedure Install_Discriminants (E : Entity_Id) is
      Disc : Entity_Id;
      Prev : Entity_Id;
   begin
      Disc := First_Discriminant (E);
      while Present (Disc) loop
         Prev := Current_Entity (Disc);
         Set_Current_Entity (Disc);
         Set_Is_Immediately_Visible (Disc);
         Set_Homonym (Disc, Prev);
         Next_Discriminant (Disc);
      end loop;
   end Install_Discriminants;

   -------------------------
   -- Is_Operational_Item --
   -------------------------

   function Is_Operational_Item (N : Node_Id) return Boolean is
   begin
      --  List of operational items is given in AARM 13.1(8.mm/1). It is
      --  clearly incomplete, as it does not include iterator aspects, among
      --  others.

      return Nkind (N) = N_Attribute_Definition_Clause
          and then
        Get_Attribute_Id (Chars (N)) in Attribute_Constant_Indexing
                                      | Attribute_External_Tag
                                      | Attribute_Default_Iterator
                                      | Attribute_Implicit_Dereference
                                      | Attribute_Input
                                      | Attribute_Iterable
                                      | Attribute_Iterator_Element
                                      | Attribute_Output
                                      | Attribute_Put_Image
                                      | Attribute_Read
                                      | Attribute_Variable_Indexing
                                      | Attribute_Write;
   end Is_Operational_Item;

   -------------------------
   -- Is_Predicate_Static --
   -------------------------

   --  Note: the basic legality of the expression has already been checked, so
   --  we don't need to worry about cases or ranges on strings for example.

   function Is_Predicate_Static
     (Expr : Node_Id;
      Nam  : Name_Id) return Boolean
   is
      function All_Static_Case_Alternatives (L : List_Id) return Boolean;
      --  Given a list of case expression alternatives, returns True if all
      --  the alternatives are static (have all static choices, and a static
      --  expression).

      function Is_Type_Ref (N : Node_Id) return Boolean;
      pragma Inline (Is_Type_Ref);
      --  Returns True if N is a reference to the type for the predicate in the
      --  expression (i.e. if it is an identifier whose Chars field matches the
      --  Nam given in the call). N must not be parenthesized, if the type name
      --  appears in parens, this routine will return False.
      --
      --  The routine also returns True for function calls generated during the
      --  expansion of comparison operators on strings, which are intended to
      --  be legal in static predicates, and are converted into calls to array
      --  comparison routines in the body of the corresponding predicate
      --  function.

      ----------------------------------
      -- All_Static_Case_Alternatives --
      ----------------------------------

      function All_Static_Case_Alternatives (L : List_Id) return Boolean is
         N : Node_Id;

      begin
         N := First (L);
         while Present (N) loop
            if not (All_Static_Choices (Discrete_Choices (N))
                     and then Is_OK_Static_Expression (Expression (N)))
            then
               return False;
            end if;

            Next (N);
         end loop;

         return True;
      end All_Static_Case_Alternatives;

      -----------------
      -- Is_Type_Ref --
      -----------------

      function Is_Type_Ref (N : Node_Id) return Boolean is
      begin
         return (Nkind (N) = N_Identifier
                  and then Chars (N) = Nam
                  and then Paren_Count (N) = 0)
           or else Nkind (N) = N_Function_Call;
      end Is_Type_Ref;

   --  Start of processing for Is_Predicate_Static

   begin
      --  Predicate_Static means one of the following holds. Numbers are the
      --  corresponding paragraph numbers in (RM 3.2.4(16-22)).

      --  16: A static expression

      if Is_OK_Static_Expression (Expr) then
         return True;

      --  17: A membership test whose simple_expression is the current
      --  instance, and whose membership_choice_list meets the requirements
      --  for a static membership test.

      elsif Nkind (Expr) in N_Membership_Test
        and then All_Membership_Choices_Static (Expr)
      then
         return True;

      --  18. A case_expression whose selecting_expression is the current
      --  instance, and whose dependent expressions are static expressions.

      elsif Nkind (Expr) = N_Case_Expression
        and then Is_Type_Ref (Expression (Expr))
        and then All_Static_Case_Alternatives (Alternatives (Expr))
      then
         return True;

      --  19. A call to a predefined equality or ordering operator, where one
      --  operand is the current instance, and the other is a static
      --  expression.

      --  Note: the RM is clearly wrong here in not excluding string types.
      --  Without this exclusion, we would allow expressions like X > "ABC"
      --  to be considered as predicate-static, which is clearly not intended,
      --  since the idea is for predicate-static to be a subset of normal
      --  static expressions (and "DEF" > "ABC" is not a static expression).

      --  However, we do allow internally generated (not from source) equality
      --  and inequality operations to be valid on strings (this helps deal
      --  with cases where we transform A in "ABC" to A = "ABC).

      --  In fact, it appears that the intent of the ARG is to extend static
      --  predicates to strings, and that the extension should probably apply
      --  to static expressions themselves. The code below accepts comparison
      --  operators that apply to static strings.

      elsif Nkind (Expr) in N_Op_Compare
        and then ((Is_Type_Ref (Left_Opnd (Expr))
                    and then Is_OK_Static_Expression (Right_Opnd (Expr)))
                  or else
                    (Is_Type_Ref (Right_Opnd (Expr))
                      and then Is_OK_Static_Expression (Left_Opnd (Expr))))
      then
         return True;

      --  20. A call to a predefined boolean logical operator, where each
      --  operand is predicate-static.

      elsif (Nkind (Expr) in N_Op_And | N_Op_Or | N_Op_Xor
              and then Is_Predicate_Static (Left_Opnd (Expr), Nam)
              and then Is_Predicate_Static (Right_Opnd (Expr), Nam))
        or else
            (Nkind (Expr) = N_Op_Not
              and then Is_Predicate_Static (Right_Opnd (Expr), Nam))
      then
         return True;

      --  21. A short-circuit control form where both operands are
      --  predicate-static.

      elsif Nkind (Expr) in N_Short_Circuit
        and then Is_Predicate_Static (Left_Opnd (Expr), Nam)
        and then Is_Predicate_Static (Right_Opnd (Expr), Nam)
      then
         return True;

      --  22. A parenthesized predicate-static expression. This does not
      --  require any special test, since we just ignore paren levels in
      --  all the cases above.

      --  One more test that is an implementation artifact caused by the fact
      --  that we are analyzing not the original expression, but the generated
      --  expression in the body of the predicate function. This can include
      --  references to inherited predicates, so that the expression we are
      --  processing looks like:

      --    xxPredicate (typ (Inns)) and then expression

      --  Where the call is to a Predicate function for an inherited predicate.
      --  We simply ignore such a call, which could be to either a dynamic or
      --  a static predicate. Note that if the parent predicate is dynamic then
      --  eventually this type will be marked as dynamic, but you are allowed
      --  to specify a static predicate for a subtype which is inheriting a
      --  dynamic predicate, so the static predicate validation here ignores
      --  the inherited predicate even if it is dynamic.
      --  In all cases, a static predicate can only apply to a scalar type.

      elsif Nkind (Expr) = N_Function_Call
        and then Is_Predicate_Function (Entity (Name (Expr)))
        and then Is_Scalar_Type (Etype (First_Entity (Entity (Name (Expr)))))
      then
         return True;

      elsif Is_Entity_Name (Expr)
        and then Entity (Expr) = Standard_True
      then
         Error_Msg_N ("predicate is redundant (always True)?", Expr);
         return True;

      --  That's an exhaustive list of tests, all other cases are not
      --  predicate-static, so we return False.

      else
         return False;
      end if;
   end Is_Predicate_Static;

   ----------------------
   -- Is_Static_Choice --
   ----------------------

   function Is_Static_Choice (N : Node_Id) return Boolean is
   begin
      return Nkind (N) = N_Others_Choice
        or else Is_OK_Static_Expression (N)
        or else (Is_Entity_Name (N) and then Is_Type (Entity (N))
                  and then Is_OK_Static_Subtype (Entity (N)))
        or else (Nkind (N) = N_Subtype_Indication
                  and then Is_OK_Static_Subtype (Entity (N)))
        or else (Nkind (N) = N_Range and then Is_OK_Static_Range (N));
   end Is_Static_Choice;

   ------------------------------
   -- Is_Type_Related_Rep_Item --
   ------------------------------

   function Is_Type_Related_Rep_Item (N : Node_Id) return Boolean is
   begin
      case Nkind (N) is
         when N_Attribute_Definition_Clause =>
            --  See AARM 13.1(8.f-8.x) list items that end in "clause"
            --  ???: include any GNAT-defined attributes here?
            return Get_Attribute_Id (Chars (N)) in Attribute_Bit_Order
                                                 | Attribute_Component_Size
                                                 | Attribute_Machine_Radix
                                                 | Attribute_Storage_Pool
                                                 | Attribute_Stream_Size;

         when N_Pragma =>
            case Get_Pragma_Id (N) is
               --  See AARM 13.1(8.f-8.x) list items that start with "pragma"
               --  ???: include any GNAT-defined pragmas here?
               when Pragma_Pack
                  | Pragma_Import
                  | Pragma_Export
                  | Pragma_Convention
                  | Pragma_Atomic
                  | Pragma_Independent
                  | Pragma_Volatile
                  | Pragma_Atomic_Components
                  | Pragma_Independent_Components
                  | Pragma_Volatile_Components
                  | Pragma_Discard_Names
               =>
                  return True;
               when others =>
                  null;
            end case;

         when N_Enumeration_Representation_Clause
            | N_Record_Representation_Clause
         =>
            return True;

         when others =>
            null;
      end case;

      return False;
   end Is_Type_Related_Rep_Item;

   ---------------------
   -- Kill_Rep_Clause --
   ---------------------

   procedure Kill_Rep_Clause (N : Node_Id) is
   begin
      pragma Assert (Ignore_Rep_Clauses);

      --  Note: we use Replace rather than Rewrite, because we don't want
      --  tools to be able to use Original_Node to dig out the (undecorated)
      --  rep clause that is being replaced.

      Replace (N, Make_Null_Statement (Sloc (N)));

      --  The null statement must be marked as not coming from source. This is
      --  so that tools ignore it, and also the back end does not expect bogus
      --  "from source" null statements in weird places (e.g. in declarative
      --  regions where such null statements are not allowed).

      Set_Comes_From_Source (N, False);
   end Kill_Rep_Clause;

   ------------------
   -- Minimum_Size --
   ------------------

   function Minimum_Size
     (T      : Entity_Id;
      Biased : Boolean := False) return Int
   is
      Lo     : Uint    := No_Uint;
      Hi     : Uint    := No_Uint;
      LoR    : Ureal   := No_Ureal;
      HiR    : Ureal   := No_Ureal;
      LoSet  : Boolean := False;
      HiSet  : Boolean := False;
      B      : Uint;
      S      : Nat;
      Ancest : Entity_Id;
      R_Typ  : constant Entity_Id := Root_Type (T);

   begin
      --  Bad type

      if T = Any_Type then
         return Unknown_Minimum_Size;

      --  For generic types, just return unknown. There cannot be any
      --  legitimate need to know such a size, but this routine may be
      --  called with a generic type as part of normal processing.

      elsif Is_Generic_Type (R_Typ) or else R_Typ = Any_Type then
         return Unknown_Minimum_Size;

         --  Access types (cannot have size smaller than System.Address)

      elsif Is_Access_Type (T) then
         return System_Address_Size;

      --  Floating-point types

      elsif Is_Floating_Point_Type (T) then
         return UI_To_Int (Esize (R_Typ));

      --  Discrete types

      elsif Is_Discrete_Type (T) then

         --  The following loop is looking for the nearest compile time known
         --  bounds following the ancestor subtype chain. The idea is to find
         --  the most restrictive known bounds information.

         Ancest := T;
         loop
            if Ancest = Any_Type or else Etype (Ancest) = Any_Type then
               return Unknown_Minimum_Size;
            end if;

            if not LoSet then
               if Compile_Time_Known_Value (Type_Low_Bound (Ancest)) then
                  Lo := Expr_Rep_Value (Type_Low_Bound (Ancest));
                  LoSet := True;
                  exit when HiSet;
               end if;
            end if;

            if not HiSet then
               if Compile_Time_Known_Value (Type_High_Bound (Ancest)) then
                  Hi := Expr_Rep_Value (Type_High_Bound (Ancest));
                  HiSet := True;
                  exit when LoSet;
               end if;
            end if;

            Ancest := Ancestor_Subtype (Ancest);

            if No (Ancest) then
               Ancest := Base_Type (T);

               if Is_Generic_Type (Ancest) then
                  return Unknown_Minimum_Size;
               end if;
            end if;
         end loop;

      --  Fixed-point types. We can't simply use Expr_Value to get the
      --  Corresponding_Integer_Value values of the bounds, since these do not
      --  get set till the type is frozen, and this routine can be called
      --  before the type is frozen. Similarly the test for bounds being static
      --  needs to include the case where we have unanalyzed real literals for
      --  the same reason.

      elsif Is_Fixed_Point_Type (T) then

         --  The following loop is looking for the nearest compile time known
         --  bounds following the ancestor subtype chain. The idea is to find
         --  the most restrictive known bounds information.

         Ancest := T;
         loop
            if Ancest = Any_Type or else Etype (Ancest) = Any_Type then
               return Unknown_Minimum_Size;
            end if;

            --  Note: In the following two tests for LoSet and HiSet, it may
            --  seem redundant to test for N_Real_Literal here since normally
            --  one would assume that the test for the value being known at
            --  compile time includes this case. However, there is a glitch.
            --  If the real literal comes from folding a non-static expression,
            --  then we don't consider any non- static expression to be known
            --  at compile time if we are in configurable run time mode (needed
            --  in some cases to give a clearer definition of what is and what
            --  is not accepted). So the test is indeed needed. Without it, we
            --  would set neither Lo_Set nor Hi_Set and get an infinite loop.

            if not LoSet then
               if Nkind (Type_Low_Bound (Ancest)) = N_Real_Literal
                 or else Compile_Time_Known_Value (Type_Low_Bound (Ancest))
               then
                  LoR := Expr_Value_R (Type_Low_Bound (Ancest));
                  LoSet := True;
                  exit when HiSet;
               end if;
            end if;

            if not HiSet then
               if Nkind (Type_High_Bound (Ancest)) = N_Real_Literal
                 or else Compile_Time_Known_Value (Type_High_Bound (Ancest))
               then
                  HiR := Expr_Value_R (Type_High_Bound (Ancest));
                  HiSet := True;
                  exit when LoSet;
               end if;
            end if;

            Ancest := Ancestor_Subtype (Ancest);

            if No (Ancest) then
               Ancest := Base_Type (T);

               if Is_Generic_Type (Ancest) then
                  return Unknown_Minimum_Size;
               end if;
            end if;
         end loop;

         Lo := UR_To_Uint (LoR / Small_Value (T));
         Hi := UR_To_Uint (HiR / Small_Value (T));

      --  No other types allowed

      else
         raise Program_Error;
      end if;

      --  Fall through with Hi and Lo set. Deal with biased case

      if (Biased
           and then not Is_Fixed_Point_Type (T)
           and then not (Is_Enumeration_Type (T)
                          and then Has_Non_Standard_Rep (T)))
        or else Has_Biased_Representation (T)
      then
         Hi := Hi - Lo;
         Lo := Uint_0;
      end if;

      --  Null range case, size is always zero. We only do this in the discrete
      --  type case, since that's the odd case that came up. Probably we should
      --  also do this in the fixed-point case, but doing so causes peculiar
      --  gigi failures, and it is not worth worrying about this incredibly
      --  marginal case (explicit null-range fixed-point type declarations).

      if Lo > Hi and then Is_Discrete_Type (T) then
         S := 0;

      --  Signed case. Note that we consider types like range 1 .. -1 to be
      --  signed for the purpose of computing the size, since the bounds have
      --  to be accommodated in the base type.

      elsif Lo < 0 or else Hi < 0 then
         S := 1;
         B := Uint_1;

         --  S = size, B = 2 ** (size - 1) (can accommodate -B .. +(B - 1))
         --  Note that we accommodate the case where the bounds cross. This
         --  can happen either because of the way the bounds are declared
         --  or because of the algorithm in Freeze_Fixed_Point_Type.

         while Lo < -B
           or else Hi < -B
           or else Lo >= B
           or else Hi >= B
         loop
            B := Uint_2 ** S;
            S := S + 1;
         end loop;

      --  Unsigned case

      else
         --  If both bounds are positive, make sure that both are represen-
         --  table in the case where the bounds are crossed. This can happen
         --  either because of the way the bounds are declared, or because of
         --  the algorithm in Freeze_Fixed_Point_Type.

         if Lo > Hi then
            Hi := Lo;
         end if;

         --  S = size, (can accommodate 0 .. (2**size - 1))

         S := 0;
         while Hi >= Uint_2 ** S loop
            S := S + 1;
         end loop;
      end if;

      return S;
   end Minimum_Size;

   ------------------------------
   -- New_Put_Image_Subprogram --
   ------------------------------

   procedure New_Put_Image_Subprogram
     (N     : Node_Id;
      Ent   : Entity_Id;
      Subp  : Entity_Id)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Sname     : constant Name_Id    :=
        Make_TSS_Name (Base_Type (Ent), TSS_Put_Image);
      Subp_Id   : Entity_Id;
      Subp_Decl : Node_Id;
      F         : Entity_Id;
      Etyp      : Entity_Id;

      Defer_Declaration : constant Boolean :=
                            Is_Tagged_Type (Ent) or else Is_Private_Type (Ent);
      --  For a tagged type, there is a declaration at the freeze point, and
      --  we must generate only a completion of this declaration. We do the
      --  same for private types, because the full view might be tagged.
      --  Otherwise we generate a declaration at the point of the attribute
      --  definition clause. If the attribute definition comes from an aspect
      --  specification the declaration is part of the freeze actions of the
      --  type.

      function Build_Spec return Node_Id;
      --  Used for declaration and renaming declaration, so that this is
      --  treated as a renaming_as_body.

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

      function Build_Spec return Node_Id is
         Formals : List_Id;
         Spec    : Node_Id;
         T_Ref   : constant Node_Id := New_Occurrence_Of (Etyp, Loc);

      begin
         Subp_Id := Make_Defining_Identifier (Loc, Sname);

         --  S : Root_Buffer_Type'Class

         Formals := New_List (
                      Make_Parameter_Specification (Loc,
                        Defining_Identifier =>
                          Make_Defining_Identifier (Loc, Name_S),
                        In_Present          => True,
                        Out_Present         => True,
                        Parameter_Type      =>
                          New_Occurrence_Of (Etype (F), Loc)));

         --  V : T

         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
             Parameter_Type      => T_Ref));

         Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       => Subp_Id,
             Parameter_Specifications => Formals);

         return Spec;
      end Build_Spec;

   --  Start of processing for New_Put_Image_Subprogram

   begin
      F := First_Formal (Subp);

      Etyp := Etype (Next_Formal (F));

      --  Prepare subprogram declaration and insert it as an action on the
      --  clause node. The visibility for this entity is used to test for
      --  visibility of the attribute definition clause (in the sense of
      --  8.3(23) as amended by AI-195).

      if not Defer_Declaration then
         Subp_Decl :=
           Make_Subprogram_Declaration (Loc,
             Specification => Build_Spec);

      --  For a tagged type, there is always a visible declaration for the
      --  Put_Image TSS (it is a predefined primitive operation), and the
      --  completion of this declaration occurs at the freeze point, which is
      --  not always visible at places where the attribute definition clause is
      --  visible. So, we create a dummy entity here for the purpose of
      --  tracking the visibility of the attribute definition clause itself.

      else
         Subp_Id :=
           Make_Defining_Identifier (Loc, New_External_Name (Sname, 'V'));
         Subp_Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Id,
             Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc));
      end if;

      if not Defer_Declaration
        and then From_Aspect_Specification (N)
        and then Has_Delayed_Freeze (Ent)
      then
         Append_Freeze_Action (Ent, Subp_Decl);

      else
         Insert_Action (N, Subp_Decl);
         Set_Entity (N, Subp_Id);
      end if;

      Subp_Decl :=
        Make_Subprogram_Renaming_Declaration (Loc,
          Specification => Build_Spec,
          Name          => New_Occurrence_Of (Subp, Loc));

      if Defer_Declaration then
         Set_TSS (Base_Type (Ent), Subp_Id);

      else
         if From_Aspect_Specification (N) then
            Append_Freeze_Action (Ent, Subp_Decl);
         else
            Insert_Action (N, Subp_Decl);
         end if;

         Copy_TSS (Subp_Id, Base_Type (Ent));
      end if;
   end New_Put_Image_Subprogram;

   ---------------------------
   -- New_Stream_Subprogram --
   ---------------------------

   procedure New_Stream_Subprogram
     (N     : Node_Id;
      Ent   : Entity_Id;
      Subp  : Entity_Id;
      Nam   : TSS_Name_Type)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Sname     : constant Name_Id    := Make_TSS_Name (Base_Type (Ent), Nam);
      Subp_Id   : Entity_Id;
      Subp_Decl : Node_Id;
      F         : Entity_Id;
      Etyp      : Entity_Id;

      Defer_Declaration : constant Boolean :=
                            Is_Tagged_Type (Ent) or else Is_Private_Type (Ent);
      --  For a tagged type, there is a declaration for each stream attribute
      --  at the freeze point, and we must generate only a completion of this
      --  declaration. We do the same for private types, because the full view
      --  might be tagged. Otherwise we generate a declaration at the point of
      --  the attribute definition clause. If the attribute definition comes
      --  from an aspect specification the declaration is part of the freeze
      --  actions of the type.

      function Build_Spec return Node_Id;
      --  Used for declaration and renaming declaration, so that this is
      --  treated as a renaming_as_body.

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

      function Build_Spec return Node_Id is
         Out_P   : constant Boolean := (Nam = TSS_Stream_Read);
         Formals : List_Id;
         Spec    : Node_Id;
         T_Ref   : constant Node_Id := New_Occurrence_Of (Etyp, Loc);

      begin
         Subp_Id := Make_Defining_Identifier (Loc, Sname);

         --  S : access Root_Stream_Type'Class

         Formals := New_List (
                      Make_Parameter_Specification (Loc,
                        Defining_Identifier =>
                          Make_Defining_Identifier (Loc, Name_S),
                        Parameter_Type =>
                          Make_Access_Definition (Loc,
                            Subtype_Mark =>
                              New_Occurrence_Of (
                                Designated_Type (Etype (F)), Loc))));

         if Nam = TSS_Stream_Input then
            Spec :=
              Make_Function_Specification (Loc,
                Defining_Unit_Name       => Subp_Id,
                Parameter_Specifications => Formals,
                Result_Definition        => T_Ref);
         else
            --  V : [out] T

            Append_To (Formals,
              Make_Parameter_Specification (Loc,
                Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
                Out_Present         => Out_P,
                Parameter_Type      => T_Ref));

            Spec :=
              Make_Procedure_Specification (Loc,
                Defining_Unit_Name       => Subp_Id,
                Parameter_Specifications => Formals);
         end if;

         return Spec;
      end Build_Spec;

   --  Start of processing for New_Stream_Subprogram

   begin
      F := First_Formal (Subp);

      if Ekind (Subp) = E_Procedure then
         Etyp := Etype (Next_Formal (F));
      else
         Etyp := Etype (Subp);
      end if;

      --  Prepare subprogram declaration and insert it as an action on the
      --  clause node. The visibility for this entity is used to test for
      --  visibility of the attribute definition clause (in the sense of
      --  8.3(23) as amended by AI-195).

      if not Defer_Declaration then
         Subp_Decl :=
           Make_Subprogram_Declaration (Loc,
             Specification => Build_Spec);

      --  For a tagged type, there is always a visible declaration for each
      --  stream TSS (it is a predefined primitive operation), and the
      --  completion of this declaration occurs at the freeze point, which is
      --  not always visible at places where the attribute definition clause is
      --  visible. So, we create a dummy entity here for the purpose of
      --  tracking the visibility of the attribute definition clause itself.

      else
         Subp_Id :=
           Make_Defining_Identifier (Loc, New_External_Name (Sname, 'V'));
         Subp_Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Id,
             Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc));
      end if;

      if not Defer_Declaration
        and then From_Aspect_Specification (N)
        and then Has_Delayed_Freeze (Ent)
      then
         Append_Freeze_Action (Ent, Subp_Decl);

      else
         Insert_Action (N, Subp_Decl);
         Set_Entity (N, Subp_Id);
      end if;

      Subp_Decl :=
        Make_Subprogram_Renaming_Declaration (Loc,
          Specification => Build_Spec,
          Name          => New_Occurrence_Of (Subp, Loc));

      if Defer_Declaration then
         Set_TSS (Base_Type (Ent), Subp_Id);

      else
         if From_Aspect_Specification (N) then
            Append_Freeze_Action (Ent, Subp_Decl);
         else
            Insert_Action (N, Subp_Decl);
         end if;

         Copy_TSS (Subp_Id, Base_Type (Ent));
      end if;
   end New_Stream_Subprogram;

   ----------------------
   -- No_Type_Rep_Item --
   ----------------------

   procedure No_Type_Rep_Item (N : Node_Id) is
   begin
      Error_Msg_N ("|type-related representation item not permitted!", N);
   end No_Type_Rep_Item;

   --------------
   -- Pop_Type --
   --------------

   procedure Pop_Type (E : Entity_Id) is
   begin
      if Ekind (E) = E_Record_Type and then E = Current_Scope then
         End_Scope;

      elsif Is_Type (E)
        and then Has_Discriminants (E)
        and then Nkind (Parent (E)) /= N_Subtype_Declaration
      then
         Uninstall_Discriminants (E);
         Pop_Scope;
      end if;
   end Pop_Type;

   ---------------
   -- Push_Type --
   ---------------

   procedure Push_Type (E : Entity_Id) is
      Comp : Entity_Id;

   begin
      if Ekind (E) = E_Record_Type then
         Push_Scope (E);

         Comp := First_Component (E);
         while Present (Comp) loop
            Install_Entity (Comp);
            Next_Component (Comp);
         end loop;

         if Has_Discriminants (E) then
            Install_Discriminants (E);
         end if;

      elsif Is_Type (E)
        and then Has_Discriminants (E)
        and then Nkind (Parent (E)) /= N_Subtype_Declaration
      then
         Push_Scope (E);
         Install_Discriminants (E);
      end if;
   end Push_Type;

   -----------------------------------
   -- Register_Address_Clause_Check --
   -----------------------------------

   procedure Register_Address_Clause_Check
     (N   : Node_Id;
      X   : Entity_Id;
      A   : Uint;
      Y   : Entity_Id;
      Off : Boolean)
   is
      ACS : constant Boolean := Scope_Suppress.Suppress (Alignment_Check);
   begin
      Address_Clause_Checks.Append ((N, X, A, Y, Off, ACS));
   end Register_Address_Clause_Check;

   ------------------------
   -- Rep_Item_Too_Early --
   ------------------------

   function Rep_Item_Too_Early (T : Entity_Id; N : Node_Id) return Boolean is
      function Has_Generic_Parent (E : Entity_Id) return Boolean;
      --  Return True if R or any ancestor is a generic type

      ------------------------
      -- Has_Generic_Parent --
      ------------------------

      function Has_Generic_Parent (E : Entity_Id) return Boolean is
         Ancestor_Type : Entity_Id := Etype (E);

      begin
         if Is_Generic_Type (E) then
            return True;
         end if;

         while Present (Ancestor_Type)
           and then not Is_Generic_Type (Ancestor_Type)
           and then Etype (Ancestor_Type) /= Ancestor_Type
         loop
            Ancestor_Type := Etype (Ancestor_Type);
         end loop;

         return
           Present (Ancestor_Type) and then Is_Generic_Type (Ancestor_Type);
      end Has_Generic_Parent;

   --  Start of processing for Rep_Item_Too_Early

   begin
      --  Cannot apply non-operational rep items to generic types

      if Is_Operational_Item (N) then
         return False;

      elsif Is_Type (T)
        and then Has_Generic_Parent (T)
        and then (Nkind (N) /= N_Pragma
                   or else Get_Pragma_Id (N) /= Pragma_Convention)
      then
         if Ada_Version < Ada_2022 then
            Error_Msg_N
              ("representation item not allowed for generic type", N);
            return True;
         else
            return False;
         end if;
      end if;

      --  Otherwise check for incomplete type

      if Is_Incomplete_Or_Private_Type (T)
        and then No (Underlying_Type (T))
        and then
          (Nkind (N) /= N_Pragma
            or else Get_Pragma_Id (N) /= Pragma_Import)
      then
         Error_Msg_N
           ("representation item must be after full type declaration", N);
         return True;

      --  If the type has incomplete components, a representation clause is
      --  illegal but stream attributes and Convention pragmas are correct.

      elsif Has_Private_Component (T) then
         if Nkind (N) = N_Pragma then
            return False;

         else
            Error_Msg_N
              ("representation item must appear after type is fully defined",
                N);
            return True;
         end if;
      else
         return False;
      end if;
   end Rep_Item_Too_Early;

   -----------------------
   -- Rep_Item_Too_Late --
   -----------------------

   function Rep_Item_Too_Late
     (T     : Entity_Id;
      N     : Node_Id;
      FOnly : Boolean := False) return Boolean
   is
      procedure Too_Late;
      --  Output message for an aspect being specified too late

      --  Note that neither of the above errors is considered a serious one,
      --  since the effect is simply that we ignore the representation clause
      --  in these cases.
      --  Is this really true? In any case if we make this change we must
      --  document the requirement in the spec of Rep_Item_Too_Late that
      --  if True is returned, then the rep item must be completely ignored???

      --------------
      -- Too_Late --
      --------------

      procedure Too_Late is
      begin
         --  Other compilers seem more relaxed about rep items appearing too
         --  late. Since analysis tools typically don't care about rep items
         --  anyway, no reason to be too strict about this.

         if not Relaxed_RM_Semantics then
            Error_Msg_N ("|representation item appears too late!", N);
         end if;
      end Too_Late;

      --  Local variables

      Parent_Type : Entity_Id;
      S           : Entity_Id;

   --  Start of processing for Rep_Item_Too_Late

   begin
      --  First make sure entity is not frozen (RM 13.1(9))

      if Is_Frozen (T)

        --  Exclude imported types, which may be frozen if they appear in a
        --  representation clause for a local type.

        and then not From_Limited_With (T)

        --  Exclude generated entities (not coming from source). The common
        --  case is when we generate a renaming which prematurely freezes the
        --  renamed internal entity, but we still want to be able to set copies
        --  of attribute values such as Size/Alignment.

        and then Comes_From_Source (T)
      then
         --  A self-referential aspect is illegal if it forces freezing the
         --  entity before the corresponding pragma has been analyzed.

         if Nkind (N) in N_Attribute_Definition_Clause | N_Pragma
           and then From_Aspect_Specification (N)
         then
            Error_Msg_NE
              ("aspect specification causes premature freezing of&", N, T);
            Set_Has_Delayed_Freeze (T, False);
            return True;
         end if;

         Too_Late;
         S := First_Subtype (T);

         if Present (Freeze_Node (S)) then
            if not Relaxed_RM_Semantics then
               Error_Msg_NE
                 ("??no more representation items for }", Freeze_Node (S), S);
            end if;
         end if;

         return True;

      --  Check for case of untagged derived type whose parent either has
      --  primitive operations (pre Ada 2022), or is a by-reference type (RM
      --  13.1(10)). In this case we do not output a Too_Late message, since
      --  there is no earlier point where the rep item could be placed to make
      --  it legal.
      --  ??? Confirming representation clauses should be allowed here.

      elsif Is_Type (T)
        and then not FOnly
        and then Is_Derived_Type (T)
        and then not Is_Tagged_Type (T)
      then
         Parent_Type := Etype (Base_Type (T));

         if Relaxed_RM_Semantics then
            null;

         elsif Ada_Version <= Ada_2012
           and then Has_Primitive_Operations (Parent_Type)
         then
            Error_Msg_N
              ("|representation item not permitted before Ada 2022!", N);
            Error_Msg_NE
              ("\parent type & has primitive operations!", N, Parent_Type);
            return True;

         elsif Is_By_Reference_Type (Parent_Type) then
            No_Type_Rep_Item (N);
            Error_Msg_NE
              ("\parent type & is a by-reference type!", N, Parent_Type);
            return True;
         end if;
      end if;

      --  No error, but one more warning to consider. The RM (surprisingly)
      --  allows this pattern in some cases:

      --    type S is ...
      --    primitive operations for S
      --    type R is new S;
      --    rep clause for S

      --  Meaning that calls on the primitive operations of S for values of
      --  type R may require possibly expensive implicit conversion operations.
      --  So even when this is not an error, it is still worth a warning.

      if not Relaxed_RM_Semantics and then Is_Type (T) then
         declare
            DTL : constant Entity_Id := Derived_Type_Link (Base_Type (T));

         begin
            if Present (DTL)

              --  For now, do not generate this warning for the case of
              --  aspect specification using Ada 2012 syntax, since we get
              --  wrong messages we do not understand. The whole business
              --  of derived types and rep items seems a bit confused when
              --  aspects are used, since the aspects are not evaluated
              --  till freeze time. However, AI12-0109 confirms (in an AARM
              --  ramification) that inheritance in this case is required
              --  to work.

              and then not From_Aspect_Specification (N)
            then
               if Is_By_Reference_Type (T)
                 and then not Is_Tagged_Type (T)
                 and then Is_Type_Related_Rep_Item (N)
                 and then (Ada_Version >= Ada_2012
                            or else Has_Primitive_Operations (Base_Type (T)))
               then
                  --  Treat as hard error (AI12-0109, binding interpretation).
                  --  Implementing a change of representation is not really
                  --  an option in the case of a by-reference type, so we
                  --  take this path for all Ada dialects if primitive
                  --  operations are present.
                  Error_Msg_Sloc := Sloc (DTL);
                  Error_Msg_N
                    ("representation item for& appears after derived type "
                     & "declaration#", N);

               elsif Has_Primitive_Operations (Base_Type (T)) then
                  Error_Msg_Sloc := Sloc (DTL);

                  Error_Msg_N
                    ("representation item for& appears after derived type "
                     & "declaration#??", N);
                  Error_Msg_NE
                    ("\may result in implicit conversions for primitive "
                     & "operations of&??", N, T);
                  Error_Msg_NE
                    ("\to change representations when called with arguments "
                     & "of type&??", N, DTL);
               end if;
            end if;
         end;
      end if;

      --  No error, link item into head of chain of rep items for the entity,
      --  but avoid chaining if we have an overloadable entity, and the pragma
      --  is one that can apply to multiple overloaded entities.

      if Is_Overloadable (T) and then Nkind (N) = N_Pragma then
         declare
            Pname : constant Name_Id := Pragma_Name (N);
         begin
            if Pname in Name_Convention | Name_Import | Name_Export
                      | Name_External   | Name_Interface
            then
               return False;
            end if;
         end;
      end if;

      Record_Rep_Item (T, N);
      return False;
   end Rep_Item_Too_Late;

   -------------------------------------
   -- Replace_Type_References_Generic --
   -------------------------------------

   procedure Replace_Type_References_Generic (N : Node_Id; T : Entity_Id) is
      TName : constant Name_Id := Chars (T);

      function Replace_Type_Ref (N : Node_Id) return Traverse_Result;
      --  Processes a single node in the traversal procedure below, checking
      --  if node N should be replaced, and if so, doing the replacement.

      function Visible_Component (Comp : Name_Id) return Entity_Id;
      --  Given an identifier in the expression, check whether there is a
      --  discriminant, component, protected procedure, or entry of the type
      --  that is directy visible, and rewrite it as the corresponding selected
      --  component of the formal of the subprogram.

      ----------------------
      -- Replace_Type_Ref --
      ----------------------

      function Replace_Type_Ref (N : Node_Id) return Traverse_Result is
         Loc : constant Source_Ptr := Sloc (N);

         procedure Add_Prefix (Ref : Node_Id; Comp : Entity_Id);
         --  Add the proper prefix to a reference to a component of the type
         --  when it is not already a selected component.

         ----------------
         -- Add_Prefix --
         ----------------

         procedure Add_Prefix (Ref : Node_Id; Comp : Entity_Id) is
         begin
            Rewrite (Ref,
              Make_Selected_Component (Loc,
                Prefix        => New_Occurrence_Of (T, Loc),
                Selector_Name => New_Occurrence_Of (Comp, Loc)));
            Replace_Type_Reference (Prefix (Ref));
         end Add_Prefix;

         --  Local variables

         Comp : Entity_Id;
         Pref : Node_Id;
         Scop : Entity_Id;

      --  Start of processing for Replace_Type_Ref

      begin
         if Nkind (N) = N_Identifier then

            --  If not the type name, check whether it is a reference to some
            --  other type, which must be frozen before the predicate function
            --  is analyzed, i.e. before the freeze node of the type to which
            --  the predicate applies.

            if Chars (N) /= TName then
               if Present (Current_Entity (N))
                 and then Is_Type (Current_Entity (N))
               then
                  Freeze_Before (Freeze_Node (T), Current_Entity (N));
               end if;

               --  The components of the type are directly visible and can
               --  be referenced without a prefix.

               if Nkind (Parent (N)) = N_Selected_Component then
                  null;

               --  In expression C (I), C may be a directly visible function
               --  or a visible component that has an array type. Disambiguate
               --  by examining the component type.

               elsif Nkind (Parent (N)) = N_Indexed_Component
                 and then N = Prefix (Parent (N))
               then
                  Comp := Visible_Component (Chars (N));

                  if Present (Comp) and then Is_Array_Type (Etype (Comp)) then
                     Add_Prefix (N, Comp);
                  end if;

               else
                  Comp := Visible_Component (Chars (N));

                  if Present (Comp) then
                     Add_Prefix (N, Comp);
                  end if;
               end if;

               return Skip;

            --  Otherwise do the replacement if this is not a qualified
            --  reference to a homograph of the type itself. Note that the
            --  current instance could not appear in such a context, e.g.
            --  the prefix of a type conversion.

            else
               if Nkind (Parent (N)) /= N_Selected_Component
                 or else N /= Selector_Name (Parent (N))
               then
                  Replace_Type_Reference (N);
               end if;

               return Skip;
            end if;

         --  Case of selected component, which may be a subcomponent of the
         --  current instance, or an expanded name which is still unanalyzed.

         elsif Nkind (N) = N_Selected_Component then

            --  If selector name is not our type, keep going (we might still
            --  have an occurrence of the type in the prefix). If it is a
            --  subcomponent of the current entity, add prefix.

            if Nkind (Selector_Name (N)) /= N_Identifier
              or else Chars (Selector_Name (N)) /= TName
            then
               if Nkind (Prefix (N)) = N_Identifier then
                  Comp := Visible_Component (Chars (Prefix (N)));

                  if Present (Comp) then
                     Add_Prefix (Prefix (N), Comp);
                  end if;
               end if;

               return OK;

            --  Selector name is our type, check qualification

            else
               --  Loop through scopes and prefixes, doing comparison

               Scop := Current_Scope;
               Pref := Prefix (N);
               loop
                  --  Continue if no more scopes or scope with no name

                  if No (Scop) or else Nkind (Scop) not in N_Has_Chars then
                     return OK;
                  end if;

                  --  Do replace if prefix is an identifier matching the scope
                  --  that we are currently looking at.

                  if Nkind (Pref) = N_Identifier
                    and then Chars (Pref) = Chars (Scop)
                  then
                     Replace_Type_Reference (N);
                     return Skip;
                  end if;

                  --  Go check scope above us if prefix is itself of the form
                  --  of a selected component, whose selector matches the scope
                  --  we are currently looking at.

                  if Nkind (Pref) = N_Selected_Component
                    and then Nkind (Selector_Name (Pref)) = N_Identifier
                    and then Chars (Selector_Name (Pref)) = Chars (Scop)
                  then
                     Scop := Scope (Scop);
                     Pref := Prefix (Pref);

                  --  For anything else, we don't have a match, so keep on
                  --  going, there are still some weird cases where we may
                  --  still have a replacement within the prefix.

                  else
                     return OK;
                  end if;
               end loop;
            end if;

         --  Continue for any other node kind

         else
            return OK;
         end if;
      end Replace_Type_Ref;

      procedure Replace_Type_Refs is new Traverse_Proc (Replace_Type_Ref);

      -----------------------
      -- Visible_Component --
      -----------------------

      function Visible_Component (Comp : Name_Id) return Entity_Id is
         E : Entity_Id;
      begin
         --  Types with nameable components are record, task, and protected
         --  types, and discriminated private types.

         if Ekind (T) in E_Record_Type
                       | E_Task_Type
                       | E_Protected_Type
           or else (Is_Private_Type (T) and then Has_Discriminants (T))
         then
            --  This is a sequential search, which seems acceptable
            --  efficiency-wise, given the typical size of component
            --  lists, protected operation lists, task item lists, and
            --  check expressions.

            E := First_Entity (T);
            while Present (E) loop
               if Comes_From_Source (E) and then Chars (E) = Comp then
                  return E;
               end if;

               Next_Entity (E);
            end loop;
         end if;

         --  Nothing by that name

         return Empty;
      end Visible_Component;

   --  Start of processing for Replace_Type_References_Generic

   begin
      Replace_Type_Refs (N);
   end Replace_Type_References_Generic;

   --------------------------------
   -- Resolve_Aspect_Expressions --
   --------------------------------

   procedure Resolve_Aspect_Expressions (E : Entity_Id) is
      function Resolve_Name (N : Node_Id) return Traverse_Result;
      --  Verify that all identifiers in the expression, with the exception
      --  of references to the current entity, denote visible entities. This
      --  is done only to detect visibility errors, as the expression will be
      --  properly analyzed/expanded during analysis of the predicate function
      --  body. We omit quantified expressions from this test, given that they
      --  introduce a local identifier that would require proper expansion to
      --  handle properly.

      ------------------
      -- Resolve_Name --
      ------------------

      function Resolve_Name (N : Node_Id) return Traverse_Result is
         Dummy : Traverse_Result;

      begin
         if Nkind (N) = N_Selected_Component then
            if Nkind (Prefix (N)) = N_Identifier
              and then Chars (Prefix (N)) /= Chars (E)
            then
               Find_Selected_Component (N);
            end if;

            return Skip;

         --  Resolve identifiers that are not selectors in parameter
         --  associations (these are never resolved by visibility).

         elsif Nkind (N) = N_Identifier
           and then Chars (N) /= Chars (E)
           and then (Nkind (Parent (N)) /= N_Parameter_Association
                      or else N /= Selector_Name (Parent (N)))
         then
            Find_Direct_Name (N);

            --  Reset the Entity if N is overloaded since the entity may not
            --  be the correct one.

            if Is_Overloaded (N) then
               Set_Entity (N, Empty);
            end if;

         --  The name in a component association needs no resolution

         elsif Nkind (N) = N_Component_Association then
            Dummy := Resolve_Name (Expression (N));
            return Skip;

         elsif Nkind (N) = N_Quantified_Expression then
            return Skip;
         end if;

         return OK;
      end Resolve_Name;

      procedure Resolve_Aspect_Expression is new Traverse_Proc (Resolve_Name);

      --  Local variables

      ASN : Node_Id := First_Rep_Item (E);

   --  Start of processing for Resolve_Aspect_Expressions

   begin
      while Present (ASN) loop
         if Nkind (ASN) = N_Aspect_Specification and then Entity (ASN) = E then
            declare
               A_Id : constant Aspect_Id := Get_Aspect_Id (ASN);
               Expr : constant Node_Id   := Expression (ASN);

            begin
               case A_Id is

                  when Aspect_Aggregate =>
                     Resolve_Aspect_Aggregate (Entity (ASN), Expr);

                  when Aspect_Stable_Properties =>
                     Resolve_Aspect_Stable_Properties
                       (Entity (ASN), Expr, Class_Present (ASN));

                  --  For now we only deal with aspects that do not generate
                  --  subprograms, or that may mention current instances of
                  --  types. These will require special handling???.

                  when Aspect_Invariant
                     | Aspect_Predicate_Failure
                  =>
                     null;

                  when Aspect_Dynamic_Predicate
                     | Aspect_Static_Predicate
                     | Aspect_Predicate
                  =>
                     --  Preanalyze expression after type replacement to catch
                     --  name resolution errors if the predicate function has
                     --  not been built yet.
                     --  Note that we cannot use Preanalyze_Spec_Expression
                     --  because of the special handling required for
                     --  quantifiers, see comments on Resolve_Aspect_Expression
                     --  above.

                     if No (Predicate_Function (E)) then
                        Push_Type (E);
                        Resolve_Aspect_Expression (Expr);
                        Pop_Type (E);
                     end if;

                  when Pre_Post_Aspects =>
                     null;

                  when Aspect_Iterable =>
                     if Nkind (Expr) = N_Aggregate then
                        declare
                           Assoc : Node_Id;

                        begin
                           Assoc := First (Component_Associations (Expr));
                           while Present (Assoc) loop
                              if Nkind (Expression (Assoc)) in N_Has_Entity
                              then
                                 Find_Direct_Name (Expression (Assoc));
                              end if;

                              Next (Assoc);
                           end loop;
                        end;
                     end if;

                  --  The expression for Default_Value is a static expression
                  --  of the type, but this expression does not freeze the
                  --  type, so it can still appear in a representation clause
                  --  before the actual freeze point.

                  when Aspect_Default_Value =>
                     Set_Must_Not_Freeze (Expr);
                     Preanalyze_Spec_Expression (Expr, E);

                  when Aspect_Priority =>
                     Push_Type (E);
                     Preanalyze_Spec_Expression (Expr, Any_Integer);
                     Pop_Type (E);

                  --  Ditto for Storage_Size. Any other aspects that carry
                  --  expressions that should not freeze ??? This is only
                  --  relevant to the misuse of deferred constants.

                  when Aspect_Storage_Size =>
                     Set_Must_Not_Freeze (Expr);
                     Preanalyze_Spec_Expression (Expr, Any_Integer);

                  when others =>
                     if Present (Expr) then
                        case Aspect_Argument (A_Id) is
                           when Expression
                              | Optional_Expression
                           =>
                              Analyze_And_Resolve (Expr);

                           when Name
                              | Optional_Name
                           =>
                              if Nkind (Expr) = N_Identifier then
                                 Find_Direct_Name (Expr);

                              elsif Nkind (Expr) = N_Selected_Component then
                                 Find_Selected_Component (Expr);
                              end if;
                        end case;
                     end if;
               end case;
            end;
         end if;

         Next_Rep_Item (ASN);
      end loop;
   end Resolve_Aspect_Expressions;

   ----------------------------
   -- Parse_Aspect_Aggregate --
   ----------------------------

   procedure Parse_Aspect_Aggregate
     (N                   : Node_Id;
      Empty_Subp          : in out Node_Id;
      Add_Named_Subp      : in out Node_Id;
      Add_Unnamed_Subp    : in out Node_Id;
      New_Indexed_Subp    : in out Node_Id;
      Assign_Indexed_Subp : in out Node_Id)
   is
      Assoc   : Node_Id := First (Component_Associations (N));
      Op_Name : Name_Id;
      Subp    : Node_Id;

   begin
      while Present (Assoc) loop
         Subp := Expression (Assoc);
         Op_Name := Chars (First (Choices (Assoc)));
         if Op_Name = Name_Empty then
            Empty_Subp := Subp;

         elsif Op_Name = Name_Add_Named then
            Add_Named_Subp := Subp;

         elsif Op_Name = Name_Add_Unnamed then
            Add_Unnamed_Subp := Subp;

         elsif Op_Name = Name_New_Indexed then
            New_Indexed_Subp := Subp;

         elsif Op_Name = Name_Assign_Indexed then
            Assign_Indexed_Subp := Subp;
         end if;

         Next (Assoc);
      end loop;
   end Parse_Aspect_Aggregate;

   ------------------------------------
   -- Parse_Aspect_Stable_Properties --
   ------------------------------------

   function Parse_Aspect_Stable_Properties
     (Aspect_Spec : Node_Id; Negated : out Boolean) return Subprogram_List
   is
      function Extract_Entity (Expr : Node_Id) return Entity_Id;
      --  Given an element of a Stable_Properties aspect spec, return the
      --  associated entity.
      --  This function updates the Negated flag as a side-effect.

      --------------------
      -- Extract_Entity --
      --------------------

      function Extract_Entity (Expr : Node_Id) return Entity_Id is
         Name : Node_Id;
      begin
         if Nkind (Expr) = N_Op_Not then
            Negated := True;
            Name := Right_Opnd (Expr);
         else
            Name := Expr;
         end if;

         if Nkind (Name) in N_Has_Entity then
            return Entity (Name);
         else
            return Empty;
         end if;
      end Extract_Entity;

      --  Local variables

      L  : List_Id;
      Id : Node_Id;

   --  Start of processing for Parse_Aspect_Stable_Properties

   begin
      Negated := False;

      if Nkind (Aspect_Spec) /= N_Aggregate then
         return (1 => Extract_Entity (Aspect_Spec));
      else
         L := Expressions (Aspect_Spec);
         Id := First (L);

         return Result : Subprogram_List (1 .. List_Length (L)) do
            for I in Result'Range loop
               Result (I) := Extract_Entity (Id);

               if No (Result (I)) then
                  pragma Assert (Serious_Errors_Detected > 0);
                  goto Ignore_Aspect;
               end if;

               Next (Id);
            end loop;
         end return;
      end if;

      <<Ignore_Aspect>> return (1 .. 0 => <>);
   end Parse_Aspect_Stable_Properties;

   -------------------------------
   -- Validate_Aspect_Aggregate --
   -------------------------------

   procedure Validate_Aspect_Aggregate (N : Node_Id) is
      Empty_Subp          : Node_Id := Empty;
      Add_Named_Subp      : Node_Id := Empty;
      Add_Unnamed_Subp    : Node_Id := Empty;
      New_Indexed_Subp    : Node_Id := Empty;
      Assign_Indexed_Subp : Node_Id := Empty;

   begin
      Error_Msg_Ada_2022_Feature ("aspect Aggregate", Sloc (N));

      if Nkind (N) /= N_Aggregate
        or else Present (Expressions (N))
        or else No (Component_Associations (N))
      then
         Error_Msg_N ("aspect Aggregate requires an aggregate "
                        & "with component associations", N);
         return;
      end if;

      Parse_Aspect_Aggregate (N,
        Empty_Subp, Add_Named_Subp, Add_Unnamed_Subp,
        New_Indexed_Subp, Assign_Indexed_Subp);

      if No (Empty_Subp) then
         Error_Msg_N ("missing specification for Empty in aggregate", N);
      end if;

      if Present (Add_Named_Subp) then
         if Present (Add_Unnamed_Subp)
           or else Present (Assign_Indexed_Subp)
         then
            Error_Msg_N
             ("conflicting operations for aggregate (RM 4.3.5)", N);
            return;
         end if;

      elsif Present (New_Indexed_Subp) /= Present (Assign_Indexed_Subp) then
         Error_Msg_N ("incomplete specification for indexed aggregate", N);
      end if;
   end Validate_Aspect_Aggregate;

   -------------------------------
   -- Validate_Aspect_Stable_Properties --
   -------------------------------

   procedure Validate_Aspect_Stable_Properties
     (E : Entity_Id; N : Node_Id; Class_Present : Boolean)
   is
      Is_Aspect_Of_Type : constant Boolean := Is_Type (E);

      type Permission is (Forbidden, Optional, Required);
      Modifier_Permission : Permission :=
       (if Is_Aspect_Of_Type then Forbidden else Optional);
      Modifier_Error_Called : Boolean := False;

      procedure Check_Property_Function_Arg (PF_Arg : Node_Id);
      --  Check syntax of a property function argument

      ----------------------------------
      -- Check_Property_Function_Arg --
      ----------------------------------

      procedure Check_Property_Function_Arg (PF_Arg : Node_Id) is
         procedure Modifier_Error;
         --  Generate message about bad "not" modifier if no message already
         --  generated. Errors include specifying "not" for an aspect of
         --  of a type and specifying "not" for some but not all of the
         --  names in a list.

         --------------------
         -- Modifier_Error --
         --------------------

         procedure Modifier_Error is
         begin
            if Modifier_Error_Called then
               return; -- error message already generated
            end if;

            Modifier_Error_Called := True;

            if Is_Aspect_Of_Type then
               Error_Msg_N
                 ("NOT modifier not allowed for Stable_Properties aspect"
                  & " of a type", PF_Arg);
            else
               Error_Msg_N ("mixed use of NOT modifiers", PF_Arg);
            end if;
         end Modifier_Error;

         PF_Name : Node_Id := PF_Arg;

      --  Start of processing for Check_Property_Function_Arg

      begin
         if Nkind (PF_Arg) = N_Op_Not then
            PF_Name := Right_Opnd (PF_Arg);

            case Modifier_Permission is
               when Forbidden =>
                  Modifier_Error;
               when Optional =>
                  Modifier_Permission := Required;
               when Required =>
                  null;
            end case;
         else
            case Modifier_Permission is
               when Forbidden =>
                  null;
               when Optional =>
                  Modifier_Permission := Forbidden;
               when Required =>
                  Modifier_Error;
            end case;
         end if;

         if Nkind (PF_Name) not in
           N_Identifier | N_Operator_Symbol | N_Selected_Component
         then
            Error_Msg_N ("bad property function name", PF_Name);
         end if;
      end Check_Property_Function_Arg;

   --  Start of processing for Validate_Aspect_Stable_Properties

   begin
      Error_Msg_Ada_2022_Feature ("aspect Stable_Properties", Sloc (N));

      if (not Is_Aspect_Of_Type) and then (not Is_Subprogram (E)) then
         Error_Msg_N ("Stable_Properties aspect can only be specified for "
                      & "a type or a subprogram", N);
      elsif Class_Present then
         if Is_Aspect_Of_Type then
            if not Is_Tagged_Type (E) then
               Error_Msg_N
                 ("Stable_Properties''Class aspect cannot be specified for "
                  & "an untagged type", N);
            end if;
         else
            if not Is_Dispatching_Operation (E) then
               Error_Msg_N
                 ("Stable_Properties''Class aspect cannot be specified for "
                  & "a subprogram that is not a primitive subprogram "
                  & "of a tagged type", N);
            end if;
         end if;
      end if;

      if Nkind (N) = N_Aggregate then
         if Present (Component_Associations (N))
            or else Null_Record_Present (N)
            or else not Present (Expressions (N))
         then
            Error_Msg_N ("bad Stable_Properties aspect specification", N);
            return;
         end if;

         declare
            PF_Arg : Node_Id := First (Expressions (N));
         begin
            while Present (PF_Arg) loop
               Check_Property_Function_Arg (PF_Arg);
               Next (PF_Arg);
            end loop;
         end;
      else
         Check_Property_Function_Arg (N);
      end if;
   end Validate_Aspect_Stable_Properties;

   --------------------------------
   -- Resolve_Iterable_Operation --
   --------------------------------

   procedure Resolve_Iterable_Operation
     (N      : Node_Id;
      Cursor : Entity_Id;
      Typ    : Entity_Id;
      Nam    : Name_Id)
   is
      Ent : Entity_Id;
      F1  : Entity_Id;
      F2  : Entity_Id;

   begin
      if not Is_Overloaded (N) then
         if not Is_Entity_Name (N)
           or else Ekind (Entity (N)) /= E_Function
           or else Scope (Entity (N)) /= Scope (Typ)
           or else No (First_Formal (Entity (N)))
           or else Etype (First_Formal (Entity (N))) /= Typ
         then
            Error_Msg_N
              ("iterable primitive must be local function name whose first "
               & "formal is an iterable type", N);
            return;
         end if;

         Ent := Entity (N);
         F1  := First_Formal (Ent);

         if Nam in Name_First | Name_Last then

            --  First or Last (Container) => Cursor

            if Etype (Ent) /= Cursor then
               Error_Msg_N ("primitive for First must yield a cursor", N);
            end if;

         elsif Nam = Name_Next then

            --  Next (Container, Cursor) => Cursor

            F2 := Next_Formal (F1);

            if Etype (F2) /= Cursor
              or else Etype (Ent) /= Cursor
              or else Present (Next_Formal (F2))
            then
               Error_Msg_N ("no match for Next iterable primitive", N);
            end if;

         elsif Nam = Name_Previous then

            --  Previous (Container, Cursor) => Cursor

            F2 := Next_Formal (F1);

            if Etype (F2) /= Cursor
              or else Etype (Ent) /= Cursor
              or else Present (Next_Formal (F2))
            then
               Error_Msg_N ("no match for Previous iterable primitive", N);
            end if;

         elsif Nam = Name_Has_Element then

            --  Has_Element (Container, Cursor) => Boolean

            F2 := Next_Formal (F1);

            if Etype (F2) /= Cursor
              or else Etype (Ent) /= Standard_Boolean
              or else Present (Next_Formal (F2))
            then
               Error_Msg_N ("no match for Has_Element iterable primitive", N);
            end if;

         elsif Nam = Name_Element then
            F2 := Next_Formal (F1);

            if No (F2)
              or else Etype (F2) /= Cursor
              or else Present (Next_Formal (F2))
            then
               Error_Msg_N ("no match for Element iterable primitive", N);
            end if;

         else
            raise Program_Error;
         end if;

      else
         --  Overloaded case: find subprogram with proper signature. Caller
         --  will report error if no match is found.

         declare
            I  : Interp_Index;
            It : Interp;

         begin
            Get_First_Interp (N, I, It);
            while Present (It.Typ) loop
               if Ekind (It.Nam) = E_Function
                  and then Scope (It.Nam) = Scope (Typ)
                  and then Etype (First_Formal (It.Nam)) = Typ
               then
                  F1 := First_Formal (It.Nam);

                  if Nam = Name_First then
                     if Etype (It.Nam) = Cursor
                       and then No (Next_Formal (F1))
                     then
                        Set_Entity (N, It.Nam);
                        exit;
                     end if;

                  elsif Nam = Name_Next then
                     F2 := Next_Formal (F1);

                     if Present (F2)
                       and then No (Next_Formal (F2))
                       and then Etype (F2) = Cursor
                       and then Etype (It.Nam) = Cursor
                     then
                        Set_Entity (N, It.Nam);
                        exit;
                     end if;

                  elsif Nam = Name_Has_Element then
                     F2 := Next_Formal (F1);

                     if Present (F2)
                       and then No (Next_Formal (F2))
                       and then Etype (F2) = Cursor
                       and then Etype (It.Nam) = Standard_Boolean
                     then
                        Set_Entity (N, It.Nam);
                        F2 := Next_Formal (F1);
                        exit;
                     end if;

                  elsif Nam = Name_Element then
                     F2 := Next_Formal (F1);

                     if Present (F2)
                       and then No (Next_Formal (F2))
                       and then Etype (F2) = Cursor
                     then
                        Set_Entity (N, It.Nam);
                        exit;
                     end if;
                  end if;
               end if;

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

   ------------------------------
   -- Resolve_Aspect_Aggregate --
   ------------------------------

   procedure Resolve_Aspect_Aggregate
    (Typ  : Entity_Id;
     Expr : Node_Id)
   is
      function Valid_Empty          (E : Entity_Id) return Boolean;
      function Valid_Add_Named      (E : Entity_Id) return Boolean;
      function Valid_Add_Unnamed    (E : Entity_Id) return Boolean;
      function Valid_New_Indexed    (E : Entity_Id) return Boolean;
      function Valid_Assign_Indexed (E : Entity_Id) return Boolean;
      --  Predicates that establish the legality of each possible operation in
      --  an Aggregate aspect.

      generic
        with function Pred (Id : Node_Id) return Boolean;
      procedure Resolve_Operation (Subp_Id : Node_Id);
      --  Common processing to resolve each aggregate operation.

      ------------------------
      -- Valid_Assign_Index --
      ------------------------

      function Valid_Assign_Indexed (E : Entity_Id) return Boolean is
      begin
         --  The profile must be the same as for Add_Named, with the added
         --  requirement that the key_type be a discrete type.

         if Valid_Add_Named (E) then
            return Is_Discrete_Type (Etype (Next_Formal (First_Formal (E))));
         else
            return False;
         end if;
      end Valid_Assign_Indexed;

      -----------------
      -- Valid_Empty --
      -----------------

      function Valid_Empty (E :  Entity_Id) return Boolean is
      begin
         if Etype (E) /= Typ or else Scope (E) /= Scope (Typ) then
            return False;

         elsif Ekind (E) = E_Constant then
            return True;

         elsif Ekind (E) = E_Function then
            return No (First_Formal (E))
              or else
                (Is_Integer_Type (Etype (First_Formal (E)))
                  and then No (Next_Formal (First_Formal (E))));
         else
            return False;
         end if;
      end Valid_Empty;

      ---------------------
      -- Valid_Add_Named --
      ---------------------

      function Valid_Add_Named (E : Entity_Id) return Boolean is
         F2, F3 : Entity_Id;
      begin
         if Ekind (E) = E_Procedure
           and then Scope (E) = Scope (Typ)
           and then Number_Formals (E) = 3
           and then Etype (First_Formal (E)) = Typ
           and then Ekind (First_Formal (E)) = E_In_Out_Parameter
         then
            F2 := Next_Formal (First_Formal (E));
            F3 := Next_Formal (F2);
            return Ekind (F2) = E_In_Parameter
              and then Ekind (F3) = E_In_Parameter
              and then not Is_Limited_Type (Etype (F2))
              and then not Is_Limited_Type (Etype (F3));
         else
            return False;
         end if;
      end Valid_Add_Named;

      -----------------------
      -- Valid_Add_Unnamed --
      -----------------------

      function Valid_Add_Unnamed (E : Entity_Id) return Boolean is
      begin
         return Ekind (E) = E_Procedure
           and then Scope (E) = Scope (Typ)
           and then Number_Formals (E) = 2
           and then Etype (First_Formal (E)) = Typ
           and then Ekind (First_Formal (E)) = E_In_Out_Parameter
           and then
             not Is_Limited_Type (Etype (Next_Formal (First_Formal (E))));
      end Valid_Add_Unnamed;

      -----------------------
      -- Valid_Nmw_Indexed --
      -----------------------

      function Valid_New_Indexed (E : Entity_Id) return Boolean is
      begin
         return Ekind (E) = E_Function
           and then Scope (E) = Scope (Typ)
           and then Etype (E) = Typ
           and then Number_Formals (E) = 2
           and then Is_Discrete_Type (Etype (First_Formal (E)))
           and then Etype (First_Formal (E)) =
             Etype (Next_Formal (First_Formal (E)));
      end Valid_New_Indexed;

      -----------------------
      -- Resolve_Operation --
      -----------------------

      procedure Resolve_Operation (Subp_Id : Node_Id) is
         Subp : Entity_Id;

         I  : Interp_Index;
         It : Interp;

      begin
         if not Is_Overloaded (Subp_Id) then
            Subp := Entity (Subp_Id);
            if not Pred (Subp) then
               Error_Msg_NE
                 ("improper aggregate operation for&", Subp_Id, Typ);
            end if;

         else
            Set_Entity (Subp_Id, Empty);
            Get_First_Interp (Subp_Id, I, It);
            while Present (It.Nam) loop
               if Pred (It.Nam) then
                  Set_Is_Overloaded (Subp_Id, False);
                  Set_Entity (Subp_Id, It.Nam);
                  exit;
               end if;

               Get_Next_Interp (I, It);
            end loop;

            if No (Entity (Subp_Id)) then
               Error_Msg_NE
                 ("improper aggregate operation for&", Subp_Id, Typ);
            end if;
         end if;
      end Resolve_Operation;

      Assoc   : Node_Id;
      Op_Name : Name_Id;
      Subp_Id : Node_Id;

      procedure Resolve_Empty   is new Resolve_Operation (Valid_Empty);
      procedure Resolve_Unnamed is new Resolve_Operation (Valid_Add_Unnamed);
      procedure Resolve_Named   is new Resolve_Operation (Valid_Add_Named);
      procedure Resolve_Indexed is new Resolve_Operation (Valid_New_Indexed);
      procedure Resolve_Assign_Indexed
                                is new Resolve_Operation
                                                      (Valid_Assign_Indexed);

   --  Start of processing for Resolve_Aspect_Aggregate

   begin
      Assoc := First (Component_Associations (Expr));

      while Present (Assoc) loop
         Op_Name := Chars (First (Choices (Assoc)));

         --  When verifying the consistency of aspects between the freeze point
         --  and the end of declarqtions, we use a copy which is not analyzed
         --  yet, so do it now.

         Subp_Id := Expression (Assoc);
         if No (Etype (Subp_Id)) then
            Analyze (Subp_Id);
         end if;

         if Op_Name = Name_Empty then
            Resolve_Empty (Subp_Id);

         elsif Op_Name = Name_Add_Named then
            Resolve_Named (Subp_Id);

         elsif Op_Name = Name_Add_Unnamed then
            Resolve_Unnamed (Subp_Id);

         elsif Op_Name = Name_New_Indexed then
            Resolve_Indexed (Subp_Id);

         elsif Op_Name = Name_Assign_Indexed then
            Resolve_Assign_Indexed (Subp_Id);
         end if;

         Next (Assoc);
      end loop;
   end Resolve_Aspect_Aggregate;

   --------------------------------------
   -- Resolve_Aspect_Stable_Properties --
   --------------------------------------

   procedure Resolve_Aspect_Stable_Properties
    (Typ_Or_Subp : Entity_Id; Expr : Node_Id; Class_Present : Boolean)
   is
      Is_Aspect_Of_Type : constant Boolean := Is_Type (Typ_Or_Subp);

      Singleton : constant Boolean := Nkind (Expr) /= N_Aggregate;
      Subp_Name : Node_Id := (if Singleton
                              then Expr
                              else First (Expressions (Expr)));
      Has_Not   : Boolean;
   begin
      if Is_Aspect_Of_Type
         and then Has_Private_Declaration (Typ_Or_Subp)
         and then not Is_Private_Type (Typ_Or_Subp)
      then
         Error_Msg_N
           ("Stable_Properties aspect cannot be specified " &
             "for the completion of a private type", Typ_Or_Subp);
      end if;

      --  Analogous checks that the aspect is not specified for a completion
      --  in the subprogram case are not performed here because they are not
      --  specific to this particular aspect. Right ???

      loop
         Has_Not := Nkind (Subp_Name) = N_Op_Not;
         if Has_Not then
            Set_Analyzed (Subp_Name); -- ???
            Subp_Name := Right_Opnd (Subp_Name);
         end if;

         if No (Etype (Subp_Name)) then
            Analyze (Subp_Name);
         end if;

         declare
            Subp : Entity_Id := Empty;

            I  : Interp_Index;
            It : Interp;

            function Is_Property_Function (E : Entity_Id) return Boolean;
            --  Implements RM 7.3.4 definition of "property function".

            function Is_Property_Function (E : Entity_Id) return Boolean is
            begin
               if Ekind (E) not in E_Function | E_Operator
                 or else Number_Formals (E) /= 1
               then
                  return False;
               end if;

               declare
                  Param_Type : constant Entity_Id :=
                     Base_Type (Etype (First_Formal (E)));

                  function Matches_Param_Type (Typ : Entity_Id)
                    return Boolean is
                    ((Base_Type (Typ) = Param_Type)
                     or else
                     (Is_Class_Wide_Type (Param_Type)
                      and then Is_Ancestor (Root_Type (Param_Type),
                                            Base_Type (Typ))));
               begin
                  if Is_Aspect_Of_Type then
                     if Matches_Param_Type (Typ_Or_Subp) then
                        return True;
                     end if;
                  elsif Is_Primitive (Typ_Or_Subp) then
                     declare
                        Formal : Entity_Id := First_Formal (Typ_Or_Subp);
                     begin
                        while Present (Formal) loop
                           if Matches_Param_Type (Etype (Formal)) then

                              --  Test whether Typ_Or_Subp (which is a subp
                              --  in this case) is primitive op of the type
                              --  of this parameter.
                              if Scope (Typ_Or_Subp) = Scope (Param_Type) then
                                 return True;
                              end if;
                           end if;
                           Next_Formal (Formal);
                        end loop;
                     end;
                  end if;
               end;

               return False;
            end Is_Property_Function;
         begin
            if not Is_Overloaded (Subp_Name) then
               Subp := Entity (Subp_Name);
               if not Is_Property_Function (Subp) then
                  Error_Msg_NE ("improper property function for&",
                    Subp_Name, Typ_Or_Subp);
                  return;
               end if;
            else
               Set_Entity (Subp_Name, Empty);
               Get_First_Interp (Subp_Name, I, It);
               while Present (It.Nam) loop
                  if Is_Property_Function (It.Nam) then
                     if Present (Subp) then
                        Error_Msg_NE
                          ("ambiguous property function name for&",
                           Subp_Name, Typ_Or_Subp);
                        return;
                     end if;

                     Subp := It.Nam;
                     Set_Is_Overloaded (Subp_Name, False);
                     Set_Entity (Subp_Name, Subp);
                  end if;

                  Get_Next_Interp (I, It);
               end loop;

               if No (Subp) then
                  Error_Msg_NE ("improper property function for&",
                    Subp_Name, Typ_Or_Subp);
                  return;
               end if;
            end if;

            --  perform legality (as opposed to name resolution) Subp checks

            if Is_Limited_Type (Etype (Subp)) then
               Error_Msg_NE
                 ("result type of property function for& is limited",
                  Subp_Name, Typ_Or_Subp);
            end if;

            if Ekind (First_Formal (Subp)) /= E_In_Parameter then
               Error_Msg_NE
                 ("mode of parameter of property function for& is not IN",
                  Subp_Name, Typ_Or_Subp);
            end if;

            if Is_Class_Wide_Type (Etype (First_Formal (Subp))) then
               if not Covers (Etype (First_Formal (Subp)), Typ_Or_Subp) then
                  Error_Msg_NE
                    ("class-wide parameter type of property function " &
                     "for& does not cover the type",
                     Subp_Name, Typ_Or_Subp);

               --  ??? This test is slightly stricter than 7.3.4(12/5);
               --  some legal corner cases may be incorrectly rejected.
               elsif Scope (Subp) /= Scope (Etype (First_Formal (Subp)))
               then
                  Error_Msg_NE
                    ("property function for& not declared in same scope " &
                     "as parameter type",
                     Subp_Name, Typ_Or_Subp);
               end if;
            elsif Is_Aspect_Of_Type and then
              Scope (Subp) /= Scope (Typ_Or_Subp) and then
              Scope (Subp) /= Standard_Standard --  e.g., derived type's "abs"
            then
               Error_Msg_NE
                 ("property function for& " &
                  "not a primitive function of the type",
                  Subp_Name, Typ_Or_Subp);
            end if;

            if Has_Not then
               --  check that Subp was mentioned in param type's aspect spec
               declare
                  Param_Type : constant Entity_Id :=
                    Base_Type (Etype (First_Formal (Subp)));
                  Aspect_Spec : constant Node_Id :=
                    Find_Value_Of_Aspect
                      (Param_Type, Aspect_Stable_Properties,
                       Class_Present => Class_Present);
                  Found : Boolean := False;
               begin
                  if Present (Aspect_Spec) then
                     declare
                        Ignored : Boolean;
                        SPF_List : constant Subprogram_List :=
                          Parse_Aspect_Stable_Properties
                            (Aspect_Spec, Negated => Ignored);
                     begin
                        Found := (for some E of SPF_List => E = Subp);
                        --  look through renamings ???
                     end;
                  end if;
                  if not Found then
                     declare
                        CW_Modifier : constant String :=
                          (if Class_Present then "class-wide " else "");
                     begin
                        Error_Msg_NE
                       (CW_Modifier
                         & "property function for& mentioned after NOT "
                         & "but not a "
                         & CW_Modifier
                         & "stable property function of its parameter type",
                        Subp_Name, Typ_Or_Subp);
                     end;
                  end if;
               end;
            end if;
         end;

         exit when Singleton;
         Subp_Name :=
           Next ((if Has_Not then Parent (Subp_Name) else Subp_Name));
         exit when No (Subp_Name);
      end loop;

      Set_Analyzed (Expr);
   end Resolve_Aspect_Stable_Properties;

   -----------------------------------------
   -- Resolve_Storage_Model_Type_Argument --
   -----------------------------------------

   procedure Resolve_Storage_Model_Type_Argument
     (N         : Node_Id;
      Typ       : Entity_Id;
      Addr_Type : in out Entity_Id;
      Nam       : Name_Id)
   is

      type Formal_Profile is record
         Subt : Entity_Id;
         Mode : Formal_Kind;
      end record;

      type Formal_Profiles is array (Positive range <>) of Formal_Profile;

      function Aspect_Argument_Profile_Matches
        (Subp            : Entity_Id;
         Profiles        : Formal_Profiles;
         Result_Subt     : Entity_Id;
         Err_On_Mismatch : Boolean) return Boolean;
      --  Checks that the formal parameters of subprogram Subp conform to the
      --  subtypes and modes specified by Profiles, as well as to the result
      --  subtype Result_Subt when that is nonempty.

      function Aspect_Argument_Profile_Matches
        (Subp            : Entity_Id;
         Profiles        : Formal_Profiles;
         Result_Subt     : Entity_Id;
         Err_On_Mismatch : Boolean) return Boolean
      is

         procedure Report_Argument_Error
           (Msg    : String;
            Formal : Entity_Id := Empty;
            Subt   : Entity_Id := Empty);
         --  If Err_On_Mismatch is True, reports an argument error given by Msg
         --  associated with Formal and/or Subt.

         procedure Report_Argument_Error
           (Msg    : String;
            Formal : Entity_Id := Empty;
            Subt   : Entity_Id := Empty)
         is
         begin
            if Err_On_Mismatch then
               if Present (Formal) then
                  if Present (Subt) then
                     Error_Msg_Node_2 := Subt;
                  end if;
                  Error_Msg_NE (Msg, N, Formal);

               elsif Present (Subt) then
                  Error_Msg_NE (Msg, N, Subt);

               else
                  Error_Msg_N (Msg, N);
               end if;
            end if;
         end Report_Argument_Error;

         --  Local variables

         Formal    : Entity_Id := First_Formal (Subp);
         Is_Error  : Boolean   := False;

      --  Start of processing for Aspect_Argument_Profile_Matches

      begin
         for FP of Profiles loop
            if not Present (Formal) then
               Is_Error := True;
               Report_Argument_Error ("missing formal of }", Subt => FP.Subt);
               exit;

            elsif not Subtypes_Statically_Match
                        (Etype (Formal), FP.Subt)
            then
               Is_Error := True;
               Report_Argument_Error
                 ("formal& must be of subtype&",
                  Formal => Formal, Subt => FP.Subt);
               exit;

            elsif Ekind (Formal) /= FP.Mode then
               Is_Error := True;
               Report_Argument_Error
                 ("formal& has wrong mode", Formal => Formal);
               exit;
            end if;

            Formal := Next_Formal (Formal);
         end loop;

         if not Is_Error
           and then Present (Formal)
         then
            Is_Error := True;
            Report_Argument_Error
              ("too many formals for subprogram in aspect");
         end if;

         if not Is_Error
           and then Present (Result_Subt)
           and then not Subtypes_Statically_Match (Etype (Subp), Result_Subt)
         then
            Is_Error := True;
            Report_Argument_Error
              ("subprogram must have result}", Subt => Result_Subt);
         end if;

         return not Is_Error;
      end Aspect_Argument_Profile_Matches;

      --  Local variables

      Ent : Entity_Id;

      Storage_Count_Type  : constant Entity_Id := RTE (RE_Storage_Count);
      System_Address_Type : constant Entity_Id := RTE (RE_Address);

   --  Start of processing for Resolve_Storage_Model_Type_Argument

   begin
      if Nam = Name_Address_Type then
         if not Is_Entity_Name (N)
           or else not Is_Type (Entity (N))
           or else (Root_Type (Entity (N)) /= System_Address_Type
                     and then not Is_Integer_Type (Entity (N)))
         then
            Error_Msg_N ("named entity must be a descendant of System.Address "
                         & "or an integer type", N);
         end if;

         Addr_Type := Entity (N);

         return;

      elsif not Present (Addr_Type) then
         Error_Msg_N ("argument association for Address_Type missing; "
                         & "must be specified as first aspect argument", N);
         return;

      elsif Nam = Name_Null_Address then
         if not Is_Entity_Name (N)
           or else not Is_Constant_Object (Entity (N))
           or else
             not Subtypes_Statically_Match (Etype (Entity (N)), Addr_Type)
         then
            Error_Msg_NE
              ("named entity must be constant of subtype}", N, Addr_Type);
         end if;

         return;

      elsif not Is_Overloaded (N) then
         if not Is_Entity_Name (N)
           or else Ekind (Entity (N)) not in E_Function | E_Procedure
           or else Scope (Entity (N)) /= Scope (Typ)
         then
            Error_Msg_N ("argument must be local subprogram name", N);
            return;
         end if;

         Ent := Entity (N);

         if Nam = Name_Allocate then
            if not Aspect_Argument_Profile_Matches
                     (Ent,
                      Profiles        =>
                        ((Typ,                E_In_Out_Parameter),
                         (Addr_Type,          E_Out_Parameter),
                         (Storage_Count_Type, E_In_Parameter),
                         (Storage_Count_Type, E_In_Parameter)),
                      Result_Subt     => Empty,
                      Err_On_Mismatch => True)
            then
               Error_Msg_N ("no match for Allocate operation", N);
            end if;

         elsif Nam = Name_Deallocate then
            if not Aspect_Argument_Profile_Matches
                     (Ent,
                      Profiles        =>
                        ((Typ,                E_In_Out_Parameter),
                         (Addr_Type,          E_In_Parameter),
                         (Storage_Count_Type, E_In_Parameter),
                         (Storage_Count_Type, E_In_Parameter)),
                      Result_Subt     => Empty,
                      Err_On_Mismatch => True)
            then
               Error_Msg_N ("no match for Deallocate operation", N);
            end if;

         elsif Nam = Name_Copy_From then
            if not Aspect_Argument_Profile_Matches
                     (Ent,
                      Profiles        =>
                        ((Typ,                 E_In_Out_Parameter),
                         (System_Address_Type, E_In_Parameter),
                         (Addr_Type,           E_In_Parameter),
                         (Storage_Count_Type,  E_In_Parameter)),
                      Result_Subt     => Empty,
                      Err_On_Mismatch => True)
            then
               Error_Msg_N ("no match for Copy_From operation", N);
            end if;

         elsif Nam = Name_Copy_To then
            if not Aspect_Argument_Profile_Matches
                     (Ent,
                      Profiles        =>
                        ((Typ,                 E_In_Out_Parameter),
                         (Addr_Type,           E_In_Parameter),
                         (System_Address_Type, E_In_Parameter),
                         (Storage_Count_Type,  E_In_Parameter)),
                      Result_Subt     => Empty,
                      Err_On_Mismatch => True)
            then
               Error_Msg_N ("no match for Copy_To operation", N);
            end if;

         elsif Nam = Name_Storage_Size then
            if not Aspect_Argument_Profile_Matches
                     (Ent,
                      Profiles        => (1 => (Typ, E_In_Parameter)),
                      Result_Subt     => Storage_Count_Type,
                      Err_On_Mismatch => True)
            then
               Error_Msg_N ("no match for Storage_Size operation", N);
            end if;

         else
            null; -- Error will be caught in Validate_Storage_Model_Type_Aspect
         end if;

      else
         --  Overloaded case: find subprogram with proper signature

         declare
            I  : Interp_Index;
            It : Interp;
            Found_Match : Boolean := False;

         begin
            Get_First_Interp (N, I, It);
            while Present (It.Typ) loop
               if Ekind (It.Nam) in E_Function | E_Procedure
                  and then Scope (It.Nam) = Scope (Typ)
               then
                  if Nam = Name_Allocate then
                     Found_Match :=
                       Aspect_Argument_Profile_Matches
                         (It.Nam,
                          Profiles        =>
                            ((Typ,                E_In_Out_Parameter),
                             (Addr_Type,          E_Out_Parameter),
                             (Storage_Count_Type, E_In_Parameter),
                             (Storage_Count_Type, E_In_Parameter)),
                          Result_Subt     => Empty,
                          Err_On_Mismatch => False);

                  elsif Nam = Name_Deallocate then
                     Found_Match :=
                       Aspect_Argument_Profile_Matches
                         (It.Nam,
                          Profiles        =>
                            ((Typ,                E_In_Out_Parameter),
                             (Addr_Type,          E_In_Parameter),
                             (Storage_Count_Type, E_In_Parameter),
                             (Storage_Count_Type, E_In_Parameter)),
                          Result_Subt     => Empty,
                          Err_On_Mismatch => False);

                  elsif Nam = Name_Copy_From then
                     Found_Match :=
                       Aspect_Argument_Profile_Matches
                         (It.Nam,
                          Profiles        =>
                            ((Typ,                 E_In_Out_Parameter),
                             (System_Address_Type, E_In_Parameter),
                             (Addr_Type,           E_In_Parameter),
                             (Storage_Count_Type,  E_In_Parameter),
                             (Storage_Count_Type,  E_In_Parameter)),
                          Result_Subt     => Empty,
                          Err_On_Mismatch => False);

                  elsif Nam = Name_Copy_To then
                     Found_Match :=
                       Aspect_Argument_Profile_Matches
                         (It.Nam,
                          Profiles        =>
                            ((Typ,                 E_In_Out_Parameter),
                             (Addr_Type,           E_In_Parameter),
                             (Storage_Count_Type,  E_In_Parameter),
                             (System_Address_Type, E_In_Parameter),
                             (Storage_Count_Type,  E_In_Parameter)),
                          Result_Subt     => Empty,
                          Err_On_Mismatch => False);

                  elsif Nam = Name_Storage_Size then
                     Found_Match :=
                       Aspect_Argument_Profile_Matches
                         (It.Nam,
                          Profiles        => (1 => (Typ, E_In_Parameter)),
                          Result_Subt     => Storage_Count_Type,
                          Err_On_Mismatch => False);
                  end if;

                  if Found_Match then
                     Set_Entity (N, It.Nam);
                     exit;
                  end if;
               end if;

               Get_Next_Interp (I, It);
            end loop;

            if not Found_Match then
               Error_Msg_N
                 ("no match found for Storage_Model_Type operation", N);
            end if;
         end;
      end if;
   end Resolve_Storage_Model_Type_Argument;

   ----------------
   -- Set_Biased --
   ----------------

   procedure Set_Biased
     (E      : Entity_Id;
      N      : Node_Id;
      Msg    : String;
      Biased : Boolean := True)
   is
   begin
      if Biased then
         Set_Has_Biased_Representation (E);

         if Warn_On_Biased_Representation then
            Error_Msg_NE
              ("?.b?" & Msg & " forces biased representation for&", N, E);
         end if;
      end if;
   end Set_Biased;

   --------------------
   -- Set_Enum_Esize --
   --------------------

   procedure Set_Enum_Esize (T : Entity_Id) is
      Lo : Uint;
      Hi : Uint;
      Sz : Unat;

   begin
      Reinit_Alignment (T);

      --  Find the minimum standard size (8,16,32,64,128) that fits

      Lo := Enumeration_Rep (Entity (Type_Low_Bound (T)));
      Hi := Enumeration_Rep (Entity (Type_High_Bound (T)));

      if Lo < 0 then
         if Lo >= -Uint_2**7 and then Hi < Uint_2**7 then
            Sz := UI_From_Int (Standard_Character_Size);
            --  Might be > 8 on some targets

         elsif Lo >= -Uint_2**15 and then Hi < Uint_2**15 then
            Sz := Uint_16;

         elsif Lo >= -Uint_2**31 and then Hi < Uint_2**31 then
            Sz := Uint_32;

         elsif Lo >= -Uint_2**63 and then Hi < Uint_2**63 then
            Sz := Uint_64;

         else pragma Assert (Lo >= -Uint_2**127 and then Hi < Uint_2**127);
            Sz := Uint_128;
         end if;

      else
         if Hi < Uint_2**8 then
            Sz := UI_From_Int (Standard_Character_Size);

         elsif Hi < Uint_2**16 then
            Sz := Uint_16;

         elsif Hi < Uint_2**32 then
            Sz := Uint_32;

         elsif Hi < Uint_2**64 then
            Sz := Uint_64;

         else pragma Assert (Hi < Uint_2**128);
            Sz := Uint_128;
         end if;
      end if;

      --  That minimum is the proper size unless we have a foreign convention
      --  and the size required is 32 or less, in which case we bump the size
      --  up to 32. This is required for C and C++ and seems reasonable for
      --  all other foreign conventions.

      if Has_Foreign_Convention (T)
        and then Esize (T) < Standard_Integer_Size

        --  Don't do this if Short_Enums on target

        and then not Target_Short_Enums
      then
         Set_Esize (T, UI_From_Int (Standard_Integer_Size));
      else
         Set_Esize (T, Sz);
      end if;
   end Set_Enum_Esize;

   -----------------------------
   -- Uninstall_Discriminants --
   -----------------------------

   procedure Uninstall_Discriminants (E : Entity_Id) is
      Disc  : Entity_Id;
      Prev  : Entity_Id;
      Outer : Entity_Id;

   begin
      --  Discriminants have been made visible for type declarations and
      --  protected type declarations, not for subtype declarations.

      if Nkind (Parent (E)) /= N_Subtype_Declaration then
         Disc := First_Discriminant (E);
         while Present (Disc) loop
            if Disc /= Current_Entity (Disc) then
               Prev := Current_Entity (Disc);
               while Present (Prev)
                 and then Present (Homonym (Prev))
                 and then Homonym (Prev) /= Disc
               loop
                  Prev := Homonym (Prev);
               end loop;
            else
               Prev := Empty;
            end if;

            Set_Is_Immediately_Visible (Disc, False);

            Outer := Homonym (Disc);
            while Present (Outer) and then Scope (Outer) = E loop
               Outer := Homonym (Outer);
            end loop;

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

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

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

            Next_Discriminant (Disc);
         end loop;
      end if;
   end Uninstall_Discriminants;

   ------------------------------
   -- Validate_Address_Clauses --
   ------------------------------

   procedure Validate_Address_Clauses is
      function Offset_Value (Expr : Node_Id) return Uint;
      --  Given an Address attribute reference, return the value in bits of its
      --  offset from the first bit of the underlying entity, or 0 if it is not
      --  known at compile time.

      ------------------
      -- Offset_Value --
      ------------------

      function Offset_Value (Expr : Node_Id) return Uint is
         N   : Node_Id := Prefix (Expr);
         Off : Uint;
         Val : Uint := Uint_0;

      begin
         --  Climb the prefix chain and compute the cumulative offset

         loop
            if Is_Entity_Name (N) then
               return Val;

            elsif Nkind (N) = N_Selected_Component then
               Off := Component_Bit_Offset (Entity (Selector_Name (N)));
               if Present (Off) and then Off >= Uint_0 then
                  Val := Val + Off;
                  N   := Prefix (N);
               else
                  return Uint_0;
               end if;

            elsif Nkind (N) = N_Indexed_Component then
               Off := Indexed_Component_Bit_Offset (N);
               if Present (Off) then
                  Val := Val + Off;
                  N   := Prefix (N);
               else
                  return Uint_0;
               end if;

            else
               return Uint_0;
            end if;
         end loop;
      end Offset_Value;

   --  Start of processing for Validate_Address_Clauses

   begin
      for J in Address_Clause_Checks.First .. Address_Clause_Checks.Last loop
         declare
            ACCR : Address_Clause_Check_Record
                     renames Address_Clause_Checks.Table (J);

            Expr : Node_Id;

            X_Alignment : Uint;
            Y_Alignment : Uint := Uint_0;

            X_Size : Uint;
            Y_Size : Uint := Uint_0;

            X_Offs : Uint;

         begin
            --  Skip processing of this entry if warning already posted, or if
            --  alignments are not set.

            if not Address_Warning_Posted (ACCR.N)
              and then Known_Alignment (ACCR.X)
              and then Known_Alignment (ACCR.Y)
            then
               Expr := Original_Node (Expression (ACCR.N));

               --  Get alignments, sizes and offset, if any

               X_Alignment := Alignment (ACCR.X);
               X_Size      := Esize (ACCR.X);

               if Present (ACCR.Y) then
                  Y_Alignment := Alignment (ACCR.Y);
                  Y_Size :=
                    (if Known_Esize (ACCR.Y) then Esize (ACCR.Y) else Uint_0);
               end if;

               if ACCR.Off
                 and then Nkind (Expr) = N_Attribute_Reference
                 and then Attribute_Name (Expr) = Name_Address
               then
                  X_Offs := Offset_Value (Expr);
               else
                  X_Offs := Uint_0;
               end if;

               --  Check for known value not multiple of alignment

               if No (ACCR.Y) then
                  if not Alignment_Checks_Suppressed (ACCR)
                    and then X_Alignment /= 0
                    and then ACCR.A mod X_Alignment /= 0
                  then
                     Error_Msg_NE
                       ("??specified address for& is inconsistent with "
                        & "alignment", ACCR.N, ACCR.X);
                     Error_Msg_N
                       ("\??program execution may be erroneous (RM 13.3(27))",
                        ACCR.N);

                     Error_Msg_Uint_1 := X_Alignment;
                     Error_Msg_NE ("\??alignment of & is ^", ACCR.N, ACCR.X);
                  end if;

               --  Check for large object overlaying smaller one

               elsif Y_Size > Uint_0
                 and then X_Size > Uint_0
                 and then X_Offs + X_Size > Y_Size
               then
                  Error_Msg_NE ("??& overlays smaller object", ACCR.N, ACCR.X);
                  Error_Msg_N
                    ("\??program execution may be erroneous", ACCR.N);

                  Error_Msg_Uint_1 := X_Size;
                  Error_Msg_NE ("\??size of & is ^", ACCR.N, ACCR.X);

                  Error_Msg_Uint_1 := Y_Size;
                  Error_Msg_NE ("\??size of & is ^", ACCR.N, ACCR.Y);

                  if Y_Size >= X_Size then
                     Error_Msg_Uint_1 := X_Offs;
                     Error_Msg_NE ("\??but offset of & is ^", ACCR.N, ACCR.X);
                  end if;

               --  Check for inadequate alignment, both of the base object
               --  and of the offset, if any. We only do this check if the
               --  run-time Alignment_Check is active. No point in warning
               --  if this check has been suppressed (or is suppressed by
               --  default in the non-strict alignment machine case).

               --  Note: we do not check the alignment if we gave a size
               --  warning, since it would likely be redundant.

               elsif not Alignment_Checks_Suppressed (ACCR)
                 and then Y_Alignment /= Uint_0
                 and then
                   (Y_Alignment < X_Alignment
                     or else
                       (ACCR.Off
                         and then Nkind (Expr) = N_Attribute_Reference
                         and then Attribute_Name (Expr) = Name_Address
                         and then Has_Compatible_Alignment
                                    (ACCR.X, Prefix (Expr), True) /=
                                      Known_Compatible))
               then
                  Error_Msg_NE
                    ("??specified address for& may be inconsistent with "
                     & "alignment", ACCR.N, ACCR.X);
                  Error_Msg_N
                    ("\??program execution may be erroneous (RM 13.3(27))",
                     ACCR.N);

                  Error_Msg_Uint_1 := X_Alignment;
                  Error_Msg_NE ("\??alignment of & is ^", ACCR.N, ACCR.X);

                  Error_Msg_Uint_1 := Y_Alignment;
                  Error_Msg_NE ("\??alignment of & is ^", ACCR.N, ACCR.Y);

                  if Y_Alignment >= X_Alignment then
                     Error_Msg_N
                       ("\??but offset is not multiple of alignment", ACCR.N);
                  end if;
               end if;
            end if;
         end;
      end loop;
   end Validate_Address_Clauses;

   ------------------------------
   -- Validate_Iterable_Aspect --
   ------------------------------

   procedure Validate_Iterable_Aspect (Typ : Entity_Id; ASN : Node_Id) is
      Assoc : Node_Id;
      Expr  : Node_Id;

      Prim   : Node_Id;
      Cursor : constant Entity_Id := Get_Cursor_Type (ASN, Typ);

      First_Id       : Entity_Id;
      Last_Id        : Entity_Id;
      Next_Id        : Entity_Id;
      Has_Element_Id : Entity_Id;
      Element_Id     : Entity_Id;

   begin
      --  If previous error aspect is unusable

      if Cursor = Any_Type then
         return;
      end if;

      First_Id       := Empty;
      Last_Id        := Empty;
      Next_Id        := Empty;
      Has_Element_Id := Empty;
      Element_Id     := Empty;

      --  Each expression must resolve to a function with the proper signature

      Assoc := First (Component_Associations (Expression (ASN)));
      while Present (Assoc) loop
         Expr := Expression (Assoc);
         Analyze (Expr);

         Prim := First (Choices (Assoc));

         if Nkind (Prim) /= N_Identifier or else Present (Next (Prim)) then
            Error_Msg_N ("illegal name in association", Prim);

         elsif Chars (Prim) = Name_First then
            Resolve_Iterable_Operation (Expr, Cursor, Typ, Name_First);
            First_Id := Entity (Expr);

         elsif Chars (Prim) = Name_Last then
            Resolve_Iterable_Operation (Expr, Cursor, Typ, Name_Last);
            Last_Id := Entity (Expr);

         elsif Chars (Prim) = Name_Previous then
            Resolve_Iterable_Operation (Expr, Cursor, Typ, Name_Previous);
            Last_Id := Entity (Expr);

         elsif Chars (Prim) = Name_Next then
            Resolve_Iterable_Operation (Expr, Cursor, Typ, Name_Next);
            Next_Id := Entity (Expr);

         elsif Chars (Prim) = Name_Has_Element then
            Resolve_Iterable_Operation (Expr, Cursor, Typ, Name_Has_Element);
            Has_Element_Id := Entity (Expr);

         elsif Chars (Prim) = Name_Element then
            Resolve_Iterable_Operation (Expr, Cursor, Typ, Name_Element);
            Element_Id := Entity (Expr);

         else
            Error_Msg_N ("invalid name for iterable function", Prim);
         end if;

         Next (Assoc);
      end loop;

      if No (First_Id) then
         Error_Msg_N ("match for First primitive not found", ASN);

      elsif No (Next_Id) then
         Error_Msg_N ("match for Next primitive not found", ASN);

      elsif No (Has_Element_Id) then
         Error_Msg_N ("match for Has_Element primitive not found", ASN);

      elsif No (Element_Id) or else No (Last_Id) then
         null;  --  optional
      end if;
   end Validate_Iterable_Aspect;

   ------------------------------
   -- Validate_Literal_Aspect --
   ------------------------------

   procedure Validate_Literal_Aspect (Typ : Entity_Id; ASN : Node_Id) is
      A_Id        : constant Aspect_Id := Get_Aspect_Id (ASN);
      pragma Assert (A_Id in Aspect_Integer_Literal |
                             Aspect_Real_Literal | Aspect_String_Literal);
      Func_Name   : constant Node_Id := Expression (ASN);
      Overloaded  : Boolean := Is_Overloaded (Func_Name);

      I            : Interp_Index := 0;
      It           : Interp;
      Param_Type   : Entity_Id;
      Match_Found  : Boolean := False;
      Match2_Found : Boolean := False;
      Is_Match     : Boolean;
      Match        : Interp;
      Match2       : Entity_Id := Empty;

      function Matching
        (Param_Id : Entity_Id; Param_Type : Entity_Id) return Boolean;
      --  Return True if Param_Id is a non aliased in parameter whose base type
      --  is Param_Type.

      --------------
      -- Matching --
      --------------

      function Matching
        (Param_Id : Entity_Id; Param_Type : Entity_Id) return Boolean is
      begin
         return Base_Type (Etype (Param_Id)) = Param_Type
           and then Ekind (Param_Id) = E_In_Parameter
           and then not Is_Aliased (Param_Id);
      end Matching;

   begin
      if not Is_Type (Typ) then
         Error_Msg_N ("aspect can only be specified for a type", ASN);
         return;

      elsif not Is_First_Subtype (Typ) then
         Error_Msg_N ("aspect cannot be specified for a subtype", ASN);
         return;
      end if;

      if A_Id = Aspect_String_Literal then
         if Is_String_Type (Typ) then
            Error_Msg_N ("aspect cannot be specified for a string type", ASN);
            return;
         end if;

         Param_Type := Standard_Wide_Wide_String;

      else
         if Is_Numeric_Type (Typ) then
            Error_Msg_N ("aspect cannot be specified for a numeric type", ASN);
            return;
         end if;

         Param_Type := Standard_String;
      end if;

      if not Overloaded and then not Present (Entity (Func_Name)) then
         --  The aspect is specified by a subprogram name, which
         --  may be an operator name given originally by a string.

         if Is_Operator_Name (Chars (Func_Name)) then
            Analyze_Operator_Symbol (Func_Name);
         else
            Analyze (Func_Name);
         end if;

         Overloaded := Is_Overloaded (Func_Name);
      end if;

      if Overloaded then
         Get_First_Interp (Func_Name, I => I, It => It);
      else
         --  only one possible interpretation
         It.Nam := Entity (Func_Name);
         pragma Assert (Present (It.Nam));
      end if;

      while It.Nam /= Empty loop
         Is_Match := False;

         if Ekind (It.Nam) = E_Function
           and then Base_Type (Etype (It.Nam)) = Base_Type (Typ)
         then
            declare
               Params     : constant List_Id :=
                 Parameter_Specifications (Parent (It.Nam));
               Param_Spec : Node_Id;

            begin
               if List_Length (Params) = 1 then
                  Param_Spec := First (Params);
                  Is_Match :=
                    Matching (Defining_Identifier (Param_Spec), Param_Type);

               --  Look for the optional overloaded 2-param Real_Literal

               elsif List_Length (Params) = 2
                 and then A_Id = Aspect_Real_Literal
               then
                  Param_Spec := First (Params);

                  if Matching (Defining_Identifier (Param_Spec), Param_Type)
                  then
                     Param_Spec := Next (Param_Spec);

                     if Matching (Defining_Identifier (Param_Spec), Param_Type)
                     then
                        if No (Match2) then
                           Match2 := It.Nam;
                           Match2_Found := True;
                        else
                           --  If we find more than one possible match then
                           --  do not take any into account here: since the
                           --  2-parameter version of Real_Literal is optional
                           --  we cannot generate an error here, so let
                           --  standard resolution fail later if we do need to
                           --  call this variant.

                           Match2_Found := False;
                        end if;
                     end if;
                  end if;
               end if;
            end;
         end if;

         if Is_Match then
            if Match_Found then
               Error_Msg_N ("aspect specification is ambiguous", ASN);
               return;
            end if;

            Match_Found := True;
            Match := It;
         end if;

         exit when not Overloaded;

         if not Is_Match then
            Remove_Interp (I => I);
         end if;

         Get_Next_Interp (I => I, It => It);
      end loop;

      if not Match_Found then
         Error_Msg_N
           ("function name in aspect specification cannot be resolved", ASN);
         return;
      end if;

      Set_Entity (Func_Name, Match.Nam);
      Set_Etype (Func_Name, Etype (Match.Nam));
      Set_Is_Overloaded (Func_Name, False);

      --  Record the match for 2-parameter function if found

      if Match2_Found then
         Set_Related_Expression (Match.Nam, Match2);
      end if;
   end Validate_Literal_Aspect;

   ----------------------------------------
   -- Validate_Storage_Model_Type_Aspect --
   ----------------------------------------

   procedure Validate_Storage_Model_Type_Aspect
     (Typ : Entity_Id; ASN : Node_Id)
   is
      Assoc  : Node_Id;
      Choice : Entity_Id;
      Expr   : Node_Id;

      Address_Type_Id : Entity_Id := Empty;
      Null_Address_Id : Entity_Id := Empty;
      Allocate_Id     : Entity_Id := Empty;
      Deallocate_Id   : Entity_Id := Empty;
      Copy_From_Id    : Entity_Id := Empty;
      Copy_To_Id      : Entity_Id := Empty;
      Storage_Size_Id : Entity_Id := Empty;

   begin
      --  Each expression must resolve to an entity of the right kind or proper
      --  profile.

      Assoc := First (Component_Associations (Expression (ASN)));
      while Present (Assoc) loop
         Expr := Expression (Assoc);
         Analyze (Expr);

         Choice := First (Choices (Assoc));

         if Nkind (Choice) /= N_Identifier or else Present (Next (Choice)) then
            Error_Msg_N ("illegal name in association", Choice);

         elsif Chars (Choice) = Name_Address_Type then
            if Assoc /= First (Component_Associations (Expression (ASN))) then
               Error_Msg_N ("Address_Type must be first association", Choice);
            end if;

            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Address_Type);
            Address_Type_Id := Entity (Expr);

         --  Shouldn't we check for duplicates of the same subaspect name,
         --  and issue an error in such cases???

         elsif not Present (Address_Type_Id) then
            Error_Msg_N
              ("Address_Type missing, must be first association", Choice);

         elsif Chars (Choice) = Name_Null_Address then
            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Null_Address);
            Null_Address_Id := Entity (Expr);

         elsif Chars (Choice) = Name_Allocate then
            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Allocate);
            Allocate_Id := Entity (Expr);

         elsif Chars (Choice) = Name_Deallocate then
            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Deallocate);
            Deallocate_Id := Entity (Expr);

         elsif Chars (Choice) = Name_Copy_From then
            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Copy_From);
            Copy_From_Id := Entity (Expr);

         elsif Chars (Choice) = Name_Copy_To then
            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Copy_To);
            Copy_To_Id := Entity (Expr);

         elsif Chars (Choice) = Name_Storage_Size then
            Resolve_Storage_Model_Type_Argument
              (Expr, Typ, Address_Type_Id, Name_Storage_Size);
            Storage_Size_Id := Entity (Expr);

         else
            Error_Msg_N
              ("invalid name for Storage_Model_Type argument", Choice);
         end if;

         Next (Assoc);
      end loop;

      if No (Address_Type_Id) then
         Error_Msg_N ("match for Address_Type not found", ASN);

      elsif No (Null_Address_Id) then
         Error_Msg_N ("match for Null_Address primitive not found", ASN);

      elsif No (Allocate_Id) then
         Error_Msg_N ("match for Allocate primitive not found", ASN);

      elsif No (Deallocate_Id) then
         Error_Msg_N ("match for Deallocate primitive not found", ASN);

      elsif No (Copy_From_Id) then
         Error_Msg_N ("match for Copy_From primitive not found", ASN);

      elsif No (Copy_To_Id) then
         Error_Msg_N ("match for Copy_To primitive not found", ASN);

      elsif No (Storage_Size_Id) then
         Error_Msg_N ("match for Storage_Size primitive not found", ASN);
      end if;
   end Validate_Storage_Model_Type_Aspect;

   -----------------------------------
   -- Validate_Unchecked_Conversion --
   -----------------------------------

   procedure Validate_Unchecked_Conversion
     (N        : Node_Id;
      Act_Unit : Entity_Id)
   is
      Source : Entity_Id;
      Target : Entity_Id;

      procedure Warn_Nonportable (RE : RE_Id);
      --  Warn if either source or target of the conversion is a predefined
      --  private type, whose representation might differ between releases and
      --  targets of the compiler.

      ----------------------
      -- Warn_Nonportable --
      ----------------------

      procedure Warn_Nonportable (RE : RE_Id) is
      begin
         if Is_RTE (Source, RE) or else Is_RTE (Target, RE) then
            pragma Assert (Is_Private_Type (RTE (RE)));
            Error_Msg_NE
              ("?z?representation of & values may change between "
               & "'G'N'A'T versions", N, RTE (RE));
         end if;
      end Warn_Nonportable;

      --  Local variables

      Vnode  : Node_Id;

   --  Start of processing for Validate_Unchecked_Conversion

   begin
      --  Obtain source and target types. Note that we call Ancestor_Subtype
      --  here because the processing for generic instantiation always makes
      --  subtypes, and we want the original frozen actual types.

      Source := Ancestor_Subtype (Etype (First_Formal (Act_Unit)));
      Target := Ancestor_Subtype (Etype (Act_Unit));

      --  If either type is generic, the instantiation happens within a generic
      --  unit, and there is nothing to check. The proper check will happen
      --  when the enclosing generic is instantiated.

      if Is_Generic_Type (Source) or else Is_Generic_Type (Target) then
         return;
      end if;

      --  Warn if one of the operands is a private type declared in
      --  Ada.Calendar or Ada.Real_Time. Do not emit a warning when compiling
      --  GNAT-related sources.

      if Warn_On_Unchecked_Conversion
        and then not In_Predefined_Unit (N)
      then
         Warn_Nonportable (RO_CA_Time);
         Warn_Nonportable (RO_RT_Time);
         Warn_Nonportable (RE_Time_Span);
      end if;

      --  If we are dealing with private types, then do the check on their
      --  fully declared counterparts if the full declarations have been
      --  encountered (they don't have to be visible, but they must exist).

      if Is_Private_Type (Source)
        and then Present (Underlying_Type (Source))
      then
         Source := Underlying_Type (Source);
      end if;

      if Is_Private_Type (Target)
        and then Present (Underlying_Type (Target))
      then
         Target := Underlying_Type (Target);
      end if;

      --  Source may be unconstrained array, but not target, except in relaxed
      --  semantics mode.

      if Is_Array_Type (Target)
        and then not Is_Constrained (Target)
        and then not Relaxed_RM_Semantics
      then
         Error_Msg_N
           ("unchecked conversion to unconstrained array not allowed", N);
         return;
      end if;

      --  Warn if conversion between two different convention pointers

      if Is_Access_Type (Target)
        and then Is_Access_Type (Source)
        and then Convention (Target) /= Convention (Source)
        and then Warn_On_Unchecked_Conversion
      then
         --  Give warnings for subprogram pointers only on most targets

         if Is_Access_Subprogram_Type (Target)
           or else Is_Access_Subprogram_Type (Source)
         then
            Error_Msg_N
              ("?z?conversion between pointers with different conventions!",
               N);
         end if;
      end if;

      --  Make entry in unchecked conversion table for later processing by
      --  Validate_Unchecked_Conversions, which will check sizes and alignments
      --  (using values set by the back end where possible). This is only done
      --  if the appropriate warning is active.

      if Warn_On_Unchecked_Conversion then
         Unchecked_Conversions.Append
           (New_Val => UC_Entry'(Eloc     => Sloc (N),
                                 Source   => Source,
                                 Target   => Target,
                                 Act_Unit => Act_Unit));

         --  If both sizes are known statically now, then back-end annotation
         --  is not required to do a proper check but if either size is not
         --  known statically, then we need the annotation.

         if Known_Static_RM_Size (Source)
              and then
            Known_Static_RM_Size (Target)
         then
            null;
         else
            Back_Annotate_Rep_Info := True;
         end if;
      end if;

      --  If unchecked conversion to access type, and access type is declared
      --  in the same unit as the unchecked conversion, then set the flag
      --  No_Strict_Aliasing (no strict aliasing is implicit here)

      if Is_Access_Type (Target)
        and then In_Same_Source_Unit (Target, N)
      then
         Set_No_Strict_Aliasing (Implementation_Base_Type (Target));
      end if;

      --  If the unchecked conversion is between Address and an access
      --  subprogram type, show that we shouldn't use an internal
      --  representation for the access subprogram type.

      if Is_Access_Subprogram_Type (Target)
        and then Is_Descendant_Of_Address (Source)
        and then In_Same_Source_Unit (Target, N)
      then
         Set_Can_Use_Internal_Rep (Target, False);
      elsif Is_Access_Subprogram_Type (Source)
        and then Is_Descendant_Of_Address (Target)
        and then In_Same_Source_Unit (Source, N)
      then
         Set_Can_Use_Internal_Rep (Source, False);
      end if;

      --  Generate N_Validate_Unchecked_Conversion node for back end in case
      --  the back end needs to perform special validation checks.

      --  Shouldn't this be in Exp_Ch13, since the check only gets done if we
      --  have full expansion and the back end is called ???

      Vnode :=
        Make_Validate_Unchecked_Conversion (Sloc (N));
      Set_Source_Type (Vnode, Source);
      Set_Target_Type (Vnode, Target);

      --  If the unchecked conversion node is in a list, just insert before it.
      --  If not we have some strange case, not worth bothering about.

      if Is_List_Member (N) then
         Insert_After (N, Vnode);
      end if;
   end Validate_Unchecked_Conversion;

   ------------------------------------
   -- Validate_Unchecked_Conversions --
   ------------------------------------

   procedure Validate_Unchecked_Conversions is
      function Is_Null_Array (T : Entity_Id) return Boolean;
      --  We want to warn in the case of converting to a wrong-sized array of
      --  bytes, including the zero-size case. This returns True in that case,
      --  which is necessary because a size of 0 is used to indicate both an
      --  unknown size and a size of 0. It's OK for this to return True in
      --  other zero-size cases, but we don't go out of our way; for example,
      --  we don't bother with multidimensional arrays.

      function Is_Null_Array (T : Entity_Id) return Boolean is
      begin
         if Is_Array_Type (T) and then Is_Constrained (T) then
            declare
               Index : constant Node_Id := First_Index (T);
               R : Node_Id; -- N_Range
            begin
               case Nkind (Index) is
                  when N_Range =>
                     R := Index;
                  when N_Subtype_Indication =>
                     R := Range_Expression (Constraint (Index));
                  when N_Identifier | N_Expanded_Name =>
                     R := Scalar_Range (Entity (Index));
                  when others =>
                     raise Program_Error;
               end case;

               return Is_Null_Range (Low_Bound (R), High_Bound (R));
            end;
         end if;

         return False;
      end Is_Null_Array;

   begin
      for N in Unchecked_Conversions.First .. Unchecked_Conversions.Last loop
         declare
            T : UC_Entry renames Unchecked_Conversions.Table (N);

            Act_Unit : constant Entity_Id  := T.Act_Unit;
            Eloc     : constant Source_Ptr := T.Eloc;
            Source   : constant Entity_Id  := T.Source;
            Target   : constant Entity_Id  := T.Target;

            Source_Siz : Uint;
            Target_Siz : Uint;

         begin
            --  Skip if function marked as warnings off

            if Warnings_Off (Act_Unit) or else Serious_Errors_Detected > 0 then
               goto Continue;
            end if;

           --  Don't do the check if warnings off for either type, note the
           --  deliberate use of OR here instead of OR ELSE to get the flag
           --  Warnings_Off_Used set for both types if appropriate.

            if Has_Warnings_Off (Source) or Has_Warnings_Off (Target) then
               goto Continue;
            end if;

            if (Known_Static_RM_Size (Source)
                  and then Known_Static_RM_Size (Target))
              or else Is_Null_Array (Target)
            then
               --  This validation check, which warns if we have unequal sizes
               --  for unchecked conversion, and thus implementation dependent
               --  semantics, is one of the few occasions on which we use the
               --  official RM size instead of Esize. See description in Einfo
               --  "Handling of Type'Size Values" for details.

               Source_Siz := RM_Size (Source);
               Target_Siz := RM_Size (Target);

               if Present (Source_Siz) and then Present (Target_Siz)
                 and then Source_Siz /= Target_Siz
               then
                  Error_Msg
                    ("?z?types for unchecked conversion have different sizes!",
                     Eloc, Act_Unit);

                  if All_Errors_Mode then
                     Error_Msg_Name_1 := Chars (Source);
                     Error_Msg_Uint_1 := Source_Siz;
                     Error_Msg_Name_2 := Chars (Target);
                     Error_Msg_Uint_2 := Target_Siz;
                     Error_Msg ("\size of % is ^, size of % is ^?z?", Eloc);

                     Error_Msg_Uint_1 := UI_Abs (Source_Siz - Target_Siz);

                     if Is_Discrete_Type (Source)
                          and then
                        Is_Discrete_Type (Target)
                     then
                        if Source_Siz > Target_Siz then
                           Error_Msg
                             ("\?z?^ high order bits of source will "
                              & "be ignored!", Eloc);

                        elsif Is_Unsigned_Type (Source) then
                           Error_Msg
                             ("\?z?source will be extended with ^ high order "
                              & "zero bits!", Eloc);

                        else
                           Error_Msg
                             ("\?z?source will be extended with ^ high order "
                              & "sign bits!", Eloc);
                        end if;

                     elsif Source_Siz < Target_Siz then
                        if Is_Discrete_Type (Target) then
                           if Bytes_Big_Endian then
                              Error_Msg
                                ("\?z?target value will include ^ undefined "
                                 & "low order bits!", Eloc, Act_Unit);
                           else
                              Error_Msg
                                ("\?z?target value will include ^ undefined "
                                 & "high order bits!", Eloc, Act_Unit);
                           end if;

                        else
                           Error_Msg
                             ("\?z?^ trailing bits of target value will be "
                              & "undefined!", Eloc, Act_Unit);
                        end if;

                     else pragma Assert (Source_Siz > Target_Siz);
                        if Is_Discrete_Type (Source) then
                           if Bytes_Big_Endian then
                              Error_Msg
                                ("\?z?^ low order bits of source will be "
                                 & "ignored!", Eloc, Act_Unit);
                           else
                              Error_Msg
                                ("\?z?^ high order bits of source will be "
                                 & "ignored!", Eloc, Act_Unit);
                           end if;

                        else
                           Error_Msg
                             ("\?z?^ trailing bits of source will be "
                              & "ignored!", Eloc, Act_Unit);
                        end if;
                     end if;
                  end if;
               end if;
            end if;

            --  If both types are access types, we need to check the alignment.
            --  If the alignment of both is specified, we can do it here.

            if Serious_Errors_Detected = 0
              and then Is_Access_Type (Source)
              and then Is_Access_Type (Target)
              and then Target_Strict_Alignment
              and then Present (Designated_Type (Source))
              and then Present (Designated_Type (Target))
            then
               declare
                  D_Source : constant Entity_Id := Designated_Type (Source);
                  D_Target : constant Entity_Id := Designated_Type (Target);

               begin
                  if Known_Alignment (D_Source)
                       and then
                     Known_Alignment (D_Target)
                  then
                     declare
                        Source_Align : constant Uint := Alignment (D_Source);
                        Target_Align : constant Uint := Alignment (D_Target);

                     begin
                        if Source_Align < Target_Align
                          and then not Is_Tagged_Type (D_Source)

                          --  Suppress warning if warnings suppressed on either
                          --  type or either designated type. Note the use of
                          --  OR here instead of OR ELSE. That is intentional,
                          --  we would like to set flag Warnings_Off_Used in
                          --  all types for which warnings are suppressed.

                          and then not (Has_Warnings_Off (D_Source)
                                          or
                                        Has_Warnings_Off (D_Target)
                                          or
                                        Has_Warnings_Off (Source)
                                          or
                                        Has_Warnings_Off (Target))
                        then
                           Error_Msg_Uint_1 := Target_Align;
                           Error_Msg_Uint_2 := Source_Align;
                           Error_Msg_Node_1 := D_Target;
                           Error_Msg_Node_2 := D_Source;
                           Error_Msg
                             ("?z?alignment of & (^) is stricter than "
                              & "alignment of & (^)!", Eloc, Act_Unit);
                           Error_Msg
                             ("\?z?resulting access value may have invalid "
                              & "alignment!", Eloc, Act_Unit);
                        end if;
                     end;
                  end if;
               end;
            end if;
         end;

      <<Continue>>
         null;
      end loop;
   end Validate_Unchecked_Conversions;

end Sem_Ch13;
