------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              E X P_ D I S T                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                            $Revision: 1.125 $
--                                                                          --
--          Copyright (C) 1992-2001 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 2,  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 COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
--                                                                          --
------------------------------------------------------------------------------

with Atree;       use Atree;
with Einfo;       use Einfo;
with Elists;      use Elists;
with Exp_Tss;     use Exp_Tss;
with Exp_Util;    use Exp_Util;
with GNAT.HTable; use GNAT.HTable;
with Lib;         use Lib;
with Namet;       use Namet;
with Nlists;      use Nlists;
with Nmake;       use Nmake;
with Opt;         use Opt;
with Rtsfind;     use Rtsfind;
with Sem;         use Sem;
with Sem_Ch3;     use Sem_Ch3;
with Sem_Ch8;     use Sem_Ch8;
with Sem_Dist;    use Sem_Dist;
with Sem_Util;    use Sem_Util;
with Sinfo;       use Sinfo;
with Snames;      use Snames;
with Stand;       use Stand;
with Stringt;     use Stringt;
with Tbuild;      use Tbuild;
with Uintp;       use Uintp;
with Uname;       use Uname;

package body Exp_Dist is

   --  The following model has been used to implement distributed objects:
   --  given a designated type D and a RACW type R, then a record of the
   --  form:
   --    type Stub is tagged record
   --       [...declaration similar to s-parint.ads RACW_Stub_Type...]
   --    end Stub;
   --  is built. This type has two properties:
   --
   --    1) Since it has the same structure than RACW_Stub_Type, it can be
   --       converted to and from this type to make it suitable for
   --       System.Partition_Interface.Get_Unique_Remote_Pointer in order
   --       to avoid memory leaks when the same remote object arrive on the
   --       same partition by following different pathes
   --
   --    2) It also has the same dispatching table as the designated type D,
   --       and thus can be used as an object designated by a value of type
   --       R on any partition other than the one on which the object has
   --       been created, since only dispatching calls will be performed and
   --       the fields themselves will not be used. We call Derive_Subprograms
   --       to fake half a derivation to ensure that the subprograms do have
   --       the same dispatching table.

   -----------------------
   -- Local subprograms --
   -----------------------

   procedure Build_General_Calling_Stubs
     (Decls                     : in List_Id;
      Statements                : in List_Id;
      Target_Partition          : in Entity_Id;
      RPC_Receiver              : in Node_Id;
      Subprogram_Id             : in Node_Id;
      Asynchronous              : in Node_Id := Empty;
      Is_Known_Asynchronous     : in Boolean := False;
      Is_Known_Non_Asynchronous : in Boolean := False;
      Is_Function               : in Boolean;
      Spec                      : in Node_Id;
      Object_Type               : in Entity_Id := Empty;
      Nod                       : in Node_Id);
   --  Build calling stubs for general purpose. The parameters are:
   --    Decls             : a place to put declarations
   --    Statements        : a place to put statements
   --    Target_Partition  : a node containing the target partition that must
   --                        be a N_Defining_Identifier
   --    RPC_Receiver      : a node containing the RPC receiver
   --    Subprogram_Id     : a node containing the subprogram ID
   --    Asynchronous      : True if an APC must be made instead of an RPC.
   --                        The value needs not be supplied if one of the
   --                        Is_Known_... is True.
   --    Is_Known_Async... : True if we know that this is asynchronous
   --    Is_Known_Non_A... : True if we know that this is not asynchronous
   --    Spec              : a node with a Parameter_Specifications and
   --                        a Subtype_Mark if applicable
   --    Object_Type       : in case of a RACW, parameters of type access to
   --                        Object_Type will be marshalled using the
   --                        address of this object (the addr field) rather
   --                        than using the 'Write on the object itself
   --    Nod               : used to provide sloc for generated code

   function Build_Subprogram_Calling_Stubs
     (Vis_Decl                 : Node_Id;
      Subp_Id                  : Int;
      Asynchronous             : Boolean;
      Dynamically_Asynchronous : Boolean   := False;
      Stub_Type                : Entity_Id := Empty;
      Locator                  : Entity_Id := Empty;
      New_Name                 : Name_Id   := No_Name)
      return                     Node_Id;
   --  Build the calling stub for a given subprogram with the subprogram ID
   --  being Subp_Id. If Stub_Type is given, then the "addr" field of
   --  parameters of this type will be marshalled instead of the object
   --  itself. It will then be converted into Stub_Type before performing
   --  the real call. If Dynamically_Asynchronous is True, then it will be
   --  computed at run time whether the call is asynchronous or not.
   --  Otherwise, the value of the formal Asynchronous will be used.
   --  If Locator is not Empty, it will be used instead of RCI_Cache. If
   --  New_Name is given, then it will be used instead of the original name.

   function Build_Subprogram_Receiving_Stubs
     (Vis_Decl                 : Node_Id;
      Asynchronous             : Boolean;
      Dynamically_Asynchronous : Boolean   := False;
      Stub_Type                : Entity_Id := Empty;
      RACW_Type                : Entity_Id := Empty;
      Parent_Primitive         : Entity_Id := Empty)
      return                     Node_Id;
   --  Build the receiving stub for a given subprogram. The subprogram
   --  declaration is also built by this procedure, and the value returned
   --  is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
   --  found in the specification, then its address is read from the stream
   --  instead of the object itself and converted into an access to
   --  class-wide type before doing the real call using any of the RACW type
   --  pointing on the designated type.

   function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
   --  Return an ordered parameter list: unconstrained parameters are put
   --  at the beginning of the list and constrained ones are put after. If
   --  there are no parameters, an empty list is returned.

   procedure Add_Calling_Stubs_To_Declarations
     (Pkg_Spec : in Node_Id;
      Decls    : in List_Id);
   --  Add calling stubs to the declarative part

   procedure Add_Receiving_Stubs_To_Declarations
     (Pkg_Spec : in Node_Id;
      Decls    : in List_Id);
   --  Add receiving stubs to the declarative part

   procedure Add_RAS_Dereference_Attribute (N : in Node_Id);
   --  Add a subprogram body for RAS dereference

   procedure Add_RAS_Access_Attribute (N : in Node_Id);
   --  Add a subprogram body for RAS Access attribute

   function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
   --  Return True if nothing prevents the program whose specification is
   --  given to be asynchronous (i.e. no out parameter).

   function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id;
   function Get_String_Id (Val : String) return String_Id;
   --  Ugly functions used to retrieve a package name. Inherited from the
   --  old exp_dist.adb and not rewritten yet ???

   function Pack_Entity_Into_Stream_Access
     (Loc    : Source_Ptr;
      Stream : Entity_Id;
      Object : Entity_Id;
      Etyp   : Entity_Id := Empty)
      return   Node_Id;
   --  Pack Object (of type Etyp) into Stream. If Etyp is not given,
   --  then Etype (Object) will be used if present. If the type is
   --  constrained, then 'Write will be used to output the object,
   --  If the type is unconstrained, 'Output will be used.

   function Pack_Node_Into_Stream
     (Loc    : Source_Ptr;
      Stream : Entity_Id;
      Object : Node_Id;
      Etyp   : Entity_Id)
      return   Node_Id;
   --  Similar to above, with an arbitrary node instead of an entity

   function Pack_Node_Into_Stream_Access
     (Loc    : Source_Ptr;
      Stream : Entity_Id;
      Object : Node_Id;
      Etyp   : Entity_Id)
      return   Node_Id;
   --  Similar to above, with Stream instead of Stream'Access

   function Copy_Specification
     (Loc         : Source_Ptr;
      Spec        : Node_Id;
      Object_Type : Entity_Id := Empty;
      Stub_Type   : Entity_Id := Empty;
      New_Name    : Name_Id   := No_Name)
      return        Node_Id;
   --  Build a specification from another one. If Object_Type is not Empty
   --  and any access to Object_Type is found, then it is replaced by an
   --  access to Stub_Type. If New_Name is given, then it will be used as
   --  the name for the newly created spec.

   function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
   --  Return the scope represented by a given spec

   function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
   --  Return True if the current parameter needs an extra formal to reflect
   --  its constrained status.

   function Is_RACW_Controlling_Formal
     (Parameter : Node_Id; Stub_Type : Entity_Id)
      return Boolean;
   --  Return True if the current parameter is a controlling formal argument
   --  of type Stub_Type or access to Stub_Type.

   type Stub_Structure is record
      Stub_Type           : Entity_Id;
      Stub_Type_Access    : Entity_Id;
      Object_RPC_Receiver : Entity_Id;
      RPC_Receiver_Stream : Entity_Id;
      RPC_Receiver_Result : Entity_Id;
      RACW_Type           : Entity_Id;
   end record;
   --  This structure is necessary because of the two phases analysis of
   --  a RACW declaration occurring in the same Remote_Types package as the
   --  designated type. RACW_Type is any of the RACW types pointing on this
   --  designated type, it is used here to save an anonymous type creation
   --  for each primitive operation.

   Empty_Stub_Structure : constant Stub_Structure :=
     (Empty, Empty, Empty, Empty, Empty, Empty);

   type Hash_Index is range 0 .. 50;
   function Hash (F : Entity_Id) return Hash_Index;

   package Stubs_Table is
      new Simple_HTable (Header_Num => Hash_Index,
                         Element    => Stub_Structure,
                         No_Element => Empty_Stub_Structure,
                         Key        => Entity_Id,
                         Hash       => Hash,
                         Equal      => "=");
   --  Mapping between a RACW designated type and its stub type

   package Asynchronous_Flags_Table is
      new Simple_HTable (Header_Num => Hash_Index,
                         Element    => Node_Id,
                         No_Element => Empty,
                         Key        => Entity_Id,
                         Hash       => Hash,
                         Equal      => "=");
   --  Mapping between a RACW type and the node holding the value True if
   --  the RACW is asynchronous and False otherwise.

   package RCI_Locator_Table is
      new Simple_HTable (Header_Num => Hash_Index,
                         Element    => Entity_Id,
                         No_Element => Empty,
                         Key        => Entity_Id,
                         Hash       => Hash,
                         Equal      => "=");
   --  Mapping between a RCI package on which All_Calls_Remote applies and
   --  the generic instantiation of RCI_Info for this package.

   package RCI_Calling_Stubs_Table is
      new Simple_HTable (Header_Num => Hash_Index,
                         Element    => Entity_Id,
                         No_Element => Empty,
                         Key        => Entity_Id,
                         Hash       => Hash,
                         Equal      => "=");
   --  Mapping between a RCI subprogram and the corresponding calling stubs

   procedure Add_Stub_Type
     (Designated_Type     : in Entity_Id;
      RACW_Type           : in Entity_Id;
      Decls               : in List_Id;
      Stub_Type           : out Entity_Id;
      Stub_Type_Access    : out Entity_Id;
      Object_RPC_Receiver : out Entity_Id;
      Existing            : out Boolean);
   --  Add the declaration of the stub type, the access to stub type and the
   --  object RPC receiver at the end of Decls. If these already exist,
   --  then nothing is added in the tree but the right values are returned
   --  anyhow and Existing is set to True.

   procedure Add_RACW_Read_Attribute
     (RACW_Type           : in Entity_Id;
      Stub_Type           : in Entity_Id;
      Stub_Type_Access    : in Entity_Id;
      Declarations        : in List_Id);
   --  Add Read attribute in Decls for the RACW type. The Read attribute
   --  is added right after the RACW_Type declaration while the body is
   --  inserted after Declarations.

   procedure Add_RACW_Write_Attribute
     (RACW_Type           : in Entity_Id;
      Stub_Type           : in Entity_Id;
      Stub_Type_Access    : in Entity_Id;
      Object_RPC_Receiver : in Entity_Id;
      Declarations        : in List_Id);
   --  Same thing for the Write attribute

   procedure Add_RACW_Read_Write_Attributes
     (RACW_Type           : in Entity_Id;
      Stub_Type           : in Entity_Id;
      Stub_Type_Access    : in Entity_Id;
      Object_RPC_Receiver : in Entity_Id;
      Declarations        : in List_Id);
   --  Add Read and Write attributes declarations and bodies for a given
   --  RACW type. The declarations are added just after the declaration
   --  of the RACW type itself, while the bodies are inserted at the end
   --  of Decls.

   function RCI_Package_Locator
     (Loc          : Source_Ptr;
      Package_Spec : Node_Id)
      return         Node_Id;
   --  Instantiate the generic package RCI_Info in order to locate the
   --  RCI package whose spec is given as argument.

   function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
   --  Surround a node N by a tag check, as in:
   --      begin
   --         <N>;
   --      exception
   --         when E : Ada.Tags.Tag_Error =>
   --           Raise_Exception (Program_Error'Identity,
   --                            Exception_Message (E));
   --      end;

   function Input_With_Tag_Check
     (Loc      : Source_Ptr;
      Var_Type : Entity_Id;
      Stream   : Entity_Id)
     return Node_Id;
   --  Return a function with the following form:
   --    function R return Var_Type is
   --    begin
   --       return Var_Type'Input (S);
   --    exception
   --       when E : Ada.Tags.Tag_Error =>
   --           Raise_Exception (Program_Error'Identity,
   --                            Exception_Message (E));
   --    end R;

   ------------------------------------
   -- Local variables and structures --
   ------------------------------------

   RCI_Cache : Node_Id;

   Output_From_Constrained : constant array (Boolean) of Name_Id :=
     (False => Name_Output,
      True  => Name_Write);
   --  The attribute to choose depending on the fact that the parameter
   --  is constrained or not. There is no such thing as Input_From_Constrained
   --  since this require separate mechanisms ('Input is a function while
   --  'Read is a procedure).

   ---------------------------------------
   -- Add_Calling_Stubs_To_Declarations --
   ---------------------------------------

   procedure Add_Calling_Stubs_To_Declarations
     (Pkg_Spec : in Node_Id;
      Decls    : in List_Id)
   is
      Current_Subprogram_Number : Int := 0;
      Current_Declaration       : Node_Id;

      Loc                       : constant Source_Ptr := Sloc (Pkg_Spec);

      RCI_Instantiation         : Node_Id;

      Subp_Stubs                : Node_Id;

   begin
      --  The first thing added is an instantiation of the generic package
      --  System.Partition_interface.RCI_Info with the name of the (current)
      --  remote package. This will act as an interface with the name server
      --  to determine the Partition_ID and the RPC_Receiver for the
      --  receiver of this package.

      RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
      RCI_Cache         := Defining_Unit_Name (RCI_Instantiation);

      Append_To (Decls, RCI_Instantiation);
      Analyze (RCI_Instantiation);

      --  For each subprogram declaration visible in the spec, we do
      --  build a body. We also increment a counter to assign a different
      --  Subprogram_Id to each subprograms. The receiving stubs processing
      --  do use the same mechanism and will thus assign the same Id and
      --  do the correct dispatching.

      Current_Declaration := First (Visible_Declarations (Pkg_Spec));

      while Current_Declaration /= Empty loop

         if Nkind (Current_Declaration) = N_Subprogram_Declaration
           and then Comes_From_Source (Current_Declaration)
         then
            pragma Assert (Current_Subprogram_Number =
              Get_Subprogram_Id (Defining_Unit_Name (Specification (
                Current_Declaration))));

            Subp_Stubs :=
              Build_Subprogram_Calling_Stubs (
                Vis_Decl     => Current_Declaration,
                Subp_Id      => Current_Subprogram_Number,
                Asynchronous =>
                  Nkind (Specification (Current_Declaration)) =
                    N_Procedure_Specification
                  and then
                    Is_Asynchronous (Defining_Unit_Name (Specification
                      (Current_Declaration))));

            Append_To (Decls, Subp_Stubs);
            Analyze (Subp_Stubs);

            Current_Subprogram_Number := Current_Subprogram_Number + 1;
         end if;

         Next (Current_Declaration);
      end loop;

   end Add_Calling_Stubs_To_Declarations;

   -----------------------
   -- Add_RACW_Features --
   -----------------------

   procedure Add_RACW_Features (RACW_Type : in Entity_Id)
   is
      Desig : constant Entity_Id :=
                Etype (Designated_Type (RACW_Type));
      Decls : List_Id :=
                List_Containing (Declaration_Node (RACW_Type));

      Same_Scope : constant Boolean :=
                     Scope (Desig) = Scope (RACW_Type);

      Stub_Type           : Entity_Id;
      Stub_Type_Access    : Entity_Id;
      Object_RPC_Receiver : Entity_Id;
      Existing            : Boolean;

   begin
      if not Expander_Active then
         return;
      end if;

      if Same_Scope then

         --  We are declaring a RACW in the same package than its designated
         --  type, so the list to use for late declarations must be the
         --  private part of the package. We do know that this private part
         --  exists since the designated type has to be a private one.

         Decls := Private_Declarations
           (Package_Specification_Of_Scope (Current_Scope));

      elsif Nkind (Parent (Decls)) = N_Package_Specification
        and then Present (Private_Declarations (Parent (Decls)))
      then
         Decls := Private_Declarations (Parent (Decls));
      end if;

      --  If we were unable to find the declarations, that means that the
      --  completion of the type was missing. We can safely return and let
      --  the error be caught by the semantic analysis.

      if No (Decls) then
         return;
      end if;

      Add_Stub_Type
        (Designated_Type     => Desig,
         RACW_Type           => RACW_Type,
         Decls               => Decls,
         Stub_Type           => Stub_Type,
         Stub_Type_Access    => Stub_Type_Access,
         Object_RPC_Receiver => Object_RPC_Receiver,
         Existing            => Existing);

      Add_RACW_Read_Write_Attributes
        (RACW_Type           => RACW_Type,
         Stub_Type           => Stub_Type,
         Stub_Type_Access    => Stub_Type_Access,
         Object_RPC_Receiver => Object_RPC_Receiver,
         Declarations        => Decls);

      if not Same_Scope and then not Existing then

         --  The RACW has been declared in another scope than the designated
         --  type and has not been handled by another RACW in the same
         --  package as the first one, so add primitive for the stub type
         --  here.

         Add_RACW_Primitive_Declarations_And_Bodies
           (Designated_Type  => Desig,
            Insertion_Node   =>
              Parent (Declaration_Node (Object_RPC_Receiver)),
            Decls            => Decls);

      else
         Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
      end if;
   end Add_RACW_Features;

   -------------------------------------------------
   --  Add_RACW_Primitive_Declarations_And_Bodies --
   -------------------------------------------------

   procedure Add_RACW_Primitive_Declarations_And_Bodies
     (Designated_Type : in Entity_Id;
      Insertion_Node  : in Node_Id;
      Decls           : in List_Id)
   is
      --  Set sloc of generated declaration to be that of the
      --  insertion node, so the declarations are recognized as
      --  belonging to the current package.

      Loc : constant Source_Ptr := Sloc (Insertion_Node);

      Stub_Elements : constant Stub_Structure :=
        Stubs_Table.Get (Designated_Type);

      pragma Assert (Stub_Elements /= Empty_Stub_Structure);

      Current_Insertion_Node : Node_Id := Insertion_Node;

      RPC_Receiver_Declarations      : List_Id;
      RPC_Receiver_Statements        : List_Id;
      RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
      RPC_Receiver_Subp_Id           : Entity_Id;

      Current_Primitive_Elmt   : Elmt_Id;
      Current_Primitive        : Entity_Id;
      Current_Primitive_Body   : Node_Id;
      Current_Primitive_Spec   : Node_Id;
      Current_Primitive_Decl   : Node_Id;
      Current_Primitive_Number : Int := 0;

      Current_Primitive_Alias : Node_Id;

      Current_Receiver      : Entity_Id;
      Current_Receiver_Body : Node_Id;

      RPC_Receiver_Decl : Node_Id;

      Possibly_Asynchronous : Boolean;

   begin

      if not Expander_Active then
         return;
      end if;

      --  Build callers, receivers for every primitive operations and a RPC
      --  receiver for this type.

      if Present (Primitive_Operations (Designated_Type)) then

         Current_Primitive_Elmt :=
           First_Elmt (Primitive_Operations (Designated_Type));

         while Current_Primitive_Elmt /= No_Elmt loop

            Current_Primitive := Node (Current_Primitive_Elmt);

            --  Copy the primitive of all the parents, except predefined
            --  ones that are not remotely dispatching.

            if Chars (Current_Primitive) /= Name_uSize
              and then Chars (Current_Primitive) /= Name_uDeep_Finalize
            then
               --  The first thing to do is build an up-to-date copy of
               --  the spec with all the formals referencing Designated_Type
               --  transformed into formals referencing Stub_Type. Since this
               --  primitive may have been inherited, go back the alias chain
               --  until the real primitive has been found.

               Current_Primitive_Alias := Current_Primitive;
               while Present (Alias (Current_Primitive_Alias)) loop
                  pragma Assert
                    (Current_Primitive_Alias
                      /= Alias (Current_Primitive_Alias));
                  Current_Primitive_Alias := Alias (Current_Primitive_Alias);
               end loop;

               Current_Primitive_Spec :=
                 Copy_Specification (Loc,
                   Spec        => Parent (Current_Primitive_Alias),
                   Object_Type => Designated_Type,
                   Stub_Type   => Stub_Elements.Stub_Type);

               Current_Primitive_Decl :=
                 Make_Subprogram_Declaration (Loc,
                   Specification => Current_Primitive_Spec);

               Insert_After (Current_Insertion_Node, Current_Primitive_Decl);
               Analyze (Current_Primitive_Decl);
               Current_Insertion_Node := Current_Primitive_Decl;

               Possibly_Asynchronous :=
                 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
                 and then Could_Be_Asynchronous (Current_Primitive_Spec);

               Current_Primitive_Body :=
                 Build_Subprogram_Calling_Stubs
                   (Vis_Decl                 => Current_Primitive_Decl,
                    Subp_Id                  => Current_Primitive_Number,
                    Asynchronous             => Possibly_Asynchronous,
                    Dynamically_Asynchronous => Possibly_Asynchronous,
                    Stub_Type                => Stub_Elements.Stub_Type);
               Append_To (Decls, Current_Primitive_Body);

               --  Analyzing the body here would cause the Stub type to be
               --  frozen, thus preventing subsequent primitive declarations.
               --  For this reason, it will be analyzed later in the
               --  regular flow.

               --  Build the receiver stubs

               Current_Receiver_Body :=
                 Build_Subprogram_Receiving_Stubs
                   (Vis_Decl                 => Current_Primitive_Decl,
                    Asynchronous             => Possibly_Asynchronous,
                    Dynamically_Asynchronous => Possibly_Asynchronous,
                    Stub_Type                => Stub_Elements.Stub_Type,
                    RACW_Type                => Stub_Elements.RACW_Type,
                    Parent_Primitive         => Current_Primitive);

               Current_Receiver :=
                  Defining_Unit_Name (Specification (Current_Receiver_Body));

               Append_To (Decls, Current_Receiver_Body);

               --  Add a case alternative to the receiver

               Append_To (RPC_Receiver_Case_Alternatives,
                 Make_Case_Statement_Alternative (Loc,
                   Discrete_Choices => New_List (
                     Make_Integer_Literal (Loc, Current_Primitive_Number)),

                   Statements       => New_List (
                     Make_Procedure_Call_Statement (Loc,
                       Name                   =>
                         New_Occurrence_Of (Current_Receiver, Loc),
                       Parameter_Associations => New_List (
                         New_Occurrence_Of
                           (Stub_Elements.RPC_Receiver_Stream, Loc),
                         New_Occurrence_Of
                           (Stub_Elements.RPC_Receiver_Result, Loc))))));

               --  Increment the index of current primitive

               Current_Primitive_Number := Current_Primitive_Number + 1;
            end if;

            Next_Elmt (Current_Primitive_Elmt);
         end loop;
      end if;

      --  Build the case statement and the heart of the subprogram

      Append_To (RPC_Receiver_Case_Alternatives,
        Make_Case_Statement_Alternative (Loc,
          Discrete_Choices => New_List (Make_Others_Choice (Loc)),
          Statements       => New_List (Make_Null_Statement (Loc))));

      RPC_Receiver_Subp_Id :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));

      RPC_Receiver_Declarations := New_List (
        Make_Object_Declaration (Loc,
          Defining_Identifier => RPC_Receiver_Subp_Id,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));

      RPC_Receiver_Statements := New_List (
        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
          Attribute_Name =>
            Name_Read,
          Expressions    => New_List (
            New_Occurrence_Of (Stub_Elements.RPC_Receiver_Stream, Loc),
            New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc))));

      Append_To (RPC_Receiver_Statements,
        Make_Case_Statement (Loc,
          Expression   =>
            New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
          Alternatives => RPC_Receiver_Case_Alternatives));

      RPC_Receiver_Decl :=
        Make_Subprogram_Body (Loc,
          Specification              =>
            Copy_Specification (Loc,
              Parent (Stub_Elements.Object_RPC_Receiver)),
          Declarations               => RPC_Receiver_Declarations,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => RPC_Receiver_Statements));

      Append_To (Decls, RPC_Receiver_Decl);

      --  Do not analyze RPC receiver at this stage since it will otherwise
      --  reference subprograms that have not been analyzed yet. It will
      --  be analyzed in the regular flow.

   end Add_RACW_Primitive_Declarations_And_Bodies;

   -----------------------------
   -- Add_RACW_Read_Attribute --
   -----------------------------

   procedure Add_RACW_Read_Attribute
     (RACW_Type           : in Entity_Id;
      Stub_Type           : in Entity_Id;
      Stub_Type_Access    : in Entity_Id;
      Declarations        : in List_Id)
   is
      Loc : constant Source_Ptr := Sloc (RACW_Type);

      Proc_Spec : Node_Id;
      --  Specification and body of the currently built procedure

      Proc_Body_Spec : Node_Id;

      Proc_Decl : Node_Id;
      Attr_Decl : Node_Id;

      Body_Node : Node_Id;

      Decls             : List_Id;
      Statements        : List_Id;
      Local_Statements  : List_Id;
      Remote_Statements : List_Id;
      --  Various parts of the procedure

      Procedure_Name    : constant Name_Id   :=
                            New_Internal_Name ('R');
      Source_Partition  : constant Entity_Id :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('P'));
      Source_Receiver   : constant Entity_Id :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('S'));
      Source_Address    : constant Entity_Id :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('P'));
      Stream_Parameter  : constant Entity_Id :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('S'));
      Result            : constant Entity_Id  :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('P'));
      Stubbed_Result    : constant Entity_Id  :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('S'));
      Asynchronous_Flag : constant Entity_Id :=
                            Make_Defining_Identifier
                              (Loc, New_Internal_Name ('S'));
      Asynchronous_Node : constant Node_Id   :=
                            New_Occurrence_Of (Standard_False, Loc);

   begin
      --  Declare the asynchronous flag. This flag will be changed to True
      --  whenever it is known that the RACW type is asynchronous. Also, the
      --  node gets stored since it may be rewritten when we process the
      --  asynchronous pragma.

      Append_To (Declarations,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Asynchronous_Flag,
          Constant_Present    => True,
          Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
          Expression          => Asynchronous_Node));

      Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Node);

      --  Object declarations

      Decls := New_List (
        Make_Object_Declaration (Loc,
          Defining_Identifier => Source_Partition,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),

        Make_Object_Declaration (Loc,
          Defining_Identifier => Source_Receiver,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),

        Make_Object_Declaration (Loc,
          Defining_Identifier => Source_Address,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),

        Make_Object_Declaration (Loc,
          Defining_Identifier => Stubbed_Result,
          Object_Definition   =>
            New_Occurrence_Of (Stub_Type_Access, Loc)));

      --  Read the source Partition_ID and RPC_Receiver from incoming stream

      Statements := New_List (
        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
          Attribute_Name => Name_Read,
          Expressions    => New_List (
            New_Occurrence_Of (Stream_Parameter, Loc),
            New_Occurrence_Of (Source_Partition, Loc))),

        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
          Attribute_Name =>
            Name_Read,
          Expressions    => New_List (
            New_Occurrence_Of (Stream_Parameter, Loc),
            New_Occurrence_Of (Source_Receiver, Loc))),

        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
          Attribute_Name =>
            Name_Read,
          Expressions    => New_List (
            New_Occurrence_Of (Stream_Parameter, Loc),
            New_Occurrence_Of (Source_Address, Loc))));

      --  If the Address is Null_Address, then return a null object

      Append_To (Statements,
        Make_Implicit_If_Statement (RACW_Type,
          Condition       =>
            Make_Op_Eq (Loc,
              Left_Opnd  => New_Occurrence_Of (Source_Address, Loc),
              Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
          Then_Statements => New_List (
            Make_Assignment_Statement (Loc,
              Name       => New_Occurrence_Of (Result, Loc),
              Expression => Make_Null (Loc)),
            Make_Return_Statement (Loc))));

      --  If the RACW denotes an object created on the current partition, then
      --  Local_Statements will be executed. The real object will be used.

      Local_Statements := New_List (
        Make_Assignment_Statement (Loc,
          Name       => New_Occurrence_Of (Result, Loc),
          Expression =>
            Unchecked_Convert_To (RACW_Type,
              OK_Convert_To (RTE (RE_Address),
                New_Occurrence_Of (Source_Address, Loc)))));

      --  If the object is located on another partition, then a stub object
      --  will be created with all the information needed to rebuild the
      --  real object at the other end.

      Remote_Statements := New_List (

        Make_Assignment_Statement (Loc,
          Name       => New_Occurrence_Of (Stubbed_Result, Loc),
          Expression =>
            Make_Allocator (Loc,
              New_Occurrence_Of (Stub_Type, Loc))),

        Make_Assignment_Statement (Loc,
          Name       => Make_Selected_Component (Loc,
            Prefix        => New_Occurrence_Of (Stubbed_Result, Loc),
            Selector_Name => Make_Identifier (Loc, Name_Origin)),
          Expression =>
            New_Occurrence_Of (Source_Partition, Loc)),

        Make_Assignment_Statement (Loc,
          Name       => Make_Selected_Component (Loc,
            Prefix        => New_Occurrence_Of (Stubbed_Result, Loc),
            Selector_Name => Make_Identifier (Loc, Name_Receiver)),
          Expression =>
            New_Occurrence_Of (Source_Receiver, Loc)),

        Make_Assignment_Statement (Loc,
          Name       => Make_Selected_Component (Loc,
            Prefix        => New_Occurrence_Of (Stubbed_Result, Loc),
            Selector_Name => Make_Identifier (Loc, Name_Addr)),
          Expression =>
            New_Occurrence_Of (Source_Address, Loc)));

      Append_To (Remote_Statements,
        Make_Assignment_Statement (Loc,
          Name       => Make_Selected_Component (Loc,
            Prefix        => New_Occurrence_Of (Stubbed_Result, Loc),
            Selector_Name => Make_Identifier (Loc, Name_Asynchronous)),
          Expression =>
            New_Occurrence_Of (Asynchronous_Flag, Loc)));

      Append_To (Remote_Statements,
        Make_Procedure_Call_Statement (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
          Parameter_Associations => New_List (
            Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
              New_Occurrence_Of (Stubbed_Result, Loc)))));

      Append_To (Remote_Statements,
        Make_Assignment_Statement (Loc,
          Name       => New_Occurrence_Of (Result, Loc),
          Expression => Unchecked_Convert_To (RACW_Type,
            New_Occurrence_Of (Stubbed_Result, Loc))));

      --  Distinguish between the local and remote cases, and execute the
      --  appropriate piece of code.

      Append_To (Statements,
        Make_Implicit_If_Statement (RACW_Type,
          Condition       =>
            Make_Op_Eq (Loc,
              Left_Opnd  =>
                Make_Function_Call (Loc,
                  Name =>
                    New_Occurrence_Of (RTE (RE_Get_Local_Partition_Id), Loc)),
              Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
          Then_Statements => Local_Statements,
          Else_Statements => Remote_Statements));

      Proc_Spec :=
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       =>
            Make_Defining_Identifier (Loc, Procedure_Name),

          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier => Stream_Parameter,
              Parameter_Type      =>
                Make_Access_Definition (Loc,
                  Subtype_Mark =>
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (RTE (RE_Root_Stream_Type), Loc),
                      Attribute_Name =>
                        Name_Class))),

            Make_Parameter_Specification (Loc,
              Defining_Identifier => Result,
              Out_Present         => True,
              Parameter_Type      =>
                New_Occurrence_Of (RACW_Type, Loc))));

      Proc_Body_Spec :=
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       =>
            Make_Defining_Identifier (Loc, Procedure_Name),

          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Chars (Stream_Parameter)),
              Parameter_Type      =>
                Make_Access_Definition (Loc,
                  Subtype_Mark =>
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (RTE (RE_Root_Stream_Type), Loc),
                      Attribute_Name =>
                        Name_Class))),

            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Chars (Result)),
              Out_Present         => True,
              Parameter_Type      =>
                New_Occurrence_Of (RACW_Type, Loc))));

      Body_Node :=
        Make_Subprogram_Body (Loc,
          Specification              => Proc_Body_Spec,
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Statements));

      Proc_Decl :=
        Make_Subprogram_Declaration (Loc, Specification => Proc_Spec);

      Attr_Decl :=
        Make_Attribute_Definition_Clause (Loc,
          Name       => New_Occurrence_Of (RACW_Type, Loc),
          Chars      => Name_Read,
          Expression =>
            New_Occurrence_Of (Defining_Unit_Name (Proc_Spec), Loc));

      Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
      Insert_After (Proc_Decl, Attr_Decl);
      Append_To (Declarations, Body_Node);
   end Add_RACW_Read_Attribute;

   ------------------------------------
   -- Add_RACW_Read_Write_Attributes --
   ------------------------------------

   procedure Add_RACW_Read_Write_Attributes
     (RACW_Type           : in Entity_Id;
      Stub_Type           : in Entity_Id;
      Stub_Type_Access    : in Entity_Id;
      Object_RPC_Receiver : in Entity_Id;
      Declarations        : in List_Id)
   is
   begin
      Add_RACW_Write_Attribute
        (RACW_Type           => RACW_Type,
         Stub_Type           => Stub_Type,
         Stub_Type_Access    => Stub_Type_Access,
         Object_RPC_Receiver => Object_RPC_Receiver,
         Declarations        => Declarations);

      Add_RACW_Read_Attribute
        (RACW_Type        => RACW_Type,
         Stub_Type        => Stub_Type,
         Stub_Type_Access => Stub_Type_Access,
         Declarations     => Declarations);
   end Add_RACW_Read_Write_Attributes;

   ------------------------------
   -- Add_RACW_Write_Attribute --
   ------------------------------

   procedure Add_RACW_Write_Attribute
     (RACW_Type           : in Entity_Id;
      Stub_Type           : in Entity_Id;
      Stub_Type_Access    : in Entity_Id;
      Object_RPC_Receiver : in Entity_Id;
      Declarations        : in List_Id)
   is
      Loc  : constant Source_Ptr := Sloc (RACW_Type);

      Proc_Spec      : Node_Id;

      Proc_Body_Spec : Node_Id;

      Body_Node      : Node_Id;

      Proc_Decl      : Node_Id;
      Attr_Decl      : Node_Id;

      Statements        : List_Id;
      Local_Statements  : List_Id;
      Remote_Statements : List_Id;
      Null_Statements   : List_Id;

      Procedure_Name    : constant Name_Id := New_Internal_Name ('R');

      Stream_Parameter : constant Entity_Id  :=
                           Make_Defining_Identifier
                             (Loc, New_Internal_Name ('S'));

      Object : constant Entity_Id   :=
                 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

   begin
      --  Build the code fragment corresponding to the marshalling of a
      --  local object.

      Local_Statements := New_List (

        Pack_Entity_Into_Stream_Access (Loc,
          Stream => Stream_Parameter,
          Object => RTE (RE_Get_Local_Partition_Id)),

        Pack_Node_Into_Stream_Access (Loc,
          Stream => Stream_Parameter,
          Object => OK_Convert_To (RTE (RE_Unsigned_64),
            Make_Attribute_Reference (Loc,
              Prefix         => New_Occurrence_Of (Object_RPC_Receiver, Loc),
              Attribute_Name => Name_Address)),
          Etyp   => RTE (RE_Unsigned_64)),

        Pack_Node_Into_Stream_Access (Loc,
          Stream => Stream_Parameter,
          Object => OK_Convert_To (RTE (RE_Unsigned_64),
            Make_Attribute_Reference (Loc,
              Prefix         =>
                Make_Explicit_Dereference (Loc,
                  Prefix => New_Occurrence_Of (Object, Loc)),
              Attribute_Name => Name_Address)),
          Etyp   => RTE (RE_Unsigned_64)));

      --  Build the code fragment corresponding to the marshalling of
      --  a remote object.

      Remote_Statements := New_List (

        Pack_Node_Into_Stream_Access (Loc,
         Stream => Stream_Parameter,
         Object =>
            Make_Selected_Component (Loc,
              Prefix        => Unchecked_Convert_To (Stub_Type_Access,
                New_Occurrence_Of (Object, Loc)),
              Selector_Name =>
                Make_Identifier (Loc, Name_Origin)),
         Etyp   => RTE (RE_Partition_ID)),

        Pack_Node_Into_Stream_Access (Loc,
         Stream => Stream_Parameter,
         Object =>
            Make_Selected_Component (Loc,
              Prefix        => Unchecked_Convert_To (Stub_Type_Access,
                New_Occurrence_Of (Object, Loc)),
              Selector_Name =>
                Make_Identifier (Loc, Name_Receiver)),
         Etyp   => RTE (RE_Unsigned_64)),

        Pack_Node_Into_Stream_Access (Loc,
         Stream => Stream_Parameter,
         Object =>
            Make_Selected_Component (Loc,
              Prefix        => Unchecked_Convert_To (Stub_Type_Access,
                New_Occurrence_Of (Object, Loc)),
              Selector_Name =>
                Make_Identifier (Loc, Name_Addr)),
         Etyp   => RTE (RE_Unsigned_64)));

      --  Build the code fragment corresponding to the marshalling of a null
      --  object.

      Null_Statements := New_List (

        Pack_Entity_Into_Stream_Access (Loc,
          Stream => Stream_Parameter,
          Object => RTE (RE_Get_Local_Partition_Id)),

        Pack_Node_Into_Stream_Access (Loc,
          Stream => Stream_Parameter,
          Object => OK_Convert_To (RTE (RE_Unsigned_64),
            Make_Attribute_Reference (Loc,
              Prefix         => New_Occurrence_Of (Object_RPC_Receiver, Loc),
              Attribute_Name => Name_Address)),
          Etyp   => RTE (RE_Unsigned_64)),

        Pack_Node_Into_Stream_Access (Loc,
          Stream => Stream_Parameter,
          Object => Make_Integer_Literal (Loc, Uint_0),
          Etyp   => RTE (RE_Unsigned_64)));

      Statements := New_List (
        Make_Implicit_If_Statement (RACW_Type,
          Condition       =>
            Make_Op_Eq (Loc,
              Left_Opnd  => New_Occurrence_Of (Object, Loc),
              Right_Opnd => Make_Null (Loc)),
          Then_Statements => Null_Statements,
          Elsif_Parts     => New_List (
            Make_Elsif_Part (Loc,
              Condition       =>
                Make_Op_Eq (Loc,
                  Left_Opnd  =>
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Object, Loc),
                      Attribute_Name => Name_Tag),
                  Right_Opnd =>
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Stub_Type, Loc),
                      Attribute_Name => Name_Tag)),
              Then_Statements => Remote_Statements)),
          Else_Statements => Local_Statements));

      Proc_Spec :=
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       =>
            Make_Defining_Identifier (Loc, Procedure_Name),

          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier => Stream_Parameter,
              Parameter_Type      =>
                Make_Access_Definition (Loc,
                  Subtype_Mark =>
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (RTE (RE_Root_Stream_Type), Loc),
                      Attribute_Name =>
                        Name_Class))),

            Make_Parameter_Specification (Loc,
              Defining_Identifier => Object,
              In_Present          => True,
              Parameter_Type      =>
                New_Occurrence_Of (RACW_Type, Loc))));

      Proc_Decl :=
        Make_Subprogram_Declaration (Loc, Specification => Proc_Spec);

      Attr_Decl :=
        Make_Attribute_Definition_Clause (Loc,
          Name       => New_Occurrence_Of (RACW_Type, Loc),
          Chars      => Name_Write,
          Expression =>
            New_Occurrence_Of (Defining_Unit_Name (Proc_Spec), Loc));

      Proc_Body_Spec :=
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       =>
            Make_Defining_Identifier (Loc, Procedure_Name),

          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Chars (Stream_Parameter)),
              Parameter_Type      =>
                Make_Access_Definition (Loc,
                  Subtype_Mark =>
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (RTE (RE_Root_Stream_Type), Loc),
                      Attribute_Name =>
                        Name_Class))),

            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Chars (Object)),
              In_Present          => True,
              Parameter_Type      =>
                New_Occurrence_Of (RACW_Type, Loc))));

      Body_Node :=
        Make_Subprogram_Body (Loc,
          Specification              => Proc_Body_Spec,
          Declarations               => No_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Statements));

      Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
      Insert_After (Proc_Decl, Attr_Decl);
      Append_To (Declarations, Body_Node);
   end Add_RACW_Write_Attribute;

   ------------------------------
   -- Add_RAS_Access_Attribute --
   ------------------------------

   procedure Add_RAS_Access_Attribute (N : in Node_Id) is
      Ras_Type : constant Entity_Id := Defining_Identifier (N);
      Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
      --  Ras_Type is the access to subprogram type while Fat_Type points to
      --  the record type corresponding to a remote access to subprogram type.

      Proc_Decls        : constant List_Id := New_List;
      Proc_Statements   : constant List_Id := New_List;

      Proc_Spec : Node_Id;
      Proc_Body : Node_Id;

      Proc : Node_Id;

      Param        : Node_Id;
      Package_Name : Node_Id;
      Subp_Id      : Node_Id;
      Asynchronous : Node_Id;
      Return_Value : Node_Id;

      Loc : constant Source_Ptr := Sloc (N);

      procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id);
      --  Set a field name for the return value

      procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id)
      is
      begin
         Append_To (Proc_Statements,
           Make_Assignment_Statement (Loc,
             Name       =>
               Make_Selected_Component (Loc,
                 Prefix        => New_Occurrence_Of (Return_Value, Loc),
                 Selector_Name => Make_Identifier (Loc, Field_Name)),
             Expression => Value));
      end Set_Field;

   --  Start of processing for Add_RAS_Access_Attribute

   begin
      Param := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
      Package_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
      Asynchronous := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
      Return_Value := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

      --  Create the object which will be returned of type Fat_Type

      Append_To (Proc_Decls,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Return_Value,
          Object_Definition   =>
            New_Occurrence_Of (Fat_Type, Loc)));

      --  Initialize the fields of the record type with the appropriate data

      Set_Field (Name_Ras,
        OK_Convert_To (RTE (RE_Unsigned_64), New_Occurrence_Of (Param, Loc)));

      Set_Field (Name_Origin,
        Unchecked_Convert_To (Standard_Integer,
          Make_Function_Call (Loc,
            Name                   =>
              New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
            Parameter_Associations => New_List (
              New_Occurrence_Of (Package_Name, Loc)))));

      Set_Field (Name_Receiver,
        Make_Function_Call (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
          Parameter_Associations => New_List (
            New_Occurrence_Of (Package_Name, Loc))));

      Set_Field (Name_Subp_Id,
        New_Occurrence_Of (Subp_Id, Loc));

      Set_Field (Name_Async,
        New_Occurrence_Of (Asynchronous, Loc));

      --  Return the newly created value

      Append_To (Proc_Statements,
        Make_Return_Statement (Loc,
          Expression =>
            New_Occurrence_Of (Return_Value, Loc)));

      Proc := Make_Defining_Identifier (Loc, Name_uRAS_Access);

      Proc_Spec :=
        Make_Function_Specification (Loc,
          Defining_Unit_Name       => Proc,
          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier => Param,
              Parameter_Type      =>
                New_Occurrence_Of (RTE (RE_Address), Loc)),

            Make_Parameter_Specification (Loc,
              Defining_Identifier => Package_Name,
              Parameter_Type      =>
                New_Occurrence_Of (Standard_String, Loc)),

            Make_Parameter_Specification (Loc,
              Defining_Identifier => Subp_Id,
              Parameter_Type      =>
                New_Occurrence_Of (Standard_Natural, Loc)),

            Make_Parameter_Specification (Loc,
              Defining_Identifier => Asynchronous,
              Parameter_Type      =>
                New_Occurrence_Of (Standard_Boolean, Loc))),

         Subtype_Mark =>
           New_Occurrence_Of (Fat_Type, Loc));

      --  Set the kind and return type of the function to prevent ambiguities
      --  between Ras_Type and Fat_Type in subsequent analysis.

      Set_Ekind (Proc, E_Function);
      Set_Etype (Proc, New_Occurrence_Of (Fat_Type, Loc));

      Proc_Body :=
        Make_Subprogram_Body (Loc,
          Specification              => Proc_Spec,
          Declarations               => Proc_Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Proc_Statements));

      Set_TSS (Fat_Type, Proc);

   end Add_RAS_Access_Attribute;

   -----------------------------------
   -- Add_RAS_Dereference_Attribute --
   -----------------------------------

   procedure Add_RAS_Dereference_Attribute (N : in Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);

      Type_Def : constant Node_Id   := Type_Definition (N);

      Ras_Type : constant Entity_Id := Defining_Identifier (N);

      Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);

      Proc_Decls      : constant List_Id := New_List;
      Proc_Statements : constant List_Id := New_List;

      Inner_Decls      : constant List_Id := New_List;
      Inner_Statements : constant List_Id := New_List;

      Direct_Statements : constant List_Id := New_List;

      Proc : Node_Id;

      Proc_Spec : Node_Id;
      Proc_Body : Node_Id;

      Param_Specs : constant List_Id := New_List;
      Param_Assoc : constant List_Id := New_List;

      Pointer : Node_Id;

      Converted_Ras    : Node_Id;
      Target_Partition : Node_Id;
      RPC_Receiver     : Node_Id;
      Subprogram_Id    : Node_Id;
      Asynchronous     : Node_Id;

      Is_Function : constant Boolean :=
                      Nkind (Type_Def) = N_Access_Function_Definition;

      Spec : constant Node_Id := Type_Def;

      Current_Parameter : Node_Id;

   begin
      --  The way to do it is test if the Ras field is non-null and then if
      --  the Origin field is equal to the current partition ID (which is in
      --  fact Current_Package'Partition_ID). If this is the case, then it
      --  is safe to dereference the Ras field directly rather than
      --  performing a remote call.

      Pointer :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

      Target_Partition :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

      Append_To (Proc_Decls,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Target_Partition,
          Constant_Present    => True,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
          Expression          =>
            Unchecked_Convert_To (RTE (RE_Partition_ID),
              Make_Selected_Component (Loc,
                Prefix        =>
                  New_Occurrence_Of (Pointer, Loc),
                Selector_Name =>
                  Make_Identifier (Loc, Name_Origin)))));

      RPC_Receiver :=
        Make_Selected_Component (Loc,
          Prefix        =>
            New_Occurrence_Of (Pointer, Loc),
          Selector_Name =>
            Make_Identifier (Loc, Name_Receiver));

      Subprogram_Id :=
        Unchecked_Convert_To (RTE (RE_Subprogram_Id),
          Make_Selected_Component (Loc,
            Prefix        =>
              New_Occurrence_Of (Pointer, Loc),
            Selector_Name =>
              Make_Identifier (Loc, Name_Subp_Id)));

      --  A function is never asynchronous. A procedure may or may not be
      --  asynchronous depending on whether a pragma Asynchronous applies
      --  on it. Since a RAST may point onto various subprograms, this is
      --  only known at runtime so both versions (synchronous and asynchronous)
      --  must be built every times it is not a function.

      if Is_Function then
         Asynchronous := Empty;

      else
         Asynchronous :=
           Make_Selected_Component (Loc,
             Prefix        =>
               New_Occurrence_Of (Pointer, Loc),
             Selector_Name =>
               Make_Identifier (Loc, Name_Async));

      end if;

      if Present (Parameter_Specifications (Type_Def)) then
         Current_Parameter := First (Parameter_Specifications (Type_Def));

         while Current_Parameter /= Empty loop
            Append_To (Param_Specs,
              Make_Parameter_Specification (Loc,
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc,
                    Chars => Chars (Defining_Identifier (Current_Parameter))),
                In_Present        => In_Present (Current_Parameter),
                Out_Present       => Out_Present (Current_Parameter),
                Parameter_Type    =>
                  New_Occurrence_Of
                    (Etype (Parameter_Type (Current_Parameter)), Loc),
                Expression        =>
                  New_Copy_Tree (Expression (Current_Parameter))));

            Append_To (Param_Assoc,
              Make_Identifier (Loc,
                Chars => Chars (Defining_Identifier (Current_Parameter))));

            Next (Current_Parameter);
         end loop;
      end if;

      Proc := Make_Defining_Identifier (Loc, Name_uRAS_Dereference);

      if Is_Function then
         Proc_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name       => Proc,
             Parameter_Specifications => Param_Specs,
             Subtype_Mark             =>
               New_Occurrence_Of (
                 Entity (Subtype_Mark (Spec)), Loc));

         Set_Ekind (Proc, E_Function);

         Set_Etype (Proc,
           New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));

      else
         Proc_Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       => Proc,
             Parameter_Specifications => Param_Specs);

         Set_Ekind (Proc, E_Procedure);
         Set_Etype (Proc, Standard_Void_Type);
      end if;

      --  Build the calling stubs for the dereference of the RAS

      Build_General_Calling_Stubs
        (Decls                     => Inner_Decls,
         Statements                => Inner_Statements,
         Target_Partition          => Target_Partition,
         RPC_Receiver              => RPC_Receiver,
         Subprogram_Id             => Subprogram_Id,
         Asynchronous              => Asynchronous,
         Is_Known_Non_Asynchronous => Is_Function,
         Is_Function               => Is_Function,
         Spec                      => Proc_Spec,
         Nod                       => N);

      Converted_Ras :=
        Unchecked_Convert_To (Ras_Type,
          OK_Convert_To (RTE (RE_Address),
            Make_Selected_Component (Loc,
              Prefix        => New_Occurrence_Of (Pointer, Loc),
              Selector_Name => Make_Identifier (Loc, Name_Ras))));

      if Is_Function then
         Append_To (Direct_Statements,
           Make_Return_Statement (Loc,
             Expression =>
               Make_Function_Call (Loc,
                 Name                   =>
                   Make_Explicit_Dereference (Loc,
                     Prefix => Converted_Ras),
                 Parameter_Associations => Param_Assoc)));

      else
         Append_To (Direct_Statements,
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               Make_Explicit_Dereference (Loc,
                 Prefix => Converted_Ras),
             Parameter_Associations => Param_Assoc));
      end if;

      Prepend_To (Param_Specs,
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Pointer,
          In_Present          => True,
          Parameter_Type      =>
            New_Occurrence_Of (Fat_Type, Loc)));

      Append_To (Proc_Statements,
        Make_Implicit_If_Statement (N,
          Condition =>
            Make_And_Then (Loc,
              Left_Opnd  =>
                Make_Op_Ne (Loc,
                  Left_Opnd  =>
                    Make_Selected_Component (Loc,
                      Prefix        => New_Occurrence_Of (Pointer, Loc),
                      Selector_Name => Make_Identifier (Loc, Name_Ras)),
                  Right_Opnd =>
                    Make_Integer_Literal (Loc, Uint_0)),

              Right_Opnd =>
                Make_Op_Eq (Loc,
                  Left_Opnd  =>
                    New_Occurrence_Of (Target_Partition, Loc),
                  Right_Opnd =>
                    Make_Function_Call (Loc,
                      New_Occurrence_Of (
                        RTE (RE_Get_Local_Partition_Id), Loc)))),

          Then_Statements =>
            Direct_Statements,

          Else_Statements => New_List (
            Make_Block_Statement (Loc,
              Declarations               => Inner_Decls,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => Inner_Statements)))));

      Proc_Body :=
        Make_Subprogram_Body (Loc,
          Specification              => Proc_Spec,
          Declarations               => Proc_Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Proc_Statements));

      Set_TSS (Fat_Type, Defining_Unit_Name (Proc_Spec));

   end Add_RAS_Dereference_Attribute;

   -----------------------
   -- Add_RAST_Features --
   -----------------------

   procedure Add_RAST_Features (Vis_Decl : Node_Id) is
   begin
      --  Do not add attributes more than once in any case. This should
      --  be replaced by an assert or this comment removed if we decide
      --  that this is normal to be called several times ???

      if Present (TSS (Equivalent_Type (Defining_Identifier
           (Vis_Decl)), Name_uRAS_Access))
      then
         return;
      end if;

      Add_RAS_Dereference_Attribute (Vis_Decl);
      Add_RAS_Access_Attribute (Vis_Decl);
   end Add_RAST_Features;

   -----------------------------------------
   -- Add_Receiving_Stubs_To_Declarations --
   -----------------------------------------

   procedure Add_Receiving_Stubs_To_Declarations
     (Pkg_Spec : in Node_Id;
      Decls    : in List_Id)
   is
      Loc : constant Source_Ptr := Sloc (Pkg_Spec);

      Stream_Parameter : Node_Id;
      Result_Parameter : Node_Id;

      Pkg_RPC_Receiver            : Node_Id;
      Pkg_RPC_Receiver_Spec       : Node_Id;
      Pkg_RPC_Receiver_Formals    : List_Id;
      Pkg_RPC_Receiver_Decls      : List_Id;
      Pkg_RPC_Receiver_Statements : List_Id;
      Pkg_RPC_Receiver_Cases      : List_Id := New_List;
      Pkg_RPC_Receiver_Body       : Node_Id;
      --  A Pkg_RPC_Receiver is built to decode the request

      Subp_Id                     : Node_Id;
      --  Subprogram_Id as read from the incoming stream

      Current_Declaration       : Node_Id;
      Current_Subprogram_Number : Int := 0;
      Current_Stubs             : Node_Id;

      Actuals : List_Id;

      Dummy_Register_Name : Name_Id;
      Dummy_Register_Spec : Node_Id;
      Dummy_Register_Decl : Node_Id;
      Dummy_Register_Body : Node_Id;

   begin
      --  Building receiving stubs consist in several operations:

      --    - a package RPC receiver must be built. This subprogram
      --      will get a Subprogram_Id from the incoming stream
      --      and will dispatch the call to the right subprogram

      --    - a receiving stub for any subprogram visible in the package
      --      spec. This stub will read all the parameters from the stream,
      --      and put the result as well as the exception occurrence in the
      --      output stream

      --    - a dummy package with an empty spec and a body made of an
      --      elaboration part, whose job is to register the receiving
      --      part of this RCI package on the name server. This is done
      --      by calling System.Partition_Interface.Register_Receiving_Stub

      Stream_Parameter :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      Result_Parameter :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
      Subp_Id :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

      Pkg_RPC_Receiver :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

      --  The parameters of the package RPC receiver are made of two
      --  streams, an input one and an output one.

      Pkg_RPC_Receiver_Formals := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Stream_Parameter,
          Parameter_Type      =>
            Make_Access_Definition (Loc,
              Subtype_Mark =>
                New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Result_Parameter,
          Parameter_Type      =>
            Make_Access_Definition (Loc,
              Subtype_Mark =>
                New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))));

      Pkg_RPC_Receiver_Spec :=
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       => Pkg_RPC_Receiver,
          Parameter_Specifications => Pkg_RPC_Receiver_Formals);

      Pkg_RPC_Receiver_Decls := New_List (
        Make_Object_Declaration (Loc,
          Defining_Identifier => Subp_Id,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));

      Pkg_RPC_Receiver_Statements := New_List (
        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
          Attribute_Name =>
            Name_Read,
          Expressions    => New_List (
            New_Occurrence_Of (Stream_Parameter, Loc),
            New_Occurrence_Of (Subp_Id, Loc))));

      --  For each subprogram, the receiving stub will be built and a
      --  case statement will be made on the Subprogram_Id to dispatch
      --  to the right subprogram.

      Current_Declaration := First (Visible_Declarations (Pkg_Spec));

      while Current_Declaration /= Empty loop

         if Nkind (Current_Declaration) = N_Subprogram_Declaration
           and then Comes_From_Source (Current_Declaration)
         then
            pragma Assert (Current_Subprogram_Number =
              Get_Subprogram_Id (Defining_Unit_Name (Specification (
                Current_Declaration))));

            Current_Stubs :=
              Build_Subprogram_Receiving_Stubs
                (Vis_Decl     => Current_Declaration,
                 Asynchronous =>
                   Nkind (Specification (Current_Declaration)) =
                       N_Procedure_Specification
                     and then Is_Asynchronous
                       (Defining_Unit_Name (Specification
                          (Current_Declaration))));

            Append_To (Decls, Current_Stubs);

            Analyze (Current_Stubs);

            Actuals := New_List (New_Occurrence_Of (Stream_Parameter, Loc));

            if Nkind (Specification (Current_Declaration))
                = N_Function_Specification
              or else
                not Is_Asynchronous (
                  Defining_Entity (Specification (Current_Declaration)))
            then
               --  An asynchronous procedure does not want an output parameter
               --  since no result and no exception will ever be returned.

               Append_To (Actuals,
                 New_Occurrence_Of (Result_Parameter, Loc));

            end if;

            Append_To (Pkg_RPC_Receiver_Cases,
              Make_Case_Statement_Alternative (Loc,
                Discrete_Choices =>
                  New_List (
                    Make_Integer_Literal (Loc, Current_Subprogram_Number)),

                Statements       =>
                  New_List (
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of (
                          Defining_Entity (Current_Stubs), Loc),
                      Parameter_Associations =>
                        Actuals))));

            Current_Subprogram_Number := Current_Subprogram_Number + 1;
         end if;

         Next (Current_Declaration);
      end loop;

      --  If we receive an invalid Subprogram_Id, it is best to do nothing
      --  rather than raising an exception since we do not want someone
      --  to crash a remote partition by sending invalid subprogram ids.
      --  This is consistent with the other parts of the case statement
      --  since even in presence of incorrect parameters in the stream,
      --  every exception will be caught and (if the subprogram is not an
      --  APC) put into the result stream and sent away.

      Append_To (Pkg_RPC_Receiver_Cases,
        Make_Case_Statement_Alternative (Loc,
          Discrete_Choices =>
            New_List (Make_Others_Choice (Loc)),
          Statements       =>
            New_List (Make_Null_Statement (Loc))));

      Append_To (Pkg_RPC_Receiver_Statements,
        Make_Case_Statement (Loc,
          Expression   =>
            New_Occurrence_Of (Subp_Id, Loc),
          Alternatives => Pkg_RPC_Receiver_Cases));

      Pkg_RPC_Receiver_Body :=
        Make_Subprogram_Body (Loc,
          Specification              => Pkg_RPC_Receiver_Spec,
          Declarations               => Pkg_RPC_Receiver_Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Pkg_RPC_Receiver_Statements));

      Append_To (Decls, Pkg_RPC_Receiver_Body);
      Analyze (Pkg_RPC_Receiver_Body);

      --  Construction of the dummy package used to register the package
      --  receiving stubs on the nameserver.

      Dummy_Register_Name := New_Internal_Name ('P');

      Dummy_Register_Spec :=
        Make_Package_Specification (Loc,
          Defining_Unit_Name   =>
            Make_Defining_Identifier (Loc, Dummy_Register_Name),
          Visible_Declarations => No_List,
          End_Label => Empty);

      Dummy_Register_Decl :=
        Make_Package_Declaration (Loc,
          Specification => Dummy_Register_Spec);

      Append_To (Decls,
        Dummy_Register_Decl);
      Analyze (Dummy_Register_Decl);

      Dummy_Register_Body :=
        Make_Package_Body (Loc,
          Defining_Unit_Name         =>
            Make_Defining_Identifier (Loc, Dummy_Register_Name),
          Declarations               => No_List,

          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (
                Make_Procedure_Call_Statement (Loc,
                  Name                   =>
                    New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),

                  Parameter_Associations => New_List (
                    Make_String_Literal (Loc,
                      Strval => Get_Pkg_Name_String_Id (Pkg_Spec)),
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
                      Attribute_Name =>
                        Name_Unrestricted_Access),
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
                      Attribute_Name =>
                        Name_Version))))));

      Append_To (Decls, Dummy_Register_Body);
      Analyze (Dummy_Register_Body);
   end Add_Receiving_Stubs_To_Declarations;

   -------------------
   -- Add_Stub_Type --
   -------------------

   procedure Add_Stub_Type
     (Designated_Type     : in Entity_Id;
      RACW_Type           : in Entity_Id;
      Decls               : in List_Id;
      Stub_Type           : out Entity_Id;
      Stub_Type_Access    : out Entity_Id;
      Object_RPC_Receiver : out Entity_Id;
      Existing            : out Boolean)
   is
      Loc : constant Source_Ptr := Sloc (RACW_Type);

      Stub_Elements : constant Stub_Structure :=
                        Stubs_Table.Get (Designated_Type);

      Stub_Type_Declaration           : Node_Id;
      Stub_Type_Access_Declaration    : Node_Id;
      Object_RPC_Receiver_Declaration : Node_Id;

      RPC_Receiver_Stream             : Entity_Id;
      RPC_Receiver_Result             : Entity_Id;

   begin
      if Stub_Elements /= Empty_Stub_Structure then
         Stub_Type           := Stub_Elements.Stub_Type;
         Stub_Type_Access    := Stub_Elements.Stub_Type_Access;
         Object_RPC_Receiver := Stub_Elements.Object_RPC_Receiver;
         Existing            := True;
         return;
      end if;

      Existing            := False;
      Stub_Type           :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      Stub_Type_Access    :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      Object_RPC_Receiver :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
      RPC_Receiver_Stream :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      RPC_Receiver_Result :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      Stubs_Table.Set (Designated_Type,
        (Stub_Type           => Stub_Type,
         Stub_Type_Access    => Stub_Type_Access,
         Object_RPC_Receiver => Object_RPC_Receiver,
         RPC_Receiver_Stream => RPC_Receiver_Stream,
         RPC_Receiver_Result => RPC_Receiver_Result,
         RACW_Type           => RACW_Type));

      --  The stub type definition below must match exactly the one in
      --  s-parint.ads, since unchecked conversions will be used in
      --  s-parint.adb to modify pointers passed to Get_Unique_Remote_Pointer.

      Stub_Type_Declaration :=
        Make_Full_Type_Declaration (Loc,
          Defining_Identifier => Stub_Type,
          Type_Definition     =>
            Make_Record_Definition (Loc,
              Tagged_Present  => True,
              Limited_Present => True,
              Component_List  =>
                Make_Component_List (Loc,
                  Component_Items => New_List (

                    Make_Component_Declaration (Loc,
                      Defining_Identifier =>
                        Make_Defining_Identifier (Loc, Name_Origin),
                      Subtype_Indication  =>
                        New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),

                    Make_Component_Declaration (Loc,
                      Defining_Identifier =>
                        Make_Defining_Identifier (Loc, Name_Receiver),
                      Subtype_Indication  =>
                        New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),

                    Make_Component_Declaration (Loc,
                      Defining_Identifier =>
                        Make_Defining_Identifier (Loc, Name_Addr),
                      Subtype_Indication  =>
                        New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),

                    Make_Component_Declaration (Loc,
                      Defining_Identifier =>
                        Make_Defining_Identifier (Loc, Name_Asynchronous),
                      Subtype_Indication  =>
                        New_Occurrence_Of (Standard_Boolean, Loc))))));

      Append_To (Decls, Stub_Type_Declaration);
      Analyze (Stub_Type_Declaration);

      --  This is in no way a type derivation, but we fake it to make
      --  sure that the dispatching table gets built with the corresponding
      --  primitive operations at the right place.

      Derive_Subprograms (Parent_Type  => Designated_Type,
                          Derived_Type => Stub_Type);

      Stub_Type_Access_Declaration :=
        Make_Full_Type_Declaration (Loc,
          Defining_Identifier => Stub_Type_Access,
          Type_Definition     =>
            Make_Access_To_Object_Definition (Loc,
              Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));

      Append_To (Decls, Stub_Type_Access_Declaration);
      Analyze (Stub_Type_Access_Declaration);

      Object_RPC_Receiver_Declaration :=
        Make_Subprogram_Declaration (Loc,
          Make_Procedure_Specification (Loc,
            Defining_Unit_Name       => Object_RPC_Receiver,
            Parameter_Specifications => New_List (
              Make_Parameter_Specification (Loc,
                Defining_Identifier => RPC_Receiver_Stream,
                Parameter_Type      =>
                  Make_Access_Definition (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),

              Make_Parameter_Specification (Loc,
                Defining_Identifier => RPC_Receiver_Result,
                Parameter_Type      =>
                  Make_Access_Definition (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of
                        (RTE (RE_Params_Stream_Type), Loc))))));

      Append_To (Decls, Object_RPC_Receiver_Declaration);
   end Add_Stub_Type;

   ---------------------------------
   -- Build_General_Calling_Stubs --
   ---------------------------------

   procedure Build_General_Calling_Stubs
     (Decls                     : List_Id;
      Statements                : List_Id;
      Target_Partition          : Entity_Id;
      RPC_Receiver              : Node_Id;
      Subprogram_Id             : Node_Id;
      Asynchronous              : Node_Id   := Empty;
      Is_Known_Asynchronous     : Boolean   := False;
      Is_Known_Non_Asynchronous : Boolean   := False;
      Is_Function               : Boolean;
      Spec                      : Node_Id;
      Object_Type               : Entity_Id := Empty;
      Nod                       : Node_Id)
   is
      Loc : constant Source_Ptr := Sloc (Nod);

      Stream_Parameter : Node_Id;
      --  Name of the stream used to transmit parameters to the remote package

      Result_Parameter : Node_Id;
      --  Name of the result parameter (in non-APC cases) which get the
      --  result of the remote subprogram.

      Exception_Return_Parameter : Node_Id;
      --  Name of the parameter which will hold the exception sent by the
      --  remote subprogram.

      Current_Parameter : Node_Id;
      --  Current parameter being handled

      Ordered_Parameters_List : constant List_Id :=
                                  Build_Ordered_Parameters_List (Spec);

      Asynchronous_Statements     : List_Id := No_List;
      Non_Asynchronous_Statements : List_Id := No_List;
      --  Statements specifics to the Asynchronous/Non-Asynchronous cases.

      Extra_Formal_Statements : constant List_Id := New_List;
      --  List of statements for extra formal parameters. It will appear after
      --  the regular statements for writing out parameters.

   begin
      --  The general form of a calling stub for a given subprogram is:

      --    procedure X (...) is
      --      P : constant Partition_ID := RCI_Cache.Get_Active_Partition_ID;
      --      Stream, Result : aliased System.RPC.Params_Stream_Type (0);
      --    begin
      --       Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
      --                  comes from RCI_Cache.Get_RCI_Package_Receiver)
      --       Put_Subprogram_Id_In_Stream;
      --       Put_Parameters_In_Stream;
      --       Do_RPC (Stream, Result);
      --       Read_Exception_Occurrence_From_Result; Raise_It;
      --       Read_Out_Parameters_And_Function_Return_From_Stream;
      --    end X;

      --  There are some variations: Do_APC is called for an asynchronous
      --  procedure and the part after the call is completely ommitted
      --  as well as the declaration of Result. For a function call,
      --  'Input is always used to read the result even if it is constrained.

      Stream_Parameter :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));

      Append_To (Decls,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Stream_Parameter,
          Aliased_Present     => True,
          Object_Definition   =>
            Make_Subtype_Indication (Loc,
              Subtype_Mark =>
                New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
              Constraint   =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints =>
                    New_List (Make_Integer_Literal (Loc, 0))))));

      if not Is_Known_Asynchronous then
         Result_Parameter :=
           Make_Defining_Identifier (Loc, New_Internal_Name ('R'));

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Result_Parameter,
             Aliased_Present     => True,
             Object_Definition   =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark =>
                   New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
                 Constraint   =>
                   Make_Index_Or_Discriminant_Constraint (Loc,
                     Constraints =>
                       New_List (Make_Integer_Literal (Loc, 0))))));

         Exception_Return_Parameter :=
           Make_Defining_Identifier (Loc, New_Internal_Name ('E'));

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Exception_Return_Parameter,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));

      else
         Result_Parameter := Empty;
         Exception_Return_Parameter := Empty;
      end if;

      --  Put first the RPC receiver corresponding to the remote package

      Append_To (Statements,
        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
          Attribute_Name => Name_Write,
          Expressions    => New_List (
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of (Stream_Parameter, Loc),
              Attribute_Name =>
                Name_Access),
            RPC_Receiver)));

      --  Then put the Subprogram_Id of the subprogram we want to call in
      --  the stream.

      Append_To (Statements,
        Make_Attribute_Reference (Loc,
          Prefix         =>
            New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
          Attribute_Name =>
            Name_Write,
          Expressions      => New_List (
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of (Stream_Parameter, Loc),
              Attribute_Name => Name_Access),
            Subprogram_Id)));

      Current_Parameter := First (Ordered_Parameters_List);

      while Current_Parameter /= Empty loop

         if Is_RACW_Controlling_Formal (Current_Parameter, Object_Type) then

            --  In the case of a controlling formal argument, we marshall
            --  its addr field rather than the local stub.

            Append_To (Statements,
               Pack_Node_Into_Stream (Loc,
                 Stream => Stream_Parameter,
                 Object =>
                   Make_Selected_Component (Loc,
                     Prefix        =>
                       New_Occurrence_Of (
                         Defining_Identifier (Current_Parameter), Loc),
                     Selector_Name =>
                       Make_Identifier (Loc, Name_Addr)),
                 Etyp   => RTE (RE_Unsigned_64)));

         else
            declare
               Etyp : constant Entity_Id :=
                        Etype (Parameter_Type (Current_Parameter));

               Constrained : constant Boolean :=
                               Is_Constrained (Etyp)
                                 or else Is_Elementary_Type (Etyp);

            begin
               if In_Present (Current_Parameter)
                 or else not Out_Present (Current_Parameter)
                 or else not Constrained
               then
                  Append_To (Statements,
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (Etyp, Loc),
                      Attribute_Name => Output_From_Constrained (Constrained),
                      Expressions    => New_List (
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of (Stream_Parameter, Loc),
                          Attribute_Name => Name_Access),
                        New_Occurrence_Of (
                          Defining_Identifier (Current_Parameter), Loc))));
               end if;
            end;
         end if;

         --  If the current parameter has a dynamic constrained status,
         --  then this status is transmitted as well.
         --  This should be done for accessibility as well ???

         if Nkind (Parameter_Type (Current_Parameter)) /= N_Access_Definition
           and then Need_Extra_Constrained (Current_Parameter)
         then
            --  In this block, we do not use the extra formal that has been
            --  created because it does not exist at the time of expansion
            --  when building calling stubs for remote access to subprogram
            --  types. We create an extra variable of this type and push it
            --  in the stream after the regular parameters.

            declare
               Extra_Parameter : constant Entity_Id :=
                                   Make_Defining_Identifier
                                     (Loc, New_Internal_Name ('P'));

            begin
               Append_To (Decls,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Extra_Parameter,
                   Constant_Present    => True,
                   Object_Definition   =>
                     New_Occurrence_Of (Standard_Boolean, Loc),
                   Expression          =>
                     Make_Attribute_Reference (Loc,
                       Prefix         =>
                         New_Occurrence_Of (
                           Defining_Identifier (Current_Parameter), Loc),
                       Attribute_Name => Name_Constrained)));

               Append_To (Extra_Formal_Statements,
                 Make_Attribute_Reference (Loc,
                   Prefix         =>
                     New_Occurrence_Of (Standard_Boolean, Loc),
                   Attribute_Name =>
                     Name_Write,
                   Expressions    => New_List (
                     Make_Attribute_Reference (Loc,
                       Prefix         =>
                         New_Occurrence_Of (Stream_Parameter, Loc),
                       Attribute_Name =>
                         Name_Access),
                     New_Occurrence_Of (Extra_Parameter, Loc))));
            end;
         end if;

         Next (Current_Parameter);
      end loop;

      --  Append the formal statements list to the statements

      Append_List_To (Statements, Extra_Formal_Statements);

      if not Is_Known_Non_Asynchronous then

         --  Build the call to System.RPC.Do_APC

         Asynchronous_Statements := New_List (
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Target_Partition, Loc),
               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   New_Occurrence_Of (Stream_Parameter, Loc),
                 Attribute_Name =>
                   Name_Access))));
      else
         Asynchronous_Statements := No_List;
      end if;

      if not Is_Known_Asynchronous then

         --  Build the call to System.RPC.Do_RPC

         Non_Asynchronous_Statements := New_List (
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Target_Partition, Loc),

               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   New_Occurrence_Of (Stream_Parameter, Loc),
                 Attribute_Name =>
                   Name_Access),

               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   New_Occurrence_Of (Result_Parameter, Loc),
                 Attribute_Name =>
                   Name_Access))));

         --  Read the exception occurrence from the result stream and
         --  reraise it. It does no harm if this is a Null_Occurrence since
         --  this does nothing.

         Append_To (Non_Asynchronous_Statements,
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),

             Attribute_Name =>
               Name_Read,

             Expressions    => New_List (
               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   New_Occurrence_Of (Result_Parameter, Loc),
                 Attribute_Name =>
                   Name_Access),
               New_Occurrence_Of (Exception_Return_Parameter, Loc))));

         Append_To (Non_Asynchronous_Statements,
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Exception_Return_Parameter, Loc))));

         if Is_Function then

            --  If this is a function call, then read the value and return
            --  it. The return value is written/read using 'Output/'Input.

            Append_To (Non_Asynchronous_Statements,
              Make_Tag_Check (Loc,
                Make_Return_Statement (Loc,
                  Expression =>
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (
                          Etype (Subtype_Mark (Spec)), Loc),

                      Attribute_Name => Name_Input,

                      Expressions    => New_List (
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of (Result_Parameter, Loc),
                          Attribute_Name => Name_Access))))));

         else
            --  Loop around parameters and assign out (or in out) parameters.
            --  In the case of RACW, controlling arguments cannot possibly
            --  have changed since they are remote, so we do not read them
            --  from the stream.

            Current_Parameter :=
              First (Ordered_Parameters_List);

            while Current_Parameter /= Empty loop

               if Out_Present (Current_Parameter)
                 and then
                   Etype (Parameter_Type (Current_Parameter)) /= Object_Type
               then
                  Append_To (Non_Asynchronous_Statements,
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        New_Occurrence_Of (
                          Etype (Parameter_Type (Current_Parameter)), Loc),

                      Attribute_Name => Name_Read,

                      Expressions    => New_List (
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of (Result_Parameter, Loc),
                          Attribute_Name =>
                            Name_Access),
                        New_Occurrence_Of (
                          Defining_Identifier (Current_Parameter), Loc))));
               end if;

               Next (Current_Parameter);
            end loop;
         end if;
      end if;

      if Is_Known_Asynchronous then
         Append_List_To (Statements, Asynchronous_Statements);

      elsif Is_Known_Non_Asynchronous then
         Append_List_To (Statements, Non_Asynchronous_Statements);

      else
         pragma Assert (Asynchronous /= Empty);
         Prepend_To (Asynchronous_Statements,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Standard_Boolean, Loc),
             Attribute_Name => Name_Write,
             Expressions    => New_List (
               Make_Attribute_Reference (Loc,
                 Prefix         => New_Occurrence_Of (Stream_Parameter, Loc),
                 Attribute_Name => Name_Access),
               New_Occurrence_Of (Standard_True, Loc))));
         Prepend_To (Non_Asynchronous_Statements,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Standard_Boolean, Loc),
             Attribute_Name => Name_Write,
             Expressions    => New_List (
               Make_Attribute_Reference (Loc,
                 Prefix         => New_Occurrence_Of (Stream_Parameter, Loc),
                 Attribute_Name => Name_Access),
               New_Occurrence_Of (Standard_False, Loc))));
         Append_To (Statements,
           Make_Implicit_If_Statement (Nod,
             Condition       => Asynchronous,
             Then_Statements => Asynchronous_Statements,
             Else_Statements => Non_Asynchronous_Statements));
      end if;
   end Build_General_Calling_Stubs;

   -----------------------------------
   -- Build_Ordered_Parameters_List --
   -----------------------------------

   function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
      Constrained_List   : List_Id;
      Unconstrained_List : List_Id;
      Current_Parameter  : Node_Id;

   begin
      if not Present (Parameter_Specifications (Spec)) then
         return New_List;
      end if;

      Constrained_List   := New_List;
      Unconstrained_List := New_List;

      --  Loop through the parameters and add them to the right list

      Current_Parameter := First (Parameter_Specifications (Spec));
      while Current_Parameter /= Empty loop

         if Nkind (Parameter_Type (Current_Parameter)) = N_Access_Definition
             or else
           Is_Constrained (Etype (Parameter_Type (Current_Parameter)))
             or else
           Is_Elementary_Type (Etype (Parameter_Type (Current_Parameter)))
         then
            Append_To (Constrained_List, New_Copy (Current_Parameter));
         else
            Append_To (Unconstrained_List, New_Copy (Current_Parameter));
         end if;

         Next (Current_Parameter);
      end loop;

      --  Unconstrained parameters are returned first

      Append_List_To (Unconstrained_List, Constrained_List);

      return Unconstrained_List;

   end Build_Ordered_Parameters_List;

   ----------------------------------
   -- Build_Passive_Partition_Stub --
   ----------------------------------

   procedure Build_Passive_Partition_Stub (U : Node_Id) is
      Pkg_Spec : Node_Id;
      L        : List_Id;
      Reg      : Node_Id;
      Loc      : constant Source_Ptr := Sloc (U);
      Dist_OK  : Entity_Id;

   begin
      --  Verify that the implementation supports distribution, by accessing
      --  a type defined in the proper version of system.rpc

      Dist_OK := RTE (RE_Params_Stream_Type);

      --  Use body if present, spec otherwise

      if Nkind (U) = N_Package_Declaration then
         Pkg_Spec := Specification (U);
         L := Visible_Declarations (Pkg_Spec);
      else
         Pkg_Spec := Parent (Corresponding_Spec (U));
         L := Declarations (U);
      end if;

      Reg :=
        Make_Procedure_Call_Statement (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
          Parameter_Associations => New_List (
            Make_String_Literal (Loc, Get_Pkg_Name_String_Id (Pkg_Spec)),
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
              Attribute_Name =>
                Name_Version)));
      Append_To (L, Reg);
      Analyze (Reg);
   end Build_Passive_Partition_Stub;

   ------------------------------------
   -- Build_Subprogram_Calling_Stubs --
   ------------------------------------

   function Build_Subprogram_Calling_Stubs
     (Vis_Decl                 : Node_Id;
      Subp_Id                  : Int;
      Asynchronous             : Boolean;
      Dynamically_Asynchronous : Boolean   := False;
      Stub_Type                : Entity_Id := Empty;
      Locator                  : Entity_Id := Empty;
      New_Name                 : Name_Id   := No_Name)
      return                     Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Vis_Decl);

      Target_Partition : Node_Id;
      --  Contains the name of the target partition

      Decls      : constant List_Id := New_List;
      Statements : constant List_Id := New_List;

      Subp_Spec : Node_Id;
      --  The specification of the body

      Controlling_Parameter : Entity_Id := Empty;
      RPC_Receiver          : Node_Id;

      Asynchronous_Expr : Node_Id := Empty;

      RCI_Locator : Entity_Id;

      Spec_To_Use : Node_Id;

      procedure Insert_Partition_Check (Parameter : in Node_Id);
      --  Check that the parameter has been elaborated on the same partition
      --  than the controlling parameter (E.4(19)).

      ----------------------------
      -- Insert_Partition_Check --
      ----------------------------

      procedure Insert_Partition_Check (Parameter : in Node_Id) is
         Parameter_Entity  : constant Entity_Id :=
                               Defining_Identifier (Parameter);
         Designated_Object : Node_Id;
         Condition         : Node_Id;

      begin
         --  The expression that will be built is of the form:
         --    if not (Parameter in Stub_Type and then
         --            Parameter.Origin = Controlling.Origin)
         --    then
         --      raise Constraint_Error;
         --    end if;
         --
         --  Condition contains the reversed condition. Also, Parameter is
         --  dereferenced if it is an access type. We do not check that
         --  Parameter is in Stub_Type since such a check has been inserted
         --  at the point of call already (a tag check since we have multiple
         --  controlling operands).

         if Nkind (Parameter_Type (Parameter)) = N_Access_Definition then
            Designated_Object :=
              Make_Explicit_Dereference (Loc,
                Prefix => New_Occurrence_Of (Parameter_Entity, Loc));
         else
            Designated_Object := New_Occurrence_Of (Parameter_Entity, Loc);
         end if;

         Condition :=
           Make_Op_Eq (Loc,
             Left_Opnd  =>
               Make_Selected_Component (Loc,
                 Prefix        =>
                   New_Occurrence_Of (Parameter_Entity, Loc),
               Selector_Name =>
                 Make_Identifier (Loc, Name_Origin)),

             Right_Opnd =>
               Make_Selected_Component (Loc,
                 Prefix        =>
                   New_Occurrence_Of (Controlling_Parameter, Loc),
               Selector_Name =>
                 Make_Identifier (Loc, Name_Origin)));

         Append_To (Decls,
           Make_Raise_Constraint_Error (Loc,
             Condition       =>
               Make_Op_Not (Loc, Right_Opnd => Condition)));
      end Insert_Partition_Check;

   --  Start of processing for Build_Subprogram_Calling_Stubs

   begin
      Target_Partition :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));

      Subp_Spec := Copy_Specification (Loc,
        Spec     => Specification (Vis_Decl),
        New_Name => New_Name);

      if Locator = Empty then
         RCI_Locator := RCI_Cache;
         Spec_To_Use := Specification (Vis_Decl);
      else
         RCI_Locator := Locator;
         Spec_To_Use := Subp_Spec;
      end if;

      --  Find a controlling argument if we have a stub type. Also check
      --  if this subprogram can be made asynchronous.

      if Stub_Type /= Empty
         and then Present (Parameter_Specifications (Spec_To_Use))
      then
         declare
            Current_Parameter : Node_Id :=
                                  First (Parameter_Specifications
                                           (Spec_To_Use));
         begin
            while Current_Parameter /= Empty loop

               if
                 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
               then
                  if Controlling_Parameter = Empty then
                     Controlling_Parameter :=
                       Defining_Identifier (Current_Parameter);
                  else
                     Insert_Partition_Check (Current_Parameter);
                  end if;
               end if;

               Next (Current_Parameter);
            end loop;
         end;
      end if;

      if Stub_Type /= Empty then
         pragma Assert (Controlling_Parameter /= Empty);

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Target_Partition,
             Constant_Present    => True,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Partition_ID), Loc),

             Expression          =>
               Make_Selected_Component (Loc,
                 Prefix        =>
                   New_Occurrence_Of (Controlling_Parameter, Loc),
                 Selector_Name =>
                   Make_Identifier (Loc, Name_Origin))));

         RPC_Receiver :=
           Make_Selected_Component (Loc,
             Prefix        =>
               New_Occurrence_Of (Controlling_Parameter, Loc),
             Selector_Name =>
               Make_Identifier (Loc, Name_Receiver));

      else
         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Target_Partition,
             Constant_Present    => True,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Partition_ID), Loc),

             Expression          =>
               Make_Function_Call (Loc,
                 Name => Make_Selected_Component (Loc,
                   Prefix        =>
                     Make_Identifier (Loc, Chars (RCI_Locator)),
                   Selector_Name =>
                     Make_Identifier (Loc, Name_Get_Active_Partition_ID)))));

         RPC_Receiver :=
           Make_Selected_Component (Loc,
             Prefix        =>
               Make_Identifier (Loc, Chars (RCI_Locator)),
             Selector_Name =>
               Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
      end if;

      if Dynamically_Asynchronous then
         Asynchronous_Expr :=
           Make_Selected_Component (Loc,
             Prefix        =>
               New_Occurrence_Of (Controlling_Parameter, Loc),
             Selector_Name =>
               Make_Identifier (Loc, Name_Asynchronous));
      end if;

      Build_General_Calling_Stubs
        (Decls                 => Decls,
         Statements            => Statements,
         Target_Partition      => Target_Partition,
         RPC_Receiver          => RPC_Receiver,
         Subprogram_Id         => Make_Integer_Literal (Loc, Subp_Id),
         Asynchronous          => Asynchronous_Expr,
         Is_Known_Asynchronous => Asynchronous
                                    and then not Dynamically_Asynchronous,
         Is_Known_Non_Asynchronous
                               => not Asynchronous
                                    and then not Dynamically_Asynchronous,
         Is_Function           => Nkind (Spec_To_Use) =
                                    N_Function_Specification,
         Spec                  => Spec_To_Use,
         Object_Type           => Stub_Type,
         Nod                   => Vis_Decl);

      RCI_Calling_Stubs_Table.Set
        (Defining_Unit_Name (Specification (Vis_Decl)),
         Defining_Unit_Name (Spec_To_Use));

      return
        Make_Subprogram_Body (Loc,
          Specification              => Subp_Spec,
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, Statements));
   end Build_Subprogram_Calling_Stubs;

   --------------------------------------
   -- Build_Subprogram_Receiving_Stubs --
   --------------------------------------

   function Build_Subprogram_Receiving_Stubs
     (Vis_Decl                 : Node_Id;
      Asynchronous             : Boolean;
      Dynamically_Asynchronous : Boolean   := False;
      Stub_Type                : Entity_Id := Empty;
      RACW_Type                : Entity_Id := Empty;
      Parent_Primitive         : Entity_Id := Empty)
      return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Vis_Decl);

      Stream_Parameter : Node_Id;
      Result_Parameter : Node_Id;
      --  See explanations of those in Build_Subprogram_Calling_Stubs

      Decls : List_Id := New_List;
      --  All the parameters will get declared before calling the real
      --  subprograms. Also the out parameters will be declared.

      Statements : List_Id := New_List;

      Extra_Formal_Statements : List_Id := New_List;
      --  Statements concerning extra formal parameters

      After_Statements : List_Id := New_List;
      --  Statements to be executed after the subprogram call

      Inner_Decls : List_Id := No_List;
      --  In case of a function, the inner declarations are needed since
      --  the result may be unconstrained.

      Excep_Handler : Node_Id;
      Excep_Choice  : Entity_Id;
      Excep_Code    : List_Id;

      Parameter_List   : List_Id := New_List;
      --  List of parameters to be passed to the subprogram.

      Current_Parameter : Node_Id;

      Ordered_Parameters_List : constant List_Id :=
        Build_Ordered_Parameters_List (Specification (Vis_Decl));

      Subp_Spec : Node_Id;
      --  Subprogram specification

      Called_Subprogram : Node_Id;
      --  The subprogram to call

      Null_Raise_Statement : Node_Id;

      Dynamic_Async : Entity_Id;

   begin
      if RACW_Type /= Empty then
         Called_Subprogram :=
           New_Occurrence_Of (Parent_Primitive, Loc);
      else
         Called_Subprogram :=
           New_Occurrence_Of (
             Defining_Unit_Name (Specification (Vis_Decl)), Loc);
      end if;

      Stream_Parameter :=
        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));

      if Dynamically_Asynchronous then
         Dynamic_Async :=
           Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
      else
         Dynamic_Async := Empty;
      end if;

      if not Asynchronous or else Dynamically_Asynchronous then
         Result_Parameter :=
           Make_Defining_Identifier (Loc, New_Internal_Name ('S'));

         --  The first statement after the subprogram call is a statement to
         --  writes a Null_Occurrence into the result stream.

         Null_Raise_Statement :=
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
             Attribute_Name => Name_Write,
             Expressions    => New_List (
               New_Occurrence_Of (Result_Parameter, Loc),
               New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));

         if Dynamically_Asynchronous then
            Null_Raise_Statement :=
              Make_Implicit_If_Statement (Vis_Decl,
                Condition       =>
                  Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
                Then_Statements => New_List (Null_Raise_Statement));
         end if;

         Append_To (After_Statements, Null_Raise_Statement);

      else
         Result_Parameter := Empty;
      end if;

      --  Loop through every parameter and get its value from the stream. If
      --  the parameter is unconstrained, then the parameter is read using
      --  'Input at the point of declaration.

      Current_Parameter := First (Ordered_Parameters_List);

      while Current_Parameter /= Empty loop

         declare
            Etyp        : Entity_Id;
            Constrained : Boolean;
            Object      : Entity_Id;
            Expr        : Node_Id := Empty;

         begin
            Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
            Set_Ekind (Object, E_Variable);

            if
              Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
            then
               --  We have a controlling formal parameter. Read its address
               --  rather than a real object. The address is in Unsigned_64
               --  form.

               Etyp := RTE (RE_Unsigned_64);
            else
               Etyp := Etype (Parameter_Type (Current_Parameter));
            end if;

            Constrained :=
              Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);

            if In_Present (Current_Parameter)
               or else not Out_Present (Current_Parameter)
               or else not Constrained
            then
               --  If an input parameter is contrained, then its reading is
               --  deferred until the beginning of the subprogram body. If
               --  it is unconstrained, then an expression is built for
               --  the object declaration and the variable is set using
               --  'Input instead of 'Read.

               if Constrained then
                  Append_To (Statements,
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Etyp, Loc),
                      Attribute_Name => Name_Read,
                      Expressions    => New_List (
                        New_Occurrence_Of (Stream_Parameter, Loc),
                        New_Occurrence_Of (Object, Loc))));

               else
                  Expr := Input_With_Tag_Check (Loc,
                    Var_Type => Etyp,
                    Stream   => Stream_Parameter);
                  Append_To (Decls, Expr);
                  Expr := Make_Function_Call (Loc,
                    New_Occurrence_Of (Defining_Unit_Name
                      (Specification (Expr)), Loc));
               end if;
            end if;

            --  If we do not have to output the current parameter, then
            --  it can well be flagged as constant. This may allow further
            --  optimizations done by the back end.

            Append_To (Decls,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Object,
                Constant_Present    =>
                  not Constrained and then not Out_Present (Current_Parameter),
                Object_Definition   =>
                  New_Occurrence_Of (Etyp, Loc),
                Expression          => Expr));

            --  An out parameter may be written back using a 'Write
            --  attribute instead of a 'Output because it has been
            --  constrained by the parameter given to the caller. Note that
            --  out controlling arguments in the case of a RACW are not put
            --  back in the stream because the pointer on them has not
            --  changed.

            if Out_Present (Current_Parameter)
              and then
                Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
            then
               Append_To (After_Statements,
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Occurrence_Of (Etyp, Loc),
                   Attribute_Name => Name_Write,
                   Expressions    => New_List (
                       New_Occurrence_Of (Result_Parameter, Loc),
                     New_Occurrence_Of (Object, Loc))));
            end if;

            if
              Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
            then

               if Nkind (Parameter_Type (Current_Parameter)) /=
                 N_Access_Definition
               then
                  Append_To (Parameter_List,
                    Make_Parameter_Association (Loc,
                      Selector_Name             =>
                        New_Occurrence_Of (
                          Defining_Identifier (Current_Parameter), Loc),
                      Explicit_Actual_Parameter =>
                        Make_Explicit_Dereference (Loc,
                          Unchecked_Convert_To (RACW_Type,
                            OK_Convert_To (RTE (RE_Address),
                              New_Occurrence_Of (Object, Loc))))));
               else
                  Append_To (Parameter_List,
                    Make_Parameter_Association (Loc,
                      Selector_Name             =>
                        New_Occurrence_Of (
                          Defining_Identifier (Current_Parameter), Loc),
                      Explicit_Actual_Parameter =>
                        Unchecked_Convert_To (RACW_Type,
                          OK_Convert_To (RTE (RE_Address),
                            New_Occurrence_Of (Object, Loc)))));
               end if;
            else
               Append_To (Parameter_List,
                 Make_Parameter_Association (Loc,
                   Selector_Name             =>
                     New_Occurrence_Of (
                       Defining_Identifier (Current_Parameter), Loc),
                   Explicit_Actual_Parameter =>
                     New_Occurrence_Of (Object, Loc)));
            end if;

            --  If the current parameter needs an extra formal, then read it
            --  from the stream and set the corresponding semantic field in
            --  the variable. If the kind of the parameter identifier is
            --  E_Void, then this is a compiler generated parameter that
            --  doesn't need an extra constrained status.

            --  The case of Extra_Accessibility should also be handled ???

            if Nkind (Parameter_Type (Current_Parameter)) /=
                                                      N_Access_Definition
              and then
                Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
              and then
                Present (Extra_Constrained
                  (Defining_Identifier (Current_Parameter)))
            then
               declare
                  Extra_Parameter : constant Entity_Id :=
                                      Extra_Constrained
                                        (Defining_Identifier
                                          (Current_Parameter));

                  Formal_Entity : constant Entity_Id :=
                                    Make_Defining_Identifier
                                        (Loc, Chars (Extra_Parameter));

                  Formal_Type : constant Entity_Id :=
                                  Etype (Extra_Parameter);

               begin
                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Formal_Entity,
                      Object_Definition   =>
                        New_Occurrence_Of (Formal_Type, Loc)));

                  Append_To (Extra_Formal_Statements,
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Formal_Type, Loc),
                      Attribute_Name => Name_Read,
                      Expressions    => New_List (
                        New_Occurrence_Of (Stream_Parameter, Loc),
                        New_Occurrence_Of (Formal_Entity, Loc))));
                  Set_Extra_Constrained (Object, Formal_Entity);
               end;
            end if;
         end;

         Next (Current_Parameter);
      end loop;

      --  Append the formal statements list at the end of regular statements

      Append_List_To (Statements, Extra_Formal_Statements);

      if Nkind (Specification (Vis_Decl)) = N_Function_Specification then

         --  The remote subprogram is a function. We build an inner block to
         --  be able to hold a potentially unconstrained result in a variable.

         declare
            Etyp   : constant Entity_Id :=
                       Etype (Subtype_Mark (Specification (Vis_Decl)));
            Result : constant Node_Id   :=
                       Make_Defining_Identifier (Loc, New_Internal_Name ('R'));

         begin
            Inner_Decls := New_List (
              Make_Object_Declaration (Loc,
                Defining_Identifier => Result,
                Constant_Present    => True,
                Object_Definition   => New_Occurrence_Of (Etyp, Loc),
                Expression          =>
                  Make_Function_Call (Loc,
                    Name                   => Called_Subprogram,
                    Parameter_Associations => Parameter_List)));

            Append_To (After_Statements,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Etyp, Loc),
                Attribute_Name => Name_Output,
                Expressions    => New_List (
                  New_Occurrence_Of (Result_Parameter, Loc),
                  New_Occurrence_Of (Result, Loc))));
         end;

         Append_To (Statements,
           Make_Block_Statement (Loc,
             Declarations               => Inner_Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => After_Statements)));

      else
         --  The remote subprogram is a procedure. We do not need any inner
         --  block in this case.

         if Dynamically_Asynchronous then
            Append_To (Decls,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Dynamic_Async,
                Object_Definition   =>
                  New_Occurrence_Of (Standard_Boolean, Loc)));

            Append_To (Statements,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Standard_Boolean, Loc),
                Attribute_Name => Name_Read,
                Expressions    => New_List (
                  New_Occurrence_Of (Stream_Parameter, Loc),
                  New_Occurrence_Of (Dynamic_Async, Loc))));
         end if;

         Append_To (Statements,
           Make_Procedure_Call_Statement (Loc,
             Name                   => Called_Subprogram,
             Parameter_Associations => Parameter_List));

         Append_List_To (Statements, After_Statements);

      end if;

      if Asynchronous and then not Dynamically_Asynchronous then

         --  An asynchronous procedure does not want a Result
         --  parameter. Also, we put an exception handler with an others
         --  clause that does nothing.

         Subp_Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       =>
               Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Stream_Parameter,
                 Parameter_Type      =>
                   Make_Access_Definition (Loc,
                   Subtype_Mark =>
                     New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));

         Excep_Handler :=
           Make_Exception_Handler (Loc,
             Exception_Choices =>
               New_List (Make_Others_Choice (Loc)),
             Statements        => New_List (
               Make_Null_Statement (Loc)));

      else
         --  In the other cases, if an exception is raised, then the
         --  exception occurrence is copied into the output stream and
         --  no other output parameter is written.

         Excep_Choice :=
           Make_Defining_Identifier (Loc, New_Internal_Name ('E'));

         Excep_Code := New_List (
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
             Attribute_Name => Name_Write,
             Expressions    => New_List (
               New_Occurrence_Of (Result_Parameter, Loc),
               New_Occurrence_Of (Excep_Choice, Loc))));

         if Dynamically_Asynchronous then
            Excep_Code := New_List (
              Make_Implicit_If_Statement (Vis_Decl,
                Condition       => Make_Op_Not (Loc,
                  New_Occurrence_Of (Dynamic_Async, Loc)),
                Then_Statements => Excep_Code));
         end if;

         Excep_Handler :=
           Make_Exception_Handler (Loc,
             Choice_Parameter   => Excep_Choice,
             Exception_Choices  => New_List (Make_Others_Choice (Loc)),
             Statements         => Excep_Code);

         Subp_Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       =>
               Make_Defining_Identifier (Loc, New_Internal_Name ('F')),

             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Stream_Parameter,
                 Parameter_Type      =>
                   Make_Access_Definition (Loc,
                   Subtype_Mark =>
                     New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),

               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Result_Parameter,
                 Parameter_Type      =>
                   Make_Access_Definition (Loc,
                  Subtype_Mark =>
                  New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
      end if;

      return
        Make_Subprogram_Body (Loc,
          Specification              => Subp_Spec,
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements         => Statements,
              Exception_Handlers => New_List (Excep_Handler)));

   end Build_Subprogram_Receiving_Stubs;

   ------------------------
   -- Copy_Specification --
   ------------------------

   function Copy_Specification
     (Loc         : Source_Ptr;
      Spec        : Node_Id;
      Object_Type : Entity_Id := Empty;
      Stub_Type   : Entity_Id := Empty;
      New_Name    : Name_Id   := No_Name)
      return        Node_Id
   is
      Parameters : List_Id := No_List;

      Current_Parameter : Node_Id;
      Current_Type      : Node_Id;

      Name_For_New_Spec : Name_Id;

      New_Identifier : Entity_Id;

   begin
      if New_Name = No_Name then
         Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
      else
         Name_For_New_Spec := New_Name;
      end if;

      if Present (Parameter_Specifications (Spec)) then

         Parameters        := New_List;
         Current_Parameter := First (Parameter_Specifications (Spec));

         while Current_Parameter /= Empty loop

            Current_Type := Parameter_Type (Current_Parameter);

            if Nkind (Current_Type) = N_Access_Definition then
               if Object_Type = Empty then
                  Current_Type :=
                    Make_Access_Definition (Loc,
                      Subtype_Mark =>
                        New_Occurrence_Of (Etype (
                          Subtype_Mark (Current_Type)), Loc));
               else
                  pragma Assert
                    (Root_Type (Etype (Subtype_Mark (Current_Type)))
                       = Root_Type (Object_Type));
                  Current_Type :=
                    Make_Access_Definition (Loc,
                      Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc));
               end if;

            elsif Object_Type /= Empty
              and then Etype (Current_Type) = Object_Type
            then
               Current_Type := New_Occurrence_Of (Stub_Type, Loc);

            else
               Current_Type := New_Occurrence_Of (Etype (Current_Type), Loc);
            end if;

            New_Identifier := Make_Defining_Identifier (Loc,
              Chars (Defining_Identifier (Current_Parameter)));

            Append_To (Parameters,
              Make_Parameter_Specification (Loc,
                Defining_Identifier => New_Identifier,
                Parameter_Type      => Current_Type,
                In_Present          => In_Present (Current_Parameter),
                Out_Present         => Out_Present (Current_Parameter),
                Expression          =>
                  New_Copy_Tree (Expression (Current_Parameter))));

            Next (Current_Parameter);
         end loop;
      end if;

      if Nkind (Spec) = N_Function_Specification then
         return
           Make_Function_Specification (Loc,
             Defining_Unit_Name       =>
               Make_Defining_Identifier (Loc,
                 Chars => Name_For_New_Spec),
             Parameter_Specifications => Parameters,
             Subtype_Mark             =>
               New_Occurrence_Of (Etype (Subtype_Mark (Spec)), Loc));

      else
         return
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       =>
               Make_Defining_Identifier (Loc,
                 Chars => Name_For_New_Spec),
             Parameter_Specifications => Parameters);
      end if;

   end Copy_Specification;

   ---------------------------
   -- Could_Be_Asynchronous --
   ---------------------------

   function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
      Current_Parameter : Node_Id;

   begin
      if Present (Parameter_Specifications (Spec)) then
         Current_Parameter := First (Parameter_Specifications (Spec));
         while Current_Parameter /= Empty loop
            if Out_Present (Current_Parameter) then
               return False;
            end if;

            Next (Current_Parameter);
         end loop;
      end if;

      return True;
   end Could_Be_Asynchronous;

   ---------------------------------------------
   -- Expand_All_Calls_Remote_Subprogram_Call --
   ---------------------------------------------

   procedure Expand_All_Calls_Remote_Subprogram_Call (N : in Node_Id) is
      Called_Subprogram : constant Entity_Id  := Entity (Name (N));
      RCI_Package       : constant Entity_Id  := Scope (Called_Subprogram);
      Loc               : constant Source_Ptr := Sloc (N);
      RCI_Locator       : Node_Id;
      RCI_Cache         : Entity_Id;
      Calling_Stubs     : Node_Id;
      E_Calling_Stubs   : Entity_Id;

   begin
      E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);

      if E_Calling_Stubs = Empty then
         RCI_Cache := RCI_Locator_Table.Get (RCI_Package);

         if RCI_Cache = Empty then
            RCI_Locator :=
              RCI_Package_Locator
                (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
            Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator);

            --  The RCI_Locator package is inserted at the top level in the
            --  current unit, and must appear in the proper scope, so that it
            --  is not prematurely removed by the GCC back-end.

            declare
               Scop : Entity_Id := Cunit_Entity (Current_Sem_Unit);

            begin
               if Ekind (Scop) = E_Package_Body then
                  New_Scope (Spec_Entity (Scop));

               elsif Ekind (Scop) = E_Subprogram_Body then
                  New_Scope
                     (Corresponding_Spec (Unit_Declaration_Node (Scop)));

               else
                  New_Scope (Scop);
               end if;

               Analyze (RCI_Locator);
               Pop_Scope;
            end;

            RCI_Cache   := Defining_Unit_Name (RCI_Locator);

         else
            RCI_Locator := Parent (RCI_Cache);
         end if;

         Calling_Stubs := Build_Subprogram_Calling_Stubs
           (Vis_Decl               => Parent (Parent (Called_Subprogram)),
            Subp_Id                => Get_Subprogram_Id (Called_Subprogram),
            Asynchronous           => Nkind (N) = N_Procedure_Call_Statement
                                        and then
                                      Is_Asynchronous (Called_Subprogram),
            Locator                => RCI_Cache,
            New_Name               => New_Internal_Name ('S'));
         Insert_After (RCI_Locator, Calling_Stubs);
         Analyze (Calling_Stubs);
         E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
      end if;

      Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
   end Expand_All_Calls_Remote_Subprogram_Call;

   ---------------------------------
   -- Expand_Calling_Stubs_Bodies --
   ---------------------------------

   procedure Expand_Calling_Stubs_Bodies (Unit_Node : in Node_Id) is
      Spec  : constant Node_Id := Specification (Unit_Node);
      Decls : constant List_Id := Visible_Declarations (Spec);

   begin
      New_Scope (Scope_Of_Spec (Spec));
      Add_Calling_Stubs_To_Declarations (Specification (Unit_Node),
                                         Decls);
      Pop_Scope;
   end Expand_Calling_Stubs_Bodies;

   -----------------------------------
   -- Expand_Receiving_Stubs_Bodies --
   -----------------------------------

   procedure Expand_Receiving_Stubs_Bodies (Unit_Node : in Node_Id) is
      Spec  : Node_Id;
      Decls : List_Id;
      Temp  : List_Id;

   begin
      if Nkind (Unit_Node) = N_Package_Declaration then
         Spec  := Specification (Unit_Node);
         Decls := Visible_Declarations (Spec);
         New_Scope (Scope_Of_Spec (Spec));
         Add_Receiving_Stubs_To_Declarations (Spec, Decls);

      else
         Spec  :=
           Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
         Decls := Declarations (Unit_Node);
         New_Scope (Scope_Of_Spec (Unit_Node));
         Temp := New_List;
         Add_Receiving_Stubs_To_Declarations (Spec, Temp);
         Insert_List_Before (First (Decls), Temp);
      end if;

      Pop_Scope;
   end Expand_Receiving_Stubs_Bodies;

   ----------------------------
   -- Get_Pkg_Name_string_Id --
   ----------------------------

   function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id is
      Unit_Name_Id : Unit_Name_Type := Get_Unit_Name (Decl_Node);

   begin
      Get_Unit_Name_String (Unit_Name_Id);

      --  Remove seven last character (" (spec)" or " (body)").

      Name_Len := Name_Len - 7;
      pragma Assert (Name_Buffer (Name_Len + 1) = ' ');

      return Get_String_Id (Name_Buffer (1 .. Name_Len));
   end Get_Pkg_Name_String_Id;

   -------------------
   -- Get_String_Id --
   -------------------

   function Get_String_Id (Val : String) return String_Id is
   begin
      Start_String;
      Store_String_Chars (Val);
      return End_String;
   end Get_String_Id;

   ----------
   -- Hash --
   ----------

   function Hash (F : Entity_Id) return Hash_Index is
   begin
      return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
   end Hash;

   --------------------------
   -- Input_With_Tag_Check --
   --------------------------

   function Input_With_Tag_Check
     (Loc      : Source_Ptr;
      Var_Type : Entity_Id;
      Stream   : Entity_Id)
      return     Node_Id
   is
   begin
      return
        Make_Subprogram_Body (Loc,
          Specification              => Make_Function_Specification (Loc,
            Defining_Unit_Name =>
              Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
            Subtype_Mark       => New_Occurrence_Of (Var_Type, Loc)),
          Declarations               => No_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, New_List (
              Make_Tag_Check (Loc,
                Make_Return_Statement (Loc,
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Occurrence_Of (Var_Type, Loc),
                    Attribute_Name => Name_Input,
                    Expressions    =>
                      New_List (New_Occurrence_Of (Stream, Loc))))))));
   end Input_With_Tag_Check;

   --------------------------------
   -- Is_RACW_Controlling_Formal --
   --------------------------------

   function Is_RACW_Controlling_Formal
     (Parameter : Node_Id;
      Stub_Type : Entity_Id)
      return      Boolean
   is
      Typ : Entity_Id;

   begin
      --  If the kind of the parameter is E_Void, then it is not a
      --  controlling formal (this can happen in the context of RAS).

      if Ekind (Defining_Identifier (Parameter)) = E_Void then
         return False;
      end if;

      --  If the parameter is not a controlling formal, then it cannot
      --  be possibly a RACW_Controlling_Formal.

      if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
         return False;
      end if;

      Typ := Parameter_Type (Parameter);
      return (Nkind (Typ) = N_Access_Definition
               and then Etype (Subtype_Mark (Typ)) = Stub_Type)
        or else Etype (Typ) = Stub_Type;
   end Is_RACW_Controlling_Formal;

   --------------------
   -- Make_Tag_Check --
   --------------------

   function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
      Occ : constant Entity_Id :=
              Make_Defining_Identifier (Loc, New_Internal_Name ('E'));

   begin
      return Make_Block_Statement (Loc,
        Handled_Statement_Sequence =>
          Make_Handled_Sequence_Of_Statements (Loc,
            Statements         => New_List (N),

            Exception_Handlers => New_List (
              Make_Exception_Handler (Loc,
                Choice_Parameter => Occ,

                Exception_Choices =>
                  New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),

                Statements =>
                  New_List (Make_Procedure_Call_Statement (Loc,
                    New_Occurrence_Of
                      (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
                    New_List (New_Occurrence_Of (Occ, Loc))))))));
   end Make_Tag_Check;

   ----------------------------
   -- Need_Extra_Constrained --
   ----------------------------

   function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
      Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));

   begin
      return Out_Present (Parameter)
        and then Has_Discriminants (Etyp)
        and then not Is_Constrained (Etyp)
        and then not Is_Indefinite_Subtype (Etyp);
   end Need_Extra_Constrained;

   ------------------------------------
   -- Pack_Entity_Into_Stream_Access --
   ------------------------------------

   function Pack_Entity_Into_Stream_Access
     (Loc    : Source_Ptr;
      Stream : Entity_Id;
      Object : Entity_Id;
      Etyp   : Entity_Id := Empty)
      return   Node_Id
   is
      Typ : Entity_Id;

   begin
      if Etyp /= Empty then
         Typ := Etyp;
      else
         Typ := Etype (Object);
      end if;

      return
        Pack_Node_Into_Stream_Access (Loc,
          Stream => Stream,
          Object => New_Occurrence_Of (Object, Loc),
          Etyp   => Typ);
   end Pack_Entity_Into_Stream_Access;

   ---------------------------
   -- Pack_Node_Into_Stream --
   ---------------------------

   function Pack_Node_Into_Stream
     (Loc    : Source_Ptr;
      Stream : Entity_Id;
      Object : Node_Id;
      Etyp   : Entity_Id)
      return   Node_Id
   is
      Write_Attribute : Name_Id := Name_Write;

   begin
      if not Is_Constrained (Etyp) then
         Write_Attribute := Name_Output;
      end if;

      return
        Make_Attribute_Reference (Loc,
          Prefix         => New_Occurrence_Of (Etyp, Loc),
          Attribute_Name => Write_Attribute,
          Expressions    => New_List (
            Make_Attribute_Reference (Loc,
              Prefix         => New_Occurrence_Of (Stream, Loc),
              Attribute_Name => Name_Access),
            Object));
   end Pack_Node_Into_Stream;

   ----------------------------------
   -- Pack_Node_Into_Stream_Access --
   ----------------------------------

   function Pack_Node_Into_Stream_Access
     (Loc    : Source_Ptr;
      Stream : Entity_Id;
      Object : Node_Id;
      Etyp   : Entity_Id)
      return   Node_Id
   is
      Write_Attribute : Name_Id := Name_Write;

   begin
      if not Is_Constrained (Etyp) then
         Write_Attribute := Name_Output;
      end if;

      return
        Make_Attribute_Reference (Loc,
          Prefix         => New_Occurrence_Of (Etyp, Loc),
          Attribute_Name => Write_Attribute,
          Expressions    => New_List (
            New_Occurrence_Of (Stream, Loc),
            Object));
   end Pack_Node_Into_Stream_Access;

   -------------------------------
   -- RACW_Type_Is_Asynchronous --
   -------------------------------

   procedure RACW_Type_Is_Asynchronous (RACW_Type : in Entity_Id) is
      N : constant Node_Id := Asynchronous_Flags_Table.Get (RACW_Type);
      pragma Assert (N /= Empty);

   begin
      Replace (N, New_Occurrence_Of (Standard_True, Sloc (N)));
   end RACW_Type_Is_Asynchronous;

   -------------------------
   -- RCI_Package_Locator --
   -------------------------

   function RCI_Package_Locator
     (Loc          : Source_Ptr;
      Package_Spec : Node_Id)
      return         Node_Id
   is
      Inst : constant Node_Id :=
               Make_Package_Instantiation (Loc,
                 Defining_Unit_Name   =>
                   Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
                 Name                 =>
                   New_Occurrence_Of (RTE (RE_RCI_Info), Loc),
                 Generic_Associations => New_List (
                   Make_Generic_Association (Loc,
                     Selector_Name                     =>
                       Make_Identifier (Loc, Name_RCI_Name),
                     Explicit_Generic_Actual_Parameter =>
                       Make_String_Literal (Loc,
                         Strval => Get_Pkg_Name_String_Id (Package_Spec)))));

   begin
      RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
        Defining_Unit_Name (Inst));
      return Inst;
   end RCI_Package_Locator;

   -----------------------------------------------
   -- Remote_Types_Tagged_Full_View_Encountered --
   -----------------------------------------------

   procedure Remote_Types_Tagged_Full_View_Encountered
     (Full_View : in Entity_Id)
   is
      Stub_Elements : constant Stub_Structure :=
                        Stubs_Table.Get (Full_View);

   begin
      if Stub_Elements /= Empty_Stub_Structure then
         Add_RACW_Primitive_Declarations_And_Bodies
           (Full_View,
            Parent (Declaration_Node (Stub_Elements.Object_RPC_Receiver)),
            List_Containing (Declaration_Node (Full_View)));
      end if;
   end Remote_Types_Tagged_Full_View_Encountered;

   -------------------
   -- Scope_Of_Spec --
   -------------------

   function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
      Unit_Name : Node_Id := Defining_Unit_Name (Spec);

   begin
      while Nkind (Unit_Name) /= N_Defining_Identifier loop
         Unit_Name := Defining_Identifier (Unit_Name);
      end loop;

      return Unit_Name;
   end Scope_Of_Spec;

end Exp_Dist;
