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

with Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
with Contracts;      use Contracts;
with Debug;          use Debug;
with 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 propageted 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 propageted 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 propageted 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 Get_Aspect_Id (Chars (N)) /= No_Aspect 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 subytype.

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

      Non_Static : exception;
      --  Raised if something non-static is found

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

      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) return RList;
      --  Given a single membership entry (range, value, or subtype), returns
      --  the corresponding range list. Raises Static_Error if not static.

      function Membership_Entries (N : Node_Id) 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).

      function Stat_Pred (Typ : Entity_Id) return RList;
      --  Given a type, if it has a static predicate, then return the predicate
      --  as a range list, otherwise raise Non_Static.

      -----------
      -- "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) 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))
                        and
                      Get_RList (Right_Opnd (Exp));

            --  Or

            when N_Op_Or
               | N_Or_Else
            =>
               return Get_RList (Left_Opnd (Exp))
                        or
                      Get_RList (Right_Opnd (Exp));

            --  Not

            when N_Op_Not =>
               return not Get_RList (Right_Opnd (Exp));

               --  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
                  raise Non_Static;
               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
                  raise Non_Static;
               end if;

               if Present (Right_Opnd (Exp)) then
                  return Membership_Entry (Right_Opnd (Exp));
               else
                  return Membership_Entries (First (Alternatives (Exp)));
               end if;

            --  Negative membership (NOT IN)

            when N_Not_In =>
               if not Is_Type_Ref (Left_Opnd (Exp)) then
                  raise Non_Static;
               end if;

               if Present (Right_Opnd (Exp)) then
                  return not Membership_Entry (Right_Opnd (Exp));
               else
                  return not Membership_Entries (First (Alternatives (Exp)));
               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)));
                     end if;
                  end;
               end if;

               --  Other function call cases are non-static

               raise Non_Static;

            --  Qualified expression, dig out the expression

            when N_Qualified_Expression =>
               return Get_RList (Expression (Exp));

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

                     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));
               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));
               else
                  raise Non_Static;
               end if;

            --  Xor operator

            when N_Op_Xor =>
               return (Get_RList (Left_Opnd (Exp))
                        and not Get_RList (Right_Opnd (Exp)))
                 or   (Get_RList (Right_Opnd (Exp))
                        and not Get_RList (Left_Opnd (Exp)));

            --  Any other node type is non-static

            when others =>
               raise Non_Static;
         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) return RList is
      begin
         if No (Next (N)) then
            return Membership_Entry (N);
         else
            return Membership_Entry (N) or Membership_Entries (Next (N));
         end if;
      end Membership_Entries;

      ----------------------
      -- Membership_Entry --
      ----------------------

      function Membership_Entry (N : Node_Id) 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
               raise Non_Static;
            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));

               --  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
                  raise Non_Static;
               end if;

            --  Any other kind of identifier in predicate (e.g. a non-static
            --  expression value) means this is not a static predicate.

            else
               raise Non_Static;
            end if;
         end if;
      end Membership_Entry;

      ---------------
      -- Stat_Pred --
      ---------------

      function Stat_Pred (Typ : Entity_Id) return RList is
      begin
         --  Not static if type does not have static predicates

         if not Has_Static_Predicate (Typ) then
            raise Non_Static;
         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
         Ranges : constant RList := Get_RList (Expr);
         --  Range list from expression if it is static

         Plist : List_Id;

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

      --  If non-static, return doing nothing

   exception
      when Non_Static =>
         return;
   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_Defining_Identifier (Loc,
                   Chars => New_Internal_Name ('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 :=
           "?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 ("?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_Entity (Tagged_Parent);
            while Present (Pcomp) loop
               if Ekind (Pcomp) in E_Discriminant | E_Component then
                  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;
               else

                  --  Skip anonymous types generated for constrained array
                  --  or record components.

                  null;
               end if;

               Next_Entity (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.

      if not Overlap_Detected 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_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);
                     Pop_Type (E);

                  else
                     Check_Aspect_At_Freeze_Point (Ritem);
                  end if;
               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 correponding 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 = Aspect_Integer_Literal) or
                     (A_Id = Aspect_Real_Literal) or
                     (A_Id = Aspect_String_Literal));
      Func_Name   : constant Node_Id := Expression (ASN);
      Overloaded  : Boolean := Is_Overloaded (Func_Name);

      I            : Interp_Index;
      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;

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