------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ A T T R                              --
--                                                                          --
--                                 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 Ada.Characters.Latin_1; use Ada.Characters.Latin_1;

with Aspects;        use Aspects;
with Atree;          use Atree;
with Casing;         use Casing;
with Checks;         use Checks;
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 Eval_Fat;
with Exp_Dist;       use Exp_Dist;
with Exp_Util;       use Exp_Util;
with Expander;       use Expander;
with Freeze;         use Freeze;
with Gnatvsn;        use Gnatvsn;
with Itypes;         use Itypes;
with Lib;            use Lib;
with Lib.Xref;       use Lib.Xref;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sdefault;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch10;       use Sem_Ch10;
with Sem_Dim;        use Sem_Dim;
with Sem_Dist;       use Sem_Dist;
with Sem_Elab;       use Sem_Elab;
with Sem_Elim;       use Sem_Elim;
with Sem_Eval;       use Sem_Eval;
with Sem_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;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with System;
with Stringt;        use Stringt;
with Style;
with Stylesw;        use Stylesw;
with Targparm;       use Targparm;
with Ttypes;         use Ttypes;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;
with Uname;          use Uname;
with Urealp;         use Urealp;

with System.CRC32;   use System.CRC32;

package body Sem_Attr is

   True_Value  : constant Uint := Uint_1;
   False_Value : constant Uint := Uint_0;
   --  Synonyms to be used when these constants are used as Boolean values

   Bad_Attribute : exception;
   --  Exception raised if an error is detected during attribute processing,
   --  used so that we can abandon the processing so we don't run into
   --  trouble with cascaded errors.

   --  The following array is the list of attributes defined in the Ada 83 RM.
   --  In Ada 83 mode, these are the only recognized attributes. In other Ada
   --  modes all these attributes are recognized, even if removed in Ada 95.

   Attribute_83 : constant Attribute_Class_Array := Attribute_Class_Array'(
      Attribute_Address                      |
      Attribute_Aft                          |
      Attribute_Alignment                    |
      Attribute_Base                         |
      Attribute_Callable                     |
      Attribute_Constrained                  |
      Attribute_Count                        |
      Attribute_Delta                        |
      Attribute_Digits                       |
      Attribute_Emax                         |
      Attribute_Epsilon                      |
      Attribute_First                        |
      Attribute_First_Bit                    |
      Attribute_Fore                         |
      Attribute_Image                        |
      Attribute_Large                        |
      Attribute_Last                         |
      Attribute_Last_Bit                     |
      Attribute_Leading_Part                 |
      Attribute_Length                       |
      Attribute_Machine_Emax                 |
      Attribute_Machine_Emin                 |
      Attribute_Machine_Mantissa             |
      Attribute_Machine_Overflows            |
      Attribute_Machine_Radix                |
      Attribute_Machine_Rounds               |
      Attribute_Mantissa                     |
      Attribute_Pos                          |
      Attribute_Position                     |
      Attribute_Pred                         |
      Attribute_Range                        |
      Attribute_Safe_Emax                    |
      Attribute_Safe_Large                   |
      Attribute_Safe_Small                   |
      Attribute_Size                         |
      Attribute_Small                        |
      Attribute_Storage_Size                 |
      Attribute_Succ                         |
      Attribute_Terminated                   |
      Attribute_Val                          |
      Attribute_Value                        |
      Attribute_Width                        => True,
      others                                 => False);

   --  The following array is the list of attributes defined in the Ada 2005
   --  RM which are not defined in Ada 95. These are recognized in Ada 95 mode,
   --  but in Ada 95 they are considered to be implementation defined.

   Attribute_05 : constant Attribute_Class_Array := Attribute_Class_Array'(
      Attribute_Machine_Rounding             |
      Attribute_Mod                          |
      Attribute_Priority                     |
      Attribute_Stream_Size                  |
      Attribute_Wide_Wide_Width              => True,
      others                                 => False);

   --  The following array is the list of attributes defined in the Ada 2012
   --  RM which are not defined in Ada 2005. These are recognized in Ada 95
   --  and Ada 2005 modes, but are considered to be implementation defined.

   Attribute_12 : constant Attribute_Class_Array := Attribute_Class_Array'(
      Attribute_First_Valid                  |
      Attribute_Has_Same_Storage             |
      Attribute_Last_Valid                   |
      Attribute_Max_Alignment_For_Allocation => True,
      others                                 => False);

   --  The following array is the list of attributes defined in the Ada 2022
   --  RM which are not defined in Ada 2012. These are recognized in Ada
   --  95/2005/2012 modes, but are considered to be implementation defined.

   Attribute_22 : constant Attribute_Class_Array := Attribute_Class_Array'(
      Attribute_Enum_Rep                     |
      Attribute_Enum_Val                     => True,
      Attribute_Preelaborable_Initialization => True,
      others                                 => False);

   --  The following array contains all attributes that imply a modification
   --  of their prefixes or result in an access value. Such prefixes can be
   --  considered as lvalues.

   Attribute_Name_Implies_Lvalue_Prefix : constant Attribute_Class_Array :=
      Attribute_Class_Array'(
      Attribute_Access                       |
      Attribute_Address                      |
      Attribute_Input                        |
      Attribute_Read                         |
      Attribute_Unchecked_Access             |
      Attribute_Unrestricted_Access          => True,
      others                                 => False);

   -----------------------
   -- Local_Subprograms --
   -----------------------

   procedure Eval_Attribute (N : Node_Id);
   --  Performs compile time evaluation of attributes where possible, leaving
   --  the Is_Static_Expression/Raises_Constraint_Error flags appropriately
   --  set, and replacing the node with a literal node if the value can be
   --  computed at compile time. All static attribute references are folded,
   --  as well as a number of cases of non-static attributes that can always
   --  be computed at compile time (e.g. floating-point model attributes that
   --  are applied to non-static subtypes). Of course in such cases, the
   --  Is_Static_Expression flag will not be set on the resulting literal.
   --  Note that the only required action of this procedure is to catch the
   --  static expression cases as described in the RM. Folding of other cases
   --  is done where convenient, but some additional non-static folding is in
   --  Expand_N_Attribute_Reference in cases where this is more convenient.

   function Is_Anonymous_Tagged_Base
     (Anon : Entity_Id;
      Typ  : Entity_Id) return Boolean;
   --  For derived tagged types that constrain parent discriminants we build
   --  an anonymous unconstrained base type. We need to recognize the relation
   --  between the two when analyzing an access attribute for a constrained
   --  component, before the full declaration for Typ has been analyzed, and
   --  where therefore the prefix of the attribute does not match the enclosing
   --  scope.

   procedure Set_Boolean_Result (N : Node_Id; B : Boolean);
   --  Rewrites node N with an occurrence of either Standard_False or
   --  Standard_True, depending on the value of the parameter B. The
   --  result is marked as a static expression.

   -----------------------
   -- Analyze_Attribute --
   -----------------------

   procedure Analyze_Attribute (N : Node_Id) is
      Loc     : constant Source_Ptr   := Sloc (N);
      Aname   : constant Name_Id      := Attribute_Name (N);
      Exprs   : constant List_Id      := Expressions (N);
      Attr_Id : constant Attribute_Id := Get_Attribute_Id (Aname);
      P_Old   : constant Node_Id      := Prefix (N);

      P       : Node_Id := P_Old;
      E1      : Node_Id;
      E2      : Node_Id;

      P_Type : Entity_Id := Empty;
      --  Type of prefix after analysis

      P_Base_Type : Entity_Id := Empty;
      --  Base type of prefix after analysis

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

      procedure Address_Checks;
      --  Semantic checks for valid use of Address attribute. This was made
      --  a separate routine with the idea of using it for unrestricted access
      --  which seems like it should follow the same rules, but that turned
      --  out to be impractical. So now this is only used for Address.

      procedure Analyze_Access_Attribute;
      --  Used for Access, Unchecked_Access, Unrestricted_Access attributes.
      --  Internally, Id distinguishes which of the three cases is involved.

      procedure Analyze_Attribute_Old_Result
        (Legal   : out Boolean;
         Spec_Id : out Entity_Id);
      --  Common processing for attributes 'Old and 'Result. The routine checks
      --  that the attribute appears in a postcondition-like aspect or pragma
      --  associated with a suitable subprogram or a body. Flag Legal is set
      --  when the above criteria are met. Spec_Id denotes the entity of the
      --  subprogram [body] or Empty if the attribute is illegal.

      procedure Analyze_Image_Attribute (Str_Typ : Entity_Id);
      --  Common processing for attributes 'Img, 'Image, 'Wide_Image, and
      --  'Wide_Wide_Image. The routine checks that the prefix is valid and
      --  sets the type of the attribute to the one specified by Str_Typ (e.g.
      --  Standard_String for 'Image and Standard_Wide_String for 'Wide_Image).

      procedure Bad_Attribute_For_Predicate;
      --  Output error message for use of a predicate (First, Last, Range) not
      --  allowed with a type that has predicates. If the type is a generic
      --  actual, then the message is a warning, and we generate code to raise
      --  program error with an appropriate reason. No error message is given
      --  for internally generated uses of the attributes. This legality rule
      --  only applies to scalar types.

      procedure Check_Array_Or_Scalar_Type;
      --  Common procedure used by First, Last, Range attribute to check
      --  that the prefix is a constrained array or scalar type, or a name
      --  of an array object, and that an argument appears only if appropriate
      --  (i.e. only in the array case).

      procedure Check_Array_Type;
      --  Common semantic checks for all array attributes. Checks that the
      --  prefix is a constrained array type or the name of an array object.
      --  The error message for non-arrays is specialized appropriately.

      procedure Check_Asm_Attribute;
      --  Common semantic checks for Asm_Input and Asm_Output attributes

      procedure Check_Component;
      --  Common processing for Bit_Position, First_Bit, Last_Bit, and
      --  Position. Checks prefix is an appropriate selected component.

      procedure Check_Decimal_Fixed_Point_Type;
      --  Check that prefix of attribute N is a decimal fixed-point type

      procedure Check_Dereference;
      --  If the prefix of attribute is an object of an access type, then
      --  introduce an explicit dereference, and adjust P_Type accordingly.

      procedure Check_Discrete_Type;
      --  Verify that prefix of attribute N is a discrete type

      procedure Check_E0;
      --  Check that no attribute arguments are present

      procedure Check_Either_E0_Or_E1;
      --  Check that there are zero or one attribute arguments present

      procedure Check_E1;
      --  Check that exactly one attribute argument is present

      procedure Check_E2;
      --  Check that two attribute arguments are present

      procedure Check_Enum_Image (Check_Enumeration_Maps : Boolean := False);
      --  Common processing for the Image and Value family of attributes,
      --  including their Wide and Wide_Wide versions, Enum_Val, Img,
      --  and Valid_Value.
      --
      --  If the prefix type of an attribute is an enumeration type, set all
      --  its literals as referenced, since the attribute function can
      --  indirectly reference any of the literals. Set the referenced flag
      --  only if the attribute is in the main code unit; otherwise an
      --  improperly set reference when analyzing an inlined body will lose a
      --  proper warning on a useless with_clause.
      --
      --  If Check_Enumeration_Maps is True, then the attribute expansion
      --  requires enumeration maps, so check whether restriction
      --  No_Enumeration_Maps is active.

      procedure Check_First_Last_Valid;
      --  Perform all checks for First_Valid and Last_Valid attributes

      procedure Check_Fixed_Point_Type;
      --  Verify that prefix of attribute N is a fixed type

      procedure Check_Fixed_Point_Type_0;
      --  Verify that prefix of attribute N is a fixed type and that
      --  no attribute expressions are present.

      procedure Check_Floating_Point_Type;
      --  Verify that prefix of attribute N is a float type

      procedure Check_Floating_Point_Type_0;
      --  Verify that prefix of attribute N is a float type and that
      --  no attribute expressions are present.

      procedure Check_Floating_Point_Type_1;
      --  Verify that prefix of attribute N is a float type and that
      --  exactly one attribute expression is present.

      procedure Check_Floating_Point_Type_2;
      --  Verify that prefix of attribute N is a float type and that
      --  two attribute expressions are present.

      procedure Check_Integer_Type;
      --  Verify that prefix of attribute N is an integer type

      procedure Check_Modular_Integer_Type;
      --  Verify that prefix of attribute N is a modular integer type

      procedure Check_Not_CPP_Type;
      --  Check that P (the prefix of the attribute) is not an CPP type
      --  for which no Ada predefined primitive is available.

      procedure Check_Not_Incomplete_Type;
      --  Check that P (the prefix of the attribute) is not an incomplete
      --  type or a private type for which no full view has been given.

      procedure Check_Object_Reference (P : Node_Id);
      --  Check that P is an object reference

      procedure Check_PolyORB_Attribute;
      --  Validity checking for PolyORB/DSA attribute

      procedure Check_Program_Unit;
      --  Verify that prefix of attribute N is a program unit

      procedure Check_Real_Type;
      --  Verify that prefix of attribute N is fixed or float type

      procedure Check_Enumeration_Type;
      --  Verify that prefix of attribute N is an enumeration type

      procedure Check_Scalar_Type;
      --  Verify that prefix of attribute N is a scalar type

      procedure Check_Standard_Prefix;
      --  Verify that prefix of attribute N is package Standard. Also checks
      --  that there are no arguments.

      procedure Check_Stream_Attribute (Nam : TSS_Name_Type);
      --  Validity checking for stream attribute. Nam is the TSS name of the
      --  corresponding possible defined attribute function (e.g. for the
      --  Read attribute, Nam will be TSS_Stream_Read).

      procedure Check_Put_Image_Attribute;
      --  Validity checking for Put_Image attribute

      procedure Check_System_Prefix;
      --  Verify that prefix of attribute N is package System

      procedure Check_Task_Prefix;
      --  Verify that prefix of attribute N is a task or task type

      procedure Check_Type;
      --  Verify that the prefix of attribute N is a type

      procedure Check_Unit_Name (Nod : Node_Id);
      --  Check that Nod is of the form of a library unit name, i.e that
      --  it is an identifier, or a selected component whose prefix is
      --  itself of the form of a library unit name. Note that this is
      --  quite different from Check_Program_Unit, since it only checks
      --  the syntactic form of the name, not the semantic identity. This
      --  is because it is used with attributes (Elab_Body, Elab_Spec and
      --  Elaborated) which can refer to non-visible unit.

      procedure Error_Attr (Msg : String; Error_Node : Node_Id);
      pragma No_Return (Error_Attr);
      procedure Error_Attr;
      pragma No_Return (Error_Attr);
      --  Posts error using Error_Msg_N at given node, sets type of attribute
      --  node to Any_Type, and then raises Bad_Attribute to avoid any further
      --  semantic processing. The message typically contains a % insertion
      --  character which is replaced by the attribute name. The call with
      --  no arguments is used when the caller has already generated the
      --  required error messages.

      procedure Error_Attr_P (Msg : String; Msg_Cont : String := "");
      pragma No_Return (Error_Attr_P);
      --  Like Error_Attr, but error is posted at the start of the prefix. The
      --  second message Msg_Cont is useful to issue a continuation message
      --  before raising Bad_Attribute.

      procedure Legal_Formal_Attribute;
      --  Common processing for attributes Definite and Has_Discriminants.
      --  Checks that prefix is generic indefinite formal type.

      procedure Max_Alignment_For_Allocation_Max_Size_In_Storage_Elements;
      --  Common processing for attributes Max_Alignment_For_Allocation and
      --  Max_Size_In_Storage_Elements.

      procedure Min_Max;
      --  Common processing for attributes Max and Min

      procedure Standard_Attribute (Val : Int);
      --  Used to process attributes whose prefix is package Standard which
      --  yield values of type Universal_Integer. The attribute reference
      --  node is rewritten with an integer literal of the given value which
      --  is marked as static.

      procedure Uneval_Old_Msg;
      --  Called when Loop_Entry or Old is used in a potentially unevaluated
      --  expression. Generates appropriate message or warning depending on
      --  the setting of Opt.Uneval_Old (or flags in an N_Aspect_Specification
      --  node in the aspect case).

      procedure Unexpected_Argument (En : Node_Id);
      pragma No_Return (Unexpected_Argument);
      --  Signal unexpected attribute argument (En is the argument), and then
      --  raises Bad_Attribute to avoid any further semantic processing.

      procedure Validate_Non_Static_Attribute_Function_Call;
      --  Called when processing an attribute that is a function call to a
      --  non-static function, i.e. an attribute function that either takes
      --  non-scalar arguments or returns a non-scalar result. Verifies that
      --  such a call does not appear in a preelaborable context.

      --------------------
      -- Address_Checks --
      --------------------

      procedure Address_Checks is
      begin
         --  An Address attribute created by expansion is legal even when it
         --  applies to other entity-denoting expressions.

         if not Comes_From_Source (N) then
            return;

         --  Address attribute on a protected object self reference is legal

         elsif Is_Protected_Self_Reference (P) then
            return;

         --  Address applied to an entity

         elsif Is_Entity_Name (P) then
            declare
               Ent : constant Entity_Id := Entity (P);

            begin
               if Is_Subprogram (Ent) then
                  Set_Address_Taken (Ent);
                  Kill_Current_Values (Ent);

                  --  An Address attribute is accepted when generated by the
                  --  compiler for dispatching operation, and an error is
                  --  issued once the subprogram is frozen (to avoid confusing
                  --  errors about implicit uses of Address in the dispatch
                  --  table initialization).

                  if Has_Pragma_Inline_Always (Entity (P))
                    and then Comes_From_Source (P)
                  then
                     Error_Attr_P
                       ("prefix of % attribute cannot be Inline_Always "
                        & "subprogram");

                  --  It is illegal to apply 'Address to an intrinsic
                  --  subprogram. This is now formalized in AI05-0095.
                  --  In an instance, an attempt to obtain 'Address of an
                  --  intrinsic subprogram (e.g the renaming of a predefined
                  --  operator that is an actual) raises Program_Error.

                  elsif Convention (Ent) = Convention_Intrinsic then
                     if In_Instance then
                        Rewrite (N,
                          Make_Raise_Program_Error (Loc,
                            Reason => PE_Address_Of_Intrinsic));

                     else
                        Error_Msg_Name_1 := Aname;
                        Error_Msg_N
                         ("cannot take % of intrinsic subprogram", N);
                     end if;

                  --  Issue an error if prefix denotes an eliminated subprogram

                  else
                     Check_For_Eliminated_Subprogram (P, Ent);
                  end if;

               --  Object or label reference

               elsif Is_Object_Reference (P) or else Ekind (Ent) = E_Label then
                  Set_Address_Taken (Ent);

                  --  Deal with No_Implicit_Aliasing restriction

                  if Restriction_Check_Required (No_Implicit_Aliasing) then
                     if not Is_Aliased_View (P) then
                        Check_Restriction (No_Implicit_Aliasing, P);
                     else
                        Check_No_Implicit_Aliasing (P);
                     end if;
                  end if;

                  --  If we have an address of an object, and the attribute
                  --  comes from source, then set the object as potentially
                  --  source modified. We do this because the resulting address
                  --  can potentially be used to modify the variable and we
                  --  might not detect this, leading to some junk warnings.

                  Set_Never_Set_In_Source (Ent, False);

               --  Allow Address to be applied to task or protected type,
               --  returning null address (what is that about???)

               elsif (Is_Concurrent_Type (Etype (Ent))
                       and then Etype (Ent) = Base_Type (Ent))
                 or else Ekind (Ent) = E_Package
                 or else Is_Generic_Unit (Ent)
               then
                  Rewrite (N,
                    New_Occurrence_Of (RTE (RE_Null_Address), Sloc (N)));

               --  Anything else is illegal

               else
                  Error_Attr ("invalid prefix for % attribute", P);
               end if;
            end;

         --  Object is OK

         elsif Is_Object_Reference (P) then
            return;

         --  Subprogram called using dot notation

         elsif Nkind (P) = N_Selected_Component
           and then Is_Subprogram (Entity (Selector_Name (P)))
         then
            return;

         --  What exactly are we allowing here ??? and is this properly
         --  documented in the sinfo documentation for this node ???

         elsif Relaxed_RM_Semantics
           and then Nkind (P) = N_Attribute_Reference
         then
            return;

         --  All other non-entity name cases are illegal

         else
            Error_Attr ("invalid prefix for % attribute", P);
         end if;
      end Address_Checks;

      ------------------------------
      -- Analyze_Access_Attribute --
      ------------------------------

      procedure Analyze_Access_Attribute is
         Acc_Type : Entity_Id;

         Scop : Entity_Id;
         Typ  : Entity_Id;

         function Build_Access_Object_Type (DT : Entity_Id) return Entity_Id;
         --  Build an access-to-object type whose designated type is DT,
         --  and whose Ekind is appropriate to the attribute type. The
         --  type that is constructed is returned as the result.

         procedure Build_Access_Subprogram_Type (P : Node_Id);
         --  Build an access to subprogram whose designated type is the type of
         --  the prefix. If prefix is overloaded, so is the node itself. The
         --  result is stored in Acc_Type.

         function OK_Self_Reference return Boolean;
         --  An access reference whose prefix is a type can legally appear
         --  within an aggregate, where it is obtained by expansion of
         --  a defaulted aggregate. The enclosing aggregate that contains
         --  the self-referenced is flagged so that the self-reference can
         --  be expanded into a reference to the target object (see exp_aggr).

         ------------------------------
         -- Build_Access_Object_Type --
         ------------------------------

         function Build_Access_Object_Type (DT : Entity_Id) return Entity_Id is
            Typ : constant Entity_Id :=
                    New_Internal_Entity
                      (E_Access_Attribute_Type, Current_Scope, Loc, 'A');
         begin
            Set_Etype                     (Typ, Typ);
            Set_Is_Itype                  (Typ);
            Set_Associated_Node_For_Itype (Typ, N);
            Set_Directly_Designated_Type  (Typ, DT);
            return Typ;
         end Build_Access_Object_Type;

         ----------------------------------
         -- Build_Access_Subprogram_Type --
         ----------------------------------

         procedure Build_Access_Subprogram_Type (P : Node_Id) is
            Index : Interp_Index;
            It    : Interp;

            procedure Check_Local_Access (E : Entity_Id);
            --  Deal with possible access to local subprogram. If we have such
            --  an access, we set a flag to kill all tracked values on any call
            --  because this access value may be passed around, and any called
            --  code might use it to access a local procedure which clobbers a
            --  tracked value. If the scope is a loop or block, indicate that
            --  value tracking is disabled for the enclosing subprogram.

            function Get_Convention (E : Entity_Id) return Convention_Id;
            function Get_Kind       (E : Entity_Id) return Entity_Kind;
            --  Distinguish between access to regular/protected subprograms

            ------------------------
            -- Check_Local_Access --
            ------------------------

            procedure Check_Local_Access (E : Entity_Id) is
            begin
               if not Is_Library_Level_Entity (E) then
                  Set_Suppress_Value_Tracking_On_Call (Current_Scope);
                  Set_Suppress_Value_Tracking_On_Call
                    (Nearest_Dynamic_Scope (Current_Scope));
               end if;
            end Check_Local_Access;

            --------------------
            -- Get_Convention --
            --------------------

            function Get_Convention (E : Entity_Id) return Convention_Id is
            begin
               --  Restrict handling by_protected_procedure access subprograms
               --  to source entities; required to avoid building access to
               --  subprogram types with convention protected when building
               --  dispatch tables.

               if Comes_From_Source (P)
                 and then Is_By_Protected_Procedure (E)
               then
                  return Convention_Protected;
               else
                  return Convention (E);
               end if;
            end Get_Convention;

            --------------
            -- Get_Kind --
            --------------

            function Get_Kind (E : Entity_Id) return Entity_Kind is
            begin
               if Get_Convention (E) = Convention_Protected then
                  return E_Access_Protected_Subprogram_Type;
               else
                  return E_Access_Subprogram_Type;
               end if;
            end Get_Kind;

         --  Start of processing for Build_Access_Subprogram_Type

         begin
            --  In the case of an access to subprogram, use the name of the
            --  subprogram itself as the designated type. Type-checking in
            --  this case compares the signatures of the designated types.

            --  Note: This fragment of the tree is temporarily malformed
            --  because the correct tree requires an E_Subprogram_Type entity
            --  as the designated type. In most cases this designated type is
            --  later overridden by the semantics with the type imposed by the
            --  context during the resolution phase. In the specific case of
            --  the expression Address!(Prim'Unrestricted_Access), used to
            --  initialize slots of dispatch tables, this work will be done by
            --  the expander (see Exp_Aggr).

            --  The reason to temporarily add this kind of node to the tree
            --  instead of a proper E_Subprogram_Type itype, is the following:
            --  in case of errors found in the source file we report better
            --  error messages. For example, instead of generating the
            --  following error:

            --      "expected access to subprogram with profile
            --       defined at line X"

            --  we currently generate:

            --      "expected access to function Z defined at line X"

            Set_Etype (N, Any_Type);

            if not Is_Overloaded (P) then
               Check_Local_Access (Entity (P));

               if not Is_Intrinsic_Subprogram (Entity (P)) then
                  Acc_Type := Create_Itype (Get_Kind (Entity (P)), N);
                  Set_Is_Public (Acc_Type, False);
                  Set_Etype (Acc_Type, Acc_Type);
                  Set_Convention (Acc_Type, Get_Convention (Entity (P)));
                  Set_Directly_Designated_Type (Acc_Type, Entity (P));
                  Set_Etype (N, Acc_Type);
                  Freeze_Before (N, Acc_Type);
               end if;

            else
               Get_First_Interp (P, Index, It);
               while Present (It.Nam) loop
                  Check_Local_Access (It.Nam);

                  if not Is_Intrinsic_Subprogram (It.Nam) then
                     Acc_Type := Create_Itype (Get_Kind (It.Nam), N);
                     Set_Is_Public (Acc_Type, False);
                     Set_Etype (Acc_Type, Acc_Type);
                     Set_Convention (Acc_Type, Get_Convention (It.Nam));
                     Set_Directly_Designated_Type (Acc_Type, It.Nam);
                     Add_One_Interp (N, Acc_Type, Acc_Type);
                     Freeze_Before (N, Acc_Type);
                  end if;

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

            --  Cannot be applied to intrinsic. Looking at the tests above,
            --  the only way Etype (N) can still be set to Any_Type is if
            --  Is_Intrinsic_Subprogram was True for some referenced entity.

            if Etype (N) = Any_Type then
               Error_Attr_P ("prefix of % attribute cannot be intrinsic");
            end if;
         end Build_Access_Subprogram_Type;

         ----------------------
         -- OK_Self_Reference --
         ----------------------

         function OK_Self_Reference return Boolean is
            Par : Node_Id;

         begin
            --  If N does not come from source, the reference is assumed to be
            --  valid.

            if not Comes_From_Source (N) then
               return True;
            end if;

            Par := Parent (N);
            while Present (Par)
              and then
               (Nkind (Par) = N_Component_Association
                 or else Nkind (Par) in N_Subexpr)
            loop
               if Nkind (Par) in N_Aggregate | N_Extension_Aggregate then
                  if Etype (Par) = Typ then
                     Set_Has_Self_Reference (Par);

                     --  Check the context: the aggregate must be part of the
                     --  initialization of a type or component, or it is the
                     --  resulting expansion in an initialization procedure.

                     if Is_Init_Proc (Current_Scope) then
                        return True;
                     else
                        Par := Parent (Par);
                        while Present (Par) loop
                           if Nkind (Par) = N_Full_Type_Declaration then
                              return True;
                           end if;

                           Par := Parent (Par);
                        end loop;
                     end if;

                     return False;
                  end if;
               end if;

               Par := Parent (Par);
            end loop;

            --  No enclosing aggregate, or not a self-reference

            return False;
         end OK_Self_Reference;

      --  Start of processing for Analyze_Access_Attribute

      begin
         --  Access and Unchecked_Access are illegal in declare_expressions,
         --  according to the RM. We also make the GNAT Unrestricted_Access
         --  attribute illegal if it comes from source.

         if In_Declare_Expr > 0
           and then (Attr_Id /= Attribute_Unrestricted_Access
                      or else Comes_From_Source (N))
         then
            Error_Attr ("% attribute cannot occur in a declare_expression", N);
         end if;

         Check_E0;

         if Nkind (P) = N_Character_Literal then
            Error_Attr_P
              ("prefix of % attribute cannot be enumeration literal");
         end if;

         --  Preserve relevant elaboration-related attributes of the context
         --  which are no longer available or very expensive to recompute once
         --  analysis, resolution, and expansion are over.

         Mark_Elaboration_Attributes
           (N_Id     => N,
            Checks   => True,
            Modes    => True,
            Warnings => True);

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

         Record_Elaboration_Scenario (N);

         --  Case of access to subprogram

         if Is_Entity_Name (P) and then Is_Overloadable (Entity (P)) then
            if Has_Pragma_Inline_Always (Entity (P)) then
               Error_Attr_P
                 ("prefix of % attribute cannot be Inline_Always subprogram");

            elsif Aname = Name_Unchecked_Access then
               Error_Attr ("attribute% cannot be applied to a subprogram", P);
            end if;

            --  Issue an error if the prefix denotes an eliminated subprogram

            Check_For_Eliminated_Subprogram (P, Entity (P));

            --  Check for obsolescent subprogram reference

            Check_Obsolescent_2005_Entity (Entity (P), P);

            --  Build the appropriate subprogram type

            Build_Access_Subprogram_Type (P);

            --  For P'Access or P'Unrestricted_Access, where P is a nested
            --  subprogram, we might be passing P to another subprogram (but we
            --  don't check that here), which might call P. P could modify
            --  local variables, so we need to kill current values. It is
            --  important not to do this for library-level subprograms, because
            --  Kill_Current_Values is very inefficient in the case of library
            --  level packages with lots of tagged types.

            if Is_Library_Level_Entity (Entity (Prefix (N))) then
               null;

            --  Do not kill values on nodes initializing dispatch tables
            --  slots. The construct Prim_Ptr!(Prim'Unrestricted_Access)
            --  is currently generated by the expander only for this
            --  purpose. Done to keep the quality of warnings currently
            --  generated by the compiler (otherwise any declaration of
            --  a tagged type cleans constant indications from its scope).

            elsif Nkind (Parent (N)) = N_Unchecked_Type_Conversion
              and then (Is_RTE (Etype (Parent (N)), RE_Prim_Ptr)
                          or else
                        Is_RTE (Etype (Parent (N)), RE_Size_Ptr))
              and then Is_Dispatching_Operation
                         (Directly_Designated_Type (Etype (N)))
            then
               null;

            else
               Kill_Current_Values;
            end if;

            --  In the static elaboration model, treat the attribute reference
            --  as a subprogram call for elaboration purposes. Suppress this
            --  treatment under debug flag. In any case, we are all done.

            if Legacy_Elaboration_Checks
              and not Dynamic_Elaboration_Checks
              and not Debug_Flag_Dot_UU
            then
               Check_Elab_Call (N);
            end if;

            return;

         --  Component is an operation of a protected type

         elsif Nkind (P) = N_Selected_Component
           and then Is_Overloadable (Entity (Selector_Name (P)))
         then
            if Ekind (Entity (Selector_Name (P))) = E_Entry then
               Error_Attr_P ("prefix of % attribute must be subprogram");
            end if;

            Build_Access_Subprogram_Type (Selector_Name (P));
            return;
         end if;

         --  Deal with incorrect reference to a type, but note that some
         --  accesses are allowed: references to the current type instance,
         --  or in Ada 2005 self-referential pointer in a default-initialized
         --  aggregate.

         if Is_Entity_Name (P) then
            Typ := Entity (P);

            --  The reference may appear in an aggregate that has been expanded
            --  into a loop. Locate scope of type definition, if any.

            Scop := Current_Scope;
            while Ekind (Scop) = E_Loop loop
               Scop := Scope (Scop);
            end loop;

            if Is_Type (Typ) then

               --  OK if we are within the scope of a limited type
               --  let's mark the component as having per object constraint

               if Is_Anonymous_Tagged_Base (Scop, Typ) then
                  Typ := Scop;
                  Set_Entity (P, Typ);
                  Set_Etype  (P, Typ);
               end if;

               if Typ = Scop then
                  declare
                     Q : Node_Id := Parent (N);

                  begin
                     while Present (Q)
                       and then Nkind (Q) /= N_Component_Declaration
                     loop
                        Q := Parent (Q);
                     end loop;

                     if Present (Q) then
                        Set_Has_Per_Object_Constraint
                          (Defining_Identifier (Q), True);
                     end if;
                  end;

                  if Nkind (P) = N_Expanded_Name then
                     Error_Msg_F
                       ("current instance prefix must be a direct name", P);
                  end if;

                  --  If a current instance attribute appears in a component
                  --  constraint it must appear alone; other contexts (spec-
                  --  expressions, within a task body) are not subject to this
                  --  restriction.

                  if not In_Spec_Expression
                    and then not Has_Completion (Scop)
                    and then
                      Nkind (Parent (N)) not in
                        N_Discriminant_Association |
                        N_Index_Or_Discriminant_Constraint
                  then
                     Error_Msg_N
                       ("current instance attribute must appear alone", N);
                  end if;

                  if Is_CPP_Class (Root_Type (Typ)) then
                     Error_Msg_N
                       ("??current instance unsupported for derivations of "
                        & "'C'P'P types", N);
                  end if;

               --  OK if we are in initialization procedure for the type
               --  in question, in which case the reference to the type
               --  is rewritten as a reference to the current object.

               elsif Ekind (Scop) = E_Procedure
                 and then Is_Init_Proc (Scop)
                 and then Etype (First_Formal (Scop)) = Typ
               then
                  Rewrite (N,
                    Make_Attribute_Reference (Loc,
                      Prefix         => Make_Identifier (Loc, Name_uInit),
                      Attribute_Name => Name_Unrestricted_Access));
                  Analyze (N);
                  return;

               --  OK if a task type, this test needs sharpening up ???

               elsif Is_Task_Type (Typ) then
                  null;

               --  OK if self-reference in an aggregate in Ada 2005, and
               --  the reference comes from a copied default expression.

               --  Note that we check legality of self-reference even if the
               --  expression comes from source, e.g. when a single component
               --  association in an aggregate has a box association.

               elsif Ada_Version >= Ada_2005 and then OK_Self_Reference then
                  null;

               --  OK if reference to current instance of a protected object

               elsif Is_Protected_Self_Reference (P) then
                  null;

               --  Otherwise we have an error case

               else
                  Error_Attr ("% attribute cannot be applied to type", P);
                  return;
               end if;
            end if;
         end if;

         --  If we fall through, we have a normal access to object case

         --  Unrestricted_Access is (for now) legal wherever an allocator would
         --  be legal, so its Etype is set to E_Allocator. The expected type
         --  of the other attributes is a general access type, and therefore
         --  we label them with E_Access_Attribute_Type.

         if not Is_Overloaded (P) then
            Acc_Type := Build_Access_Object_Type (P_Type);
            Set_Etype (N, Acc_Type);

         else
            declare
               Index : Interp_Index;
               It    : Interp;
            begin
               Set_Etype (N, Any_Type);
               Get_First_Interp (P, Index, It);
               while Present (It.Typ) loop
                  Acc_Type := Build_Access_Object_Type (It.Typ);
                  Add_One_Interp (N, Acc_Type, Acc_Type);
                  Get_Next_Interp (Index, It);
               end loop;
            end;
         end if;

         --  Special cases when we can find a prefix that is an entity name

         declare
            PP  : Node_Id;
            Ent : Entity_Id;

         begin
            PP := P;
            loop
               if Is_Entity_Name (PP) then
                  Ent := Entity (PP);

                  --  If we have an access to an object, and the attribute
                  --  comes from source, then set the object as potentially
                  --  source modified. We do this because the resulting access
                  --  pointer can be used to modify the variable, and we might
                  --  not detect this, leading to some junk warnings.

                  --  We only do this for source references, since otherwise
                  --  we can suppress warnings, e.g. from the unrestricted
                  --  access generated for validity checks in -gnatVa mode.

                  if Comes_From_Source (N) then
                     Set_Never_Set_In_Source (Ent, False);
                  end if;

                  --  Mark entity as address taken in the case of
                  --  'Unrestricted_Access or subprograms, and kill current
                  --  values.

                  if Aname = Name_Unrestricted_Access
                    or else Is_Subprogram (Ent)
                  then
                     Set_Address_Taken (Ent);
                  end if;

                  Kill_Current_Values (Ent);
                  exit;

               elsif Nkind (PP) in N_Selected_Component | N_Indexed_Component
               then
                  PP := Prefix (PP);

               else
                  exit;
               end if;
            end loop;
         end;
      end Analyze_Access_Attribute;

      ----------------------------------
      -- Analyze_Attribute_Old_Result --
      ----------------------------------

      procedure Analyze_Attribute_Old_Result
        (Legal   : out Boolean;
         Spec_Id : out Entity_Id)
      is
         procedure Check_Placement_In_Check (Prag : Node_Id);
         --  Verify that the attribute appears within pragma Check that mimics
         --  a postcondition.

         procedure Check_Placement_In_Contract_Cases (Prag : Node_Id);
         --  Verify that the attribute appears within a consequence of aspect
         --  or pragma Contract_Cases denoted by Prag.

         procedure Check_Placement_In_Test_Case (Prag : Node_Id);
         --  Verify that the attribute appears within the "Ensures" argument of
         --  aspect or pragma Test_Case denoted by Prag.

         function Is_Within
           (Nod      : Node_Id;
            Encl_Nod : Node_Id) return Boolean;
         --  Subsidiary to Check_Placemenet_In_XXX. Determine whether arbitrary
         --  node Nod is within enclosing node Encl_Nod.

         procedure Placement_Error;
         pragma No_Return (Placement_Error);
         --  Emit a general error when the attributes does not appear in a
         --  postcondition-like aspect or pragma, and then raises Bad_Attribute
         --  to avoid any further semantic processing.

         ------------------------------
         -- Check_Placement_In_Check --
         ------------------------------

         procedure Check_Placement_In_Check (Prag : Node_Id) is
            Args : constant List_Id := Pragma_Argument_Associations (Prag);
            Nam  : constant Name_Id := Chars (Get_Pragma_Arg (First (Args)));

         begin
            --  The "Name" argument of pragma Check denotes a postcondition

            if Nam in Name_Post
                    | Name_Post_Class
                    | Name_Postcondition
                    | Name_Refined_Post
            then
               null;

            --  Otherwise the placement of the attribute is illegal

            else
               Placement_Error;
            end if;
         end Check_Placement_In_Check;

         ---------------------------------------
         -- Check_Placement_In_Contract_Cases --
         ---------------------------------------

         procedure Check_Placement_In_Contract_Cases (Prag : Node_Id) is
            Arg   : Node_Id;
            Cases : Node_Id;
            CCase : Node_Id;

         begin
            --  Obtain the argument of the aspect or pragma

            if Nkind (Prag) = N_Aspect_Specification then
               Arg := Prag;
            else
               Arg := First (Pragma_Argument_Associations (Prag));
            end if;

            Cases := Expression (Arg);

            if Present (Component_Associations (Cases)) then
               CCase := First (Component_Associations (Cases));
               while Present (CCase) loop

                  --  Detect whether the attribute appears within the
                  --  consequence of the current contract case.

                  if Nkind (CCase) = N_Component_Association
                    and then Is_Within (N, Expression (CCase))
                  then
                     return;
                  end if;

                  Next (CCase);
               end loop;
            end if;

            --  Otherwise aspect or pragma Contract_Cases is either malformed
            --  or the attribute does not appear within a consequence.

            Error_Attr
              ("attribute % must appear in the consequence of a contract case",
               P);
         end Check_Placement_In_Contract_Cases;

         ----------------------------------
         -- Check_Placement_In_Test_Case --
         ----------------------------------

         procedure Check_Placement_In_Test_Case (Prag : Node_Id) is
            Arg : constant Node_Id :=
                    Test_Case_Arg
                      (Prag        => Prag,
                       Arg_Nam     => Name_Ensures,
                       From_Aspect => Nkind (Prag) = N_Aspect_Specification);

         begin
            --  Detect whether the attribute appears within the "Ensures"
            --  expression of aspect or pragma Test_Case.

            if Present (Arg) and then Is_Within (N, Arg) then
               null;

            else
               Error_Attr
                 ("attribute % must appear in the ensures expression of a "
                  & "test case", P);
            end if;
         end Check_Placement_In_Test_Case;

         ---------------
         -- Is_Within --
         ---------------

         function Is_Within
           (Nod      : Node_Id;
            Encl_Nod : Node_Id) return Boolean
         is
            Par : Node_Id;

         begin
            Par := Nod;
            while Present (Par) loop
               if Par = Encl_Nod then
                  return True;

               --  Prevent the search from going too far

               elsif Is_Body_Or_Package_Declaration (Par) then
                  exit;
               end if;

               Par := Parent (Par);
            end loop;

            return False;
         end Is_Within;

         ---------------------
         -- Placement_Error --
         ---------------------

         procedure Placement_Error is
         begin
            if Aname = Name_Old then
               Error_Attr ("attribute % can only appear in postcondition", P);

            --  Specialize the error message for attribute 'Result

            else
               Error_Attr
                 ("attribute % can only appear in postcondition of function",
                  P);
            end if;
         end Placement_Error;

         --  Local variables

         Prag      : Node_Id;
         Prag_Nam  : Name_Id;
         Subp_Decl : Node_Id;

      --  Start of processing for Analyze_Attribute_Old_Result

      begin
         --  Assume that the attribute is illegal

         Legal   := False;
         Spec_Id := Empty;

         --  Skip processing during preanalysis of class-wide preconditions and
         --  postconditions since at this stage the expression is not installed
         --  yet on its definite context.

         if Inside_Class_Condition_Preanalysis then
            Legal   := True;
            Spec_Id := Current_Scope;
            return;
         end if;

         --  Traverse the parent chain to find the aspect or pragma where the
         --  attribute resides.

         Prag := N;
         while Present (Prag) loop
            if Nkind (Prag) in N_Aspect_Specification | N_Pragma then
               exit;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Prag) then
               exit;
            end if;

            Prag := Parent (Prag);
         end loop;

         --  The attribute is allowed to appear only in postcondition-like
         --  aspects or pragmas.

         if Nkind (Prag) in N_Aspect_Specification | N_Pragma then
            if Nkind (Prag) = N_Aspect_Specification then
               Prag_Nam := Chars (Identifier (Prag));
            else
               Prag_Nam := Pragma_Name (Prag);
            end if;

            if Prag_Nam = Name_Check then
               Check_Placement_In_Check (Prag);

            elsif Prag_Nam = Name_Contract_Cases then
               Check_Placement_In_Contract_Cases (Prag);

            --  Attribute 'Result is allowed to appear in aspect or pragma
            --  [Refined_]Depends (SPARK RM 6.1.5(11)).

            elsif Prag_Nam in Name_Depends | Name_Refined_Depends
              and then Aname = Name_Result
            then
               null;

            --  Attribute 'Result is allowed to appear in aspect
            --  Relaxed_Initialization (SPARK RM 6.10).

            elsif Prag_Nam = Name_Relaxed_Initialization
              and then Aname = Name_Result
            then
               null;

            elsif Prag_Nam in Name_Post
                            | Name_Post_Class
                            | Name_Postcondition
                            | Name_Refined_Post
            then
               null;

            elsif Prag_Nam = Name_Test_Case then
               Check_Placement_In_Test_Case (Prag);

            else
               Placement_Error;
               return;
            end if;

         --  Otherwise the placement of the attribute is illegal

         else
            Placement_Error;
            return;
         end if;

         --  Find the related subprogram subject to the aspect or pragma

         if Nkind (Prag) = N_Aspect_Specification then
            Subp_Decl := Parent (Prag);
         else
            Subp_Decl := Find_Related_Declaration_Or_Body (Prag);
         end if;

         --  The aspect or pragma where the attribute resides should be
         --  associated with a subprogram declaration or a body. If this is not
         --  the case, then the aspect or pragma is illegal. Return as analysis
         --  cannot be carried out. Note that it is legal to have the aspect
         --  appear on a subprogram renaming, when the renamed entity is an
         --  attribute reference.

         --  Generating C code the internally built nested _postcondition
         --  subprograms are inlined; after expanded, inlined aspects are
         --  located in the internal block generated by the frontend.

         if Nkind (Subp_Decl) = N_Block_Statement
           and then Modify_Tree_For_C
           and then In_Inlined_Body
         then
            null;

         elsif Nkind (Subp_Decl) not in N_Abstract_Subprogram_Declaration
                                      | N_Entry_Declaration
                                      | N_Expression_Function
                                      | N_Generic_Subprogram_Declaration
                                      | N_Subprogram_Body
                                      | N_Subprogram_Body_Stub
                                      | N_Subprogram_Declaration
                                      | N_Subprogram_Renaming_Declaration
         then
            return;
         end if;

         --  If we get here, then the attribute is legal

         Legal   := True;
         Spec_Id := Unique_Defining_Entity (Subp_Decl);

         --  When generating C code, nested _postcondition subprograms are
         --  inlined by the front end to avoid problems (when unnested) with
         --  referenced itypes. Handle that here, since as part of inlining the
         --  expander nests subprogram within a dummy procedure named _parent
         --  (see Build_Postconditions_Procedure and Build_Body_To_Inline).
         --  Hence, in this context, the spec_id of _postconditions is the
         --  enclosing scope.

         if Modify_Tree_For_C
           and then Chars (Spec_Id) = Name_uParent
           and then Chars (Scope (Spec_Id)) = Name_uPostconditions
         then
            --  This situation occurs only when preanalyzing the inlined body

            pragma Assert (not Full_Analysis);

            Spec_Id := Scope (Spec_Id);
            pragma Assert (Is_Inlined (Spec_Id));
         end if;
      end Analyze_Attribute_Old_Result;

      -----------------------------
      -- Analyze_Image_Attribute --
      -----------------------------

      procedure Analyze_Image_Attribute (Str_Typ : Entity_Id) is
         procedure Check_Image_Type (Image_Type : Entity_Id);
         --  Check that Image_Type is legal as the type of a prefix of 'Image.
         --  Legality depends on the Ada language version.

         ----------------------
         -- Check_Image_Type --
         ----------------------

         procedure Check_Image_Type (Image_Type : Entity_Id) is
         begin
            --  Image_Type may be empty in case of another error detected,
            --  or if an N_Raise_xxx_Error node is a parent of N.

            if Ada_Version < Ada_2022
              and then Present (Image_Type)
              and then not Is_Scalar_Type (Image_Type)
            then
               Error_Msg_Ada_2022_Feature ("nonscalar ''Image", Sloc (P));
               Error_Attr;
            end if;
         end Check_Image_Type;

      --  Start of processing for Analyze_Image_Attribute

      begin
         --  AI12-0124: The ARG has adopted the GNAT semantics of 'Img for
         --  scalar types, so that the prefix can be an object, a named value,
         --  or a type. If the prefix is an object, there is no argument.

         if Is_Object_Image (P) then
            Check_E0;
            Set_Etype (N, Str_Typ);
            Check_Image_Type (Etype (P));

            if Attr_Id /= Attribute_Img then
               Error_Msg_Ada_2012_Feature ("|Object''Image", Sloc (P));
            end if;
         else
            Check_E1;
            Set_Etype (N, Str_Typ);

            pragma Assert (Is_Entity_Name (P) and then Is_Type (Entity (P)));

            if Ekind (Entity (P)) = E_Incomplete_Type
              and then Present (Full_View (Entity (P)))
            then
               P_Type := Full_View (Entity (P));
               P_Base_Type := Base_Type (P_Type);
               Set_Entity (P, P_Type);
            end if;

            Check_Image_Type (P_Type);
            Resolve (E1, P_Base_Type);
            Validate_Non_Static_Attribute_Function_Call;
         end if;

         Check_Enum_Image (Check_Enumeration_Maps => True);

         --  Check restriction No_Fixed_IO. Note the check of Comes_From_Source
         --  to avoid giving a duplicate message for when Image attributes
         --  applied to object references get expanded into type-based Image
         --  attributes.

         if Restriction_Check_Required (No_Fixed_IO)
           and then Comes_From_Source (N)
           and then Is_Fixed_Point_Type (P_Type)
         then
            Check_Restriction (No_Fixed_IO, P);
         end if;
      end Analyze_Image_Attribute;

      ---------------------------------
      -- Bad_Attribute_For_Predicate --
      ---------------------------------

      procedure Bad_Attribute_For_Predicate is
      begin
         if Is_Scalar_Type (P_Type)
           and then Comes_From_Source (N)
         then
            Error_Msg_Name_1 := Aname;
            Bad_Predicated_Subtype_Use
              ("type& has predicates, attribute % not allowed", N, P_Type);
         end if;
      end Bad_Attribute_For_Predicate;

      --------------------------------
      -- Check_Array_Or_Scalar_Type --
      --------------------------------

      procedure Check_Array_Or_Scalar_Type is
         function In_Aspect_Specification return Boolean;
         --  A current instance of a type in an aspect specification is an
         --  object and not a type, and therefore cannot be of a scalar type
         --  in the prefix of one of the array attributes if the attribute
         --  reference is part of an aspect expression.

         -----------------------------
         -- In_Aspect_Specification --
         -----------------------------

         function In_Aspect_Specification return Boolean is
            P : Node_Id;

         begin
            P := Parent (N);
            while Present (P) loop
               if Nkind (P) = N_Aspect_Specification then
                  return P_Type = Entity (P);

               elsif Nkind (P) in N_Declaration then
                  return False;
               end if;

               P := Parent (P);
            end loop;

            return False;
         end In_Aspect_Specification;

         --  Local variables

         Index : Entity_Id;

      --  Start of processing for Check_Array_Or_Scalar_Type

      begin
         --  Case of string literal or string literal subtype. These cases
         --  cannot arise from legal Ada code, but the expander is allowed
         --  to generate them. They require special handling because string
         --  literal subtypes do not have standard bounds (the whole idea
         --  of these subtypes is to avoid having to generate the bounds)

         if Ekind (P_Type) = E_String_Literal_Subtype then
            Set_Etype (N, Etype (First_Index (P_Base_Type)));
            return;

         --  Scalar types

         elsif Is_Scalar_Type (P_Type) then
            Check_Type;

            if Present (E1) then
               Error_Attr ("invalid argument in % attribute", E1);

            elsif In_Aspect_Specification then
               Error_Attr
                 ("prefix of % attribute cannot be the current instance of a "
                  & "scalar type", P);

            else
               Set_Etype (N, P_Base_Type);
               return;
            end if;

         --  The following is a special test to allow 'First to apply to
         --  private scalar types if the attribute comes from generated
         --  code. This occurs in the case of Normalize_Scalars code.

         elsif Is_Private_Type (P_Type)
           and then Present (Full_View (P_Type))
           and then Is_Scalar_Type (Full_View (P_Type))
           and then not Comes_From_Source (N)
         then
            Set_Etype (N, Implementation_Base_Type (P_Type));

         --  Array types other than string literal subtypes handled above

         else
            Check_Array_Type;

            --  We know prefix is an array type, or the name of an array
            --  object, and that the expression, if present, is static
            --  and within the range of the dimensions of the type.

            pragma Assert (Is_Array_Type (P_Type));
            Index := First_Index (P_Base_Type);

            if No (E1) then

               --  First dimension assumed

               Set_Etype (N, Base_Type (Etype (Index)));

            else
               declare
                  Udims : constant Uint := Expr_Value (E1);
                  Dims  : constant Int  := UI_To_Int (Udims);
               begin
                  for J in 1 .. Dims - 1 loop
                     Next_Index (Index);
                  end loop;
               end;

               Set_Etype (N, Base_Type (Etype (Index)));
            end if;
         end if;
      end Check_Array_Or_Scalar_Type;

      ----------------------
      -- Check_Array_Type --
      ----------------------

      procedure Check_Array_Type is
         D : Pos;
         --  Dimension number for array attributes

      begin
         --  If the type is a string literal type, then this must be generated
         --  internally, and no further check is required on its legality.

         if Ekind (P_Type) = E_String_Literal_Subtype then
            return;

         --  If the type is a composite, it is an illegal aggregate, no point
         --  in going on.

         elsif P_Type = Any_Composite then
            raise Bad_Attribute;
         end if;

         --  Normal case of array type or subtype. Note that if the
         --  prefix is a current instance of a type declaration it
         --  appears within an aspect specification and is legal.

         Check_Either_E0_Or_E1;
         Check_Dereference;

         if Is_Array_Type (P_Type) then
            if not Is_Constrained (P_Type)
              and then Is_Entity_Name (P)
              and then Is_Type (Entity (P))
              and then not Is_Current_Instance (P)
            then
               --  Note: we do not call Error_Attr here, since we prefer to
               --  continue, using the relevant index type of the array,
               --  even though it is unconstrained. This gives better error
               --  recovery behavior.

               Error_Msg_Name_1 := Aname;
               Error_Msg_F
                 ("prefix for % attribute must be constrained array", P);
            end if;

            --  The attribute reference freezes the type, and thus the
            --  component type, even if the attribute may not depend on the
            --  component. Diagnose arrays with incomplete components now.
            --  If the prefix is an access to array, this does not freeze
            --  the designated type.

            if Nkind (P) /= N_Explicit_Dereference then
               Check_Fully_Declared (Component_Type (P_Type), P);
            end if;

            D := Number_Dimensions (P_Type);

         else
            if Is_Private_Type (P_Type) then
               Error_Attr_P ("prefix for % attribute may not be private type");

            elsif Is_Access_Type (P_Type)
              and then Is_Array_Type (Designated_Type (P_Type))
              and then Is_Entity_Name (P)
              and then Is_Type (Entity (P))
            then
               Error_Attr_P ("prefix of % attribute cannot be access type");

            elsif Attr_Id = Attribute_First
                    or else
                  Attr_Id = Attribute_Last
            then
               Error_Attr ("invalid prefix for % attribute", P);

            else
               Error_Attr_P ("prefix for % attribute must be array");
            end if;
         end if;

         if Present (E1) then
            Resolve (E1, Any_Integer);
            Set_Etype (E1, Standard_Integer);

            if not Is_OK_Static_Expression (E1)
              or else Raises_Constraint_Error (E1)
            then
               Flag_Non_Static_Expr
                 ("expression for dimension must be static!", E1);
               Error_Attr;

            elsif Expr_Value (E1) > D or else Expr_Value (E1) < 1 then
               Error_Attr ("invalid dimension number for array type", E1);
            end if;
         end if;

         if (Style_Check and Style_Check_Array_Attribute_Index)
           and then Comes_From_Source (N)
         then
            Style.Check_Array_Attribute_Index (N, E1, D);
         end if;
      end Check_Array_Type;

      -------------------------
      -- Check_Asm_Attribute --
      -------------------------

      procedure Check_Asm_Attribute is
      begin
         Check_Type;
         Check_E2;

         --  Check first argument is static string expression

         Analyze_And_Resolve (E1, Standard_String);

         if Etype (E1) = Any_Type then
            return;

         elsif not Is_OK_Static_Expression (E1) then
            Flag_Non_Static_Expr
              ("constraint argument must be static string expression!", E1);
            Error_Attr;
         end if;

         --  Check second argument is right type

         Analyze_And_Resolve (E2, Entity (P));

         --  Note: that is all we need to do, we don't need to check
         --  that it appears in a correct context. The Ada type system
         --  will do that for us.

      end Check_Asm_Attribute;

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

      procedure Check_Component is
      begin
         Check_E0;

         if Nkind (P) /= N_Selected_Component
           or else
             (Ekind (Entity (Selector_Name (P))) /= E_Component
               and then
              Ekind (Entity (Selector_Name (P))) /= E_Discriminant)
         then
            Error_Attr_P ("prefix for % attribute must be selected component");
         end if;
      end Check_Component;

      ------------------------------------
      -- Check_Decimal_Fixed_Point_Type --
      ------------------------------------

      procedure Check_Decimal_Fixed_Point_Type is
      begin
         Check_Type;

         if not Is_Decimal_Fixed_Point_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be decimal type");
         end if;
      end Check_Decimal_Fixed_Point_Type;

      -----------------------
      -- Check_Dereference --
      -----------------------

      procedure Check_Dereference is
      begin

         --  Case of a subtype mark

         if Is_Entity_Name (P) and then Is_Type (Entity (P)) then
            return;
         end if;

         --  Case of an expression

         Resolve (P_Old);

         if Is_Access_Type (P_Type) then

            --  If there is an implicit dereference, then we must freeze the
            --  designated type of the access type, since the type of the
            --  referenced array is this type (see AI95-00106).

            --  As done elsewhere, freezing must not happen when preanalyzing
            --  a pre- or postcondition or a default value for an object or for
            --  a formal parameter.

            if not In_Spec_Expression then
               Freeze_Before (N, Designated_Type (P_Type));
            end if;

            Rewrite (P_Old,
              Make_Explicit_Dereference (Sloc (P_Old),
                Prefix => Relocate_Node (P_Old)));

            Analyze_And_Resolve (P_Old);
            P_Type := Etype (P_Old);

            if P_Type = Any_Type then
               raise Bad_Attribute;
            end if;

            P_Base_Type := Base_Type (P_Type);
         end if;
      end Check_Dereference;

      -------------------------
      -- Check_Discrete_Type --
      -------------------------

      procedure Check_Discrete_Type is
      begin
         Check_Type;

         if not Is_Discrete_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be discrete type");
         end if;
      end Check_Discrete_Type;

      --------------
      -- Check_E0 --
      --------------

      procedure Check_E0 is
      begin
         if Present (E1) then
            Unexpected_Argument (E1);
         end if;
      end Check_E0;

      --------------
      -- Check_E1 --
      --------------

      procedure Check_E1 is
      begin
         Check_Either_E0_Or_E1;

         if No (E1) then

            --  Special-case attributes that are functions and that appear as
            --  the prefix of another attribute. Error is posted on parent.

            if Nkind (Parent (N)) = N_Attribute_Reference
              and then Attribute_Name (Parent (N)) in Name_Address
                                                    | Name_Code_Address
                                                    | Name_Access
            then
               Error_Msg_Name_1 := Attribute_Name (Parent (N));
               Error_Msg_N ("illegal prefix for % attribute", Parent (N));
               Set_Etype (Parent (N), Any_Type);
               Set_Entity (Parent (N), Any_Type);
               raise Bad_Attribute;

            else
               Error_Attr ("missing argument for % attribute", N);
            end if;
         end if;
      end Check_E1;

      --------------
      -- Check_E2 --
      --------------

      procedure Check_E2 is
      begin
         if No (E1) then
            Error_Attr ("missing arguments for % attribute (2 required)", N);
         elsif No (E2) then
            Error_Attr ("missing argument for % attribute (2 required)", N);
         end if;
      end Check_E2;

      ---------------------------
      -- Check_Either_E0_Or_E1 --
      ---------------------------

      procedure Check_Either_E0_Or_E1 is
      begin
         if Present (E2) then
            Unexpected_Argument (E2);
         end if;
      end Check_Either_E0_Or_E1;

      ----------------------
      -- Check_Enum_Image --
      ----------------------

      procedure Check_Enum_Image (Check_Enumeration_Maps : Boolean := False) is
         Lit : Entity_Id;

      begin
         --  Ensure that Check_Enumeration_Maps parameter is set precisely for
         --  attributes whose implementation requires enumeration maps.

         pragma Assert
           (Check_Enumeration_Maps = (Attr_Id in Attribute_Image
                                               | Attribute_Img
                                               | Attribute_Valid_Value
                                               | Attribute_Value
                                               | Attribute_Wide_Image
                                               | Attribute_Wide_Value
                                               | Attribute_Wide_Wide_Image
                                               | Attribute_Wide_Wide_Value));

         --  When an enumeration type appears in an attribute reference, all
         --  literals of the type are marked as referenced. This must only be
         --  done if the attribute reference appears in the current source.
         --  Otherwise the information on references may differ between a
         --  normal compilation and one that performs inlining.

         if Is_Enumeration_Type (P_Base_Type)
           and then In_Extended_Main_Code_Unit (N)
         then
            if Check_Enumeration_Maps then
               Check_Restriction (No_Enumeration_Maps, N);
            end if;

            Lit := First_Literal (P_Base_Type);
            while Present (Lit) loop
               Set_Referenced (Lit);
               Next_Literal (Lit);
            end loop;
         end if;
      end Check_Enum_Image;

      ----------------------------
      -- Check_First_Last_Valid --
      ----------------------------

      procedure Check_First_Last_Valid is
      begin
         Check_Discrete_Type;

         --  Freeze the subtype now, so that the following test for predicates
         --  works (we set the predicates stuff up at freeze time)

         Insert_Actions (N, Freeze_Entity (P_Type, P));

         --  Now test for dynamic predicate

         if Has_Predicates (P_Type)
           and then not (Has_Static_Predicate (P_Type))
         then
            Error_Attr_P
              ("prefix of % attribute may not have dynamic predicate");
         end if;

         --  Check non-static subtype

         if not Is_OK_Static_Subtype (P_Type) then
            Error_Attr_P ("prefix of % attribute must be a static subtype");
         end if;

         --  Test case for no values

         if Expr_Value (Type_Low_Bound (P_Type)) >
            Expr_Value (Type_High_Bound (P_Type))
           or else (Has_Predicates (P_Type)
                     and then
                       Is_Empty_List (Static_Discrete_Predicate (P_Type)))
         then
            Error_Attr_P
              ("prefix of % attribute must be subtype with at least one "
               & "value");
         end if;
      end Check_First_Last_Valid;

      ----------------------------
      -- Check_Fixed_Point_Type --
      ----------------------------

      procedure Check_Fixed_Point_Type is
      begin
         Check_Type;

         if not Is_Fixed_Point_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be fixed point type");
         end if;
      end Check_Fixed_Point_Type;

      ------------------------------
      -- Check_Fixed_Point_Type_0 --
      ------------------------------

      procedure Check_Fixed_Point_Type_0 is
      begin
         Check_Fixed_Point_Type;
         Check_E0;
      end Check_Fixed_Point_Type_0;

      -------------------------------
      -- Check_Floating_Point_Type --
      -------------------------------

      procedure Check_Floating_Point_Type is
      begin
         Check_Type;

         if not Is_Floating_Point_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be float type");
         end if;
      end Check_Floating_Point_Type;

      ---------------------------------
      -- Check_Floating_Point_Type_0 --
      ---------------------------------

      procedure Check_Floating_Point_Type_0 is
      begin
         Check_Floating_Point_Type;
         Check_E0;
      end Check_Floating_Point_Type_0;

      ---------------------------------
      -- Check_Floating_Point_Type_1 --
      ---------------------------------

      procedure Check_Floating_Point_Type_1 is
      begin
         Check_Floating_Point_Type;
         Check_E1;
      end Check_Floating_Point_Type_1;

      ---------------------------------
      -- Check_Floating_Point_Type_2 --
      ---------------------------------

      procedure Check_Floating_Point_Type_2 is
      begin
         Check_Floating_Point_Type;
         Check_E2;
      end Check_Floating_Point_Type_2;

      ------------------------
      -- Check_Integer_Type --
      ------------------------

      procedure Check_Integer_Type is
      begin
         Check_Type;

         if not Is_Integer_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be integer type");
         end if;
      end Check_Integer_Type;

      --------------------------------
      -- Check_Modular_Integer_Type --
      --------------------------------

      procedure Check_Modular_Integer_Type is
      begin
         Check_Type;

         if not Is_Modular_Integer_Type (P_Type) then
            Error_Attr_P
              ("prefix of % attribute must be modular integer type");
         end if;
      end Check_Modular_Integer_Type;

      ------------------------
      -- Check_Not_CPP_Type --
      ------------------------

      procedure Check_Not_CPP_Type is
      begin
         if Is_Tagged_Type (Etype (P))
           and then Convention (Etype (P)) = Convention_CPP
           and then Is_CPP_Class (Root_Type (Etype (P)))
         then
            Error_Attr_P
              ("invalid use of % attribute with 'C'P'P tagged type");
         end if;
      end Check_Not_CPP_Type;

      -------------------------------
      -- Check_Not_Incomplete_Type --
      -------------------------------

      procedure Check_Not_Incomplete_Type is
         E   : Entity_Id;
         Typ : Entity_Id;

      begin
         --  Ada 2005 (AI-50217, AI-326): If the prefix is an explicit
         --  dereference we have to check wrong uses of incomplete types
         --  (other wrong uses are checked at their freezing point).

         --  In Ada 2012, incomplete types can appear in subprogram
         --  profiles, but formals with incomplete types cannot be the
         --  prefix of attributes.

         --  Example 1: Limited-with

         --    limited with Pkg;
         --    package P is
         --       type Acc is access Pkg.T;
         --       X : Acc;
         --       S : Integer := X.all'Size;                    -- ERROR
         --    end P;

         --  Example 2: Tagged incomplete

         --     type T is tagged;
         --     type Acc is access all T;
         --     X : Acc;
         --     S : constant Integer := X.all'Size;             -- ERROR
         --     procedure Q (Obj : Integer := X.all'Alignment); -- ERROR

         if Ada_Version >= Ada_2005
           and then Nkind (P) = N_Explicit_Dereference
         then
            E := P;
            while Nkind (E) = N_Explicit_Dereference loop
               E := Prefix (E);
            end loop;

            Typ := Etype (E);

            if From_Limited_With (Typ) then
               Error_Attr_P
                 ("prefix of % attribute cannot be an incomplete type");

            --  If the prefix is an access type check the designated type

            elsif Is_Access_Type (Typ)
              and then Nkind (P) = N_Explicit_Dereference
            then
               Typ := Directly_Designated_Type (Typ);
            end if;

            if Is_Class_Wide_Type (Typ) then
               Typ := Root_Type (Typ);
            end if;

            --  A legal use of a shadow entity occurs only when the unit where
            --  the non-limited view resides is imported via a regular with
            --  clause in the current body. Such references to shadow entities
            --  may occur in subprogram formals.

            if Is_Incomplete_Type (Typ)
              and then From_Limited_With (Typ)
              and then Present (Non_Limited_View (Typ))
              and then Is_Legal_Shadow_Entity_In_Body (Typ)
            then
               Typ := Non_Limited_View (Typ);
            end if;

            --  If still incomplete, it can be a local incomplete type, or a
            --  limited view whose scope is also a limited view.

            if Ekind (Typ) = E_Incomplete_Type then
               if not From_Limited_With (Typ)
                  and then No (Full_View (Typ))
               then
                  Error_Attr_P
                    ("prefix of % attribute cannot be an incomplete type");

               --  The limited view may be available indirectly through
               --  an intermediate unit. If the non-limited view is available
               --  the attribute reference is legal.

               elsif From_Limited_With (Typ)
                 and then
                   (No (Non_Limited_View (Typ))
                     or else Is_Incomplete_Type (Non_Limited_View (Typ)))
               then
                  Error_Attr_P
                    ("prefix of % attribute cannot be an incomplete type");
               end if;
            end if;

         --  Ada 2012 : formals in bodies may be incomplete, but no attribute
         --  legally applies.

         elsif Is_Entity_Name (P)
           and then Is_Formal (Entity (P))
           and then Is_Incomplete_Type (Etype (Etype (P)))
         then
            Error_Attr_P
              ("prefix of % attribute cannot be an incomplete type");
         end if;

         if not Is_Entity_Name (P)
           or else not Is_Type (Entity (P))
           or else In_Spec_Expression
         then
            return;
         else
            Check_Fully_Declared (P_Type, P);
         end if;
      end Check_Not_Incomplete_Type;

      ----------------------------
      -- Check_Object_Reference --
      ----------------------------

      procedure Check_Object_Reference (P : Node_Id) is
         Rtyp : Entity_Id;

      begin
         --  If we need an object, and we have a prefix that is the name of a
         --  function entity, convert it into a function call.

         if Is_Entity_Name (P)
           and then Ekind (Entity (P)) = E_Function
         then
            Rtyp := Etype (Entity (P));

            Rewrite (P,
              Make_Function_Call (Sloc (P),
                Name => Relocate_Node (P)));

            Analyze_And_Resolve (P, Rtyp);

         --  Otherwise we must have an object reference

         elsif not Is_Object_Reference (P) then
            Error_Attr_P ("prefix of % attribute must be object");
         end if;
      end Check_Object_Reference;

      ----------------------------
      -- Check_PolyORB_Attribute --
      ----------------------------

      procedure Check_PolyORB_Attribute is
      begin
         Validate_Non_Static_Attribute_Function_Call;

         Check_Type;
         Check_Not_CPP_Type;

         if Get_PCS_Name /= Name_PolyORB_DSA then
            Error_Attr
              ("attribute% requires the 'Poly'O'R'B 'P'C'S", N);
         end if;
      end Check_PolyORB_Attribute;

      ------------------------
      -- Check_Program_Unit --
      ------------------------

      procedure Check_Program_Unit is
      begin
         if Is_Entity_Name (P) then
            declare
               E : constant Entity_Id := Entity (P);
            begin
               if Ekind (E) in E_Protected_Type
                             | E_Task_Type
                             | Entry_Kind
                             | Generic_Unit_Kind
                             | Subprogram_Kind
                             | E_Package
                 or else Is_Single_Concurrent_Object (E)
               then
                  return;
               end if;
            end;
         end if;

         Error_Attr_P ("prefix of % attribute must be program unit");
      end Check_Program_Unit;

      ---------------------
      -- Check_Real_Type --
      ---------------------

      procedure Check_Real_Type is
      begin
         Check_Type;

         if not Is_Real_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be real type");
         end if;
      end Check_Real_Type;

      ----------------------------
      -- Check_Enumeration_Type --
      ----------------------------

      procedure Check_Enumeration_Type is
      begin
         Check_Type;

         if not Is_Enumeration_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be enumeration type");
         end if;
      end Check_Enumeration_Type;

      -----------------------
      -- Check_Scalar_Type --
      -----------------------

      procedure Check_Scalar_Type is
      begin
         Check_Type;

         if not Is_Scalar_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be scalar type");
         end if;
      end Check_Scalar_Type;

      ---------------------------
      -- Check_Standard_Prefix --
      ---------------------------

      procedure Check_Standard_Prefix is
      begin
         Check_E0;

         if Nkind (P) /= N_Identifier or else Chars (P) /= Name_Standard then
            Error_Attr ("only allowed prefix for % attribute is Standard", P);
         end if;
      end Check_Standard_Prefix;

      -------------------------------
      -- Check_Put_Image_Attribute --
      -------------------------------

      procedure Check_Put_Image_Attribute is
      begin
         --  Put_Image is a procedure, and can only appear at the position of a
         --  procedure call. If it's a list member and it's parent is a
         --  procedure call or aggregate, then this is appearing as an actual
         --  parameter or component association, which is wrong.

         if Is_List_Member (N)
           and then Nkind (Parent (N)) not in
                      N_Procedure_Call_Statement | N_Aggregate
         then
            null;
         else
            Error_Attr
              ("invalid context for attribute%, which is a procedure", N);
         end if;

         Check_Type;
         Analyze_And_Resolve (E1);

         --  Check that the first argument is
         --  Ada.Strings.Text_Buffers.Root_Buffer_Type'Class.

         --  Note: the double call to Root_Type here is needed because the
         --  root type of a class-wide type is the corresponding type (e.g.
         --  X for X'Class, and we really want to go to the root.)

         if not Is_RTE (Root_Type (Root_Type (Etype (E1))),
                        RE_Root_Buffer_Type)
         then
            Error_Attr
              ("expected Ada.Strings.Text_Buffers.Root_Buffer_Type''Class",
               E1);
         end if;

         --  Check that the second argument is of the right type

         Analyze (E2);
         Resolve (E2, P_Type);
      end Check_Put_Image_Attribute;

      ----------------------------
      -- Check_Stream_Attribute --
      ----------------------------

      procedure Check_Stream_Attribute (Nam : TSS_Name_Type) is
         Etyp : Entity_Id;
         Btyp : Entity_Id;

         In_Shared_Var_Procs : Boolean;
         --  True when compiling System.Shared_Storage.Shared_Var_Procs body.
         --  For this runtime package (always compiled in GNAT mode), we allow
         --  stream attributes references for limited types for the case where
         --  shared passive objects are implemented using stream attributes,
         --  which is the default in GNAT's persistent storage implementation.

      begin
         Validate_Non_Static_Attribute_Function_Call;

         --  With the exception of 'Input, Stream attributes are procedures,
         --  and can only appear at the position of procedure calls. We check
         --  for this here, before they are rewritten, to give a more precise
         --  diagnostic.

         if Nam = TSS_Stream_Input then
            null;

         elsif Is_List_Member (N)
           and then Nkind (Parent (N)) not in
                      N_Procedure_Call_Statement | N_Aggregate
         then
            null;

         else
            Error_Attr
              ("invalid context for attribute%, which is a procedure", N);
         end if;

         Check_Type;
         Btyp := Implementation_Base_Type (P_Type);

         --  Stream attributes not allowed on limited types unless the
         --  attribute reference was generated by the expander (in which
         --  case the underlying type will be used, as described in Sinfo),
         --  or the attribute was specified explicitly for the type itself
         --  or one of its ancestors (taking visibility rules into account if
         --  in Ada 2005 mode), or a pragma Stream_Convert applies to Btyp
         --  (with no visibility restriction).

         declare
            Gen_Body : constant Node_Id := Enclosing_Generic_Body (N);
         begin
            if Present (Gen_Body) then
               In_Shared_Var_Procs :=
                 Is_RTE (Corresponding_Spec (Gen_Body), RE_Shared_Var_Procs);
            else
               In_Shared_Var_Procs := False;
            end if;
         end;

         if (Comes_From_Source (N)
              and then not (In_Shared_Var_Procs or In_Instance))
           and then not Stream_Attribute_Available (P_Type, Nam)
           and then not Has_Rep_Pragma (Btyp, Name_Stream_Convert)
         then
            Error_Msg_Name_1 := Aname;

            if Is_Limited_Type (P_Type) then
               Error_Msg_NE
                 ("limited type& has no% attribute", P, P_Type);
               Explain_Limited_Type (P_Type, P);
            else
               Error_Msg_NE
                 ("attribute% for type& is not available", P, P_Type);
            end if;
         end if;

         --  Check for no stream operations allowed from No_Tagged_Streams

         if Is_Tagged_Type (P_Type)
           and then Present (No_Tagged_Streams_Pragma (P_Type))
         then
            Error_Msg_Sloc := Sloc (No_Tagged_Streams_Pragma (P_Type));
            Error_Msg_NE
              ("no stream operations for & (No_Tagged_Streams #)", N, P_Type);
            return;
         end if;

         --  Check restriction violations

         --  First check the No_Streams restriction, which prohibits the use
         --  of explicit stream attributes in the source program. We do not
         --  prevent the occurrence of stream attributes in generated code,
         --  for instance those generated implicitly for dispatching purposes.

         if Comes_From_Source (N) then
            Check_Restriction (No_Streams, P);
         end if;

         --  AI05-0057: if restriction No_Default_Stream_Attributes is active,
         --  it is illegal to use a predefined elementary type stream attribute
         --  either by itself, or more importantly as part of the attribute
         --  subprogram for a composite type. However, if the broader
         --  restriction No_Streams is active, stream operations are not
         --  generated, and there is no error.

         if Restriction_Active (No_Default_Stream_Attributes)
           and then not Restriction_Active (No_Streams)
         then
            declare
               T : Entity_Id;

            begin
               if Nam = TSS_Stream_Input
                    or else
                  Nam = TSS_Stream_Read
               then
                  T :=
                    Type_Without_Stream_Operation (P_Type, TSS_Stream_Read);
               else
                  T :=
                    Type_Without_Stream_Operation (P_Type, TSS_Stream_Write);
               end if;

               if Present (T) then
                  Check_Restriction (No_Default_Stream_Attributes, N);

                  Error_Msg_NE
                    ("missing user-defined Stream Read or Write for type&",
                      N, T);
                  if not Is_Elementary_Type (P_Type) then
                     Error_Msg_NE
                     ("\which is a component of type&", N, P_Type);
                  end if;
               end if;
            end;
         end if;

         --  Check special case of Exception_Id and Exception_Occurrence which
         --  are not allowed for restriction No_Exception_Registration.

         if Restriction_Check_Required (No_Exception_Registration)
           and then (Is_RTE (P_Type, RE_Exception_Id)
                       or else
                     Is_RTE (P_Type, RE_Exception_Occurrence))
         then
            Check_Restriction (No_Exception_Registration, P);
         end if;

         --  Here we must check that the first argument is an access type
         --  that is compatible with Ada.Streams.Root_Stream_Type'Class.

         Analyze_And_Resolve (E1);
         Etyp := Etype (E1);

         --  Note: the double call to Root_Type here is needed because the
         --  root type of a class-wide type is the corresponding type (e.g.
         --  X for X'Class, and we really want to go to the root.)

         if not Is_Access_Type (Etyp)
           or else not Is_RTE (Root_Type (Root_Type (Designated_Type (Etyp))),
                               RE_Root_Stream_Type)
         then
            Error_Attr
              ("expected access to Ada.Streams.Root_Stream_Type''Class", E1);
         end if;

         --  Check that the second argument is of the right type if there is
         --  one (the Input attribute has only one argument so this is skipped)

         if Present (E2) then
            Analyze (E2);

            if Nam = TSS_Stream_Read
              and then not Is_OK_Variable_For_Out_Formal (E2)
            then
               Error_Attr
                 ("second argument of % attribute must be a variable", E2);
            end if;

            Resolve (E2, P_Type);
         end if;

         Check_Not_CPP_Type;
      end Check_Stream_Attribute;

      -------------------------
      -- Check_System_Prefix --
      -------------------------

      procedure Check_System_Prefix is
      begin
         if Nkind (P) /= N_Identifier or else Chars (P) /= Name_System then
            Error_Attr ("only allowed prefix for % attribute is System", P);
         end if;
      end Check_System_Prefix;

      -----------------------
      -- Check_Task_Prefix --
      -----------------------

      procedure Check_Task_Prefix is
      begin
         Analyze (P);

         --  Ada 2005 (AI-345): Attribute 'Terminated can be applied to
         --  task interface class-wide types.

         if Is_Task_Type (Etype (P))
           or else (Is_Access_Type (Etype (P))
                      and then Is_Task_Type (Designated_Type (Etype (P))))
           or else (Ada_Version >= Ada_2005
                      and then Ekind (Etype (P)) = E_Class_Wide_Type
                      and then Is_Interface (Etype (P))
                      and then Is_Task_Interface (Etype (P)))
         then
            Resolve (P);

         else
            if Ada_Version >= Ada_2005 then
               Error_Attr_P
                 ("prefix of % attribute must be a task or a task " &
                  "interface class-wide object");

            else
               Error_Attr_P ("prefix of % attribute must be a task");
            end if;
         end if;
      end Check_Task_Prefix;

      ----------------
      -- Check_Type --
      ----------------

      --  The possibilities are an entity name denoting a type, or an
      --  attribute reference that denotes a type (Base or Class). If
      --  the type is incomplete, replace it with its full view.

      procedure Check_Type is
      begin
         if not Is_Entity_Name (P)
           or else not Is_Type (Entity (P))
         then
            Error_Attr_P ("prefix of % attribute must be a type");

         elsif Is_Protected_Self_Reference (P) then
            Error_Attr_P
              ("prefix of % attribute denotes current instance "
               & "(RM 9.4(21/2))");

         elsif Ekind (Entity (P)) = E_Incomplete_Type
            and then Present (Full_View (Entity (P)))
         then
            P_Type := Full_View (Entity (P));
            Set_Entity (P, P_Type);
         end if;
      end Check_Type;

      ---------------------
      -- Check_Unit_Name --
      ---------------------

      procedure Check_Unit_Name (Nod : Node_Id) is
      begin
         if Nkind (Nod) = N_Identifier then
            return;

         elsif Nkind (Nod) in N_Selected_Component | N_Expanded_Name then
            Check_Unit_Name (Prefix (Nod));

            if Nkind (Selector_Name (Nod)) = N_Identifier then
               return;
            end if;
         end if;

         Error_Attr ("argument for % attribute must be unit name", P);
      end Check_Unit_Name;

      ----------------
      -- Error_Attr --
      ----------------

      procedure Error_Attr is
      begin
         Set_Etype  (N, Any_Type);
         Set_Entity (N, Any_Type);
         raise Bad_Attribute;
      end Error_Attr;

      procedure Error_Attr (Msg : String; Error_Node : Node_Id) is
      begin
         Error_Msg_Name_1 := Aname;
         Error_Msg_N (Msg, Error_Node);
         Error_Attr;
      end Error_Attr;

      ------------------
      -- Error_Attr_P --
      ------------------

      procedure Error_Attr_P (Msg : String; Msg_Cont : String := "") is
      begin
         Error_Msg_Name_1 := Aname;
         Error_Msg_F (Msg, P);
         if Msg_Cont /= "" then
            Error_Msg_F (Msg_Cont, P);
         end if;
         Error_Attr;
      end Error_Attr_P;

      ----------------------------
      -- Legal_Formal_Attribute --
      ----------------------------

      procedure Legal_Formal_Attribute is
      begin
         Check_E0;

         if not Is_Entity_Name (P)
           or else not Is_Type (Entity (P))
         then
            Error_Attr_P ("prefix of % attribute must be generic type");

         elsif Is_Generic_Actual_Type (Entity (P))
           or else In_Instance
           or else In_Inlined_Body
         then
            null;

         elsif Is_Generic_Type (Entity (P)) then
            if Is_Definite_Subtype (Entity (P)) then
               Error_Attr_P
                 ("prefix of % attribute must be indefinite generic type");
            end if;

         else
            Error_Attr_P
              ("prefix of % attribute must be indefinite generic type");
         end if;

         Set_Etype (N, Standard_Boolean);
      end Legal_Formal_Attribute;

      ---------------------------------------------------------------
      -- Max_Alignment_For_Allocation_Max_Size_In_Storage_Elements --
      ---------------------------------------------------------------

      procedure Max_Alignment_For_Allocation_Max_Size_In_Storage_Elements is
      begin
         Check_E0;
         Check_Type;
         Check_Not_Incomplete_Type;
         Set_Etype (N, Universal_Integer);
      end Max_Alignment_For_Allocation_Max_Size_In_Storage_Elements;

      -------------
      -- Min_Max --
      -------------

      procedure Min_Max is
      begin
         --  Attribute can appear as function name in a reduction.
         --  Semantic checks are performed later.

         if Nkind (Parent (N)) = N_Attribute_Reference
           and then Attribute_Name (Parent (N)) = Name_Reduce
         then
            Set_Etype (N, P_Base_Type);
            return;
         end if;

         Check_E2;
         Check_Scalar_Type;
         Resolve (E1, P_Base_Type);
         Resolve (E2, P_Base_Type);
         Set_Etype (N, P_Base_Type);

         --  Check for comparison on unordered enumeration type

         if Bad_Unordered_Enumeration_Reference (N, P_Base_Type) then
            Error_Msg_Sloc := Sloc (P_Base_Type);
            Error_Msg_NE
              ("comparison on unordered enumeration type& declared#?U?",
               N, P_Base_Type);
         end if;
      end Min_Max;

      ------------------------
      -- Standard_Attribute --
      ------------------------

      procedure Standard_Attribute (Val : Int) is
      begin
         Check_Standard_Prefix;
         Rewrite (N, Make_Integer_Literal (Loc, Val));
         Analyze (N);
         Set_Is_Static_Expression (N, True);
      end Standard_Attribute;

      --------------------
      -- Uneval_Old_Msg --
      --------------------

      procedure Uneval_Old_Msg is
         Uneval_Old_Setting : Character;
         Prag               : Node_Id;

      begin
         --  If from aspect, then Uneval_Old_Setting comes from flags in the
         --  N_Aspect_Specification node that corresponds to the attribute.

         --  First find the pragma in which we appear (note that at this stage,
         --  even if we appeared originally within an aspect specification, we
         --  are now within the corresponding pragma).

         Prag := N;
         loop
            Prag := Parent (Prag);
            exit when No (Prag) or else Nkind (Prag) = N_Pragma;
         end loop;

         if Present (Prag) then
            if Uneval_Old_Accept (Prag) then
               Uneval_Old_Setting := 'A';
            elsif Uneval_Old_Warn (Prag) then
               Uneval_Old_Setting := 'W';
            else
               Uneval_Old_Setting := 'E';
            end if;

         --  If we did not find the pragma, that's odd, just use the setting
         --  from Opt.Uneval_Old. Perhaps this is due to a previous error?

         else
            Uneval_Old_Setting := Opt.Uneval_Old;
         end if;

         --  Processing depends on the setting of Uneval_Old

         case Uneval_Old_Setting is
            when 'E' =>
               --  ??? In the case where Ada_Version is < Ada_2022 and
               --  an illegal 'Old prefix would be legal in Ada_2022,
               --  we'd like to call Error_Msg_Ada_2022_Feature.
               --  Identifying that case involves some work.

               Error_Attr_P
                 ("prefix of attribute % that is potentially "
                  & "unevaluated must statically name an entity"

                  --  further text needed for accuracy if Ada_2022
                  & (if Ada_Version >= Ada_2022
                       and then Attr_Id = Attribute_Old
                     then " or be eligible for conditional evaluation"
                          & " (RM 6.1.1 (27))"
                     else ""),
                  Msg_Cont =>
                    "\using pragma Unevaluated_Use_Of_Old (Allow) will make "
                    & "this legal");

            when 'W' =>
               Error_Msg_Name_1 := Aname;
               Error_Msg_F
                 ("??prefix of attribute % appears in potentially "
                  & "unevaluated context, exception may be raised", P);

            when 'A' =>
               null;

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

      -------------------------
      -- Unexpected Argument --
      -------------------------

      procedure Unexpected_Argument (En : Node_Id) is
      begin
         Error_Attr ("unexpected argument for % attribute", En);
      end Unexpected_Argument;

      -------------------------------------------------
      -- Validate_Non_Static_Attribute_Function_Call --
      -------------------------------------------------

      --  This function should be moved to Sem_Dist ???

      procedure Validate_Non_Static_Attribute_Function_Call is
      begin
         if In_Preelaborated_Unit
           and then not In_Subprogram_Or_Concurrent_Unit
         then
            Flag_Non_Static_Expr
              ("non-static function call in preelaborated unit!", N);
         end if;
      end Validate_Non_Static_Attribute_Function_Call;

   --  Start of processing for Analyze_Attribute

   begin
      --  Immediate return if unrecognized attribute (already diagnosed by
      --  parser, so there is nothing more that we need to do).

      if not Is_Attribute_Name (Aname) then
         raise Bad_Attribute;
      end if;

      Check_Restriction_No_Use_Of_Attribute (N);

      --  Deal with Ada 83 issues

      if Comes_From_Source (N) then
         if not Attribute_83 (Attr_Id) then
            if Ada_Version = Ada_83 and then Comes_From_Source (N) then
               Error_Msg_Name_1 := Aname;
               Error_Msg_N ("(Ada 83) attribute% is not standard??", N);
            end if;

            if Attribute_Impl_Def (Attr_Id) then
               Check_Restriction (No_Implementation_Attributes, N);
            end if;
         end if;
      end if;

      --  Deal with Ada 2005 attributes that are implementation attributes
      --  because they appear in a version of Ada before Ada 2005, ditto for
      --  Ada 2012 and Ada 2022 attributes appearing in an earlier version.

      if (Attribute_05 (Attr_Id) and then Ada_Version < Ada_2005)
            or else
         (Attribute_12 (Attr_Id) and then Ada_Version < Ada_2012)
            or else
         (Attribute_22 (Attr_Id) and then Ada_Version < Ada_2022)
      then
         Check_Restriction (No_Implementation_Attributes, N);
      end if;

      --   Remote access to subprogram type access attribute reference needs
      --   unanalyzed copy for tree transformation. The analyzed copy is used
      --   for its semantic information (whether prefix is a remote subprogram
      --   name), the unanalyzed copy is used to construct new subtree rooted
      --   with N_Aggregate which represents a fat pointer aggregate.

      if Aname = Name_Access then
         Discard_Node (Copy_Separate_Tree (N));
      end if;

      --  Analyze prefix and exit if error in analysis. If the prefix is an
      --  incomplete type, use full view if available. Note that there are
      --  some attributes for which we do not analyze the prefix, since the
      --  prefix is not a normal name, or else needs special handling.

      if Aname /= Name_Elab_Body       and then
         Aname /= Name_Elab_Spec       and then
         Aname /= Name_Elab_Subp_Body  and then
         Aname /= Name_Enabled         and then
         Aname /= Name_Old
      then
         Analyze (P);
         P_Type := Etype (P);

         if Is_Entity_Name (P)
           and then Present (Entity (P))
           and then Is_Type (Entity (P))
         then
            if Ekind (Entity (P)) = E_Incomplete_Type then
               P_Type := Get_Full_View (P_Type);
               Set_Entity (P, P_Type);
               Set_Etype  (P, P_Type);

            elsif Entity (P) = Current_Scope
              and then Is_Record_Type (Entity (P))
            then
               --  Use of current instance within the type. Verify that if the
               --  attribute appears within a constraint, it  yields an access
               --  type, other uses are illegal.

               declare
                  Par : Node_Id;

               begin
                  Par := Parent (N);
                  while Present (Par)
                    and then Nkind (Parent (Par)) /= N_Component_Definition
                  loop
                     Par := Parent (Par);
                  end loop;

                  if Present (Par)
                    and then Nkind (Par) = N_Subtype_Indication
                  then
                     if Attr_Id /= Attribute_Access
                       and then Attr_Id /= Attribute_Unchecked_Access
                       and then Attr_Id /= Attribute_Unrestricted_Access
                     then
                        Error_Msg_N
                          ("in a constraint the current instance can only "
                           & "be used with an access attribute", N);
                     end if;
                  end if;
               end;
            end if;
         end if;

         if P_Type = Any_Type then
            raise Bad_Attribute;
         end if;

         P_Base_Type := Base_Type (P_Type);
      end if;

      --  Analyze expressions that may be present, exiting if an error occurs

      if No (Exprs) then
         E1 := Empty;
         E2 := Empty;

      else
         E1 := First (Exprs);

         --  Skip analysis for case of Restriction_Set, we do not expect
         --  the argument to be analyzed in this case.

         if Aname /= Name_Restriction_Set then
            Analyze (E1);

            --  Check for missing/bad expression (result of previous error)

            if No (E1) or else Etype (E1) = Any_Type then
               raise Bad_Attribute;
            end if;
         end if;

         E2 := Next (E1);

         if Present (E2) then
            Analyze (E2);

            if Etype (E2) = Any_Type then
               raise Bad_Attribute;
            end if;

            if Present (Next (E2)) then
               Unexpected_Argument (Next (E2));
            end if;
         end if;
      end if;

      --  Cases where prefix must be resolvable by itself

      if Is_Overloaded (P)
        and then Aname /= Name_Access
        and then Aname /= Name_Address
        and then Aname /= Name_Code_Address
        and then Aname /= Name_Result
        and then Aname /= Name_Unchecked_Access
      then
         --  The prefix must be resolvable by itself, without reference to the
         --  attribute. One case that requires special handling is a prefix
         --  that is a function name, where one interpretation may be a
         --  parameterless call. Entry attributes are handled specially below.

         if Is_Entity_Name (P)
           and then Aname not in Name_Count | Name_Caller
         then
            Check_Parameterless_Call (P);
         end if;

         if Is_Overloaded (P) then

            --  Ada 2005 (AI-345): Since protected and task types have
            --  primitive entry wrappers, the attributes Count, and Caller
            --  require a context check

            if Aname in Name_Count | Name_Caller then
               declare
                  Count : Natural := 0;
                  I     : Interp_Index;
                  It    : Interp;

               begin
                  Get_First_Interp (P, I, It);
                  while Present (It.Nam) loop
                     if Comes_From_Source (It.Nam) then
                        Count := Count + 1;
                     else
                        Remove_Interp (I);
                     end if;

                     Get_Next_Interp (I, It);
                  end loop;

                  if Count > 1 then
                     Error_Attr ("ambiguous prefix for % attribute", P);
                  else
                     Set_Is_Overloaded (P, False);
                  end if;
               end;

            else
               Error_Attr ("ambiguous prefix for % attribute", P);
            end if;
         end if;
      end if;

      --  If the prefix was rewritten as a raise node, then rewrite N as a
      --  raise node, to avoid creating inconsistent trees. We still need to
      --  perform legality checks on the original tree.

      if Nkind (P) in N_Raise_xxx_Error then
         Rewrite (N, Relocate_Node (P));
         P := Original_Node (P_Old);
      end if;

      --  Remaining processing depends on attribute

      case Attr_Id is

      --  Attributes related to Ada 2012 iterators. Attribute specifications
      --  exist for these, but they cannot be queried.

      when Attribute_Constant_Indexing
         | Attribute_Default_Iterator
         | Attribute_Implicit_Dereference
         | Attribute_Iterator_Element
         | Attribute_Iterable
         | Attribute_Variable_Indexing
      =>
         Error_Msg_N ("illegal attribute", N);

      --  Internal attributes used to deal with Ada 2012 delayed aspects. These
      --  were already rejected by the parser. Thus they shouldn't appear here.

      when Internal_Attribute_Id =>
         raise Program_Error;

      ------------------
      -- Abort_Signal --
      ------------------

      when Attribute_Abort_Signal =>
         Check_Standard_Prefix;
         Rewrite (N, New_Occurrence_Of (Stand.Abort_Signal, Loc));
         Analyze (N);

      ------------
      -- Access --
      ------------

      when Attribute_Access =>
         Analyze_Access_Attribute;
         Check_Not_Incomplete_Type;

      -------------
      -- Address --
      -------------

      when Attribute_Address =>
         Check_E0;
         Address_Checks;
         Check_Not_Incomplete_Type;
         Set_Etype (N, RTE (RE_Address));

      ------------------
      -- Address_Size --
      ------------------

      when Attribute_Address_Size =>
         Standard_Attribute (System_Address_Size);

      --------------
      -- Adjacent --
      --------------

      when Attribute_Adjacent
         | Attribute_Copy_Sign
         | Attribute_Remainder
      =>
         Check_Floating_Point_Type_2;
         Set_Etype (N, P_Base_Type);
         Resolve (E1, P_Base_Type);
         Resolve (E2, P_Base_Type);

      ---------
      -- Aft --
      ---------

      when Attribute_Aft =>
         Check_Fixed_Point_Type_0;
         Set_Etype (N, Universal_Integer);

      ---------------
      -- Alignment --
      ---------------

      when Attribute_Alignment =>

         --  Don't we need more checking here, cf Size ???

         Check_E0;
         Check_Not_Incomplete_Type;
         Check_Not_CPP_Type;
         Set_Etype (N, Universal_Integer);

      ---------------
      -- Asm_Input --
      ---------------

      when Attribute_Asm_Input =>
         Check_Asm_Attribute;

         --  The back end may need to take the address of E2

         if Is_Entity_Name (E2) then
            Set_Address_Taken (Entity (E2));
         end if;

         Set_Etype (N, RTE (RE_Asm_Input_Operand));

      ----------------
      -- Asm_Output --
      ----------------

      when Attribute_Asm_Output =>
         Check_Asm_Attribute;

         if Etype (E2) = Any_Type then
            return;

         elsif Aname = Name_Asm_Output then
            if not Is_Variable (E2) then
               Error_Attr
                 ("second argument for Asm_Output is not variable", E2);
            end if;
         end if;

         Note_Possible_Modification (E2, Sure => True);

         --  The back end may need to take the address of E2

         if Is_Entity_Name (E2) then
            Set_Address_Taken (Entity (E2));
         end if;

         Set_Etype (N, RTE (RE_Asm_Output_Operand));

      -----------------------------
      -- Atomic_Always_Lock_Free --
      -----------------------------

      when Attribute_Atomic_Always_Lock_Free =>
         Check_E0;
         Check_Type;
         Set_Etype (N, Standard_Boolean);

      ----------
      -- Base --
      ----------

      --  Note: when the base attribute appears in the context of a subtype
      --  mark, the analysis is done by Sem_Ch8.Find_Type, rather than by
      --  the following circuit.

      when Attribute_Base => Base : declare
         Typ : Entity_Id;

      begin
         Check_E0;
         Find_Type (P);
         Typ := Entity (P);

         if Ada_Version >= Ada_95
           and then not Is_Scalar_Type (Typ)
           and then not Is_Generic_Type (Typ)
         then
            Error_Attr_P ("prefix of Base attribute must be scalar type");

         elsif Sloc (Typ) = Standard_Location
           and then Base_Type (Typ) = Typ
           and then Warn_On_Redundant_Constructs
         then
            Error_Msg_NE -- CODEFIX
              ("?r?redundant attribute, & is its own base type", N, Typ);
         end if;

         Set_Etype (N, Base_Type (Entity (P)));
         Set_Entity (N, Base_Type (Entity (P)));
         Rewrite (N, New_Occurrence_Of (Entity (N), Loc));
         Analyze (N);
      end Base;

      ---------
      -- Bit --
      ---------

      when Attribute_Bit =>
         Check_E0;

         if not Is_Object_Reference (P) then
            Error_Attr_P ("prefix of % attribute must be object");

         --  What about the access object cases ???

         else
            null;
         end if;

         Set_Etype (N, Universal_Integer);

      ---------------
      -- Bit_Order --
      ---------------

      when Attribute_Bit_Order =>
         Check_E0;
         Check_Type;

         if not Is_Record_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be record type");
         end if;

         if Bytes_Big_Endian xor Reverse_Bit_Order (P_Type) then
            Rewrite (N,
              New_Occurrence_Of (RTE (RE_High_Order_First), Loc));
         else
            Rewrite (N,
              New_Occurrence_Of (RTE (RE_Low_Order_First), Loc));
         end if;

         Set_Etype (N, RTE (RE_Bit_Order));
         Resolve (N);

         --  Reset incorrect indication of staticness

         Set_Is_Static_Expression (N, False);

      ------------------
      -- Bit_Position --
      ------------------

      --  Note: in generated code, we can have a Bit_Position attribute
      --  applied to a (naked) record component (i.e. the prefix is an
      --  identifier that references an E_Component or E_Discriminant
      --  entity directly, and this is interpreted as expected by Gigi.
      --  The following code will not tolerate such usage, but when the
      --  expander creates this special case, it marks it as analyzed
      --  immediately and sets an appropriate type.

      when Attribute_Bit_Position =>
         if Comes_From_Source (N) then
            Check_Component;
         end if;

         Set_Etype (N, Universal_Integer);

      ------------------
      -- Body_Version --
      ------------------

      when Attribute_Body_Version =>
         Check_E0;
         Check_Program_Unit;
         Set_Etype (N, RTE (RE_Version_String));

      --------------
      -- Callable --
      --------------

      when Attribute_Callable
         | Attribute_Terminated
      =>
         Check_E0;
         Set_Etype (N, Standard_Boolean);
         Check_Task_Prefix;

      ------------
      -- Caller --
      ------------

      when Attribute_Caller => Caller : declare
         Ent        : Entity_Id;
         S          : Entity_Id;

      begin
         Check_E0;

         if Nkind (P) in N_Identifier | N_Expanded_Name then
            Ent := Entity (P);

            if not Is_Entry (Ent) then
               Error_Attr ("invalid entry name", N);
            end if;

         else
            Error_Attr ("invalid entry name", N);
            return;
         end if;

         for J in reverse 0 .. Scope_Stack.Last loop
            S := Scope_Stack.Table (J).Entity;

            if S = Scope (Ent) then
               Error_Attr ("Caller must appear in matching accept or body", N);
            elsif S = Ent then
               exit;
            end if;
         end loop;

         Set_Etype (N, RTE (RO_AT_Task_Id));
      end Caller;

      -------------
      -- Ceiling --
      -------------

      when Attribute_Ceiling
         | Attribute_Floor
         | Attribute_Fraction
         | Attribute_Machine
         | Attribute_Machine_Rounding
         | Attribute_Model
         | Attribute_Rounding
         | Attribute_Truncation
         | Attribute_Unbiased_Rounding
      =>
         Check_Floating_Point_Type_1;
         Set_Etype (N, P_Base_Type);
         Resolve (E1, P_Base_Type);

      -----------
      -- Class --
      -----------

      when Attribute_Class =>
         Check_Restriction (No_Dispatch, N);
         Check_E0;
         Find_Type (N);

         --  Applying Class to untagged incomplete type is obsolescent in Ada
         --  2005. Note that we can't test Is_Tagged_Type here on P_Type, since
         --  this flag gets set by Find_Type in this situation.

         if Restriction_Check_Required (No_Obsolescent_Features)
           and then Ada_Version >= Ada_2005
           and then Ekind (P_Type) = E_Incomplete_Type
         then
            declare
               DN : constant Node_Id := Declaration_Node (P_Type);
            begin
               if Nkind (DN) = N_Incomplete_Type_Declaration
                 and then not Tagged_Present (DN)
               then
                  Check_Restriction (No_Obsolescent_Features, P);
               end if;
            end;
         end if;

      ------------------
      -- Code_Address --
      ------------------

      when Attribute_Code_Address =>
         Check_E0;

         if Nkind (P) = N_Attribute_Reference
           and then Attribute_Name (P) in Name_Elab_Body | Name_Elab_Spec
         then
            null;

         elsif not Is_Entity_Name (P)
           or else (Ekind (Entity (P)) /= E_Function
                      and then
                    Ekind (Entity (P)) /= E_Procedure)
         then
            Error_Attr ("invalid prefix for % attribute", P);
            Set_Address_Taken (Entity (P));

         --  Issue an error if the prefix denotes an eliminated subprogram

         else
            Check_For_Eliminated_Subprogram (P, Entity (P));
         end if;

         Set_Etype (N, RTE (RE_Address));

      ----------------------
      -- Compiler_Version --
      ----------------------

      when Attribute_Compiler_Version =>
         Check_E0;
         Check_Standard_Prefix;
         Rewrite (N, Make_String_Literal (Loc, "GNAT " & Gnat_Version_String));
         Analyze_And_Resolve (N, Standard_String);
         Set_Is_Static_Expression (N, True);

      --------------------
      -- Component_Size --
      --------------------

      when Attribute_Component_Size =>
         Check_E0;
         Set_Etype (N, Universal_Integer);

         --  Note: unlike other array attributes, unconstrained arrays are OK

         if Is_Array_Type (P_Type) and then not Is_Constrained (P_Type) then
            null;
         else
            Check_Array_Type;
         end if;

      -------------
      -- Compose --
      -------------

      when Attribute_Compose
         | Attribute_Leading_Part
         | Attribute_Scaling
      =>
         Check_Floating_Point_Type_2;
         Set_Etype (N, P_Base_Type);
         Resolve (E1, P_Base_Type);
         Resolve (E2, Any_Integer);

      -----------------
      -- Constrained --
      -----------------

      when Attribute_Constrained =>
         Check_E0;
         Set_Etype (N, Standard_Boolean);

         --  Case from RM J.4(2) of constrained applied to private type

         if Is_Entity_Name (P) and then Is_Type (Entity (P)) then
            Check_Restriction (No_Obsolescent_Features, P);

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("constrained for private type is an obsolescent feature "
                  & "(RM J.4)?j?", N);
            end if;

            --  If we are within an instance, the attribute must be legal
            --  because it was valid in the generic unit. Ditto if this is
            --  an inlining of a function declared in an instance.

            if In_Instance or else In_Inlined_Body then
               return;

            --  For sure OK if we have a real private type itself, but must
            --  be completed, cannot apply Constrained to incomplete type.

            elsif Is_Private_Type (Entity (P)) then

               --  Note: this is one of the Annex J features that does not
               --  generate a warning from -gnatwj, since in fact it seems
               --  very useful, and is used in the GNAT runtime.

               Check_Not_Incomplete_Type;
               return;
            end if;

         --  Normal (non-obsolescent case) of application to object or value of
         --  a discriminated type.

         else
            --  AI12-0068: In a type or subtype aspect, a prefix denoting the
            --  current instance of the (sub)type is defined to be a value,
            --  not an object, so the Constrained attribute is always True
            --  (see RM 8.6(18/5) and RM 3.7.2(3/5)). We issue a warning about
            --  this unintuitive result, to help avoid confusion.

            if Is_Current_Instance_Reference_In_Type_Aspect (P) then
               Error_Msg_Name_1 := Aname;
               Error_Msg_N
                 ("current instance attribute % in subtype aspect always " &
                  "true??", N);

            else
               Check_Object_Reference (P);
            end if;

            --  If N does not come from source, then we allow the
            --  the attribute prefix to be of a private type whose
            --  full type has discriminants. This occurs in cases
            --  involving expanded calls to stream attributes.

            if not Comes_From_Source (N) then
               P_Type := Underlying_Type (P_Type);
            end if;

            --  Must have discriminants or be an access type designating a type
            --  with discriminants. If it is a class-wide type it has unknown
            --  discriminants.

            if Has_Discriminants (P_Type)
              or else Has_Unknown_Discriminants (P_Type)
              or else
                (Is_Access_Type (P_Type)
                  and then Has_Discriminants (Designated_Type (P_Type)))
            then
               return;

            --  The rule given in 3.7.2 is part of static semantics, but the
            --  intent is clearly that it be treated as a legality rule, and
            --  rechecked in the visible part of an instance. Nevertheless
            --  the intent also seems to be it should legally apply to the
            --  actual of a formal with unknown discriminants, regardless of
            --  whether the actual has discriminants, in which case the value
            --  of the attribute is determined using the J.4 rules. This choice
            --  seems the most useful, and is compatible with existing tests.

            elsif In_Instance then
               return;

            --  Also allow an object of a generic type if extensions allowed
            --  and allow this for any type at all.

            elsif (Is_Generic_Type (P_Type)
                    or else Is_Generic_Actual_Type (P_Type))
              and then Extensions_Allowed
            then
               return;
            end if;
         end if;

         --  Fall through if bad prefix

         Error_Attr_P
           ("prefix of % attribute must be object of discriminated type");

      ---------------
      -- Copy_Sign --
      ---------------

      --  Shares processing with Adjacent attribute

      -----------
      -- Count --
      -----------

      when Attribute_Count => Count : declare
         Ent : Entity_Id;
         S   : Entity_Id;
         Tsk : Entity_Id;

      begin
         Check_E0;

         if Nkind (P) in N_Identifier | N_Expanded_Name then
            Ent := Entity (P);

            if Ekind (Ent) /= E_Entry then
               Error_Attr ("invalid entry name", N);
            end if;

         elsif Nkind (P) = N_Indexed_Component then
            if not Is_Entity_Name (Prefix (P))
              or else No (Entity (Prefix (P)))
              or else Ekind (Entity (Prefix (P))) /= E_Entry_Family
            then
               if Nkind (Prefix (P)) = N_Selected_Component
                 and then Present (Entity (Selector_Name (Prefix (P))))
                 and then Ekind (Entity (Selector_Name (Prefix (P)))) =
                                                             E_Entry_Family
               then
                  Error_Attr
                    ("attribute % must apply to entry of current task", P);

               else
                  Error_Attr ("invalid entry family name", P);
               end if;
               return;

            else
               Ent := Entity (Prefix (P));
            end if;

         elsif Nkind (P) = N_Selected_Component
           and then Present (Entity (Selector_Name (P)))
           and then Ekind (Entity (Selector_Name (P))) = E_Entry
         then
            Error_Attr
              ("attribute % must apply to entry of current task", P);

         else
            Error_Attr ("invalid entry name", N);
            return;
         end if;

         for J in reverse 0 .. Scope_Stack.Last loop
            S := Scope_Stack.Table (J).Entity;

            if S = Scope (Ent) then
               if Nkind (P) = N_Expanded_Name then
                  Tsk := Entity (Prefix (P));

                  --  The prefix denotes either the task type, or else a
                  --  single task whose task type is being analyzed.

                  if (Is_Type (Tsk) and then Tsk = S)
                    or else (not Is_Type (Tsk)
                              and then Etype (Tsk) = S
                              and then not (Comes_From_Source (S)))
                  then
                     null;
                  else
                     Error_Attr
                       ("attribute % must apply to entry of current task", N);
                  end if;
               end if;

               exit;

            elsif Ekind (Scope (Ent)) in Task_Kind
              and then Ekind (S) not in E_Block
                                      | E_Entry
                                      | E_Entry_Family
                                      | E_Loop
            then
               Error_Attr ("attribute % cannot appear in inner unit", N);

            elsif Ekind (Scope (Ent)) = E_Protected_Type
              and then not Has_Completion (Scope (Ent))
            then
               Error_Attr ("attribute % can only be used inside body", N);
            end if;
         end loop;

         if Is_Overloaded (P) then
            declare
               Index : Interp_Index;
               It    : Interp;

            begin
               Get_First_Interp (P, Index, It);
               while Present (It.Nam) loop
                  if It.Nam = Ent then
                     null;

                  --  Ada 2005 (AI-345): Do not consider primitive entry
                  --  wrappers generated for task or protected types.

                  elsif Ada_Version >= Ada_2005
                    and then not Comes_From_Source (It.Nam)
                  then
                     null;

                  else
                     Error_Attr ("ambiguous entry name", N);
                  end if;

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

         Set_Etype (N, Universal_Integer);
      end Count;

      -----------------------
      -- Default_Bit_Order --
      -----------------------

      when Attribute_Default_Bit_Order => Default_Bit_Order : declare
         Target_Default_Bit_Order : System.Bit_Order;

      begin
         Check_Standard_Prefix;

         if Bytes_Big_Endian then
            Target_Default_Bit_Order := System.High_Order_First;
         else
            Target_Default_Bit_Order := System.Low_Order_First;
         end if;

         Rewrite (N,
           Make_Integer_Literal (Loc,
             UI_From_Int (System.Bit_Order'Pos (Target_Default_Bit_Order))));

         Set_Etype (N, Universal_Integer);
         Set_Is_Static_Expression (N);
      end Default_Bit_Order;

      ----------------------------------
      -- Default_Scalar_Storage_Order --
      ----------------------------------

      when Attribute_Default_Scalar_Storage_Order => Default_SSO : declare
         RE_Default_SSO : RE_Id;

      begin
         Check_Standard_Prefix;

         case Opt.Default_SSO is
            when ' ' =>
               if Bytes_Big_Endian then
                  RE_Default_SSO := RE_High_Order_First;
               else
                  RE_Default_SSO := RE_Low_Order_First;
               end if;

            when 'H' =>
               RE_Default_SSO := RE_High_Order_First;

            when 'L' =>
               RE_Default_SSO := RE_Low_Order_First;

            when others =>
               raise Program_Error;
         end case;

         Rewrite (N, New_Occurrence_Of (RTE (RE_Default_SSO), Loc));
      end Default_SSO;

      --------------
      -- Definite --
      --------------

      when Attribute_Definite =>
         Legal_Formal_Attribute;

      -----------
      -- Delta --
      -----------

      when Attribute_Delta =>
         Check_Fixed_Point_Type_0;
         Set_Etype (N, Universal_Real);

      ------------
      -- Denorm --
      ------------

      when Attribute_Denorm
         | Attribute_Signed_Zeros
      =>
         Check_Floating_Point_Type_0;
         Set_Etype (N, Standard_Boolean);

      -----------
      -- Deref --
      -----------

      when Attribute_Deref =>
         Check_Type;
         Check_E1;
         Resolve (E1, RTE (RE_Address));
         Set_Etype (N, P_Type);

      ---------------------
      -- Descriptor_Size --
      ---------------------

      when Attribute_Descriptor_Size =>
         Check_E0;

         if not Is_Entity_Name (P) or else not Is_Type (Entity (P)) then
            Error_Attr_P ("prefix of attribute % must denote a type");
         end if;

         Set_Etype (N, Universal_Integer);

      ------------
      -- Digits --
      ------------

      when Attribute_Digits =>
         Check_E0;
         Check_Type;

         if not Is_Floating_Point_Type (P_Type)
           and then not Is_Decimal_Fixed_Point_Type (P_Type)
         then
            Error_Attr_P
              ("prefix of % attribute must be float or decimal type");
         end if;

         Set_Etype (N, Universal_Integer);

      ---------------
      -- Elab_Body --
      ---------------

      --  Also handles processing for Elab_Spec and Elab_Subp_Body

      when Attribute_Elab_Body
         | Attribute_Elab_Spec
         | Attribute_Elab_Subp_Body
      =>
         Check_E0;
         Check_Unit_Name (P);
         Set_Etype (N, Standard_Void_Type);

         --  We have to manually call the expander in this case to get
         --  the necessary expansion (normally attributes that return
         --  entities are not expanded).

         Expand (N);

      ---------------
      -- Elab_Spec --
      ---------------

      --  Shares processing with Elab_Body attribute

      ----------------
      -- Elaborated --
      ----------------

      when Attribute_Elaborated =>
         Check_E0;
         Check_Unit_Name (P);
         Set_Etype (N, Standard_Boolean);

      ----------
      -- Emax --
      ----------

      when Attribute_Emax
         | Attribute_Machine_Emax
         | Attribute_Machine_Emin
         | Attribute_Machine_Mantissa
         | Attribute_Model_Emin
         | Attribute_Model_Mantissa
         | Attribute_Safe_Emax
      =>
         Check_Floating_Point_Type_0;
         Set_Etype (N, Universal_Integer);

      -------------
      -- Enabled --
      -------------

      when Attribute_Enabled =>
         Check_Either_E0_Or_E1;

         if Present (E1) then
            if not Is_Entity_Name (E1) or else No (Entity (E1)) then
               Error_Msg_N ("entity name expected for Enabled attribute", E1);
               E1 := Empty;
            end if;
         end if;

         if Nkind (P) /= N_Identifier then
            Error_Msg_N ("identifier expected (check name)", P);
         elsif Get_Check_Id (Chars (P)) = No_Check_Id then
            Error_Msg_N ("& is not a recognized check name", P);
         end if;

         Set_Etype (N, Standard_Boolean);

      --------------
      -- Enum_Rep --
      --------------

      when Attribute_Enum_Rep =>

         --  T'Enum_Rep (X) case

         if Present (E1) then
            Check_E1;
            Check_Discrete_Type;
            Resolve (E1, P_Base_Type);

         --  X'Enum_Rep case. X must be an object or enumeration literal
         --  (including an attribute reference), and it must be of a
         --  discrete type.

         elsif not
           ((Is_Object_Reference (P)
               or else
                 (Is_Entity_Name (P)
                    and then Ekind (Entity (P)) = E_Enumeration_Literal)
               or else Nkind (P) = N_Attribute_Reference)
             and then Is_Discrete_Type (Etype (P)))
         then
            Error_Attr_P ("prefix of % attribute must be discrete object");
         end if;

         Set_Etype (N, Universal_Integer);

      --------------
      -- Enum_Val --
      --------------

      when Attribute_Enum_Val =>
         Check_E1;
         Check_Type;

         if not Is_Enumeration_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be enumeration type");
         end if;

         --  If the enumeration type has a standard representation, the effect
         --  is the same as 'Val, so rewrite the attribute as a 'Val.

         if not Has_Non_Standard_Rep (P_Base_Type) then
            Rewrite (N,
              Make_Attribute_Reference (Loc,
                Prefix         => Relocate_Node (Prefix (N)),
                Attribute_Name => Name_Val,
                Expressions    => New_List (Relocate_Node (E1))));
            Analyze_And_Resolve (N, P_Base_Type);

         --  Non-standard representation case (enumeration with holes)

         else
            Check_Enum_Image;
            Resolve (E1, Any_Integer);
            Set_Etype (N, P_Base_Type);
         end if;

      -------------
      -- Epsilon --
      -------------

      when Attribute_Epsilon
         | Attribute_Model_Epsilon
         | Attribute_Model_Small
         | Attribute_Safe_First
         | Attribute_Safe_Last
      =>
         Check_Floating_Point_Type_0;
         Set_Etype (N, Universal_Real);

      --------------
      -- Exponent --
      --------------

      when Attribute_Exponent =>
         Check_Floating_Point_Type_1;
         Set_Etype (N, Universal_Integer);
         Resolve (E1, P_Base_Type);

      ------------------
      -- External_Tag --
      ------------------

      when Attribute_External_Tag =>
         Check_E0;
         Check_Type;

         Set_Etype (N, Standard_String);

         if not Is_Tagged_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be tagged");
         end if;

      ---------------
      -- Fast_Math --
      ---------------

      when Attribute_Fast_Math =>
         Check_Standard_Prefix;
         Rewrite (N, New_Occurrence_Of (Boolean_Literals (Fast_Math), Loc));

      -----------------------
      -- Finalization_Size --
      -----------------------

      when Attribute_Finalization_Size =>
         Check_E0;

         --  The prefix denotes an object

         if Is_Object_Reference (P) then
            Check_Object_Reference (P);

         --  The prefix denotes a type

         elsif Is_Entity_Name (P) and then Is_Type (Entity (P)) then
            Check_Type;
            Check_Not_Incomplete_Type;

            --  Attribute 'Finalization_Size is not defined for class-wide
            --  types because it is not possible to know statically whether
            --  a definite type will have controlled components or not.

            if Is_Class_Wide_Type (Etype (P)) then
               Error_Attr_P
                 ("prefix of % attribute cannot denote a class-wide type");
            end if;

         --  The prefix denotes an illegal construct

         else
            Error_Attr_P
              ("prefix of % attribute must be a definite type or an object");
         end if;

         Set_Etype (N, Universal_Integer);

      -----------
      -- First --
      -----------

      when Attribute_First
         | Attribute_Last
      =>
         Check_Array_Or_Scalar_Type;
         Bad_Attribute_For_Predicate;

      ---------------
      -- First_Bit --
      ---------------

      when Attribute_First_Bit
         | Attribute_Last_Bit
         | Attribute_Position
      =>
         Check_Component;
         Set_Etype (N, Universal_Integer);

      -----------------
      -- First_Valid --
      -----------------

      when Attribute_First_Valid
         | Attribute_Last_Valid
      =>
         Check_First_Last_Valid;
         Set_Etype (N, P_Type);

      -----------------
      -- Fixed_Value --
      -----------------

      when Attribute_Fixed_Value =>
         Check_Fixed_Point_Type;
         Check_E1;
         Resolve (E1, Any_Integer);
         Set_Etype (N, P_Base_Type);

      -----------
      -- Floor --
      -----------

      --  Shares processing with Ceiling attribute

      ----------
      -- Fore --
      ----------

      when Attribute_Fore =>
         Check_Fixed_Point_Type_0;
         Set_Etype (N, Universal_Integer);

      --------------
      -- Fraction --
      --------------

      --  Shares processing with Ceiling attribute

      --------------
      -- From_Any --
      --------------

      when Attribute_From_Any =>
         Check_E1;
         Check_PolyORB_Attribute;
         Set_Etype (N, P_Base_Type);

      -----------------------
      -- Has_Access_Values --
      -----------------------

      when Attribute_Has_Access_Values
         | Attribute_Has_Tagged_Values
      =>
         Check_Type;
         Check_E0;
         Set_Etype (N, Standard_Boolean);

      ----------------------
      -- Has_Same_Storage --
      ----------------------

      when Attribute_Has_Same_Storage =>
         Check_E1;

         --  The arguments must be objects of any type

         Analyze_And_Resolve (P);
         Analyze_And_Resolve (E1);
         Check_Object_Reference (P);
         Check_Object_Reference (E1);
         Set_Etype (N, Standard_Boolean);

      -----------------------
      -- Has_Tagged_Values --
      -----------------------

      --  Shares processing with Has_Access_Values attribute

      -----------------------
      -- Has_Discriminants --
      -----------------------

      when Attribute_Has_Discriminants =>
         Legal_Formal_Attribute;

      --------------
      -- Identity --
      --------------

      when Attribute_Identity =>
         Check_E0;
         Analyze (P);

         if Etype (P) = Standard_Exception_Type then
            Set_Etype (N, RTE (RE_Exception_Id));

         --  Ada 2005 (AI-345): Attribute 'Identity may be applied to task
         --  interface class-wide types.

         elsif Is_Task_Type (Etype (P))
           or else (Is_Access_Type (Etype (P))
                      and then Is_Task_Type (Designated_Type (Etype (P))))
           or else (Ada_Version >= Ada_2005
                      and then Ekind (Etype (P)) = E_Class_Wide_Type
                      and then Is_Interface (Etype (P))
                      and then Is_Task_Interface (Etype (P)))
         then
            Resolve (P);
            Set_Etype (N, RTE (RO_AT_Task_Id));

         else
            if Ada_Version >= Ada_2005 then
               Error_Attr_P
                 ("prefix of % attribute must be an exception, a task or a "
                  & "task interface class-wide object");
            else
               Error_Attr_P
                 ("prefix of % attribute must be a task or an exception");
            end if;
         end if;

      -----------
      -- Image --
      -----------

      when Attribute_Image =>
         if Is_Real_Type (P_Type) then
            if Ada_Version = Ada_83 and then Comes_From_Source (N) then
               Error_Msg_Name_1 := Aname;
               Error_Msg_N
                 ("(Ada 83) % attribute not allowed for real types", N);
            end if;
         end if;

         Analyze_Image_Attribute (Standard_String);

      ---------
      -- Img --
      ---------

      when Attribute_Img =>
         Analyze_Image_Attribute (Standard_String);

      -----------------
      -- Initialized --
      -----------------

      when Attribute_Initialized =>
         Check_E0;

         if Comes_From_Source (N) then

            --  This attribute be prefixed with references to objects or
            --  values (such as a current instance value given within a type
            --  or subtype aspect).

            if not Is_Object_Reference (P)
              and then not Is_Current_Instance_Reference_In_Type_Aspect (P)
            then
               Error_Attr_P ("prefix of % attribute must be object");
            end if;
         end if;

         Set_Etype (N, Standard_Boolean);

      -----------
      -- Input --
      -----------

      when Attribute_Input =>
         Check_E1;
         Check_Stream_Attribute (TSS_Stream_Input);
         Set_Etype (N, P_Base_Type);

      -------------------
      -- Integer_Value --
      -------------------

      when Attribute_Integer_Value =>
         Check_E1;
         Check_Integer_Type;
         Resolve (E1, Any_Fixed);

         --  Signal an error if argument type is not a specific fixed-point
         --  subtype. An error has been signalled already if the argument
         --  was not of a fixed-point type.

         if Etype (E1) = Any_Fixed and then not Error_Posted (E1) then
            Error_Attr ("argument of % must be of a fixed-point type", E1);
         end if;

         Set_Etype (N, P_Base_Type);

      -------------------
      -- Invalid_Value --
      -------------------

      when Attribute_Invalid_Value =>
         Check_E0;
         Check_Scalar_Type;
         Set_Etype (N, P_Base_Type);
         Invalid_Value_Used := True;

      -----------
      -- Large --
      -----------

      when Attribute_Large
         | Attribute_Small
         | Attribute_Safe_Large
         | Attribute_Safe_Small
      =>
         Check_E0;
         Check_Real_Type;
         Set_Etype (N, Universal_Real);

      ----------
      -- Last --
      ----------

      --  Shares processing with First attribute

      --------------
      -- Last_Bit --
      --------------

      --  Shares processing with First_Bit attribute

      ----------------
      -- Last_Valid --
      ----------------

      --  Shares processing with First_Valid attribute

      ------------------
      -- Leading_Part --
      ------------------

      --  Shares processing with Compose attribute

      ------------
      -- Length --
      ------------

      when Attribute_Length =>
         Check_Array_Type;
         Set_Etype (N, Universal_Integer);

      -------------------
      -- Library_Level --
      -------------------

      when Attribute_Library_Level =>
         Check_E0;

         if not Is_Entity_Name (P) then
            Error_Attr_P ("prefix of % attribute must be an entity name");
         end if;

         if not Inside_A_Generic then
            Set_Boolean_Result (N,
              Is_Library_Level_Entity (Entity (P)));
         end if;

         Set_Etype (N, Standard_Boolean);

      ---------------
      -- Lock_Free --
      ---------------

      when Attribute_Lock_Free =>
         Check_E0;
         Set_Etype (N, Standard_Boolean);

         if not Is_Protected_Type (P_Type) then
            Error_Attr_P
              ("prefix of % attribute must be a protected object");
         end if;

      ----------------
      -- Loop_Entry --
      ----------------

      when Attribute_Loop_Entry => Loop_Entry : declare
         procedure Check_References_In_Prefix (Loop_Id : Entity_Id);
         --  Inspect the prefix for any uses of entities declared within the
         --  related loop. Loop_Id denotes the loop identifier.

         --------------------------------
         -- Check_References_In_Prefix --
         --------------------------------

         procedure Check_References_In_Prefix (Loop_Id : Entity_Id) is
            Loop_Decl : constant Node_Id := Label_Construct (Parent (Loop_Id));

            function Check_Reference (Nod : Node_Id) return Traverse_Result;
            --  Determine whether a reference mentions an entity declared
            --  within the related loop.

            function Declared_Within (Nod : Node_Id) return Boolean;
            --  Determine whether Nod appears in the subtree of Loop_Decl but
            --  not within the subtree of the prefix P itself.

            ---------------------
            -- Check_Reference --
            ---------------------

            function Check_Reference (Nod : Node_Id) return Traverse_Result is
            begin
               if Nkind (Nod) = N_Identifier
                 and then Present (Entity (Nod))
                 and then Declared_Within (Declaration_Node (Entity (Nod)))
               then
                  Error_Attr
                    ("prefix of attribute % cannot reference local entities",
                     Nod);
                  return Abandon;
               else
                  return OK;
               end if;
            end Check_Reference;

            procedure Check_References is new Traverse_Proc (Check_Reference);

            ---------------------
            -- Declared_Within --
            ---------------------

            function Declared_Within (Nod : Node_Id) return Boolean is
               Stmt : Node_Id;

            begin
               Stmt := Nod;
               while Present (Stmt) loop
                  if Stmt = Loop_Decl then
                     return True;

                  elsif Stmt = P then
                     return False;

                  --  Prevent the search from going too far

                  elsif Is_Body_Or_Package_Declaration (Stmt) then
                     exit;
                  end if;

                  Stmt := Parent (Stmt);
               end loop;

               return False;
            end Declared_Within;

         --  Start of processing for Check_Prefix_For_Local_References

         begin
            Check_References (P);
         end Check_References_In_Prefix;

         --  Local variables

         Context   : constant Node_Id := Parent (N);
         Attr      : Node_Id;
         Encl_Loop : Node_Id   := Empty;
         Encl_Prag : Node_Id   := Empty;
         Loop_Id   : Entity_Id := Empty;
         Scop      : Entity_Id;
         Stmt      : Node_Id;

      --  Start of processing for Loop_Entry

      begin
         Attr := N;

         --  Set the type of the attribute now to ensure the successful
         --  continuation of analysis even if the attribute is misplaced.

         Set_Etype (Attr, P_Type);

         --  Attribute 'Loop_Entry may appear in several flavors:

         --    * Prefix'Loop_Entry - in this form, the attribute applies to the
         --        nearest enclosing loop.

         --    * Prefix'Loop_Entry (Expr) - depending on what Expr denotes, the
         --        attribute may be related to a loop denoted by label Expr or
         --        the prefix may denote an array object and Expr may act as an
         --        indexed component.

         --    * Prefix'Loop_Entry (Expr1, ..., ExprN) - the attribute applies
         --        to the nearest enclosing loop, all expressions are part of
         --        an indexed component.

         --    * Prefix'Loop_Entry (Expr) (...) (...) - depending on what Expr
         --        denotes, the attribute may be related to a loop denoted by
         --        label Expr or the prefix may denote a multidimensional array
         --        array object and Expr along with the rest of the expressions
         --        may act as indexed components.

         --  Regardless of variations, the attribute reference does not have an
         --  expression list. Instead, all available expressions are stored as
         --  indexed components.

         --  When the attribute is part of an indexed component, find the first
         --  expression as it will determine the semantics of 'Loop_Entry.

         --  If the attribute is itself an index in an indexed component, i.e.
         --  a member of a list, the context itself is not relevant (the code
         --  below would lead to an infinite loop) and the attribute applies
         --  to the enclosing loop.

         if Nkind (Context) = N_Indexed_Component
           and then not Is_List_Member (N)
         then
            E1 := First (Expressions (Context));
            E2 := Next (E1);

            --  The attribute reference appears in the following form:

            --    Prefix'Loop_Entry (Exp1, Expr2, ..., ExprN) [(...)]

            --  In this case, the loop name is omitted and no rewriting is
            --  required.

            if Present (E2) then
               null;

            --  The form of the attribute is:

            --    Prefix'Loop_Entry (Expr) [(...)]

            --  If Expr denotes a loop entry, the whole attribute and indexed
            --  component will have to be rewritten to reflect this relation.

            else
               pragma Assert (Present (E1));

               --  Do not expand the expression as it may have side effects.
               --  Simply preanalyze to determine whether it is a loop name or
               --  something else.

               Preanalyze_And_Resolve (E1);

               if Is_Entity_Name (E1)
                 and then Present (Entity (E1))
                 and then Ekind (Entity (E1)) = E_Loop
               then
                  Loop_Id := Entity (E1);

                  --  Transform the attribute and enclosing indexed component

                  Set_Expressions (N, Expressions (Context));
                  Rewrite   (Context, N);
                  Set_Etype (Context, P_Type);

                  Attr := Context;
               end if;
            end if;
         end if;

         --  The prefix must denote an object

         if not Is_Object_Reference (P) then
            Error_Attr_P ("prefix of attribute % must denote an object");
         end if;

         --  The prefix cannot be of a limited type because the expansion of
         --  Loop_Entry must create a constant initialized by the evaluated
         --  prefix.

         if Is_Limited_View (Etype (P)) then
            Error_Attr_P ("prefix of attribute % cannot be limited");
         end if;

         --  Climb the parent chain to verify the location of the attribute and
         --  find the enclosing loop.

         Stmt := Attr;
         while Present (Stmt) loop

            --  Locate the corresponding enclosing pragma. Note that in the
            --  case of Assert[And_Cut] and Assume, we have already checked
            --  that the pragma appears in an appropriate loop location.

            if Nkind (Original_Node (Stmt)) = N_Pragma
              and then
                Pragma_Name_Unmapped (Original_Node (Stmt))
                  in Name_Loop_Invariant
                   | Name_Loop_Variant
                   | Name_Assert
                   | Name_Assert_And_Cut
                   | Name_Assume
            then
               Encl_Prag := Original_Node (Stmt);

            --  Locate the enclosing loop (if any). Note that Ada 2012 array
            --  iteration may be expanded into several nested loops, we are
            --  interested in the outermost one which has the loop identifier,
            --  and comes from source.

            elsif Nkind (Stmt) = N_Loop_Statement
              and then Present (Identifier (Stmt))
              and then Comes_From_Source (Original_Node (Stmt))
              and then Nkind (Original_Node (Stmt)) = N_Loop_Statement
            then
               Encl_Loop := Stmt;

               --  The original attribute reference may lack a loop name. Use
               --  the name of the enclosing loop because it is the related
               --  loop.

               if No (Loop_Id) then
                  Loop_Id := Entity (Identifier (Encl_Loop));
               end if;

               exit;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Stmt) then
               exit;
            end if;

            Stmt := Parent (Stmt);
         end loop;

         --  Loop_Entry must appear within a Loop_Assertion pragma (Assert,
         --  Assert_And_Cut, Assume count as loop assertion pragmas for this
         --  purpose if they appear in an appropriate location in a loop,
         --  which was already checked by the top level pragma circuit).

         --  Loop_Entry also denotes a value and as such can appear within an
         --  expression that is an argument for another loop aspect. In that
         --  case it will have been expanded into the corresponding assignment.

         if Expander_Active
           and then Nkind (Parent (N)) = N_Assignment_Statement
           and then not Comes_From_Source (Parent (N))
         then
            null;

         elsif No (Encl_Prag) then
            Error_Attr ("attribute% must appear within appropriate pragma", N);
         end if;

         --  A Loop_Entry that applies to a given loop statement must not
         --  appear within a body of accept statement, if this construct is
         --  itself enclosed by the given loop statement.

         for Index in reverse 0 .. Scope_Stack.Last loop
            Scop := Scope_Stack.Table (Index).Entity;

            if Ekind (Scop) = E_Loop and then Scop = Loop_Id then
               exit;
            elsif Ekind (Scop) in E_Block | E_Loop | E_Return_Statement then
               null;
            else
               Error_Attr
                 ("attribute % cannot appear in body or accept statement", N);
               exit;
            end if;
         end loop;

         --  The prefix cannot mention entities declared within the related
         --  loop because they will not be visible once the prefix is moved
         --  outside the loop.

         Check_References_In_Prefix (Loop_Id);

         --  The prefix must statically name an object if the pragma does not
         --  apply to the innermost enclosing loop statement, or if it appears
         --  within a potentially unevaluated expression.

         if Is_Entity_Name (P)
           or else Nkind (Parent (P)) = N_Object_Renaming_Declaration
           or else Statically_Names_Object (P)
         then
            null;

         elsif Present (Encl_Loop)
           and then Entity (Identifier (Encl_Loop)) /= Loop_Id
         then
            Error_Attr_P
              ("prefix of attribute % that applies to outer loop must denote "
               & "an entity");

         elsif Is_Potentially_Unevaluated (P) then
            Uneval_Old_Msg;
         end if;

         --  Replace the Loop_Entry attribute reference by its prefix if the
         --  related pragma is ignored. This transformation is OK with respect
         --  to typing because Loop_Entry's type is that of its prefix. This
         --  early transformation also avoids the generation of a useless loop
         --  entry constant.

         if Present (Encl_Prag) and then Is_Ignored (Encl_Prag) then
            Rewrite (N, Relocate_Node (P));
            Preanalyze_And_Resolve (N);

         else
            Preanalyze_And_Resolve (P);
         end if;
      end Loop_Entry;

      -------------
      -- Machine --
      -------------

      --  Shares processing with Ceiling attribute

      ------------------
      -- Machine_Emax --
      ------------------

      --  Shares processing with Emax attribute

      ------------------
      -- Machine_Emin --
      ------------------

      --  Shares processing with Emax attribute

      ----------------------
      -- Machine_Mantissa --
      ----------------------

      --  Shares processing with Emax attribute

      -----------------------
      -- Machine_Overflows --
      -----------------------

      when Attribute_Machine_Overflows
         | Attribute_Machine_Rounds
      =>
         Check_Real_Type;
         Check_E0;
         Set_Etype (N, Standard_Boolean);

      -------------------
      -- Machine_Radix --
      -------------------

      when Attribute_Machine_Radix
         | Attribute_Mantissa
      =>
         Check_Real_Type;
         Check_E0;
         Set_Etype (N, Universal_Integer);

      ----------------------
      -- Machine_Rounding --
      ----------------------

      --  Shares processing with Ceiling attribute

      --------------------
      -- Machine_Rounds --
      --------------------

      --  Shares processing with Machine_Overflows attribute

      ------------------
      -- Machine_Size --
      ------------------

      when Attribute_Machine_Size
         | Attribute_Object_Size
         | Attribute_Value_Size
      =>
         Check_E0;
         Check_Type;
         Check_Not_Incomplete_Type;
         Set_Etype (N, Universal_Integer);

      --------------
      -- Mantissa --
      --------------

      --  Shares processing with Machine_Radix attribute

      ---------
      -- Max --
      ---------

      when Attribute_Max =>
         Min_Max;

      ----------------------------------
      -- Max_Alignment_For_Allocation --
      ----------------------------------

      when Attribute_Max_Size_In_Storage_Elements =>
         Max_Alignment_For_Allocation_Max_Size_In_Storage_Elements;

      ----------------------
      -- Max_Integer_Size --
      ----------------------

      when Attribute_Max_Integer_Size =>
         Standard_Attribute (System_Max_Integer_Size);

      ----------------------------------
      -- Max_Size_In_Storage_Elements --
      ----------------------------------

      when Attribute_Max_Alignment_For_Allocation =>
         Max_Alignment_For_Allocation_Max_Size_In_Storage_Elements;

      -----------------------
      -- Maximum_Alignment --
      -----------------------

      when Attribute_Maximum_Alignment =>
         Standard_Attribute (Ttypes.Maximum_Alignment);

      --------------------
      -- Mechanism_Code --
      --------------------

      when Attribute_Mechanism_Code =>
         if not Is_Entity_Name (P)
           or else not Is_Subprogram (Entity (P))
         then
            Error_Attr_P ("prefix of % attribute must be subprogram");
         end if;

         Check_Either_E0_Or_E1;

         if Present (E1) then
            Resolve (E1, Any_Integer);
            Set_Etype (E1, Standard_Integer);

            if not Is_OK_Static_Expression (E1) then
               Flag_Non_Static_Expr
                 ("expression for parameter number must be static!", E1);
               Error_Attr;

            elsif UI_To_Int (Intval (E1)) > Number_Formals (Entity (P))
              or else Intval (E1) < 0
            then
               Error_Attr ("invalid parameter number for % attribute", E1);
            end if;
         end if;

         Set_Etype (N, Universal_Integer);

      ---------
      -- Min --
      ---------

      when Attribute_Min =>
         Min_Max;

      ---------
      -- Mod --
      ---------

      when Attribute_Mod =>

         --  Note: this attribute is only allowed in Ada 2005 mode, but
         --  we do not need to test that here, since Mod is only recognized
         --  as an attribute name in Ada 2005 mode during the parse.

         Check_E1;
         Check_Modular_Integer_Type;
         Resolve (E1, Any_Integer);
         Set_Etype (N, P_Base_Type);

      -----------
      -- Model --
      -----------

      --  Shares processing with Ceiling attribute

      ----------------
      -- Model_Emin --
      ----------------

      --  Shares processing with Emax attribute

      -------------------
      -- Model_Epsilon --
      -------------------

      --  Shares processing with Epsilon attribute

      --------------------
      -- Model_Mantissa --
      --------------------

      --  Shares processing with Emax attribute

      -----------------
      -- Model_Small --
      -----------------

      --  Shares processing with Epsilon attribute

      -------------
      -- Modulus --
      -------------

      when Attribute_Modulus =>
         Check_E0;
         Check_Modular_Integer_Type;
         Set_Etype (N, Universal_Integer);

      --------------------
      -- Null_Parameter --
      --------------------

      when Attribute_Null_Parameter => Null_Parameter : declare
         Parnt  : constant Node_Id := Parent (N);
         GParnt : constant Node_Id := Parent (Parnt);

         procedure Bad_Null_Parameter (Msg : String);
         --  Used if bad Null parameter attribute node is found. Issues
         --  given error message, and also sets the type to Any_Type to
         --  avoid blowups later on from dealing with a junk node.

         procedure Must_Be_Imported (Proc_Ent : Entity_Id);
         --  Called to check that Proc_Ent is imported subprogram

         ------------------------
         -- Bad_Null_Parameter --
         ------------------------

         procedure Bad_Null_Parameter (Msg : String) is
         begin
            Error_Msg_N (Msg, N);
            Set_Etype (N, Any_Type);
         end Bad_Null_Parameter;

         ----------------------
         -- Must_Be_Imported --
         ----------------------

         procedure Must_Be_Imported (Proc_Ent : Entity_Id) is
            Pent : constant Entity_Id := Ultimate_Alias (Proc_Ent);

         begin
            --  Ignore check if procedure not frozen yet (we will get
            --  another chance when the default parameter is reanalyzed)

            if not Is_Frozen (Pent) then
               return;

            elsif not Is_Imported (Pent) then
               Bad_Null_Parameter
                 ("Null_Parameter can only be used with imported subprogram");

            else
               return;
            end if;
         end Must_Be_Imported;

      --  Start of processing for Null_Parameter

      begin
         Check_Type;
         Check_E0;
         Set_Etype (N, P_Type);

         --  Case of attribute used as default expression

         if Nkind (Parnt) = N_Parameter_Specification then
            Must_Be_Imported (Defining_Entity (GParnt));

         --  Case of attribute used as actual for subprogram (positional)

         elsif Nkind (Parnt) in N_Subprogram_Call
            and then Is_Entity_Name (Name (Parnt))
         then
            Must_Be_Imported (Entity (Name (Parnt)));

         --  Case of attribute used as actual for subprogram (named)

         elsif Nkind (Parnt) = N_Parameter_Association
           and then Nkind (GParnt) in N_Subprogram_Call
           and then Is_Entity_Name (Name (GParnt))
         then
            Must_Be_Imported (Entity (Name (GParnt)));

         --  Not an allowed case

         else
            Bad_Null_Parameter
              ("Null_Parameter must be actual or default parameter");
         end if;
      end Null_Parameter;

      -----------------
      -- Object_Size --
      -----------------

      --  Shares processing with Machine_Size attribute

      ---------
      -- Old --
      ---------

      when Attribute_Old => Old : declare
         procedure Check_References_In_Prefix (Subp_Id : Entity_Id);
         --  Inspect the contents of the prefix and detect illegal uses of a
         --  nested 'Old, attribute 'Result or a use of an entity declared in
         --  the related postcondition expression. Subp_Id is the subprogram to
         --  which the related postcondition applies.

         --------------------------------
         -- Check_References_In_Prefix --
         --------------------------------

         procedure Check_References_In_Prefix (Subp_Id : Entity_Id) is
            function Check_Reference (Nod : Node_Id) return Traverse_Result;
            --  Detect attribute 'Old, attribute 'Result of a use of an entity
            --  and perform the appropriate semantic check.

            ---------------------
            -- Check_Reference --
            ---------------------

            function Check_Reference (Nod : Node_Id) return Traverse_Result is
            begin
               --  Attributes 'Old and 'Result cannot appear in the prefix of
               --  another attribute 'Old.

               if Nkind (Nod) = N_Attribute_Reference
                 and then Attribute_Name (Nod) in Name_Old | Name_Result
               then
                  Error_Msg_Name_1 := Attribute_Name (Nod);
                  Error_Msg_Name_2 := Name_Old;
                  Error_Msg_N
                    ("attribute % cannot appear in the prefix of attribute %",
                     Nod);
                  return Abandon;

               --  Entities mentioned within the prefix of attribute 'Old must
               --  be global to the related postcondition. If this is not the
               --  case, then the scope of the local entity is nested within
               --  that of the subprogram.

               elsif Is_Entity_Name (Nod)
                 and then Present (Entity (Nod))
                 and then Scope_Within (Scope (Entity (Nod)), Subp_Id)
               then
                  Error_Attr
                    ("prefix of attribute % cannot reference local entities",
                     Nod);
                  return Abandon;

               --  Otherwise keep inspecting the prefix

               else
                  return OK;
               end if;
            end Check_Reference;

            procedure Check_References is new Traverse_Proc (Check_Reference);

         --  Start of processing for Check_References_In_Prefix

         begin
            Check_References (P);
         end Check_References_In_Prefix;

         --  Local variables

         Legal    : Boolean;
         Pref_Id  : Entity_Id;
         Pref_Typ : Entity_Id;
         Spec_Id  : Entity_Id;

      --  Start of processing for Old

      begin
         --  The attribute reference is a primary. If any expressions follow,
         --  then the attribute reference is an indexable object. Transform the
         --  attribute into an indexed component and analyze it.

         if Present (E1) then
            Rewrite (N,
              Make_Indexed_Component (Loc,
                Prefix      =>
                  Make_Attribute_Reference (Loc,
                    Prefix         => Relocate_Node (P),
                    Attribute_Name => Name_Old),
                Expressions => Expressions (N)));
            Analyze (N);
            return;
         end if;

         Analyze_Attribute_Old_Result (Legal, Spec_Id);

         --  The aspect or pragma where attribute 'Old resides should be
         --  associated with a subprogram declaration or a body. If this is not
         --  the case, then the aspect or pragma is illegal. Return as analysis
         --  cannot be carried out.

         --  The exception to this rule is when generating C since in this case
         --  postconditions are inlined.

         if No (Spec_Id)
           and then Modify_Tree_For_C
           and then In_Inlined_Body
         then
            Spec_Id := Entity (P);

         elsif not Legal then
            return;
         end if;

         --  The prefix must be preanalyzed as the full analysis will take
         --  place during expansion.

         Preanalyze_And_Resolve (P);

         --  Ensure that the prefix does not contain attributes 'Old or 'Result

         Check_References_In_Prefix (Spec_Id);

         --  Set the type of the attribute now to prevent cascaded errors

         Pref_Typ := Etype (P);
         Set_Etype (N, Pref_Typ);

         --  Legality checks

         if Is_Limited_Type (Pref_Typ) then
            Error_Attr ("attribute % cannot apply to limited objects", P);
         end if;

         --  The prefix is a simple name

         if Is_Entity_Name (P) and then Present (Entity (P)) then
            Pref_Id := Entity (P);

            --  Emit a warning when the prefix is a constant. Note that the use
            --  of Error_Attr would reset the type of N to Any_Type even though
            --  this is a warning. Use Error_Msg_XXX instead.

            if Is_Constant_Object (Pref_Id) then
               Error_Msg_Name_1 := Name_Old;
               Error_Msg_N
                 ("??attribute % applied to constant has no effect", P);
            end if;

         --  Otherwise the prefix is not a simple name

         else
            --  Ensure that the prefix of attribute 'Old is an entity when it
            --  is potentially unevaluated (6.1.1 (27/3)). This rule is
            --  relaxed in Ada 2022 - this relaxation is reflected in the
            --  call (below) to Eligible_For_Conditional_Evaluation.

            if Is_Potentially_Unevaluated (N)
              and then not Statically_Names_Object (P)
              and then not
                Old_Attr_Util.Conditional_Evaluation
                 .Eligible_For_Conditional_Evaluation (N)
            then
               Uneval_Old_Msg;

            --  Detect a possible infinite recursion when the prefix denotes
            --  the related function.

            --    function Func (...) return ...
            --      with Post => Func'Old ...;

            --  The function may be specified in qualified form X.Y where X is
            --  a protected object and Y is a protected function. In that case
            --  ensure that the qualified form has an entity.

            elsif Nkind (P) = N_Function_Call
              and then Nkind (Name (P)) in N_Has_Entity
            then
               Pref_Id := Entity (Name (P));

               if Ekind (Spec_Id) in E_Function | E_Generic_Function
                 and then Pref_Id = Spec_Id
               then
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Error_Msg_N ("!possible infinite recursion<<", P);
                  Error_Msg_N ("\!??Storage_Error ]<<", P);
               end if;
            end if;

            --  The prefix of attribute 'Old may refer to a component of a
            --  formal parameter. In this case its expansion may generate
            --  actual subtypes that are referenced in an inner context and
            --  that must be elaborated within the subprogram itself. If the
            --  prefix includes a function call, it may involve finalization
            --  actions that should be inserted when the attribute has been
            --  rewritten as a declaration. Create a declaration for the prefix
            --  and insert it at the start of the enclosing subprogram. This is
            --  an expansion activity that has to be performed now to prevent
            --  out-of-order issues.

            --  This expansion is both harmful and not needed in SPARK mode,
            --  since the formal verification back end relies on the types of
            --  nodes (hence is not robust w.r.t. a change to base type here),
            --  and does not suffer from the out-of-order issue described
            --  above. Thus, this expansion is skipped in SPARK mode.

            --  The expansion is not relevant for discrete types, which will
            --  not generate extra declarations, and where use of the base type
            --  may lead to spurious errors if context is a case.

            if not GNATprove_Mode then
               if not Is_Discrete_Type (Pref_Typ) then
                  Pref_Typ := Base_Type (Pref_Typ);
               end if;

               Set_Etype (N, Pref_Typ);
               Set_Etype (P, Pref_Typ);

               Analyze_Dimension (N);
               Expand (N);
            end if;
         end if;
      end Old;

      ----------------------
      -- Overlaps_Storage --
      ----------------------

      when Attribute_Overlaps_Storage =>
         Check_E1;

         --  Both arguments must be objects of any type

         Analyze_And_Resolve (P);
         Analyze_And_Resolve (E1);
         Check_Object_Reference (P);
         Check_Object_Reference (E1);
         Set_Etype (N, Standard_Boolean);

      ------------
      -- Output --
      ------------

      when Attribute_Output =>
         Check_E2;
         Check_Stream_Attribute (TSS_Stream_Output);
         Set_Etype (N, Standard_Void_Type);
         Resolve (N, Standard_Void_Type);

      ------------------
      -- Partition_ID --
      ------------------

      when Attribute_Partition_ID =>
         Check_E0;

         if P_Type /= Any_Type then
            if not Is_Library_Level_Entity (Entity (P)) then
               Error_Attr_P
                 ("prefix of % attribute must be library-level entity");

            --  The defining entity of prefix should not be declared inside a
            --  Pure unit. RM E.1(8). Is_Pure was set during declaration.

            elsif Is_Entity_Name (P)
              and then Is_Pure (Entity (P))
            then
               Error_Attr_P ("prefix of% attribute must not be declared pure");
            end if;
         end if;

         Set_Etype (N, Universal_Integer);

      -------------------------
      -- Passed_By_Reference --
      -------------------------

      when Attribute_Passed_By_Reference =>
         Check_E0;
         Check_Type;
         Check_Not_Incomplete_Type;
         Set_Etype (N, Standard_Boolean);

      ------------------
      -- Pool_Address --
      ------------------

      when Attribute_Pool_Address =>
         Check_E0;
         Set_Etype (N, RTE (RE_Address));

      ---------
      -- Pos --
      ---------

      when Attribute_Pos =>
         Check_Discrete_Type;
         Check_E1;
         Resolve (E1, P_Base_Type);
         Set_Etype (N, Universal_Integer);

      --------------
      -- Position --
      --------------

      --  Shares processing with First_Bit attribute

      ----------
      -- Pred --
      ----------

      when Attribute_Pred
         | Attribute_Succ
      =>
         Check_Scalar_Type;
         Check_E1;
         Resolve (E1, P_Base_Type);
         Set_Etype (N, P_Base_Type);

         --  Since Pred/Succ work on the base type, we normally do no check for
         --  the floating-point case, since the base type is unconstrained. But
         --  we make an exception in Check_Float_Overflow mode.

         if Is_Floating_Point_Type (P_Type) then
            if not Range_Checks_Suppressed (P_Base_Type) then
               Set_Do_Range_Check (E1);
            end if;

         --  If not modular type, test for overflow check required

         else
            if not Is_Modular_Integer_Type (P_Type)
              and then not Range_Checks_Suppressed (P_Base_Type)
            then
               Enable_Range_Check (E1);
            end if;
         end if;

      ----------------------------------
      -- Preelaborable_Initialization --
      ----------------------------------

      when Attribute_Preelaborable_Initialization =>
         Check_E0;
         Check_Type;

         --  If we're in an instance, we know that the legality of the
         --  attribute prefix type was already checked in the generic.

         if not In_Instance then

            --  If the prefix type is a generic formal type, then it must be
            --  either a formal private type or a formal derived type.

            if Is_Generic_Type (P_Type) then
               if not Is_Private_Type (P_Type)
                 and then not Is_Derived_Type (P_Type)
               then
                  Error_Attr_P ("formal type prefix of % attribute must be "
                                 & "formal private or formal derived type");
               end if;

            --  Otherwise, the prefix type must be a nonformal composite
            --  type declared within the visible part of a package or
            --  generic package.

            elsif not Is_Composite_Type (P_Type)
              or else not Original_View_In_Visible_Part (P_Type)
            then
               Error_Attr_P
                 ("prefix of % attribute must be composite type declared "
                    & "in visible part of a package or generic package");
            end if;
         end if;

         Set_Etype (N, Standard_Boolean);

      --------------
      -- Priority --
      --------------

      --  Ada 2005 (AI-327): Dynamic ceiling priorities

      when Attribute_Priority =>
         if Ada_Version < Ada_2005 then
            Error_Attr ("% attribute is allowed only in Ada 2005 mode", P);
         end if;

         Check_E0;

         Check_Restriction (No_Dynamic_Priorities, N);

         --  The prefix must be a protected object (AARM D.5.2 (2/2))

         Analyze (P);

         if Is_Protected_Type (Etype (P))
           or else (Is_Access_Type (Etype (P))
                      and then Is_Protected_Type (Designated_Type (Etype (P))))
         then
            Resolve (P);
         else
            Error_Attr_P ("prefix of % attribute must be a protected object");
         end if;

         Set_Etype (N, Standard_Integer);

         --  Must be called from within a protected procedure or entry of the
         --  protected object.

         declare
            S : Entity_Id;

         begin
            S := Current_Scope;
            while S /= Etype (P)
               and then S /= Standard_Standard
            loop
               S := Scope (S);
            end loop;

            if S = Standard_Standard then
               Error_Attr ("the attribute % is only allowed inside protected "
                           & "operations", P);
            end if;
         end;

         Validate_Non_Static_Attribute_Function_Call;

      ---------------
      -- Put_Image --
      ---------------

      when Attribute_Put_Image =>
         Check_E2;
         Check_Put_Image_Attribute;
         Set_Etype (N, Standard_Void_Type);
         Resolve (N, Standard_Void_Type);

      -----------
      -- Range --
      -----------

      when Attribute_Range =>
         Check_Array_Or_Scalar_Type;
         Bad_Attribute_For_Predicate;

         if Ada_Version = Ada_83
           and then Is_Scalar_Type (P_Type)
           and then Comes_From_Source (N)
         then
            Error_Attr
              ("(Ada 83) % attribute not allowed for scalar type", P);
         end if;

      ------------
      -- Result --
      ------------

      when Attribute_Result => Result : declare
         function Denote_Same_Function
           (Pref_Id : Entity_Id;
            Spec_Id : Entity_Id) return Boolean;
         --  Determine whether the entity of the prefix Pref_Id denotes the
         --  same entity as that of the related subprogram Spec_Id.

         --------------------------
         -- Denote_Same_Function --
         --------------------------

         function Denote_Same_Function
           (Pref_Id : Entity_Id;
            Spec_Id : Entity_Id) return Boolean
         is
            Over_Id   : constant Entity_Id := Overridden_Operation (Spec_Id);
            Subp_Spec : constant Node_Id   := Parent (Spec_Id);

         begin
            --  The prefix denotes the related subprogram

            if Pref_Id = Spec_Id then
               return True;

            --  Account for a special case when attribute 'Result appears in
            --  the postcondition of a generic function.

            --    generic
            --    function Gen_Func return ...
            --      with Post => Gen_Func'Result ...;

            --  When the generic function is instantiated, the Chars field of
            --  the instantiated prefix still denotes the name of the generic
            --  function. Note that any preemptive transformation is impossible
            --  without a proper analysis. The structure of the wrapper package
            --  is as follows:

            --    package Anon_Gen_Pack is
            --       <subtypes and renamings>
            --       function Subp_Decl return ...;               --  (!)
            --       pragma Postcondition (Gen_Func'Result ...);  --  (!)
            --       function Gen_Func ... renames Subp_Decl;
            --    end Anon_Gen_Pack;

            elsif Nkind (Subp_Spec) = N_Function_Specification
              and then Present (Generic_Parent (Subp_Spec))
              and then Ekind (Pref_Id) in E_Generic_Function | E_Function
            then
               if Generic_Parent (Subp_Spec) = Pref_Id then
                  return True;

               elsif Present (Alias (Pref_Id))
                 and then Alias (Pref_Id) = Spec_Id
               then
                  return True;
               end if;

            --  Account for a special case where a primitive of a tagged type
            --  inherits a class-wide postcondition from a parent type. In this
            --  case the prefix of attribute 'Result denotes the overriding
            --  primitive.

            elsif Present (Over_Id) and then Pref_Id = Over_Id then
               return True;
            end if;

            --  Otherwise the prefix does not denote the related subprogram

            return False;
         end Denote_Same_Function;

         --  Local variables

         In_Inlined_C_Postcondition : constant Boolean :=
                                        Modify_Tree_For_C
                                          and then In_Inlined_Body;

         Legal   : Boolean;
         Pref_Id : Entity_Id;
         Spec_Id : Entity_Id;

      --  Start of processing for Result

      begin
         --  The attribute reference is a primary. If any expressions follow,
         --  then the attribute reference is an indexable object. Transform the
         --  attribute into an indexed component and analyze it.

         if Present (E1) then
            Rewrite (N,
              Make_Indexed_Component (Loc,
                Prefix      =>
                  Make_Attribute_Reference (Loc,
                    Prefix         => Relocate_Node (P),
                    Attribute_Name => Name_Result),
                Expressions => Expressions (N)));
            Analyze (N);
            return;
         end if;

         Analyze_Attribute_Old_Result (Legal, Spec_Id);

         --  The aspect or pragma where attribute 'Result resides should be
         --  associated with a subprogram declaration or a body. If this is not
         --  the case, then the aspect or pragma is illegal. Return as analysis
         --  cannot be carried out.

         --  The exception to this rule is when generating C since in this case
         --  postconditions are inlined.

         if No (Spec_Id) and then In_Inlined_C_Postcondition then
            Spec_Id := Entity (P);

         elsif not Legal then
            Error_Attr ("prefix of % attribute must be a function", P);
            return;
         end if;

         --  Attribute 'Result is part of a _Postconditions procedure. There is
         --  no need to perform the semantic checks below as they were already
         --  verified when the attribute was analyzed in its original context.
         --  Instead, rewrite the attribute as a reference to formal parameter
         --  _Result of the _Postconditions procedure.

         if Chars (Spec_Id) = Name_uPostconditions
           or else
             (In_Inlined_C_Postcondition
               and then Nkind (Parent (Spec_Id)) = N_Block_Statement)
         then
            Rewrite (N, Make_Identifier (Loc, Name_uResult));

            --  The type of formal parameter _Result is that of the function
            --  encapsulating the _Postconditions procedure. Resolution must
            --  be carried out against the function return type.

            Analyze_And_Resolve (N, Etype (Scope (Spec_Id)));

         --  Otherwise attribute 'Result appears in its original context and
         --  all semantic checks should be carried out.

         else
            --  Verify the legality of the prefix. It must denotes the entity
            --  of the related [generic] function.

            if Is_Entity_Name (P) then
               Pref_Id := Entity (P);

               --  Either both the prefix and the annotated spec must be
               --  generic functions, or they both must be nongeneric
               --  functions, or the prefix must be generic and the spec
               --  must be nongeneric (i.e. it must denote an instance).

               if (Ekind (Pref_Id) in E_Function | E_Generic_Function
                    and then Ekind (Pref_Id) = Ekind (Spec_Id))
                 or else
                   (Ekind (Pref_Id) = E_Generic_Function
                     and then Ekind (Spec_Id) = E_Function)
               then
                  if Denote_Same_Function (Pref_Id, Spec_Id) then

                     --  Correct the prefix of the attribute when the context
                     --  is a generic function.

                     if Pref_Id /= Spec_Id then
                        Rewrite (P, New_Occurrence_Of (Spec_Id, Loc));
                        Analyze (P);
                     end if;

                     Set_Etype (N, Etype (Spec_Id));

                  --  Otherwise the prefix denotes some unrelated function

                  else
                     Error_Msg_Name_2 := Chars (Spec_Id);
                     Error_Attr
                       ("incorrect prefix for attribute %, expected %", P);
                  end if;

               --  Otherwise the prefix denotes some other form of subprogram
               --  entity.

               else
                  Error_Attr
                    ("attribute % can only appear in postcondition of "
                     & "function", P);
               end if;

            --  Otherwise the prefix is illegal

            else
               Error_Msg_Name_2 := Chars (Spec_Id);
               Error_Attr ("incorrect prefix for attribute %, expected %", P);
            end if;
         end if;
      end Result;

      ------------------
      -- Range_Length --
      ------------------

      when Attribute_Range_Length =>
         Check_E0;
         Check_Discrete_Type;
         Set_Etype (N, Universal_Integer);

      ------------
      -- Reduce --
      ------------

      when Attribute_Reduce =>
         Check_E2;

         if not Extensions_Allowed then
            Error_Attr
              ("% attribute only supported under -gnatX", P);
         end if;

         declare
            Stream : constant Node_Id := Prefix (N);
            Typ    : Entity_Id;
         begin
            if Nkind (Stream) /= N_Aggregate then
               --  Prefix is a name, as for other attributes.

               --  If the object is a function we asume that it is not
               --  overloaded. AI12-242 does not suggest a name resolution
               --  rule for that case, but we can suppose that the expected
               --  type of the reduction is the expected type of the component
               --  of the prefix.

               Analyze_And_Resolve (Stream);
               Typ := Etype (Stream);

               --  Verify that prefix can be iterated upon.

               if Is_Array_Type (Typ)
                 or else Present (Find_Aspect (Typ, Aspect_Default_Iterator))
                 or else Present (Find_Aspect (Typ, Aspect_Iterable))
               then
                  null;
               else
                  Error_Msg_NE
                    ("cannot apply Reduce to object of type&", N, Typ);
               end if;

            elsif Present (Expressions (Stream))
              or else No (Component_Associations (Stream))
              or else Nkind (First (Component_Associations (Stream))) /=
                N_Iterated_Component_Association
            then
               Error_Msg_N
                 ("prefix of Reduce must be an iterated component", N);
            end if;

            Analyze (E1);
            Analyze (E2);
            Set_Etype (N, Etype (E2));
         end;

      ----------
      -- Read --
      ----------

      when Attribute_Read =>
         Check_E2;
         Check_Stream_Attribute (TSS_Stream_Read);
         Set_Etype (N, Standard_Void_Type);
         Resolve (N, Standard_Void_Type);
         Note_Possible_Modification (E2, Sure => True);

      ---------
      -- Ref --
      ---------

      when Attribute_Ref =>
         Check_E1;
         Analyze (P);

         if Nkind (P) /= N_Expanded_Name
           or else not Is_RTE (P_Type, RE_Address)
         then
            Error_Attr_P ("prefix of % attribute must be System.Address");
         end if;

         Analyze_And_Resolve (E1, Any_Integer);
         Set_Etype (N, RTE (RE_Address));

      ---------------
      -- Remainder --
      ---------------

      --  Shares processing with Adjacent attribute

      ---------------------
      -- Restriction_Set --
      ---------------------

      when Attribute_Restriction_Set => Restriction_Set : declare
         R    : Restriction_Id;
         U    : Node_Id;
         Unam : Unit_Name_Type;

      begin
         Check_E1;
         Analyze (P);
         Check_System_Prefix;

         --  No_Dependence case

         if Nkind (E1) = N_Parameter_Association then
            pragma Assert (Chars (Selector_Name (E1)) = Name_No_Dependence);
            U := Explicit_Actual_Parameter (E1);

            if not OK_No_Dependence_Unit_Name (U) then
               Set_Boolean_Result (N, False);
               Error_Attr;
            end if;

            --  See if there is an entry already in the table. That's the
            --  case in which we can return True.

            for J in No_Dependences.First .. No_Dependences.Last loop
               if Designate_Same_Unit (U, No_Dependences.Table (J).Unit)
                 and then No_Dependences.Table (J).Warn = False
               then
                  Set_Boolean_Result (N, True);
                  return;
               end if;
            end loop;

            --  If not in the No_Dependence table, result is False

            Set_Boolean_Result (N, False);

            --  In this case, we must ensure that the binder will reject any
            --  other unit in the partition that sets No_Dependence for this
            --  unit. We do that by making an entry in the special table kept
            --  for this purpose (if the entry is not there already).

            Unam := Get_Spec_Name (Get_Unit_Name (U));

            for J in Restriction_Set_Dependences.First ..
                     Restriction_Set_Dependences.Last
            loop
               if Restriction_Set_Dependences.Table (J) = Unam then
                  return;
               end if;
            end loop;

            Restriction_Set_Dependences.Append (Unam);

         --  Normal restriction case

         else
            if Nkind (E1) /= N_Identifier then
               Set_Boolean_Result (N, False);
               Error_Attr ("attribute % requires restriction identifier", E1);

            else
               R := Get_Restriction_Id (Process_Restriction_Synonyms (E1));

               if R = Not_A_Restriction_Id then
                  Set_Boolean_Result (N, False);
                  Error_Msg_Node_1 := E1;
                  Error_Attr ("invalid restriction identifier &", E1);

               elsif R not in Partition_Boolean_Restrictions then
                  Set_Boolean_Result (N, False);
                  Error_Msg_Node_1 := E1;
                  Error_Attr
                    ("& is not a boolean partition-wide restriction", E1);
               end if;

               if Restriction_Active (R) then
                  Set_Boolean_Result (N, True);
               else
                  Check_Restriction (R, N);
                  Set_Boolean_Result (N, False);
               end if;
            end if;
         end if;
      end Restriction_Set;

      -----------
      -- Round --
      -----------

      when Attribute_Round =>
         Check_E1;
         Check_Decimal_Fixed_Point_Type;
         Set_Etype (N, P_Base_Type);

         --  Because the context is universal_real (3.5.10(12)) it is a
         --  legal context for a universal fixed expression. This is the
         --  only attribute whose functional description involves U_R.

         if Etype (E1) = Universal_Fixed then
            declare
               Conv : constant Node_Id := Make_Type_Conversion (Loc,
                  Subtype_Mark => New_Occurrence_Of (Universal_Real, Loc),
                  Expression   => Relocate_Node (E1));

            begin
               Rewrite (E1, Conv);
               Analyze (E1);
            end;
         end if;

         Resolve (E1, Any_Real);

      --------------
      -- Rounding --
      --------------

      --  Shares processing with Ceiling attribute

      ---------------
      -- Safe_Emax --
      ---------------

      --  Shares processing with Emax attribute

      ----------------
      -- Safe_First --
      ----------------

      --  Shares processing with Epsilon attribute

      ----------------
      -- Safe_Large --
      ----------------

      --  Shares processing with Large attribute

      ---------------
      -- Safe_Last --
      ---------------

      --  Shares processing with Epsilon attribute

      ----------------
      -- Safe_Small --
      ----------------

      --  Shares processing with Large attribute

      --------------------------
      -- Scalar_Storage_Order --
      --------------------------

      when Attribute_Scalar_Storage_Order => Scalar_Storage_Order : declare
         Ent : Entity_Id := Empty;

      begin
         Check_E0;
         Check_Type;

         if not (Is_Record_Type (P_Type) or else Is_Array_Type (P_Type)) then

            --  The attribute applies to generic private types (in which case
            --  the legality rule is applied in the instance) as well as to
            --  composite types. For noncomposite types it always returns the
            --  default bit order for the target.
            --  Allowing formal private types was originally introduced in
            --  GNAT_Mode only, to compile instances of Sequential_IO, but
            --  users find it more generally useful in generic units.

            if not (Is_Generic_Type (P_Type) and then Is_Private_Type (P_Type))
              and then not In_Instance
            then
               Error_Attr_P
                 ("prefix of % attribute must be record or array type");

            elsif not Is_Generic_Type (P_Type) then
               if Bytes_Big_Endian then
                  Ent := RTE (RE_High_Order_First);
               else
                  Ent := RTE (RE_Low_Order_First);
               end if;
            end if;

         elsif Bytes_Big_Endian xor Reverse_Storage_Order (P_Type) then
            Ent := RTE (RE_High_Order_First);

         else
            Ent := RTE (RE_Low_Order_First);
         end if;

         if Present (Ent) then
            Rewrite (N, New_Occurrence_Of (Ent, Loc));
         end if;

         Set_Etype (N, RTE (RE_Bit_Order));
         Resolve (N);

         --  Reset incorrect indication of staticness

         Set_Is_Static_Expression (N, False);
      end Scalar_Storage_Order;

      -----------
      -- Scale --
      -----------

      when Attribute_Scale =>
         Check_E0;
         Check_Decimal_Fixed_Point_Type;
         Set_Etype (N, Universal_Integer);

      -------------
      -- Scaling --
      -------------

      --  Shares processing with Compose attribute

      ------------------
      -- Signed_Zeros --
      ------------------

      --  Shares processing with Denorm attribute

      ----------
      -- Size --
      ----------

      when Attribute_Size
         | Attribute_VADS_Size
      =>
         Check_E0;

         --  If prefix is parameterless function call, rewrite and resolve
         --  as such.

         if Is_Entity_Name (P)
           and then Ekind (Entity (P)) = E_Function
         then
            Resolve (P);

         --  Similar processing for a protected function call

         elsif Nkind (P) = N_Selected_Component
           and then Ekind (Entity (Selector_Name (P))) = E_Function
         then
            Resolve (P);
         end if;

         if Is_Object_Reference (P) then
            Check_Object_Reference (P);

         elsif Is_Entity_Name (P)
           and then (Is_Type (Entity (P))
                       or else Ekind (Entity (P)) = E_Enumeration_Literal)
         then
            null;

         elsif Nkind (P) = N_Type_Conversion
           and then not Comes_From_Source (P)
         then
            null;

         --  Some other compilers allow dubious use of X'???'Size

         elsif Relaxed_RM_Semantics
           and then Nkind (P) = N_Attribute_Reference
         then
            null;

         else
            Error_Attr_P ("invalid prefix for % attribute");
         end if;

         Check_Not_Incomplete_Type;
         Check_Not_CPP_Type;
         Set_Etype (N, Universal_Integer);

         --  If we are processing pragmas Compile_Time_Warning and Compile_
         --  Time_Errors after the back end has been called and this occurrence
         --  of 'Size is known at compile time then it is safe to perform this
         --  evaluation. Needed to perform the static evaluation of the full
         --  boolean expression of these pragmas. Note that Known_RM_Size is
         --  sometimes True when Size_Known_At_Compile_Time is False, when the
         --  back end has computed it.

         if In_Compile_Time_Warning_Or_Error
           and then Is_Entity_Name (P)
           and then (Is_Type (Entity (P))
                      or else Ekind (Entity (P)) = E_Enumeration_Literal)
           and then (Known_RM_Size (Entity (P))
                       or else Size_Known_At_Compile_Time (Entity (P)))
         then
            declare
               Siz : Uint;

            begin
               if Known_Static_RM_Size (Entity (P)) then
                  Siz := RM_Size (Entity (P));
               else
                  Siz := Esize (Entity (P));
               end if;

               Rewrite (N, Make_Integer_Literal (Sloc (N), Siz));
               Analyze (N);
            end;
         end if;

      -----------
      -- Small --
      -----------

      --  Shares processing with Large attribute

      ---------------------------------------
      -- Small_Denominator/Small_Numerator --
      ---------------------------------------

      when Attribute_Small_Denominator
         | Attribute_Small_Numerator
      =>
         Check_Fixed_Point_Type_0;
         Set_Etype (N, Universal_Integer);

      ------------------
      -- Storage_Pool --
      ------------------

      when Attribute_Storage_Pool
         | Attribute_Simple_Storage_Pool
      =>
         Check_E0;

         if Is_Access_Type (P_Type) then
            if Ekind (P_Type) = E_Access_Subprogram_Type then
               Error_Attr_P
                 ("cannot use % attribute for access-to-subprogram type");
            end if;

            --  Set appropriate entity

            if Present (Associated_Storage_Pool (Root_Type (P_Type))) then
               Set_Entity (N, Associated_Storage_Pool (Root_Type (P_Type)));
            else
               Set_Entity (N, RTE (RE_Global_Pool_Object));
            end if;

            if Attr_Id = Attribute_Storage_Pool then
               if Present (Get_Rep_Pragma (Etype (Entity (N)),
                                           Name_Simple_Storage_Pool_Type))
               then
                  Error_Msg_Name_1 := Aname;
                     Error_Msg_Warn := SPARK_Mode /= On;
                  Error_Msg_N
                    ("cannot use % attribute for type with simple storage "
                     & "pool<<", N);
                  Error_Msg_N ("\Program_Error [<<", N);

                  Rewrite
                    (N, Make_Raise_Program_Error
                          (Sloc (N), Reason => PE_Explicit_Raise));
               end if;

               Set_Etype (N, Class_Wide_Type (RTE (RE_Root_Storage_Pool)));

            --  In the Simple_Storage_Pool case, verify that the pool entity is
            --  actually of a simple storage pool type, and set the attribute's
            --  type to the pool object's type.

            else
               if not Present (Get_Rep_Pragma (Etype (Entity (N)),
                                               Name_Simple_Storage_Pool_Type))
               then
                  Error_Attr_P
                    ("cannot use % attribute for type without simple " &
                     "storage pool");
               end if;

               Set_Etype (N, Etype (Entity (N)));
            end if;

            --  Validate_Remote_Access_To_Class_Wide_Type for attribute
            --  Storage_Pool since this attribute is not defined for such
            --  types (RM E.2.2(17)).

            Validate_Remote_Access_To_Class_Wide_Type (N);

         else
            Error_Attr_P ("prefix of % attribute must be access type");
         end if;

      ------------------
      -- Storage_Size --
      ------------------

      when Attribute_Storage_Size =>
         Check_E0;

         if Is_Task_Type (P_Type) then
            Set_Etype (N, Universal_Integer);

            --  Use with tasks is an obsolescent feature

            Check_Restriction (No_Obsolescent_Features, P);

         elsif Is_Access_Type (P_Type) then
            Set_Etype (N, Universal_Integer);

            if Ekind (P_Type) = E_Access_Subprogram_Type then
               Error_Attr_P
                 ("cannot use % attribute for access-to-subprogram type");
            end if;

            if Is_Entity_Name (P)
              and then Is_Type (Entity (P))
            then
               Check_Type;

               --  Validate_Remote_Access_To_Class_Wide_Type for attribute
               --  Storage_Size since this attribute is not defined for
               --  such types (RM E.2.2(17)).

               Validate_Remote_Access_To_Class_Wide_Type (N);

            --  The prefix is allowed to be an implicit dereference of an
            --  access value designating a task.

            else
               Check_Task_Prefix;
            end if;

         else
            Error_Attr_P ("prefix of % attribute must be access or task type");
         end if;

      ------------------
      -- Storage_Unit --
      ------------------

      when Attribute_Storage_Unit =>
         Standard_Attribute (Ttypes.System_Storage_Unit);

      -----------------
      -- Stream_Size --
      -----------------

      when Attribute_Stream_Size =>
         Check_E0;
         Check_Type;

         if Is_Entity_Name (P)
           and then Is_Elementary_Type (Entity (P))
         then
            Set_Etype (N, Universal_Integer);
         else
            Error_Attr_P ("invalid prefix for % attribute");
         end if;

      ---------------
      -- Stub_Type --
      ---------------

      when Attribute_Stub_Type =>
         Check_Type;
         Check_E0;

         if Is_Remote_Access_To_Class_Wide_Type (Base_Type (P_Type)) then

            --  For a real RACW [sub]type, use corresponding stub type

            if not Is_Generic_Type (P_Type) then
               Rewrite (N,
                 New_Occurrence_Of
                   (Corresponding_Stub_Type (Base_Type (P_Type)), Loc));

            --  For a generic type (that has been marked as an RACW using the
            --  Remote_Access_Type aspect or pragma), use a generic RACW stub
            --  type. Note that if the actual is not a remote access type, the
            --  instantiation will fail.

            else
               --  Note: we go to the underlying type here because the view
               --  returned by RTE (RE_RACW_Stub_Type) might be incomplete.

               Rewrite (N,
                 New_Occurrence_Of
                   (Underlying_Type (RTE (RE_RACW_Stub_Type)), Loc));
            end if;

         else
            Error_Attr_P
              ("prefix of% attribute must be remote access-to-class-wide");
         end if;

      ----------
      -- Succ --
      ----------

      --  Shares processing with Pred attribute

      --------------------------------
      -- System_Allocator_Alignment --
      --------------------------------

      when Attribute_System_Allocator_Alignment =>
         Standard_Attribute (Ttypes.System_Allocator_Alignment);

      ---------
      -- Tag --
      ---------

      when Attribute_Tag =>
         Check_E0;
         Check_Dereference;

         if not Is_Tagged_Type (P_Type) then
            Error_Attr_P ("prefix of % attribute must be tagged");

         --  Next test does not apply to generated code why not, and what does
         --  the illegal reference mean???

         elsif Is_Object_Reference (P)
           and then not Is_Class_Wide_Type (P_Type)
           and then Comes_From_Source (N)
         then
            Error_Attr_P
              ("% attribute can only be applied to objects " &
               "of class-wide type");
         end if;

         --  The prefix cannot be an incomplete type. However, references to
         --  'Tag can be generated when expanding interface conversions, and
         --  this is legal.

         if Comes_From_Source (N) then
            Check_Not_Incomplete_Type;

            --  'Tag requires visibility on the corresponding package holding
            --  the tag, so record a reference here, to avoid spurious unused
            --  with_clause reported when compiling the main unit.

            if In_Extended_Main_Source_Unit (Current_Scope) then
               Set_Referenced (P_Type, True);
               Set_Referenced (Scope (P_Type), True);
            end if;
         end if;

         --  Set appropriate type

         Set_Etype (N, RTE (RE_Tag));

      -----------------
      -- Target_Name --
      -----------------

      when Attribute_Target_Name => Target_Name : declare
         TN : constant String := Sdefault.Target_Name.all;
         TL : Natural;

      begin
         Check_Standard_Prefix;

         TL := TN'Last;

         if TN (TL) = '/' or else TN (TL) = '\' then
            TL := TL - 1;
         end if;

         Rewrite (N,
           Make_String_Literal (Loc,
             Strval => TN (TN'First .. TL)));
         Analyze_And_Resolve (N, Standard_String);
         Set_Is_Static_Expression (N, True);
      end Target_Name;

      ----------------
      -- Terminated --
      ----------------

      --  Shares processing with Callable attribute

      ----------------
      -- To_Address --
      ----------------

      when Attribute_To_Address => To_Address : declare
         Val : Uint;
      begin
         Check_E1;
         Analyze (P);
         Check_System_Prefix;

         Generate_Reference (RTE (RE_Address), P);
         Analyze_And_Resolve (E1, Any_Integer);
         Set_Etype (N, RTE (RE_Address));
         Set_Is_Static_Expression (N, Is_Static_Expression (E1));

         --  OK static expression case, check range and set appropriate type

         if Is_OK_Static_Expression (E1) then
            Val := Expr_Value (E1);

            if Val < -(Uint_2 ** (System_Address_Size - 1))
                 or else
               Val > Uint_2 ** System_Address_Size - 1
            then
               Error_Attr ("address value out of range for % attribute", E1);
            end if;

            --  In most cases the expression is a numeric literal or some other
            --  address expression, but if it is a declared constant it may be
            --  of a compatible type that must be left on the node.

            if Is_Entity_Name (E1) then
               null;

            --  Set type to universal integer if negative

            elsif Val < 0 then
               Set_Etype (E1, Universal_Integer);

            --  Otherwise set type to Unsigned_64 to accommodate large values

            else
               Set_Etype (E1, Standard_Unsigned_64);
            end if;
         end if;
      end To_Address;

      ------------
      -- To_Any --
      ------------

      when Attribute_To_Any =>
         Check_E1;
         Check_PolyORB_Attribute;
         Set_Etype (N, RTE (RE_Any));

      ----------------
      -- Truncation --
      ----------------

      --  Shares processing with Ceiling attribute

      ----------------
      -- Type_Class --
      ----------------

      when Attribute_Type_Class =>
         Check_E0;
         Check_Type;
         Check_Not_Incomplete_Type;
         Set_Etype (N, RTE (RE_Type_Class));

      --------------
      -- TypeCode --
      --------------

      when Attribute_TypeCode =>
         Check_E0;
         Check_PolyORB_Attribute;
         Set_Etype (N, RTE (RE_TypeCode));

      --------------
      -- Type_Key --
      --------------

      when Attribute_Type_Key => Type_Key : declare
         Full_Name  : constant String_Id :=
                        Fully_Qualified_Name_String (Entity (P));

         CRC : CRC32;
         --  The computed signature for the type

         Deref : Boolean;
         --  To simplify the handling of mutually recursive types, follow a
         --  single dereference link in a composite type.

         procedure Compute_Type_Key (T : Entity_Id);
         --  Create a CRC integer from the declaration of the type. For a
         --  composite type, fold in the representation of its components in
         --  recursive fashion. We use directly the source representation of
         --  the types involved.

         ----------------------
         -- Compute_Type_Key --
         ----------------------

         procedure Compute_Type_Key (T : Entity_Id) is
            Buffer : Source_Buffer_Ptr;
            P_Max  : Source_Ptr;
            P_Min  : Source_Ptr;
            Rep    : Node_Id;
            SFI    : Source_File_Index;

            procedure Process_One_Declaration;
            --  Update CRC with the characters of one type declaration, or a
            --  representation pragma that applies to the type.

            -----------------------------
            -- Process_One_Declaration --
            -----------------------------

            procedure Process_One_Declaration is
            begin
               --  Scan type declaration, skipping blanks

               for Ptr in P_Min .. P_Max loop
                  if Buffer (Ptr) /= ' ' then
                     System.CRC32.Update (CRC, Buffer (Ptr));
                  end if;
               end loop;
            end Process_One_Declaration;

         --  Start of processing for Compute_Type_Key

         begin
            if Is_Itype (T) then
               return;
            end if;

            --  If the type is declared in Standard, there is no source, so
            --  just use its name.

            if Scope (T) = Standard_Standard then
               declare
                  Name : constant String := Get_Name_String (Chars (T));
               begin
                  for J in Name'Range loop
                     System.CRC32.Update (CRC, Name (J));
                  end loop;
               end;

               return;
            end if;

            Sloc_Range (Enclosing_Declaration (T), P_Min, P_Max);
            SFI := Get_Source_File_Index (P_Min);
            pragma Assert (SFI = Get_Source_File_Index (P_Max));
            Buffer := Source_Text (SFI);

            Process_One_Declaration;

            --  Recurse on relevant component types

            if Is_Array_Type (T) then
               Compute_Type_Key (Component_Type (T));

            elsif Is_Access_Type (T) then
               if not Deref then
                  Deref := True;
                  Compute_Type_Key (Designated_Type (T));
               end if;

            elsif Is_Derived_Type (T) then
               Compute_Type_Key (Etype (T));

            elsif Is_Record_Type (T) then
               declare
                  Comp : Entity_Id;
               begin
                  Comp := First_Component (T);
                  while Present (Comp) loop
                     Compute_Type_Key (Etype (Comp));
                     Next_Component (Comp);
                  end loop;
               end;
            end if;

            if Is_First_Subtype (T) then

               --  Fold in representation aspects for the type, which appear in
               --  the same source buffer. If the representation aspects are in
               --  a different source file, then skip them; they apply to some
               --  other type, perhaps one we're derived from.

               Rep := First_Rep_Item (T);

               while Present (Rep) loop
                  if Comes_From_Source (Rep) then
                     Sloc_Range (Rep, P_Min, P_Max);

                     if SFI = Get_Source_File_Index (P_Min) then
                        pragma Assert (SFI = Get_Source_File_Index (P_Max));
                        Process_One_Declaration;
                     end if;
                  end if;

                  Next_Rep_Item (Rep);
               end loop;
            end if;
         end Compute_Type_Key;

      --  Start of processing for Type_Key

      begin
         Check_E0;
         Check_Type;

         Start_String;
         Deref := False;

         --  Copy all characters in Full_Name but the trailing NUL

         for J in 1 .. String_Length (Full_Name) - 1 loop
            Store_String_Char (Get_String_Char (Full_Name, Pos (J)));
         end loop;

         --  Compute CRC and convert it to string one character at a time, so
         --  as not to use Image within the compiler.

         Initialize (CRC);
         Compute_Type_Key (Entity (P));

         if not Is_Frozen (Entity (P))
           and then not Is_Generic_Type (Entity (P))
         then
            Error_Msg_N ("premature usage of Type_Key?", N);
         end if;

         while CRC > 0 loop
            Store_String_Char (Character'Val (48 + (CRC rem 10)));
            CRC := CRC / 10;
         end loop;

         Rewrite (N, Make_String_Literal (Loc, End_String));
         Analyze_And_Resolve (N, Standard_String);
      end Type_Key;

      -----------------------
      -- Unbiased_Rounding --
      -----------------------

      --  Shares processing with Ceiling attribute

      ----------------------
      -- Unchecked_Access --
      ----------------------

      when Attribute_Unchecked_Access =>
         if Comes_From_Source (N) then
            Check_Restriction (No_Unchecked_Access, N);
         end if;

         Analyze_Access_Attribute;
         Check_Not_Incomplete_Type;

      -------------------------
      -- Unconstrained_Array --
      -------------------------

      when Attribute_Unconstrained_Array =>
         Check_E0;
         Check_Type;
         Check_Not_Incomplete_Type;
         Set_Etype (N, Standard_Boolean);
         Set_Is_Static_Expression (N, True);

      ------------------------------
      -- Universal_Literal_String --
      ------------------------------

      --  This is a GNAT specific attribute whose prefix must be a named
      --  number where the expression is either a single numeric literal,
      --  or a numeric literal immediately preceded by a minus sign. The
      --  result is equivalent to a string literal containing the text of
      --  the literal as it appeared in the source program with a possible
      --  leading minus sign.

      when Attribute_Universal_Literal_String =>
         Check_E0;

         if not Is_Entity_Name (P)
           or else not Is_Named_Number (Entity (P))
         then
            Error_Attr_P ("prefix for % attribute must be named number");

         else
            declare
               Expr     : Node_Id;
               Negative : Boolean;
               S        : Source_Ptr;
               Src      : Source_Buffer_Ptr;

            begin
               Expr := Original_Node (Expression (Parent (Entity (P))));

               if Nkind (Expr) = N_Op_Minus then
                  Negative := True;
                  Expr := Original_Node (Right_Opnd (Expr));
               else
                  Negative := False;
               end if;

               if Nkind (Expr) not in N_Integer_Literal | N_Real_Literal then
                  Error_Attr
                    ("named number for % attribute must be simple literal", N);
               end if;

               --  Build string literal corresponding to source literal text

               Start_String;

               if Negative then
                  Store_String_Char (Get_Char_Code ('-'));
               end if;

               S := Sloc (Expr);
               Src := Source_Text (Get_Source_File_Index (S));

               while Src (S) /= ';' and then Src (S) /= ' ' loop
                  Store_String_Char (Get_Char_Code (Src (S)));
                  S := S + 1;
               end loop;

               --  Now we rewrite the attribute with the string literal

               Rewrite (N,
                 Make_String_Literal (Loc, End_String));
               Analyze (N);
               Set_Is_Static_Expression (N, True);
            end;
         end if;

      -------------------------
      -- Unrestricted_Access --
      -------------------------

      --  This is a GNAT specific attribute which is like Access except that
      --  all scope checks and checks for aliased views are omitted. It is
      --  documented as being equivalent to the use of the Address attribute
      --  followed by an unchecked conversion to the target access type.

      when Attribute_Unrestricted_Access =>

         --  If from source, deal with relevant restrictions

         if Comes_From_Source (N) then
            Check_Restriction (No_Unchecked_Access, N);

            if Nkind (P) in N_Has_Entity
              and then Present (Entity (P))
              and then Is_Object (Entity (P))
            then
               Check_Restriction (No_Implicit_Aliasing, N);
            end if;
         end if;

         if Is_Entity_Name (P) then
            Set_Address_Taken (Entity (P));
         end if;

         --  It might seem reasonable to call Address_Checks here to apply the
         --  same set of semantic checks that we enforce for 'Address (after
         --  all we document Unrestricted_Access as being equivalent to the
         --  use of Address followed by an Unchecked_Conversion). However, if
         --  we do enable these checks, we get multiple failures in both the
         --  compiler run-time and in our regression test suite, so we leave
         --  out these checks for now. To be investigated further some time???

         --  Address_Checks;

         --  Now complete analysis using common access processing

         Analyze_Access_Attribute;

      ------------
      -- Update --
      ------------

      when Attribute_Update => Update : declare
         Common_Typ : Entity_Id;
         --  The common type of a multiple component update for a record

         Comps : Elist_Id := No_Elist;
         --  A list used in the resolution of a record update. It contains the
         --  entities of all record components processed so far.

         procedure Analyze_Array_Component_Update (Assoc : Node_Id);
         --  Analyze and resolve array_component_association Assoc against the
         --  index of array type P_Type.

         procedure Analyze_Record_Component_Update (Comp : Node_Id);
         --  Analyze and resolve record_component_association Comp against
         --  record type P_Type.

         ------------------------------------
         -- Analyze_Array_Component_Update --
         ------------------------------------

         procedure Analyze_Array_Component_Update (Assoc : Node_Id) is
            Expr      : Node_Id;
            High      : Node_Id;
            Index     : Node_Id;
            Index_Typ : Entity_Id;
            Low       : Node_Id;

         begin
            --  The current association contains a sequence of indexes denoting
            --  an element of a multidimensional array:

            --    (Index_1, ..., Index_N)

            --  Examine each individual index and resolve it against the proper
            --  index type of the array.

            if Nkind (First (Choices (Assoc))) = N_Aggregate then
               Expr := First (Choices (Assoc));
               while Present (Expr) loop

                  --  The use of others is illegal (SPARK RM 4.4.1(12))

                  if Nkind (Expr) = N_Others_Choice then
                     Error_Attr
                       ("OTHERS choice not allowed in attribute %", Expr);

                  --  Otherwise analyze and resolve all indexes

                  else
                     Index     := First (Expressions (Expr));
                     Index_Typ := First_Index (P_Type);
                     while Present (Index) and then Present (Index_Typ) loop
                        Analyze_And_Resolve (Index, Etype (Index_Typ));
                        Next (Index);
                        Next_Index (Index_Typ);
                     end loop;

                     --  Detect a case where the association either lacks an
                     --  index or contains an extra index.

                     if Present (Index) or else Present (Index_Typ) then
                        Error_Msg_N
                          ("dimension mismatch in index list", Assoc);
                     end if;
                  end if;

                  Next (Expr);
               end loop;

            --  The current association denotes either a single component or a
            --  range of components of a one dimensional array:

            --    1, 2 .. 5

            --  Resolve the index or its high and low bounds (if range) against
            --  the proper index type of the array.

            else
               Index     := First (Choices (Assoc));
               Index_Typ := First_Index (P_Type);

               if Present (Next_Index (Index_Typ)) then
                  Error_Msg_N ("too few subscripts in array reference", Assoc);
               end if;

               while Present (Index) loop

                  --  The use of others is illegal (SPARK RM 4.4.1(12))

                  if Nkind (Index) = N_Others_Choice then
                     Error_Attr
                       ("OTHERS choice not allowed in attribute %", Index);

                  --  The index denotes a range of elements

                  elsif Nkind (Index) = N_Range then
                     Low  := Low_Bound  (Index);
                     High := High_Bound (Index);

                     Analyze_And_Resolve (Low,  Etype (Index_Typ));
                     Analyze_And_Resolve (High, Etype (Index_Typ));

                  --  Otherwise the index denotes a single element

                  else
                     Analyze_And_Resolve (Index, Etype (Index_Typ));
                  end if;

                  Next (Index);
               end loop;
            end if;
         end Analyze_Array_Component_Update;

         -------------------------------------
         -- Analyze_Record_Component_Update --
         -------------------------------------

         procedure Analyze_Record_Component_Update (Comp : Node_Id) is
            Comp_Name     : constant Name_Id := Chars (Comp);
            Base_Typ      : Entity_Id;
            Comp_Or_Discr : Entity_Id;

         begin
            --  Find the discriminant or component whose name corresponds to
            --  Comp. A simple character comparison is sufficient because all
            --  visible names within a record type are unique.

            Comp_Or_Discr := First_Entity (P_Type);
            while Present (Comp_Or_Discr) loop
               if Chars (Comp_Or_Discr) = Comp_Name then

                  --  Decorate the component reference by setting its entity
                  --  and type for resolution purposes.

                  Set_Entity (Comp, Comp_Or_Discr);
                  Set_Etype  (Comp, Etype (Comp_Or_Discr));
                  exit;
               end if;

               Next_Entity (Comp_Or_Discr);
            end loop;

            --  Diagnose an illegal reference

            if Present (Comp_Or_Discr) then
               if Ekind (Comp_Or_Discr) = E_Discriminant then
                  Error_Attr
                    ("attribute % may not modify record discriminants", Comp);

               else pragma Assert (Ekind (Comp_Or_Discr) = E_Component);
                  if Contains (Comps, Comp_Or_Discr) then
                     Error_Msg_N ("component & already updated", Comp);

                  --  Mark this component as processed

                  else
                     Append_New_Elmt (Comp_Or_Discr, Comps);
                  end if;
               end if;

            --  The update aggregate mentions an entity that does not belong to
            --  the record type.

            else
               Error_Msg_N ("& is not a component of aggregate subtype", Comp);
            end if;

            --  Verify the consistency of types when the current component is
            --  part of a multiple component update.

            --    Comp_1 | ... | Comp_N => <value>

            if Present (Etype (Comp)) then
               Base_Typ := Base_Type (Etype (Comp));

               --  Save the type of the first component reference as the
               --  remaning references (if any) must resolve to this type.

               if No (Common_Typ) then
                  Common_Typ := Base_Typ;

               elsif Base_Typ /= Common_Typ then
                  Error_Msg_N
                    ("components in choice list must have same type", Comp);
               end if;
            end if;
         end Analyze_Record_Component_Update;

         --  Local variables

         Assoc : Node_Id;
         Comp  : Node_Id;

      --  Start of processing for Update

      begin
         if Warn_On_Obsolescent_Feature then
            Error_Msg_N ("?j?attribute Update is an obsolescent feature", N);
            Error_Msg_N ("\?j?use a delta aggregate instead", N);
         end if;

         Check_E1;

         if not Is_Object_Reference (P) then
            Error_Attr_P ("prefix of attribute % must denote an object");

         elsif not Is_Array_Type (P_Type)
           and then not Is_Record_Type (P_Type)
         then
            Error_Attr_P ("prefix of attribute % must be a record or array");

         elsif Is_Limited_View (P_Type) then
            Error_Attr ("prefix of attribute % cannot be limited", N);

         elsif Nkind (E1) /= N_Aggregate then
            Error_Attr ("attribute % requires component association list", N);

         elsif Present (Expressions (E1)) then
            Error_Attr ("attribute % requires named component associations",
                        First (Expressions (E1)));

         end if;

         --  Inspect the update aggregate, looking at all the associations and
         --  choices. Perform the following checks:

         --    1) Legality of "others" in all cases
         --    2) Legality of <>
         --    3) Component legality for arrays
         --    4) Component legality for records

         --  The remaining checks are performed on the expanded attribute

         Assoc := First (Component_Associations (E1));
         while Present (Assoc) loop

            --  The use of <> is illegal (SPARK RM 4.4.1(1))

            if Box_Present (Assoc) then
               Error_Attr
                 ("default initialization not allowed in attribute %", Assoc);

            --  Otherwise process the association

            else
               Analyze (Expression (Assoc));

               if Is_Array_Type (P_Type) then
                  Analyze_Array_Component_Update (Assoc);

               elsif Is_Record_Type (P_Type) then

                  --  Reset the common type used in a multiple component update
                  --  as we are processing the contents of a new association.

                  Common_Typ := Empty;

                  Comp := First (Choices (Assoc));
                  while Present (Comp) loop
                     if Nkind (Comp) = N_Identifier then
                        Analyze_Record_Component_Update (Comp);

                     --  The use of others is illegal (SPARK RM 4.4.1(5))

                     elsif Nkind (Comp) = N_Others_Choice then
                        Error_Attr
                          ("OTHERS choice not allowed in attribute %", Comp);

                     --  The name of a record component cannot appear in any
                     --  other form.

                     else
                        Error_Msg_N
                          ("name should be identifier or OTHERS", Comp);
                     end if;

                     Next (Comp);
                  end loop;
               end if;
            end if;

            Next (Assoc);
         end loop;

         --  The type of attribute 'Update is that of the prefix

         Set_Etype (N, P_Type);

         Sem_Warn.Warn_On_Suspicious_Update (N);
      end Update;

      ---------
      -- Val --
      ---------

      when Attribute_Val =>
         Check_E1;
         Check_Discrete_Type;

         --  Note, we need a range check in general, but we wait for the
         --  Resolve call to do this, since we want to let Eval_Attribute
         --  have a chance to find an static illegality first.

         Resolve (E1, Any_Integer);
         Set_Etype (N, P_Base_Type);

      -----------
      -- Valid --
      -----------

      when Attribute_Valid => Valid : declare
         Pred_Func : constant Entity_Id := Predicate_Function (P_Type);

      begin
         Check_E0;

         --  Ignore check for object if we have a 'Valid reference generated
         --  by the expanded code, since in some cases valid checks can occur
         --  on items that are names, but are not objects (e.g. attributes).

         if Comes_From_Source (N) then
            Check_Object_Reference (P);

            if not Is_Scalar_Type (P_Type) then
               Error_Attr_P ("object for % attribute must be of scalar type");
            end if;

            --  If the attribute appears within the subtype's own predicate
            --  function, then issue a warning that this will cause infinite
            --  recursion.

            if Present (Pred_Func) and then Current_Scope = Pred_Func then
               Error_Msg_N ("attribute Valid requires a predicate check??", N);
               Error_Msg_N ("\and will result in infinite recursion??", N);
            end if;
         end if;

         Set_Etype (N, Standard_Boolean);
      end Valid;

      -----------------
      -- Valid_Value --
      -----------------

      when Attribute_Valid_Value =>
         Check_E1;
         Check_Enumeration_Type;
         Check_Enum_Image (Check_Enumeration_Maps => True);
         Set_Etype (N, Standard_Boolean);
         Validate_Non_Static_Attribute_Function_Call;

         if P_Type in Standard_Boolean
                    | Standard_Character
                    | Standard_Wide_Character
                    | Standard_Wide_Wide_Character
         then
            Error_Attr_P
              ("prefix of % attribute must not be a type in Standard");
         end if;

         if Discard_Names (First_Subtype (P_Type)) then
            Error_Attr_P
              ("prefix of % attribute must not have Discard_Names");
         end if;

      -------------------
      -- Valid_Scalars --
      -------------------

      when Attribute_Valid_Scalars => Valid_Scalars : declare
      begin
         Check_E0;

         if Comes_From_Source (N) then
            Check_Object_Reference (P);

            --  Do not emit any diagnostics related to private types to avoid
            --  disclosing the structure of the type.

            if Is_Private_Type (P_Type) then

               --  Attribute 'Valid_Scalars is not supported on private tagged
               --  types due to a code generation issue. Is_Visible_Component
               --  does not allow for a component of a private tagged type to
               --  be successfully retrieved.
               --  ??? This attribute should simply ignore type privacy
               --  (see Validated_View). It should examine components of the
               --  tagged type extensions (if any) and recursively examine
               --  'Valid_Scalars of the parent's type (if any).

               --  Do not use Error_Attr_P because this bypasses any subsequent
               --  processing and leaves the attribute with type Any_Type. This
               --  in turn prevents the proper expansion of the attribute into
               --  True.

               if Is_Tagged_Type (P_Type) then
                  Error_Msg_Name_1 := Aname;
                  Error_Msg_N ("??effects of attribute % are ignored", N);
               end if;

            --  Otherwise the type is not private

            else
               if not Scalar_Part_Present (P_Type) then
                  Error_Msg_Name_1 := Aname;
                  Error_Msg_F
                    ("??attribute % always True, no scalars to check", P);
                  Set_Boolean_Result (N, True);
               end if;

               --  Attribute 'Valid_Scalars is illegal on unchecked union types
               --  because it is not always guaranteed that the components are
               --  retrievable based on whether the discriminants are inferable

               if Has_Unchecked_Union (P_Type) then
                  Error_Attr_P
                    ("attribute % not allowed for Unchecked_Union type");
               end if;
            end if;
         end if;

         Set_Etype (N, Standard_Boolean);
      end Valid_Scalars;

      -----------
      -- Value --
      -----------

      when Attribute_Value
         | Attribute_Wide_Value
         | Attribute_Wide_Wide_Value
      =>
         Check_E1;
         Check_Scalar_Type;
         Check_Enum_Image (Check_Enumeration_Maps => True);

         --  Set Etype before resolving expression because expansion of
         --  expression may require enclosing type. Note that the type
         --  returned by 'Value is the base type of the prefix type.

         Set_Etype (N, P_Base_Type);
         Validate_Non_Static_Attribute_Function_Call;

         --  Check restriction No_Fixed_IO

         if Restriction_Check_Required (No_Fixed_IO)
           and then Is_Fixed_Point_Type (P_Type)
         then
            Check_Restriction (No_Fixed_IO, P);
         end if;

      ----------------
      -- Value_Size --
      ----------------

      --  Shares processing with Machine_Size attribute

      -------------
      -- Version --
      -------------

      when Attribute_Version =>
         Check_E0;
         Check_Program_Unit;
         Set_Etype (N, RTE (RE_Version_String));

      ------------------
      -- Wchar_T_Size --
      ------------------

      when Attribute_Wchar_T_Size =>
         Standard_Attribute (Interfaces_Wchar_T_Size);

      ----------------
      -- Wide_Image --
      ----------------

      when Attribute_Wide_Image =>
         Analyze_Image_Attribute (Standard_Wide_String);

      ---------------------
      -- Wide_Wide_Image --
      ---------------------

      when Attribute_Wide_Wide_Image =>
         Analyze_Image_Attribute (Standard_Wide_Wide_String);

      ----------------
      -- Wide_Value --
      ----------------

      --  Shares processing with Value attribute

      ---------------------
      -- Wide_Wide_Value --
      ---------------------

      --  Shares processing with Value attribute

      ---------------------
      -- Wide_Wide_Width --
      ---------------------

      when Attribute_Wide_Wide_Width
         | Attribute_Wide_Width
         | Attribute_Width
      =>
         Check_E0;
         Check_Scalar_Type;
         Set_Etype (N, Universal_Integer);

      ----------------
      -- Wide_Width --
      ----------------

      --  Shares processing with Wide_Wide_Width attribute

      -----------
      -- Width --
      -----------

      --  Shares processing with Wide_Wide_Width attribute

      ---------------
      -- Word_Size --
      ---------------

      when Attribute_Word_Size =>
         Standard_Attribute (System_Word_Size);

      -----------
      -- Write --
      -----------

      when Attribute_Write =>
         Check_E2;
         Check_Stream_Attribute (TSS_Stream_Write);
         Set_Etype (N, Standard_Void_Type);
         Resolve (N, Standard_Void_Type);

      end case;

      --  In SPARK certain attributes (see below) depend on Tasking_State.
      --  Ensure that the entity is available for gnat2why by loading it.
      --  See SPARK RM 9(18) for the relevant rule.

      if GNATprove_Mode then
         case Attr_Id is
            when Attribute_Callable
               | Attribute_Caller
               | Attribute_Count
               | Attribute_Terminated
            =>
               SPARK_Implicit_Load (RE_Tasking_State);

            when others =>
               null;
         end case;
      end if;

   --  All errors raise Bad_Attribute, so that we get out before any further
   --  damage occurs when an error is detected (for example, if we check for
   --  one attribute expression, and the check succeeds, we want to be able
   --  to proceed securely assuming that an expression is in fact present.

   --  Note: we set the attribute analyzed in this case to prevent any
   --  attempt at reanalysis which could generate spurious error msgs.

   exception
      when Bad_Attribute =>
         Set_Analyzed (N);
         Set_Etype (N, Any_Type);
         return;
   end Analyze_Attribute;

   --------------------
   -- Eval_Attribute --
   --------------------

   procedure Eval_Attribute (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);

      C_Type : constant Entity_Id := Etype (N);
      --  The type imposed by the context

      Aname : Name_Id;
      --  Attribute_Name (N) after verification of validity of N

      Id : Attribute_Id;
      --  Get_Attribute_Id (Aname) after Aname is set

      P : Node_Id;
      --  Prefix (N) after verification of validity of N

      E1 : Node_Id;
      --  First expression, or Empty if none

      E2 : Node_Id;
      --  Second expression, or Empty if none

      P_Entity : Entity_Id;
      --  Entity denoted by prefix

      P_Type : Entity_Id;
      --  The type of the prefix

      P_Base_Type : Entity_Id;
      --  The base type of the prefix type

      P_Root_Type : Entity_Id;
      --  The root type of the prefix type

      Static : Boolean := False;
      --  True if the result is Static. This is set by the general processing
      --  to true if the prefix is static, and all expressions are static. It
      --  can be reset as processing continues for particular attributes. This
      --  flag can still be True if the reference raises a constraint error.
      --  Is_Static_Expression (N) is set to follow this value as it is set
      --  and we could always reference this, but it is convenient to have a
      --  simple short name to use, since it is frequently referenced.

      Lo_Bound, Hi_Bound : Node_Id;
      --  Expressions for low and high bounds of type or array index referenced
      --  by First, Last, or Length attribute for array, set by Set_Bounds.

      CE_Node : Node_Id;
      --  Constraint error node used if we have an attribute reference has
      --  an argument that raises a constraint error. In this case we replace
      --  the attribute with a raise constraint_error node. This is important
      --  processing, since otherwise gigi might see an attribute which it is
      --  unprepared to deal with.

      procedure Check_Concurrent_Discriminant (Bound : Node_Id);
      --  If Bound is a reference to a discriminant of a task or protected type
      --  occurring within the object's body, rewrite attribute reference into
      --  a reference to the corresponding discriminal. Use for the expansion
      --  of checks against bounds of entry family index subtypes.

      procedure Check_Expressions;
      --  In case where the attribute is not foldable, the expressions, if
      --  any, of the attribute, are in a non-static context. This procedure
      --  performs the required additional checks.

      function Compile_Time_Known_Bounds (Typ : Entity_Id) return Boolean;
      --  Determines if the given type has compile time known bounds. Note
      --  that we enter the case statement even in cases where the prefix
      --  type does NOT have known bounds, so it is important to guard any
      --  attempt to evaluate both bounds with a call to this function.

      procedure Compile_Time_Known_Attribute (N : Node_Id; Val : Uint);
      --  This procedure is called when the attribute N has a non-static
      --  but compile time known value given by Val. It includes the
      --  necessary checks for out of range values.

      function Fore_Value return Nat;
      --  Computes the Fore value for the current attribute prefix, which is
      --  known to be a static fixed-point type. Used by Fore and Width.

      function Mantissa return Uint;
      --  Returns the Mantissa value for the prefix type

      procedure Set_Bounds;
      --  Used for First, Last and Length attributes applied to an array or
      --  array subtype. Sets the variables Lo_Bound and Hi_Bound to the low
      --  and high bound expressions for the index referenced by the attribute
      --  designator (i.e. the first index if no expression is present, and the
      --  N'th index if the value N is present as an expression). Also used for
      --  First and Last of scalar types and for First_Valid and Last_Valid.
      --  Static is reset to False if the type or index type is not statically
      --  constrained.

      -----------------------------------
      -- Check_Concurrent_Discriminant --
      -----------------------------------

      procedure Check_Concurrent_Discriminant (Bound : Node_Id) is
         Tsk : Entity_Id;
         --  The concurrent (task or protected) type

      begin
         if Nkind (Bound) = N_Identifier
           and then Ekind (Entity (Bound)) = E_Discriminant
           and then Is_Concurrent_Record_Type (Scope (Entity (Bound)))
         then
            Tsk := Corresponding_Concurrent_Type (Scope (Entity (Bound)));

            if In_Open_Scopes (Tsk) and then Has_Completion (Tsk) then

               --  Find discriminant of original concurrent type, and use
               --  its current discriminal, which is the renaming within
               --  the task/protected body.

               Rewrite (N,
                 New_Occurrence_Of
                   (Find_Body_Discriminal (Entity (Bound)), Loc));
            end if;
         end if;
      end Check_Concurrent_Discriminant;

      -----------------------
      -- Check_Expressions --
      -----------------------

      procedure Check_Expressions is
         E : Node_Id;
      begin
         E := E1;
         while Present (E) loop
            Check_Non_Static_Context (E);
            Next (E);
         end loop;
      end Check_Expressions;

      ----------------------------------
      -- Compile_Time_Known_Attribute --
      ----------------------------------

      procedure Compile_Time_Known_Attribute (N : Node_Id; Val : Uint) is
         T : constant Entity_Id := Etype (N);

      begin
         Fold_Uint (N, Val, False);

         --  Check that result is in bounds of the type if it is static

         if Is_In_Range (N, T, Assume_Valid => False) then
            null;

         elsif Is_Out_Of_Range (N, T) then
            Apply_Compile_Time_Constraint_Error
              (N, "value not in range of}??", CE_Range_Check_Failed);

         elsif not Range_Checks_Suppressed (T) then
            Enable_Range_Check (N);

         else
            Set_Do_Range_Check (N, False);
         end if;
      end Compile_Time_Known_Attribute;

      -------------------------------
      -- Compile_Time_Known_Bounds --
      -------------------------------

      function Compile_Time_Known_Bounds (Typ : Entity_Id) return Boolean is
      begin
         return
           Compile_Time_Known_Value (Type_Low_Bound (Typ))
             and then
           Compile_Time_Known_Value (Type_High_Bound (Typ));
      end Compile_Time_Known_Bounds;

      ----------------
      -- Fore_Value --
      ----------------

      --  Note that the Fore calculation is based on the actual values
      --  of the bounds, and does not take into account possible rounding.

      function Fore_Value return Nat is
         Lo      : constant Uint  := Expr_Value (Type_Low_Bound (P_Type));
         Hi      : constant Uint  := Expr_Value (Type_High_Bound (P_Type));
         Small   : constant Ureal := Small_Value (P_Type);
         Lo_Real : constant Ureal := Lo * Small;
         Hi_Real : constant Ureal := Hi * Small;
         T       : Ureal;
         R       : Nat;

      begin
         --  Bounds are given in terms of small units, so first compute
         --  proper values as reals.

         T := UR_Max (abs Lo_Real, abs Hi_Real);
         R := 2;

         --  Loop to compute proper value if more than one digit required

         while T >= Ureal_10 loop
            R := R + 1;
            T := T / Ureal_10;
         end loop;

         return R;
      end Fore_Value;

      --------------
      -- Mantissa --
      --------------

      --  Table of mantissa values accessed by function  Computed using
      --  the relation:

      --    T'Mantissa = integer next above (D * log(10)/log(2)) + 1)

      --  where D is T'Digits (RM83 3.5.7)

      Mantissa_Value : constant array (Nat range 1 .. 40) of Nat := (
          1 =>   5,
          2 =>   8,
          3 =>  11,
          4 =>  15,
          5 =>  18,
          6 =>  21,
          7 =>  25,
          8 =>  28,
          9 =>  31,
         10 =>  35,
         11 =>  38,
         12 =>  41,
         13 =>  45,
         14 =>  48,
         15 =>  51,
         16 =>  55,
         17 =>  58,
         18 =>  61,
         19 =>  65,
         20 =>  68,
         21 =>  71,
         22 =>  75,
         23 =>  78,
         24 =>  81,
         25 =>  85,
         26 =>  88,
         27 =>  91,
         28 =>  95,
         29 =>  98,
         30 => 101,
         31 => 104,
         32 => 108,
         33 => 111,
         34 => 114,
         35 => 118,
         36 => 121,
         37 => 124,
         38 => 128,
         39 => 131,
         40 => 134);

      function Mantissa return Uint is
      begin
         return
           UI_From_Int (Mantissa_Value (UI_To_Int (Digits_Value (P_Type))));
      end Mantissa;

      ----------------
      -- Set_Bounds --
      ----------------

      procedure Set_Bounds is
         Ndim : Nat;
         Indx : Node_Id;
         Ityp : Entity_Id;

      begin
         --  For a string literal subtype, we have to construct the bounds.
         --  Valid Ada code never applies attributes to string literals, but
         --  it is convenient to allow the expander to generate attribute
         --  references of this type (e.g. First and Last applied to a string
         --  literal).

         --  Note that the whole point of the E_String_Literal_Subtype is to
         --  avoid this construction of bounds, but the cases in which we
         --  have to materialize them are rare enough that we don't worry.

         --  The low bound is simply the low bound of the base type. The
         --  high bound is computed from the length of the string and this
         --  low bound.

         if Ekind (P_Type) = E_String_Literal_Subtype then
            Ityp := Etype (First_Index (Base_Type (P_Type)));
            Lo_Bound := Type_Low_Bound (Ityp);

            Hi_Bound :=
              Make_Integer_Literal (Sloc (P),
                Intval =>
                  Expr_Value (Lo_Bound) + String_Literal_Length (P_Type) - 1);

            Set_Parent (Hi_Bound, P);
            Analyze_And_Resolve (Hi_Bound, Etype (Lo_Bound));
            return;

         --  For non-array case, just get bounds of scalar type

         elsif Is_Scalar_Type (P_Type) then
            Ityp := P_Type;

            --  For a fixed-point type, we must freeze to get the attributes
            --  of the fixed-point type set now so we can reference them.

            if Is_Fixed_Point_Type (P_Type)
              and then not Is_Frozen (Base_Type (P_Type))
              and then Compile_Time_Known_Value (Type_Low_Bound (P_Type))
              and then Compile_Time_Known_Value (Type_High_Bound (P_Type))
            then
               Freeze_Fixed_Point_Type (Base_Type (P_Type));
            end if;

         --  For array case, get type of proper index

         else
            if No (E1) then
               Ndim := 1;
            else
               Ndim := UI_To_Int (Expr_Value (E1));
            end if;

            Indx := First_Index (P_Type);
            for J in 1 .. Ndim - 1 loop
               Next_Index (Indx);
            end loop;

            --  If no index type, get out (some other error occurred, and
            --  we don't have enough information to complete the job).

            if No (Indx) then
               Lo_Bound := Error;
               Hi_Bound := Error;
               return;
            end if;

            Ityp := Etype (Indx);
         end if;

         --  A discrete range in an index constraint is allowed to be a
         --  subtype indication. This is syntactically a pain, but should
         --  not propagate to the entity for the corresponding index subtype.
         --  After checking that the subtype indication is legal, the range
         --  of the subtype indication should be transfered to the entity.
         --  The attributes for the bounds should remain the simple retrievals
         --  that they are now.

         Lo_Bound := Type_Low_Bound (Ityp);
         Hi_Bound := Type_High_Bound (Ityp);

         --  If subtype is non-static, result is definitely non-static

         if not Is_Static_Subtype (Ityp) then
            Static := False;
            Set_Is_Static_Expression (N, False);

         --  Subtype is static, does it raise CE?

         elsif not Is_OK_Static_Subtype (Ityp) then
            Set_Raises_Constraint_Error (N);
         end if;
      end Set_Bounds;

   --  Start of processing for Eval_Attribute

   begin
      --  Return immediately if e.g. N has been rewritten or is malformed due
      --  to previous errors.

      if Nkind (N) /= N_Attribute_Reference then
         return;
      end if;

      Aname := Attribute_Name (N);
      Id    := Get_Attribute_Id (Aname);
      P     := Prefix (N);

      --  The To_Address attribute can be static, but it cannot be evaluated at
      --  compile time, so just return.

      if Id = Attribute_To_Address then
         return;
      end if;

      --  Initialize result as non-static, will be reset if appropriate

      Set_Is_Static_Expression (N, False);

      --  Acquire first two expressions (at the moment, no attributes take more
      --  than two expressions in any case).

      if Present (Expressions (N)) then
         E1 := First (Expressions (N));
         E2 := Next (E1);
      else
         E1 := Empty;
         E2 := Empty;
      end if;

      --  Special processing for Enabled attribute. This attribute has a very
      --  special prefix, and the easiest way to avoid lots of special checks
      --  to protect this special prefix from causing trouble is to deal with
      --  this attribute immediately and be done with it.

      if Id = Attribute_Enabled then

         --  We skip evaluation if the expander is not active. This is not just
         --  an optimization. It is of key importance that we not rewrite the
         --  attribute in a generic template, since we want to pick up the
         --  setting of the check in the instance.

         if not Inside_A_Generic then
            declare
               C : constant Check_Id := Get_Check_Id (Chars (P));
               R : Boolean;

            begin
               if No (E1) then
                  if C in Predefined_Check_Id then
                     R := Scope_Suppress.Suppress (C);
                  else
                     R := Is_Check_Suppressed (Empty, C);
                  end if;

               else
                  R := Is_Check_Suppressed (Entity (E1), C);
               end if;

               Rewrite (N, New_Occurrence_Of (Boolean_Literals (not R), Loc));
            end;
         end if;

         return;
      end if;

      --  Attribute 'Img applied to a static enumeration value is static, and
      --  we will do the folding right here (things get confused if we let this
      --  case go through the normal circuitry).

      if Id = Attribute_Img
        and then Is_Entity_Name (P)
        and then Is_Enumeration_Type (Etype (Entity (P)))
        and then Is_OK_Static_Expression (P)
      then
         declare
            Lit : constant Entity_Id := Expr_Value_E (P);
            Str : String_Id;

         begin
            Start_String;
            Get_Unqualified_Decoded_Name_String (Chars (Lit));
            Set_Casing (All_Upper_Case);
            Store_String_Chars (Name_Buffer (1 .. Name_Len));
            Str := End_String;

            Rewrite (N, Make_String_Literal (Loc, Strval => Str));
            Analyze_And_Resolve (N, Standard_String);
            Set_Is_Static_Expression (N, True);
         end;

         return;
      end if;

      --  Special processing for cases where the prefix is an object or value,
      --  including string literals (attributes of string literals can only
      --  appear in generated code) and current instance prefixes in type or
      --  subtype aspects.

      if Is_Object_Reference (P)
        or else Is_Current_Instance_Reference_In_Type_Aspect (P)
        or else Nkind (P) = N_String_Literal
        or else (Is_Entity_Name (P)
                 and then Ekind (Entity (P)) = E_Enumeration_Literal)
      then
         --  For Alignment, give alignment of object if available, otherwise we
         --  cannot fold Alignment.

         if Id = Attribute_Alignment then
            if Is_Entity_Name (P) and then Known_Alignment (Entity (P)) then
               Compile_Time_Known_Attribute (N, Alignment (Entity (P)));
            else
               Check_Expressions;
            end if;

            return;

         --  For Component_Size, the prefix is an array object, and we apply
         --  the attribute to the type of the object. This is allowed for both
         --  unconstrained and constrained arrays, since the bounds have no
         --  influence on the value of this attribute.

         elsif Id = Attribute_Component_Size then
            P_Entity := Etype (P);

         --  For Enum_Rep, evaluation depends on the nature of the prefix and
         --  the optional argument.

         elsif Id = Attribute_Enum_Rep then
            if Is_Entity_Name (P) then

               declare
                  Enum_Expr : Node_Id;
                  --  The enumeration-type expression of interest

               begin
                  --  P'Enum_Rep case

                  if Ekind (Entity (P)) in E_Constant | E_Enumeration_Literal
                  then
                     Enum_Expr := P;

                  --  Enum_Type'Enum_Rep (E1) case

                  elsif Is_Enumeration_Type (Entity (P)) then
                     Enum_Expr := E1;

                  --  Otherwise the attribute must be expanded into a
                  --  conversion and evaluated at run time.

                  else
                     Check_Expressions;
                     return;
                  end if;

                  --  We can fold if the expression is an enumeration
                  --  literal, or if it denotes a constant whose value
                  --  is known at compile time.

                  if Nkind (Enum_Expr) in N_Has_Entity
                    and then (Ekind (Entity (Enum_Expr)) =
                                E_Enumeration_Literal
                      or else
                       (Ekind (Entity (Enum_Expr)) = E_Constant
                          and then Nkind (Parent (Entity (Enum_Expr))) =
                                     N_Object_Declaration
                          and then Present
                                     (Expression (Parent (Entity (P))))
                          and then Compile_Time_Known_Value
                                     (Expression (Parent (Entity (P))))))
                  then
                     P_Entity := Etype (P);
                  else
                     Check_Expressions;
                     return;
                  end if;
               end;

            --  Otherwise the attribute is illegal, do not attempt to perform
            --  any kind of folding.

            else
               return;
            end if;

         --  For Bit_Position, give Component_Bit_Offset of object if available
         --  otherwise we cannot fold Bit_Position. Note that the attribute can
         --  be applied to a naked record component in generated code, in which
         --  case the prefix is an identifier that references the component or
         --  discriminant entity.

         elsif Id = Attribute_Bit_Position then
            declare
               CE : Entity_Id;

            begin
               if Is_Entity_Name (P) then
                  CE := Entity (P);
               else
                  CE := Entity (Selector_Name (P));
               end if;

               if Known_Static_Component_Bit_Offset (CE) then
                  Compile_Time_Known_Attribute
                    (N, Component_Bit_Offset (CE));
               else
                  Check_Expressions;
               end if;

               return;
            end;

         --  For Position, in Ada 2005 (or later) if we have the non-default
         --  bit order, we return the original value as given in the component
         --  clause (RM 2005 13.5.2(3/2)). Otherwise (Ada 83/95, or later with
         --  default bit order) return the value if it is known statically.

         elsif Id = Attribute_Position then
            declare
               CE : constant Entity_Id := Entity (Selector_Name (P));

            begin
               if Present (Component_Clause (CE))
                 and then Ada_Version >= Ada_2005
                 and then Reverse_Bit_Order (Scope (CE))
               then
                  Compile_Time_Known_Attribute
                    (N, Expr_Value (Position (Component_Clause (CE))));

               elsif Known_Static_Component_Bit_Offset (CE) then
                  Compile_Time_Known_Attribute
                    (N, Component_Bit_Offset (CE) / System_Storage_Unit);

               else
                  Check_Expressions;
               end if;

               return;
            end;

         --  For First_Bit, in Ada 2005 (or later) if we have the non-default
         --  bit order, we return the original value as given in the component
         --  clause (RM 2005 13.5.2(3/2)). Otherwise (Ada 83/95, or later with
         --  default bit order) return the value if it is known statically.

         elsif Id = Attribute_First_Bit then
            declare
               CE : constant Entity_Id := Entity (Selector_Name (P));

            begin
               if Present (Component_Clause (CE))
                 and then Ada_Version >= Ada_2005
                 and then Reverse_Bit_Order (Scope (CE))
               then
                  Compile_Time_Known_Attribute
                    (N, Expr_Value (First_Bit (Component_Clause (CE))));

               elsif Known_Static_Component_Bit_Offset (CE) then
                  Compile_Time_Known_Attribute
                    (N, Component_Bit_Offset (CE) mod System_Storage_Unit);

               else
                  Check_Expressions;
               end if;

               return;
            end;

         --  For Last_Bit, in Ada 2005 (or later) if we have the non-default
         --  bit order, we return the original value as given in the component
         --  clause (RM 2005 13.5.2(3/2)). Otherwise (Ada 83/95, or later with
         --  default bit order) return the value if it is known statically.

         elsif Id = Attribute_Last_Bit then
            declare
               CE : constant Entity_Id := Entity (Selector_Name (P));

            begin
               if Present (Component_Clause (CE))
                 and then Ada_Version >= Ada_2005
                 and then Reverse_Bit_Order (Scope (CE))
               then
                  Compile_Time_Known_Attribute
                    (N, Expr_Value (Last_Bit (Component_Clause (CE))));

               elsif Known_Static_Component_Bit_Offset (CE)
                 and then Known_Static_Esize (CE)
               then
                  Compile_Time_Known_Attribute
                    (N, (Component_Bit_Offset (CE) mod System_Storage_Unit)
                                                             + Esize (CE) - 1);
               else
                  Check_Expressions;
               end if;

               return;
            end;

         --  For First, Last and Length, the prefix is an array object, and we
         --  apply the attribute to its type, but we need a constrained type
         --  for this, so we use the actual subtype if available.

         elsif Id = Attribute_First
           or else Id = Attribute_Last
           or else Id = Attribute_Length
         then
            declare
               AS : constant Entity_Id := Get_Actual_Subtype_If_Available (P);

            begin
               if Present (AS) and then Is_Constrained (AS) then
                  P_Entity := AS;

               --  If we have an unconstrained type we cannot fold

               else
                  Check_Expressions;
                  return;
               end if;
            end;

         elsif Id = Attribute_Size then
            --  For Enum_Lit'Size, use Enum_Type'Object_Size. Taking the 'Size
            --  of a literal is kind of a strange thing to do, so we don't want
            --  to pass this oddity on to the back end. Note that Etype of an
            --  enumeration literal is always a (base) type, never a
            --  constrained subtype, so the Esize is always known.

            if Is_Entity_Name (P)
              and then Ekind (Entity (P)) = E_Enumeration_Literal
            then
               pragma Assert (Known_Static_Esize (Etype (P)));
               Compile_Time_Known_Attribute (N, Esize (Etype (P)));

            --  Otherwise, if Size is available, use that

            elsif Is_Entity_Name (P) and then Known_Static_Esize (Entity (P))
            then
               Compile_Time_Known_Attribute (N, Esize (Entity (P)));

            --  Otherwise, we cannot fold

            else
               Check_Expressions;
            end if;

            return;

         --  For Lock_Free, we apply the attribute to the type of the object.
         --  This is allowed since we have already verified that the type is a
         --  protected type.

         elsif Id = Attribute_Lock_Free then
            P_Entity := Etype (P);

         --  No other attributes for objects are folded

         else
            Check_Expressions;
            return;
         end if;

      --  Cases where P is not an object. Cannot do anything if P is not the
      --  name of an entity.

      elsif not Is_Entity_Name (P) then
         Check_Expressions;
         return;

      --  Otherwise get prefix entity

      else
         P_Entity := Entity (P);
      end if;

      --  If we are asked to evaluate an attribute where the prefix is a
      --  non-frozen generic actual type whose RM_Size has not been set,
      --  then abandon the effort.

      if Is_Type (P_Entity)
        and then (not Is_Frozen (P_Entity)
                   and then Is_Generic_Actual_Type (P_Entity)
                   and then not Known_RM_Size (P_Entity))

        --  However, the attribute Unconstrained_Array must be evaluated,
        --  since it is documented to be a static attribute (and can for
        --  example appear in a Compile_Time_Warning pragma). The frozen
        --  status of the type does not affect its evaluation.

        and then Id /= Attribute_Unconstrained_Array
      then
         return;
      end if;

      --  At this stage P_Entity is the entity to which the attribute
      --  is to be applied. This is usually simply the entity of the
      --  prefix, except in some cases of attributes for objects, where
      --  as described above, we apply the attribute to the object type.

      --  Here is where we make sure that static attributes are properly
      --  marked as such. These are attributes whose prefix is a static
      --  scalar subtype, whose result is scalar, and whose arguments, if
      --  present, are static scalar expressions. Note that such references
      --  are static expressions even if they raise Constraint_Error.

      --  For example, Boolean'Pos (1/0 = 0) is a static expression, even
      --  though evaluating it raises constraint error. This means that a
      --  declaration like:

      --    X : constant := (if True then 1 else Boolean'Pos (1/0 = 0));

      --  is legal, since here this expression appears in a statically
      --  unevaluated position, so it does not actually raise an exception.
      --
      --  T'Descriptor_Size is never static, even if T is static.

      if Is_Scalar_Type (P_Entity)
        and then not Is_Generic_Type (P_Entity)
        and then Is_Static_Subtype (P_Entity)
        and then Is_Scalar_Type (Etype (N))
        and then
          (No (E1)
            or else (Is_Static_Expression (E1)
                      and then Is_Scalar_Type (Etype (E1))))
        and then
          (No (E2)
            or else (Is_Static_Expression (E2)
                      and then Is_Scalar_Type (Etype (E1))))
        and then Id /= Attribute_Descriptor_Size
      then
         Static := True;
         Set_Is_Static_Expression (N, True);
      end if;

      --  First foldable possibility is a scalar or array type (RM 4.9(7))
      --  that is not generic (generic types are eliminated by RM 4.9(25)).
      --  Note we allow nonstatic nongeneric types at this stage as further
      --  described below.

      if Is_Type (P_Entity)
        and then (Is_Scalar_Type (P_Entity) or Is_Array_Type (P_Entity))
        and then not Is_Generic_Type (P_Entity)
      then
         P_Type := P_Entity;

      --  Second foldable possibility is an array object (RM 4.9(8))

      elsif Ekind (P_Entity) in E_Variable | E_Constant
        and then Is_Array_Type (Etype (P_Entity))
        and then not Is_Generic_Type (Etype (P_Entity))
      then
         P_Type := Etype (P_Entity);

         --  If the entity is an array constant with an unconstrained nominal
         --  subtype then get the type from the initial value. If the value has
         --  been expanded into assignments, there is no expression and the
         --  attribute reference remains dynamic.

         --  We could do better here and retrieve the type ???

         if Ekind (P_Entity) = E_Constant
           and then not Is_Constrained (P_Type)
         then
            if No (Constant_Value (P_Entity)) then
               return;
            else
               P_Type := Etype (Constant_Value (P_Entity));
            end if;
         end if;

      --  Definite must be folded if the prefix is not a generic type, that
      --  is to say if we are within an instantiation. Same processing applies
      --  to selected GNAT attributes.

      elsif (Id = Attribute_Atomic_Always_Lock_Free      or else
             Id = Attribute_Definite                     or else
             Id = Attribute_Descriptor_Size              or else
             Id = Attribute_Has_Access_Values            or else
             Id = Attribute_Has_Discriminants            or else
             Id = Attribute_Has_Tagged_Values            or else
             Id = Attribute_Lock_Free                    or else
             Id = Attribute_Preelaborable_Initialization or else
             Id = Attribute_Type_Class                   or else
             Id = Attribute_Unconstrained_Array          or else
             Id = Attribute_Max_Alignment_For_Allocation)
        and then not Is_Generic_Type (P_Entity)
      then
         P_Type := P_Entity;

      --  We can fold 'Size applied to a type if the size is known (as happens
      --  for a size from an attribute definition clause). At this stage, this
      --  can happen only for types (e.g. record types) for which the size is
      --  always non-static. We exclude generic types from consideration (since
      --  they have bogus sizes set within templates). We can also fold
      --  Max_Size_In_Storage_Elements in the same cases.

      elsif (Id = Attribute_Size or
             Id = Attribute_Max_Size_In_Storage_Elements)
        and then Is_Type (P_Entity)
        and then not Is_Generic_Type (P_Entity)
        and then Known_Static_RM_Size (P_Entity)
      then
         declare
            Attr_Value : Uint := RM_Size (P_Entity);
         begin
            if Id = Attribute_Max_Size_In_Storage_Elements then
               Attr_Value := (Attr_Value + System_Storage_Unit - 1)
                             / System_Storage_Unit;
            end if;
            Compile_Time_Known_Attribute (N, Attr_Value);
         end;
         return;

      --  We can fold 'Alignment applied to a type if the alignment is known
      --  (as happens for an alignment from an attribute definition clause).
      --  At this stage, this can happen only for types (e.g. record types) for
      --  which the size is always non-static. We exclude generic types from
      --  consideration (since they have bogus sizes set within templates).

      elsif Id = Attribute_Alignment
        and then Is_Type (P_Entity)
        and then not Is_Generic_Type (P_Entity)
        and then Known_Alignment (P_Entity)
      then
         Compile_Time_Known_Attribute (N, Alignment (P_Entity));
         return;

      --  If this is an access attribute that is known to fail accessibility
      --  check, rewrite accordingly.

      elsif Id = Attribute_Address
        and then Raises_Constraint_Error (N)
      then
         Rewrite (N,
           Make_Raise_Program_Error (Loc,
             Reason => PE_Accessibility_Check_Failed));
         Set_Etype (N, C_Type);
         return;

      --  No other cases are foldable (they certainly aren't static, and at
      --  the moment we don't try to fold any cases other than the ones above).

      else
         Check_Expressions;
         return;
      end if;

      --  If either attribute or the prefix is Any_Type, then propagate
      --  Any_Type to the result and don't do anything else at all.

      if P_Type = Any_Type
        or else (Present (E1) and then Etype (E1) = Any_Type)
        or else (Present (E2) and then Etype (E2) = Any_Type)
      then
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  Scalar subtype case. We have not yet enforced the static requirement
      --  of (RM 4.9(7)) and we don't intend to just yet, since there are cases
      --  of non-static attribute references (e.g. S'Digits for a non-static
      --  floating-point type, which we can compute at compile time).

      --  Note: this folding of non-static attributes is not simply a case of
      --  optimization. For many of the attributes affected, Gigi cannot handle
      --  the attribute and depends on the front end having folded them away.

      --  Note: although we don't require staticness at this stage, we do set
      --  the Static variable to record the staticness, for easy reference by
      --  those attributes where it matters (e.g. Succ and Pred), and also to
      --  be used to ensure that non-static folded things are not marked as
      --  being static (a check that is done right at the end).

      P_Root_Type := Root_Type (P_Type);
      P_Base_Type := Base_Type (P_Type);

      --  If the root type or base type is generic, then we cannot fold. This
      --  test is needed because subtypes of generic types are not always
      --  marked as being generic themselves (which seems odd???)

      if Is_Generic_Type (P_Root_Type)
        or else Is_Generic_Type (P_Base_Type)
      then
         return;
      end if;

      if Is_Scalar_Type (P_Type) then
         if not Is_Static_Subtype (P_Type) then
            Static := False;
            Set_Is_Static_Expression (N, False);
         elsif not Is_OK_Static_Subtype (P_Type) then
            Set_Raises_Constraint_Error (N);
         end if;

      --  Array case. We enforce the constrained requirement of (RM 4.9(7-8))
      --  since we can't do anything with unconstrained arrays. In addition,
      --  only the First, Last and Length attributes are possibly static.

      --  Atomic_Always_Lock_Free, Definite, Descriptor_Size, Has_Access_Values
      --  Has_Discriminants, Has_Tagged_Values, Lock_Free, Type_Class, and
      --  Unconstrained_Array are again exceptions, because they apply as well
      --  to unconstrained types.

      --  In addition Component_Size is an exception since it is possibly
      --  foldable, even though it is never static, and it does apply to
      --  unconstrained arrays. Furthermore, it is essential to fold this
      --  in the packed case, since otherwise the value will be incorrect.

      --  Folding can also be done for Preelaborable_Initialization based on
      --  whether the prefix type has preelaborable initialization, even though
      --  the attribute is nonstatic.

      elsif Id = Attribute_Atomic_Always_Lock_Free      or else
            Id = Attribute_Definite                     or else
            Id = Attribute_Descriptor_Size              or else
            Id = Attribute_Has_Access_Values            or else
            Id = Attribute_Has_Discriminants            or else
            Id = Attribute_Has_Tagged_Values            or else
            Id = Attribute_Lock_Free                    or else
            Id = Attribute_Preelaborable_Initialization or else
            Id = Attribute_Type_Class                   or else
            Id = Attribute_Unconstrained_Array          or else
            Id = Attribute_Component_Size
      then
         Static := False;
         Set_Is_Static_Expression (N, False);

      elsif Id /= Attribute_Max_Alignment_For_Allocation then
         if not Is_Constrained (P_Type)
           or else (Id /= Attribute_First and then
                    Id /= Attribute_Last  and then
                    Id /= Attribute_Length)
         then
            Check_Expressions;
            return;
         end if;

         --  The rules in (RM 4.9(7,8)) require a static array, but as in the
         --  scalar case, we hold off on enforcing staticness, since there are
         --  cases which we can fold at compile time even though they are not
         --  static (e.g. 'Length applied to a static index, even though other
         --  non-static indexes make the array type non-static). This is only
         --  an optimization, but it falls out essentially free, so why not.
         --  Again we compute the variable Static for easy reference later
         --  (note that no array attributes are static in Ada 83).

         --  We also need to set Static properly for subsequent legality checks
         --  which might otherwise accept non-static constants in contexts
         --  where they are not legal.

         Static :=
           Ada_Version >= Ada_95 and then Statically_Denotes_Entity (P);
         Set_Is_Static_Expression (N, Static);

         declare
            Nod : Node_Id;

         begin
            Nod := First_Index (P_Type);

            --  The expression is static if the array type is constrained
            --  by given bounds, and not by an initial expression. Constant
            --  strings are static in any case.

            if Root_Type (P_Type) /= Standard_String then
               Static :=
                 Static and then not Is_Constr_Subt_For_U_Nominal (P_Type);
               Set_Is_Static_Expression (N, Static);
            end if;

            while Present (Nod) loop
               if not Is_Static_Subtype (Etype (Nod)) then
                  Static := False;
                  Set_Is_Static_Expression (N, False);

               elsif not Is_OK_Static_Subtype (Etype (Nod)) then
                  Set_Raises_Constraint_Error (N);
                  Static := False;
                  Set_Is_Static_Expression (N, False);
               end if;

               --  If however the index type is generic, or derived from
               --  one, attributes cannot be folded.

               if Is_Generic_Type (Root_Type (Etype (Nod)))
                 and then Id /= Attribute_Component_Size
               then
                  return;
               end if;

               Next_Index (Nod);
            end loop;
         end;
      end if;

      --  Check any expressions that are present. Note that these expressions,
      --  depending on the particular attribute type, are either part of the
      --  attribute designator, or they are arguments in a case where the
      --  attribute reference returns a function. In the latter case, the
      --  rule in (RM 4.9(22)) applies and in particular requires the type
      --  of the expressions to be scalar in order for the attribute to be
      --  considered to be static.

      declare
         E : Node_Id;

      begin
         E := E1;

         while Present (E) loop

            --  If expression is not static, then the attribute reference
            --  result certainly cannot be static.

            if not Is_Static_Expression (E) then
               Static := False;
               Set_Is_Static_Expression (N, False);
            end if;

            if Raises_Constraint_Error (E) then
               Set_Raises_Constraint_Error (N);
            end if;

            --  If the result is not known at compile time, or is not of
            --  a scalar type, then the result is definitely not static,
            --  so we can quit now.

            if not Compile_Time_Known_Value (E)
              or else not Is_Scalar_Type (Etype (E))
            then
               Check_Expressions;
               return;

            --  If the expression raises a constraint error, then so does
            --  the attribute reference. We keep going in this case because
            --  we are still interested in whether the attribute reference
            --  is static even if it is not static.

            elsif Raises_Constraint_Error (E) then
               Set_Raises_Constraint_Error (N);
            end if;

            Next (E);
         end loop;

         if Raises_Constraint_Error (Prefix (N)) then
            Set_Is_Static_Expression (N, False);
            return;
         end if;
      end;

      --  Deal with the case of a static attribute reference that raises
      --  constraint error. The Raises_Constraint_Error flag will already
      --  have been set, and the Static flag shows whether the attribute
      --  reference is static. In any case we certainly can't fold such an
      --  attribute reference.

      --  Note that the rewriting of the attribute node with the constraint
      --  error node is essential in this case, because otherwise Gigi might
      --  blow up on one of the attributes it never expects to see.

      --  The constraint_error node must have the type imposed by the context,
      --  to avoid spurious errors in the enclosing expression.

      if Raises_Constraint_Error (N) then
         CE_Node :=
           Make_Raise_Constraint_Error (Sloc (N),
             Reason => CE_Range_Check_Failed);
         Set_Etype (CE_Node, Etype (N));
         Set_Raises_Constraint_Error (CE_Node);
         Check_Expressions;
         Rewrite (N, Relocate_Node (CE_Node));
         Set_Raises_Constraint_Error (N, True);
         return;
      end if;

      --  At this point we have a potentially foldable attribute reference.
      --  If Static is set, then the attribute reference definitely obeys
      --  the requirements in (RM 4.9(7,8,22)), and it definitely can be
      --  folded. If Static is not set, then the attribute may or may not
      --  be foldable, and the individual attribute processing routines
      --  test Static as required in cases where it makes a difference.

      --  In the case where Static is not set, we do know that all the
      --  expressions present are at least known at compile time (we assumed
      --  above that if this was not the case, then there was no hope of static
      --  evaluation). However, we did not require that the bounds of the
      --  prefix type be compile time known, let alone static). That's because
      --  there are many attributes that can be computed at compile time on
      --  non-static subtypes, even though such references are not static
      --  expressions.

      --  For VAX float, the root type is an IEEE type. So make sure to use the
      --  base type instead of the root-type for floating point attributes.

      case Id is

      --  Attributes related to Ada 2012 iterators; nothing to evaluate for
      --  these.

      when Attribute_Constant_Indexing
         | Attribute_Default_Iterator
         | Attribute_Implicit_Dereference
         | Attribute_Iterator_Element
         | Attribute_Iterable
         | Attribute_Reduce
         | Attribute_Variable_Indexing
      =>
         null;

      --  Internal attributes used to deal with Ada 2012 delayed aspects.
      --  These were already rejected by the parser. Thus they shouldn't
      --  appear here.

      when Internal_Attribute_Id =>
         raise Program_Error;

      --------------
      -- Adjacent --
      --------------

      when Attribute_Adjacent =>
         Fold_Ureal
           (N,
            Eval_Fat.Adjacent
              (P_Base_Type, Expr_Value_R (E1), Expr_Value_R (E2)),
            Static);

      ---------
      -- Aft --
      ---------

      when Attribute_Aft =>
         Fold_Uint (N, Aft_Value (P_Type), Static);

      ---------------
      -- Alignment --
      ---------------

      when Attribute_Alignment => Alignment_Block : declare
         P_TypeA : constant Entity_Id := Underlying_Type (P_Type);

      begin
         --  Fold if alignment is set and not otherwise

         if Known_Alignment (P_TypeA) then
            Fold_Uint (N, Alignment (P_TypeA), Static);
         end if;
      end Alignment_Block;

      -----------------------------
      -- Atomic_Always_Lock_Free --
      -----------------------------

      --  Atomic_Always_Lock_Free attribute is a Boolean, thus no need to fold
      --  here.

      when Attribute_Atomic_Always_Lock_Free => Atomic_Always_Lock_Free :
      declare
         V : constant Entity_Id :=
               Boolean_Literals
                 (Support_Atomic_Primitives_On_Target
                   and then Support_Atomic_Primitives (P_Type));

      begin
         Rewrite (N, New_Occurrence_Of (V, Loc));

         --  Analyze and resolve as boolean. Note that this attribute is a
         --  static attribute in GNAT.

         Analyze_And_Resolve (N, Standard_Boolean);
         Static := True;
         Set_Is_Static_Expression (N);
      end Atomic_Always_Lock_Free;

      ---------
      -- Bit --
      ---------

      --  Bit can never be folded

      when Attribute_Bit =>
         null;

      ------------------
      -- Body_Version --
      ------------------

      --  Body_version can never be static

      when Attribute_Body_Version =>
         null;

      -------------
      -- Ceiling --
      -------------

      when Attribute_Ceiling =>
         Fold_Ureal
           (N, Eval_Fat.Ceiling (P_Base_Type, Expr_Value_R (E1)), Static);

      --------------------
      -- Component_Size --
      --------------------

      --  Fold Component_Size if it is known at compile time, which is always
      --  true in the packed array case. It is important that the packed array
      --  case is handled here since the back end would otherwise get confused
      --  by the equivalent packed array type.

      when Attribute_Component_Size =>
         if Known_Static_Component_Size (P_Type) then
            Fold_Uint (N, Component_Size (P_Type), Static);
         end if;

      -------------
      -- Compose --
      -------------

      when Attribute_Compose =>
         Fold_Ureal
           (N,
            Eval_Fat.Compose (P_Base_Type, Expr_Value_R (E1), Expr_Value (E2)),
            Static);

      -----------------
      -- Constrained --
      -----------------

      --  Constrained is never folded for now, there may be cases that
      --  could be handled at compile time. To be looked at later.

      when Attribute_Constrained =>

         --  The expander might fold it and set the static flag accordingly,
         --  but with expansion disabled, it remains as an attribute reference,
         --  and this reference is not static.

         Set_Is_Static_Expression (N, False);

      ---------------
      -- Copy_Sign --
      ---------------

      when Attribute_Copy_Sign =>
         Fold_Ureal
           (N,
            Eval_Fat.Copy_Sign
              (P_Base_Type, Expr_Value_R (E1), Expr_Value_R (E2)),
            Static);

      --------------
      -- Definite --
      --------------

      when Attribute_Definite =>
         Rewrite (N, New_Occurrence_Of (
           Boolean_Literals (Is_Definite_Subtype (P_Entity)), Loc));
         Analyze_And_Resolve (N, Standard_Boolean);

      -----------
      -- Delta --
      -----------

      when Attribute_Delta =>
         Fold_Ureal (N, Delta_Value (P_Type), True);

      ------------
      -- Denorm --
      ------------

      when Attribute_Denorm =>
         Fold_Uint
           (N, UI_From_Int (Boolean'Pos (Has_Denormals (P_Type))), Static);

      ---------------------
      -- Descriptor_Size --
      ---------------------

      --  Descriptor_Size is nonnull only for unconstrained array types

      when Attribute_Descriptor_Size =>
         if not Is_Array_Type (P_Type) or else Is_Constrained (P_Type) then
            Fold_Uint (N, Uint_0, Static);
         end if;

      ------------
      -- Digits --
      ------------

      when Attribute_Digits =>
         Fold_Uint (N, Digits_Value (P_Type), Static);

      ----------
      -- Emax --
      ----------

      when Attribute_Emax =>

         --  Ada 83 attribute is defined as (RM83 3.5.8)

         --    T'Emax = 4 * T'Mantissa

         Fold_Uint (N, 4 * Mantissa, Static);

      --------------
      -- Enum_Rep --
      --------------

      when Attribute_Enum_Rep => Enum_Rep : declare
         Val : Node_Id;

      begin
         --  The attribute appears in the form:

         --    Enum_Typ'Enum_Rep (Const)
         --    Enum_Typ'Enum_Rep (Enum_Lit)

         if Present (E1) then
            Val := E1;

         --  Otherwise the prefix denotes a constant or enumeration literal:

         --    Const'Enum_Rep
         --    Enum_Lit'Enum_Rep

         else
            Val := P;
         end if;

         --  For an enumeration type with a non-standard representation use
         --  the Enumeration_Rep field of the proper constant. Note that this
         --  will not work for types Character/Wide_[Wide-]Character, since no
         --  real entities are created for the enumeration literals, but that
         --  does not matter since these two types do not have non-standard
         --  representations anyway.

         if Is_Enumeration_Type (P_Type)
           and then Has_Non_Standard_Rep (P_Type)
         then
            Fold_Uint (N, Enumeration_Rep (Expr_Value_E (Val)), Static);

         --  For enumeration types with standard representations and all other
         --  cases (i.e. all integer and modular types), Enum_Rep is equivalent
         --  to Pos.

         else
            Fold_Uint (N, Expr_Value (Val), Static);
         end if;
      end Enum_Rep;

      --------------
      -- Enum_Val --
      --------------

      when Attribute_Enum_Val => Enum_Val : declare
         Lit : Entity_Id;

      begin
         --  We have something like Enum_Type'Enum_Val (23), so search for a
         --  corresponding value in the list of Enum_Rep values for the type.

         Lit := First_Literal (P_Base_Type);
         loop
            if Enumeration_Rep (Lit) = Expr_Value (E1) then
               Fold_Uint (N, Enumeration_Pos (Lit), Static);
               exit;
            end if;

            Next_Literal (Lit);

            if No (Lit) then
               Apply_Compile_Time_Constraint_Error
                 (N, "no representation value matches",
                  CE_Range_Check_Failed,
                  Warn => not Static);
               exit;
            end if;
         end loop;
      end Enum_Val;

      -------------
      -- Epsilon --
      -------------

      when Attribute_Epsilon =>

         --  Ada 83 attribute is defined as (RM83 3.5.8)

         --    T'Epsilon = 2.0**(1 - T'Mantissa)

         Fold_Ureal (N, Ureal_2 ** (1 - Mantissa), True);

      --------------
      -- Exponent --
      --------------

      when Attribute_Exponent =>
         Fold_Uint (N,
           Eval_Fat.Exponent (P_Base_Type, Expr_Value_R (E1)), Static);

      -----------------------
      -- Finalization_Size --
      -----------------------

      when Attribute_Finalization_Size =>
         null;

      -----------
      -- First --
      -----------

      when Attribute_First =>
         Set_Bounds;

         if Compile_Time_Known_Value (Lo_Bound) then
            if Is_Real_Type (P_Type) then
               Fold_Ureal (N, Expr_Value_R (Lo_Bound), Static);
            else
               Fold_Uint  (N, Expr_Value (Lo_Bound), Static);
            end if;

         else
            Check_Concurrent_Discriminant (Lo_Bound);
         end if;

      -----------------
      -- First_Valid --
      -----------------

      when Attribute_First_Valid =>
         if Has_Predicates (P_Type)
           and then Has_Static_Predicate (P_Type)
         then
            declare
               FirstN : constant Node_Id :=
                          First (Static_Discrete_Predicate (P_Type));
            begin
               if Nkind (FirstN) = N_Range then
                  Fold_Uint (N, Expr_Value (Low_Bound (FirstN)), Static);
               else
                  Fold_Uint (N, Expr_Value (FirstN), Static);
               end if;
            end;

         else
            Set_Bounds;
            Fold_Uint (N, Expr_Value (Lo_Bound), Static);
         end if;

      -----------------
      -- Fixed_Value --
      -----------------

      when Attribute_Fixed_Value =>
         null;

      -----------
      -- Floor --
      -----------

      when Attribute_Floor =>
         Fold_Ureal
           (N, Eval_Fat.Floor (P_Base_Type, Expr_Value_R (E1)), Static);

      ----------
      -- Fore --
      ----------

      when Attribute_Fore =>
         if Compile_Time_Known_Bounds (P_Type) then
            Fold_Uint (N, UI_From_Int (Fore_Value), Static);
         end if;

      --------------
      -- Fraction --
      --------------

      when Attribute_Fraction =>
         Fold_Ureal
           (N, Eval_Fat.Fraction (P_Base_Type, Expr_Value_R (E1)), Static);

      -----------------------
      -- Has_Access_Values --
      -----------------------

      when Attribute_Has_Access_Values =>
         Rewrite (N, New_Occurrence_Of
           (Boolean_Literals (Has_Access_Values (P_Root_Type)), Loc));
         Analyze_And_Resolve (N, Standard_Boolean);

      -----------------------
      -- Has_Discriminants --
      -----------------------

      when Attribute_Has_Discriminants =>
         Rewrite (N, New_Occurrence_Of (
           Boolean_Literals (Has_Discriminants (P_Entity)), Loc));
         Analyze_And_Resolve (N, Standard_Boolean);

      ----------------------
      -- Has_Same_Storage --
      ----------------------

      when Attribute_Has_Same_Storage =>
         null;

      -----------------------
      -- Has_Tagged_Values --
      -----------------------

      when Attribute_Has_Tagged_Values =>
         Rewrite (N, New_Occurrence_Of
           (Boolean_Literals (Has_Tagged_Component (P_Root_Type)), Loc));
         Analyze_And_Resolve (N, Standard_Boolean);

      --------------
      -- Identity --
      --------------

      when Attribute_Identity =>
         null;

      -----------
      -- Image --
      -----------

      --  Image is a scalar attribute, but is never static, because it is
      --  not a static function (having a non-scalar argument (RM 4.9(22))
      --  However, we can constant-fold the image of an enumeration literal
      --  if names are available.

      when Attribute_Image =>
         if Is_Entity_Name (E1)
           and then Ekind (Entity (E1)) = E_Enumeration_Literal
           and then not Discard_Names (First_Subtype (Etype (E1)))
           and then not Global_Discard_Names
         then
            declare
               Lit : constant Entity_Id := Entity (E1);
               Str : String_Id;
            begin
               Start_String;
               Get_Unqualified_Decoded_Name_String (Chars (Lit));
               Set_Casing (All_Upper_Case);
               Store_String_Chars (Name_Buffer (1 .. Name_Len));
               Str := End_String;
               Rewrite (N, Make_String_Literal (Loc, Strval => Str));
               Analyze_And_Resolve (N, Standard_String);
               Set_Is_Static_Expression (N, False);
            end;
         end if;

      -------------------
      -- Integer_Value --
      -------------------

      --  We never try to fold Integer_Value (though perhaps we could???)

      when Attribute_Integer_Value =>
         null;

      -------------------
      -- Invalid_Value --
      -------------------

      --  Invalid_Value is a scalar attribute that is never static, because
      --  the value is by design out of range.

      when Attribute_Invalid_Value =>
         null;

      -----------
      -- Large --
      -----------

      when Attribute_Large =>

         --  For fixed-point, we use the identity:

         --    T'Large = (2.0**T'Mantissa - 1.0) * T'Small

         if Is_Fixed_Point_Type (P_Type) then
            Rewrite (N,
              Make_Op_Multiply (Loc,
                Left_Opnd =>
                  Make_Op_Subtract (Loc,
                    Left_Opnd =>
                      Make_Op_Expon (Loc,
                        Left_Opnd =>
                          Make_Real_Literal (Loc, Ureal_2),
                        Right_Opnd =>
                          Make_Attribute_Reference (Loc,
                            Prefix => P,
                            Attribute_Name => Name_Mantissa)),
                    Right_Opnd => Make_Real_Literal (Loc, Ureal_1)),

                Right_Opnd =>
                  Make_Real_Literal (Loc, Small_Value (Entity (P)))));

            Analyze_And_Resolve (N, C_Type);

         --  Floating-point (Ada 83 compatibility)

         else
            --  Ada 83 attribute is defined as (RM83 3.5.8)

            --    T'Large = 2.0**T'Emax * (1.0 - 2.0**(-T'Mantissa))

            --  where

            --    T'Emax = 4 * T'Mantissa

            Fold_Ureal
              (N,
               Ureal_2 ** (4 * Mantissa) * (Ureal_1 - Ureal_2 ** (-Mantissa)),
               True);
         end if;

      ---------------
      -- Lock_Free --
      ---------------

      when Attribute_Lock_Free => Lock_Free : declare
         V : constant Entity_Id := Boolean_Literals (Uses_Lock_Free (P_Type));

      begin
         Rewrite (N, New_Occurrence_Of (V, Loc));

         --  Analyze and resolve as boolean. Note that this attribute is a
         --  static attribute in GNAT.

         Analyze_And_Resolve (N, Standard_Boolean);
         Static := True;
         Set_Is_Static_Expression (N);
      end Lock_Free;

      ----------
      -- Last --
      ----------

      when Attribute_Last =>
         Set_Bounds;

         if Compile_Time_Known_Value (Hi_Bound) then
            if Is_Real_Type (P_Type) then
               Fold_Ureal (N, Expr_Value_R (Hi_Bound), Static);
            else
               Fold_Uint  (N, Expr_Value (Hi_Bound), Static);
            end if;

         else
            Check_Concurrent_Discriminant (Hi_Bound);
         end if;

      ----------------
      -- Last_Valid --
      ----------------

      when Attribute_Last_Valid =>
         if Has_Predicates (P_Type)
           and then Has_Static_Predicate (P_Type)
         then
            declare
               LastN : constant Node_Id :=
                         Last (Static_Discrete_Predicate (P_Type));
            begin
               if Nkind (LastN) = N_Range then
                  Fold_Uint (N, Expr_Value (High_Bound (LastN)), Static);
               else
                  Fold_Uint (N, Expr_Value (LastN), Static);
               end if;
            end;

         else
            Set_Bounds;
            Fold_Uint (N, Expr_Value (Hi_Bound), Static);
         end if;

      ------------------
      -- Leading_Part --
      ------------------

      when Attribute_Leading_Part => Leading_Part : declare
         Radix_Digits : constant Uint := Expr_Value (E2);

      begin
         if UI_Le (Radix_Digits, Uint_0) then
            Apply_Compile_Time_Constraint_Error
              (N, "Radix_Digits in Leading_Part is zero or negative",
               CE_Explicit_Raise,
               Warn => not Static);

            Check_Expressions;
            return;
         end if;

         Fold_Ureal
           (N,
            Eval_Fat.Leading_Part
              (P_Base_Type, Expr_Value_R (E1), Radix_Digits),
            Static);
      end Leading_Part;

      ------------
      -- Length --
      ------------

      when Attribute_Length => Length : declare
         Ind : Node_Id;

      begin
         --  If any index type is a formal type, or derived from one, the
         --  bounds are not static. Treating them as static can produce
         --  spurious warnings or improper constant folding.

         Ind := First_Index (P_Type);
         while Present (Ind) loop
            if Is_Generic_Type (Root_Type (Etype (Ind))) then
               return;
            end if;

            Next_Index (Ind);
         end loop;

         Set_Bounds;

         --  For two compile time values, we can compute length

         if Compile_Time_Known_Value (Lo_Bound)
           and then Compile_Time_Known_Value (Hi_Bound)
         then
            Fold_Uint (N,
              UI_Max (0, 1 + (Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound))),
              Static);
         end if;

         --  One more case is where Hi_Bound and Lo_Bound are compile-time
         --  comparable, and we can figure out the difference between them.

         declare
            Diff : aliased Uint;

         begin
            case
              Compile_Time_Compare
                (Lo_Bound, Hi_Bound, Diff'Access, Assume_Valid => False)
            is
               when EQ =>
                  Fold_Uint (N, Uint_1, Static);

               when GT =>
                  Fold_Uint (N, Uint_0, Static);

               when LT =>
                  if Present (Diff) then
                     Fold_Uint (N, Diff + 1, Static);
                  end if;

               when others =>
                  null;
            end case;
         end;
      end Length;

      ----------------
      -- Loop_Entry --
      ----------------

      --  Loop_Entry acts as an alias of a constant initialized to the prefix
      --  of the said attribute at the point of entry into the related loop. As
      --  such, the attribute reference does not need to be evaluated because
      --  the prefix is the one that is evaluted.

      when Attribute_Loop_Entry =>
         null;

      -------------
      -- Machine --
      -------------

      --  We use the same rounding mode as the one used for RM 4.9(38)

      when Attribute_Machine =>
         Fold_Ureal
           (N,
            Eval_Fat.Machine
              (P_Base_Type, Expr_Value_R (E1), Eval_Fat.Round_Even, N),
            Static);

      ------------------
      -- Machine_Emax --
      ------------------

      when Attribute_Machine_Emax =>
         Fold_Uint (N, Machine_Emax_Value (P_Type), Static);

      ------------------
      -- Machine_Emin --
      ------------------

      when Attribute_Machine_Emin =>
         Fold_Uint (N, Machine_Emin_Value (P_Type), Static);

      ----------------------
      -- Machine_Mantissa --
      ----------------------

      when Attribute_Machine_Mantissa =>
         Fold_Uint (N, Machine_Mantissa_Value (P_Type), Static);

      -----------------------
      -- Machine_Overflows --
      -----------------------

      when Attribute_Machine_Overflows =>

         --  Always true for fixed-point

         if Is_Fixed_Point_Type (P_Type) then
            Fold_Uint (N, True_Value, Static);

         --  Floating point case

         else
            Fold_Uint (N,
              UI_From_Int (Boolean'Pos (Machine_Overflows_On_Target)),
              Static);
         end if;

      -------------------
      -- Machine_Radix --
      -------------------

      when Attribute_Machine_Radix =>
         if Is_Fixed_Point_Type (P_Type) then
            if Is_Decimal_Fixed_Point_Type (P_Type)
              and then Machine_Radix_10 (P_Type)
            then
               Fold_Uint (N, Uint_10, Static);
            else
               Fold_Uint (N, Uint_2, Static);
            end if;

         --  All floating-point type always have radix 2

         else
            Fold_Uint (N, Uint_2, Static);
         end if;

      ----------------------
      -- Machine_Rounding --
      ----------------------

      --  Note: for the folding case, it is fine to treat Machine_Rounding
      --  exactly the same way as Rounding, since this is one of the allowed
      --  behaviors, and performance is not an issue here. It might be a bit
      --  better to give the same result as it would give at run time, even
      --  though the non-determinism is certainly permitted.

      when Attribute_Machine_Rounding =>
         Fold_Ureal
           (N, Eval_Fat.Rounding (P_Base_Type, Expr_Value_R (E1)), Static);

      --------------------
      -- Machine_Rounds --
      --------------------

      when Attribute_Machine_Rounds =>

         --  Always False for fixed-point

         if Is_Fixed_Point_Type (P_Type) then
            Fold_Uint (N, False_Value, Static);

         --  Else yield proper floating-point result

         else
            Fold_Uint
              (N, UI_From_Int (Boolean'Pos (Machine_Rounds_On_Target)),
               Static);
         end if;

      ------------------
      -- Machine_Size --
      ------------------

      --  Note: Machine_Size is identical to Object_Size

      when Attribute_Machine_Size => Machine_Size : declare
         P_TypeA : constant Entity_Id := Underlying_Type (P_Type);

      begin
         if Known_Esize (P_TypeA) then
            Fold_Uint (N, Esize (P_TypeA), Static);
         end if;
      end Machine_Size;

      --------------
      -- Mantissa --
      --------------

      when Attribute_Mantissa =>

         --  Fixed-point mantissa

         if Is_Fixed_Point_Type (P_Type) then

            --  Compile time foldable case

            if Compile_Time_Known_Value (Type_Low_Bound  (P_Type))
                 and then
               Compile_Time_Known_Value (Type_High_Bound (P_Type))
            then
               --  The calculation of the obsolete Ada 83 attribute Mantissa
               --  is annoying, because of AI00143, quoted here:

               --  !question 84-01-10

               --  Consider the model numbers for F:

               --         type F is delta 1.0 range -7.0 .. 8.0;

               --  The wording requires that F'MANTISSA be the SMALLEST
               --  integer number for which each  bound  of the specified
               --  range is either a model number or lies at most small
               --  distant from a model number. This means F'MANTISSA
               --  is required to be 3 since the range  -7.0 .. 7.0 fits
               --  in 3 signed bits, and 8 is "at most" 1.0 from a model
               --  number, namely, 7. Is this analysis correct? Note that
               --  this implies the upper bound of the range is not
               --  represented as a model number.

               --  !response 84-03-17

               --  The analysis is correct. The upper and lower bounds for
               --  a fixed  point type can lie outside the range of model
               --  numbers.

               declare
                  Siz     : Uint;
                  LBound  : Ureal;
                  UBound  : Ureal;
                  Bound   : Ureal;
                  Max_Man : Uint;

               begin
                  LBound  := Expr_Value_R (Type_Low_Bound  (P_Type));
                  UBound  := Expr_Value_R (Type_High_Bound (P_Type));
                  Bound   := UR_Max (UR_Abs (LBound), UR_Abs (UBound));
                  Max_Man := UR_Trunc (Bound / Small_Value (P_Type));

                  --  If the Bound is exactly a model number, i.e. a multiple
                  --  of Small, then we back it off by one to get the integer
                  --  value that must be representable.

                  if Small_Value (P_Type) * Max_Man = Bound then
                     Max_Man := Max_Man - 1;
                  end if;

                  --  Now find corresponding size = Mantissa value

                  Siz := Uint_0;
                  while 2 ** Siz < Max_Man loop
                     Siz := Siz + 1;
                  end loop;

                  Fold_Uint (N, Siz, Static);
               end;

            else
               --  The case of dynamic bounds cannot be evaluated at compile
               --  time. Instead we use a runtime routine (see Exp_Attr).

               null;
            end if;

         --  Floating-point Mantissa

         else
            Fold_Uint (N, Mantissa, Static);
         end if;

      ---------
      -- Max --
      ---------

      when Attribute_Max =>
         if Is_Real_Type (P_Type) then
            Fold_Ureal
              (N, UR_Max (Expr_Value_R (E1), Expr_Value_R (E2)), Static);
         else
            Fold_Uint (N, UI_Max (Expr_Value (E1), Expr_Value (E2)), Static);
         end if;

      ----------------------------------
      -- Max_Alignment_For_Allocation --
      ----------------------------------

      --  Max_Alignment_For_Allocation is usually the Alignment. However,
      --  arrays are allocated with dope, so we need to take into account both
      --  the alignment of the array, which comes from the component alignment,
      --  and the alignment of the dope. Also, if the alignment is unknown, we
      --  use the max (it's OK to be pessimistic).

      when Attribute_Max_Alignment_For_Allocation => Max_Align : declare
         A : Uint := UI_From_Int (Ttypes.Maximum_Alignment);
      begin
         if Known_Alignment (P_Type)
           and then (not Is_Array_Type (P_Type) or else Alignment (P_Type) > A)
         then
            A := Alignment (P_Type);
         end if;

            Fold_Uint (N, A, Static);
      end Max_Align;

      ----------------------------------
      -- Max_Size_In_Storage_Elements --
      ----------------------------------

      --  Max_Size_In_Storage_Elements is simply the Size rounded up to a
      --  Storage_Unit boundary. We can fold any cases for which the size
      --  is known by the front end.

      when Attribute_Max_Size_In_Storage_Elements =>
         if Known_Esize (P_Type) then
            Fold_Uint (N,
              (Esize (P_Type) + System_Storage_Unit - 1) /
                                          System_Storage_Unit,
               Static);
         end if;

      --------------------
      -- Mechanism_Code --
      --------------------

      when Attribute_Mechanism_Code => Mechanism_Code : declare
         Formal : Entity_Id;
         Mech   : Mechanism_Type;
         Val    : Int;

      begin
         if No (E1) then
            Mech := Mechanism (P_Entity);

         else
            Val := UI_To_Int (Expr_Value (E1));

            Formal := First_Formal (P_Entity);
            for J in 1 .. Val - 1 loop
               Next_Formal (Formal);
            end loop;

            Mech := Mechanism (Formal);
         end if;

         if Mech < 0 then
            Fold_Uint (N, UI_From_Int (Int (-Mech)), Static);
         end if;
      end Mechanism_Code;

      ---------
      -- Min --
      ---------

      when Attribute_Min =>
         if Is_Real_Type (P_Type) then
            Fold_Ureal
              (N, UR_Min (Expr_Value_R (E1), Expr_Value_R (E2)), Static);
         else
            Fold_Uint
              (N, UI_Min (Expr_Value (E1), Expr_Value (E2)), Static);
         end if;

      ---------
      -- Mod --
      ---------

      when Attribute_Mod =>
         Fold_Uint
           (N, UI_Mod (Expr_Value (E1), Modulus (P_Base_Type)), Static);

      -----------
      -- Model --
      -----------

      when Attribute_Model =>
         Fold_Ureal
           (N, Eval_Fat.Model (P_Base_Type, Expr_Value_R (E1)), Static);

      ----------------
      -- Model_Emin --
      ----------------

      when Attribute_Model_Emin =>
         Fold_Uint (N, Model_Emin_Value (P_Base_Type), Static);

      -------------------
      -- Model_Epsilon --
      -------------------

      when Attribute_Model_Epsilon =>
         Fold_Ureal (N, Model_Epsilon_Value (P_Base_Type), Static);

      --------------------
      -- Model_Mantissa --
      --------------------

      when Attribute_Model_Mantissa =>
         Fold_Uint (N, Model_Mantissa_Value (P_Base_Type), Static);

      -----------------
      -- Model_Small --
      -----------------

      when Attribute_Model_Small =>
         Fold_Ureal (N, Model_Small_Value (P_Base_Type), Static);

      -------------
      -- Modulus --
      -------------

      when Attribute_Modulus =>
         Fold_Uint (N, Modulus (P_Type), Static);

      --------------------
      -- Null_Parameter --
      --------------------

      --  Cannot fold, we know the value sort of, but the whole point is
      --  that there is no way to talk about this imaginary value except
      --  by using the attribute, so we leave it the way it is.

      when Attribute_Null_Parameter =>
         null;

      -----------------
      -- Object_Size --
      -----------------

      --  The Object_Size attribute for a type returns the Esize of the
      --  type and can be folded if this value is known.

      when Attribute_Object_Size => Object_Size : declare
         P_TypeA : constant Entity_Id := Underlying_Type (P_Type);

      begin
         if Known_Esize (P_TypeA) then
            Fold_Uint (N, Esize (P_TypeA), Static);
         end if;
      end Object_Size;

      ----------------------
      -- Overlaps_Storage --
      ----------------------

      when Attribute_Overlaps_Storage =>
         null;

      -------------------------
      -- Passed_By_Reference --
      -------------------------

      --  Scalar types are never passed by reference

      when Attribute_Passed_By_Reference =>
         Fold_Uint (N, False_Value, Static);

      ---------
      -- Pos --
      ---------

      when Attribute_Pos =>
         Fold_Uint (N, Expr_Value (E1), Static);

      ----------
      -- Pred --
      ----------

      when Attribute_Pred =>

         --  Floating-point case

         if Is_Floating_Point_Type (P_Type) then
            Fold_Ureal
              (N, Eval_Fat.Pred (P_Base_Type, Expr_Value_R (E1)), Static);

         --  Fixed-point case

         elsif Is_Fixed_Point_Type (P_Type) then
            Fold_Ureal
              (N, Expr_Value_R (E1) - Small_Value (P_Type), True);

         --  Modular integer case (wraps)

         elsif Is_Modular_Integer_Type (P_Type) then
            Fold_Uint (N, (Expr_Value (E1) - 1) mod Modulus (P_Type), Static);

         --  Other scalar cases

         else
            pragma Assert (Is_Scalar_Type (P_Type));

            if Is_Enumeration_Type (P_Type)
              and then Expr_Value (E1) =
                         Expr_Value (Type_Low_Bound (P_Base_Type))
            then
               Apply_Compile_Time_Constraint_Error
                 (N, "Pred of `&''First`",
                  CE_Overflow_Check_Failed,
                  Ent  => P_Base_Type,
                  Warn => not Static);

               Check_Expressions;
               return;
            end if;

            Fold_Uint (N, Expr_Value (E1) - 1, Static);
         end if;

      ----------------------------------
      -- Preelaborable_Initialization --
      ----------------------------------

      when Attribute_Preelaborable_Initialization =>
         Fold_Uint
           (N,
            UI_From_Int
              (Boolean'Pos (Has_Preelaborable_Initialization (P_Type))),
            Static);

      -----------
      -- Range --
      -----------

      --  No processing required, because by this stage, Range has been
      --  replaced by First .. Last, so this branch can never be taken.

      when Attribute_Range =>
         raise Program_Error;

      ------------------
      -- Range_Length --
      ------------------

      when Attribute_Range_Length => Range_Length : declare
         Diff : aliased Uint;

      begin
         Set_Bounds;

         --  Can fold if both bounds are compile time known

         if Compile_Time_Known_Value (Hi_Bound)
           and then Compile_Time_Known_Value (Lo_Bound)
         then
            Fold_Uint (N,
              UI_Max
                (0, Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound) + 1),
                 Static);
         end if;

         --  One more case is where Hi_Bound and Lo_Bound are compile-time
         --  comparable, and we can figure out the difference between them.

         case Compile_Time_Compare
                (Lo_Bound, Hi_Bound, Diff'Access, Assume_Valid => False)
         is
            when EQ =>
               Fold_Uint (N, Uint_1, Static);

            when GT =>
               Fold_Uint (N, Uint_0, Static);

            when LT =>
               if Present (Diff) then
                  Fold_Uint (N, Diff + 1, Static);
               end if;

            when others =>
               null;
         end case;
      end Range_Length;

      ---------
      -- Ref --
      ---------

      when Attribute_Ref =>
         Fold_Uint (N, Expr_Value (E1), Static);

      ---------------
      -- Remainder --
      ---------------

      when Attribute_Remainder => Remainder : declare
         X : constant Ureal := Expr_Value_R (E1);
         Y : constant Ureal := Expr_Value_R (E2);

      begin
         if UR_Is_Zero (Y) then
            Apply_Compile_Time_Constraint_Error
              (N, "division by zero in Remainder",
               CE_Overflow_Check_Failed,
               Warn => not Static);

            Check_Expressions;
            return;
         end if;

         Fold_Ureal (N, Eval_Fat.Remainder (P_Base_Type, X, Y), Static);
      end Remainder;

      -----------------
      -- Restriction --
      -----------------

      when Attribute_Restriction_Set =>
         Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
         Set_Is_Static_Expression (N);

      -----------
      -- Round --
      -----------

      when Attribute_Round => Round : declare
         Sr : Ureal;
         Si : Uint;

      begin
         --  First we get the (exact result) in units of small

         Sr := Expr_Value_R (E1) / Small_Value (C_Type);

         --  Now round that exactly to an integer

         Si := UR_To_Uint (Sr);

         --  Finally the result is obtained by converting back to real

         Fold_Ureal (N, Si * Small_Value (C_Type), Static);
      end Round;

      --------------
      -- Rounding --
      --------------

      when Attribute_Rounding =>
         Fold_Ureal
           (N, Eval_Fat.Rounding (P_Base_Type, Expr_Value_R (E1)), Static);

      ---------------
      -- Safe_Emax --
      ---------------

      when Attribute_Safe_Emax =>
         Fold_Uint (N, Safe_Emax_Value (P_Type), Static);

      ----------------
      -- Safe_First --
      ----------------

      when Attribute_Safe_First =>
         Fold_Ureal (N, Safe_First_Value (P_Type), Static);

      ----------------
      -- Safe_Large --
      ----------------

      when Attribute_Safe_Large =>
         if Is_Fixed_Point_Type (P_Type) then
            Fold_Ureal
              (N, Expr_Value_R (Type_High_Bound (P_Base_Type)), Static);
         else
            Fold_Ureal (N, Safe_Last_Value (P_Type), Static);
         end if;

      ---------------
      -- Safe_Last --
      ---------------

      when Attribute_Safe_Last =>
         Fold_Ureal (N, Safe_Last_Value (P_Type), Static);

      ----------------
      -- Safe_Small --
      ----------------

      when Attribute_Safe_Small =>

         --  In Ada 95, the old Ada 83 attribute Safe_Small is redundant
         --  for fixed-point, since is the same as Small, but we implement
         --  it for backwards compatibility.

         if Is_Fixed_Point_Type (P_Type) then
            Fold_Ureal (N, Small_Value (P_Type), Static);

         --  Ada 83 Safe_Small for floating-point cases

         else
            Fold_Ureal (N, Model_Small_Value (P_Type), Static);
         end if;

      -----------
      -- Scale --
      -----------

      when Attribute_Scale =>
         Fold_Uint (N, Scale_Value (P_Type), Static);

      -------------
      -- Scaling --
      -------------

      when Attribute_Scaling =>
         Fold_Ureal
           (N,
            Eval_Fat.Scaling
              (P_Base_Type, Expr_Value_R (E1), Expr_Value (E2)),
            Static);

      ------------------
      -- Signed_Zeros --
      ------------------

      when Attribute_Signed_Zeros =>
         Fold_Uint
           (N, UI_From_Int (Boolean'Pos (Has_Signed_Zeros (P_Type))), Static);

      ----------
      -- Size --
      ----------

      --  Size attribute returns the RM size. All scalar types can be folded,
      --  as well as any types for which the size is known by the front end,
      --  including any type for which a size attribute is specified. This is
      --  one of the places where it is annoying that a size of zero means two
      --  things (zero size for scalars, unspecified size for non-scalars).

      when Attribute_Size
         | Attribute_VADS_Size
      =>
         Size : declare
            P_TypeA : constant Entity_Id := Underlying_Type (P_Type);

         begin
            pragma Assert
              (if Is_Scalar_Type (P_TypeA) then Known_RM_Size (P_TypeA));
            if Known_RM_Size (P_TypeA) then
               --  VADS_Size case

               if Id = Attribute_VADS_Size or else Use_VADS_Size then
                  declare
                     S : constant Node_Id := Size_Clause (P_TypeA);

                  begin
                     --  If a size clause applies, then use the size from it.
                     --  This is one of the rare cases where we can use the
                     --  Size_Clause field for a subtype when Has_Size_Clause
                     --  is False. Consider:

                     --    type x is range 1 .. 64;
                     --    for x'size use 12;
                     --    subtype y is x range 0 .. 3;

                     --  Here y has a size clause inherited from x, but
                     --  normally it does not apply, and y'size is 2. However,
                     --  y'VADS_Size is indeed 12 and not 2.

                     if Present (S)
                       and then Is_OK_Static_Expression (Expression (S))
                     then
                        Fold_Uint (N, Expr_Value (Expression (S)), Static);

                     --  If no size is specified, then we simply use the object
                     --  size in the VADS_Size case (e.g. Natural'Size is equal
                     --  to Integer'Size, not one less).

                     else
                        Fold_Uint (N, Esize (P_TypeA), Static);
                     end if;
                  end;

               --  Normal case (Size) in which case we want the RM_Size

               else
                  Fold_Uint (N, RM_Size (P_TypeA), Static);
               end if;
            end if;
         end Size;

      -----------
      -- Small --
      -----------

      when Attribute_Small =>

         --  The floating-point case is present only for Ada 83 compatibility.
         --  Note that strictly this is an illegal addition, since we are
         --  extending an Ada 95 defined attribute, but we anticipate an
         --  ARG ruling that will permit this.

         if Is_Floating_Point_Type (P_Type) then

            --  Ada 83 attribute is defined as (RM83 3.5.8)

            --    T'Small = 2.0**(-T'Emax - 1)

            --  where

            --    T'Emax = 4 * T'Mantissa

            Fold_Ureal (N, Ureal_2 ** ((-(4 * Mantissa)) - 1), Static);

         --  Normal Ada 95 fixed-point case

         else
            Fold_Ureal (N, Small_Value (P_Type), True);
         end if;

      -----------------------
      -- Small_Denominator --
      -----------------------

      when Attribute_Small_Denominator =>
         Fold_Uint (N, Norm_Den (Small_Value (P_Type)), True);

      ---------------------
      -- Small_Numerator --
      ---------------------

      when Attribute_Small_Numerator =>
         Fold_Uint (N, Norm_Num (Small_Value (P_Type)), True);

      -----------------
      -- Stream_Size --
      -----------------

      when Attribute_Stream_Size =>
         null;

      ----------
      -- Succ --
      ----------

      when Attribute_Succ =>
         --  Floating-point case

         if Is_Floating_Point_Type (P_Type) then
            Fold_Ureal
              (N, Eval_Fat.Succ (P_Base_Type, Expr_Value_R (E1)), Static);

         --  Fixed-point case

         elsif Is_Fixed_Point_Type (P_Type) then
            Fold_Ureal (N, Expr_Value_R (E1) + Small_Value (P_Type), Static);

         --  Modular integer case (wraps)

         elsif Is_Modular_Integer_Type (P_Type) then
            Fold_Uint (N, (Expr_Value (E1) + 1) mod Modulus (P_Type), Static);

         --  Other scalar cases

         else
            pragma Assert (Is_Scalar_Type (P_Type));

            if Is_Enumeration_Type (P_Type)
              and then Expr_Value (E1) =
                         Expr_Value (Type_High_Bound (P_Base_Type))
            then
               Apply_Compile_Time_Constraint_Error
                 (N, "Succ of `&''Last`",
                  CE_Overflow_Check_Failed,
                  Ent  => P_Base_Type,
                  Warn => not Static);

               Check_Expressions;
               return;
            else
               Fold_Uint (N, Expr_Value (E1) + 1, Static);
            end if;
         end if;

      ----------------
      -- Truncation --
      ----------------

      when Attribute_Truncation =>
         Fold_Ureal
           (N,
            Eval_Fat.Truncation (P_Base_Type, Expr_Value_R (E1)),
            Static);

      ----------------
      -- Type_Class --
      ----------------

      when Attribute_Type_Class => Type_Class : declare
         Typ : constant Entity_Id := Underlying_Type (P_Base_Type);
         Id  : RE_Id;

      begin
         if Is_Descendant_Of_Address (Typ) then
            Id := RE_Type_Class_Address;

         elsif Is_Enumeration_Type (Typ) then
            Id := RE_Type_Class_Enumeration;

         elsif Is_Integer_Type (Typ) then
            Id := RE_Type_Class_Integer;

         elsif Is_Fixed_Point_Type (Typ) then
            Id := RE_Type_Class_Fixed_Point;

         elsif Is_Floating_Point_Type (Typ) then
            Id := RE_Type_Class_Floating_Point;

         elsif Is_Array_Type (Typ) then
            Id := RE_Type_Class_Array;

         elsif Is_Record_Type (Typ) then
            Id := RE_Type_Class_Record;

         elsif Is_Access_Type (Typ) then
            Id := RE_Type_Class_Access;

         elsif Is_Task_Type (Typ) then
            Id := RE_Type_Class_Task;

         --  We treat protected types like task types. It would make more
         --  sense to have another enumeration value, but after all the
         --  whole point of this feature is to be exactly DEC compatible,
         --  and changing the type Type_Class would not meet this requirement.

         elsif Is_Protected_Type (Typ) then
            Id := RE_Type_Class_Task;

         --  Not clear if there are any other possibilities, but if there
         --  are, then we will treat them as the address case.

         else
            Id := RE_Type_Class_Address;
         end if;

         Rewrite (N, New_Occurrence_Of (RTE (Id), Loc));
      end Type_Class;

      -----------------------
      -- Unbiased_Rounding --
      -----------------------

      when Attribute_Unbiased_Rounding =>
         Fold_Ureal
           (N,
            Eval_Fat.Unbiased_Rounding (P_Base_Type, Expr_Value_R (E1)),
            Static);

      -------------------------
      -- Unconstrained_Array --
      -------------------------

      when Attribute_Unconstrained_Array => Unconstrained_Array : declare
         Typ : constant Entity_Id := Underlying_Type (P_Type);

      begin
         Rewrite (N, New_Occurrence_Of (
           Boolean_Literals (
             Is_Array_Type (P_Type)
              and then not Is_Constrained (Typ)), Loc));

         --  Analyze and resolve as boolean, note that this attribute is
         --  a static attribute in GNAT.

         Analyze_And_Resolve (N, Standard_Boolean);
         Static := True;
         Set_Is_Static_Expression (N, True);
      end Unconstrained_Array;

      --  Attribute Update is never static

      when Attribute_Update =>
         return;

      ---------------
      -- VADS_Size --
      ---------------

      --  Processing is shared with Size

      ---------
      -- Val --
      ---------

      when Attribute_Val =>
         if  Expr_Value (E1) < Expr_Value (Type_Low_Bound (P_Base_Type))
           or else
             Expr_Value (E1) > Expr_Value (Type_High_Bound (P_Base_Type))
         then
            Apply_Compile_Time_Constraint_Error
              (N, "Val expression out of range",
               CE_Range_Check_Failed,
               Warn => not Static);

            Check_Expressions;
            return;

         else
            Fold_Uint (N, Expr_Value (E1), Static);
         end if;

      ----------------
      -- Value_Size --
      ----------------

      --  The Value_Size attribute for a type returns the RM size of the type.
      --  This an always be folded for scalar types, and can also be folded for
      --  non-scalar types if the size is set. This is one of the places where
      --  it is annoying that a size of zero means two things!

      when Attribute_Value_Size => Value_Size : declare
         P_TypeA : constant Entity_Id := Underlying_Type (P_Type);

      begin
         pragma Assert
           (if Is_Scalar_Type (P_TypeA) then Known_RM_Size (P_TypeA));
         if Known_RM_Size (P_TypeA) then
            Fold_Uint (N, RM_Size (P_TypeA), Static);
         end if;
      end Value_Size;

      -------------
      -- Version --
      -------------

      --  Version can never be static

      when Attribute_Version =>
         null;

      ----------------
      -- Wide_Image --
      ----------------

      --  Wide_Image is a scalar attribute, but is never static, because it
      --  is not a static function (having a non-scalar argument (RM 4.9(22))

      when Attribute_Wide_Image =>
         null;

      ---------------------
      -- Wide_Wide_Image --
      ---------------------

      --  Wide_Wide_Image is a scalar attribute but is never static, because it
      --  is not a static function (having a non-scalar argument (RM 4.9(22)).

      when Attribute_Wide_Wide_Image =>
         null;

      ---------------------
      -- Wide_Wide_Width --
      ---------------------

      --  Processing for Wide_Wide_Width is combined with Width

      ----------------
      -- Wide_Width --
      ----------------

      --  Processing for Wide_Width is combined with Width

      -----------
      -- Width --
      -----------

      --  This processing also handles the case of Wide_[Wide_]Width

      when Attribute_Width
         | Attribute_Wide_Width
         | Attribute_Wide_Wide_Width
      =>
         if Compile_Time_Known_Bounds (P_Type) then

            --  Floating-point types

            if Is_Floating_Point_Type (P_Type) then

               --  Width is zero for a null range (RM 3.5 (38))

               if Expr_Value_R (Type_High_Bound (P_Type)) <
                  Expr_Value_R (Type_Low_Bound (P_Type))
               then
                  Fold_Uint (N, Uint_0, Static);

               else
                  --  For floating-point, we have +N.dddE+nnn where length
                  --  of ddd is determined by type'Digits - 1, but is one
                  --  if Digits is one (RM 3.5 (33)).

                  --  nnn is set to 2 for Short_Float and Float (32 bit
                  --  floats), and 3 for Long_Float and Long_Long_Float.
                  --  For machines where Long_Long_Float is the IEEE
                  --  extended precision type, the exponent takes 4 digits.

                  declare
                     Len : Int :=
                             Int'Max (2, UI_To_Int (Digits_Value (P_Type)));

                  begin
                     if Esize (P_Type) <= 32 then
                        Len := Len + 6;
                     elsif Esize (P_Type) = 64 then
                        Len := Len + 7;
                     else
                        Len := Len + 8;
                     end if;

                     Fold_Uint (N, UI_From_Int (Len), Static);
                  end;
               end if;

            --  Fixed-point types

            elsif Is_Fixed_Point_Type (P_Type) then

               --  Width is zero for a null range (RM 3.5 (38))

               if Expr_Value (Type_High_Bound (P_Type)) <
                  Expr_Value (Type_Low_Bound  (P_Type))
               then
                  Fold_Uint (N, Uint_0, Static);

               --  The non-null case depends on the specific real type

               else
                  --  For fixed-point type width is Fore + 1 + Aft (RM 3.5(34))

                  Fold_Uint
                    (N, UI_From_Int (Fore_Value + 1) + Aft_Value (P_Type),
                     Static);
               end if;

            --  Discrete types

            else
               declare
                  R  : constant Entity_Id := Root_Type (P_Type);
                  Lo : constant Uint := Expr_Value (Type_Low_Bound (P_Type));
                  Hi : constant Uint := Expr_Value (Type_High_Bound (P_Type));
                  W  : Nat;
                  Wt : Nat;
                  T  : Uint;
                  L  : Node_Id;
                  C  : Character;

               begin
                  --  Empty ranges

                  if Lo > Hi then
                     W := 0;

                  --  Width for types derived from Standard.Character
                  --  and Standard.Wide_[Wide_]Character.

                  elsif Is_Standard_Character_Type (P_Type) then
                     W := 0;

                     --  Set W larger if needed

                     for J in UI_To_Int (Lo) .. UI_To_Int (Hi) loop

                        --  All wide characters look like Hex_hhhhhhhh

                        if J > 255 then

                           --  No need to compute this more than once

                           exit;

                        else
                           C := Character'Val (J);

                           --  Test for all cases where Character'Image
                           --  yields an image that is longer than three
                           --  characters. First the cases of Reserved_xxx
                           --  names (length = 12).

                           case C is
                              when Reserved_128
                                 | Reserved_129
                                 | Reserved_132
                                 | Reserved_153
                              =>
                                 Wt := 12;

                              when BS
                                 | CR
                                 | EM
                                 | FF
                                 | FS
                                 | GS
                                 | HT
                                 | LF
                                 | MW
                                 | PM
                                 | RI
                                 | RS
                                 | SI
                                 | SO
                                 | ST
                                 | US
                                 | VT
                              =>
                                 Wt := 2;

                              when ACK
                                 | APC
                                 | BEL
                                 | BPH
                                 | CAN
                                 | CCH
                                 | CSI
                                 | DC1
                                 | DC2
                                 | DC3
                                 | DC4
                                 | DCS
                                 | DEL
                                 | DLE
                                 | ENQ
                                 | EOT
                                 | EPA
                                 | ESA
                                 | ESC
                                 | ETB
                                 | ETX
                                 | HTJ
                                 | HTS
                                 | NAK
                                 | NBH
                                 | NEL
                                 | NUL
                                 | OSC
                                 | PLD
                                 | PLU
                                 | PU1
                                 | PU2
                                 | SCI
                                 | SOH
                                 | SOS
                                 | SPA
                                 | SS2
                                 | SS3
                                 | SSA
                                 | STS
                                 | STX
                                 | SUB
                                 | SYN
                                 | VTS
                              =>
                                 Wt := 3;

                              when Space .. Tilde
                                 | No_Break_Space .. LC_Y_Diaeresis
                              =>
                                 --  Special case of soft hyphen in Ada 2005

                                 if C = Character'Val (16#AD#)
                                   and then Ada_Version >= Ada_2005
                                 then
                                    Wt := 11;
                                 else
                                    Wt := 3;
                                 end if;
                           end case;

                           W := Int'Max (W, Wt);
                        end if;
                     end loop;

                  --  Width for types derived from Standard.Boolean

                  elsif R = Standard_Boolean then
                     if Lo = 0 then
                        W := 5; -- FALSE
                     else
                        W := 4; -- TRUE
                     end if;

                  --  Width for integer types

                  elsif Is_Integer_Type (P_Type) then
                     T := UI_Max (abs Lo, abs Hi);

                     W := 2;
                     while T >= 10 loop
                        W := W + 1;
                        T := T / 10;
                     end loop;

                  --  User declared enum type with discard names

                  elsif Discard_Names (R) then

                     --  If range is null, result is zero, that has already
                     --  been dealt with, so what we need is the power of ten
                     --  that accommodates the Pos of the largest value, which
                     --  is the high bound of the range + one for the space.

                     W := 1;
                     T := Hi;
                     while T /= 0 loop
                        T := T / 10;
                        W := W + 1;
                     end loop;

                  --  Only remaining possibility is user declared enum type
                  --  with normal case of Discard_Names not active.

                  else
                     pragma Assert (Is_Enumeration_Type (P_Type));

                     W := 0;
                     L := First_Literal (P_Type);
                     while Present (L) loop

                        --  Only pay attention to in range characters

                        if Lo <= Enumeration_Pos (L)
                          and then Enumeration_Pos (L) <= Hi
                        then
                           --  For Width case, use decoded name

                           if Id = Attribute_Width then
                              Get_Decoded_Name_String (Chars (L));
                              Wt := Nat (Name_Len);

                           --  For Wide_[Wide_]Width, use encoded name, and
                           --  then adjust for the encoding.

                           else
                              Get_Name_String (Chars (L));

                              --  Character literals are always of length 3

                              if Name_Buffer (1) = 'Q' then
                                 Wt := 3;

                              --  Otherwise loop to adjust for upper/wide chars

                              else
                                 Wt := Nat (Name_Len);

                                 for J in 1 .. Name_Len loop
                                    if Name_Buffer (J) = 'U' then
                                       Wt := Wt - 2;
                                    elsif Name_Buffer (J) = 'W' then
                                       Wt := Wt - 4;
                                    end if;
                                 end loop;
                              end if;
                           end if;

                           W := Int'Max (W, Wt);
                        end if;

                        Next_Literal (L);
                     end loop;
                  end if;

                  Fold_Uint (N, UI_From_Int (W), Static);
               end;
            end if;
         end if;

      --  The following attributes denote functions that cannot be folded

      when Attribute_From_Any
         | Attribute_To_Any
         | Attribute_TypeCode
      =>
         null;

      --  The following attributes can never be folded, and furthermore we
      --  should not even have entered the case statement for any of these.
      --  Note that in some cases, the values have already been folded as
      --  a result of the processing in Analyze_Attribute or earlier in
      --  this procedure.

      when Attribute_Abort_Signal
         | Attribute_Access
         | Attribute_Address
         | Attribute_Address_Size
         | Attribute_Asm_Input
         | Attribute_Asm_Output
         | Attribute_Base
         | Attribute_Bit_Order
         | Attribute_Bit_Position
         | Attribute_Callable
         | Attribute_Caller
         | Attribute_Class
         | Attribute_Code_Address
         | Attribute_Compiler_Version
         | Attribute_Count
         | Attribute_Default_Bit_Order
         | Attribute_Default_Scalar_Storage_Order
         | Attribute_Deref
         | Attribute_Elaborated
         | Attribute_Elab_Body
         | Attribute_Elab_Spec
         | Attribute_Elab_Subp_Body
         | Attribute_Enabled
         | Attribute_External_Tag
         | Attribute_Fast_Math
         | Attribute_First_Bit
         | Attribute_Img
         | Attribute_Input
         | Attribute_Initialized
         | Attribute_Last_Bit
         | Attribute_Library_Level
         | Attribute_Max_Integer_Size
         | Attribute_Maximum_Alignment
         | Attribute_Old
         | Attribute_Output
         | Attribute_Partition_ID
         | Attribute_Pool_Address
         | Attribute_Position
         | Attribute_Priority
         | Attribute_Put_Image
         | Attribute_Read
         | Attribute_Result
         | Attribute_Scalar_Storage_Order
         | Attribute_Simple_Storage_Pool
         | Attribute_Storage_Pool
         | Attribute_Storage_Size
         | Attribute_Storage_Unit
         | Attribute_Stub_Type
         | Attribute_System_Allocator_Alignment
         | Attribute_Tag
         | Attribute_Target_Name
         | Attribute_Terminated
         | Attribute_To_Address
         | Attribute_Type_Key
         | Attribute_Unchecked_Access
         | Attribute_Universal_Literal_String
         | Attribute_Unrestricted_Access
         | Attribute_Valid
         | Attribute_Valid_Scalars
         | Attribute_Valid_Value
         | Attribute_Value
         | Attribute_Wchar_T_Size
         | Attribute_Wide_Value
         | Attribute_Wide_Wide_Value
         | Attribute_Word_Size
         | Attribute_Write
      =>
         raise Program_Error;
      end case;

      --  At the end of the case, one more check. If we did a static evaluation
      --  so that the result is now a literal, then set Is_Static_Expression
      --  in the constant only if the prefix type is a static subtype. For
      --  non-static subtypes, the folding is still OK, but not static.

      --  An exception is the GNAT attribute Constrained_Array which is
      --  defined to be a static attribute in all cases.

      if Nkind (N) in N_Integer_Literal
                    | N_Real_Literal
                    | N_Character_Literal
                    | N_String_Literal
        or else (Is_Entity_Name (N)
                  and then Ekind (Entity (N)) = E_Enumeration_Literal)
      then
         Set_Is_Static_Expression (N, Static);

      --  If this is still an attribute reference, then it has not been folded
      --  and that means that its expressions are in a non-static context.

      elsif Nkind (N) = N_Attribute_Reference then
         Check_Expressions;

      --  Note: the else case not covered here are odd cases where the
      --  processing has transformed the attribute into something other
      --  than a constant. Nothing more to do in such cases.

      else
         null;
      end if;
   end Eval_Attribute;

   ------------------------------
   -- Is_Anonymous_Tagged_Base --
   ------------------------------

   function Is_Anonymous_Tagged_Base
     (Anon : Entity_Id;
      Typ  : Entity_Id) return Boolean
   is
   begin
      return
        Anon = Current_Scope
          and then Is_Itype (Anon)
          and then Associated_Node_For_Itype (Anon) = Parent (Typ);
   end Is_Anonymous_Tagged_Base;

   --------------------------------
   -- Name_Implies_Lvalue_Prefix --
   --------------------------------

   function Name_Implies_Lvalue_Prefix (Nam : Name_Id) return Boolean is
      pragma Assert (Is_Attribute_Name (Nam));
   begin
      return Attribute_Name_Implies_Lvalue_Prefix (Get_Attribute_Id (Nam));
   end Name_Implies_Lvalue_Prefix;

   -----------------------
   -- Resolve_Attribute --
   -----------------------

   procedure Resolve_Attribute (N : Node_Id; Typ : Entity_Id) is
      Loc      : constant Source_Ptr   := Sloc (N);
      P        : constant Node_Id      := Prefix (N);
      Aname    : constant Name_Id      := Attribute_Name (N);
      Attr_Id  : constant Attribute_Id := Get_Attribute_Id (Aname);
      Btyp     : constant Entity_Id    := Base_Type (Typ);
      Des_Btyp : Entity_Id;
      Index    : Interp_Index;
      It       : Interp;
      Nom_Subt : Entity_Id;

      procedure Accessibility_Message;
      --  Error, or warning within an instance, if the static accessibility
      --  rules of 3.10.2 are violated.

      function Declared_Within_Generic_Unit
        (Entity       : Entity_Id;
         Generic_Unit : Node_Id) return Boolean;
      --  Returns True if Declared_Entity is declared within the declarative
      --  region of Generic_Unit; otherwise returns False.

      function Prefix_With_Safe_Accessibility_Level return Boolean;
      --  Return True if the prefix does not have a value conversion of an
      --  array because a value conversion is like an aggregate with respect
      --  to determining accessibility level (RM 3.10.2); even if evaluation
      --  of a value conversion is guaranteed to not create a new object,
      --  accessibility rules are defined as if it might.

      ---------------------------
      -- Accessibility_Message --
      ---------------------------

      procedure Accessibility_Message is
         Indic : Node_Id := Parent (Parent (N));

      begin
         --  In an instance, this is a runtime check, but one we
         --  know will fail, so generate an appropriate warning.

         if In_Instance_Body then
            Error_Msg_Warn := SPARK_Mode /= On;
            Error_Msg_F
              ("non-local pointer cannot point to local object<<", P);
            Error_Msg_F ("\Program_Error [<<", P);
            Rewrite (N,
              Make_Raise_Program_Error (Loc,
                Reason => PE_Accessibility_Check_Failed));
            Set_Etype (N, Typ);
            return;

         else
            Error_Msg_F ("non-local pointer cannot point to local object", P);

            --  Check for case where we have a missing access definition

            if Is_Record_Type (Current_Scope)
              and then
                Nkind (Parent (N)) in N_Discriminant_Association
                                    | N_Index_Or_Discriminant_Constraint
            then
               Indic := Parent (Parent (N));
               while Present (Indic)
                 and then Nkind (Indic) /= N_Subtype_Indication
               loop
                  Indic := Parent (Indic);
               end loop;

               if Present (Indic) then
                  Error_Msg_NE
                    ("\use an access definition for" &
                     " the access discriminant of&",
                     N, Entity (Subtype_Mark (Indic)));
               end if;
            end if;
         end if;
      end Accessibility_Message;

      ----------------------------------
      -- Declared_Within_Generic_Unit --
      ----------------------------------

      function Declared_Within_Generic_Unit
        (Entity       : Entity_Id;
         Generic_Unit : Node_Id) return Boolean
      is
         Generic_Encloser : Node_Id := Enclosing_Generic_Unit (Entity);

      begin
         while Present (Generic_Encloser) loop
            if Generic_Encloser = Generic_Unit then
               return True;
            end if;

            --  We have to step to the scope of the generic's entity, because
            --  otherwise we'll just get back the same generic.

            Generic_Encloser :=
              Enclosing_Generic_Unit
                (Scope (Defining_Entity (Generic_Encloser)));
         end loop;

         return False;
      end Declared_Within_Generic_Unit;

      ------------------------------------------
      -- Prefix_With_Safe_Accessibility_Level --
      ------------------------------------------

      function Prefix_With_Safe_Accessibility_Level return Boolean is
         function Safe_Value_Conversions return Boolean;
         --  Return False if the prefix has a value conversion of an array type

         ----------------------------
         -- Safe_Value_Conversions --
         ----------------------------

         function Safe_Value_Conversions return Boolean is
            PP : Node_Id := P;

         begin
            loop
               if Nkind (PP) in N_Selected_Component | N_Indexed_Component then
                  PP := Prefix (PP);

               elsif Comes_From_Source (PP)
                 and then Nkind (PP) in N_Type_Conversion
                                      | N_Unchecked_Type_Conversion
                 and then Is_Array_Type (Etype (PP))
               then
                  return False;

               elsif Comes_From_Source (PP)
                 and then Nkind (PP) = N_Qualified_Expression
                 and then Is_Array_Type (Etype (PP))
                 and then Nkind (Original_Node (Expression (PP))) in
                            N_Aggregate | N_Extension_Aggregate
               then
                  return False;

               else
                  exit;
               end if;
            end loop;

            return True;
         end Safe_Value_Conversions;

      --  Start of processing for Prefix_With_Safe_Accessibility_Level

      begin
         --  No check required for unchecked and unrestricted access

         if Attr_Id = Attribute_Unchecked_Access
           or else Attr_Id = Attribute_Unrestricted_Access
         then
            return True;

         --  Check value conversions

         elsif Ekind (Btyp) = E_General_Access_Type
           and then not Safe_Value_Conversions
         then
            return False;
         end if;

         return True;
      end Prefix_With_Safe_Accessibility_Level;

   --  Start of processing for Resolve_Attribute

   begin
      --  If error during analysis, no point in continuing, except for array
      --  types, where we get better recovery by using unconstrained indexes
      --  than nothing at all (see Check_Array_Type).

      if Error_Posted (N)
        and then Attr_Id /= Attribute_First
        and then Attr_Id /= Attribute_Last
        and then Attr_Id /= Attribute_Length
        and then Attr_Id /= Attribute_Range
      then
         return;
      end if;

      --  If attribute was universal type, reset to actual type

      if Is_Universal_Numeric_Type (Etype (N)) then
         Set_Etype (N, Typ);
      end if;

      --  Remaining processing depends on attribute

      case Attr_Id is

         ------------
         -- Access --
         ------------

         --  For access attributes, if the prefix denotes an entity, it is
         --  interpreted as a name, never as a call. It may be overloaded,
         --  in which case resolution uses the profile of the context type.
         --  Otherwise prefix must be resolved.

         when Attribute_Access
            | Attribute_Unchecked_Access
            | Attribute_Unrestricted_Access
         =>
            --  Note possible modification if we have a variable

            if Is_Variable (P) then
               declare
                  PN : constant Node_Id := Parent (N);
                  Nm : Node_Id;

                  Note : Boolean := True;
                  --  Skip this for the case of Unrestricted_Access occurring
                  --  in the context of a Valid check, since this otherwise
                  --  leads to a missed warning (the Valid check does not
                  --  really modify!) If this case, Note will be reset to
                  --  False.

                  --  Skip it as well if the type is an Access_To_Constant,
                  --  given that no use of the value can modify the prefix.

               begin
                  if Attr_Id = Attribute_Unrestricted_Access
                    and then Nkind (PN) = N_Function_Call
                  then
                     Nm := Name (PN);

                     if Nkind (Nm) = N_Expanded_Name
                       and then Chars (Nm) = Name_Valid
                       and then Nkind (Prefix (Nm)) = N_Identifier
                       and then Chars (Prefix (Nm)) = Name_Attr_Long_Float
                     then
                        Note := False;
                     end if;

                  elsif Is_Access_Constant (Typ) then
                     Note := False;
                  end if;

                  if Note then
                     Note_Possible_Modification (P, Sure => False);
                  end if;
               end;
            end if;

            --  Case where prefix is an entity name

            if Is_Entity_Name (P) then

               --  Deal with case where prefix itself is overloaded

               if Is_Overloaded (P) then
                  Get_First_Interp (P, Index, It);
                  while Present (It.Nam) loop
                     if Type_Conformant (Designated_Type (Typ), It.Nam) then
                        Set_Entity (P, It.Nam);

                        --  The prefix is definitely NOT overloaded anymore at
                        --  this point, so we reset the Is_Overloaded flag to
                        --  avoid any confusion when reanalyzing the node.

                        Set_Is_Overloaded (P, False);
                        Set_Is_Overloaded (N, False);
                        Generate_Reference (Entity (P), P);
                        exit;
                     end if;

                     Get_Next_Interp (Index, It);
                  end loop;

                  --  If Prefix is a subprogram name, this reference freezes,
                  --  but not if within spec expression mode. The profile of
                  --  the subprogram is not frozen at this point.

                  if not In_Spec_Expression then
                     Freeze_Before (N, Entity (P), Do_Freeze_Profile => False);
                  end if;

               --  If it is a type, there is nothing to resolve.
               --  If it is a subprogram, do not freeze its profile.
               --  If it is an object, complete its resolution.

               elsif Is_Overloadable (Entity (P)) then
                  if not In_Spec_Expression then
                     Freeze_Before (N, Entity (P), Do_Freeze_Profile => False);
                  end if;

               --  Nothing to do if prefix is a type name

               elsif Is_Type (Entity (P)) then
                  null;

               --  Otherwise non-overloaded other case, resolve the prefix

               else
                  Resolve (P);
               end if;

               --  Some further error checks

               Error_Msg_Name_1 := Aname;

               if not Is_Entity_Name (P) then
                  null;

               elsif Is_Overloadable (Entity (P))
                 and then Is_Abstract_Subprogram (Entity (P))
               then
                  Error_Msg_F ("prefix of % attribute cannot be abstract", P);
                  Set_Etype (N, Any_Type);

               elsif Ekind (Entity (P)) = E_Enumeration_Literal then
                  Error_Msg_F
                    ("prefix of % attribute cannot be enumeration literal", P);
                  Set_Etype (N, Any_Type);

               --  An attempt to take 'Access of a function that renames an
               --  enumeration literal. Issue a specialized error message.

               elsif Ekind (Entity (P)) = E_Function
                 and then Present (Alias (Entity (P)))
                 and then Ekind (Alias (Entity (P))) = E_Enumeration_Literal
               then
                  Error_Msg_F
                    ("prefix of % attribute cannot be function renaming "
                     & "an enumeration literal", P);
                  Set_Etype (N, Any_Type);

               elsif Convention (Entity (P)) = Convention_Intrinsic then
                  Error_Msg_F ("prefix of % attribute cannot be intrinsic", P);
                  Set_Etype (N, Any_Type);
               end if;

               --  Assignments, return statements, components of aggregates,
               --  generic instantiations will require convention checks if
               --  the type is an access to subprogram. Given that there will
               --  also be accessibility checks on those, this is where the
               --  checks can eventually be centralized ???

               if Ekind (Btyp) in E_Access_Protected_Subprogram_Type
                                | E_Access_Subprogram_Type
                                | E_Anonymous_Access_Protected_Subprogram_Type
                                | E_Anonymous_Access_Subprogram_Type
               then
                  --  Deal with convention mismatch

                  if Convention (Designated_Type (Btyp)) /=
                     Convention (Entity (P))
                  then
                     Error_Msg_FE
                       ("subprogram & has wrong convention", P, Entity (P));
                     Error_Msg_Sloc := Sloc (Btyp);
                     Error_Msg_FE ("\does not match & declared#", P, Btyp);

                     if not Is_Itype (Btyp)
                       and then not Has_Convention_Pragma (Btyp)
                       and then Convention (Entity (P)) /= Convention_Intrinsic
                     then
                        Error_Msg_FE
                          ("\probable missing pragma Convention for &",
                           P, Btyp);
                     end if;

                  else
                     Check_Subtype_Conformant
                       (New_Id  => Entity (P),
                        Old_Id  => Designated_Type (Btyp),
                        Err_Loc => P);
                  end if;

                  if Attr_Id = Attribute_Unchecked_Access then
                     Error_Msg_Name_1 := Aname;
                     Error_Msg_F
                       ("attribute% cannot be applied to a subprogram", P);

                  elsif Aname = Name_Unrestricted_Access then
                     null;  --  Nothing to check

                  --  Check the static accessibility rule of 3.10.2(32).
                  --  This rule also applies within the private part of an
                  --  instantiation. This rule does not apply to anonymous
                  --  access-to-subprogram types in access parameters.

                  elsif Attr_Id = Attribute_Access
                    and then not In_Instance_Body
                    and then
                      (Ekind (Btyp) = E_Access_Subprogram_Type
                        or else Is_Local_Anonymous_Access (Btyp))
                    and then Subprogram_Access_Level (Entity (P)) >
                               Type_Access_Level (Btyp)
                  then
                     Error_Msg_F
                       ("subprogram must not be deeper than access type", P);

                  --  Check the restriction of 3.10.2(32) that disallows the
                  --  access attribute within a generic body when the ultimate
                  --  ancestor of the type of the attribute is declared outside
                  --  of the generic unit and the subprogram is declared within
                  --  that generic unit. This includes any such attribute that
                  --  occurs within the body of a generic unit that is a child
                  --  of the generic unit where the subprogram is declared.

                  --  The rule also prohibits applying the attribute when the
                  --  access type is a generic formal access type (since the
                  --  level of the actual type is not known). This restriction
                  --  does not apply when the attribute type is an anonymous
                  --  access-to-subprogram type. Note that this check was
                  --  revised by AI-229, because the original Ada 95 rule
                  --  was too lax. The original rule only applied when the
                  --  subprogram was declared within the body of the generic,
                  --  which allowed the possibility of dangling references).
                  --  The rule was also too strict in some cases, in that it
                  --  didn't permit the access to be declared in the generic
                  --  spec, whereas the revised rule does (as long as it's not
                  --  a formal type).

                  --  There are a couple of subtleties of the test for applying
                  --  the check that are worth noting. First, we only apply it
                  --  when the levels of the subprogram and access type are the
                  --  same (the case where the subprogram is statically deeper
                  --  was applied above, and the case where the type is deeper
                  --  is always safe). Second, we want the check to apply
                  --  within nested generic bodies and generic child unit
                  --  bodies, but not to apply to an attribute that appears in
                  --  the generic unit's specification. This is done by testing
                  --  that the attribute's innermost enclosing generic body is
                  --  not the same as the innermost generic body enclosing the
                  --  generic unit where the subprogram is declared (we don't
                  --  want the check to apply when the access attribute is in
                  --  the spec and there's some other generic body enclosing
                  --  generic). Finally, there's no point applying the check
                  --  when within an instance, because any violations will have
                  --  been caught by the compilation of the generic unit.

                  --  We relax this check in Relaxed_RM_Semantics mode for
                  --  compatibility with legacy code for use by Ada source
                  --  code analyzers (e.g. CodePeer).

                  elsif Attr_Id = Attribute_Access
                    and then not Relaxed_RM_Semantics
                    and then not In_Instance
                    and then Present (Enclosing_Generic_Unit (Entity (P)))
                    and then Present (Enclosing_Generic_Body (N))
                    and then Enclosing_Generic_Body (N) /=
                               Enclosing_Generic_Body
                                 (Enclosing_Generic_Unit (Entity (P)))
                    and then Subprogram_Access_Level (Entity (P)) =
                               Type_Access_Level (Btyp)
                    and then Ekind (Btyp) /=
                               E_Anonymous_Access_Subprogram_Type
                    and then Ekind (Btyp) /=
                               E_Anonymous_Access_Protected_Subprogram_Type
                  then
                     --  The attribute type's ultimate ancestor must be
                     --  declared within the same generic unit as the
                     --  subprogram is declared (including within another
                     --  nested generic unit). The error message is
                     --  specialized to say "ancestor" for the case where the
                     --  access type is not its own ancestor, since saying
                     --  simply "access type" would be very confusing.

                     if not Declared_Within_Generic_Unit
                              (Root_Type (Btyp),
                               Enclosing_Generic_Unit (Entity (P)))
                     then
                        Error_Msg_N
                          ("''Access attribute not allowed in generic body",
                           N);

                        if Root_Type (Btyp) = Btyp then
                           Error_Msg_NE
                             ("\because " &
                              "access type & is declared outside " &
                              "generic unit (RM 3.10.2(32))", N, Btyp);
                        else
                           Error_Msg_NE
                             ("\because ancestor of " &
                              "access type & is declared outside " &
                              "generic unit (RM 3.10.2(32))", N, Btyp);
                        end if;

                        Error_Msg_NE
                          ("\move ''Access to private part, or " &
                           "(Ada 2005) use anonymous access type instead of &",
                           N, Btyp);

                     --  If the ultimate ancestor of the attribute's type is
                     --  a formal type, then the attribute is illegal because
                     --  the actual type might be declared at a higher level.
                     --  The error message is specialized to say "ancestor"
                     --  for the case where the access type is not its own
                     --  ancestor, since saying simply "access type" would be
                     --  very confusing.

                     elsif Is_Generic_Type (Root_Type (Btyp)) then
                        if Root_Type (Btyp) = Btyp then
                           Error_Msg_N
                             ("access type must not be a generic formal type",
                              N);
                        else
                           Error_Msg_N
                             ("ancestor access type must not be a generic " &
                              "formal type", N);
                        end if;
                     end if;
                  end if;
               end if;

               --  If this is a renaming, an inherited operation, or a
               --  subprogram instance, use the original entity. This may make
               --  the node type-inconsistent, so this transformation can only
               --  be done if the node will not be reanalyzed. In particular,
               --  if it is within a default expression, the transformation
               --  must be delayed until the default subprogram is created for
               --  it, when the enclosing subprogram is frozen.

               if Is_Entity_Name (P)
                 and then Is_Overloadable (Entity (P))
                 and then Present (Alias (Entity (P)))
                 and then Expander_Active
               then
                  Rewrite (P,
                    New_Occurrence_Of (Alias (Entity (P)), Sloc (P)));
               end if;

            elsif Nkind (P) = N_Selected_Component
              and then Is_Overloadable (Entity (Selector_Name (P)))
            then
               --  Protected operation. If operation is overloaded, must
               --  disambiguate. Prefix that denotes protected object itself
               --  is resolved with its own type.

               if Attr_Id = Attribute_Unchecked_Access then
                  Error_Msg_Name_1 := Aname;
                  Error_Msg_F
                    ("attribute% cannot be applied to protected operation", P);
               end if;

               Resolve (Prefix (P));

               if not Is_Overloaded (P) then
                  Generate_Reference (Entity (Selector_Name (P)), P);

               else
                  Get_First_Interp (P, Index, It);
                  while Present (It.Nam) loop
                     if Type_Conformant (Designated_Type (Typ), It.Nam) then
                        Set_Entity (Selector_Name (P), It.Nam);

                        --  The prefix is definitely NOT overloaded anymore at
                        --  this point, so we reset the Is_Overloaded flag to
                        --  avoid any confusion when reanalyzing the node.

                        Set_Is_Overloaded (P, False);
                        Set_Is_Overloaded (N, False);
                        Generate_Reference (Entity (Selector_Name (P)), P);
                        exit;
                     end if;

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

            --  Implement check implied by 3.10.2 (18.1/2) : F.all'access is
            --  statically illegal if F is an anonymous access to subprogram.

            elsif Nkind (P) = N_Explicit_Dereference
              and then Is_Entity_Name (Prefix (P))
              and then Ekind (Etype (Entity (Prefix  (P)))) =
                 E_Anonymous_Access_Subprogram_Type
            then
               Error_Msg_N ("anonymous access to subprogram "
                 &  "has deeper accessibility than any master", P);

            elsif Is_Overloaded (P) then

               --  Use the designated type of the context to disambiguate
               --  Note that this was not strictly conformant to Ada 95,
               --  but was the implementation adopted by most Ada 95 compilers.
               --  The use of the context type to resolve an Access attribute
               --  reference is now mandated in AI-235 for Ada 2005.

               declare
                  Index : Interp_Index;
                  It    : Interp;

               begin
                  Get_First_Interp (P, Index, It);
                  while Present (It.Typ) loop
                     if Covers (Designated_Type (Typ), It.Typ) then
                        Resolve (P, It.Typ);
                        exit;
                     end if;

                     Get_Next_Interp (Index, It);
                  end loop;
               end;
            else
               Resolve (P);
            end if;

            --  X'Access is illegal if X denotes a constant and the access type
            --  is access-to-variable. Same for 'Unchecked_Access. The rule
            --  does not apply to 'Unrestricted_Access. If the reference is a
            --  default-initialized aggregate component for a self-referential
            --  type the reference is legal.

            if not (Ekind (Btyp) = E_Access_Subprogram_Type
                     or else Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type
                     or else (Is_Record_Type (Btyp)
                               and then
                                 Present (Corresponding_Remote_Type (Btyp)))
                     or else Ekind (Btyp) = E_Access_Protected_Subprogram_Type
                     or else Ekind (Btyp)
                               = E_Anonymous_Access_Protected_Subprogram_Type
                     or else Is_Access_Constant (Btyp)
                     or else Is_Variable (P)
                     or else Attr_Id = Attribute_Unrestricted_Access)
            then
               if Is_Entity_Name (P)
                 and then Is_Type (Entity (P))
               then
                  --  Legality of a self-reference through an access
                  --  attribute has been verified in Analyze_Access_Attribute.

                  null;

               elsif Comes_From_Source (N) then
                  Error_Msg_F ("access-to-variable designates constant", P);
               end if;
            end if;

            Des_Btyp := Designated_Type (Btyp);

            if Ada_Version >= Ada_2005
              and then Is_Incomplete_Type (Des_Btyp)
            then
               --  Ada 2005 (AI-412): If the (sub)type is a limited view of an
               --  imported entity, and the non-limited view is visible, make
               --  use of it. If it is an incomplete subtype, use the base type
               --  in any case.

               if From_Limited_With (Des_Btyp)
                 and then Present (Non_Limited_View (Des_Btyp))
               then
                  Des_Btyp := Non_Limited_View (Des_Btyp);

               elsif Ekind (Des_Btyp) = E_Incomplete_Subtype then
                  Des_Btyp := Etype (Des_Btyp);
               end if;
            end if;

            if (Attr_Id = Attribute_Access
                  or else
                Attr_Id = Attribute_Unchecked_Access)
              and then (Ekind (Btyp) = E_General_Access_Type
                         or else Ekind (Btyp) = E_Anonymous_Access_Type)
            then
               --  Ada 2005 (AI-230): Check the accessibility of anonymous
               --  access types for stand-alone objects, record and array
               --  components, and return objects. For a component definition
               --  the level is the same of the enclosing composite type.

               if Ada_Version >= Ada_2005
                 and then (Is_Local_Anonymous_Access (Btyp)

                            --  Handle cases where Btyp is the anonymous access
                            --  type of an Ada 2012 stand-alone object.

                            or else Nkind (Associated_Node_For_Itype (Btyp)) =
                                                        N_Object_Declaration)
                 and then Attr_Id = Attribute_Access

                 --  Verify that static checking is OK (namely that we aren't
                 --  in a specific context requiring dynamic checks on
                 --  expicitly aliased parameters), and then check the level.

                 --  Otherwise a check will be generated later when the return
                 --  statement gets expanded.

                 and then not Is_Special_Aliased_Formal_Access (N)
                 and then
                   Static_Accessibility_Level (N, Zero_On_Dynamic_Level) >
                     Deepest_Type_Access_Level (Btyp)
               then
                  --  In an instance, this is a runtime check, but one we know
                  --  will fail, so generate an appropriate warning. As usual,
                  --  this kind of warning is an error in SPARK mode.

                  if In_Instance_Body then
                     Error_Msg_Warn :=
                       SPARK_Mode /= On
                         and then
                           not No_Dynamic_Accessibility_Checks_Enabled (P);

                     Error_Msg_F
                       ("non-local pointer cannot point to local object<<", P);
                     Error_Msg_F ("\Program_Error [<<", P);

                     Rewrite (N,
                       Make_Raise_Program_Error (Loc,
                         Reason => PE_Accessibility_Check_Failed));
                     Set_Etype (N, Typ);

                  else
                     Error_Msg_F
                       ("non-local pointer cannot point to local object", P);
                  end if;
               end if;

               if Is_Dependent_Component_Of_Mutable_Object (P) then
                  Error_Msg_F
                    ("illegal attribute for discriminant-dependent component",
                     P);
               end if;

               --  Check static matching rule of 3.10.2(27). Nominal subtype
               --  of the prefix must statically match the designated type.

               Nom_Subt := Etype (P);

               if Is_Constr_Subt_For_U_Nominal (Nom_Subt) then
                  Nom_Subt := Base_Type (Nom_Subt);
               end if;

               if Is_Tagged_Type (Designated_Type (Typ)) then

                  --  If the attribute is in the context of an access
                  --  parameter, then the prefix is allowed to be of
                  --  the class-wide type (by AI-127).

                  if Ekind (Typ) = E_Anonymous_Access_Type then
                     if not Covers (Designated_Type (Typ), Nom_Subt)
                       and then not Covers (Nom_Subt, Designated_Type (Typ))
                     then
                        declare
                           Desig : Entity_Id;

                        begin
                           Desig := Designated_Type (Typ);

                           if Is_Class_Wide_Type (Desig) then
                              Desig := Etype (Desig);
                           end if;

                           if Is_Anonymous_Tagged_Base (Nom_Subt, Desig) then
                              null;

                           else
                              Error_Msg_FE
                                ("type of prefix: & not compatible",
                                  P, Nom_Subt);
                              Error_Msg_FE
                                ("\with &, the expected designated type",
                                  P, Designated_Type (Typ));
                           end if;
                        end;
                     end if;

                  elsif not Covers (Designated_Type (Typ), Nom_Subt)
                    or else
                      (not Is_Class_Wide_Type (Designated_Type (Typ))
                        and then Is_Class_Wide_Type (Nom_Subt))
                  then
                     Error_Msg_FE
                       ("type of prefix: & is not covered", P, Nom_Subt);
                     Error_Msg_FE
                       ("\by &, the expected designated type" &
                           " (RM 3.10.2 (27))", P, Designated_Type (Typ));
                  end if;

                  if Is_Class_Wide_Type (Designated_Type (Typ))
                    and then Has_Discriminants (Etype (Designated_Type (Typ)))
                    and then Is_Constrained (Etype (Designated_Type (Typ)))
                    and then Designated_Type (Typ) /= Nom_Subt
                  then
                     Apply_Discriminant_Check
                       (N, Etype (Designated_Type (Typ)));
                  end if;

               --  Ada 2005 (AI-363): Require static matching when designated
               --  type has discriminants and a constrained partial view, since
               --  in general objects of such types are mutable, so we can't
               --  allow the access value to designate a constrained object
               --  (because access values must be assumed to designate mutable
               --  objects when designated type does not impose a constraint).

               elsif Subtypes_Statically_Match (Des_Btyp, Nom_Subt) then
                  null;

               elsif Has_Discriminants (Designated_Type (Typ))
                 and then not Is_Constrained (Des_Btyp)
                 and then
                   (Ada_Version < Ada_2005
                     or else
                       not Object_Type_Has_Constrained_Partial_View
                             (Typ => Designated_Type (Base_Type (Typ)),
                              Scop => Current_Scope))
               then
                  null;

               else
                  Error_Msg_F
                    ("object subtype must statically match "
                     & "designated subtype", P);

                  if Is_Entity_Name (P)
                    and then Is_Array_Type (Designated_Type (Typ))
                  then
                     declare
                        D : constant Node_Id := Declaration_Node (Entity (P));
                     begin
                        Error_Msg_N
                          ("aliased object has explicit bounds??", D);
                        Error_Msg_N
                          ("\declare without bounds (and with explicit "
                           & "initialization)??", D);
                        Error_Msg_N
                          ("\for use with unconstrained access??", D);
                     end;
                  end if;
               end if;

               --  Check the static accessibility rule of 3.10.2(28). Note that
               --  this check is not performed for the case of an anonymous
               --  access type, since the access attribute is always legal
               --  in such a context - unless the restriction
               --  No_Dynamic_Accessibility_Checks is active.

               declare
                  No_Dynamic_Acc_Checks : constant Boolean :=
                    No_Dynamic_Accessibility_Checks_Enabled (Btyp);

                  Compatible_Alt_Checks : constant Boolean :=
                    No_Dynamic_Acc_Checks and then not Debug_Flag_Underscore_B;
               begin
                  if Attr_Id /= Attribute_Unchecked_Access
                    and then (Ekind (Btyp) = E_General_Access_Type
                               or else No_Dynamic_Acc_Checks)

                    --  In the case of the alternate "compatibility"
                    --  accessibility model we do not perform a static
                    --  accessibility check on actuals for anonymous access
                    --  types - so exclude them here.

                    and then not (Compatible_Alt_Checks
                                   and then Is_Actual_Parameter (N)
                                   and then Ekind (Btyp)
                                              = E_Anonymous_Access_Type)

                    --  Call Accessibility_Level directly to avoid returning
                    --  zero on cases where the prefix is an explicitly aliased
                    --  parameter in a return statement, instead of using the
                    --  normal Static_Accessibility_Level function.

                    --  Shouldn't this be handled somehow in
                    --  Static_Accessibility_Level ???

                    and then Nkind (Accessibility_Level (P, Dynamic_Level))
                               = N_Integer_Literal
                    and then
                      Intval (Accessibility_Level (P, Dynamic_Level))
                        > Deepest_Type_Access_Level (Btyp)
                  then
                     Accessibility_Message;
                     return;
                  end if;
               end;
            end if;

            if Ekind (Btyp) in E_Access_Protected_Subprogram_Type
                             | E_Anonymous_Access_Protected_Subprogram_Type
            then
               if Is_Entity_Name (P)
                 and then not Is_Protected_Type (Scope (Entity (P)))
               then
                  Error_Msg_F ("context requires a protected subprogram", P);

               --  Check accessibility of protected object against that of the
               --  access type, but only on user code, because the expander
               --  creates access references for handlers. If the context is an
               --  anonymous_access_to_protected, there are no accessibility
               --  checks either. Omit check entirely for Unrestricted_Access.

               elsif Static_Accessibility_Level (P, Zero_On_Dynamic_Level)
                       > Deepest_Type_Access_Level (Btyp)
                 and then Comes_From_Source (N)
                 and then Ekind (Btyp) = E_Access_Protected_Subprogram_Type
                 and then Attr_Id /= Attribute_Unrestricted_Access
               then
                  Accessibility_Message;
                  return;

               --  AI05-0225: If the context is not an access to protected
               --  function, the prefix must be a variable, given that it may
               --  be used subsequently in a protected call.

               elsif Nkind (P) = N_Selected_Component
                 and then not Is_Variable (Prefix (P))
                 and then Ekind (Entity (Selector_Name (P))) /= E_Function
               then
                  Error_Msg_N
                    ("target object of access to protected procedure "
                      & "must be variable", N);

               elsif Is_Entity_Name (P) then
                  Check_Internal_Protected_Use (N, Entity (P));
               end if;

            elsif Ekind (Btyp) in E_Access_Subprogram_Type
                                | E_Anonymous_Access_Subprogram_Type
              and then Ekind (Etype (N)) = E_Access_Protected_Subprogram_Type
            then
               Error_Msg_F ("context requires a non-protected subprogram", P);
            end if;

            --  AI12-0412: The rule in RM 6.1.1(18.2/5) disallows applying
            --  attribute Access to a primitive of an abstract type when the
            --  primitive has any Pre'Class or Post'Class aspects specified
            --  with nonstatic expressions.

            if Attr_Id = Attribute_Access
              and then Ekind (Btyp) in E_Access_Subprogram_Type
                                     | E_Anonymous_Access_Subprogram_Type
              and then Is_Entity_Name (P)
              and then Is_Dispatching_Operation (Entity (P))
              and then
                Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post (Entity (P))
            then
               Error_Msg_N
                 ("attribute not allowed for primitive of abstract type with "
                   & "nonstatic class-wide pre/postconditions",
                  N);
            end if;

            --  The context cannot be a pool-specific type, but this is a
            --  legality rule, not a resolution rule, so it must be checked
            --  separately, after possibly disambiguation (see AI-245).

            if Ekind (Btyp) = E_Access_Type
              and then Attr_Id /= Attribute_Unrestricted_Access
            then
               Wrong_Type (N, Typ);
            end if;

            --  The context may be a constrained access type (however ill-
            --  advised such subtypes might be) so in order to generate a
            --  constraint check we need to set the type of the attribute
            --  reference to the base type of the context.

            Set_Etype (N, Btyp);

            --  Check for incorrect atomic/volatile/VFA reference (RM C.6(12))

            if Attr_Id /= Attribute_Unrestricted_Access then
               if Is_Atomic_Object (P)
                 and then not Is_Atomic (Designated_Type (Typ))
               then
                  Error_Msg_F
                    ("access to atomic object cannot yield access-to-" &
                     "non-atomic type", P);

               elsif Is_Volatile_Object_Ref (P)
                 and then not Is_Volatile (Designated_Type (Typ))
               then
                  Error_Msg_F
                    ("access to volatile object cannot yield access-to-" &
                     "non-volatile type", P);

               elsif Is_Volatile_Full_Access_Object_Ref (P)
                 and then not Is_Volatile_Full_Access (Designated_Type (Typ))
               then
                  Error_Msg_F
                    ("access to full access object cannot yield access-to-" &
                     "non-full-access type", P);
               end if;

               --  Check for nonatomic subcomponent of a full access object
               --  in Ada 2022 (RM C.6 (12)).

               if Ada_Version >= Ada_2022
                 and then Is_Subcomponent_Of_Full_Access_Object (P)
                 and then not Is_Atomic_Object (P)
               then
                  Error_Msg_NE
                    ("cannot have access attribute with prefix &", N, P);
                  Error_Msg_N
                    ("\nonatomic subcomponent of full access object "
                     & "(RM C.6(12))", N);
               end if;
            end if;

            --  Check for aliased view. We allow a nonaliased prefix when in
            --  an instance because the prefix may have been a tagged formal
            --  object, which is defined to be aliased even when the actual
            --  might not be (other instance cases will have been caught in
            --  the generic). Similarly, within an inlined body we know that
            --  the attribute is legal in the original subprogram, therefore
            --  legal in the expansion.

            if not (Is_Entity_Name (P)
                     and then Is_Overloadable (Entity (P)))
              and then not (Nkind (P) = N_Selected_Component
                             and then
                               Is_Overloadable (Entity (Selector_Name (P))))
              and then not Is_Aliased_View (Original_Node (P))
              and then not In_Instance
              and then not In_Inlined_Body
              and then Comes_From_Source (N)
            then
               --  Here we have a non-aliased view. This is illegal unless we
               --  have the case of Unrestricted_Access, where for now we allow
               --  this (we will reject later if expected type is access to an
               --  unconstrained array with a thin pointer).

               --  No need for an error message on a generated access reference
               --  for the controlling argument in a dispatching call: error
               --  will be reported when resolving the call.

               if Attr_Id /= Attribute_Unrestricted_Access then
                  Error_Msg_Name_1 := Aname;
                  Error_Msg_N ("prefix of % attribute must be aliased", P);

               --  Check for unrestricted access where expected type is a thin
               --  pointer to an unconstrained array.

               elsif Has_Size_Clause (Typ)
                 and then RM_Size (Typ) = System_Address_Size
               then
                  declare
                     DT : constant Entity_Id := Designated_Type (Typ);
                  begin
                     if Is_Array_Type (DT)
                       and then not Is_Constrained (DT)
                     then
                        Error_Msg_N
                          ("illegal use of Unrestricted_Access attribute", P);
                        Error_Msg_N
                          ("\attempt to generate thin pointer to unaliased "
                           & "object", P);
                     end if;
                  end;
               end if;
            end if;

            --  Check that the prefix does not have a value conversion of an
            --  array type since a value conversion is like an aggregate with
            --  respect to determining accessibility level (RM 3.10.2).

            if not Prefix_With_Safe_Accessibility_Level then
               Accessibility_Message;
               return;
            end if;

            --  Mark that address of entity is taken in case of
            --  'Unrestricted_Access or in case of a subprogram.

            if Is_Entity_Name (P)
              and then (Attr_Id = Attribute_Unrestricted_Access
                         or else Is_Subprogram (Entity (P)))
            then
               Set_Address_Taken (Entity (P));
            end if;

            --  Deal with possible elaboration check

            if Is_Entity_Name (P) and then Is_Subprogram (Entity (P)) then
               declare
                  Subp_Id   : constant Entity_Id := Entity (P);
                  Scop      : constant Entity_Id := Scope (Subp_Id);
                  Subp_Decl : constant Node_Id   :=
                                Unit_Declaration_Node (Subp_Id);
                  Flag_Id   : Entity_Id;
                  Subp_Body : Node_Id;

               --  If the access has been taken and the body of the subprogram
               --  has not been see yet, indirect calls must be protected with
               --  elaboration checks. We have the proper elaboration machinery
               --  for subprograms declared in packages, but within a block or
               --  a subprogram the body will appear in the same declarative
               --  part, and we must insert a check in the eventual body itself
               --  using the elaboration flag that we generate now. The check
               --  is then inserted when the body is expanded. This processing
               --  is not needed for a stand alone expression function because
               --  the internally generated spec and body are always inserted
               --  as a pair in the same declarative list.

               begin
                  if Expander_Active
                    and then Comes_From_Source (Subp_Id)
                    and then Comes_From_Source (N)
                    and then In_Open_Scopes (Scop)
                    and then Ekind (Scop) in E_Block | E_Procedure | E_Function
                    and then not Has_Completion (Subp_Id)
                    and then No (Elaboration_Entity (Subp_Id))
                    and then Nkind (Subp_Decl) = N_Subprogram_Declaration
                    and then Nkind (Original_Node (Subp_Decl)) /=
                                                       N_Expression_Function
                  then
                     --  Create elaboration variable for it

                     Flag_Id := Make_Temporary (Loc, 'E');
                     Set_Elaboration_Entity (Subp_Id, Flag_Id);
                     Set_Is_Frozen (Flag_Id);

                     --  Insert declaration for flag after subprogram
                     --  declaration. Note that attribute reference may
                     --  appear within a nested scope.

                     Insert_After_And_Analyze (Subp_Decl,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Flag_Id,
                         Object_Definition   =>
                           New_Occurrence_Of (Standard_Short_Integer, Loc),
                         Expression          =>
                           Make_Integer_Literal (Loc, Uint_0)));

                     --  The above sets the Scope of the flag entity to the
                     --  current scope, in which the attribute appears, but
                     --  the flag declaration has been inserted after that
                     --  of Subp_Id, so the scope of the flag is the same as
                     --  that of Subp_Id. This is relevant when unnesting,
                     --  where processing depends on correct scope setting.

                     Set_Scope (Flag_Id, Scop);
                  end if;

                  --  Taking the 'Access of an expression function freezes its
                  --  expression (RM 13.14 10.3/3). This does not apply to an
                  --  expression function that acts as a completion because the
                  --  generated body is immediately analyzed and the expression
                  --  is automatically frozen.

                  if Is_Expression_Function (Subp_Id)
                    and then Present (Corresponding_Body (Subp_Decl))
                  then
                     Subp_Body :=
                       Unit_Declaration_Node (Corresponding_Body (Subp_Decl));

                     --  The body has already been analyzed when the expression
                     --  function acts as a completion.

                     if Analyzed (Subp_Body) then
                        null;

                     --  Attribute 'Access may appear within the generated body
                     --  of the expression function subject to the attribute:

                     --    function F is (... F'Access ...);

                     --  If the expression function is on the scope stack, then
                     --  the body is currently being analyzed. Do not reanalyze
                     --  it because this will lead to infinite recursion.

                     elsif In_Open_Scopes (Subp_Id) then
                        null;

                     --  If reference to the expression function appears in an
                     --  inner scope, for example as an actual in an instance,
                     --  this is not a freeze point either.

                     elsif Scope (Subp_Id) /= Current_Scope then
                        null;

                      --  Analyze the body of the expression function to freeze
                      --  the expression. This takes care of the case where the
                      --  'Access is part of dispatch table initialization and
                      --  the generated body of the expression function has not
                      --  been analyzed yet.

                     else
                        Analyze (Subp_Body);
                     end if;
                  end if;
               end;
            end if;

         -------------
         -- Address --
         -------------

         --  Deal with resolving the type for Address attribute, overloading
         --  is not permitted here, since there is no context to resolve it.

         when Attribute_Address
            | Attribute_Code_Address
         =>
            --  To be safe, assume that if the address of a variable is taken,
            --  it may be modified via this address, so note modification.

            if Is_Variable (P) then
               Note_Possible_Modification (P, Sure => False);
            end if;

            if Nkind (P) in N_Subexpr
              and then Is_Overloaded (P)
            then
               Get_First_Interp (P, Index, It);
               Get_Next_Interp (Index, It);

               if Present (It.Nam) then
                  Error_Msg_Name_1 := Aname;
                  Error_Msg_F
                    ("prefix of % attribute cannot be overloaded", P);
               end if;
            end if;

            if not Is_Entity_Name (P)
              or else not Is_Overloadable (Entity (P))
            then
               if not Is_Task_Type (Etype (P))
                 or else Nkind (P) = N_Explicit_Dereference
               then
                  Resolve (P);
               end if;
            end if;

            --  If this is the name of a derived subprogram, or that of a
            --  generic actual, the address is that of the original entity.

            if Is_Entity_Name (P)
              and then Is_Overloadable (Entity (P))
              and then Present (Alias (Entity (P)))
            then
               Rewrite (P,
                 New_Occurrence_Of (Alias (Entity (P)), Sloc (P)));
            end if;

            if Is_Entity_Name (P) then
               Set_Address_Taken (Entity (P));
            end if;

            if Nkind (P) = N_Slice then

               --  Arr (X .. Y)'address is identical to Arr (X)'address,
               --  even if the array is packed and the slice itself is not
               --  addressable. Transform the prefix into an indexed component.

               --  Note that the transformation is safe only if we know that
               --  the slice is non-null. That is because a null slice can have
               --  an out of bounds index value.

               --  Right now, gigi blows up if given 'Address on a slice as a
               --  result of some incorrect freeze nodes generated by the front
               --  end, and this covers up that bug in one case, but the bug is
               --  likely still there in the cases not handled by this code ???

               --  It's not clear what 'Address *should* return for a null
               --  slice with out of bounds indexes, this might be worth an ARG
               --  discussion ???

               --  One approach would be to do a length check unconditionally,
               --  and then do the transformation below unconditionally, but
               --  analyze with checks off, avoiding the problem of the out of
               --  bounds index. This approach would interpret the address of
               --  an out of bounds null slice as being the address where the
               --  array element would be if there was one, which is probably
               --  as reasonable an interpretation as any ???

               declare
                  Loc : constant Source_Ptr := Sloc (P);
                  D   : constant Node_Id := Discrete_Range (P);
                  Lo  : Node_Id;

               begin
                  if Is_Entity_Name (D)
                    and then
                      Not_Null_Range
                        (Type_Low_Bound (Entity (D)),
                         Type_High_Bound (Entity (D)))
                  then
                     Lo :=
                       Make_Attribute_Reference (Loc,
                          Prefix => (New_Occurrence_Of (Entity (D), Loc)),
                          Attribute_Name => Name_First);

                  elsif Nkind (D) = N_Range
                    and then Not_Null_Range (Low_Bound (D), High_Bound (D))
                  then
                     Lo := Low_Bound (D);

                  else
                     Lo := Empty;
                  end if;

                  if Present (Lo) then
                     Rewrite (P,
                        Make_Indexed_Component (Loc,
                           Prefix => Relocate_Node (Prefix (P)),
                           Expressions => New_List (Lo)));

                     Analyze_And_Resolve (P);
                  end if;
               end;
            end if;

         ------------------
         -- Body_Version --
         ------------------

         --  Prefix of Body_Version attribute can be a subprogram name which
         --  must not be resolved, since this is not a call.

         when Attribute_Body_Version =>
            null;

         ------------
         -- Caller --
         ------------

         --  Prefix of Caller attribute is an entry name which must not
         --  be resolved, since this is definitely not an entry call.

         when Attribute_Caller =>
            null;

         ------------------
         -- Code_Address --
         ------------------

         --  Shares processing with Address attribute

         -----------
         -- Count --
         -----------

         --  If the prefix of the Count attribute is an entry name it must not
         --  be resolved, since this is definitely not an entry call. However,
         --  if it is an element of an entry family, the index itself may
         --  have to be resolved because it can be a general expression.

         when Attribute_Count =>
            if Nkind (P) = N_Indexed_Component
              and then Is_Entity_Name (Prefix (P))
            then
               declare
                  Indx : constant Node_Id   := First (Expressions (P));
                  Fam  : constant Entity_Id := Entity (Prefix (P));
               begin
                  Resolve (Indx, Entry_Index_Type (Fam));
                  Apply_Scalar_Range_Check (Indx, Entry_Index_Type (Fam));
               end;
            end if;

         ----------------
         -- Elaborated --
         ----------------

         --  Prefix of the Elaborated attribute is a subprogram name which
         --  must not be resolved, since this is definitely not a call. Note
         --  that it is a library unit, so it cannot be overloaded here.

         when Attribute_Elaborated =>
            null;

         -------------
         -- Enabled --
         -------------

         --  Prefix of Enabled attribute is a check name, which must be treated
         --  specially and not touched by Resolve.

         when Attribute_Enabled =>
            null;

         ----------------
         -- Loop_Entry --
         ----------------

         --  Do not resolve the prefix of Loop_Entry, instead wait until the
         --  attribute has been expanded (see Expand_Loop_Entry_Attributes).
         --  The delay ensures that any generated checks or temporaries are
         --  inserted before the relocated prefix.

         when Attribute_Loop_Entry =>
            null;

         --------------------
         -- Mechanism_Code --
         --------------------

         --  Prefix of the Mechanism_Code attribute is a function name
         --  which must not be resolved. Should we check for overloaded ???

         when Attribute_Mechanism_Code =>
            null;

         ------------------
         -- Partition_ID --
         ------------------

         --  Most processing is done in sem_dist, after determining the
         --  context type. Node is rewritten as a conversion to a runtime call.

         when Attribute_Partition_ID =>
            Process_Partition_Id (N);
            return;

         ------------------
         -- Pool_Address --
         ------------------

         when Attribute_Pool_Address =>
            Resolve (P);

         -----------
         -- Range --
         -----------

         --  We replace the Range attribute node with a range expression whose
         --  bounds are the 'First and 'Last attributes applied to the same
         --  prefix. The reason that we do this transformation here instead of
         --  in the expander is that it simplifies other parts of the semantic
         --  analysis which assume that the Range has been replaced; thus it
         --  must be done even when in semantic-only mode (note that the RM
         --  specifically mentions this equivalence, we take care that the
         --  prefix is only evaluated once).

         when Attribute_Range => Range_Attribute : declare
            Dims : List_Id;
            HB   : Node_Id;
            LB   : Node_Id;

         begin
            if not Is_Entity_Name (P) or else not Is_Type (Entity (P)) then
               Resolve (P);

               --  If the prefix is a function call returning on the secondary
               --  stack, we must make sure to mark/release the stack.

               if Nkind (P) = N_Function_Call
                 and then Nkind (Parent (N)) = N_Loop_Parameter_Specification
                 and then Requires_Transient_Scope (Etype (P))
               then
                  Set_Uses_Sec_Stack (Scope (Current_Scope));
               end if;
            end if;

            Dims := Expressions (N);

            HB :=
              Make_Attribute_Reference (Loc,
                Prefix         => Duplicate_Subexpr (P, Name_Req => True),
                Attribute_Name => Name_Last,
                Expressions    => Dims);

            LB :=
              Make_Attribute_Reference (Loc,
                Prefix          => P,
                Attribute_Name  => Name_First,
                Expressions     => (Dims));

            --  Do not share the dimension indicator, if present. Even though
            --  it is a static constant, its source location may be modified
            --  when printing expanded code and node sharing will lead to chaos
            --  in Sprint.

            if Present (Dims) then
               Set_Expressions (LB, New_List (New_Copy_Tree (First (Dims))));
            end if;

            --  If the original was marked as Must_Not_Freeze (see code in
            --  Sem_Ch3.Make_Index), then make sure the rewriting does not
            --  freeze either.

            if Must_Not_Freeze (N) then
               Set_Must_Not_Freeze (HB);
               Set_Must_Not_Freeze (LB);
               Set_Must_Not_Freeze (Prefix (HB));
               Set_Must_Not_Freeze (Prefix (LB));
            end if;

            if Raises_Constraint_Error (Prefix (N)) then

               --  Preserve Sloc of prefix in the new bounds, so that the
               --  posted warning can be removed if we are within unreachable
               --  code.

               Set_Sloc (LB, Sloc (Prefix (N)));
               Set_Sloc (HB, Sloc (Prefix (N)));
            end if;

            Rewrite (N, Make_Range (Loc, LB, HB));
            Analyze_And_Resolve (N, Typ);

            --  Ensure that the expanded range does not have side effects

            Force_Evaluation (LB);
            Force_Evaluation (HB);

            --  Normally after resolving attribute nodes, Eval_Attribute
            --  is called to do any possible static evaluation of the node.
            --  However, here since the Range attribute has just been
            --  transformed into a range expression it is no longer an
            --  attribute node and therefore the call needs to be avoided
            --  and is accomplished by simply returning from the procedure.

            return;
         end Range_Attribute;

         -------------
         -- Reduce --
         -------------

         when Attribute_Reduce =>
            declare
               E1 : constant Node_Id := First (Expressions (N));
               E2 : constant Node_Id := Next (E1);
               Op : Entity_Id := Empty;

               Index : Interp_Index;
               It    : Interp;
               function Proper_Op (Op : Entity_Id) return Boolean;

               ---------------
               -- Proper_Op --
               ---------------

               function Proper_Op (Op : Entity_Id) return Boolean is
                  F1, F2 : Entity_Id;

               begin
                  F1 := First_Formal (Op);
                  if No (F1) then
                     return False;
                  else
                     F2 := Next_Formal (F1);
                     if No (F2)
                       or else Present (Next_Formal (F2))
                     then
                        return False;

                     elsif Ekind (Op) = E_Procedure then
                        return Ekind (F1) = E_In_Out_Parameter
                          and then Covers (Typ, Etype (F1));

                     else
                        return
                          (Ekind (Op) = E_Operator
                            and then Scope (Op) = Standard_Standard)
                            or else  Covers (Typ, Etype (Op));
                     end if;
                  end if;
               end Proper_Op;

            begin
               Resolve (E2, Typ);
               if Is_Overloaded (E1) then
                  Get_First_Interp (E1, Index, It);
                  while Present (It.Nam) loop
                     if Proper_Op (It.Nam) then
                        Op := It.Nam;
                        Set_Entity (E1, Op);
                        exit;
                     end if;

                     Get_Next_Interp (Index, It);
                  end loop;

               elsif Nkind (E1) = N_Attribute_Reference
                 and then (Attribute_Name (E1) = Name_Max
                   or else Attribute_Name (E1) = Name_Min)
               then
                  Op := E1;

               elsif Proper_Op (Entity (E1)) then
                  Op := Entity (E1);
                  Set_Etype (N, Typ);
               end if;

               if No (Op) then
                  Error_Msg_N ("No visible subprogram for reduction", E1);
               end if;
            end;

         ------------
         -- Result --
         ------------

         --  We will only come here during the prescan of a spec expression
         --  containing a Result attribute. In that case the proper Etype has
         --  already been set, and nothing more needs to be done here.

         when Attribute_Result =>
            null;

         ----------------------
         -- Unchecked_Access --
         ----------------------

         --  Processing is shared with Access

         -------------------------
         -- Unrestricted_Access --
         -------------------------

         --  Processing is shared with Access

         ------------
         -- Update --
         ------------

         --  Resolve aggregate components in component associations

         when Attribute_Update => Update : declare
            Aggr  : constant Node_Id   := First (Expressions (N));
            Typ   : constant Entity_Id := Etype (Prefix (N));
            Assoc : Node_Id;
            Comp  : Node_Id;
            Expr  : Node_Id;

         begin
            --  Set the Etype of the aggregate to that of the prefix, even
            --  though the aggregate may not be a proper representation of a
            --  value of the type (missing or duplicated associations, etc.)
            --  Complete resolution of the prefix. Note that in Ada 2012 it
            --  can be a qualified expression that is e.g. an aggregate.

            Set_Etype (Aggr, Typ);
            Resolve (Prefix (N), Typ);

            --  For an array type, resolve expressions with the component type
            --  of the array, and apply constraint checks when needed.

            if Is_Array_Type (Typ) then
               Assoc := First (Component_Associations (Aggr));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Resolve (Expr, Component_Type (Typ));

                  --  The choices in the association are static constants,
                  --  or static aggregates each of whose components belongs
                  --  to the proper index type. However, they must also
                  --  belong to the index subtype (s) of the prefix, which
                  --  may be a subtype (e.g. given by a slice).

                  --  Choices may also be identifiers with no staticness
                  --  requirements, in which case they must resolve to the
                  --  index type.

                  declare
                     C    : Node_Id;
                     C_E  : Node_Id;
                     Indx : Node_Id;

                  begin
                     C := First (Choices (Assoc));
                     while Present (C) loop
                        Indx := First_Index (Etype (Prefix (N)));

                        if Nkind (C) /= N_Aggregate then
                           Analyze_And_Resolve (C, Etype (Indx));
                        else
                           C_E := First (Expressions (C));
                           while Present (C_E) loop
                              Analyze_And_Resolve (C_E, Etype (Indx));

                              Next (C_E);
                              Next_Index (Indx);
                           end loop;
                        end if;

                        Next (C);
                     end loop;
                  end;

                  Next (Assoc);
               end loop;

            --  For a record type, use type of each component, which is
            --  recorded during analysis.

            else
               Assoc := First (Component_Associations (Aggr));
               while Present (Assoc) loop
                  Comp := First (Choices (Assoc));
                  Expr := Expression (Assoc);

                  if Nkind (Comp) /= N_Others_Choice
                    and then not Error_Posted (Comp)
                  then
                     Resolve (Expr, Etype (Entity (Comp)));
                  end if;

                  Next (Assoc);
               end loop;
            end if;
         end Update;

         ---------
         -- Val --
         ---------

         --  Apply range check. Note that we did not do this during the
         --  analysis phase, since we wanted Eval_Attribute to have a
         --  chance at finding an illegal out of range value.

         when Attribute_Val =>

            --  Note that we do our own Eval_Attribute call here rather than
            --  use the common one, because we need to do processing after
            --  the call, as per above comment.

            Eval_Attribute (N);

            --  Eval_Attribute may replace the node with a raise CE, or
            --  fold it to a constant. Obviously we only apply a scalar
            --  range check if this did not happen.

            if Nkind (N) = N_Attribute_Reference
              and then Attribute_Name (N) = Name_Val
            then
               Apply_Scalar_Range_Check (First (Expressions (N)), Btyp);
            end if;

            return;

         -------------
         -- Version --
         -------------

         --  Prefix of Version attribute can be a subprogram name which
         --  must not be resolved, since this is not a call.

         when Attribute_Version =>
            null;

         ----------------------
         -- Other Attributes --
         ----------------------

         --  For other attributes, resolve prefix unless it is a type. If
         --  the attribute reference itself is a type name ('Base and 'Class)
         --  then this is only legal within a task or protected record.

         when others =>
            if not Is_Entity_Name (P) or else not Is_Type (Entity (P)) then
               Resolve (P);
            end if;

            --  If the attribute reference itself is a type name ('Base,
            --  'Class) then this is only legal within a task or protected
            --  record. What is this all about ???

            if Is_Entity_Name (N) and then Is_Type (Entity (N)) then
               if Is_Concurrent_Type (Entity (N))
                 and then In_Open_Scopes (Entity (P))
               then
                  null;
               else
                  Error_Msg_N
                    ("invalid use of subtype name in expression or call", N);
               end if;
            end if;

            --  For attributes whose argument may be a string, complete
            --  resolution of argument now. This avoids premature expansion
            --  (and the creation of transient scopes) before the attribute
            --  reference is resolved.

            case Attr_Id is
               when Attribute_Valid_Value | Attribute_Value =>
                  Resolve (First (Expressions (N)), Standard_String);

               when Attribute_Wide_Value =>
                  Resolve (First (Expressions (N)), Standard_Wide_String);

               when Attribute_Wide_Wide_Value =>
                  Resolve (First (Expressions (N)), Standard_Wide_Wide_String);

               when others => null;
            end case;

            --  If the prefix of the attribute is a class-wide type then it
            --  will be expanded into a dispatching call to a predefined
            --  primitive. Therefore we must check for potential violation
            --  of such restriction.

            if Is_Class_Wide_Type (Etype (P)) then
               Check_Restriction (No_Dispatching_Calls, N);
            end if;
      end case;

      --  Mark use clauses of the original prefix if the attribute is applied
      --  to an entity.

      if Nkind (Original_Node (P)) in N_Has_Entity
        and then Present (Entity (Original_Node (P)))
      then
         Mark_Use_Clauses (Original_Node (P));
      end if;

      --  Normally the Freezing is done by Resolve but sometimes the Prefix
      --  is not resolved, in which case the freezing must be done now.

      --  For an elaboration check on a subprogram, we do not freeze its type.
      --  It may be declared in an unrelated scope, in particular in the case
      --  of a generic function whose type may remain unelaborated.

      if Attr_Id = Attribute_Elaborated then
         null;

      --  Should this be restricted to Expander_Active???

      else
         Freeze_Expression (P);
      end if;

      --  Finally perform static evaluation on the attribute reference

      Analyze_Dimension (N);
      Eval_Attribute (N);
   end Resolve_Attribute;

   ------------------------
   -- Set_Boolean_Result --
   ------------------------

   procedure Set_Boolean_Result (N : Node_Id; B : Boolean) is
      Loc : constant Source_Ptr := Sloc (N);
   begin
      if B then
         Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
      else
         Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
      end if;
   end Set_Boolean_Result;

   --------------------------------
   -- Stream_Attribute_Available --
   --------------------------------

   function Stream_Attribute_Available
     (Typ          : Entity_Id;
      Nam          : TSS_Name_Type;
      Partial_View : Entity_Id := Empty) return Boolean
   is
      Etyp : Entity_Id := Typ;

   --  Start of processing for Stream_Attribute_Available

   begin
      --  We need some comments in this body ???

      if Has_Stream_Attribute_Definition (Typ, Nam) then
         return True;
      end if;

      if Is_Class_Wide_Type (Typ) then
         return not Is_Limited_Type (Typ)
           or else Stream_Attribute_Available (Etype (Typ), Nam);
      end if;

      if Nam = TSS_Stream_Input
        and then Is_Abstract_Type (Typ)
        and then not Is_Class_Wide_Type (Typ)
      then
         return False;
      end if;

      if not (Is_Limited_Type (Typ)
        or else (Present (Partial_View)
                   and then Is_Limited_Type (Partial_View)))
      then
         return True;
      end if;

      --  In Ada 2005, Input can invoke Read, and Output can invoke Write

      if Nam = TSS_Stream_Input
        and then Ada_Version >= Ada_2005
        and then Stream_Attribute_Available (Etyp, TSS_Stream_Read)
      then
         return True;

      elsif Nam = TSS_Stream_Output
        and then Ada_Version >= Ada_2005
        and then Stream_Attribute_Available (Etyp, TSS_Stream_Write)
      then
         return True;
      end if;

      --  Case of Read and Write: check for attribute definition clause that
      --  applies to an ancestor type.

      while Etype (Etyp) /= Etyp loop
         declare
            Derived_Type : constant Entity_Id := Etyp;
         begin
            Etyp := Etype (Etyp);

            if Has_Stream_Attribute_Definition (Etyp, Nam) then
               if not Derivation_Too_Early_To_Inherit (Derived_Type, Nam) then
                  return True;
               end if;
            end if;
         end;
      end loop;

      if Ada_Version < Ada_2005 then

         --  In Ada 95 mode, also consider a non-visible definition

         declare
            Btyp : constant Entity_Id := Implementation_Base_Type (Typ);
         begin
            return Btyp /= Typ
              and then Stream_Attribute_Available
                         (Btyp, Nam, Partial_View => Typ);
         end;
      end if;

      return False;
   end Stream_Attribute_Available;

end Sem_Attr;
