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

with Atree;          use Atree;
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 Lib;            use Lib;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Sem;            use Sem;
with Sem_Attr;       use Sem_Attr;
with Sem_Aux;        use Sem_Aux;
with Sem_Dist;       use Sem_Dist;
with Sem_Eval;       use Sem_Eval;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Snames;         use Snames;
with Stand;          use Stand;

package body Sem_Cat is

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

   procedure Check_Categorization_Dependencies
     (Unit_Entity     : Entity_Id;
      Depended_Entity : Entity_Id;
      Info_Node       : Node_Id;
      Is_Subunit      : Boolean);
   --  This procedure checks that the categorization of a lib unit and that
   --  of the depended unit satisfy dependency restrictions.
   --  The depended_entity can be the entity in a with_clause item, in which
   --  case Info_Node denotes that item. The depended_entity can also be the
   --  parent unit of a child unit, in which case Info_Node is the declaration
   --  of the child unit.  The error message is posted on Info_Node, and is
   --  specialized if Is_Subunit is true.

   procedure Check_Non_Static_Default_Expr
     (Type_Def : Node_Id;
      Obj_Decl : Node_Id);
   --  Iterate through the component list of a record definition, check
   --  that no component is declared with a nonstatic default value.
   --  If a nonstatic default exists, report an error on Obj_Decl.

   function Has_Read_Write_Attributes (E : Entity_Id) return Boolean;
   --  Return True if entity has attribute definition clauses for Read and
   --  Write attributes that are visible at some place.

   function Is_Non_Remote_Access_Type (E : Entity_Id) return Boolean;
   --  Returns true if the entity is a type whose full view is a non-remote
   --  access type, for the purpose of enforcing E.2.2(8) rules.

   function Has_Non_Remote_Access (Typ : Entity_Id) return Boolean;
   --  Return true if Typ or the type of any of its subcomponents is a non
   --  remote access type and doesn't have user-defined stream attributes.

   function No_External_Streaming (E : Entity_Id) return Boolean;
   --  Return True if the entity or one of its subcomponents does not support
   --  external streaming.

   function In_RCI_Declaration return Boolean;
   function In_RT_Declaration return Boolean;
   --  Determine if current scope is within the declaration of a Remote Call
   --  Interface or Remote Types unit, for semantic checking purposes.

   function In_Package_Declaration return Boolean;
   --  Shared supporting routine for In_RCI_Declaration and In_RT_Declaration

   function In_Shared_Passive_Unit return Boolean;
   --  Determines if current scope is within a Shared Passive compilation unit

   function Static_Discriminant_Expr (L : List_Id) return Boolean;
   --  Iterate through the list of discriminants to check if any of them
   --  contains non-static default expression, which is a violation in
   --  a preelaborated library unit.

   procedure Validate_Remote_Access_Object_Type_Declaration (T : Entity_Id);
   --  Check validity of declaration if RCI or RT unit. It should not contain
   --  the declaration of an access-to-object type unless it is a general
   --  access type that designates a class-wide limited private type. There are
   --  also constraints about the primitive subprograms of the class-wide type.
   --  RM E.2 (9, 13, 14)

   procedure Validate_RACW_Primitive
     (Subp : Entity_Id;
      RACW : Entity_Id);
   --  Check legality of the declaration of primitive Subp of the designated
   --  type of the given RACW type.

   ---------------------------------------
   -- Check_Categorization_Dependencies --
   ---------------------------------------

   procedure Check_Categorization_Dependencies
     (Unit_Entity     : Entity_Id;
      Depended_Entity : Entity_Id;
      Info_Node       : Node_Id;
      Is_Subunit      : Boolean)
   is
      N   : constant Node_Id := Info_Node;
      Err : Boolean;

      --  Here we define an enumeration type to represent categorization types,
      --  ordered so that a unit with a given categorization can only WITH
      --  units with lower or equal categorization type.

      type Categorization is
        (Pure,
         Shared_Passive,
         Remote_Types,
         Remote_Call_Interface,
         Normal);

      function Get_Categorization (E : Entity_Id) return Categorization;
      --  Check categorization flags from entity, and return in the form
      --  of the lowest value of the Categorization type that applies to E.

      ------------------------
      -- Get_Categorization --
      ------------------------

      function Get_Categorization (E : Entity_Id) return Categorization is
      begin
         --  Get the lowest categorization that corresponds to E. Note that
         --  nothing prevents several (different) categorization pragmas
         --  to apply to the same library unit, in which case the unit has
         --  all associated categories, so we need to be careful here to
         --  check pragmas in proper Categorization order in order to
         --  return the lowest applicable value.

         --  Ignore Pure specification if set by pragma Pure_Function

         if Is_Pure (E)
           and then not
            (Has_Pragma_Pure_Function (E) and not Has_Pragma_Pure (E))
         then
            return Pure;

         elsif Is_Shared_Passive (E) then
            return Shared_Passive;

         elsif Is_Remote_Types (E) then
            return Remote_Types;

         elsif Is_Remote_Call_Interface (E) then
            return Remote_Call_Interface;

         else
            return Normal;
         end if;
      end Get_Categorization;

      Unit_Category : Categorization;
      With_Category : Categorization;

   --  Start of processing for Check_Categorization_Dependencies

   begin
      --  Intrinsic subprograms are preelaborated, so do not impose any
      --  categorization dependencies. Also, ignore categorization
      --  dependencies when compilation switch -gnatdu is used.

      if Is_Intrinsic_Subprogram (Depended_Entity) or else Debug_Flag_U then
         return;
      end if;

      --  First check 10.2.1 (11/1) rules on preelaborate packages

      if Is_Preelaborated (Unit_Entity)
        and then not Is_Preelaborated (Depended_Entity)
        and then not Is_Pure (Depended_Entity)
      then
         Err := True;
      else
         Err := False;
      end if;

      --  Check categorization rules of RM E.2(5)

      Unit_Category := Get_Categorization (Unit_Entity);
      With_Category := Get_Categorization (Depended_Entity);

      if With_Category > Unit_Category then

         --  Special case: Remote_Types and Remote_Call_Interface are allowed
         --  to WITH anything in the package body, per (RM E.2(5)).

         if (Unit_Category = Remote_Types
              or else Unit_Category = Remote_Call_Interface)
           and then In_Package_Body (Unit_Entity)
         then
            null;

         --  Special case: Remote_Types and Remote_Call_Interface declarations
         --  can depend on a preelaborated unit via a private with_clause, per
         --  AI05-0206.

         elsif (Unit_Category = Remote_Types
                  or else
                Unit_Category = Remote_Call_Interface)
           and then Nkind (N) = N_With_Clause
           and then Private_Present (N)
           and then Is_Preelaborated (Depended_Entity)
         then
            null;

         --  All other cases, we do have an error

         else
            Err := True;
         end if;
      end if;

      --  Here if we have an error

      if Err then

         --  These messages are warnings in GNAT mode or if the -gnateP switch
         --  was set. Otherwise these are real errors for real illegalities.

         --  The reason we suppress these errors in GNAT mode is that the run-
         --  time has several instances of violations of the categorization
         --  errors (e.g. Pure units withing Preelaborate units. All these
         --  violations are harmless in the cases where we intend them, and
         --  we suppress the warnings with Warnings (Off). In cases where we
         --  do not intend the violation, warnings are errors in GNAT mode
         --  anyway, so we will still get an error.

         Error_Msg_Warn :=
           Treat_Categorization_Errors_As_Warnings or GNAT_Mode;

         --  Don't give error if main unit is not an internal unit, and the
         --  unit generating the message is an internal unit. This is the
         --  situation in which such messages would be ignored in any case,
         --  so it is convenient not to generate them (since it causes
         --  annoying interference with debugging).

         if Is_Internal_Unit (Current_Sem_Unit)
           and then not Is_Internal_Unit (Main_Unit)
         then
            return;

         --  Dependence of Remote_Types or Remote_Call_Interface declaration
         --  on a preelaborated unit with a normal with_clause.

         elsif (Unit_Category = Remote_Types
                  or else
                Unit_Category = Remote_Call_Interface)
           and then Is_Preelaborated (Depended_Entity)
         then
            Error_Msg_NE
              ("<<must use private with clause for preelaborated unit&",
               N, Depended_Entity);

         --  Subunit case

         elsif Is_Subunit then
            Error_Msg_NE
              ("<subunit cannot depend on& " &
               "(parent has wrong categorization)", N, Depended_Entity);

         --  Normal unit, not subunit

         else
            Error_Msg_NE
              ("<<cannot depend on& " &
               "(wrong categorization)", N, Depended_Entity);
         end if;

         --  Add further explanation for Pure/Preelaborate common cases

         if Unit_Category = Pure then
            Error_Msg_N
              ("\<<pure unit cannot depend on non-pure unit", N);

         elsif Is_Preelaborated (Unit_Entity)
           and then not Is_Preelaborated (Depended_Entity)
           and then not Is_Pure (Depended_Entity)
         then
            Error_Msg_N
              ("\<<preelaborated unit cannot depend on "
               & "non-preelaborated unit", N);
         end if;
      end if;
   end Check_Categorization_Dependencies;

   -----------------------------------
   -- Check_Non_Static_Default_Expr --
   -----------------------------------

   procedure Check_Non_Static_Default_Expr
     (Type_Def : Node_Id;
      Obj_Decl : Node_Id)
   is
      Recdef         : Node_Id;
      Component_Decl : Node_Id;

   begin
      if Nkind (Type_Def) = N_Derived_Type_Definition then
         Recdef := Record_Extension_Part (Type_Def);

         if No (Recdef) then
            return;
         end if;

      else
         Recdef := Type_Def;
      end if;

      --  Check that component declarations do not involve:

      --    a. a non-static default expression, where the object is
      --       declared to be default initialized.

      --    b. a dynamic Itype (discriminants and constraints)

      if Null_Present (Recdef) then
         return;
      else
         Component_Decl := First (Component_Items (Component_List (Recdef)));
      end if;

      while Present (Component_Decl)
        and then Nkind (Component_Decl) = N_Component_Declaration
      loop
         if Present (Expression (Component_Decl))
           and then Nkind (Expression (Component_Decl)) /= N_Null
           and then not Is_OK_Static_Expression (Expression (Component_Decl))

           --  If we're in a predefined unit, we can put whatever we like in a
           --  preelaborated package, and in fact in some cases it's necessary
           --  to bend the rules. Ada.Containers.Bounded_Hashed_Maps contains
           --  some code that would not be considered preelaborable in user
           --  code, for example.

           and then not In_Predefined_Unit (Component_Decl)
         then
            Error_Msg_Sloc := Sloc (Component_Decl);
            Error_Msg_F
              ("object in preelaborated unit has non-static default#",
               Obj_Decl);

         --  Fix this later ???

         --  elsif Has_Dynamic_Itype (Component_Decl) then
         --     Error_Msg_N
         --       ("dynamic type discriminant," &
         --        " constraint in preelaborated unit",
         --        Component_Decl);
         end if;

         Next (Component_Decl);
      end loop;
   end Check_Non_Static_Default_Expr;

   ---------------------------
   -- Has_Non_Remote_Access --
   ---------------------------

   function Has_Non_Remote_Access (Typ : Entity_Id) return Boolean is
      Component : Entity_Id;
      Comp_Type : Entity_Id;
      U_Typ     : constant Entity_Id := Underlying_Type (Typ);

   begin
      if No (U_Typ) then
         return False;

      elsif Has_Read_Write_Attributes (Typ)
        or else Has_Read_Write_Attributes (U_Typ)
      then
         return False;

      elsif Is_Non_Remote_Access_Type (U_Typ) then
         return True;
      end if;

      if Is_Record_Type (U_Typ) then
         Component := First_Entity (U_Typ);
         while Present (Component) loop
            if not Is_Tag (Component) then
               Comp_Type := Etype (Component);

               if Has_Non_Remote_Access (Comp_Type) then
                  return True;
               end if;
            end if;

            Next_Entity (Component);
         end loop;

      elsif Is_Array_Type (U_Typ) then
         return Has_Non_Remote_Access (Component_Type (U_Typ));

      end if;

      return False;
   end Has_Non_Remote_Access;

   -------------------------------
   -- Has_Read_Write_Attributes --
   -------------------------------

   function Has_Read_Write_Attributes (E : Entity_Id) return Boolean is
      Real_Rep : Node_Id;
   begin
      return True
        and then Has_Stream_Attribute_Definition
                   (E, TSS_Stream_Read, Real_Rep, At_Any_Place => True)
        and then Has_Stream_Attribute_Definition
                   (E, TSS_Stream_Write, Real_Rep, At_Any_Place => True);
   end Has_Read_Write_Attributes;

   -------------------------------------
   -- Has_Stream_Attribute_Definition --
   -------------------------------------

   function Has_Stream_Attribute_Definition
     (Typ          : Entity_Id;
      Nam          : TSS_Name_Type;
      Real_Rep     : out Node_Id;
      At_Any_Place : Boolean := False) return Boolean
   is
      Rep_Item : Node_Id;

   begin
      --  We start from the declaration node and then loop until the end of
      --  the list until we find the requested attribute definition clause.
      --  In Ada 2005 mode, clauses are ignored if they are not currently
      --  visible (this is tested using the corresponding Entity, which is
      --  inserted by the expander at the point where the clause occurs),
      --  unless At_Any_Place is true.

      Real_Rep := Empty;

      Rep_Item := First_Rep_Item (Typ);
      while Present (Rep_Item) loop
         Real_Rep := Rep_Item;

         --  If the representation item is an aspect specification, retrieve
         --  the corresponding pragma or attribute definition.

         if Nkind (Rep_Item) = N_Aspect_Specification then
            Real_Rep := Aspect_Rep_Item (Rep_Item);
         end if;

         if Nkind (Real_Rep) = N_Attribute_Definition_Clause then
            case Chars (Real_Rep) is
               when Name_Read =>
                  exit when Nam = TSS_Stream_Read;

               when Name_Write =>
                  exit when Nam = TSS_Stream_Write;

               when Name_Input =>
                  exit when Nam = TSS_Stream_Input;

               when Name_Output =>
                  exit when Nam = TSS_Stream_Output;

               when others =>
                  null;
            end case;
         end if;

         Next_Rep_Item (Rep_Item);
      end loop;

      --  If not found, and the type is derived from a private view, check
      --  for a stream attribute inherited from parent. Any specified stream
      --  attributes will be attached to the derived type's underlying type
      --  rather the derived type entity itself (which is itself private).

      if No (Rep_Item)
        and then Is_Private_Type (Typ)
        and then Is_Derived_Type (Typ)
        and then Present (Full_View (Typ))
      then
         return Has_Stream_Attribute_Definition
                  (Underlying_Type (Typ), Nam, Real_Rep, At_Any_Place);

      --  Otherwise, if At_Any_Place is true, return True if the attribute is
      --  available at any place; if it is false, return True only if the
      --  attribute is currently visible.

      else
         return Present (Rep_Item)
           and then (Ada_Version < Ada_2005
                      or else At_Any_Place
                      or else not Is_Hidden (Entity (Rep_Item)));
      end if;
   end Has_Stream_Attribute_Definition;

   ----------------------------
   -- In_Package_Declaration --
   ----------------------------

   function In_Package_Declaration return Boolean is
      Unit_Kind  : constant Node_Kind :=
                     Nkind (Unit (Cunit (Current_Sem_Unit)));

   begin
      --  There are no restrictions on the body of an RCI or RT unit

      return Is_Package_Or_Generic_Package (Current_Scope)
        and then Unit_Kind /= N_Package_Body
        and then not In_Package_Body (Current_Scope)
        and then not In_Instance;
   end In_Package_Declaration;

   ---------------------------
   -- In_Preelaborated_Unit --
   ---------------------------

   function In_Preelaborated_Unit return Boolean is
      Unit_Entity : Entity_Id := Current_Scope;
      Unit_Kind   : constant Node_Kind :=
                      Nkind (Unit (Cunit (Current_Sem_Unit)));

   begin
      --  If evaluating actuals for a child unit instantiation, then ignore
      --  the preelaboration status of the parent; use the child instead.

      if Is_Compilation_Unit (Unit_Entity)
        and then Unit_Kind in N_Generic_Instantiation
        and then not In_Same_Source_Unit (Unit_Entity,
                                          Cunit (Current_Sem_Unit))
      then
         Unit_Entity := Cunit_Entity (Current_Sem_Unit);
      end if;

      --  There are no constraints on the body of Remote_Call_Interface or
      --  Remote_Types packages.

      return (Unit_Entity /= Standard_Standard)
        and then (Is_Preelaborated (Unit_Entity)
                    or else Is_Pure (Unit_Entity)
                    or else Is_Shared_Passive (Unit_Entity)
                    or else
                      ((Is_Remote_Types (Unit_Entity)
                          or else Is_Remote_Call_Interface (Unit_Entity))
                         and then Ekind (Unit_Entity) = E_Package
                         and then Unit_Kind /= N_Package_Body
                         and then not In_Package_Body (Unit_Entity)
                         and then not In_Instance));
   end In_Preelaborated_Unit;

   ------------------
   -- In_Pure_Unit --
   ------------------

   function In_Pure_Unit return Boolean is
   begin
      return Is_Pure (Current_Scope);
   end In_Pure_Unit;

   ------------------------
   -- In_RCI_Declaration --
   ------------------------

   function In_RCI_Declaration return Boolean is
   begin
      return Is_Remote_Call_Interface (Current_Scope)
        and then In_Package_Declaration;
   end In_RCI_Declaration;

   -----------------------
   -- In_RT_Declaration --
   -----------------------

   function In_RT_Declaration return Boolean is
   begin
      return Is_Remote_Types (Current_Scope) and then In_Package_Declaration;
   end In_RT_Declaration;

   ----------------------------
   -- In_Shared_Passive_Unit --
   ----------------------------

   function In_Shared_Passive_Unit return Boolean is
      Unit_Entity : constant Entity_Id := Current_Scope;

   begin
      return Is_Shared_Passive (Unit_Entity);
   end In_Shared_Passive_Unit;

   ---------------------------------------
   -- In_Subprogram_Task_Protected_Unit --
   ---------------------------------------

   function In_Subprogram_Task_Protected_Unit return Boolean is
      E : Entity_Id;

   begin
      --  The following is to verify that a declaration is inside
      --  subprogram, generic subprogram, task unit, protected unit.
      --  Used to validate if a lib. unit is Pure. RM 10.2.1(16).

      --  Use scope chain to check successively outer scopes

      E := Current_Scope;
      loop
         if Is_Subprogram_Or_Generic_Subprogram (E)
              or else
            Is_Concurrent_Type (E)
         then
            return True;

         elsif E = Standard_Standard then
            return False;
         end if;

         E := Scope (E);
      end loop;
   end In_Subprogram_Task_Protected_Unit;

   -------------------------------
   -- Is_Non_Remote_Access_Type --
   -------------------------------

   function Is_Non_Remote_Access_Type (E : Entity_Id) return Boolean is
      U_E : constant Entity_Id := Underlying_Type (Base_Type (E));
      --  Use full view of base type to handle subtypes properly.

   begin
      if No (U_E) then

         --  This case arises for the case of a generic formal type, in which
         --  case E.2.2(8) rules will be enforced at instantiation time.

         return False;
      end if;

      return Is_Access_Type (U_E)
        and then not Is_Remote_Access_To_Class_Wide_Type (U_E)
        and then not Is_Remote_Access_To_Subprogram_Type (U_E);
   end Is_Non_Remote_Access_Type;

   ---------------------------
   -- No_External_Streaming --
   ---------------------------

   function No_External_Streaming (E : Entity_Id) return Boolean is
      U_E : constant Entity_Id := Underlying_Type (E);

   begin
      if No (U_E) then
         return False;

      elsif Has_Read_Write_Attributes (E) then

         --  Note: availability of stream attributes is tested on E, not U_E.
         --  There may be stream attributes defined on U_E that are not visible
         --  at the place where support of external streaming is tested.

         return False;

      elsif Has_Non_Remote_Access (U_E) then
         return True;
      end if;

      return Is_Limited_Type (E);
   end No_External_Streaming;

   -------------------------------------
   -- Set_Categorization_From_Pragmas --
   -------------------------------------

   procedure Set_Categorization_From_Pragmas (N : Node_Id) is
      P : constant Node_Id := Parent (N);

      procedure Make_Parents_Visible_And_Process_Pragmas (Par : Entity_Id);
      --  Parents might not be immediately visible during analysis. Make
      --  them momentarily visible so that the argument of the pragma can
      --  be resolved properly, process pragmas and restore the previous
      --  visibility.

      procedure Process_Categorization_Pragmas;
      --  Process categorization pragmas, if any

      ------------------------------------
      -- Process_Categorization_Pragmas --
      ------------------------------------

      procedure Process_Categorization_Pragmas is
         PN : Node_Id;

      begin
         PN := First (Pragmas_After (Aux_Decls_Node (P)));
         while Present (PN) loop

            --  Skip implicit types that may have been introduced by
            --  previous analysis.

            if Nkind (PN) = N_Pragma then
               case Get_Pragma_Id (PN) is
                  when Pragma_All_Calls_Remote
                     | Pragma_Preelaborate
                     | Pragma_Pure
                     | Pragma_Remote_Call_Interface
                     | Pragma_Remote_Types
                     | Pragma_Shared_Passive
                  =>
                     Analyze (PN);

                  when others =>
                     null;
               end case;
            end if;

            Next (PN);
         end loop;
      end Process_Categorization_Pragmas;

      ----------------------------------------------
      -- Make_Parents_Visible_And_Process_Pragmas --
      ----------------------------------------------

      procedure Make_Parents_Visible_And_Process_Pragmas (Par : Entity_Id) is
      begin
         --  When we reached the Standard scope, then just process pragmas

         if Par = Standard_Standard then
            Process_Categorization_Pragmas;

         --  Otherwise make the current scope momentarily visible, recurse
         --  into its enclosing scope, and restore the visibility. This is
         --  required for child units that are instances of generic parents.

         else
            declare
               Save_Is_Immediately_Visible : constant Boolean :=
                 Is_Immediately_Visible (Par);
            begin
               Set_Is_Immediately_Visible (Par);
               Make_Parents_Visible_And_Process_Pragmas (Scope (Par));
               Set_Is_Immediately_Visible (Par, Save_Is_Immediately_Visible);
            end;
         end if;
      end Make_Parents_Visible_And_Process_Pragmas;

   --  Start of processing for Set_Categorization_From_Pragmas

   begin
      --  Deal with categorization pragmas in Pragmas of Compilation_Unit.
      --  The purpose is to set categorization flags before analyzing the
      --  unit itself, so as to diagnose violations of categorization as
      --  we process each declaration, even though the pragma appears after
      --  the unit.

      if Nkind (P) /= N_Compilation_Unit then
         return;
      end if;

      Make_Parents_Visible_And_Process_Pragmas (Scope (Current_Scope));
   end Set_Categorization_From_Pragmas;

   -----------------------------------
   -- Set_Categorization_From_Scope --
   -----------------------------------

   procedure Set_Categorization_From_Scope (E : Entity_Id; Scop : Entity_Id) is
      Declaration   : Node_Id := Empty;
      Specification : Node_Id := Empty;

   begin
      --  Do not modify the purity of an internally generated entity if it has
      --  been explicitly marked as pure for optimization purposes.

      if not Has_Pragma_Pure_Function (E) then
         Set_Is_Pure
           (E, Is_Pure (Scop) and then Is_Library_Level_Entity (E));
      end if;

      if not Is_Remote_Call_Interface (E) then
         if Is_Subprogram (E) then
            Declaration := Unit_Declaration_Node (E);

            if Nkind (Declaration) in
                 N_Subprogram_Body | N_Subprogram_Renaming_Declaration
            then
               Specification := Corresponding_Spec (Declaration);
            end if;
         end if;

         --  A subprogram body or renaming-as-body is a remote call interface
         --  if it serves as the completion of a subprogram declaration that
         --  is a remote call interface.

         if Nkind (Specification) in N_Entity then
            Set_Is_Remote_Call_Interface
              (E, Is_Remote_Call_Interface (Specification));

         --  A subprogram declaration is a remote call interface when it is
         --  declared within the visible part of, or declared by, a library
         --  unit declaration that is a remote call interface.

         else
            Set_Is_Remote_Call_Interface
              (E, Is_Remote_Call_Interface (Scop)
                    and then not (In_Private_Part (Scop)
                                   or else In_Package_Body (Scop)));
         end if;
      end if;

      Set_Is_Remote_Types
        (E, Is_Remote_Types (Scop)
              and then not (In_Private_Part (Scop)
                             or else In_Package_Body (Scop)));
   end Set_Categorization_From_Scope;

   ------------------------------
   -- Static_Discriminant_Expr --
   ------------------------------

   --  We need to accommodate a Why_Not_Static call somehow here ???

   function Static_Discriminant_Expr (L : List_Id) return Boolean is
      Discriminant_Spec : Node_Id;

   begin
      Discriminant_Spec := First (L);
      while Present (Discriminant_Spec) loop
         if Present (Expression (Discriminant_Spec))
           and then
             not Is_OK_Static_Expression (Expression (Discriminant_Spec))
         then
            return False;
         end if;

         Next (Discriminant_Spec);
      end loop;

      return True;
   end Static_Discriminant_Expr;

   --------------------------------------
   -- Validate_Access_Type_Declaration --
   --------------------------------------

   procedure Validate_Access_Type_Declaration (T : Entity_Id; N : Node_Id) is
      Def : constant Node_Id := Type_Definition (N);

   begin
      case Nkind (Def) is

         --  Access to subprogram case

         when N_Access_To_Subprogram_Definition =>

            --  A pure library_item must not contain the declaration of a
            --  named access type, except within a subprogram, generic
            --  subprogram, task unit, or protected unit (RM 10.2.1(16)).

            --  This test is skipped in Ada 2005 (see AI-366)

            if Ada_Version < Ada_2005
              and then Comes_From_Source (T)
              and then In_Pure_Unit
              and then not In_Subprogram_Task_Protected_Unit
            then
               Error_Msg_N ("named access type not allowed in pure unit", T);
            end if;

         --  Access to object case

         when N_Access_To_Object_Definition =>
            if Comes_From_Source (T)
              and then In_Pure_Unit
              and then not In_Subprogram_Task_Protected_Unit
            then
               --  We can't give the message yet, since the type is not frozen
               --  and in Ada 2005 mode, access types are allowed in pure units
               --  if the type has no storage pool (see AI-366). So we set a
               --  flag which will be checked at freeze time.

               Set_Is_Pure_Unit_Access_Type (T);
            end if;

            --  Check for RCI or RT unit type declaration: declaration of an
            --  access-to-object type is illegal unless it is a general access
            --  type that designates a class-wide limited private type.
            --  Note that constraints on the primitive subprograms of the
            --  designated tagged type are not enforced here but in
            --  Validate_RACW_Primitives, which is done separately because the
            --  designated type might not be frozen (and therefore its
            --  primitive operations might not be completely known) at the
            --  point of the RACW declaration.

            Validate_Remote_Access_Object_Type_Declaration (T);

            --  Check for shared passive unit type declaration. It should
            --  not contain the declaration of access to class wide type,
            --  access to task type and access to protected type with entry.

            Validate_SP_Access_Object_Type_Decl (T);

         when others =>
            null;
      end case;

      --  Set categorization flag from package on entity as well, to allow
      --  easy checks later on for required validations of RCI or RT units.
      --  This is only done for entities that are in the original source.

      if Comes_From_Source (T)
        and then not (In_Package_Body (Scope (T))
                       or else In_Private_Part (Scope (T)))
      then
         Set_Is_Remote_Call_Interface
           (T, Is_Remote_Call_Interface (Scope (T)));
         Set_Is_Remote_Types
           (T, Is_Remote_Types (Scope (T)));
      end if;
   end Validate_Access_Type_Declaration;

   ----------------------------
   -- Validate_Ancestor_Part --
   ----------------------------

   procedure Validate_Ancestor_Part (N : Node_Id) is
      A : constant Node_Id   := Ancestor_Part (N);
      T : constant Entity_Id := Entity (A);

   begin
      if In_Preelaborated_Unit
        and then not In_Subprogram_Or_Concurrent_Unit
        and then (not Inside_A_Generic
                   or else Present (Enclosing_Generic_Body (N)))
      then
         --  If the type is private, it must have the Ada 2005 pragma
         --  Has_Preelaborable_Initialization.

         --  The check is omitted within predefined units. This is probably
         --  obsolete code to fix the Ada 95 weakness in this area ???

         if Is_Private_Type (T)
           and then not Has_Pragma_Preelab_Init (T)
           and then not In_Internal_Unit (N)
         then
            Error_Msg_N
              ("private ancestor type not allowed in preelaborated unit", A);

         elsif Is_Record_Type (T) then
            if Nkind (Parent (T)) = N_Full_Type_Declaration then
               Check_Non_Static_Default_Expr
                 (Type_Definition (Parent (T)), A);
            end if;
         end if;
      end if;
   end Validate_Ancestor_Part;

   ----------------------------------------
   -- Validate_Categorization_Dependency --
   ----------------------------------------

   procedure Validate_Categorization_Dependency
     (N : Node_Id;
      E : Entity_Id)
   is
      K          : constant Node_Kind := Nkind (N);
      P          : Node_Id            := Parent (N);
      U          : Entity_Id := E;
      Is_Subunit : constant Boolean := Nkind (P) = N_Subunit;

   begin
      --  Only validate library units and subunits. For subunits, checks
      --  concerning withed units apply to the parent compilation unit.

      if Is_Subunit then
         P := Parent (P);
         U := Scope (E);

         while Present (U)
           and then not Is_Compilation_Unit (U)
           and then not Is_Child_Unit (U)
         loop
            U := Scope (U);
         end loop;
      end if;

      if Nkind (P) /= N_Compilation_Unit then
         return;
      end if;

      --  Body of RCI unit does not need validation

      if Is_Remote_Call_Interface (E)
        and then Nkind (N) in N_Package_Body | N_Subprogram_Body
      then
         return;
      end if;

      --  Ada 2005 (AI-50217): Process explicit non-limited with_clauses

      declare
         Item             : Node_Id;
         Entity_Of_Withed : Entity_Id;

      begin
         Item := First (Context_Items (P));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause
              and then
                not (Implicit_With (Item)
                      or else Limited_Present (Item)

                      --  Skip if error already posted on the WITH clause (in
                      --  which case the Name attribute may be invalid). In
                      --  particular, this fixes the problem of hanging in the
                      --  presence of a WITH clause on a child that is an
                      --  illegal generic instantiation.

                      or else Error_Posted (Item))
              and then
                not (Try_Semantics

                      --  Skip processing malformed trees

                      and then Nkind (Name (Item)) not in N_Has_Entity)
            then
               Entity_Of_Withed := Entity (Name (Item));
               Check_Categorization_Dependencies
                 (U, Entity_Of_Withed, Item, Is_Subunit);
            end if;

            Next (Item);
         end loop;
      end;

      --  Child depends on parent; therefore parent should also be categorized
      --  and satisfy the dependency hierarchy.

      --  Check if N is a child spec

      if (K in N_Generic_Declaration              or else
          K in N_Generic_Instantiation            or else
          K in N_Generic_Renaming_Declaration     or else
          K =  N_Package_Declaration              or else
          K =  N_Package_Renaming_Declaration     or else
          K =  N_Subprogram_Declaration           or else
          K =  N_Subprogram_Renaming_Declaration)
        and then Present (Parent_Spec (N))
      then
         Check_Categorization_Dependencies (E, Scope (E), N, False);

         --  Verify that public child of an RCI library unit must also be an
         --  RCI library unit (RM E.2.3(15)).

         if Is_Remote_Call_Interface (Scope (E))
           and then not Private_Present (P)
           and then not Is_Remote_Call_Interface (E)
         then
            Error_Msg_N
              ("public child of 'R'C'I unit must also be 'R'C'I unit", N);
         end if;
      end if;
   end Validate_Categorization_Dependency;

   --------------------------------
   -- Validate_Controlled_Object --
   --------------------------------

   procedure Validate_Controlled_Object (E : Entity_Id) is
   begin
      --  Don't need this check in Ada 2005 mode, where this is all taken
      --  care of by the mechanism for Preelaborable Initialization.

      if Ada_Version >= Ada_2005 then
         return;
      end if;

      --  For now, never apply this check for internal GNAT units, since we
      --  have a number of cases in the library where we are stuck with objects
      --  of this type, and the RM requires Preelaborate.

      --  For similar reasons, we only do this check for source entities, since
      --  we generate entities of this type in some situations.

      --  Note that the 10.2.1(9) restrictions are not relevant to us anyway.
      --  We have to enforce them for RM compatibility, but we have no trouble
      --  accepting these objects and doing the right thing. Note that there is
      --  no requirement that Preelaborate not actually generate any code.

      if In_Preelaborated_Unit
        and then not Debug_Flag_PP
        and then Comes_From_Source (E)
        and then not In_Internal_Unit (E)
        and then (not Inside_A_Generic
                   or else Present (Enclosing_Generic_Body (E)))
        and then not Is_Protected_Type (Etype (E))
      then
         Error_Msg_N
           ("library level controlled object not allowed in " &
            "preelaborated unit", E);
      end if;
   end Validate_Controlled_Object;

   --------------------------------------
   -- Validate_Null_Statement_Sequence --
   --------------------------------------

   procedure Validate_Null_Statement_Sequence (N : Node_Id) is
      Item : Node_Id;

   begin
      if In_Preelaborated_Unit then
         Item := First (Statements (Handled_Statement_Sequence (N)));
         while Present (Item) loop
            if Nkind (Item) /= N_Label
              and then Nkind (Item) /= N_Null_Statement
            then
               --  In GNAT mode, this is a warning, allowing the run-time
               --  to judiciously bypass this error condition.

               Error_Msg_Warn := GNAT_Mode;
               Error_Msg_N
                 ("<<statements not allowed in preelaborated unit", Item);

               exit;
            end if;

            Next (Item);
         end loop;
      end if;
   end Validate_Null_Statement_Sequence;

   ---------------------------------
   -- Validate_Object_Declaration --
   ---------------------------------

   procedure Validate_Object_Declaration (N : Node_Id) is
      Id  : constant Entity_Id  := Defining_Identifier (N);
      E   : constant Node_Id    := Expression (N);
      Odf : constant Node_Id    := Object_Definition (N);
      T   : constant Entity_Id  := Etype (Id);

   begin
      --  Verify that any access to subprogram object does not have in its
      --  subprogram profile access type parameters or limited parameters
      --  without Read and Write attributes (E.2.3(13)).

      Validate_RCI_Subprogram_Declaration (N);

      --  Check that if we are in preelaborated elaboration code, then we
      --  do not have an instance of a default initialized private, task or
      --  protected object declaration which would violate (RM 10.2.1(9)).
      --  Note that constants are never default initialized (and the test
      --  below also filters out deferred constants). A variable is default
      --  initialized if it does *not* have an initialization expression.

      --  Filter out cases that are not declaration of a variable from source

      if Nkind (N) /= N_Object_Declaration
        or else Constant_Present (N)
        or else not Comes_From_Source (Id)
      then
         return;
      end if;

      --  Exclude generic specs from the checks (this will get rechecked
      --  on instantiations).

      if Inside_A_Generic and then No (Enclosing_Generic_Body (Id)) then
         return;
      end if;

      --  Required checks for declaration that is in a preelaborated package
      --  and is not within some subprogram.

      if In_Preelaborated_Unit
        and then not In_Subprogram_Or_Concurrent_Unit
      then
         --  Check for default initialized variable case. Note that in
         --  accordance with (RM B.1(24)) imported objects are not subject to
         --  default initialization.
         --  If the initialization does not come from source and is an
         --  aggregate, it is a static initialization that replaces an
         --  implicit call, and must be treated as such.

         if Present (E)
           and then (Comes_From_Source (E) or else Nkind (E) /= N_Aggregate)
         then
            null;

         elsif Is_Imported (Id) then
            null;

         else
            declare
               Ent : Entity_Id := T;

            begin
               --  An array whose component type is a record with nonstatic
               --  default expressions is a violation, so we get the array's
               --  component type.

               if Is_Array_Type (Ent) then
                  declare
                     Comp_Type : Entity_Id;

                  begin
                     Comp_Type := Component_Type (Ent);
                     while Is_Array_Type (Comp_Type) loop
                        Comp_Type := Component_Type (Comp_Type);
                     end loop;

                     Ent := Comp_Type;
                  end;
               end if;

               --  Object decl. that is of record type and has no default expr.
               --  should check if there is any non-static default expression
               --  in component decl. of the record type decl.

               if Is_Record_Type (Ent) then
                  if Nkind (Parent (Ent)) = N_Full_Type_Declaration then
                     Check_Non_Static_Default_Expr
                       (Type_Definition (Parent (Ent)), N);

                  elsif Nkind (Odf) = N_Subtype_Indication
                    and then not Is_Array_Type (T)
                    and then not Is_Private_Type (T)
                  then
                     Check_Non_Static_Default_Expr (Type_Definition
                       (Parent (Entity (Subtype_Mark (Odf)))), N);
                  end if;
               end if;

               --  Check for invalid use of private object. Note that Ada 2005
               --  AI-161 modifies the rules for Ada 2005, including the use of
               --  the new pragma Preelaborable_Initialization.

               if Is_Private_Type (Ent)
                 or else Depends_On_Private (Ent)
               then
                  --  Case where type has preelaborable initialization which
                  --  means that a pragma Preelaborable_Initialization was
                  --  given for the private type.

                  if Relaxed_RM_Semantics then

                     --  In relaxed mode, do not issue these messages, this
                     --  is basically similar to the GNAT_Mode test below.

                     null;

                  elsif Has_Preelaborable_Initialization (Ent) then

                     --  But for the predefined units, we will ignore this
                     --  status unless we are in Ada 2005 mode since we want
                     --  Ada 95 compatible behavior, in which the entities
                     --  marked with this pragma in the predefined library are
                     --  not treated specially.

                     if Ada_Version < Ada_2005 then
                        Error_Msg_N
                          ("private object not allowed in preelaborated unit",
                           N);
                        Error_Msg_N ("\(would be legal in Ada 2005 mode)", N);
                     end if;

                  --  Type does not have preelaborable initialization

                  else
                     --  We allow this when compiling in GNAT mode to make life
                     --  easier for some cases where it would otherwise be hard
                     --  to be exactly valid Ada.

                     if not GNAT_Mode then
                        Error_Msg_N
                          ("private object not allowed in preelaborated unit",
                           N);

                        --  Add a message if it would help to provide a pragma
                        --  Preelaborable_Initialization on the type of the
                        --  object (which would make it legal in Ada 2005).

                        --  If the type has no full view (generic type, or
                        --  previous error), the warning does not apply.

                        if Is_Private_Type (Ent)
                          and then Present (Full_View (Ent))
                          and then
                            Has_Preelaborable_Initialization (Full_View (Ent))
                        then
                           Error_Msg_Sloc := Sloc (Ent);

                           if Ada_Version >= Ada_2005 then
                              Error_Msg_NE
                                ("\would be legal if pragma Preelaborable_" &
                                 "Initialization given for & #", N, Ent);
                           else
                              Error_Msg_NE
                                ("\would be legal in Ada 2005 if pragma " &
                                 "Preelaborable_Initialization given for & #",
                                 N, Ent);
                           end if;
                        end if;
                     end if;
                  end if;

               --  Access to Task or Protected type

               elsif Is_Entity_Name (Odf)
                 and then Present (Etype (Odf))
                 and then Is_Access_Type (Etype (Odf))
               then
                  Ent := Designated_Type (Etype (Odf));

               elsif Is_Entity_Name (Odf) then
                  Ent := Entity (Odf);

               elsif Nkind (Odf) = N_Subtype_Indication then
                  Ent := Etype (Subtype_Mark (Odf));

               elsif Nkind (Odf) = N_Constrained_Array_Definition then
                  Ent := Component_Type (T);
               end if;

               if Is_Task_Type (Ent)
                 or else (Is_Protected_Type (Ent) and then Has_Entries (Ent))
               then
                  Error_Msg_N
                    ("concurrent object not allowed in preelaborated unit",
                     N);
                  return;
               end if;
            end;
         end if;

         --  Non-static discriminants not allowed in preelaborated unit.
         --  Objects of a controlled type with a user-defined Initialize
         --  are forbidden as well.

         if Is_Record_Type (Etype (Id)) then
            declare
               ET  : constant Entity_Id := Etype (Id);
               EE  : constant Entity_Id := Etype (Etype (Id));
               PEE : Node_Id;

            begin
               if Has_Discriminants (ET) and then Present (EE) then
                  PEE := Parent (EE);

                  if Nkind (PEE) = N_Full_Type_Declaration
                    and then not Static_Discriminant_Expr
                                   (Discriminant_Specifications (PEE))
                  then
                     Error_Msg_N
                       ("non-static discriminant in preelaborated unit",
                        PEE);
                  end if;
               end if;

               --  For controlled type or type with controlled component, check
               --  preelaboration flag, as there may be a non-null Initialize
               --  primitive. For language versions earlier than Ada 2005,
               --  there is no notion of preelaborable initialization, and
               --  Validate_Controlled_Object is used to enforce rules for
               --  controlled objects.

               if (Is_Controlled (ET) or else Has_Controlled_Component (ET))
                    and then Ada_Version >= Ada_2005
                    and then not Has_Preelaborable_Initialization (ET)
               then
                  Error_Msg_NE
                    ("controlled type& does not have"
                      & " preelaborable initialization", N, ET);
               end if;
            end;

         end if;
      end if;

      --  A pure library_item must not contain the declaration of any variable
      --  except within a subprogram, generic subprogram, task unit, or
      --  protected unit (RM 10.2.1(16)).

      if In_Pure_Unit and then not In_Subprogram_Task_Protected_Unit then
         Error_Msg_N ("declaration of variable not allowed in pure unit", N);

      elsif not In_Private_Part (Id) then

         --  The visible part of an RCI library unit must not contain the
         --  declaration of a variable (RM E.1.3(9)).

         if In_RCI_Declaration then
            Error_Msg_N ("visible variable not allowed in 'R'C'I unit", N);

         --  The visible part of a Shared Passive library unit must not contain
         --  the declaration of a variable (RM E.2.2(7)).

         elsif In_RT_Declaration then
            Error_Msg_N
              ("visible variable not allowed in remote types unit", N);
         end if;
      end if;
   end Validate_Object_Declaration;

   -----------------------------
   -- Validate_RACW_Primitive --
   -----------------------------

   procedure Validate_RACW_Primitive
     (Subp : Entity_Id;
      RACW : Entity_Id)
   is
      procedure Illegal_Remote_Subp (Msg : String; N : Node_Id);
      --  Diagnose illegality on N. If RACW is present, report the error on it
      --  rather than on N.

      -------------------------
      -- Illegal_Remote_Subp --
      -------------------------

      procedure Illegal_Remote_Subp (Msg : String; N : Node_Id) is
      begin
         if Present (RACW) then
            if not Error_Posted (RACW) then
               Error_Msg_N
                 ("illegal remote access to class-wide type&", RACW);
            end if;

            Error_Msg_Sloc := Sloc (N);
            Error_Msg_NE ("\\" & Msg & " in primitive& #", RACW, Subp);

         else
            Error_Msg_NE (Msg & " in remote subprogram&", N, Subp);
         end if;
      end Illegal_Remote_Subp;

      Rtyp       : Entity_Id;
      Param      : Node_Id;
      Param_Spec : Node_Id;
      Param_Type : Entity_Id;

   --  Start of processing for Validate_RACW_Primitive

   begin
      --  Check return type

      if Ekind (Subp) = E_Function then
         Rtyp := Etype (Subp);

         --  AI05-0101 (Binding Interpretation): The result type of a remote
         --  function must either support external streaming or be a
         --  controlling access result type.

         if Has_Controlling_Result (Subp) then
            null;

         elsif Ekind (Rtyp) = E_Anonymous_Access_Type then
            Illegal_Remote_Subp ("anonymous access result", Rtyp);

         elsif Is_Limited_Type (Rtyp) then
            if No (TSS (Rtyp, TSS_Stream_Read))
                 or else
               No (TSS (Rtyp, TSS_Stream_Write))
            then
               Illegal_Remote_Subp
                 ("limited return type must have Read and Write attributes",
                     Parent (Subp));
               Explain_Limited_Type (Rtyp, Parent (Subp));
            end if;

         --  Check that the return type supports external streaming

         elsif No_External_Streaming (Rtyp)
           and then not Error_Posted (Rtyp)
         then
            Illegal_Remote_Subp ("return type containing non-remote access "
              & "must have Read and Write attributes",
              Parent (Subp));
         end if;
      end if;

      Param := First_Formal (Subp);
      while Present (Param) loop

         --  Now find out if this parameter is a controlling parameter

         Param_Spec := Parent (Param);
         Param_Type := Etype (Param);

         if Is_Controlling_Formal (Param) then

            --  It is a controlling parameter, so specific checks below do not
            --  apply.

            null;

         elsif Ekind (Param_Type) in E_Anonymous_Access_Type
                                   | E_Anonymous_Access_Subprogram_Type
         then
            --  From RM E.2.2(14), no anonymous access parameter other than
            --  controlling ones may be used (because an anonymous access
            --  type never supports external streaming).

            Illegal_Remote_Subp
              ("non-controlling access parameter", Param_Spec);

         elsif No_External_Streaming (Param_Type)
            and then not Error_Posted (Param_Type)
         then
            Illegal_Remote_Subp ("formal parameter in remote subprogram must "
              & "support external streaming", Param_Spec);
         end if;

         --  Check next parameter in this subprogram

         Next_Formal (Param);
      end loop;
   end Validate_RACW_Primitive;

   ------------------------------
   -- Validate_RACW_Primitives --
   ------------------------------

   procedure Validate_RACW_Primitives (T : Entity_Id) is
      Desig_Type             : Entity_Id;
      Primitive_Subprograms  : Elist_Id;
      Subprogram_Elmt        : Elmt_Id;
      Subprogram             : Entity_Id;

   begin
      Desig_Type := Etype (Designated_Type (T));

      --  No action needed for concurrent types

      if Is_Concurrent_Type (Desig_Type) then
         return;
      end if;

      Primitive_Subprograms := Primitive_Operations (Desig_Type);

      Subprogram_Elmt := First_Elmt (Primitive_Subprograms);
      while Subprogram_Elmt /= No_Elmt loop
         Subprogram := Node (Subprogram_Elmt);

         if Is_Predefined_Dispatching_Operation (Subprogram)
           or else Is_Hidden (Subprogram)
         then
            goto Next_Subprogram;
         end if;

         Validate_RACW_Primitive (Subp => Subprogram, RACW => T);

      <<Next_Subprogram>>
         Next_Elmt (Subprogram_Elmt);
      end loop;
   end Validate_RACW_Primitives;

   -------------------------------
   -- Validate_RCI_Declarations --
   -------------------------------

   procedure Validate_RCI_Declarations (P : Entity_Id) is
      E : Entity_Id;

   begin
      E := First_Entity (P);
      while Present (E) loop
         if Comes_From_Source (E) then
            if Is_Limited_Type (E) then
               Error_Msg_N
                 ("limited type not allowed in 'R'C'I unit", Parent (E));
               Explain_Limited_Type (E, Parent (E));

            elsif Ekind (E) in E_Generic_Function
                             | E_Generic_Package
                             | E_Generic_Procedure
            then
               Error_Msg_N ("generic declaration not allowed in 'R'C'I unit",
                 Parent (E));

            elsif (Ekind (E) = E_Function or else Ekind (E) = E_Procedure)
              and then Has_Pragma_Inline (E)
            then
               Error_Msg_N
                 ("inlined subprogram not allowed in 'R'C'I unit", Parent (E));

            --  Inner packages that are renamings need not be checked. Generic
            --  RCI packages are subject to the checks, but entities that come
            --  from formal packages are not part of the visible declarations
            --  of the package and are not checked.

            elsif Ekind (E) = E_Package then
               if Present (Renamed_Entity (E)) then
                  null;

               elsif Ekind (P) /= E_Generic_Package
                 or else List_Containing (Unit_Declaration_Node (E)) /=
                           Generic_Formal_Declarations
                             (Unit_Declaration_Node (P))
               then
                  Validate_RCI_Declarations (E);
               end if;
            end if;
         end if;

         Next_Entity (E);
      end loop;
   end Validate_RCI_Declarations;

   -----------------------------------------
   -- Validate_RCI_Subprogram_Declaration --
   -----------------------------------------

   procedure Validate_RCI_Subprogram_Declaration (N : Node_Id) is
      K               : constant Node_Kind := Nkind (N);
      Profile         : List_Id;
      Id              : constant Entity_Id := Defining_Entity (N);
      Param_Spec      : Node_Id;
      Param_Type      : Entity_Id;
      Error_Node      : Node_Id := N;

   begin
      --  This procedure enforces rules on subprogram and access to subprogram
      --  declarations in RCI units. These rules do not apply to expander
      --  generated routines, which are not remote subprograms. It is called:

      --    1. from Analyze_Subprogram_Declaration.
      --    2. from Validate_Object_Declaration (access to subprogram).

      if not (Comes_From_Source (N)
                and then In_RCI_Declaration
                and then not In_Private_Part (Scope (Id)))
      then
         return;
      end if;

      if K = N_Subprogram_Declaration then
         Profile := Parameter_Specifications (Specification (N));

      else
         pragma Assert (K = N_Object_Declaration);

         --  The above assertion is dubious, the visible declarations of an
         --  RCI unit never contain an object declaration, this should be an
         --  ACCESS-to-object declaration???

         if Nkind (Id) = N_Defining_Identifier
           and then Nkind (Parent (Etype (Id))) = N_Full_Type_Declaration
           and then Ekind (Etype (Id)) = E_Access_Subprogram_Type
         then
            Profile :=
              Parameter_Specifications (Type_Definition (Parent (Etype (Id))));
         else
            return;
         end if;
      end if;

      --  Iterate through the parameter specification list, checking that
      --  no access parameter and no limited type parameter in the list.
      --  RM E.2.3(14).

      if Present (Profile) then
         Param_Spec := First (Profile);
         while Present (Param_Spec) loop
            Param_Type := Etype (Defining_Identifier (Param_Spec));

            if Ekind (Param_Type) = E_Anonymous_Access_Type then
               if K = N_Subprogram_Declaration then
                  Error_Node := Param_Spec;
               end if;

               --  Report error only if declaration is in source program

               if Comes_From_Source (Id) then
                  Error_Msg_N
                    ("subprogram in 'R'C'I unit cannot have access parameter",
                     Error_Node);
               end if;

            --  For a limited private type parameter, we check only the private
            --  declaration and ignore full type declaration, unless this is
            --  the only declaration for the type, e.g., as a limited record.

            elsif No_External_Streaming (Param_Type) then
               if K = N_Subprogram_Declaration then
                  Error_Node := Param_Spec;
               end if;

               Error_Msg_NE
                 ("formal of remote subprogram& "
                  & "must support external streaming",
                  Error_Node, Id);
               if Is_Limited_Type (Param_Type) then
                  Explain_Limited_Type (Param_Type, Error_Node);
               end if;
            end if;

            Next (Param_Spec);
         end loop;
      end if;

      if Ekind (Id) = E_Function
        and then Ekind (Etype (Id)) = E_Anonymous_Access_Type
        and then Comes_From_Source (Id)
      then
         Error_Msg_N
           ("function in 'R'C'I unit cannot have access result",
             Error_Node);
      end if;
   end Validate_RCI_Subprogram_Declaration;

   ----------------------------------------------------
   -- Validate_Remote_Access_Object_Type_Declaration --
   ----------------------------------------------------

   procedure Validate_Remote_Access_Object_Type_Declaration (T : Entity_Id) is
      Direct_Designated_Type : Entity_Id;
      Desig_Type             : Entity_Id;

   begin
      --  We are called from Analyze_Full_Type_Declaration, and the Nkind of
      --  the given node is N_Access_To_Object_Definition.

      if not Comes_From_Source (T)
        or else (not In_RCI_Declaration and then not In_RT_Declaration)
      then
         return;
      end if;

      --  An access definition in the private part of a package is not a
      --  remote access type. Restrictions related to external streaming
      --  support for non-remote access types are enforced elsewhere. Note
      --  that In_Private_Part is never set on type entities: check flag
      --  on enclosing scope.

      if In_Private_Part (Scope (T)) then
         return;
      end if;

      --  Check RCI or RT unit type declaration. It may not contain the
      --  declaration of an access-to-object type unless it is a general access
      --  type that designates a class-wide limited private type or subtype.
      --  There are also constraints on the primitive subprograms of the
      --  class-wide type (RM E.2.2(14), see Validate_RACW_Primitives).

      if Ekind (T) /= E_General_Access_Type
        or else not Is_Class_Wide_Type (Designated_Type (T))
      then
         if In_RCI_Declaration then
            Error_Msg_N
              ("error in access type in Remote_Call_Interface unit", T);
         else
            Error_Msg_N
              ("error in access type in Remote_Types unit", T);
         end if;

         Error_Msg_N ("\must be general access to class-wide type", T);
         return;
      end if;

      Direct_Designated_Type := Designated_Type (T);
      Desig_Type := Etype (Direct_Designated_Type);

      --  Why is this check not in Validate_Remote_Access_To_Class_Wide_Type???

      if not Is_Valid_Remote_Object_Type (Desig_Type) then
         Error_Msg_N
           ("error in designated type of remote access to class-wide type", T);
         Error_Msg_N
           ("\must be tagged limited private or private extension", T);
         return;
      end if;
   end Validate_Remote_Access_Object_Type_Declaration;

   -----------------------------------------------
   -- Validate_Remote_Access_To_Class_Wide_Type --
   -----------------------------------------------

   procedure Validate_Remote_Access_To_Class_Wide_Type (N : Node_Id) is
      K  : constant Node_Kind := Nkind (N);
      PK : constant Node_Kind := Nkind (Parent (N));
      E  : Entity_Id;

   begin
      --  This subprogram enforces the checks in (RM E.2.2(8)) for certain uses
      --  of class-wide limited private types.

      --    Storage_Pool and Storage_Size are not defined for such types
      --
      --    The expected type of allocator must not be such a type.

      --    The actual parameter of generic instantiation must not be such a
      --    type if the formal parameter is of an access type.

      --  On entry, there are several cases:

      --    1. called from sem_attr Analyze_Attribute where attribute name is
      --       either Storage_Pool or Storage_Size.

      --    2. called from exp_ch4 Expand_N_Allocator

      --    3. called from sem_ch4 Analyze_Explicit_Dereference

      --    4. called from sem_res Resolve_Actuals

      if K = N_Attribute_Definition_Clause then
         E := Etype (Entity (N));

         if Is_Remote_Access_To_Class_Wide_Type (E) then
            Error_Msg_Name_1 := Chars (N);
            Error_Msg_N
              ("cannot specify% aspect for a remote operand", N);
            return;
         end if;

      elsif K = N_Attribute_Reference then
         E := Etype (Prefix (N));

         if Is_Remote_Access_To_Class_Wide_Type (E) then
            Error_Msg_N ("incorrect attribute of remote operand", N);
            return;
         end if;

      elsif K = N_Allocator then
         E := Etype (N);

         if Is_Remote_Access_To_Class_Wide_Type (E) then
            Error_Msg_N ("incorrect expected remote type of allocator", N);
            return;
         end if;

      --  This subprogram also enforces the checks in E.2.2(13). A value of
      --  such type must not be dereferenced unless as controlling operand of
      --  a dispatching call. Explicit dereferences not coming from source are
      --  exempted from this checking because the expander produces them in
      --  some cases (such as for tag checks on dispatching calls with multiple
      --  controlling operands). However we do check in the case of an implicit
      --  dereference that is expanded to an explicit dereference (hence the
      --  test of whether Original_Node (N) comes from source).

      elsif K = N_Explicit_Dereference
        and then Comes_From_Source (Original_Node (N))
      then
         E := Etype (Prefix (N));

         --  If the class-wide type is not a remote one, the restrictions
         --  do not apply.

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

         --  If we have a true dereference that comes from source and that
         --  is a controlling argument for a dispatching call, accept it.

         if Is_Actual_Parameter (N) and then Is_Controlling_Actual (N) then
            return;
         end if;

         --  If we are just within a procedure or function call and the
         --  dereference has not been analyzed, return because this procedure
         --  will be called again from sem_res Resolve_Actuals. The same can
         --  apply in the case of dereference that is the prefix of a selected
         --  component, which can be a call given in prefixed form.

         if (Is_Actual_Parameter (N) or else PK = N_Selected_Component)
           and then not Analyzed (N)
         then
            return;
         end if;

         --  We must allow expanded code to generate a reference to the tag of
         --  the designated object (may be either the actual tag, or the stub
         --  tag in the case of a remote object).

         if PK = N_Selected_Component
           and then Is_Tag (Entity (Selector_Name (Parent (N))))
         then
            return;
         end if;

         Error_Msg_N
           ("invalid dereference of a remote access-to-class-wide value", N);
      end if;
   end Validate_Remote_Access_To_Class_Wide_Type;

   ------------------------------------------
   -- Validate_Remote_Type_Type_Conversion --
   ------------------------------------------

   procedure Validate_Remote_Type_Type_Conversion (N : Node_Id) is
      S : constant Entity_Id := Etype (N);
      E : constant Entity_Id := Etype (Expression (N));

   begin
      --  This test is required in the case where a conversion appears inside a
      --  normal package, it does not necessarily have to be inside an RCI,
      --  Remote_Types unit (RM E.2.2(9,12)).

      if Is_Remote_Access_To_Subprogram_Type (E)
        and then not Is_Remote_Access_To_Subprogram_Type (S)
      then
         Error_Msg_N
           ("incorrect conversion of remote operand to local type", N);
         return;

      elsif not Is_Remote_Access_To_Subprogram_Type (E)
        and then Is_Remote_Access_To_Subprogram_Type (S)
      then
         Error_Msg_N
           ("incorrect conversion of local operand to remote type", N);
         return;

      elsif Is_Remote_Access_To_Class_Wide_Type (E)
        and then not Is_Remote_Access_To_Class_Wide_Type (S)
      then
         Error_Msg_N
           ("incorrect conversion of remote operand to local type", N);
         return;
      end if;

      --  If a local access type is converted into a RACW type, then the
      --  current unit has a pointer that may now be exported to another
      --  partition.

      if Is_Remote_Access_To_Class_Wide_Type (S)
        and then not Is_Remote_Access_To_Class_Wide_Type (E)
      then
         Set_Has_RACW (Current_Sem_Unit);
      end if;
   end Validate_Remote_Type_Type_Conversion;

   -------------------------------
   -- Validate_RT_RAT_Component --
   -------------------------------

   procedure Validate_RT_RAT_Component (N : Node_Id) is
      Spec           : constant Node_Id   := Specification (N);
      Name_U         : constant Entity_Id := Defining_Entity (Spec);
      Typ            : Entity_Id;
      U_Typ          : Entity_Id;
      First_Priv_Ent : constant Entity_Id := First_Private_Entity (Name_U);

      function Stream_Attributes_Available (Typ : Entity_Id) return Boolean;
      --  True if any stream attribute is available for Typ

      ---------------------------------
      -- Stream_Attributes_Available --
      ---------------------------------

      function Stream_Attributes_Available (Typ : Entity_Id) return Boolean
      is
      begin
         return Stream_Attribute_Available (Typ, TSS_Stream_Read)
                  or else
                Stream_Attribute_Available (Typ, TSS_Stream_Write)
                  or else
                Stream_Attribute_Available (Typ, TSS_Stream_Input)
                  or else
                Stream_Attribute_Available (Typ, TSS_Stream_Output);
      end Stream_Attributes_Available;

   --  Start of processing for Validate_RT_RAT_Component

   begin
      if not Is_Remote_Types (Name_U) then
         return;
      end if;

      Typ := First_Entity (Name_U);
      while Present (Typ) and then Typ /= First_Priv_Ent loop
         U_Typ := Underlying_Type (Base_Type (Typ));

         if No (U_Typ) then
            U_Typ := Typ;
         end if;

         if Comes_From_Source (Typ) and then Is_Type (Typ)
           and then Ekind (Typ) /= E_Incomplete_Type
         then
            --  Check that the type can be meaningfully transmitted to another
            --  partition (E.2.2(8)).

            if (Ada_Version < Ada_2005 and then Has_Non_Remote_Access (U_Typ))
                 or else (Stream_Attributes_Available (Typ)
                           and then No_External_Streaming (U_Typ))
            then
               if Is_Non_Remote_Access_Type (Typ) then
                  Error_Msg_N ("error in non-remote access type", U_Typ);
               else
                  Error_Msg_N
                    ("error in record type containing a component of a " &
                     "non-remote access type", U_Typ);
               end if;

               if Ada_Version >= Ada_2005 then
                  Error_Msg_N
                    ("\must have visible Read and Write attribute " &
                     "definition clauses (RM E.2.2(8))", U_Typ);
               else
                  Error_Msg_N
                    ("\must have Read and Write attribute " &
                     "definition clauses (RM E.2.2(8))", U_Typ);
               end if;
            end if;
         end if;

         Next_Entity (Typ);
      end loop;
   end Validate_RT_RAT_Component;

   -----------------------------------------
   -- Validate_SP_Access_Object_Type_Decl --
   -----------------------------------------

   procedure Validate_SP_Access_Object_Type_Decl (T : Entity_Id) is
      Direct_Designated_Type : Entity_Id;

      function Has_Entry_Declarations (E : Entity_Id) return Boolean;
      --  Return true if the protected type designated by T has entry
      --  declarations.

      ----------------------------
      -- Has_Entry_Declarations --
      ----------------------------

      function Has_Entry_Declarations (E : Entity_Id) return Boolean is
         Ety : Entity_Id;

      begin
         if Nkind (Parent (E)) = N_Protected_Type_Declaration then
            Ety := First_Entity (E);
            while Present (Ety) loop
               if Ekind (Ety) = E_Entry then
                  return True;
               end if;

               Next_Entity (Ety);
            end loop;
         end if;

         return False;
      end Has_Entry_Declarations;

   --  Start of processing for Validate_SP_Access_Object_Type_Decl

   begin
      --  We are called from Sem_Ch3.Analyze_Full_Type_Declaration, and the
      --  Nkind of the given entity is N_Access_To_Object_Definition.

      if not Comes_From_Source (T)
        or else not In_Shared_Passive_Unit
        or else In_Subprogram_Task_Protected_Unit
      then
         return;
      end if;

      --  Check Shared Passive unit. It should not contain the declaration
      --  of an access-to-object type whose designated type is a class-wide
      --  type, task type or protected type with entry (RM E.2.1(7)).

      Direct_Designated_Type := Designated_Type (T);

      if Ekind (Direct_Designated_Type) = E_Class_Wide_Type then
         Error_Msg_N
           ("invalid access-to-class-wide type in shared passive unit", T);
         return;

      elsif Ekind (Direct_Designated_Type) in Task_Kind then
         Error_Msg_N
           ("invalid access-to-task type in shared passive unit", T);
         return;

      elsif Ekind (Direct_Designated_Type) in Protected_Kind
        and then Has_Entry_Declarations (Direct_Designated_Type)
      then
         Error_Msg_N
           ("invalid access-to-protected type in shared passive unit", T);
         return;
      end if;
   end Validate_SP_Access_Object_Type_Decl;

   ---------------------------------
   -- Validate_Static_Object_Name --
   ---------------------------------

   procedure Validate_Static_Object_Name (N : Node_Id) is
      E   : Entity_Id;
      Val : Node_Id;

      function Is_Primary (N : Node_Id) return Boolean;
      --  Determine whether node is syntactically a primary in an expression
      --  This function should probably be somewhere else ???
      --
      --  Also it does not do what it says, e.g if N is a binary operator
      --  whose parent is a binary operator, Is_Primary returns True ???

      ----------------
      -- Is_Primary --
      ----------------

      function Is_Primary (N : Node_Id) return Boolean is
         K : constant Node_Kind := Nkind (Parent (N));

      begin
         case K is
            when N_Aggregate
               | N_Component_Association
               | N_Index_Or_Discriminant_Constraint
               | N_Membership_Test
               | N_Op
               | N_Range
            =>
               return True;

            when N_Attribute_Reference =>
               declare
                  Attr : constant Name_Id := Attribute_Name (Parent (N));

               begin
                  return     Attr /= Name_Address
                    and then Attr /= Name_Access
                    and then Attr /= Name_Unchecked_Access
                    and then Attr /= Name_Unrestricted_Access;
               end;

            when N_Indexed_Component =>
               return N /= Prefix (Parent (N)) or else Is_Primary (Parent (N));

            when N_Qualified_Expression
               | N_Type_Conversion
            =>
               return Is_Primary (Parent (N));

            when N_Assignment_Statement
               | N_Object_Declaration
            =>
               return N = Expression (Parent (N));

            when N_Selected_Component =>
               return Is_Primary (Parent (N));

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

   --  Start of processing for Validate_Static_Object_Name

   begin
      if not In_Preelaborated_Unit
        or else not Comes_From_Source (N)
        or else In_Subprogram_Or_Concurrent_Unit
        or else Ekind (Current_Scope) = E_Block
      then
         return;

      --  Filter out cases where primary is default in a component declaration,
      --  discriminant specification, or actual in a record type initialization
      --  call.

      --  Initialization call of internal types

      elsif Nkind (Parent (N)) = N_Procedure_Call_Statement then

         if Present (Parent (Parent (N)))
           and then Nkind (Parent (Parent (N))) = N_Freeze_Entity
         then
            return;
         end if;

         if Nkind (Name (Parent (N))) = N_Identifier
           and then not Comes_From_Source (Entity (Name (Parent (N))))
         then
            return;
         end if;
      end if;

      --  Error if the name is a primary in an expression. The parent must not
      --  be an operator, or a selected component or an indexed component that
      --  is itself a primary. Entities that are actuals do not need to be
      --  checked, because the call itself will be diagnosed. Entities in a
      --  generic unit or within a preanalyzed expression are not checked:
      --  only their use in executable code matters.

      if Is_Primary (N)
        and then (not Inside_A_Generic
                   or else Present (Enclosing_Generic_Body (N)))
        and then not In_Spec_Expression
      then
         if Ekind (Entity (N)) = E_Variable
           or else Ekind (Entity (N)) in Formal_Object_Kind
         then
            Flag_Non_Static_Expr
              ("non-static object name in preelaborated unit", N);

         --  Give an error for a reference to a nonstatic constant, unless the
         --  constant is in another GNAT library unit that is preelaborable.

         elsif Ekind (Entity (N)) = E_Constant
           and then not Is_Static_Expression (N)
         then
            E   := Entity (N);
            Val := Constant_Value (E);

            if In_Internal_Unit (N)
              and then
                Enclosing_Comp_Unit_Node (N) /= Enclosing_Comp_Unit_Node (E)
              and then (Is_Preelaborated (Scope (E))
                         or else Is_Pure (Scope (E))
                         or else (Present (Renamed_Object (E))
                                   and then Is_Entity_Name (Renamed_Object (E))
                                   and then
                                     (Is_Preelaborated
                                        (Scope (Renamed_Object (E)))
                                       or else
                                         Is_Pure
                                           (Scope (Renamed_Object (E))))))
            then
               null;

            --  If the value of the constant is a local variable that renames
            --  an aggregate, this is in itself legal. The aggregate may be
            --  expanded into a loop, but this does not affect preelaborability
            --  in itself. If some aggregate components are non-static, that is
            --  to say if they involve non static primaries, they will be
            --  flagged when analyzed.

            elsif Present (Val)
              and then Is_Entity_Name (Val)
              and then Is_Array_Type (Etype (Val))
              and then not Comes_From_Source (Val)
              and then Nkind (Original_Node (Val)) = N_Aggregate
            then
               null;

            --  This is the error case

            else
               --  In GNAT mode or Relaxed RM Semantic mode, this is just a
               --  warning, to allow it to be judiciously turned off.
               --  Otherwise it is a real error.

               if GNAT_Mode or Relaxed_RM_Semantics then
                  Error_Msg_N
                    ("??non-static constant in preelaborated unit", N);
               else
                  Flag_Non_Static_Expr
                    ("non-static constant in preelaborated unit", N);
               end if;
            end if;
         end if;
      end if;
   end Validate_Static_Object_Name;

end Sem_Cat;
