------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              S E M _ C A T                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2019, 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 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 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_NE
              ("\<<pure unit cannot depend on non-pure unit",
               N, Depended_Entity);

         elsif Is_Preelaborated (Unit_Entity)
           and then not Is_Preelaborated (Depended_Entity)
           and then not Is_Pure (Depended_Entity)
         then
            Error_Msg_NE
              ("\<<preelaborated unit cannot depend on "
               & "non-preelaborated unit",
               N, Depended_Entity);
         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))
         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
   begin
      return True
        and then Has_Stream_Attribute_Definition
                   (E, TSS_Stream_Read,  At_Any_Place => True)
        and then Has_Stream_Attribute_Definition
                   (E, TSS_Stream_Write, 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;
      At_Any_Place : Boolean := False) return Boolean
   is
      Rep_Item : Node_Id;

      Real_Rep : Node_Id;
      --  The stream operation may be specified by an attribute definition
      --  clause in the source, or by an aspect that generates such an
      --  attribute definition. For an aspect, the generated attribute
      --  definition may be placed at the freeze point of the full view of
      --  the type, but the aspect specification makes the operation visible
      --  to a client wherever the partial view is visible.

   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.

      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, 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);
      S   : constant Entity_Id := Current_Scope;

      procedure Set_Parents (Visibility : Boolean);
         --  If this is a child instance, the parents are not immediately
         --  visible during analysis. Make them momentarily visible so that
         --  the argument of the pragma can be resolved properly, and reset
         --  afterwards.

      -----------------
      -- Set_Parents --
      -----------------

      procedure Set_Parents (Visibility : Boolean) is
         Par : Entity_Id;
      begin
         Par := Scope (S);
         while Present (Par) and then Par /= Standard_Standard loop
            Set_Is_Immediately_Visible (Par, Visibility);
            Par := Scope (Par);
         end loop;
      end Set_Parents;

   --  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. This processing is only needed if compilation unit pragmas
      --  are present.
      --  Note: This code may be incorrect in the unlikely case a child generic
      --  unit is instantiated as a child of its (nongeneric) parent, so that
      --  generic and instance are siblings.

      if Nkind (P) /= N_Compilation_Unit
         or else No (First (Pragmas_After (Aux_Decls_Node (P))))
      then
         return;
      end if;

      declare
         PN : Node_Id;

      begin
         if Is_Child_Unit (S) and then Is_Generic_Instance (S) then
            Set_Parents (True);
         end if;

         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;

         if Is_Child_Unit (S) and then Is_Generic_Instance (S) then
            Set_Parents (False);
         end if;
      end;
   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 Ekind (E) in Subprogram_Kind then
            Declaration := Unit_Declaration_Node (E);

            if Nkind_In (Declaration, 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_In (N, 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 rci unit must also be rci 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_In (Param_Type, 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 rci unit", Parent (E));
               Explain_Limited_Type (E, Parent (E));

            elsif Ekind_In (E, E_Generic_Function,
                               E_Generic_Package,
                               E_Generic_Procedure)
            then
               Error_Msg_N ("generic declaration not allowed in rci 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 rci 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_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
            =>
               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;
