OSDN Git Service

2008-08-04 Kevin Pouget <pouget@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_dist.adb
index 6b4ced7..8576cbf 100644 (file)
@@ -6,49 +6,50 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2004 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2008, 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- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Atree;       use Atree;
-with Einfo;       use Einfo;
-with Elists;      use Elists;
-with Exp_Strm;    use Exp_Strm;
-with Exp_Tss;     use Exp_Tss;
-with Exp_Util;    use Exp_Util;
+with Atree;    use Atree;
+with Einfo;    use Einfo;
+with Elists;   use Elists;
+with Exp_Atag; use Exp_Atag;
+with Exp_Strm; use Exp_Strm;
+with Exp_Tss;  use Exp_Tss;
+with Exp_Util; use Exp_Util;
+with Lib;      use Lib;
+with Nlists;   use Nlists;
+with Nmake;    use Nmake;
+with Opt;      use Opt;
+with Rtsfind;  use Rtsfind;
+with Sem;      use Sem;
+with Sem_Cat;  use Sem_Cat;
+with Sem_Ch3;  use Sem_Ch3;
+with Sem_Ch8;  use Sem_Ch8;
+with Sem_Dist; use Sem_Dist;
+with Sem_Eval; use Sem_Eval;
+with Sem_Util; use Sem_Util;
+with Sinfo;    use Sinfo;
+with Stand;    use Stand;
+with Stringt;  use Stringt;
+with Tbuild;   use Tbuild;
+with Ttypes;   use Ttypes;
+with Uintp;    use Uintp;
+
 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
 
@@ -66,7 +67,7 @@ package body Exp_Dist is
    --       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
+   --       same partition through several paths;
 
    --    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
@@ -76,56 +77,127 @@ package body Exp_Dist is
    --       to fake half a derivation to ensure that the subprograms do have
    --       the same dispatching table.
 
+   First_RCI_Subprogram_Id : constant := 2;
+   --  RCI subprograms are numbered starting at 2. The RCI receiver for
+   --  an RCI package can thus identify calls received through remote
+   --  access-to-subprogram dereferences by the fact that they have a
+   --  (primitive) subprogram id of 0, and 1 is used for the internal
+   --  RAS information lookup operation. (This is for the Garlic code
+   --  generation, where subprograms are identified by numbers; in the
+   --  PolyORB version, they are identified by name, with a numeric suffix
+   --  for homonyms.)
+
+   type Hash_Index is range 0 .. 50;
+
    -----------------------
    -- Local subprograms --
    -----------------------
 
-   function Get_Subprogram_Id (E : Entity_Id) return Int;
-   --  Given a subprogram defined in a RCI package, get its subprogram id
-   --  which will be used for remote calls.
-
-   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 Hash (F : Entity_Id) return Hash_Index;
+   --  DSA expansion associates stubs to distributed object types using
+   --  a hash table on entity ids.
+
+   function Hash (F : Name_Id) return Hash_Index;
+   --  The generation of subprogram identifiers requires an overload counter
+   --  to be associated with each remote subprogram names. These counters
+   --  are maintained in a hash table on name ids.
+
+   type Subprogram_Identifiers is record
+      Str_Identifier : String_Id;
+      Int_Identifier : Int;
+   end record;
+
+   package Subprogram_Identifier_Table is
+      new Simple_HTable (Header_Num => Hash_Index,
+                         Element    => Subprogram_Identifiers,
+                         No_Element => (No_String, 0),
+                         Key        => Entity_Id,
+                         Hash       => Hash,
+                         Equal      => "=");
+   --  Mapping between a remote subprogram and the corresponding
+   --  subprogram identifiers.
+
+   package Overload_Counter_Table is
+      new Simple_HTable (Header_Num => Hash_Index,
+                         Element    => Int,
+                         No_Element => 0,
+                         Key        => Name_Id,
+                         Hash       => Hash,
+                         Equal      => "=");
+   --  Mapping between a subprogram name and an integer that
+   --  counts the number of defining subprogram names with that
+   --  Name_Id encountered so far in a given context (an interface).
+
+   function Get_Subprogram_Ids (Def : Entity_Id) return Subprogram_Identifiers;
+   function Get_Subprogram_Id  (Def : Entity_Id) return String_Id;
+   function Get_Subprogram_Id  (Def : Entity_Id) return Int;
+   --  Given a subprogram defined in a RCI package, get its distribution
+   --  subprogram identifiers (the distribution identifiers are a unique
+   --  subprogram number, and the non-qualified subprogram name, in the
+   --  casing used for the subprogram declaration; if the name is overloaded,
+   --  a double underscore and a serial number are appended.
+   --
+   --  The integer identifier is used to perform remote calls with GARLIC;
+   --  the string identifier is used in the case of PolyORB.
+   --
+   --  Although the PolyORB DSA receiving stubs will make a caseless comparison
+   --  when receiving a call, the calling stubs will create requests with the
+   --  exact casing of the defining unit name of the called subprogram, so as
+   --  to allow calls to subprograms on distributed nodes that do distinguish
+   --  between casings.
+   --
+   --  NOTE: Another design would be to allow a representation clause on
+   --  subprogram specs: for Subp'Distribution_Identifier use "fooBar";
+
+   pragma Warnings (Off, Get_Subprogram_Id);
+   --  One homonym only is unreferenced (specific to the GARLIC version)
+
+   procedure Add_RAS_Dereference_TSS (N : Node_Id);
+   --  Add a subprogram body for RAS Dereference TSS
+
+   procedure Add_RAS_Proxy_And_Analyze
+     (Decls              : List_Id;
+      Vis_Decl           : Node_Id;
+      All_Calls_Remote_E : Entity_Id;
+      Proxy_Object_Addr  : out Entity_Id);
+   --  Add the proxy type required, on the receiving (server) side, to handle
+   --  calls to the subprogram declared by Vis_Decl through a remote access
+   --  to subprogram type. All_Calls_Remote_E must be Standard_True if a pragma
+   --  All_Calls_Remote applies, Standard_False otherwise. The new proxy type
+   --  is appended to Decls. Proxy_Object_Addr is a constant of type
+   --  System.Address that designates an instance of the proxy object.
+
+   function Build_Remote_Subprogram_Proxy_Type
+     (Loc            : Source_Ptr;
+      ACR_Expression : Node_Id) return Node_Id;
+   --  Build and return a tagged record type definition for an RCI
+   --  subprogram proxy type.
+   --  ACR_Expression is use as the initialization value for
+   --  the All_Calls_Remote component.
+
+   function Build_Get_Unique_RP_Call
+     (Loc       : Source_Ptr;
+      Pointer   : Entity_Id;
+      Stub_Type : Entity_Id) return List_Id;
+   --  Build a call to Get_Unique_Remote_Pointer (Pointer), followed by a
+   --  tag fixup (Get_Unique_Remote_Pointer may have changed Pointer'Tag to
+   --  RACW_Stub_Type'Tag, while the desired tag is that of Stub_Type).
+
+   function Build_Stub_Tag
+     (Loc       : Source_Ptr;
+      RACW_Type : Entity_Id) return Node_Id;
+   --  Return an expression denoting the tag of the stub type associated with
+   --  RACW_Type.
 
    function Build_Subprogram_Calling_Stubs
      (Vis_Decl                 : Node_Id;
-      Subp_Id                  : Int;
+      Subp_Id                  : Node_Id;
       Asynchronous             : Boolean;
       Dynamically_Asynchronous : Boolean   := False;
       Stub_Type                : Entity_Id := Empty;
+      RACW_Type                : Entity_Id := Empty;
       Locator                  : Entity_Id := Empty;
-      New_Name                 : Name_Id   := No_Name)
-      return                     Node_Id;
+      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
@@ -136,66 +208,38 @@ package body Exp_Dist is
    --  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_RPC_Receiver_Specification
-     (RPC_Receiver     : Entity_Id;
-      Stream_Parameter : Entity_Id;
-      Result_Parameter : Entity_Id)
-      return Node_Id;
-   --  Make a subprogram specification for an RPC receiver,
-   --  with the given defining unit name and formal parameters.
+     (RPC_Receiver      : Entity_Id;
+      Request_Parameter : Entity_Id) return Node_Id;
+   --  Make a subprogram specification for an RPC receiver, with the given
+   --  defining unit name and formal parameter.
 
    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.
+   --  there are no parameters, an empty list is returned. Special case:
+   --  the controlling formal of the equivalent RACW operation for a RAS
+   --  type is always left in first position.
+
+   function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean;
+   --  True when Typ is an unconstrained type, or a null-excluding access type.
+   --  In either case, this means stubs cannot contain a default-initialized
+   --  object declaration of such type.
 
    procedure Add_Calling_Stubs_To_Declarations
-     (Pkg_Spec : in Node_Id;
-      Decls    : in List_Id);
+     (Pkg_Spec : Node_Id;
+      Decls    : 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 : Node_Id;
       Object : Entity_Id;
-      Etyp   : Entity_Id := Empty)
-      return   Node_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,
@@ -205,62 +249,105 @@ package body Exp_Dist is
      (Loc    : Source_Ptr;
       Stream : Entity_Id;
       Object : Node_Id;
-      Etyp   : Entity_Id)
-      return   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 : Node_Id;
       Object : Node_Id;
-      Etyp   : Entity_Id)
-      return   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 Make_Selected_Component
+     (Loc           : Source_Ptr;
+      Prefix        : Entity_Id;
+      Selector_Name : Name_Id) return Node_Id;
+   --  Return a selected_component whose prefix denotes the given entity,
+   --  and with the given Selector_Name.
 
    function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
    --  Return the scope represented by a given spec
 
+   procedure Set_Renaming_TSS
+     (Typ     : Entity_Id;
+      Nam     : Entity_Id;
+      TSS_Nam : TSS_Name_Type);
+   --  Create a renaming declaration of subprogram Nam,
+   --  and register it as a TSS for Typ with name TSS_Nam.
+
    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;
+     (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.
 
+   procedure Declare_Create_NVList
+     (Loc    : Source_Ptr;
+      NVList : Entity_Id;
+      Decls  : List_Id;
+      Stmts  : List_Id);
+   --  Append the declaration of NVList to Decls, and its
+   --  initialization to Stmts.
+
+   function Add_Parameter_To_NVList
+     (Loc         : Source_Ptr;
+      NVList      : Entity_Id;
+      Parameter   : Entity_Id;
+      Constrained : Boolean;
+      RACW_Ctrl   : Boolean := False;
+      Any         : Entity_Id) return Node_Id;
+   --  Return a call to Add_Item to add the Any corresponding to the designated
+   --  formal Parameter (with the indicated Constrained status) to NVList.
+   --  RACW_Ctrl must be set to True for controlling formals of distributed
+   --  object primitive operations.
+
+   --------------------
+   -- Stub_Structure --
+   --------------------
+
+   --  This record describes various tree fragments associated with the
+   --  generation of RACW calling stubs. One such record exists for every
+   --  distributed object type, i.e. each tagged type that is the designated
+   --  type of one or more RACW 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;
+      Stub_Type         : Entity_Id;
+      --  Stub type: this type has the same primitive operations as the
+      --  designated types, but the provided bodies for these operations
+      --  a remote call to an actual target object potentially located on
+      --  another partition; each value of the stub type encapsulates a
+      --  reference to a remote object.
+
+      Stub_Type_Access  : Entity_Id;
+      --  A local access type designating the stub type (this is not an RACW
+      --  type).
+
+      RPC_Receiver_Decl : Node_Id;
+      --  Declaration for the RPC receiver entity associated with the
+      --  designated type. As an exception, for the case of an RACW that
+      --  implements a RAS, no object RPC receiver is generated. Instead,
+      --  RPC_Receiver_Decl is the declaration after which the RPC receiver
+      --  would have been inserted.
+
+      Body_Decls        : List_Id;
+      --  List of subprogram bodies to be included in generated code: bodies
+      --  for the RACW's stream attributes, and for the primitive operations
+      --  of the stub type.
+
+      RACW_Type         : Entity_Id;
+      --  One of the RACW types designating this distributed object type
+      --  (they are all interchangeable; we use any one of them in order to
+      --  avoid having to create various anonymous access types).
+
    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;
+     (Empty, Empty, Empty, No_List, Empty);
 
    package Stubs_Table is
       new Simple_HTable (Header_Num => Hash_Index,
@@ -273,13 +360,13 @@ package body Exp_Dist is
 
    package Asynchronous_Flags_Table is
       new Simple_HTable (Header_Num => Hash_Index,
-                         Element    => Node_Id,
+                         Element    => Entity_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.
+   --  Mapping between a RACW type and a constant having the value True
+   --  if the RACW is asynchronous and False otherwise.
 
    package RCI_Locator_Table is
       new Simple_HTable (Header_Num => Hash_Index,
@@ -289,7 +376,7 @@ package body Exp_Dist is
                          Hash       => Hash,
                          Equal      => "=");
    --  Mapping between a RCI package on which All_Calls_Remote applies and
-   --  the generic instantiation of RCI_Info for this package.
+   --  the generic instantiation of RCI_Locator for this package.
 
    package RCI_Calling_Stubs_Table is
       new Simple_HTable (Header_Num => Hash_Index,
@@ -300,52 +387,46 @@ package body Exp_Dist is
                          Equal      => "=");
    --  Mapping between a RCI subprogram and the corresponding calling stubs
 
+   function Get_Stub_Elements (RACW_Type : Entity_Id) return Stub_Structure;
+   --  Return the stub information associated with the given RACW 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);
+     (Designated_Type   : Entity_Id;
+      RACW_Type         : Entity_Id;
+      Decls             : List_Id;
+      Stub_Type         : out Entity_Id;
+      Stub_Type_Access  : out Entity_Id;
+      RPC_Receiver_Decl : out Node_Id;
+      Body_Decls        : out List_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 Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id;
+   --  Retrieve the Body_Decls list associated to RACW_Type in the stub
+   --  structure table, reset it to No_List, and return the previous value.
+
+   procedure Add_RACW_Asynchronous_Flag
+     (Declarations : List_Id;
+      RACW_Type    : Entity_Id);
+   --  Declare a boolean constant associated with RACW_Type whose value
+   --  indicates at run time whether a pragma Asynchronous applies to it.
+
+   procedure Assign_Subprogram_Identifier
+     (Def : Entity_Id;
+      Spn : Int;
+      Id  : out String_Id);
+   --  Determine the distribution subprogram identifier to
+   --  be used for remote subprogram Def, return it in Id and
+   --  store it in a hash table for later retrieval by
+   --  Get_Subprogram_Id. Spn is the subprogram number.
 
    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
+      Package_Spec : Node_Id) return Node_Id;
+   --  Instantiate the generic package RCI_Locator 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;
@@ -361,8 +442,7 @@ package body Exp_Dist is
    function Input_With_Tag_Check
      (Loc      : Source_Ptr;
       Var_Type : Entity_Id;
-      Stream   : Entity_Id)
-     return Node_Id;
+      Stream   : Node_Id) return Node_Id;
    --  Return a function with the following form:
    --    function R return Var_Type is
    --    begin
@@ -373,11 +453,436 @@ package body Exp_Dist is
    --                            Exception_Message (E));
    --    end R;
 
+   procedure Build_Actual_Object_Declaration
+     (Object   : Entity_Id;
+      Etyp     : Entity_Id;
+      Variable : Boolean;
+      Expr     : Node_Id;
+      Decls    : List_Id);
+   --  Build the declaration of an object with the given defining identifier,
+   --  initialized with Expr if provided, to serve as actual parameter in a
+   --  server stub. If Variable is true, the declared object will be a variable
+   --  (case of an out or in out formal), else it will be a constant. Object's
+   --  Ekind is set accordingly. The declaration, as well as any other
+   --  declarations it requires, are appended to Decls.
+
+   --------------------------------------------
+   -- Hooks for PCS-specific code generation --
+   --------------------------------------------
+
+   --  Part of the code generation circuitry for distribution needs to be
+   --  tailored for each implementation of the PCS. For each routine that
+   --  needs to be specialized, a Specific_<routine> wrapper is created,
+   --  which calls the corresponding <routine> in package
+   --  <pcs_implementation>_Support.
+
+   procedure Specific_Add_RACW_Features
+     (RACW_Type           : Entity_Id;
+      Desig               : Entity_Id;
+      Stub_Type           : Entity_Id;
+      Stub_Type_Access    : Entity_Id;
+      RPC_Receiver_Decl   : Node_Id;
+      Body_Decls          : List_Id);
+   --  Add declaration for TSSs for a given RACW type. The declarations are
+   --  added just after the declaration of the RACW type itself. If the RACW
+   --  appears in the main unit, Body_Decls is a list of declarations to which
+   --  the bodies are appended. Else Body_Decls is No_List.
+   --  PCS-specific ancillary subprogram for Add_RACW_Features.
+
+   procedure Specific_Add_RAST_Features
+     (Vis_Decl : Node_Id;
+      RAS_Type : Entity_Id);
+   --  Add declaration for TSSs for a given RAS type. PCS-specific ancillary
+   --  subprogram for Add_RAST_Features.
+
+   --  An RPC_Target record is used during construction of calling stubs
+   --  to pass PCS-specific tree fragments corresponding to the information
+   --  necessary to locate the target of a remote subprogram call.
+
+   type RPC_Target (PCS_Kind : PCS_Names) is record
+      case PCS_Kind is
+         when Name_PolyORB_DSA =>
+            Object : Node_Id;
+            --  An expression whose value is a PolyORB reference to the target
+            --  object.
+
+         when others           =>
+            Partition : Entity_Id;
+            --  A variable containing the Partition_ID of the target partition
+
+            RPC_Receiver : Node_Id;
+            --  An expression whose value is the address of the target RPC
+            --  receiver.
+      end case;
+   end record;
+
+   procedure Specific_Build_General_Calling_Stubs
+     (Decls                     : List_Id;
+      Statements                : List_Id;
+      Target                    : RPC_Target;
+      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;
+      Stub_Type                 : Entity_Id := Empty;
+      RACW_Type                 : Entity_Id := Empty;
+      Nod                       : Node_Id);
+   --  Build calling stubs for general purpose. The parameters are:
+   --    Decls             : a place to put declarations
+   --    Statements        : a place to put statements
+   --    Target            : PCS-specific target information (see details
+   --                        in RPC_Target declaration).
+   --    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 Result_Definition if applicable
+   --    Stub_Type         : in case of RACW stubs, parameters of type access
+   --                        to Stub_Type will be marshalled using the
+   --                        address of the object (the addr field) rather
+   --                        than using the 'Write on the stub itself
+   --    Nod               : used to provide sloc for generated code
+
+   function Specific_Build_Stub_Target
+     (Loc                   : Source_Ptr;
+      Decls                 : List_Id;
+      RCI_Locator           : Entity_Id;
+      Controlling_Parameter : Entity_Id) return RPC_Target;
+   --  Build call target information nodes for use within calling stubs. In the
+   --  RCI case, RCI_Locator is the entity for the instance of RCI_Locator. If
+   --  for an RACW, Controlling_Parameter is the entity for the controlling
+   --  formal parameter used to determine the location of the target of the
+   --  call. Decls provides a location where variable declarations can be
+   --  appended to construct the necessary values.
+
+   procedure Specific_Build_Stub_Type
+     (RACW_Type         : Entity_Id;
+      Stub_Type         : Entity_Id;
+      Stub_Type_Decl    : out Node_Id;
+      RPC_Receiver_Decl : out Node_Id);
+   --  Build a type declaration for the stub type associated with an RACW
+   --  type, and the necessary RPC receiver, if applicable. PCS-specific
+   --  ancillary subprogram for Add_Stub_Type. If no RPC receiver declaration
+   --  is generated, then RPC_Receiver_Decl is set to Empty.
+
+   procedure Specific_Build_RPC_Receiver_Body
+     (RPC_Receiver : Entity_Id;
+      Request      : out Entity_Id;
+      Subp_Id      : out Entity_Id;
+      Subp_Index   : out Entity_Id;
+      Stmts        : out List_Id;
+      Decl         : out Node_Id);
+   --  Make a subprogram body for an RPC receiver, with the given
+   --  defining unit name. On return:
+   --    - Subp_Id is the subprogram identifier from the PCS.
+   --    - Subp_Index is the index in the list of subprograms
+   --      used for dispatching (a variable of type Subprogram_Id).
+   --    - Stmts is the place where the request dispatching
+   --      statements can occur,
+   --    - Decl is the subprogram body declaration.
+
+   function Specific_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.
+
+   procedure Specific_Add_Obj_RPC_Receiver_Completion
+     (Loc           : Source_Ptr;
+      Decls         : List_Id;
+      RPC_Receiver  : Entity_Id;
+      Stub_Elements : Stub_Structure);
+   --  Add the necessary code to Decls after the completion of generation
+   --  of the RACW RPC receiver described by Stub_Elements.
+
+   procedure Specific_Add_Receiving_Stubs_To_Declarations
+     (Pkg_Spec : Node_Id;
+      Decls    : List_Id;
+      Stmts    : List_Id);
+   --  Add receiving stubs to the declarative part of an RCI unit
+
+   package GARLIC_Support is
+
+      --  Support for generating DSA code that uses the GARLIC PCS
+
+      --  The subprograms below provide the GARLIC versions of the
+      --  corresponding Specific_<subprogram> routine declared above.
+
+      procedure Add_RACW_Features
+        (RACW_Type         : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Access  : Entity_Id;
+         RPC_Receiver_Decl : Node_Id;
+         Body_Decls        : List_Id);
+
+      procedure Add_RAST_Features
+        (Vis_Decl : Node_Id;
+         RAS_Type : Entity_Id);
+
+      procedure Build_General_Calling_Stubs
+        (Decls                     : List_Id;
+         Statements                : List_Id;
+         Target_Partition          : Entity_Id; --  From RPC_Target
+         Target_RPC_Receiver       : Node_Id;   --  From RPC_Target
+         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;
+         Stub_Type                 : Entity_Id := Empty;
+         RACW_Type                 : Entity_Id := Empty;
+         Nod                       : Node_Id);
+
+      function Build_Stub_Target
+        (Loc                   : Source_Ptr;
+         Decls                 : List_Id;
+         RCI_Locator           : Entity_Id;
+         Controlling_Parameter : Entity_Id) return RPC_Target;
+
+      procedure Build_Stub_Type
+        (RACW_Type         : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Decl    : out Node_Id;
+         RPC_Receiver_Decl : out Node_Id);
+
+      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;
+
+      procedure Add_Obj_RPC_Receiver_Completion
+        (Loc           : Source_Ptr;
+         Decls         : List_Id;
+         RPC_Receiver  : Entity_Id;
+         Stub_Elements : Stub_Structure);
+
+      procedure Add_Receiving_Stubs_To_Declarations
+        (Pkg_Spec : Node_Id;
+         Decls    : List_Id;
+         Stmts    : List_Id);
+
+      procedure Build_RPC_Receiver_Body
+        (RPC_Receiver : Entity_Id;
+         Request      : out Entity_Id;
+         Subp_Id      : out Entity_Id;
+         Subp_Index   : out Entity_Id;
+         Stmts        : out List_Id;
+         Decl         : out Node_Id);
+
+   end GARLIC_Support;
+
+   package PolyORB_Support is
+
+      --  Support for generating DSA code that uses the PolyORB PCS
+
+      --  The subprograms below provide the PolyORB versions of the
+      --  corresponding Specific_<subprogram> routine declared above.
+
+      procedure Add_RACW_Features
+        (RACW_Type         : Entity_Id;
+         Desig             : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Access  : Entity_Id;
+         RPC_Receiver_Decl : Node_Id;
+         Body_Decls        : List_Id);
+
+      procedure Add_RAST_Features
+        (Vis_Decl : Node_Id;
+         RAS_Type : Entity_Id);
+
+      procedure Build_General_Calling_Stubs
+        (Decls                     : List_Id;
+         Statements                : List_Id;
+         Target_Object             : Node_Id; --  From RPC_Target
+         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;
+         Stub_Type                 : Entity_Id := Empty;
+         RACW_Type                 : Entity_Id := Empty;
+         Nod                       : Node_Id);
+
+      function Build_Stub_Target
+        (Loc                   : Source_Ptr;
+         Decls                 : List_Id;
+         RCI_Locator           : Entity_Id;
+         Controlling_Parameter : Entity_Id) return RPC_Target;
+
+      procedure Build_Stub_Type
+        (RACW_Type         : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Decl    : out Node_Id;
+         RPC_Receiver_Decl : out Node_Id);
+
+      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;
+
+      procedure Add_Obj_RPC_Receiver_Completion
+        (Loc           : Source_Ptr;
+         Decls         : List_Id;
+         RPC_Receiver  : Entity_Id;
+         Stub_Elements : Stub_Structure);
+
+      procedure Add_Receiving_Stubs_To_Declarations
+        (Pkg_Spec : Node_Id;
+         Decls    : List_Id;
+         Stmts    : List_Id);
+
+      procedure Build_RPC_Receiver_Body
+        (RPC_Receiver : Entity_Id;
+         Request      : out Entity_Id;
+         Subp_Id      : out Entity_Id;
+         Subp_Index   : out Entity_Id;
+         Stmts        : out List_Id;
+         Decl         : out Node_Id);
+
+      procedure Reserve_NamingContext_Methods;
+      --  Mark the method names for interface NamingContext as already used in
+      --  the overload table, so no clashes occur with user code (with the
+      --  PolyORB PCS, RCIs Implement The NamingContext interface to allow
+      --  their methods to be accessed as objects, for the implementation of
+      --  remote access-to-subprogram types).
+
+      package Helpers is
+
+         --  Routines to build distribution helper subprograms for user-defined
+         --  types. For implementation of the Distributed systems annex (DSA)
+         --  over the PolyORB generic middleware components, it is necessary to
+         --  generate several supporting subprograms for each application data
+         --  type used in inter-partition communication. These subprograms are:
+
+         --    A Typecode function returning a high-level description of the
+         --    type's structure;
+
+         --    Two conversion functions allowing conversion of values of the
+         --    type from and to the generic data containers used by PolyORB.
+         --    These generic containers are called 'Any' type values after the
+         --    CORBA terminology, and hence the conversion subprograms are
+         --    named To_Any and From_Any.
+
+         function Build_From_Any_Call
+           (Typ   : Entity_Id;
+            N     : Node_Id;
+            Decls : List_Id) return Node_Id;
+         --  Build call to From_Any attribute function of type Typ with
+         --  expression N as actual parameter. Decls is the declarations list
+         --  for an appropriate enclosing scope of the point where the call
+         --  will be inserted; if the From_Any attribute for Typ needs to be
+         --  generated at this point, its declaration is appended to Decls.
+
+         procedure Build_From_Any_Function
+           (Loc  : Source_Ptr;
+            Typ  : Entity_Id;
+            Decl : out Node_Id;
+            Fnam : out Entity_Id);
+         --  Build From_Any attribute function for Typ. Loc is the reference
+         --  location for generated nodes, Typ is the type for which the
+         --  conversion function is generated. On return, Decl and Fnam contain
+         --  the declaration and entity for the newly-created function.
+
+         function Build_To_Any_Call
+           (N     : Node_Id;
+            Decls : List_Id) return Node_Id;
+         --  Build call to To_Any attribute function with expression as actual
+         --  parameter. Decls is the declarations list for an appropriate
+         --  enclosing scope of the point where the call will be inserted; if
+         --  the To_Any attribute for Typ needs to be generated at this point,
+         --  its declaration is appended to Decls.
+
+         procedure Build_To_Any_Function
+           (Loc  : Source_Ptr;
+            Typ  : Entity_Id;
+            Decl : out Node_Id;
+            Fnam : out Entity_Id);
+         --  Build To_Any attribute function for Typ. Loc is the reference
+         --  location for generated nodes, Typ is the type for which the
+         --  conversion function is generated. On return, Decl and Fnam contain
+         --  the declaration and entity for the newly-created function.
+
+         function Build_TypeCode_Call
+           (Loc   : Source_Ptr;
+            Typ   : Entity_Id;
+            Decls : List_Id) return Node_Id;
+         --  Build call to TypeCode attribute function for Typ. Decls is the
+         --  declarations list for an appropriate enclosing scope of the point
+         --  where the call will be inserted; if the To_Any attribute for Typ
+         --  needs to be generated at this point, its declaration is appended
+         --  to Decls.
+
+         procedure Build_TypeCode_Function
+           (Loc  : Source_Ptr;
+            Typ  : Entity_Id;
+            Decl : out Node_Id;
+            Fnam : out Entity_Id);
+         --  Build TypeCode attribute function for Typ. Loc is the reference
+         --  location for generated nodes, Typ is the type for which the
+         --  conversion function is generated. On return, Decl and Fnam contain
+         --  the declaration and entity for the newly-created function.
+
+         procedure Build_Name_And_Repository_Id
+           (E           : Entity_Id;
+            Name_Str    : out String_Id;
+            Repo_Id_Str : out String_Id);
+         --  In the PolyORB distribution model, each distributed object type
+         --  and each distributed operation has a globally unique identifier,
+         --  its Repository Id. This subprogram builds and returns two strings
+         --  for entity E (a distributed object type or operation): one
+         --  containing the name of E, the second containing its repository id.
+
+      end Helpers;
+
+   end PolyORB_Support;
+
+   --  The following PolyORB-specific subprograms are made visible to Exp_Attr:
+
+   function Build_From_Any_Call
+     (Typ   : Entity_Id;
+      N     : Node_Id;
+      Decls : List_Id) return Node_Id
+     renames PolyORB_Support.Helpers.Build_From_Any_Call;
+
+   function Build_To_Any_Call
+     (N     : Node_Id;
+      Decls : List_Id) return Node_Id
+     renames PolyORB_Support.Helpers.Build_To_Any_Call;
+
+   function Build_TypeCode_Call
+     (Loc   : Source_Ptr;
+      Typ   : Entity_Id;
+      Decls : List_Id) return Node_Id
+     renames PolyORB_Support.Helpers.Build_TypeCode_Call;
+
    ------------------------------------
    -- Local variables and structures --
    ------------------------------------
 
    RCI_Cache : Node_Id;
+   --  Needs comments ???
 
    Output_From_Constrained : constant array (Boolean) of Name_Id :=
      (False => Name_Output,
@@ -392,24 +897,27 @@ package body Exp_Dist is
    ---------------------------------------
 
    procedure Add_Calling_Stubs_To_Declarations
-     (Pkg_Spec : in Node_Id;
-      Decls    : in List_Id)
+     (Pkg_Spec : Node_Id;
+      Decls    : List_Id)
    is
-      Current_Subprogram_Number : Int := 0;
-      Current_Declaration       : Node_Id;
-
-      Loc                       : constant Source_Ptr := Sloc (Pkg_Spec);
+      Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
+      --  Subprogram id 0 is reserved for calls received from
+      --  remote access-to-subprogram dereferences.
 
-      RCI_Instantiation         : Node_Id;
+      Current_Declaration : Node_Id;
+      Loc                 : constant Source_Ptr := Sloc (Pkg_Spec);
+      RCI_Instantiation   : Node_Id;
+      Subp_Stubs          : Node_Id;
+      Subp_Str            : String_Id;
 
-      Subp_Stubs                : Node_Id;
+      pragma Warnings (Off, Subp_Str);
 
    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.
+      --  System.Partition_Interface.RCI_Locator with the name of this 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);
@@ -417,27 +925,31 @@ package body Exp_Dist is
       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));
+      --  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.
 
-      while Current_Declaration /= Empty loop
+      Overload_Counter_Table.Reset;
+      PolyORB_Support.Reserve_NamingContext_Methods;
 
+      Current_Declaration := First (Visible_Declarations (Pkg_Spec));
+      while Present (Current_Declaration) 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))));
+            Assign_Subprogram_Identifier
+              (Defining_Unit_Name (Specification (Current_Declaration)),
+               Current_Subprogram_Number,
+               Subp_Str);
 
             Subp_Stubs :=
               Build_Subprogram_Calling_Stubs (
                 Vis_Decl     => Current_Declaration,
-                Subp_Id      => Current_Subprogram_Number,
+                Subp_Id      =>
+                  Build_Subprogram_Id (Loc,
+                    Defining_Unit_Name (Specification (Current_Declaration))),
                 Asynchronous =>
                   Nkind (Specification (Current_Declaration)) =
                     N_Procedure_Specification
@@ -453,52 +965,198 @@ package body Exp_Dist is
 
          Next (Current_Declaration);
       end loop;
-
    end Add_Calling_Stubs_To_Declarations;
 
+   -----------------------------
+   -- Add_Parameter_To_NVList --
+   -----------------------------
+
+   function Add_Parameter_To_NVList
+     (Loc         : Source_Ptr;
+      NVList      : Entity_Id;
+      Parameter   : Entity_Id;
+      Constrained : Boolean;
+      RACW_Ctrl   : Boolean := False;
+      Any         : Entity_Id) return Node_Id
+   is
+      Parameter_Name_String : String_Id;
+      Parameter_Mode        : Node_Id;
+
+      function Parameter_Passing_Mode
+        (Loc         : Source_Ptr;
+         Parameter   : Entity_Id;
+         Constrained : Boolean) return Node_Id;
+      --  Return an expression that denotes the parameter passing mode to be
+      --  used for Parameter in distribution stubs, where Constrained is
+      --  Parameter's constrained status.
+
+      ----------------------------
+      -- Parameter_Passing_Mode --
+      ----------------------------
+
+      function Parameter_Passing_Mode
+        (Loc         : Source_Ptr;
+         Parameter   : Entity_Id;
+         Constrained : Boolean) return Node_Id
+      is
+         Lib_RE : RE_Id;
+
+      begin
+         if Out_Present (Parameter) then
+            if In_Present (Parameter)
+              or else not Constrained
+            then
+               --  Unconstrained formals must be translated
+               --  to 'in' or 'inout', not 'out', because
+               --  they need to be constrained by the actual.
+
+               Lib_RE := RE_Mode_Inout;
+            else
+               Lib_RE := RE_Mode_Out;
+            end if;
+
+         else
+            Lib_RE := RE_Mode_In;
+         end if;
+
+         return New_Occurrence_Of (RTE (Lib_RE), Loc);
+      end Parameter_Passing_Mode;
+
+   --  Start of processing for Add_Parameter_To_NVList
+
+   begin
+      if Nkind (Parameter) = N_Defining_Identifier then
+         Get_Name_String (Chars (Parameter));
+      else
+         Get_Name_String (Chars (Defining_Identifier (Parameter)));
+      end if;
+
+      Parameter_Name_String := String_From_Name_Buffer;
+
+      if RACW_Ctrl or else Nkind (Parameter) = N_Defining_Identifier then
+
+         --  When the parameter passed to Add_Parameter_To_NVList is an
+         --  Extra_Constrained parameter, Parameter is an N_Defining_
+         --  Identifier, instead of a complete N_Parameter_Specification.
+         --  Thus, we explicitly set 'in' mode in this case.
+
+         Parameter_Mode := New_Occurrence_Of (RTE (RE_Mode_In), Loc);
+
+      else
+         Parameter_Mode :=
+           Parameter_Passing_Mode (Loc, Parameter, Constrained);
+      end if;
+
+      return
+        Make_Procedure_Call_Statement (Loc,
+          Name =>
+            New_Occurrence_Of
+              (RTE (RE_NVList_Add_Item), Loc),
+          Parameter_Associations => New_List (
+            New_Occurrence_Of (NVList, Loc),
+            Make_Function_Call (Loc,
+              Name =>
+                New_Occurrence_Of
+                  (RTE (RE_To_PolyORB_String), Loc),
+              Parameter_Associations => New_List (
+                Make_String_Literal (Loc,
+                  Strval => Parameter_Name_String))),
+            New_Occurrence_Of (Any, Loc),
+            Parameter_Mode));
+   end Add_Parameter_To_NVList;
+
+   --------------------------------
+   -- Add_RACW_Asynchronous_Flag --
+   --------------------------------
+
+   procedure Add_RACW_Asynchronous_Flag
+     (Declarations : List_Id;
+      RACW_Type    : Entity_Id)
+   is
+      Loc : constant Source_Ptr := Sloc (RACW_Type);
+
+      Asynchronous_Flag : constant Entity_Id :=
+                            Make_Defining_Identifier (Loc,
+                              New_External_Name (Chars (RACW_Type), 'A'));
+
+   begin
+      --  Declare the asynchronous flag. This flag will be changed to True
+      --  whenever it is known that the RACW type is asynchronous.
+
+      Append_To (Declarations,
+        Make_Object_Declaration (Loc,
+          Defining_Identifier => Asynchronous_Flag,
+          Constant_Present    => True,
+          Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
+          Expression          => New_Occurrence_Of (Standard_False, Loc)));
+
+      Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Flag);
+   end Add_RACW_Asynchronous_Flag;
+
    -----------------------
    -- 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));
+   procedure Add_RACW_Features (RACW_Type : Entity_Id) is
+      Desig      : constant Entity_Id := Etype (Designated_Type (RACW_Type));
+      Same_Scope : constant Boolean   := Scope (Desig) = Scope (RACW_Type);
 
-      Same_Scope : constant Boolean :=
-                     Scope (Desig) = Scope (RACW_Type);
+      Pkg_Spec   : Node_Id;
+      Decls      : List_Id;
+      Body_Decls : List_Id;
 
-      Stub_Type           : Entity_Id;
-      Stub_Type_Access    : Entity_Id;
-      Object_RPC_Receiver : Entity_Id;
-      Existing            : Boolean;
+      Stub_Type         : Entity_Id;
+      Stub_Type_Access  : Entity_Id;
+      RPC_Receiver_Decl : Node_Id;
+
+      Existing : Boolean;
+      --  True when appropriate stubs have already been generated (this is the
+      --  case when another RACW with the same designated type has already been
+      --  encountered), in which case we reuse the previous stubs rather than
+      --  generating new ones.
 
    begin
       if not Expander_Active then
          return;
       end if;
 
+      --  Mark the current package declaration as containing an RACW, so that
+      --  the bodies for the calling stubs and the RACW stream subprograms
+      --  are attached to the tree when the corresponding body is encountered.
+
+      Set_Has_RACW (Current_Scope);
+
+      --  Look for place to declare the RACW stub type and RACW operations
+
+      Pkg_Spec := Empty;
+
       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.
+         --  Case of declaring the RACW in the same package as its designated
+         --  type: we know that the designated type is a private type, so we
+         --  use the private declarations list.
 
-         Decls := Private_Declarations
-           (Package_Specification_Of_Scope (Current_Scope));
+         Pkg_Spec := Package_Specification_Of_Scope (Current_Scope);
+
+         if Present (Private_Declarations (Pkg_Spec)) then
+            Decls := Private_Declarations (Pkg_Spec);
+         else
+            Decls := Visible_Declarations (Pkg_Spec);
+         end if;
+
+      else
+
+         --  Case of declaring the RACW in another package than its designated
+         --  type: use the private declarations list if present; otherwise
+         --  use the visible declarations.
+
+         Decls := List_Containing (Declaration_Node (RACW_Type));
 
-      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.
+      --  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;
@@ -510,60 +1168,90 @@ package body Exp_Dist is
          Decls               => Decls,
          Stub_Type           => Stub_Type,
          Stub_Type_Access    => Stub_Type_Access,
-         Object_RPC_Receiver => Object_RPC_Receiver,
+         RPC_Receiver_Decl   => RPC_Receiver_Decl,
+         Body_Decls          => Body_Decls,
          Existing            => Existing);
 
-      Add_RACW_Read_Write_Attributes
+      --  If this RACW is not in the main unit, do not generate primitive or
+      --  TSS bodies.
+
+      if not Entity_Is_In_Main_Unit (RACW_Type) then
+         Body_Decls := No_List;
+      end if;
+
+      Add_RACW_Asynchronous_Flag
+        (Declarations        => Decls,
+         RACW_Type           => RACW_Type);
+
+      Specific_Add_RACW_Features
         (RACW_Type           => RACW_Type,
+         Desig               => Desig,
          Stub_Type           => Stub_Type,
          Stub_Type_Access    => Stub_Type_Access,
-         Object_RPC_Receiver => Object_RPC_Receiver,
-         Declarations        => Decls);
+         RPC_Receiver_Decl   => RPC_Receiver_Decl,
+         Body_Decls          => Body_Decls);
 
-      if not Same_Scope and then not Existing then
+      --  If we already have stubs for this designated type, nothing to do
 
-         --  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.
+      if Existing then
+         return;
+      end if;
 
+      if Is_Frozen (Desig) then
+         Validate_RACW_Primitives (RACW_Type);
          Add_RACW_Primitive_Declarations_And_Bodies
            (Designated_Type  => Desig,
-            Insertion_Node   =>
-              Parent (Declaration_Node (Object_RPC_Receiver)),
-            Decls            => Decls);
+            Insertion_Node   => RPC_Receiver_Decl,
+            Body_Decls       => Body_Decls);
 
       else
+         --  Validate_RACW_Primitives requires the list of all primitives of
+         --  the designated type, so defer processing until Desig is frozen.
+         --  See Exp_Ch3.Freeze_Type.
+
          Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
       end if;
    end Add_RACW_Features;
 
-   -------------------------------------------------
-   --  Add_RACW_Primitive_Declarations_And_Bodies --
-   -------------------------------------------------
+   ------------------------------------------------
+   -- 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)
+     (Designated_Type : Entity_Id;
+      Insertion_Node  : Node_Id;
+      Body_Decls      : 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);
+      --  Set Sloc of generated declaration copy of insertion node Sloc, so
+      --  the declarations are recognized as belonging to the current package.
 
       Stub_Elements : constant Stub_Structure :=
-        Stubs_Table.Get (Designated_Type);
+                        Stubs_Table.Get (Designated_Type);
 
       pragma Assert (Stub_Elements /= Empty_Stub_Structure);
 
+      Is_RAS : constant Boolean :=
+                 not Comes_From_Source (Stub_Elements.RACW_Type);
+      --  Case of the RACW generated to implement a remote access-to-
+      --  subprogram type.
+
+      Build_Bodies : constant Boolean :=
+                       In_Extended_Main_Code_Unit (Stub_Elements.Stub_Type);
+      --  True when bodies must be prepared in Body_Decls. Bodies are generated
+      --  only when the main unit is the unit that contains the stub type.
+
       Current_Insertion_Node : Node_Id := Insertion_Node;
 
-      RPC_Receiver_Declarations      : List_Id;
+      RPC_Receiver                   : Entity_Id;
       RPC_Receiver_Statements        : List_Id;
       RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
+      RPC_Receiver_Elsif_Parts       : List_Id;
+      RPC_Receiver_Request           : Entity_Id;
       RPC_Receiver_Subp_Id           : Entity_Id;
+      RPC_Receiver_Subp_Index        : Entity_Id;
+
+      Subp_Str : String_Id;
 
       Current_Primitive_Elmt   : Elmt_Id;
       Current_Primitive        : Entity_Id;
@@ -571,42 +1259,68 @@ package body Exp_Dist is
       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;
 
-      Current_Primitive_Alias : Node_Id;
+   begin
+      if not Expander_Active then
+         return;
+      end if;
 
-      Current_Receiver      : Entity_Id;
-      Current_Receiver_Body : Node_Id;
+      if not Is_RAS then
+         RPC_Receiver :=
+           Make_Defining_Identifier (Loc,
+             Chars => New_Internal_Name ('P'));
 
-      RPC_Receiver_Decl : Node_Id;
+         Specific_Build_RPC_Receiver_Body
+           (RPC_Receiver => RPC_Receiver,
+            Request      => RPC_Receiver_Request,
+            Subp_Id      => RPC_Receiver_Subp_Id,
+            Subp_Index   => RPC_Receiver_Subp_Index,
+            Stmts        => RPC_Receiver_Statements,
+            Decl         => RPC_Receiver_Decl);
 
-      Possibly_Asynchronous : Boolean;
+         if Get_PCS_Name = Name_PolyORB_DSA then
 
-   begin
-      if not Expander_Active then
-         return;
+            --  For the case of PolyORB, we need to map a textual operation
+            --  name into a primitive index. Currently we do so using a simple
+            --  sequence of string comparisons.
+
+            RPC_Receiver_Elsif_Parts := New_List;
+         end if;
       end if;
 
       --  Build callers, receivers for every primitive operations and a RPC
       --  receiver for this type.
 
       if Present (Primitive_Operations (Designated_Type)) then
+         Overload_Counter_Table.Reset;
 
          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.
+            --  Copy the primitive of all the parents, except predefined ones
+            --  that are not remotely dispatching. Also omit hidden primitives
+            --  (occurs in the case of primitives of interface progenitors
+            --  other than immediate ancestors of the Designated_Type).
 
             if Chars (Current_Primitive) /= Name_uSize
               and then Chars (Current_Primitive) /= Name_uAlignment
-              and then not Is_TSS (Current_Primitive, TSS_Deep_Finalize)
+              and then not
+                (Is_TSS (Current_Primitive, TSS_Deep_Finalize) or else
+                 Is_TSS (Current_Primitive, TSS_Stream_Input)  or else
+                 Is_TSS (Current_Primitive, TSS_Stream_Output) or else
+                 Is_TSS (Current_Primitive, TSS_Stream_Read)   or else
+                 Is_TSS (Current_Primitive, TSS_Stream_Write))
+              and then not Is_Hidden (Current_Primitive)
             then
-               --  The first thing to do is build an up-to-date copy of
-               --  the spec with all the formals referencing Designated_Type
+               --  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.
@@ -619,70 +1333,111 @@ package body Exp_Dist is
                   Current_Primitive_Alias := Alias (Current_Primitive_Alias);
                end loop;
 
+               --  Copy the spec from the original declaration for the purpose
+               --  of declaring an overriding subprogram: we need to replace
+               --  the type of each controlling formal with Stub_Type. The
+               --  primitive may have been declared for Designated_Type or
+               --  inherited from some ancestor type for which we do not have
+               --  an easily determined Entity_Id. We have no systematic way
+               --  of knowing which type to substitute Stub_Type for. Instead,
+               --  Copy_Specification relies on the flag Is_Controlling_Formal
+               --  to determine which formals to change.
+
                Current_Primitive_Spec :=
                  Copy_Specification (Loc,
                    Spec        => Parent (Current_Primitive_Alias),
-                   Object_Type => Designated_Type,
-                   Stub_Type   => Stub_Elements.Stub_Type);
+                   Ctrl_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);
+               Insert_After_And_Analyze (Current_Insertion_Node,
+                 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);
+               Assign_Subprogram_Identifier (
+                 Defining_Unit_Name (Current_Primitive_Spec),
+                 Current_Primitive_Number,
+                 Subp_Str);
+
+               if Build_Bodies then
+                  Current_Primitive_Body :=
+                    Build_Subprogram_Calling_Stubs
+                      (Vis_Decl                 => Current_Primitive_Decl,
+                       Subp_Id                  =>
+                         Build_Subprogram_Id (Loc,
+                           Defining_Unit_Name (Current_Primitive_Spec)),
+                       Asynchronous             => Possibly_Asynchronous,
+                       Dynamically_Asynchronous => Possibly_Asynchronous,
+                       Stub_Type                => Stub_Elements.Stub_Type,
+                       RACW_Type                => Stub_Elements.RACW_Type);
+                  Append_To (Body_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 (and in the context of the
+                  --  appropriate unit body, see Append_RACW_Bodies).
 
-               --  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.
+               end if;
 
                --  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)),
+               if Build_Bodies and then not Is_RAS then
+                  Current_Receiver_Body :=
+                    Specific_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 (Body_Decls, Current_Receiver_Body);
+
+                  --  Add a case alternative to the receiver
+
+                  if Get_PCS_Name = Name_PolyORB_DSA then
+                     Append_To (RPC_Receiver_Elsif_Parts,
+                       Make_Elsif_Part (Loc,
+                         Condition =>
+                           Make_Function_Call (Loc,
+                             Name =>
+                               New_Occurrence_Of (
+                                 RTE (RE_Caseless_String_Eq), Loc),
+                             Parameter_Associations => New_List (
+                               New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
+                               Make_String_Literal (Loc, Subp_Str))),
+
+                         Then_Statements => New_List (
+                           Make_Assignment_Statement (Loc,
+                             Name => New_Occurrence_Of (
+                                       RPC_Receiver_Subp_Index, Loc),
+                             Expression =>
+                               Make_Integer_Literal (Loc,
+                                  Intval => Current_Primitive_Number)))));
+                  end if;
 
-                   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))))));
+                  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 (RPC_Receiver_Request, Loc))))));
+               end if;
 
                --  Increment the index of current primitive
 
@@ -695,3094 +1450,9611 @@ package body Exp_Dist is
 
       --  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))));
+      if Build_Bodies and then not Is_RAS then
+         if Get_PCS_Name = Name_PolyORB_DSA
+           and then Present (First (RPC_Receiver_Elsif_Parts))
+         then
+            Append_To (RPC_Receiver_Statements,
+              Make_Implicit_If_Statement (Designated_Type,
+                Condition       => New_Occurrence_Of (Standard_False, Loc),
+                Then_Statements => New_List,
+                Elsif_Parts     => RPC_Receiver_Elsif_Parts));
+         end if;
 
-      Append_To (RPC_Receiver_Statements,
-        Make_Case_Statement (Loc,
-          Expression   =>
-            New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
-          Alternatives => RPC_Receiver_Case_Alternatives));
+         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_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 (RPC_Receiver_Statements,
+           Make_Case_Statement (Loc,
+             Expression   =>
+               New_Occurrence_Of (RPC_Receiver_Subp_Index, Loc),
+             Alternatives => RPC_Receiver_Case_Alternatives));
 
-      Append_To (Decls, RPC_Receiver_Decl);
+         Append_To (Body_Decls, RPC_Receiver_Decl);
+         Specific_Add_Obj_RPC_Receiver_Completion (Loc,
+           Body_Decls, RPC_Receiver, Stub_Elements);
 
-      --  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.
+      --  Do not analyze RPC receiver body at this stage since it references
+      --  subprograms that have not been analyzed yet. It will be analyzed in
+      --  the regular flow (see Append_RACW_Bodies).
 
+      end if;
    end Add_RACW_Primitive_Declarations_And_Bodies;
 
    -----------------------------
-   -- Add_RACW_Read_Attribute --
+   -- Add_RAS_Dereference_TSS --
    -----------------------------
 
-   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);
+   procedure Add_RAS_Dereference_TSS (N : Node_Id) is
+      Loc : constant Source_Ptr := Sloc (N);
 
-      Proc_Decl : Node_Id;
-      Attr_Decl : Node_Id;
+      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);
+      RACW_Type : constant Entity_Id := Underlying_RACW_Type (RAS_Type);
 
-      Body_Node : Node_Id;
+      RACW_Primitive_Name : 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'));
-      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);
+      Proc : constant Entity_Id :=
+               Make_Defining_Identifier (Loc,
+                 Chars => Make_TSS_Name (RAS_Type, TSS_RAS_Dereference));
 
-      --  Functions to create occurrences of the formal
-      --  parameter names.
+      Proc_Spec   : Node_Id;
+      Param_Specs : List_Id;
+      Param_Assoc : constant List_Id := New_List;
+      Stmts       : constant List_Id := New_List;
 
-      function Stream_Parameter return Node_Id;
-      function Result return Node_Id;
+      RAS_Parameter : constant Entity_Id :=
+                        Make_Defining_Identifier (Loc,
+                          Chars => New_Internal_Name ('P'));
 
-      function Stream_Parameter return Node_Id is
-      begin
-         return Make_Identifier (Loc, Name_S);
-      end Stream_Parameter;
+      Is_Function : constant Boolean :=
+                      Nkind (Type_Def) = N_Access_Function_Definition;
 
-      function Result return Node_Id is
-      begin
-         return Make_Identifier (Loc, Name_V);
-      end Result;
+      Is_Degenerate : Boolean;
+      --  Set to True if the subprogram_specification for this RAS has an
+      --  anonymous access parameter (see Process_Remote_AST_Declaration).
 
-   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));
+      Spec : constant Node_Id := Type_Def;
 
-      Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Node);
+      Current_Parameter : Node_Id;
 
-      --  Object declarations
+   --  Start of processing for Add_RAS_Dereference_TSS
 
-      Decls := New_List (
-        Make_Object_Declaration (Loc,
-          Defining_Identifier => Source_Partition,
-          Object_Definition   =>
-            New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
+   begin
+      --  The Dereference TSS for a remote access-to-subprogram type has the
+      --  form:
 
-        Make_Object_Declaration (Loc,
-          Defining_Identifier => Source_Receiver,
-          Object_Definition   =>
-            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
+      --    [function|procedure] ras_typeRD (RAS_Value, <RAS_Parameters>)
+      --       [return <>]
 
-        Make_Object_Declaration (Loc,
-          Defining_Identifier => Source_Address,
-          Object_Definition   =>
-            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
+      --  This is called whenever a value of a RAS type is dereferenced
 
-        Make_Object_Declaration (Loc,
-          Defining_Identifier => Stubbed_Result,
-          Object_Definition   =>
-            New_Occurrence_Of (Stub_Type_Access, Loc)));
+      --  First construct a list of parameter specifications:
 
-      --  Read the source Partition_ID and RPC_Receiver from incoming stream
+      --  The first formal is the RAS values
 
-      Statements := New_List (
-        Make_Attribute_Reference (Loc,
-          Prefix         =>
-            New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
-          Attribute_Name => Name_Read,
-          Expressions    => New_List (
-            Stream_Parameter,
-            New_Occurrence_Of (Source_Partition, Loc))),
+      Param_Specs := New_List (
+        Make_Parameter_Specification (Loc,
+          Defining_Identifier => RAS_Parameter,
+          In_Present          => True,
+          Parameter_Type      =>
+            New_Occurrence_Of (Fat_Type, Loc)));
 
-        Make_Attribute_Reference (Loc,
-          Prefix         =>
-            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
-          Attribute_Name =>
-            Name_Read,
-          Expressions    => New_List (
-            Stream_Parameter,
-            New_Occurrence_Of (Source_Receiver, Loc))),
+      --  The following formals are copied from the type declaration
 
-        Make_Attribute_Reference (Loc,
-          Prefix         =>
-            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
-          Attribute_Name =>
-            Name_Read,
-          Expressions    => New_List (
-            Stream_Parameter,
-            New_Occurrence_Of (Source_Address, Loc))));
+      Is_Degenerate := False;
+      Current_Parameter := First (Parameter_Specifications (Type_Def));
+      Parameters : while Present (Current_Parameter) loop
+         if Nkind (Parameter_Type (Current_Parameter)) =
+                                            N_Access_Definition
+         then
+            Is_Degenerate := True;
+         end if;
 
-      --  If the Address is Null_Address, then return a null object
+         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_Copy_Tree (Parameter_Type (Current_Parameter)),
+             Expression        =>
+               New_Copy_Tree (Expression (Current_Parameter))));
+
+         Append_To (Param_Assoc,
+           Make_Identifier (Loc,
+             Chars => Chars (Defining_Identifier (Current_Parameter))));
 
-      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       => Result,
-              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       => Result,
-          Expression =>
-            Unchecked_Convert_To (RACW_Type,
-              OK_Convert_To (RTE (RE_Address),
-                New_Occurrence_Of (Source_Address, Loc)))));
+         Next (Current_Parameter);
+      end loop Parameters;
 
-      --  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.
+      if Is_Degenerate then
+         Prepend_To (Param_Assoc, New_Occurrence_Of (RAS_Parameter, Loc));
 
-      Remote_Statements := New_List (
+         --  Generate a dummy body. This code will never actually be executed,
+         --  because null is the only legal value for a degenerate RAS type.
+         --  For legality's sake (in order to avoid generating a function that
+         --  does not contain a return statement), we include a dummy recursive
+         --  call on the TSS itself.
 
-        Make_Assignment_Statement (Loc,
-          Name       => New_Occurrence_Of (Stubbed_Result, Loc),
-          Expression =>
-            Make_Allocator (Loc,
-              New_Occurrence_Of (Stub_Type, Loc))),
+         Append_To (Stmts,
+           Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
+         RACW_Primitive_Name := New_Occurrence_Of (Proc, 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)),
+      else
+         --  For a normal RAS type, we cast the RAS formal to the corresponding
+         --  tagged type, and perform a dispatching call to its Call primitive
+         --  operation.
 
-        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)),
+         Prepend_To (Param_Assoc,
+           Unchecked_Convert_To (RACW_Type,
+             New_Occurrence_Of (RAS_Parameter, 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)));
+         RACW_Primitive_Name :=
+           Make_Selected_Component (Loc,
+             Prefix        => Scope (RACW_Type),
+             Selector_Name => Name_uCall);
+      end if;
 
-      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)));
+      if Is_Function then
+         Append_To (Stmts,
+            Make_Simple_Return_Statement (Loc,
+              Expression =>
+                Make_Function_Call (Loc,
+                  Name                   => RACW_Primitive_Name,
+                  Parameter_Associations => Param_Assoc)));
 
-      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)))));
+      else
+         Append_To (Stmts,
+           Make_Procedure_Call_Statement (Loc,
+             Name                   => RACW_Primitive_Name,
+             Parameter_Associations => Param_Assoc));
+      end if;
 
-      Append_To (Remote_Statements,
-        Make_Assignment_Statement (Loc,
-          Name       => Result,
-          Expression => Unchecked_Convert_To (RACW_Type,
-            New_Occurrence_Of (Stubbed_Result, Loc))));
+      --  Build the complete subprogram
 
-      --  Distinguish between the local and remote cases, and execute the
-      --  appropriate piece of code.
+      if Is_Function then
+         Proc_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name       => Proc,
+             Parameter_Specifications => Param_Specs,
+             Result_Definition        =>
+               New_Occurrence_Of (
+                 Entity (Result_Definition (Spec)), Loc));
 
-      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));
-
-      Build_Stream_Procedure
-        (Loc, RACW_Type, Body_Node,
-         Make_Defining_Identifier (Loc, Procedure_Name),
-         Statements, Outp => True);
-      Set_Declarations (Body_Node, Decls);
-
-      Proc_Decl := Make_Subprogram_Declaration (Loc,
-        Copy_Specification (Loc, Specification (Body_Node)));
-
-      Attr_Decl :=
-        Make_Attribute_Definition_Clause (Loc,
-          Name       => New_Occurrence_Of (RACW_Type, Loc),
-          Chars      => Name_Read,
-          Expression =>
-            New_Occurrence_Of (
-              Defining_Unit_Name (Specification (Proc_Decl)), Loc));
+         Set_Ekind (Proc, E_Function);
+         Set_Etype (Proc,
+           New_Occurrence_Of (Entity (Result_Definition (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;
+      else
+         Proc_Spec :=
+           Make_Procedure_Specification (Loc,
+             Defining_Unit_Name       => Proc,
+             Parameter_Specifications => Param_Specs);
 
-   ------------------------------------
-   -- Add_RACW_Read_Write_Attributes --
-   ------------------------------------
+         Set_Ekind (Proc, E_Procedure);
+         Set_Etype (Proc, Standard_Void_Type);
+      end if;
 
-   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);
+      Discard_Node (
+        Make_Subprogram_Body (Loc,
+          Specification              => Proc_Spec,
+          Declarations               => New_List,
+          Handled_Statement_Sequence =>
+            Make_Handled_Sequence_Of_Statements (Loc,
+              Statements => Stmts)));
 
-      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;
+      Set_TSS (Fat_Type, Proc);
+   end Add_RAS_Dereference_TSS;
 
-   ------------------------------
-   -- Add_RACW_Write_Attribute --
-   ------------------------------
+   -------------------------------
+   -- Add_RAS_Proxy_And_Analyze --
+   -------------------------------
 
-   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)
+   procedure Add_RAS_Proxy_And_Analyze
+     (Decls              : List_Id;
+      Vis_Decl           : Node_Id;
+      All_Calls_Remote_E : Entity_Id;
+      Proxy_Object_Addr  : out Entity_Id)
    is
-      Loc : constant Source_Ptr := Sloc (RACW_Type);
+      Loc : constant Source_Ptr := Sloc (Vis_Decl);
 
-      Body_Node : Node_Id;
-      Proc_Decl : Node_Id;
-      Attr_Decl : Node_Id;
+      Subp_Name : constant Entity_Id :=
+                     Defining_Unit_Name (Specification (Vis_Decl));
 
-      Statements        : List_Id;
-      Local_Statements  : List_Id;
-      Remote_Statements : List_Id;
-      Null_Statements   : List_Id;
+      Pkg_Name : constant Entity_Id :=
+                   Make_Defining_Identifier (Loc,
+                     Chars => New_External_Name (Chars (Subp_Name), 'P', -1));
 
-      Procedure_Name    : constant Name_Id := New_Internal_Name ('R');
+      Proxy_Type : constant Entity_Id :=
+                     Make_Defining_Identifier (Loc,
+                       Chars =>
+                         New_External_Name
+                           (Related_Id => Chars (Subp_Name),
+                            Suffix     => 'P'));
 
-      --  Functions to create occurrences of the formal
-      --  parameter names.
+      Proxy_Type_Full_View : constant Entity_Id :=
+                               Make_Defining_Identifier (Loc,
+                                 Chars (Proxy_Type));
 
-      function Stream_Parameter return Node_Id;
-      function Object return Node_Id;
+      Subp_Decl_Spec : constant Node_Id :=
+                         Build_RAS_Primitive_Specification
+                           (Subp_Spec          => Specification (Vis_Decl),
+                            Remote_Object_Type => Proxy_Type);
 
-      function Stream_Parameter return Node_Id is
-      begin
-         return Make_Identifier (Loc, Name_S);
-      end Stream_Parameter;
+      Subp_Body_Spec : constant Node_Id :=
+                         Build_RAS_Primitive_Specification
+                           (Subp_Spec          => Specification (Vis_Decl),
+                            Remote_Object_Type => Proxy_Type);
 
-      function Object return Node_Id is
-      begin
-         return Make_Identifier (Loc, Name_V);
-      end Object;
+      Vis_Decls    : constant List_Id := New_List;
+      Pvt_Decls    : constant List_Id := New_List;
+      Actuals      : constant List_Id := New_List;
+      Formal       : Node_Id;
+      Perform_Call : Node_Id;
 
    begin
-      --  Build the code fragment corresponding to the marshalling of a
-      --  local object.
-
-      Local_Statements := New_List (
+      --  type subpP is tagged limited private;
 
-        Pack_Entity_Into_Stream_Access (Loc,
-          Stream => Stream_Parameter,
-          Object => RTE (RE_Get_Local_Partition_Id)),
+      Append_To (Vis_Decls,
+        Make_Private_Type_Declaration (Loc,
+          Defining_Identifier => Proxy_Type,
+          Tagged_Present      => True,
+          Limited_Present     => True));
 
-        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)),
+      --  [subprogram] Call
+      --    (Self : access subpP;
+      --     ...other-formals...)
+      --     [return T];
 
-        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 => Object),
-              Attribute_Name => Name_Address)),
-          Etyp   => RTE (RE_Unsigned_64)));
+      Append_To (Vis_Decls,
+        Make_Subprogram_Declaration (Loc,
+          Specification => Subp_Decl_Spec));
 
-      --  Build the code fragment corresponding to the marshalling of
-      --  a remote object.
+      --  A : constant System.Address;
 
-      Remote_Statements := New_List (
+      Proxy_Object_Addr := Make_Defining_Identifier (Loc, Name_uA);
 
-        Pack_Node_Into_Stream_Access (Loc,
-         Stream => Stream_Parameter,
-         Object =>
-            Make_Selected_Component (Loc,
-              Prefix        => Unchecked_Convert_To (Stub_Type_Access,
-                Object),
-              Selector_Name =>
-                Make_Identifier (Loc, Name_Origin)),
-         Etyp   => RTE (RE_Partition_ID)),
+      Append_To (Vis_Decls,
+        Make_Object_Declaration (Loc,
+          Defining_Identifier => Proxy_Object_Addr,
+          Constant_Present    => True,
+          Object_Definition   => New_Occurrence_Of (RTE (RE_Address), Loc)));
 
-        Pack_Node_Into_Stream_Access (Loc,
-         Stream => Stream_Parameter,
-         Object =>
-            Make_Selected_Component (Loc,
-              Prefix        => Unchecked_Convert_To (Stub_Type_Access,
-                Object),
-              Selector_Name =>
-                Make_Identifier (Loc, Name_Receiver)),
-         Etyp   => RTE (RE_Unsigned_64)),
+      --  private
 
-        Pack_Node_Into_Stream_Access (Loc,
-         Stream => Stream_Parameter,
-         Object =>
-            Make_Selected_Component (Loc,
-              Prefix        => Unchecked_Convert_To (Stub_Type_Access,
-                Object),
-              Selector_Name =>
-                Make_Identifier (Loc, Name_Addr)),
-         Etyp   => RTE (RE_Unsigned_64)));
+      --  type subpP is tagged limited record
+      --     All_Calls_Remote : Boolean := [All_Calls_Remote?];
+      --     ...
+      --  end record;
 
-      --  Build the code fragment corresponding to the marshalling of a null
-      --  object.
+      Append_To (Pvt_Decls,
+        Make_Full_Type_Declaration (Loc,
+          Defining_Identifier => Proxy_Type_Full_View,
+          Type_Definition     =>
+            Build_Remote_Subprogram_Proxy_Type (Loc,
+              New_Occurrence_Of (All_Calls_Remote_E, Loc))));
+
+      --  Trick semantic analysis into swapping the public and full view when
+      --  freezing the public view.
+
+      Set_Comes_From_Source (Proxy_Type_Full_View, True);
+
+      --  procedure Call
+      --    (Self : access O;
+      --     ...other-formals...) is
+      --  begin
+      --    P (...other-formals...);
+      --  end Call;
+
+      --  function Call
+      --    (Self : access O;
+      --     ...other-formals...)
+      --     return T is
+      --  begin
+      --    return F (...other-formals...);
+      --  end Call;
+
+      if Nkind (Subp_Decl_Spec) = N_Procedure_Specification then
+         Perform_Call :=
+           Make_Procedure_Call_Statement (Loc,
+             Name                   => New_Occurrence_Of (Subp_Name, Loc),
+             Parameter_Associations => Actuals);
+      else
+         Perform_Call :=
+           Make_Simple_Return_Statement (Loc,
+             Expression =>
+               Make_Function_Call (Loc,
+                 Name                   => New_Occurrence_Of (Subp_Name, Loc),
+                 Parameter_Associations => Actuals));
+      end if;
 
-      Null_Statements := New_List (
+      Formal := First (Parameter_Specifications (Subp_Decl_Spec));
+      pragma Assert (Present (Formal));
+      loop
+         Next (Formal);
+         exit when No (Formal);
+         Append_To (Actuals,
+           New_Occurrence_Of (Defining_Identifier (Formal), Loc));
+      end loop;
 
-        Pack_Entity_Into_Stream_Access (Loc,
-          Stream => Stream_Parameter,
-          Object => RTE (RE_Get_Local_Partition_Id)),
+      --  O : aliased subpP;
 
-        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)),
+      Append_To (Pvt_Decls,
+        Make_Object_Declaration (Loc,
+          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO),
+          Aliased_Present     => True,
+          Object_Definition   => New_Occurrence_Of (Proxy_Type, Loc)));
 
-        Pack_Node_Into_Stream_Access (Loc,
-          Stream => Stream_Parameter,
-          Object => Make_Integer_Literal (Loc, Uint_0),
-          Etyp   => RTE (RE_Unsigned_64)));
+      --  A : constant System.Address := O'Address;
 
-      Statements := New_List (
-        Make_Implicit_If_Statement (RACW_Type,
-          Condition       =>
-            Make_Op_Eq (Loc,
-              Left_Opnd  => Object,
-              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         => Object,
-                      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));
-
-      Build_Stream_Procedure
-        (Loc, RACW_Type, Body_Node,
-         Make_Defining_Identifier (Loc, Procedure_Name),
-         Statements, Outp => False);
-
-      Proc_Decl := Make_Subprogram_Declaration (Loc,
-        Copy_Specification (Loc, Specification (Body_Node)));
-
-      Attr_Decl :=
-        Make_Attribute_Definition_Clause (Loc,
-          Name       => New_Occurrence_Of (RACW_Type, Loc),
-          Chars      => Name_Write,
+      Append_To (Pvt_Decls,
+        Make_Object_Declaration (Loc,
+          Defining_Identifier =>
+            Make_Defining_Identifier (Loc, Chars (Proxy_Object_Addr)),
+          Constant_Present    => True,
+          Object_Definition   => New_Occurrence_Of (RTE (RE_Address), Loc),
           Expression =>
-            New_Occurrence_Of (
-              Defining_Unit_Name (Specification (Proc_Decl)), Loc));
-
-      Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
-      Insert_After (Proc_Decl, Attr_Decl);
-      Append_To (Declarations, Body_Node);
-   end Add_RACW_Write_Attribute;
+            Make_Attribute_Reference (Loc,
+              Prefix => New_Occurrence_Of (
+                Defining_Identifier (Last (Pvt_Decls)), Loc),
+              Attribute_Name => Name_Address)));
 
-   ------------------------------
-   -- Add_RAS_Access_Attribute --
-   ------------------------------
+      Append_To (Decls,
+        Make_Package_Declaration (Loc,
+          Specification => Make_Package_Specification (Loc,
+            Defining_Unit_Name   => Pkg_Name,
+            Visible_Declarations => Vis_Decls,
+            Private_Declarations => Pvt_Decls,
+            End_Label            => Empty)));
+      Analyze (Last (Decls));
 
-   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         : Node_Id;
-      Local_Addr   : Entity_Id;
-      Package_Name : Entity_Id;
-      Subp_Id      : Entity_Id;
-      Asynch_P     : Entity_Id;
-      Origin       : Entity_Id;
-      Return_Value : Entity_Id;
-
-      All_Calls_Remote : Entity_Id;
-      --  True if an All_Calls_Remote pragma applies to the RCI unit
-      --  that contains the subprogram (currently unused, all RAS
-      --  dereferences are handled through the PCS).
+      Append_To (Decls,
+        Make_Package_Body (Loc,
+          Defining_Unit_Name =>
+            Make_Defining_Identifier (Loc, Chars (Pkg_Name)),
+          Declarations => New_List (
+            Make_Subprogram_Body (Loc,
+              Specification  => Subp_Body_Spec,
+              Declarations   => New_List,
+              Handled_Statement_Sequence =>
+                Make_Handled_Sequence_Of_Statements (Loc,
+                  Statements => New_List (Perform_Call))))));
+      Analyze (Last (Decls));
+   end Add_RAS_Proxy_And_Analyze;
 
-      Loc : constant Source_Ptr := Sloc (N);
+   -----------------------
+   -- Add_RAST_Features --
+   -----------------------
 
-      function Set_Field
-        (Field_Name : Name_Id;
-         Value      : Node_Id) return Node_Id;
-      --  Construct an assignment that sets the named component in the
-      --  returned record
+   procedure Add_RAST_Features (Vis_Decl : Node_Id) is
+      RAS_Type : constant Entity_Id :=
+                   Equivalent_Type (Defining_Identifier (Vis_Decl));
+   begin
+      pragma Assert (No (TSS (RAS_Type, TSS_RAS_Access)));
+      Add_RAS_Dereference_TSS (Vis_Decl);
+      Specific_Add_RAST_Features (Vis_Decl, RAS_Type);
+   end Add_RAST_Features;
 
-      ---------------
-      -- Set_Field --
-      ---------------
+   -------------------
+   -- Add_Stub_Type --
+   -------------------
 
-      function Set_Field
-        (Field_Name : Name_Id;
-         Value      : Node_Id) return Node_Id
-      is
-      begin
-         return
-           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;
+   procedure Add_Stub_Type
+     (Designated_Type   : Entity_Id;
+      RACW_Type         : Entity_Id;
+      Decls             : List_Id;
+      Stub_Type         : out Entity_Id;
+      Stub_Type_Access  : out Entity_Id;
+      RPC_Receiver_Decl : out Node_Id;
+      Body_Decls        : out List_Id;
+      Existing          : out Boolean)
+   is
+      Loc : constant Source_Ptr := Sloc (RACW_Type);
 
-   --  Start of processing for Add_RAS_Access_Attribute
+      Stub_Elements : constant Stub_Structure :=
+                        Stubs_Table.Get (Designated_Type);
+      Stub_Type_Decl        : Node_Id;
+      Stub_Type_Access_Decl : Node_Id;
 
    begin
-      Local_Addr   := Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
-      Package_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
-      Subp_Id      := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
-      Asynch_P     := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
-      Origin       := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
-      Return_Value := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
-      All_Calls_Remote :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-
-      --  Create the object which will be returned of type Fat_Type
+      if Stub_Elements /= Empty_Stub_Structure then
+         Stub_Type           := Stub_Elements.Stub_Type;
+         Stub_Type_Access    := Stub_Elements.Stub_Type_Access;
+         RPC_Receiver_Decl   := Stub_Elements.RPC_Receiver_Decl;
+         Body_Decls          := Stub_Elements.Body_Decls;
+         Existing            := True;
+         return;
+      end if;
 
-      Append_List_To (Proc_Decls, New_List (
+      Existing := False;
+      Stub_Type :=
+        Make_Defining_Identifier (Loc,
+          Chars => New_Internal_Name ('S'));
+      Set_Ekind (Stub_Type, E_Record_Type);
+      Set_Is_RACW_Stub_Type (Stub_Type);
+      Stub_Type_Access :=
+        Make_Defining_Identifier (Loc,
+          Chars => New_External_Name
+                     (Related_Id => Chars (Stub_Type), Suffix => 'A'));
 
-        Make_Object_Declaration (Loc,
-          Defining_Identifier => Origin,
-          Constant_Present    => True,
-          Object_Definition   =>
-            New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
-          Expression          =>
-            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)))),
+      Specific_Build_Stub_Type
+        (RACW_Type, Stub_Type,
+         Stub_Type_Decl, RPC_Receiver_Decl);
 
-        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
-
-      Append_List_To (Proc_Statements, New_List (
-        Make_Implicit_If_Statement (N,
-          Condition =>
-            Make_And_Then (Loc,
-              Left_Opnd =>
-                Make_Op_Not (Loc,
-                  New_Occurrence_Of (All_Calls_Remote, Loc)),
-              Right_Opnd =>
-                Make_Op_Eq (Loc,
-                  Left_Opnd =>
-                    New_Occurrence_Of (Origin, Loc),
-                  Right_Opnd =>
-                    Make_Function_Call (Loc,
-                      New_Occurrence_Of (
-                        RTE (RE_Get_Local_Partition_Id), Loc)))),
+      Stub_Type_Access_Decl :=
+        Make_Full_Type_Declaration (Loc,
+          Defining_Identifier => Stub_Type_Access,
+          Type_Definition     =>
+            Make_Access_To_Object_Definition (Loc,
+              All_Present        => True,
+              Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
 
-          Then_Statements => New_List (
-            Set_Field (Name_Ras,
-              OK_Convert_To (RTE (RE_Unsigned_64),
-                             New_Occurrence_Of (Local_Addr, Loc)))),
+      Append_To (Decls, Stub_Type_Decl);
+      Analyze (Last (Decls));
+      Append_To (Decls, Stub_Type_Access_Decl);
+      Analyze (Last (Decls));
 
-          Else_Statements => New_List (
-            Set_Field (Name_Ras,
-              Make_Integer_Literal (Loc, Uint_0)))),
+      --  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.
 
-        Set_Field (Name_Origin,
-          Unchecked_Convert_To (Standard_Integer,
-            New_Occurrence_Of (Origin, Loc))),
+      Derive_Subprograms (Parent_Type  => Designated_Type,
+                          Derived_Type => Stub_Type);
 
-        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)))),
+      if Present (RPC_Receiver_Decl) then
+         Append_To (Decls, RPC_Receiver_Decl);
+      else
+         RPC_Receiver_Decl := Last (Decls);
+      end if;
 
-        Set_Field (Name_Subp_Id,
-          New_Occurrence_Of (Subp_Id, Loc)),
+      Body_Decls := New_List;
 
-        Set_Field (Name_Async,
-          New_Occurrence_Of (Asynch_P, Loc))));
+      Stubs_Table.Set (Designated_Type,
+        (Stub_Type           => Stub_Type,
+         Stub_Type_Access    => Stub_Type_Access,
+         RPC_Receiver_Decl   => RPC_Receiver_Decl,
+         Body_Decls          => Body_Decls,
+         RACW_Type           => RACW_Type));
+   end Add_Stub_Type;
 
-      --  Return the newly created value
+   ------------------------
+   -- Append_RACW_Bodies --
+   ------------------------
 
-      Append_To (Proc_Statements,
-        Make_Return_Statement (Loc,
-          Expression =>
-            New_Occurrence_Of (Return_Value, Loc)));
+   procedure Append_RACW_Bodies (Decls : List_Id; Spec_Id : Entity_Id) is
+      E : Entity_Id;
+   begin
+      E := First_Entity (Spec_Id);
+      while Present (E) loop
+         if Is_Remote_Access_To_Class_Wide_Type (E) then
+            Append_List_To (Decls, Get_And_Reset_RACW_Bodies (E));
+         end if;
 
-      Proc :=
-        Make_Defining_Identifier (Loc,
-          Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
+         Next_Entity (E);
+      end loop;
+   end Append_RACW_Bodies;
 
-      Proc_Spec :=
-        Make_Function_Specification (Loc,
-          Defining_Unit_Name       => Proc,
-          Parameter_Specifications => New_List (
-            Make_Parameter_Specification (Loc,
-              Defining_Identifier => Local_Addr,
-              Parameter_Type      =>
-                New_Occurrence_Of (RTE (RE_Address), Loc)),
+   ----------------------------------
+   -- Assign_Subprogram_Identifier --
+   ----------------------------------
 
-            Make_Parameter_Specification (Loc,
-              Defining_Identifier => Package_Name,
-              Parameter_Type      =>
-                New_Occurrence_Of (Standard_String, Loc)),
+   procedure Assign_Subprogram_Identifier
+     (Def : Entity_Id;
+      Spn : Int;
+      Id  : out String_Id)
+   is
+      N : constant Name_Id := Chars (Def);
 
-            Make_Parameter_Specification (Loc,
-              Defining_Identifier => Subp_Id,
-              Parameter_Type      =>
-                New_Occurrence_Of (Standard_Natural, Loc)),
+      Overload_Order : constant Int :=
+                         Overload_Counter_Table.Get (N) + 1;
 
-            Make_Parameter_Specification (Loc,
-              Defining_Identifier => Asynch_P,
-              Parameter_Type      =>
-                New_Occurrence_Of (Standard_Boolean, Loc)),
+   begin
+      Overload_Counter_Table.Set (N, Overload_Order);
 
-            Make_Parameter_Specification (Loc,
-              Defining_Identifier => All_Calls_Remote,
-              Parameter_Type      =>
-                New_Occurrence_Of (Standard_Boolean, Loc))),
+      Get_Name_String (N);
 
-         Subtype_Mark =>
-           New_Occurrence_Of (Fat_Type, Loc));
+      --  Homonym handling: as in Exp_Dbug, but much simpler,
+      --  because the only entities for which we have to generate
+      --  names here need only to be disambiguated within their
+      --  own scope.
 
-      --  Set the kind and return type of the function to prevent ambiguities
-      --  between Ras_Type and Fat_Type in subsequent analysis.
+      if Overload_Order > 1 then
+         Name_Buffer (Name_Len + 1 .. Name_Len + 2) := "__";
+         Name_Len := Name_Len + 2;
+         Add_Nat_To_Name_Buffer (Overload_Order);
+      end if;
 
-      Set_Ekind (Proc, E_Function);
-      Set_Etype (Proc, New_Occurrence_Of (Fat_Type, Loc));
+      Id := String_From_Name_Buffer;
+      Subprogram_Identifier_Table.Set (Def,
+        Subprogram_Identifiers'(Str_Identifier => Id, Int_Identifier => Spn));
+   end Assign_Subprogram_Identifier;
+
+   -------------------------------------
+   -- Build_Actual_Object_Declaration --
+   -------------------------------------
+
+   procedure Build_Actual_Object_Declaration
+     (Object   : Entity_Id;
+      Etyp     : Entity_Id;
+      Variable : Boolean;
+      Expr     : Node_Id;
+      Decls    : List_Id)
+   is
+      Loc : constant Source_Ptr := Sloc (Object);
+   begin
+      --  Declare a temporary object for the actual, possibly initialized with
+      --  a 'Input/From_Any call.
 
-      Discard_Node (
-        Make_Subprogram_Body (Loc,
-          Specification              => Proc_Spec,
-          Declarations               => Proc_Decls,
-          Handled_Statement_Sequence =>
-            Make_Handled_Sequence_Of_Statements (Loc,
-              Statements => Proc_Statements)));
+      --  Complication arises in the case of limited types, for which such a
+      --  declaration is illegal in Ada 95. In that case, we first generate a
+      --  renaming declaration of the 'Input call, and then if needed we
+      --  generate an overlaid non-constant view.
 
-      Set_TSS (Fat_Type, Proc);
+      if Ada_Version <= Ada_95
+        and then Is_Limited_Type (Etyp)
+        and then Present (Expr)
+      then
 
-   end Add_RAS_Access_Attribute;
+         --  Object : Etyp renames <func-call>
 
-   -----------------------------------
-   -- Add_RAS_Dereference_Attribute --
-   -----------------------------------
+         Append_To (Decls,
+           Make_Object_Renaming_Declaration (Loc,
+             Defining_Identifier => Object,
+             Subtype_Mark        => New_Occurrence_Of (Etyp, Loc),
+             Name                => Expr));
 
-   procedure Add_RAS_Dereference_Attribute (N : in Node_Id) is
-      Loc : constant Source_Ptr := Sloc (N);
+         if Variable then
 
-      Type_Def : constant Node_Id   := Type_Definition (N);
+            --  The name defined by the renaming declaration denotes a
+            --  constant view; create a non-constant object at the same address
+            --  to be used as the actual.
 
-      Ras_Type : constant Entity_Id := Defining_Identifier (N);
+            declare
+               Constant_Object : constant Entity_Id :=
+                                   Make_Defining_Identifier (Loc,
+                                     New_Internal_Name ('P'));
+            begin
+               Set_Defining_Identifier
+                 (Last (Decls), Constant_Object);
 
-      Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
+               --  We have an unconstrained Etyp: build the actual constrained
+               --  subtype for the value we just read from the stream.
 
-      Proc_Decls      : constant List_Id := New_List;
-      Proc_Statements : constant List_Id := New_List;
+               --  subtype S is <actual subtype of Constant_Object>;
 
-      Inner_Decls      : constant List_Id := New_List;
-      Inner_Statements : constant List_Id := New_List;
+               Append_To (Decls,
+                 Build_Actual_Subtype (Etyp,
+                   New_Occurrence_Of (Constant_Object, Loc)));
 
-      Direct_Statements : constant List_Id := New_List;
+               --  Object : S;
 
-      Proc        : Node_Id;
-      Proc_Spec   : Node_Id;
-      Param_Specs : constant List_Id := New_List;
-      Param_Assoc : constant List_Id := New_List;
+               Append_To (Decls,
+                 Make_Object_Declaration (Loc,
+                   Defining_Identifier => Object,
+                   Object_Definition   =>
+                     New_Occurrence_Of
+                       (Defining_Identifier (Last (Decls)), Loc)));
+               Set_Ekind (Object, E_Variable);
 
-      Pointer : Node_Id;
+               --  Suppress default initialization:
+               --  pragma Import (Ada, Object);
 
-      Converted_Ras    : Node_Id;
-      Target_Partition : Node_Id;
-      RPC_Receiver     : Node_Id;
-      Subprogram_Id    : Node_Id;
-      Asynchronous     : Node_Id;
+               Append_To (Decls,
+                 Make_Pragma (Loc,
+                   Chars => Name_Import,
+                   Pragma_Argument_Associations => New_List (
+                     Make_Pragma_Argument_Association (Loc,
+                       Chars      => Name_Convention,
+                       Expression => Make_Identifier (Loc, Name_Ada)),
+                     Make_Pragma_Argument_Association (Loc,
+                       Chars      => Name_Entity,
+                       Expression => New_Occurrence_Of (Object, Loc)))));
+
+               --  for Object'Address use Constant_Object'Address;
 
-      Is_Function : constant Boolean :=
-                      Nkind (Type_Def) = N_Access_Function_Definition;
+               Append_To (Decls,
+                 Make_Attribute_Definition_Clause (Loc,
+                   Name       => New_Occurrence_Of (Object, Loc),
+                   Chars      => Name_Address,
+                   Expression =>
+                     Make_Attribute_Reference (Loc,
+                       Prefix => New_Occurrence_Of (Constant_Object, Loc),
+                       Attribute_Name => Name_Address)));
+            end;
+         end if;
 
-      Spec : constant Node_Id := Type_Def;
+      else
 
-      Current_Parameter : Node_Id;
+         --  General case of a regular object declaration. Object is flagged
+         --  constant unless it has mode out or in out, to allow the backend
+         --  to optimize where possible.
 
-   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.
+         --  Object : [constant] Etyp [:= <expr>];
 
-      Pointer :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         Append_To (Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Object,
+             Constant_Present    => Present (Expr) and then not Variable,
+             Object_Definition   => New_Occurrence_Of (Etyp, Loc),
+             Expression          => Expr));
+
+         if Constant_Present (Last (Decls)) then
+            Set_Ekind (Object, E_Constant);
+         else
+            Set_Ekind (Object, E_Variable);
+         end if;
+      end if;
+   end Build_Actual_Object_Declaration;
+
+   ------------------------------
+   -- Build_Get_Unique_RP_Call --
+   ------------------------------
+
+   function Build_Get_Unique_RP_Call
+     (Loc       : Source_Ptr;
+      Pointer   : Entity_Id;
+      Stub_Type : Entity_Id) return List_Id
+   is
+   begin
+      return New_List (
+        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 (Pointer, Loc)))),
+
+        Make_Assignment_Statement (Loc,
+          Name =>
+            Make_Selected_Component (Loc,
+              Prefix => New_Occurrence_Of (Pointer, Loc),
+              Selector_Name =>
+                New_Occurrence_Of (First_Tag_Component
+                  (Designated_Type (Etype (Pointer))), Loc)),
+          Expression =>
+            Make_Attribute_Reference (Loc,
+              Prefix         => New_Occurrence_Of (Stub_Type, Loc),
+              Attribute_Name => Name_Tag)));
+
+      --  Note: The assignment to Pointer._Tag is safe here because
+      --  we carefully ensured that Stub_Type has exactly the same layout
+      --  as System.Partition_Interface.RACW_Stub_Type.
+
+   end Build_Get_Unique_RP_Call;
+
+   -----------------------------------
+   -- 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;
+      Ptyp               : Node_Id;
+
+      First_Parameter : Node_Id;
+      For_RAS         : Boolean := False;
+
+   begin
+      if No (Parameter_Specifications (Spec)) then
+         return New_List;
+      end if;
+
+      Constrained_List   := New_List;
+      Unconstrained_List := New_List;
+      First_Parameter    := First (Parameter_Specifications (Spec));
+
+      if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition
+        and then Chars (Defining_Identifier (First_Parameter)) = Name_uS
+      then
+         For_RAS := True;
+      end if;
+
+      --  Loop through the parameters and add them to the right list. Note that
+      --  we treat a parameter of a null-excluding access type as unconstrained
+      --  because we can't declare an object of such a type with default
+      --  initialization.
+
+      Current_Parameter := First_Parameter;
+      while Present (Current_Parameter) loop
+         Ptyp := Parameter_Type (Current_Parameter);
+
+         if (Nkind (Ptyp) = N_Access_Definition
+               or else not Transmit_As_Unconstrained (Etype (Ptyp)))
+           and then not (For_RAS and then Current_Parameter = First_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;
+      Pkg_Name : String_Id;
+      L        : List_Id;
+      Reg      : Node_Id;
+      Loc      : constant Source_Ptr := Sloc (U);
+
+   begin
+      --  Verify that the implementation supports distribution, by accessing
+      --  a type defined in the proper version of system.rpc
+
+      declare
+         Dist_OK : Entity_Id;
+         pragma Warnings (Off, Dist_OK);
+      begin
+         Dist_OK := RTE (RE_Params_Stream_Type);
+      end;
+
+      --  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;
+
+      Get_Library_Unit_Name_String (Pkg_Spec);
+      Pkg_Name := String_From_Name_Buffer;
+      Reg :=
+        Make_Procedure_Call_Statement (Loc,
+          Name                   =>
+            New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
+          Parameter_Associations => New_List (
+            Make_String_Literal (Loc, Pkg_Name),
+            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_RPC_Receiver_Specification --
+   --------------------------------------
+
+   function Build_RPC_Receiver_Specification
+     (RPC_Receiver      : Entity_Id;
+      Request_Parameter : Entity_Id) return Node_Id
+   is
+      Loc : constant Source_Ptr := Sloc (RPC_Receiver);
+   begin
+      return
+        Make_Procedure_Specification (Loc,
+          Defining_Unit_Name       => RPC_Receiver,
+          Parameter_Specifications => New_List (
+            Make_Parameter_Specification (Loc,
+              Defining_Identifier => Request_Parameter,
+              Parameter_Type      =>
+                New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
+   end Build_RPC_Receiver_Specification;
+
+   ----------------------------------------
+   -- Build_Remote_Subprogram_Proxy_Type --
+   ----------------------------------------
+
+   function Build_Remote_Subprogram_Proxy_Type
+     (Loc            : Source_Ptr;
+      ACR_Expression : Node_Id) return Node_Id
+   is
+   begin
+      return
+        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_All_Calls_Remote),
+                  Component_Definition =>
+                    Make_Component_Definition (Loc,
+                      Subtype_Indication =>
+                        New_Occurrence_Of (Standard_Boolean, Loc)),
+                  Expression =>
+                    ACR_Expression),
+
+                Make_Component_Declaration (Loc,
+                  Defining_Identifier =>
+                    Make_Defining_Identifier (Loc,
+                      Name_Receiver),
+                  Component_Definition =>
+                    Make_Component_Definition (Loc,
+                      Subtype_Indication =>
+                        New_Occurrence_Of (RTE (RE_Address), Loc)),
+                  Expression =>
+                    New_Occurrence_Of (RTE (RE_Null_Address), Loc)),
+
+                Make_Component_Declaration (Loc,
+                  Defining_Identifier =>
+                    Make_Defining_Identifier (Loc,
+                      Name_Subp_Id),
+                  Component_Definition =>
+                    Make_Component_Definition (Loc,
+                      Subtype_Indication =>
+                        New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))))));
+   end Build_Remote_Subprogram_Proxy_Type;
+
+   --------------------
+   -- Build_Stub_Tag --
+   --------------------
+
+   function Build_Stub_Tag
+     (Loc       : Source_Ptr;
+      RACW_Type : Entity_Id) return Node_Id
+   is
+      Stub_Type : constant Entity_Id := Corresponding_Stub_Type (RACW_Type);
+   begin
+      return
+        Make_Attribute_Reference (Loc,
+          Prefix         => New_Occurrence_Of (Stub_Type, Loc),
+          Attribute_Name => Name_Tag);
+   end Build_Stub_Tag;
+
+   ------------------------------------
+   -- Build_Subprogram_Calling_Stubs --
+   ------------------------------------
+
+   function Build_Subprogram_Calling_Stubs
+     (Vis_Decl                 : Node_Id;
+      Subp_Id                  : Node_Id;
+      Asynchronous             : Boolean;
+      Dynamically_Asynchronous : Boolean   := False;
+      Stub_Type                : Entity_Id := Empty;
+      RACW_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);
+
+      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;
+
+      Asynchronous_Expr : Node_Id := Empty;
+
+      RCI_Locator : Entity_Id;
+
+      Spec_To_Use : Node_Id;
+
+      procedure Insert_Partition_Check (Parameter : 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 : Node_Id) is
+         Parameter_Entity : constant Entity_Id :=
+                              Defining_Identifier (Parameter);
+      begin
+         --  The expression that will be built is of the form:
+
+         --    if not Same_Partition (Parameter, Controlling_Parameter) then
+         --      raise Constraint_Error;
+         --    end if;
+
+         --  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).
+
+         Append_To (Decls,
+           Make_Raise_Constraint_Error (Loc,
+             Condition       =>
+               Make_Op_Not (Loc,
+                 Right_Opnd =>
+                   Make_Function_Call (Loc,
+                     Name =>
+                       New_Occurrence_Of (RTE (RE_Same_Partition), Loc),
+                     Parameter_Associations =>
+                       New_List (
+                         Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
+                           New_Occurrence_Of (Parameter_Entity, Loc)),
+                         Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
+                           New_Occurrence_Of (Controlling_Parameter, Loc))))),
+             Reason => CE_Partition_Check_Failed));
+      end Insert_Partition_Check;
+
+   --  Start of processing for Build_Subprogram_Calling_Stubs
+
+   begin
+      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 Present (Stub_Type)
+         and then Present (Parameter_Specifications (Spec_To_Use))
+      then
+         declare
+            Current_Parameter : Node_Id :=
+                                  First (Parameter_Specifications
+                                           (Spec_To_Use));
+         begin
+            while Present (Current_Parameter) 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;
+
+      pragma Assert (No (Stub_Type) or else Present (Controlling_Parameter));
+
+      if Dynamically_Asynchronous then
+         Asynchronous_Expr := Make_Selected_Component (Loc,
+                                Prefix        => Controlling_Parameter,
+                                Selector_Name => Name_Asynchronous);
+      end if;
+
+      Specific_Build_General_Calling_Stubs
+        (Decls                 => Decls,
+         Statements            => Statements,
+         Target                => Specific_Build_Stub_Target (Loc,
+                                    Decls, RCI_Locator, Controlling_Parameter),
+         Subprogram_Id         => 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,
+         Stub_Type             => Stub_Type,
+         RACW_Type             => RACW_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_Id --
+   -------------------------
+
+   function Build_Subprogram_Id
+     (Loc : Source_Ptr;
+      E   : Entity_Id) return Node_Id
+   is
+   begin
+      if Get_Subprogram_Ids (E).Str_Identifier = No_String then
+         declare
+            Current_Declaration : Node_Id;
+            Current_Subp        : Entity_Id;
+            Current_Subp_Str    : String_Id;
+            Current_Subp_Number : Int := First_RCI_Subprogram_Id;
+
+            pragma Warnings (Off, Current_Subp_Str);
+
+         begin
+            --  Build_Subprogram_Id is called outside of the context of
+            --  generating calling or receiving stubs. Hence we are processing
+            --  an 'Access attribute_reference for an RCI subprogram, for the
+            --  purpose of obtaining a RAS value.
+
+            pragma Assert
+              (Is_Remote_Call_Interface (Scope (E))
+                 and then
+                  (Nkind (Parent (E)) = N_Procedure_Specification
+                     or else
+                   Nkind (Parent (E)) = N_Function_Specification));
+
+            Current_Declaration :=
+              First (Visible_Declarations
+                (Package_Specification_Of_Scope (Scope (E))));
+            while Present (Current_Declaration) loop
+               if Nkind (Current_Declaration) = N_Subprogram_Declaration
+                 and then Comes_From_Source (Current_Declaration)
+               then
+                  Current_Subp := Defining_Unit_Name (Specification (
+                    Current_Declaration));
+
+                  Assign_Subprogram_Identifier
+                    (Current_Subp, Current_Subp_Number, Current_Subp_Str);
+
+                  Current_Subp_Number := Current_Subp_Number + 1;
+               end if;
+
+               Next (Current_Declaration);
+            end loop;
+         end;
+      end if;
+
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            return Make_String_Literal (Loc, Get_Subprogram_Id (E));
+         when others =>
+            return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
+      end case;
+   end Build_Subprogram_Id;
+
+   ------------------------
+   -- Copy_Specification --
+   ------------------------
+
+   function Copy_Specification
+     (Loc         : Source_Ptr;
+      Spec        : Node_Id;
+      Ctrl_Type   : Entity_Id := Empty;
+      New_Name    : Name_Id   := No_Name) return Node_Id
+   is
+      Parameters : List_Id := No_List;
+
+      Current_Parameter  : Node_Id;
+      Current_Identifier : Entity_Id;
+      Current_Type       : Node_Id;
+
+      Name_For_New_Spec : Name_Id;
+
+      New_Identifier : Entity_Id;
+
+   --  Comments needed in body below ???
+
+   begin
+      if New_Name = No_Name then
+         pragma Assert (Nkind (Spec) = N_Function_Specification
+                or else Nkind (Spec) = N_Procedure_Specification);
+
+         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 Present (Current_Parameter) loop
+            Current_Identifier := Defining_Identifier (Current_Parameter);
+            Current_Type       := Parameter_Type (Current_Parameter);
+
+            if Nkind (Current_Type) = N_Access_Definition then
+               if Present (Ctrl_Type) then
+                  pragma Assert (Is_Controlling_Formal (Current_Identifier));
+                  Current_Type :=
+                    Make_Access_Definition (Loc,
+                      Subtype_Mark => New_Occurrence_Of (Ctrl_Type, Loc),
+                      Null_Exclusion_Present =>
+                        Null_Exclusion_Present (Current_Type));
+
+               else
+                  Current_Type :=
+                    Make_Access_Definition (Loc,
+                      Subtype_Mark =>
+                        New_Copy_Tree (Subtype_Mark (Current_Type)),
+                      Null_Exclusion_Present =>
+                        Null_Exclusion_Present (Current_Type));
+               end if;
+
+            else
+               if Present (Ctrl_Type)
+                 and then Is_Controlling_Formal (Current_Identifier)
+               then
+                  Current_Type := New_Occurrence_Of (Ctrl_Type, Loc);
+               else
+                  Current_Type := New_Copy_Tree (Current_Type);
+               end if;
+            end if;
+
+            New_Identifier := Make_Defining_Identifier (Loc,
+              Chars (Current_Identifier));
+
+            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))));
+
+            --  For a regular formal parameter (that needs to be marshalled
+            --  in the context of remote calls), set the Etype now, because
+            --  marshalling processing might need it.
+
+            if Is_Entity_Name (Current_Type) then
+               Set_Etype (New_Identifier, Entity (Current_Type));
+
+            --  Current_Type is an access definition, special processing
+            --  (not requiring etype) will occur for marshalling.
+
+            else
+               null;
+            end if;
+
+            Next (Current_Parameter);
+         end loop;
+      end if;
+
+      case Nkind (Spec) is
+
+         when N_Function_Specification | N_Access_Function_Definition =>
+            return
+              Make_Function_Specification (Loc,
+                Defining_Unit_Name       =>
+                  Make_Defining_Identifier (Loc,
+                    Chars => Name_For_New_Spec),
+                Parameter_Specifications => Parameters,
+                Result_Definition        =>
+                  New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
+
+         when N_Procedure_Specification | N_Access_Procedure_Definition =>
+            return
+              Make_Procedure_Specification (Loc,
+                Defining_Unit_Name       =>
+                  Make_Defining_Identifier (Loc,
+                    Chars => Name_For_New_Spec),
+                Parameter_Specifications => Parameters);
+
+         when others =>
+            raise Program_Error;
+      end case;
+   end Copy_Specification;
+
+   -----------------------------
+   -- Corresponding_Stub_Type --
+   -----------------------------
+
+   function Corresponding_Stub_Type (RACW_Type : Entity_Id) return Entity_Id is
+      Desig         : constant Entity_Id      :=
+                        Etype (Designated_Type (RACW_Type));
+      Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
+   begin
+      return Stub_Elements.Stub_Type;
+   end Corresponding_Stub_Type;
+
+   ---------------------------
+   -- 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 Present (Current_Parameter) loop
+            if Out_Present (Current_Parameter) then
+               return False;
+            end if;
+
+            Next (Current_Parameter);
+         end loop;
+      end if;
+
+      return True;
+   end Could_Be_Asynchronous;
+
+   ---------------------------
+   -- Declare_Create_NVList --
+   ---------------------------
+
+   procedure Declare_Create_NVList
+     (Loc    : Source_Ptr;
+      NVList : Entity_Id;
+      Decls  : List_Id;
+      Stmts  : List_Id)
+   is
+   begin
+      Append_To (Decls,
+        Make_Object_Declaration (Loc,
+          Defining_Identifier => NVList,
+          Aliased_Present     => False,
+          Object_Definition   =>
+              New_Occurrence_Of (RTE (RE_NVList_Ref), Loc)));
+
+      Append_To (Stmts,
+        Make_Procedure_Call_Statement (Loc,
+          Name => New_Occurrence_Of (RTE (RE_NVList_Create), Loc),
+          Parameter_Associations => New_List (
+            New_Occurrence_Of (NVList, Loc))));
+   end Declare_Create_NVList;
+
+   ---------------------------------------------
+   -- Expand_All_Calls_Remote_Subprogram_Call --
+   ---------------------------------------------
+
+   procedure Expand_All_Calls_Remote_Subprogram_Call (N : 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 : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
+
+            begin
+               if Ekind (Scop) = E_Package_Body then
+                  Push_Scope (Spec_Entity (Scop));
+
+               elsif Ekind (Scop) = E_Subprogram_Body then
+                  Push_Scope
+                     (Corresponding_Spec (Unit_Declaration_Node (Scop)));
+
+               else
+                  Push_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                =>
+              Build_Subprogram_Id (Loc, 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 : Node_Id) is
+      Spec  : constant Node_Id := Specification (Unit_Node);
+      Decls : constant List_Id := Visible_Declarations (Spec);
+   begin
+      Push_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 : Node_Id) is
+      Spec        : Node_Id;
+      Decls       : List_Id;
+      Stubs_Decls : List_Id;
+      Stubs_Stmts : List_Id;
+
+   begin
+      if Nkind (Unit_Node) = N_Package_Declaration then
+         Spec  := Specification (Unit_Node);
+         Decls := Private_Declarations (Spec);
+
+         if No (Decls) then
+            Decls := Visible_Declarations (Spec);
+         end if;
+
+         Push_Scope (Scope_Of_Spec (Spec));
+         Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls, Decls);
+
+      else
+         Spec :=
+           Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
+         Decls := Declarations (Unit_Node);
+
+         Push_Scope (Scope_Of_Spec (Unit_Node));
+         Stubs_Decls := New_List;
+         Stubs_Stmts := New_List;
+         Specific_Add_Receiving_Stubs_To_Declarations
+           (Spec, Stubs_Decls, Stubs_Stmts);
+
+         Insert_List_Before (First (Decls), Stubs_Decls);
+
+         declare
+            HSS_Stmts : constant List_Id :=
+                          Statements (Handled_Statement_Sequence (Unit_Node));
+
+            First_HSS_Stmt : constant Node_Id := First (HSS_Stmts);
+
+         begin
+            if No (First_HSS_Stmt) then
+               Append_List_To (HSS_Stmts, Stubs_Stmts);
+            else
+               Insert_List_Before (First_HSS_Stmt, Stubs_Stmts);
+            end if;
+         end;
+      end if;
+
+      Pop_Scope;
+   end Expand_Receiving_Stubs_Bodies;
+
+   --------------------
+   -- GARLIC_Support --
+   --------------------
+
+   package body GARLIC_Support is
+
+      --  Local subprograms
+
+      procedure Add_RACW_Read_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         Body_Decls       : List_Id);
+      --  Add Read attribute for the RACW type. The declaration and attribute
+      --  definition clauses are inserted right after the declaration of
+      --  RACW_Type. If Body_Decls is not No_List, the subprogram body is
+      --  appended to it (case where the RACW declaration is in the main unit).
+
+      procedure Add_RACW_Write_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         RPC_Receiver     : Node_Id;
+         Body_Decls       : List_Id);
+      --  Same as above for the Write attribute
+
+      function Stream_Parameter return Node_Id;
+      function Result return Node_Id;
+      function Object return Node_Id renames Result;
+      --  Functions to create occurrences of the formal parameter names of the
+      --  'Read and 'Write attributes.
+
+      Loc : Source_Ptr;
+      --  Shared source location used by Add_{Read,Write}_Read_Attribute and
+      --  their ancillary subroutines (set on entry by Add_RACW_Features).
+
+      procedure Add_RAS_Access_TSS (N : Node_Id);
+      --  Add a subprogram body for RAS Access TSS
+
+      -------------------------------------
+      -- Add_Obj_RPC_Receiver_Completion --
+      -------------------------------------
+
+      procedure Add_Obj_RPC_Receiver_Completion
+        (Loc           : Source_Ptr;
+         Decls         : List_Id;
+         RPC_Receiver  : Entity_Id;
+         Stub_Elements : Stub_Structure)
+      is
+      begin
+         --  The RPC receiver body should not be the completion of the
+         --  declaration recorded in the stub structure, because then the
+         --  occurrences of the formal parameters within the body should refer
+         --  to the entities from the declaration, not from the completion, to
+         --  which we do not have easy access. Instead, the RPC receiver body
+         --  acts as its own declaration, and the RPC receiver declaration is
+         --  completed by a renaming-as-body.
+
+         Append_To (Decls,
+           Make_Subprogram_Renaming_Declaration (Loc,
+             Specification =>
+               Copy_Specification (Loc,
+                 Specification (Stub_Elements.RPC_Receiver_Decl)),
+             Name          => New_Occurrence_Of (RPC_Receiver, Loc)));
+      end Add_Obj_RPC_Receiver_Completion;
+
+      -----------------------
+      -- Add_RACW_Features --
+      -----------------------
+
+      procedure Add_RACW_Features
+        (RACW_Type         : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Access  : Entity_Id;
+         RPC_Receiver_Decl : Node_Id;
+         Body_Decls        : List_Id)
+      is
+         RPC_Receiver : Node_Id;
+         Is_RAS       : constant Boolean := not Comes_From_Source (RACW_Type);
+
+      begin
+         Loc := Sloc (RACW_Type);
+
+         if Is_RAS then
+
+            --  For a RAS, the RPC receiver is that of the RCI unit, not that
+            --  of the corresponding distributed object type. We retrieve its
+            --  address from the local proxy object.
+
+            RPC_Receiver := Make_Selected_Component (Loc,
+              Prefix         =>
+                Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object),
+              Selector_Name  => Make_Identifier (Loc, Name_Receiver));
+
+         else
+            RPC_Receiver := Make_Attribute_Reference (Loc,
+              Prefix         => New_Occurrence_Of (
+                Defining_Unit_Name (Specification (RPC_Receiver_Decl)), Loc),
+              Attribute_Name => Name_Address);
+         end if;
+
+         Add_RACW_Write_Attribute
+           (RACW_Type,
+            Stub_Type,
+            Stub_Type_Access,
+            RPC_Receiver,
+            Body_Decls);
+
+         Add_RACW_Read_Attribute
+           (RACW_Type,
+            Stub_Type,
+            Stub_Type_Access,
+            Body_Decls);
+      end Add_RACW_Features;
+
+      -----------------------------
+      -- Add_RACW_Read_Attribute --
+      -----------------------------
+
+      procedure Add_RACW_Read_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         Body_Decls       : List_Id)
+      is
+         Proc_Decl : Node_Id;
+         Attr_Decl : Node_Id;
+
+         Body_Node : Node_Id;
+
+         Statements        : constant List_Id := New_List;
+         Decls             : List_Id;
+         Local_Statements  : List_Id;
+         Remote_Statements : List_Id;
+         --  Various parts of the procedure
+
+         Pnam              : constant Entity_Id :=
+                               Make_Defining_Identifier
+                                 (Loc, New_Internal_Name ('R'));
+         Asynchronous_Flag : constant Entity_Id :=
+                               Asynchronous_Flags_Table.Get (RACW_Type);
+         pragma Assert (Present (Asynchronous_Flag));
+
+         --  Prepare local identifiers
+
+         Source_Partition : Entity_Id;
+         Source_Receiver  : Entity_Id;
+         Source_Address   : Entity_Id;
+         Local_Stub       : Entity_Id;
+         Stubbed_Result   : Entity_Id;
+
+      --  Start of processing for Add_RACW_Read_Attribute
+
+      begin
+         Build_Stream_Procedure (Loc,
+           RACW_Type, Body_Node, Pnam, Statements, Outp => True);
+         Proc_Decl := Make_Subprogram_Declaration (Loc,
+           Copy_Specification (Loc, Specification (Body_Node)));
+
+         Attr_Decl :=
+           Make_Attribute_Definition_Clause (Loc,
+             Name       => New_Occurrence_Of (RACW_Type, Loc),
+             Chars      => Name_Read,
+             Expression =>
+               New_Occurrence_Of (
+                 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
+
+         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
+         Insert_After (Proc_Decl, Attr_Decl);
+
+         if No (Body_Decls) then
+
+            --  Case of processing an RACW type from another unit than the
+            --  main one: do not generate a body.
+
+            return;
+         end if;
+
+         --  Prepare local identifiers
+
+         Source_Partition :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         Source_Receiver  :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+         Source_Address   :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         Local_Stub       :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
+         Stubbed_Result   :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+
+         --  Generate 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 => Local_Stub,
+             Aliased_Present     => True,
+             Object_Definition   => New_Occurrence_Of (Stub_Type, Loc)),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Stubbed_Result,
+             Object_Definition   =>
+               New_Occurrence_Of (Stub_Type_Access, Loc),
+             Expression          =>
+               Make_Attribute_Reference (Loc,
+                 Prefix =>
+                   New_Occurrence_Of (Local_Stub, Loc),
+                 Attribute_Name =>
+                   Name_Unchecked_Access)));
+
+         --  Read the source Partition_ID and RPC_Receiver from incoming stream
+
+         Append_List_To (Statements, New_List (
+           Make_Attribute_Reference (Loc,
+             Prefix         =>
+               New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
+             Attribute_Name => Name_Read,
+             Expressions    => New_List (
+               Stream_Parameter,
+               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 (
+               Stream_Parameter,
+               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 (
+               Stream_Parameter,
+               New_Occurrence_Of (Source_Address, Loc)))));
+
+         --  Build_Get_Unique_RP_Call needs the type of Stubbed_Result
+
+         Set_Etype (Stubbed_Result, Stub_Type_Access);
+
+         --  If the Address is Null_Address, then return a null object, unless
+         --  RACW_Type is null-excluding, in which case unconditionally raise
+         --  CONSTRAINT_ERROR instead.
+
+         declare
+            Zero_Statements : List_Id;
+            --  Statements executed when a zero value is received
+
+         begin
+            if Can_Never_Be_Null (RACW_Type) then
+               Zero_Statements := New_List (
+                 Make_Raise_Constraint_Error (Loc,
+                   Reason => CE_Null_Not_Allowed));
+            else
+               Zero_Statements := New_List (
+                 Make_Assignment_Statement (Loc,
+                   Name       => Result,
+                   Expression => Make_Null (Loc)),
+                 Make_Simple_Return_Statement (Loc));
+            end if;
+
+            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 => Zero_Statements));
+         end;
+
+         --  If the RACW denotes an object created on the current partition,
+         --  Local_Statements will be executed. The real object will be used.
+
+         Local_Statements := New_List (
+           Make_Assignment_Statement (Loc,
+             Name       => Result,
+             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       => Make_Selected_Component (Loc,
+               Prefix        => Stubbed_Result,
+               Selector_Name => Name_Origin),
+             Expression =>
+               New_Occurrence_Of (Source_Partition, Loc)),
+
+           Make_Assignment_Statement (Loc,
+             Name       => Make_Selected_Component (Loc,
+               Prefix        => Stubbed_Result,
+               Selector_Name => Name_Receiver),
+             Expression =>
+               New_Occurrence_Of (Source_Receiver, Loc)),
+
+           Make_Assignment_Statement (Loc,
+             Name       => Make_Selected_Component (Loc,
+               Prefix        => Stubbed_Result,
+               Selector_Name => Name_Addr),
+             Expression =>
+               New_Occurrence_Of (Source_Address, Loc)));
+
+         Append_To (Remote_Statements,
+           Make_Assignment_Statement (Loc,
+             Name       => Make_Selected_Component (Loc,
+               Prefix        => Stubbed_Result,
+               Selector_Name => Name_Asynchronous),
+             Expression =>
+               New_Occurrence_Of (Asynchronous_Flag, Loc)));
+
+         Append_List_To (Remote_Statements,
+           Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
+         --  ??? Issue with asynchronous calls here: the Asynchronous flag is
+         --  set on the stub type if, and only if, the RACW type has a pragma
+         --  Asynchronous. This is incorrect for RACWs that implement RAS
+         --  types, because in that case the /designated subprogram/ (not the
+         --  type) might be asynchronous, and that causes the stub to need to
+         --  be asynchronous too. A solution is to transport a RAS as a struct
+         --  containing a RACW and an asynchronous flag, and to properly alter
+         --  the Asynchronous component in the stub type in the RAS's Input
+         --  TSS.
+
+         Append_To (Remote_Statements,
+           Make_Assignment_Statement (Loc,
+             Name       => Result,
+             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));
+
+         Set_Declarations (Body_Node, Decls);
+         Append_To (Body_Decls, Body_Node);
+      end Add_RACW_Read_Attribute;
+
+      ------------------------------
+      -- Add_RACW_Write_Attribute --
+      ------------------------------
+
+      procedure Add_RACW_Write_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         RPC_Receiver     : Node_Id;
+         Body_Decls       : List_Id)
+      is
+         Body_Node : Node_Id;
+         Proc_Decl : Node_Id;
+         Attr_Decl : Node_Id;
+
+         Statements        : constant List_Id := New_List;
+         Local_Statements  : List_Id;
+         Remote_Statements : List_Id;
+         Null_Statements   : List_Id;
+
+         Pnam : constant Entity_Id :=
+                  Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+
+      begin
+         Build_Stream_Procedure
+           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => False);
+
+         Proc_Decl := Make_Subprogram_Declaration (Loc,
+           Copy_Specification (Loc, Specification (Body_Node)));
+
+         Attr_Decl :=
+           Make_Attribute_Definition_Clause (Loc,
+             Name       => New_Occurrence_Of (RACW_Type, Loc),
+             Chars      => Name_Write,
+             Expression =>
+               New_Occurrence_Of (
+                 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
+
+         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
+         Insert_After (Proc_Decl, Attr_Decl);
+
+         if No (Body_Decls) then
+            return;
+         end if;
+
+         --  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), RPC_Receiver),
+             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 => Object),
+                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, Object),
+                 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, Object),
+                 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, Object),
+                 Selector_Name => Make_Identifier (Loc, Name_Addr)),
+            Etyp   => RTE (RE_Unsigned_64)));
+
+         --  Build code fragment corresponding to 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), RPC_Receiver),
+             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)));
+
+         Append_To (Statements,
+           Make_Implicit_If_Statement (RACW_Type,
+             Condition       =>
+               Make_Op_Eq (Loc,
+                 Left_Opnd  => Object,
+                 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         => Object,
+                         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));
+
+         Append_To (Body_Decls, Body_Node);
+      end Add_RACW_Write_Attribute;
+
+      ------------------------
+      -- Add_RAS_Access_TSS --
+      ------------------------
+
+      procedure Add_RAS_Access_TSS (N : Node_Id) is
+         Loc : constant Source_Ptr := Sloc (N);
+
+         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 is the
+         --  corresponding record type.
+
+         RACW_Type : constant Entity_Id :=
+                       Underlying_RACW_Type (Ras_Type);
+         Desig     : constant Entity_Id :=
+                       Etype (Designated_Type (RACW_Type));
+
+         Stub_Elements : constant Stub_Structure :=
+                           Stubs_Table.Get (Desig);
+         pragma Assert (Stub_Elements /= Empty_Stub_Structure);
+
+         Proc : constant Entity_Id :=
+                  Make_Defining_Identifier (Loc,
+                    Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
+
+         Proc_Spec : Node_Id;
+
+         --  Formal parameters
+
+         Package_Name : constant Entity_Id :=
+                          Make_Defining_Identifier (Loc,
+                            Chars => Name_P);
+         --  Target package
+
+         Subp_Id : constant Entity_Id :=
+                     Make_Defining_Identifier (Loc,
+                       Chars => Name_S);
+         --  Target subprogram
+
+         Asynch_P : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc,
+                        Chars => Name_Asynchronous);
+         --  Is the procedure to which the 'Access applies asynchronous?
+
+         All_Calls_Remote : constant Entity_Id :=
+                              Make_Defining_Identifier (Loc,
+                                Chars => Name_All_Calls_Remote);
+         --  True if an All_Calls_Remote pragma applies to the RCI unit
+         --  that contains the subprogram.
+
+         --  Common local variables
+
+         Proc_Decls      : List_Id;
+         Proc_Statements : List_Id;
+
+         Origin : constant Entity_Id :=
+                    Make_Defining_Identifier (Loc,
+                      Chars => New_Internal_Name ('P'));
+
+         --  Additional local variables for the local case
+
+         Proxy_Addr : constant Entity_Id :=
+                        Make_Defining_Identifier (Loc,
+                          Chars => New_Internal_Name ('P'));
+
+         --  Additional local variables for the remote case
+
+         Local_Stub : constant Entity_Id :=
+                        Make_Defining_Identifier (Loc,
+                          Chars => New_Internal_Name ('L'));
+
+         Stub_Ptr : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc,
+                        Chars => New_Internal_Name ('S'));
+
+         function Set_Field
+           (Field_Name : Name_Id;
+            Value      : Node_Id) return Node_Id;
+         --  Construct an assignment that sets the named component in the
+         --  returned record
+
+         ---------------
+         -- Set_Field --
+         ---------------
+
+         function Set_Field
+           (Field_Name : Name_Id;
+            Value      : Node_Id) return Node_Id
+         is
+         begin
+            return
+              Make_Assignment_Statement (Loc,
+                Name       =>
+                  Make_Selected_Component (Loc,
+                    Prefix        => Stub_Ptr,
+                    Selector_Name => Field_Name),
+                Expression => Value);
+         end Set_Field;
+
+      --  Start of processing for Add_RAS_Access_TSS
+
+      begin
+         Proc_Decls := New_List (
+
+            --  Common declarations
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Origin,
+             Constant_Present    => True,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
+             Expression          =>
+               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)))),
+
+            --  Declaration use only in the local case: proxy address
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Proxy_Addr,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
+
+            --  Declarations used only in the remote case: stub object and
+            --  stub pointer.
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Local_Stub,
+             Aliased_Present     => True,
+             Object_Definition   =>
+               New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier =>
+               Stub_Ptr,
+             Object_Definition   =>
+               New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
+             Expression          =>
+               Make_Attribute_Reference (Loc,
+                 Prefix => New_Occurrence_Of (Local_Stub, Loc),
+                 Attribute_Name => Name_Unchecked_Access)));
+
+         Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
+
+         --  Build_Get_Unique_RP_Call needs above information
+
+         --  Note: Here we assume that the Fat_Type is a record
+         --  containing just a pointer to a proxy or stub object.
+
+         Proc_Statements := New_List (
+
+         --  Generate:
+
+         --    Get_RAS_Info (Pkg, Subp, PA);
+         --    if Origin = Local_Partition_Id
+         --      and then not All_Calls_Remote
+         --    then
+         --       return Fat_Type!(PA);
+         --    end if;
+
+            Make_Procedure_Call_Statement (Loc,
+              Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
+              Parameter_Associations => New_List (
+                New_Occurrence_Of (Package_Name, Loc),
+                New_Occurrence_Of (Subp_Id, Loc),
+                New_Occurrence_Of (Proxy_Addr, Loc))),
+
+           Make_Implicit_If_Statement (N,
+             Condition =>
+               Make_And_Then (Loc,
+                 Left_Opnd  =>
+                   Make_Op_Eq (Loc,
+                     Left_Opnd =>
+                       New_Occurrence_Of (Origin, Loc),
+                     Right_Opnd =>
+                       Make_Function_Call (Loc,
+                         New_Occurrence_Of (
+                           RTE (RE_Get_Local_Partition_Id), Loc))),
+
+                 Right_Opnd =>
+                   Make_Op_Not (Loc,
+                     New_Occurrence_Of (All_Calls_Remote, Loc))),
+
+             Then_Statements => New_List (
+               Make_Simple_Return_Statement (Loc,
+                 Unchecked_Convert_To (Fat_Type,
+                   OK_Convert_To (RTE (RE_Address),
+                     New_Occurrence_Of (Proxy_Addr, Loc)))))),
+
+           Set_Field (Name_Origin,
+               New_Occurrence_Of (Origin, 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_Addr, New_Occurrence_Of (Proxy_Addr, Loc)),
+
+            --  E.4.1(9) A remote call is asynchronous if it is a call to
+            --  a procedure or a call through a value of an access-to-procedure
+            --  type to which a pragma Asynchronous applies.
+
+            --  Asynch_P is true when the procedure is asynchronous;
+            --  Asynch_T is true when the type is asynchronous.
+
+           Set_Field (Name_Asynchronous,
+             Make_Or_Else (Loc,
+               New_Occurrence_Of (Asynch_P, Loc),
+               New_Occurrence_Of (Boolean_Literals (
+                 Is_Asynchronous (Ras_Type)), Loc))));
+
+         Append_List_To (Proc_Statements,
+           Build_Get_Unique_RP_Call
+             (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
+
+         --  Return the newly created value
+
+         Append_To (Proc_Statements,
+           Make_Simple_Return_Statement (Loc,
+             Expression =>
+               Unchecked_Convert_To (Fat_Type,
+                 New_Occurrence_Of (Stub_Ptr, Loc))));
+
+         Proc_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name       => Proc,
+             Parameter_Specifications => New_List (
+               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 (RTE (RE_Subprogram_Id), Loc)),
+
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => Asynch_P,
+                 Parameter_Type      =>
+                   New_Occurrence_Of (Standard_Boolean, Loc)),
+
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => All_Calls_Remote,
+                 Parameter_Type      =>
+                   New_Occurrence_Of (Standard_Boolean, Loc))),
+
+            Result_Definition =>
+              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, Fat_Type);
+
+         Discard_Node (
+           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_TSS;
+
+      -----------------------
+      -- Add_RAST_Features --
+      -----------------------
+
+      procedure Add_RAST_Features
+        (Vis_Decl : Node_Id;
+         RAS_Type : Entity_Id)
+      is
+         pragma Warnings (Off);
+         pragma Unreferenced (RAS_Type);
+         pragma Warnings (On);
+      begin
+         Add_RAS_Access_TSS (Vis_Decl);
+      end Add_RAST_Features;
+
+      -----------------------------------------
+      -- Add_Receiving_Stubs_To_Declarations --
+      -----------------------------------------
+
+      procedure Add_Receiving_Stubs_To_Declarations
+        (Pkg_Spec : Node_Id;
+         Decls    : List_Id;
+         Stmts    : List_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (Pkg_Spec);
+
+         Request_Parameter : Node_Id;
+
+         Pkg_RPC_Receiver            : constant Entity_Id :=
+                                         Make_Defining_Identifier (Loc,
+                                           New_Internal_Name ('H'));
+         Pkg_RPC_Receiver_Statements : List_Id;
+         Pkg_RPC_Receiver_Cases      : constant List_Id := New_List;
+         Pkg_RPC_Receiver_Body       : Node_Id;
+         --  A Pkg_RPC_Receiver is built to decode the request
+
+         Lookup_RAS_Info : constant Entity_Id :=
+                             Make_Defining_Identifier (Loc,
+                               Chars => New_Internal_Name ('R'));
+         --  A remote subprogram is created to allow peers to look up
+         --  RAS information using subprogram ids.
+
+         Subp_Id    : Entity_Id;
+         Subp_Index : Entity_Id;
+         --  Subprogram_Id as read from the incoming stream
+
+         Current_Declaration       : Node_Id;
+         Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
+         Current_Stubs             : Node_Id;
+
+         Subp_Info_Array : constant Entity_Id :=
+                             Make_Defining_Identifier (Loc,
+                               Chars => New_Internal_Name ('I'));
+
+         Subp_Info_List : constant List_Id := New_List;
+
+         Register_Pkg_Actuals : constant List_Id := New_List;
+
+         All_Calls_Remote_E  : Entity_Id;
+         Proxy_Object_Addr   : Entity_Id;
+
+         procedure Append_Stubs_To
+           (RPC_Receiver_Cases : List_Id;
+            Stubs              : Node_Id;
+            Subprogram_Number  : Int);
+         --  Add one case to the specified RPC receiver case list
+         --  associating Subprogram_Number with the subprogram declared
+         --  by Declaration, for which we have receiving stubs in Stubs.
+
+         ---------------------
+         -- Append_Stubs_To --
+         ---------------------
+
+         procedure Append_Stubs_To
+           (RPC_Receiver_Cases : List_Id;
+            Stubs              : Node_Id;
+            Subprogram_Number  : Int)
+         is
+         begin
+            Append_To (RPC_Receiver_Cases,
+              Make_Case_Statement_Alternative (Loc,
+                Discrete_Choices =>
+                   New_List (Make_Integer_Literal (Loc, Subprogram_Number)),
+                Statements       =>
+                  New_List (
+                    Make_Procedure_Call_Statement (Loc,
+                      Name                   =>
+                        New_Occurrence_Of (Defining_Entity (Stubs), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Request_Parameter, Loc))))));
+         end Append_Stubs_To;
+
+      --  Start of processing for Add_Receiving_Stubs_To_Declarations
+
+      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 each 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.
+
+         Build_RPC_Receiver_Body (
+           RPC_Receiver => Pkg_RPC_Receiver,
+           Request      => Request_Parameter,
+           Subp_Id      => Subp_Id,
+           Subp_Index   => Subp_Index,
+           Stmts        => Pkg_RPC_Receiver_Statements,
+           Decl         => Pkg_RPC_Receiver_Body);
+         pragma Assert (Subp_Id = Subp_Index);
+
+         --  A null subp_id denotes a call through a RAS, in which case the
+         --  next Uint_64 element in the stream is the address of the local
+         --  proxy object, from which we can retrieve the actual subprogram id.
+
+         Append_To (Pkg_RPC_Receiver_Statements,
+           Make_Implicit_If_Statement (Pkg_Spec,
+             Condition =>
+               Make_Op_Eq (Loc,
+                 New_Occurrence_Of (Subp_Id, Loc),
+                 Make_Integer_Literal (Loc, 0)),
+
+             Then_Statements => New_List (
+               Make_Assignment_Statement (Loc,
+                 Name =>
+                   New_Occurrence_Of (Subp_Id, Loc),
+
+                 Expression =>
+                   Make_Selected_Component (Loc,
+                     Prefix =>
+                       Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
+                         OK_Convert_To (RTE (RE_Address),
+                           Make_Attribute_Reference (Loc,
+                             Prefix =>
+                               New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
+                             Attribute_Name =>
+                               Name_Input,
+                             Expressions => New_List (
+                               Make_Selected_Component (Loc,
+                                 Prefix        => Request_Parameter,
+                                 Selector_Name => Name_Params))))),
+
+                     Selector_Name =>
+                       Make_Identifier (Loc, Name_Subp_Id))))));
+
+         --  Build a subprogram for RAS information lookups
+
+         Current_Declaration :=
+           Make_Subprogram_Declaration (Loc,
+             Specification =>
+               Make_Function_Specification (Loc,
+                 Defining_Unit_Name =>
+                   Lookup_RAS_Info,
+                 Parameter_Specifications => New_List (
+                   Make_Parameter_Specification (Loc,
+                     Defining_Identifier =>
+                       Make_Defining_Identifier (Loc, Name_Subp_Id),
+                     In_Present =>
+                       True,
+                     Parameter_Type =>
+                       New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
+                 Result_Definition =>
+                   New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
+
+         Append_To (Decls, Current_Declaration);
+         Analyze (Current_Declaration);
+
+         Current_Stubs := Build_Subprogram_Receiving_Stubs
+           (Vis_Decl     => Current_Declaration,
+            Asynchronous => False);
+         Append_To (Decls, Current_Stubs);
+         Analyze (Current_Stubs);
+
+         Append_Stubs_To (Pkg_RPC_Receiver_Cases,
+           Stubs       =>
+             Current_Stubs,
+           Subprogram_Number => 1);
+
+         --  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.
+
+         All_Calls_Remote_E :=
+           Boolean_Literals
+             (Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
+
+         Overload_Counter_Table.Reset;
+
+         Current_Declaration := First (Visible_Declarations (Pkg_Spec));
+         while Present (Current_Declaration) loop
+            if Nkind (Current_Declaration) = N_Subprogram_Declaration
+              and then Comes_From_Source (Current_Declaration)
+            then
+               declare
+                  Loc : constant Source_Ptr := Sloc (Current_Declaration);
+                  --  While specifically processing Current_Declaration, use
+                  --  its Sloc as the location of all generated nodes.
+
+                  Subp_Def : constant Entity_Id :=
+                               Defining_Unit_Name
+                                 (Specification (Current_Declaration));
+
+                  Subp_Val : String_Id;
+                  pragma Warnings (Off, Subp_Val);
+
+               begin
+                  --  Build receiving stub
+
+                  Current_Stubs :=
+                    Build_Subprogram_Receiving_Stubs
+                      (Vis_Decl     => Current_Declaration,
+                       Asynchronous =>
+                         Nkind (Specification (Current_Declaration)) =
+                             N_Procedure_Specification
+                           and then Is_Asynchronous (Subp_Def));
+
+                  Append_To (Decls, Current_Stubs);
+                  Analyze (Current_Stubs);
+
+                  --  Build RAS proxy
+
+                  Add_RAS_Proxy_And_Analyze (Decls,
+                    Vis_Decl           => Current_Declaration,
+                    All_Calls_Remote_E => All_Calls_Remote_E,
+                    Proxy_Object_Addr  => Proxy_Object_Addr);
+
+                  --  Compute distribution identifier
+
+                  Assign_Subprogram_Identifier
+                    (Subp_Def,
+                     Current_Subprogram_Number,
+                     Subp_Val);
+
+                  pragma Assert
+                    (Current_Subprogram_Number = Get_Subprogram_Id (Subp_Def));
+
+                  --  Add subprogram descriptor (RCI_Subp_Info) to the
+                  --  subprograms table for this receiver. The aggregate
+                  --  below must be kept consistent with the declaration
+                  --  of type RCI_Subp_Info in System.Partition_Interface.
+
+                  Append_To (Subp_Info_List,
+                    Make_Component_Association (Loc,
+                      Choices => New_List (
+                        Make_Integer_Literal (Loc,
+                          Current_Subprogram_Number)),
+
+                      Expression =>
+                        Make_Aggregate (Loc,
+                          Component_Associations => New_List (
+                            Make_Component_Association (Loc,
+                              Choices => New_List (
+                                Make_Identifier (Loc, Name_Addr)),
+                              Expression =>
+                                New_Occurrence_Of (
+                                  Proxy_Object_Addr, Loc))))));
+
+                  Append_Stubs_To (Pkg_RPC_Receiver_Cases,
+                    Stubs             => Current_Stubs,
+                    Subprogram_Number => Current_Subprogram_Number);
+               end;
+
+               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));
+
+         Append_To (Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Subp_Info_Array,
+             Constant_Present    => True,
+             Aliased_Present     => True,
+             Object_Definition   =>
+               Make_Subtype_Indication (Loc,
+                 Subtype_Mark =>
+                   New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
+                 Constraint =>
+                   Make_Index_Or_Discriminant_Constraint (Loc,
+                     New_List (
+                       Make_Range (Loc,
+                         Low_Bound  => Make_Integer_Literal (Loc,
+                           First_RCI_Subprogram_Id),
+                         High_Bound =>
+                           Make_Integer_Literal (Loc,
+                             Intval =>
+                               First_RCI_Subprogram_Id
+                               + List_Length (Subp_Info_List) - 1)))))));
+
+         --  For a degenerate RCI with no visible subprograms, Subp_Info_List
+         --  has zero length, and the declaration is for an empty array, in
+         --  which case no initialization aggregate must be generated.
+
+         if Present (First (Subp_Info_List)) then
+            Set_Expression (Last (Decls),
+              Make_Aggregate (Loc,
+                Component_Associations => Subp_Info_List));
+
+         --  No initialization provided: remove CONSTANT so that the
+         --  declaration is not an incomplete deferred constant.
+
+         else
+            Set_Constant_Present (Last (Decls), False);
+         end if;
+
+         Analyze (Last (Decls));
+
+         declare
+            Subp_Info_Addr : Node_Id;
+            --  Return statement for Lookup_RAS_Info: address of the subprogram
+            --  information record for the requested subprogram id.
+
+         begin
+            if Present (First (Subp_Info_List)) then
+               Subp_Info_Addr :=
+                 Make_Selected_Component (Loc,
+                   Prefix =>
+                     Make_Indexed_Component (Loc,
+                       Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
+                       Expressions => New_List (
+                         Convert_To (Standard_Integer,
+                           Make_Identifier (Loc, Name_Subp_Id)))),
+                   Selector_Name => Make_Identifier (Loc, Name_Addr));
+
+            --  Case of no visible subprogram: just raise Constraint_Error, we
+            --  know for sure we got junk from a remote partition.
+
+            else
+               Subp_Info_Addr :=
+                 Make_Raise_Constraint_Error (Loc,
+                    Reason => CE_Range_Check_Failed);
+               Set_Etype (Subp_Info_Addr, RTE (RE_Unsigned_64));
+            end if;
+
+            Append_To (Decls,
+              Make_Subprogram_Body (Loc,
+                Specification =>
+                  Copy_Specification (Loc, Parent (Lookup_RAS_Info)),
+                Declarations  => No_List,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => New_List (
+                      Make_Simple_Return_Statement (Loc,
+                        Expression =>
+                          OK_Convert_To
+                            (RTE (RE_Unsigned_64), Subp_Info_Addr))))));
+         end;
+
+         Analyze (Last (Decls));
+
+         Append_To (Decls, Pkg_RPC_Receiver_Body);
+         Analyze (Last (Decls));
+
+         Get_Library_Unit_Name_String (Pkg_Spec);
+
+         --  Name
+
+         Append_To (Register_Pkg_Actuals,
+           Make_String_Literal (Loc,
+             Strval => String_From_Name_Buffer));
+
+         --  Receiver
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         => New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
+             Attribute_Name => Name_Unrestricted_Access));
+
+         --  Version
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         =>
+               New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
+             Attribute_Name => Name_Version));
+
+         --  Subp_Info
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Address));
+
+         --  Subp_Info_Len
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Length));
+
+         --  Generate the call
+
+         Append_To (Stmts,
+           Make_Procedure_Call_Statement (Loc,
+             Name                   =>
+               New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
+             Parameter_Associations => Register_Pkg_Actuals));
+         Analyze (Last (Stmts));
+      end Add_Receiving_Stubs_To_Declarations;
+
+      ---------------------------------
+      -- Build_General_Calling_Stubs --
+      ---------------------------------
+
+      procedure Build_General_Calling_Stubs
+        (Decls                     : List_Id;
+         Statements                : List_Id;
+         Target_Partition          : Entity_Id;
+         Target_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;
+         Stub_Type                 : Entity_Id := Empty;
+         RACW_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.
+
+         pragma Warnings (Off);
+         pragma Unreferenced (RACW_Type);
+         --  Used only for the PolyORB case
+         pragma Warnings (On);
+
+      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),
+               Target_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 Present (Current_Parameter) loop
+            declare
+               Typ             : constant Node_Id :=
+                                   Parameter_Type (Current_Parameter);
+               Etyp            : Entity_Id;
+               Constrained     : Boolean;
+               Value           : Node_Id;
+               Extra_Parameter : Entity_Id;
+
+            begin
+               if Is_RACW_Controlling_Formal
+                    (Current_Parameter, Stub_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        =>
+                             Defining_Identifier (Current_Parameter),
+                           Selector_Name => Name_Addr),
+                       Etyp   => RTE (RE_Unsigned_64)));
+
+               else
+                  Value :=
+                    New_Occurrence_Of
+                      (Defining_Identifier (Current_Parameter), Loc);
+
+                  --  Access type parameters are transmitted as in out
+                  --  parameters. However, a dereference is needed so that
+                  --  we marshall the designated object.
+
+                  if Nkind (Typ) = N_Access_Definition then
+                     Value := Make_Explicit_Dereference (Loc, Value);
+                     Etyp  := Etype (Subtype_Mark (Typ));
+                  else
+                     Etyp := Etype (Typ);
+                  end if;
+
+                  Constrained := not Transmit_As_Unconstrained (Etyp);
+
+                  --  Any parameter but unconstrained out parameters are
+                  --  transmitted to the peer.
+
+                  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),
+                           Value)));
+                  end if;
+               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 (Typ) /= 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.
+
+                  Extra_Parameter := Make_Defining_Identifier
+                                       (Loc, New_Internal_Name ('P'));
+
+                  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 if;
+
+               Next (Current_Parameter);
+            end;
+         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_Simple_Return_Statement (Loc,
+                     Expression =>
+                       Make_Attribute_Reference (Loc,
+                         Prefix         =>
+                           New_Occurrence_Of (
+                             Etype (Result_Definition (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 Present (Current_Parameter) loop
+                  declare
+                     Typ   : constant Node_Id :=
+                               Parameter_Type (Current_Parameter);
+                     Etyp  : Entity_Id;
+                     Value : Node_Id;
+
+                  begin
+                     Value :=
+                       New_Occurrence_Of
+                         (Defining_Identifier (Current_Parameter), Loc);
+
+                     if Nkind (Typ) = N_Access_Definition then
+                        Value := Make_Explicit_Dereference (Loc, Value);
+                        Etyp  := Etype (Subtype_Mark (Typ));
+                     else
+                        Etyp := Etype (Typ);
+                     end if;
+
+                     if (Out_Present (Current_Parameter)
+                          or else Nkind (Typ) = N_Access_Definition)
+                       and then Etyp /= Stub_Type
+                     then
+                        Append_To (Non_Asynchronous_Statements,
+                           Make_Attribute_Reference (Loc,
+                             Prefix         =>
+                               New_Occurrence_Of (Etyp, Loc),
+
+                             Attribute_Name => Name_Read,
+
+                             Expressions    => New_List (
+                               Make_Attribute_Reference (Loc,
+                                 Prefix         =>
+                                   New_Occurrence_Of (Result_Parameter, Loc),
+                                 Attribute_Name => Name_Access),
+                               Value)));
+                     end if;
+                  end;
+
+                  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 (Present (Asynchronous));
+            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_RPC_Receiver_Body --
+      -----------------------------
+
+      procedure Build_RPC_Receiver_Body
+        (RPC_Receiver : Entity_Id;
+         Request      : out Entity_Id;
+         Subp_Id      : out Entity_Id;
+         Subp_Index   : out Entity_Id;
+         Stmts        : out List_Id;
+         Decl         : out Node_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (RPC_Receiver);
+
+         RPC_Receiver_Spec  : Node_Id;
+         RPC_Receiver_Decls : List_Id;
+
+      begin
+         Request := Make_Defining_Identifier (Loc, Name_R);
+
+         RPC_Receiver_Spec :=
+           Build_RPC_Receiver_Specification
+             (RPC_Receiver      => RPC_Receiver,
+              Request_Parameter => Request);
+
+         Subp_Id    := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         Subp_Index := Subp_Id;
+
+         --  Subp_Id may not be a constant, because in the case of the RPC
+         --  receiver for an RCI package, when a call is received from a RAS
+         --  dereference, it will be assigned during subsequent processing.
+
+         RPC_Receiver_Decls := New_List (
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Subp_Id,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
+             Expression          =>
+               Make_Attribute_Reference (Loc,
+                 Prefix          =>
+                   New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
+                 Attribute_Name  => Name_Input,
+                 Expressions     => New_List (
+                   Make_Selected_Component (Loc,
+                     Prefix        => Request,
+                     Selector_Name => Name_Params)))));
+
+         Stmts := New_List;
+
+         Decl :=
+           Make_Subprogram_Body (Loc,
+             Specification              => RPC_Receiver_Spec,
+             Declarations               => RPC_Receiver_Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Stmts));
+      end Build_RPC_Receiver_Body;
+
+      -----------------------
+      -- Build_Stub_Target --
+      -----------------------
+
+      function Build_Stub_Target
+        (Loc                   : Source_Ptr;
+         Decls                 : List_Id;
+         RCI_Locator           : Entity_Id;
+         Controlling_Parameter : Entity_Id) return RPC_Target
+      is
+         Target_Info : RPC_Target (PCS_Kind => Name_GARLIC_DSA);
+      begin
+         Target_Info.Partition :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         if Present (Controlling_Parameter) then
+            Append_To (Decls,
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Target_Info.Partition,
+                Constant_Present    => True,
+                Object_Definition   =>
+                  New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
+
+                Expression          =>
+                  Make_Selected_Component (Loc,
+                    Prefix        => Controlling_Parameter,
+                    Selector_Name => Name_Origin)));
+
+            Target_Info.RPC_Receiver :=
+              Make_Selected_Component (Loc,
+                Prefix        => Controlling_Parameter,
+                Selector_Name => Name_Receiver);
+
+         else
+            Append_To (Decls,
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Target_Info.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)))));
+
+            Target_Info.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;
+         return Target_Info;
+      end Build_Stub_Target;
+
+      ---------------------
+      -- Build_Stub_Type --
+      ---------------------
+
+      procedure Build_Stub_Type
+        (RACW_Type         : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Decl    : out Node_Id;
+         RPC_Receiver_Decl : out Node_Id)
+      is
+         Loc    : constant Source_Ptr := Sloc (Stub_Type);
+         Is_RAS : constant Boolean    := not Comes_From_Source (RACW_Type);
+
+      begin
+         Stub_Type_Decl :=
+           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),
+                         Component_Definition =>
+                           Make_Component_Definition (Loc,
+                             Aliased_Present    => False,
+                             Subtype_Indication =>
+                               New_Occurrence_Of (
+                                 RTE (RE_Partition_ID), Loc))),
+
+                       Make_Component_Declaration (Loc,
+                         Defining_Identifier =>
+                           Make_Defining_Identifier (Loc, Name_Receiver),
+                         Component_Definition =>
+                           Make_Component_Definition (Loc,
+                             Aliased_Present    => False,
+                             Subtype_Indication =>
+                               New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
+
+                       Make_Component_Declaration (Loc,
+                         Defining_Identifier =>
+                           Make_Defining_Identifier (Loc, Name_Addr),
+                         Component_Definition =>
+                           Make_Component_Definition (Loc,
+                             Aliased_Present    => False,
+                             Subtype_Indication =>
+                               New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
+
+                       Make_Component_Declaration (Loc,
+                         Defining_Identifier =>
+                           Make_Defining_Identifier (Loc, Name_Asynchronous),
+                         Component_Definition =>
+                           Make_Component_Definition (Loc,
+                             Aliased_Present    => False,
+                             Subtype_Indication =>
+                               New_Occurrence_Of (
+                                 Standard_Boolean, Loc)))))));
+
+         if Is_RAS then
+            RPC_Receiver_Decl := Empty;
+         else
+            declare
+               RPC_Receiver_Request : constant Entity_Id :=
+                                        Make_Defining_Identifier (Loc, Name_R);
+            begin
+               RPC_Receiver_Decl :=
+                 Make_Subprogram_Declaration (Loc,
+                   Build_RPC_Receiver_Specification (
+                     RPC_Receiver      => Make_Defining_Identifier (Loc,
+                                            New_Internal_Name ('R')),
+                     Request_Parameter => RPC_Receiver_Request));
+            end;
+         end if;
+      end Build_Stub_Type;
+
+      --------------------------------------
+      -- 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);
+
+         Request_Parameter : constant Entity_Id :=
+                               Make_Defining_Identifier (Loc,
+                                 New_Internal_Name ('R'));
+         --  Formal parameter for receiving stubs: a descriptor for an incoming
+         --  request.
+
+         Decls : constant List_Id := New_List;
+         --  All the parameters will get declared before calling the real
+         --  subprograms. Also the out parameters will be declared.
+
+         Statements : constant List_Id := New_List;
+
+         Extra_Formal_Statements : constant List_Id := New_List;
+         --  Statements concerning extra formal parameters
+
+         After_Statements : constant 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_Handlers : List_Id := No_List;
+         Excep_Choice   : Entity_Id;
+         Excep_Code     : List_Id;
+
+         Parameter_List : constant 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 Present (RACW_Type) then
+            Called_Subprogram := New_Occurrence_Of (Parent_Primitive, Loc);
+         else
+            Called_Subprogram :=
+              New_Occurrence_Of
+                (Defining_Unit_Name (Specification (Vis_Decl)), Loc);
+         end if;
+
+         if Dynamically_Asynchronous then
+            Dynamic_Async :=
+              Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+         else
+            Dynamic_Async := Empty;
+         end if;
+
+         if not Asynchronous or Dynamically_Asynchronous then
+
+            --  The first statement after the subprogram call is a statement to
+            --  write 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 (
+                  Make_Selected_Component (Loc,
+                    Prefix        => Request_Parameter,
+                    Selector_Name => Name_Result),
+                  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);
+         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 Present (Current_Parameter) loop
+            declare
+               Etyp        : Entity_Id;
+               Constrained : Boolean;
+
+               Need_Extra_Constrained : Boolean;
+               --  True when an Extra_Constrained actual is required
+
+               Object : constant Entity_Id :=
+                          Make_Defining_Identifier (Loc,
+                            New_Internal_Name ('P'));
+
+               Expr : Node_Id := Empty;
+
+               Is_Controlling_Formal : constant Boolean :=
+                                         Is_RACW_Controlling_Formal
+                                           (Current_Parameter, Stub_Type);
+
+            begin
+               if Is_Controlling_Formal 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 := not Transmit_As_Unconstrained (Etyp);
+
+               if In_Present (Current_Parameter)
+                 or else not Out_Present (Current_Parameter)
+                 or else not Constrained
+                 or else Is_Controlling_Formal
+               then
+                  --  If an input parameter is constrained, then the read of
+                  --  the parameter 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. Note that
+                  --  this deferral does not change the order in which the
+                  --  actuals are read because Build_Ordered_Parameter_List
+                  --  puts them unconstrained first.
+
+                  if Constrained then
+                     Append_To (Statements,
+                       Make_Attribute_Reference (Loc,
+                         Prefix         => New_Occurrence_Of (Etyp, Loc),
+                         Attribute_Name => Name_Read,
+                         Expressions    => New_List (
+                           Make_Selected_Component (Loc,
+                             Prefix        => Request_Parameter,
+                             Selector_Name => Name_Params),
+                           New_Occurrence_Of (Object, Loc))));
+
+                  else
+
+                     --  Build and append Input_With_Tag_Check function
+
+                     Append_To (Decls,
+                       Input_With_Tag_Check (Loc,
+                         Var_Type => Etyp,
+                         Stream   =>
+                           Make_Selected_Component (Loc,
+                             Prefix        => Request_Parameter,
+                             Selector_Name => Name_Params)));
+
+                     --  Prepare function call expression
+
+                     Expr :=
+                       Make_Function_Call (Loc,
+                         Name =>
+                           New_Occurrence_Of
+                             (Defining_Unit_Name
+                               (Specification (Last (Decls))), Loc));
+                  end if;
+               end if;
+
+               Need_Extra_Constrained :=
+                 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)));
+
+               --  We may not associate an extra constrained actual to a
+               --  constant object, so if one is needed, declare the actual
+               --  as a variable even if it won't be modified.
+
+               Build_Actual_Object_Declaration
+                 (Object   => Object,
+                  Etyp     => Etyp,
+                  Variable => Need_Extra_Constrained
+                                or else Out_Present (Current_Parameter),
+                  Expr     => Expr,
+                  Decls    => Decls);
+
+               --  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 (
+                        Make_Selected_Component (Loc,
+                          Prefix        => Request_Parameter,
+                          Selector_Name => Name_Result),
+                        New_Occurrence_Of (Object, Loc))));
+               end if;
+
+               --  For RACW controlling formals, the Etyp of Object is always
+               --  an RACW, even if the parameter is not of an anonymous access
+               --  type. In such case, we need to dereference it at call time.
+
+               if Is_Controlling_Formal 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 Need_Extra_Constrained 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 (
+                           Make_Selected_Component (Loc,
+                             Prefix        => Request_Parameter,
+                             Selector_Name => Name_Params),
+                           New_Occurrence_Of (Formal_Entity, Loc))));
+
+                     --  Note: the call to Set_Extra_Constrained below relies
+                     --  on the fact that Object's Ekind has been set by
+                     --  Build_Actual_Object_Declaration.
+
+                     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 (Result_Definition (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)));
+
+               if Is_Class_Wide_Type (Etyp) then
+
+                  --  For a remote call to a function with a class-wide type,
+                  --  check that the returned value satisfies the requirements
+                  --  of E.4(18).
+
+                  Append_To (Inner_Decls,
+                    Make_Transportable_Check (Loc,
+                      New_Occurrence_Of (Result, Loc)));
+
+               end if;
+
+               Append_To (After_Statements,
+                 Make_Attribute_Reference (Loc,
+                   Prefix         => New_Occurrence_Of (Etyp, Loc),
+                   Attribute_Name => Name_Output,
+                   Expressions    => New_List (
+                     Make_Selected_Component (Loc,
+                       Prefix        => Request_Parameter,
+                       Selector_Name => Name_Result),
+                     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 (
+                     Make_Selected_Component (Loc,
+                       Prefix        => Request_Parameter,
+                       Selector_Name => Name_Params),
+                     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
+
+            --  For an asynchronous procedure, add a null exception handler
+
+            Excep_Handlers := New_List (
+              Make_Implicit_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 (
+                                    Make_Selected_Component (Loc,
+                                      Prefix        => Request_Parameter,
+                                      Selector_Name => Name_Result),
+                                    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_Handlers := New_List (
+              Make_Implicit_Exception_Handler (Loc,
+                Choice_Parameter   => Excep_Choice,
+                Exception_Choices  => New_List (Make_Others_Choice (Loc)),
+                Statements         => Excep_Code));
+
+         end if;
+
+         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 => Request_Parameter,
+                 Parameter_Type      =>
+                   New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
+
+         return
+           Make_Subprogram_Body (Loc,
+             Specification              => Subp_Spec,
+             Declarations               => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements         => Statements,
+                 Exception_Handlers => Excep_Handlers));
+      end Build_Subprogram_Receiving_Stubs;
+
+      ------------
+      -- Result --
+      ------------
+
+      function Result return Node_Id is
+      begin
+         return Make_Identifier (Loc, Name_V);
+      end Result;
+
+      ----------------------
+      -- Stream_Parameter --
+      ----------------------
+
+      function Stream_Parameter return Node_Id is
+      begin
+         return Make_Identifier (Loc, Name_S);
+      end Stream_Parameter;
+
+   end GARLIC_Support;
+
+   -------------------------------
+   -- Get_And_Reset_RACW_Bodies --
+   -------------------------------
+
+   function Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id is
+      Desig : constant Entity_Id := Etype (Designated_Type (RACW_Type));
+      Stub_Elements : Stub_Structure := Stubs_Table.Get (Desig);
+
+      Body_Decls : List_Id;
+      --  Returned list of declarations
+
+   begin
+      if Stub_Elements = Empty_Stub_Structure then
+
+         --  Stub elements may be missing as a consequence of a previously
+         --  detected error.
+
+         return No_List;
+      end if;
+
+      Body_Decls := Stub_Elements.Body_Decls;
+      Stub_Elements.Body_Decls := No_List;
+      Stubs_Table.Set (Desig, Stub_Elements);
+      return Body_Decls;
+   end Get_And_Reset_RACW_Bodies;
+
+   -----------------------
+   -- Get_Stub_Elements --
+   -----------------------
+
+   function Get_Stub_Elements (RACW_Type : Entity_Id) return Stub_Structure is
+      Desig         : constant Entity_Id :=
+                        Etype (Designated_Type (RACW_Type));
+      Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
+   begin
+      pragma Assert (Stub_Elements /= Empty_Stub_Structure);
+      return Stub_Elements;
+   end Get_Stub_Elements;
+
+   -----------------------
+   -- Get_Subprogram_Id --
+   -----------------------
+
+   function Get_Subprogram_Id (Def : Entity_Id) return String_Id is
+      Result : constant String_Id := Get_Subprogram_Ids (Def).Str_Identifier;
+   begin
+      pragma Assert (Result /= No_String);
+      return Result;
+   end Get_Subprogram_Id;
+
+   -----------------------
+   -- Get_Subprogram_Id --
+   -----------------------
+
+   function Get_Subprogram_Id (Def : Entity_Id) return Int is
+   begin
+      return Get_Subprogram_Ids (Def).Int_Identifier;
+   end Get_Subprogram_Id;
+
+   ------------------------
+   -- Get_Subprogram_Ids --
+   ------------------------
+
+   function Get_Subprogram_Ids
+     (Def : Entity_Id) return Subprogram_Identifiers
+   is
+   begin
+      return Subprogram_Identifier_Table.Get (Def);
+   end Get_Subprogram_Ids;
+
+   ----------
+   -- Hash --
+   ----------
+
+   function Hash (F : Entity_Id) return Hash_Index is
+   begin
+      return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
+   end Hash;
+
+   function Hash (F : Name_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   : Node_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')),
+            Result_Definition  => 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_Simple_Return_Statement (Loc,
+                  Make_Attribute_Reference (Loc,
+                    Prefix         => New_Occurrence_Of (Var_Type, Loc),
+                    Attribute_Name => Name_Input,
+                    Expressions    =>
+                      New_List (Stream)))))));
+   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_Transportable_Check --
+   ------------------------------
+
+   function Make_Transportable_Check
+     (Loc  : Source_Ptr;
+      Expr : Node_Id) return Node_Id is
+   begin
+      return
+        Make_Raise_Program_Error (Loc,
+          Condition       =>
+            Make_Op_Not (Loc,
+              Build_Get_Transportable (Loc,
+                Make_Selected_Component (Loc,
+                  Prefix        => Expr,
+                  Selector_Name => Make_Identifier (Loc, Name_uTag)))),
+          Reason => PE_Non_Transportable_Actual);
+   end Make_Transportable_Check;
+
+   -----------------------------
+   -- Make_Selected_Component --
+   -----------------------------
+
+   function Make_Selected_Component
+     (Loc           : Source_Ptr;
+      Prefix        : Entity_Id;
+      Selector_Name : Name_Id) return Node_Id
+   is
+   begin
+      return Make_Selected_Component (Loc,
+               Prefix        => New_Occurrence_Of (Prefix, Loc),
+               Selector_Name => Make_Identifier (Loc, Selector_Name));
+   end Make_Selected_Component;
+
+   --------------------
+   -- 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_Implicit_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 : Node_Id;
+      Object : Entity_Id;
+      Etyp   : Entity_Id := Empty) return Node_Id
+   is
+      Typ : Entity_Id;
+
+   begin
+      if Present (Etyp) 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 : Node_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 (
+            Stream,
+            Object));
+   end Pack_Node_Into_Stream_Access;
+
+   ---------------------
+   -- PolyORB_Support --
+   ---------------------
+
+   package body PolyORB_Support is
+
+      --  Local subprograms
+
+      procedure Add_RACW_Read_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         Body_Decls       : List_Id);
+      --  Add Read attribute for the RACW type. The declaration and attribute
+      --  definition clauses are inserted right after the declaration of
+      --  RACW_Type. If Body_Decls is not No_List, the subprogram body is
+      --  appended to it (case where the RACW declaration is in the main unit).
+
+      procedure Add_RACW_Write_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         Body_Decls       : List_Id);
+      --  Same as above for the Write attribute
+
+      procedure Add_RACW_From_Any
+        (RACW_Type        : Entity_Id;
+         Body_Decls       : List_Id);
+      --  Add the From_Any TSS for this RACW type
+
+      procedure Add_RACW_To_Any
+        (RACW_Type        : Entity_Id;
+         Body_Decls       : List_Id);
+      --  Add the To_Any TSS for this RACW type
+
+      procedure Add_RACW_TypeCode
+        (Designated_Type : Entity_Id;
+         RACW_Type       : Entity_Id;
+         Body_Decls      : List_Id);
+      --  Add the TypeCode TSS for this RACW type
+
+      procedure Add_RAS_From_Any (RAS_Type : Entity_Id);
+      --  Add the From_Any TSS for this RAS type
+
+      procedure Add_RAS_To_Any   (RAS_Type : Entity_Id);
+      --  Add the To_Any TSS for this RAS type
+
+      procedure Add_RAS_TypeCode (RAS_Type : Entity_Id);
+      --  Add the TypeCode TSS for this RAS type
+
+      procedure Add_RAS_Access_TSS (N : Node_Id);
+      --  Add a subprogram body for RAS Access TSS
+
+      -------------------------------------
+      -- Add_Obj_RPC_Receiver_Completion --
+      -------------------------------------
+
+      procedure Add_Obj_RPC_Receiver_Completion
+        (Loc           : Source_Ptr;
+         Decls         : List_Id;
+         RPC_Receiver  : Entity_Id;
+         Stub_Elements : Stub_Structure)
+      is
+         Desig : constant Entity_Id :=
+           Etype (Designated_Type (Stub_Elements.RACW_Type));
+      begin
+         Append_To (Decls,
+           Make_Procedure_Call_Statement (Loc,
+              Name =>
+                New_Occurrence_Of (
+                  RTE (RE_Register_Obj_Receiving_Stub), Loc),
+
+                Parameter_Associations => New_List (
+
+               --  Name
+
+                Make_String_Literal (Loc,
+                  Full_Qualified_Name (Desig)),
+
+               --  Handler
+
+                Make_Attribute_Reference (Loc,
+                  Prefix =>
+                    New_Occurrence_Of (
+                      Defining_Unit_Name (Parent (RPC_Receiver)), Loc),
+                  Attribute_Name =>
+                    Name_Access),
+
+               --  Receiver
+
+                Make_Attribute_Reference (Loc,
+                  Prefix =>
+                    New_Occurrence_Of (
+                      Defining_Identifier (
+                        Stub_Elements.RPC_Receiver_Decl), Loc),
+                  Attribute_Name =>
+                    Name_Access))));
+      end Add_Obj_RPC_Receiver_Completion;
+
+      -----------------------
+      -- Add_RACW_Features --
+      -----------------------
+
+      procedure Add_RACW_Features
+        (RACW_Type         : Entity_Id;
+         Desig             : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Access  : Entity_Id;
+         RPC_Receiver_Decl : Node_Id;
+         Body_Decls        : List_Id)
+      is
+         pragma Warnings (Off);
+         pragma Unreferenced (RPC_Receiver_Decl);
+         pragma Warnings (On);
+
+      begin
+         Add_RACW_From_Any
+           (RACW_Type           => RACW_Type,
+            Body_Decls          => Body_Decls);
+
+         Add_RACW_To_Any
+           (RACW_Type           => RACW_Type,
+            Body_Decls          => Body_Decls);
+
+         Add_RACW_Write_Attribute
+           (RACW_Type           => RACW_Type,
+            Stub_Type           => Stub_Type,
+            Stub_Type_Access    => Stub_Type_Access,
+            Body_Decls          => Body_Decls);
+
+         Add_RACW_Read_Attribute
+           (RACW_Type           => RACW_Type,
+            Stub_Type           => Stub_Type,
+            Stub_Type_Access    => Stub_Type_Access,
+            Body_Decls          => Body_Decls);
+
+         Add_RACW_TypeCode
+           (Designated_Type     => Desig,
+            RACW_Type           => RACW_Type,
+            Body_Decls          => Body_Decls);
+      end Add_RACW_Features;
+
+      -----------------------
+      -- Add_RACW_From_Any --
+      -----------------------
+
+      procedure Add_RACW_From_Any
+        (RACW_Type        : Entity_Id;
+         Body_Decls       : List_Id)
+      is
+         Loc    : constant Source_Ptr := Sloc (RACW_Type);
+         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
+
+         Fnam   : constant Entity_Id :=
+                    Make_Defining_Identifier (Loc,
+                      Chars => New_External_Name (Chars (RACW_Type), 'F'));
+
+         Func_Spec : Node_Id;
+         Func_Decl : Node_Id;
+         Func_Body : Node_Id;
+
+         Statements       : List_Id;
+         --  Various parts of the subprogram
+
+         Any_Parameter  : constant Entity_Id :=
+                            Make_Defining_Identifier (Loc, Name_A);
+
+         Asynchronous_Flag : constant Entity_Id :=
+                               Asynchronous_Flags_Table.Get (RACW_Type);
+         --  The flag object declared in Add_RACW_Asynchronous_Flag
+
+      begin
+         Func_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name =>
+               Fnam,
+             Parameter_Specifications => New_List (
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier =>
+                   Any_Parameter,
+                 Parameter_Type =>
+                   New_Occurrence_Of (RTE (RE_Any), Loc))),
+             Result_Definition => New_Occurrence_Of (RACW_Type, Loc));
+
+         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
+         --  entity in the declaration spec, not those of the body spec.
+
+         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
+         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
+         Set_Renaming_TSS (RACW_Type, Fnam, TSS_From_Any);
+
+         if No (Body_Decls) then
+            return;
+         end if;
+
+         --  ??? Issue with asynchronous calls here: the Asynchronous flag is
+         --  set on the stub type if, and only if, the RACW type has a pragma
+         --  Asynchronous. This is incorrect for RACWs that implement RAS
+         --  types, because in that case the /designated subprogram/ (not the
+         --  type) might be asynchronous, and that causes the stub to need to
+         --  be asynchronous too. A solution is to transport a RAS as a struct
+         --  containing a RACW and an asynchronous flag, and to properly alter
+         --  the Asynchronous component in the stub type in the RAS's _From_Any
+         --  TSS.
+
+         Statements := New_List (
+           Make_Simple_Return_Statement (Loc,
+             Expression => Unchecked_Convert_To (RACW_Type,
+               Make_Function_Call (Loc,
+                 Name => New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
+                 Parameter_Associations => New_List (
+                   Make_Function_Call (Loc,
+                     Name => New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
+                     Parameter_Associations => New_List (
+                       New_Occurrence_Of (Any_Parameter, Loc))),
+                   Build_Stub_Tag (Loc, RACW_Type),
+                   New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
+                   New_Occurrence_Of (Asynchronous_Flag, Loc))))));
+
+         Func_Body :=
+           Make_Subprogram_Body (Loc,
+             Specification => Copy_Specification (Loc, Func_Spec),
+             Declarations  => No_List,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Statements));
+
+         Append_To (Body_Decls, Func_Body);
+      end Add_RACW_From_Any;
+
+      -----------------------------
+      -- Add_RACW_Read_Attribute --
+      -----------------------------
+
+      procedure Add_RACW_Read_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         Body_Decls       : List_Id)
+      is
+         pragma Warnings (Off);
+         pragma Unreferenced (Stub_Type, Stub_Type_Access);
+         pragma Warnings (On);
+         Loc : constant Source_Ptr := Sloc (RACW_Type);
+
+         Proc_Decl : Node_Id;
+         Attr_Decl : Node_Id;
+
+         Body_Node : Node_Id;
+
+         Decls      : constant List_Id   := New_List;
+         Statements : constant List_Id   := New_List;
+         Reference  : constant Entity_Id :=
+                        Make_Defining_Identifier (Loc, Name_R);
+         --  Various parts of the procedure
+
+         Pnam : constant Entity_Id := Make_Defining_Identifier (Loc,
+                                        New_Internal_Name ('R'));
+
+         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
+
+         Asynchronous_Flag : constant Entity_Id :=
+                               Asynchronous_Flags_Table.Get (RACW_Type);
+         pragma Assert (Present (Asynchronous_Flag));
+
+         function Stream_Parameter return Node_Id;
+         function Result return Node_Id;
+
+         --  Functions to create occurrences of the formal parameter names
+
+         ------------
+         -- Result --
+         ------------
+
+         function Result return Node_Id is
+         begin
+            return Make_Identifier (Loc, Name_V);
+         end Result;
+
+         ----------------------
+         -- Stream_Parameter --
+         ----------------------
+
+         function Stream_Parameter return Node_Id is
+         begin
+            return Make_Identifier (Loc, Name_S);
+         end Stream_Parameter;
+
+      --  Start of processing for Add_RACW_Read_Attribute
+
+      begin
+         Build_Stream_Procedure
+           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => True);
+
+         Proc_Decl := Make_Subprogram_Declaration (Loc,
+           Copy_Specification (Loc, Specification (Body_Node)));
+
+         Attr_Decl :=
+           Make_Attribute_Definition_Clause (Loc,
+             Name       => New_Occurrence_Of (RACW_Type, Loc),
+             Chars      => Name_Read,
+             Expression =>
+               New_Occurrence_Of (
+                 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
+
+         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
+         Insert_After (Proc_Decl, Attr_Decl);
+
+         if No (Body_Decls) then
+            return;
+         end if;
+
+         Append_To (Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier =>
+               Reference,
+             Object_Definition =>
+               New_Occurrence_Of (RTE (RE_Object_Ref), Loc)));
+
+         Append_List_To (Statements, New_List (
+           Make_Attribute_Reference (Loc,
+             Prefix         =>
+               New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
+             Attribute_Name => Name_Read,
+             Expressions    => New_List (
+               Stream_Parameter,
+               New_Occurrence_Of (Reference, Loc))),
+
+           Make_Assignment_Statement (Loc,
+             Name       =>
+               Result,
+             Expression =>
+               Unchecked_Convert_To (RACW_Type,
+                 Make_Function_Call (Loc,
+                   Name                   =>
+                     New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
+                   Parameter_Associations => New_List (
+                     New_Occurrence_Of (Reference, Loc),
+                     Build_Stub_Tag (Loc, RACW_Type),
+                     New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
+                     New_Occurrence_Of (Asynchronous_Flag, Loc)))))));
+
+         Set_Declarations (Body_Node, Decls);
+         Append_To (Body_Decls, Body_Node);
+      end Add_RACW_Read_Attribute;
+
+      ---------------------
+      -- Add_RACW_To_Any --
+      ---------------------
+
+      procedure Add_RACW_To_Any
+        (RACW_Type        : Entity_Id;
+         Body_Decls       : List_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (RACW_Type);
+
+         Fnam : constant Entity_Id :=
+                  Make_Defining_Identifier (Loc,
+                    Chars => New_External_Name (Chars (RACW_Type), 'T'));
+
+         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
+
+         Stub_Elements : constant Stub_Structure :=
+                           Get_Stub_Elements (RACW_Type);
+
+         Func_Spec : Node_Id;
+         Func_Decl : Node_Id;
+         Func_Body : Node_Id;
+
+         Decls             : List_Id;
+         Statements        : List_Id;
+         --  Various parts of the subprogram
+
+         RACW_Parameter : constant Entity_Id :=
+                            Make_Defining_Identifier (Loc, Name_R);
+
+         Reference         : constant Entity_Id :=
+                               Make_Defining_Identifier
+                                 (Loc, New_Internal_Name ('R'));
+         Any               : constant Entity_Id :=
+                               Make_Defining_Identifier
+                                 (Loc, New_Internal_Name ('A'));
+
+      begin
+         Func_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name =>
+               Fnam,
+             Parameter_Specifications => New_List (
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier =>
+                   RACW_Parameter,
+                 Parameter_Type =>
+                   New_Occurrence_Of (RACW_Type, Loc))),
+             Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
+
+         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
+         --  entity in the declaration spec, not in the body spec.
+
+         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
+
+         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
+         Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any);
+
+         if No (Body_Decls) then
+            return;
+         end if;
+
+         --  Generate:
+
+         --    R : constant Object_Ref :=
+         --          Get_Reference
+         --            (Address!(RACW),
+         --             "typ",
+         --             Stub_Type'Tag,
+         --             Is_RAS,
+         --             RPC_Receiver'Access);
+         --    A : Any;
+
+         Decls := New_List (
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Reference,
+             Constant_Present    => True,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
+             Expression          =>
+               Make_Function_Call (Loc,
+                 Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
+                 Parameter_Associations => New_List (
+                   Unchecked_Convert_To (RTE (RE_Address),
+                     New_Occurrence_Of (RACW_Parameter, Loc)),
+                   Make_String_Literal (Loc,
+                     Strval => Full_Qualified_Name
+                                 (Etype (Designated_Type (RACW_Type)))),
+                   Build_Stub_Tag (Loc, RACW_Type),
+                   New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
+                   Make_Attribute_Reference (Loc,
+                     Prefix         =>
+                       New_Occurrence_Of
+                         (Defining_Identifier
+                           (Stub_Elements.RPC_Receiver_Decl), Loc),
+                     Attribute_Name => Name_Access)))),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Any,
+             Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc)));
+
+         --  Generate:
+
+         --    Any := TA_ObjRef (Reference);
+         --    Set_TC (Any, RPC_Receiver.Obj_TypeCode);
+         --    return Any;
+
+         Statements := New_List (
+           Make_Assignment_Statement (Loc,
+             Name => New_Occurrence_Of (Any, Loc),
+             Expression =>
+               Make_Function_Call (Loc,
+                 Name => New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc),
+                 Parameter_Associations => New_List (
+                   New_Occurrence_Of (Reference, Loc)))),
+
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
+             Parameter_Associations => New_List (
+               New_Occurrence_Of (Any, Loc),
+               Make_Selected_Component (Loc,
+                 Prefix =>
+                     Defining_Identifier (
+                       Stub_Elements.RPC_Receiver_Decl),
+                 Selector_Name => Name_Obj_TypeCode))),
+
+           Make_Simple_Return_Statement (Loc,
+             Expression => New_Occurrence_Of (Any, Loc)));
+
+         Func_Body :=
+           Make_Subprogram_Body (Loc,
+             Specification              => Copy_Specification (Loc, Func_Spec),
+             Declarations               => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Statements));
+         Append_To (Body_Decls, Func_Body);
+      end Add_RACW_To_Any;
+
+      -----------------------
+      -- Add_RACW_TypeCode --
+      -----------------------
+
+      procedure Add_RACW_TypeCode
+        (Designated_Type  : Entity_Id;
+         RACW_Type        : Entity_Id;
+         Body_Decls       : List_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (RACW_Type);
+
+         Fnam : constant Entity_Id :=
+                  Make_Defining_Identifier (Loc,
+                    Chars => New_External_Name (Chars (RACW_Type), 'Y'));
+
+         Stub_Elements : constant Stub_Structure :=
+                           Stubs_Table.Get (Designated_Type);
+         pragma Assert (Stub_Elements /= Empty_Stub_Structure);
+
+         Func_Spec : Node_Id;
+         Func_Decl : Node_Id;
+         Func_Body : Node_Id;
+
+      begin
+
+         --  The spec for this subprogram has a dummy 'access RACW' argument,
+         --  which serves only for overloading purposes.
+
+         Func_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name => Fnam,
+             Result_Definition  => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
+
+         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
+         --  entity in the declaration spec, not those of the body spec.
+
+         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
+         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
+         Set_Renaming_TSS (RACW_Type, Fnam, TSS_TypeCode);
+
+         if No (Body_Decls) then
+            return;
+         end if;
+
+         Func_Body :=
+           Make_Subprogram_Body (Loc,
+             Specification              => Copy_Specification (Loc, Func_Spec),
+             Declarations               => Empty_List,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => New_List (
+                   Make_Simple_Return_Statement (Loc,
+                     Expression =>
+                       Make_Selected_Component (Loc,
+                         Prefix =>
+                           Defining_Identifier
+                             (Stub_Elements.RPC_Receiver_Decl),
+                         Selector_Name => Name_Obj_TypeCode)))));
+
+         Append_To (Body_Decls, Func_Body);
+      end Add_RACW_TypeCode;
+
+      ------------------------------
+      -- Add_RACW_Write_Attribute --
+      ------------------------------
+
+      procedure Add_RACW_Write_Attribute
+        (RACW_Type        : Entity_Id;
+         Stub_Type        : Entity_Id;
+         Stub_Type_Access : Entity_Id;
+         Body_Decls       : List_Id)
+      is
+         pragma Warnings (Off);
+         pragma Unreferenced (Stub_Type, Stub_Type_Access);
+         pragma Warnings (On);
+
+         Loc : constant Source_Ptr := Sloc (RACW_Type);
+
+         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
+
+         Stub_Elements : constant Stub_Structure :=
+                            Get_Stub_Elements (RACW_Type);
+
+         Body_Node : Node_Id;
+         Proc_Decl : Node_Id;
+         Attr_Decl : Node_Id;
+
+         Statements : constant List_Id := New_List;
+         Pnam : constant Entity_Id :=
+                  Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+
+         function Stream_Parameter return Node_Id;
+         function Object return Node_Id;
+         --  Functions to create occurrences of the formal parameter names
+
+         ------------
+         -- Object --
+         ------------
+
+         function Object return Node_Id is
+         begin
+            return Make_Identifier (Loc, Name_V);
+         end Object;
+
+         ----------------------
+         -- Stream_Parameter --
+         ----------------------
+
+         function Stream_Parameter return Node_Id is
+         begin
+            return Make_Identifier (Loc, Name_S);
+         end Stream_Parameter;
+
+      --  Start of processing for Add_RACW_Write_Attribute
+
+      begin
+         Build_Stream_Procedure
+           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => False);
+
+         Proc_Decl :=
+           Make_Subprogram_Declaration (Loc,
+             Copy_Specification (Loc, Specification (Body_Node)));
+
+         Attr_Decl :=
+           Make_Attribute_Definition_Clause (Loc,
+             Name       => New_Occurrence_Of (RACW_Type, Loc),
+             Chars      => Name_Write,
+             Expression =>
+               New_Occurrence_Of (
+                 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
+
+         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
+         Insert_After (Proc_Decl, Attr_Decl);
+
+         if No (Body_Decls) then
+            return;
+         end if;
+
+         Append_To (Statements,
+           Pack_Node_Into_Stream_Access (Loc,
+             Stream => Stream_Parameter,
+             Object =>
+               Make_Function_Call (Loc,
+                 Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
+                 Parameter_Associations => New_List (
+                   Unchecked_Convert_To (RTE (RE_Address), Object),
+                  Make_String_Literal (Loc,
+                    Strval => Full_Qualified_Name
+                                (Etype (Designated_Type (RACW_Type)))),
+                  Build_Stub_Tag (Loc, RACW_Type),
+                  New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
+                  Make_Attribute_Reference (Loc,
+                    Prefix         =>
+                       New_Occurrence_Of
+                         (Defining_Identifier
+                           (Stub_Elements.RPC_Receiver_Decl), Loc),
+                    Attribute_Name => Name_Access))),
+
+             Etyp => RTE (RE_Object_Ref)));
+
+         Append_To (Body_Decls, Body_Node);
+      end Add_RACW_Write_Attribute;
+
+      -----------------------
+      -- Add_RAST_Features --
+      -----------------------
+
+      procedure Add_RAST_Features
+        (Vis_Decl : Node_Id;
+         RAS_Type : Entity_Id)
+      is
+      begin
+         Add_RAS_Access_TSS (Vis_Decl);
+
+         Add_RAS_From_Any (RAS_Type);
+         Add_RAS_TypeCode (RAS_Type);
+
+         --  To_Any uses TypeCode, and therefore needs to be generated last
+
+         Add_RAS_To_Any   (RAS_Type);
+      end Add_RAST_Features;
+
+      ------------------------
+      -- Add_RAS_Access_TSS --
+      ------------------------
+
+      procedure Add_RAS_Access_TSS (N : Node_Id) is
+         Loc : constant Source_Ptr := Sloc (N);
+
+         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; Fat_Type is the
+         --  corresponding record type.
+
+         RACW_Type : constant Entity_Id :=
+                       Underlying_RACW_Type (Ras_Type);
+
+         Stub_Elements : constant Stub_Structure :=
+                           Get_Stub_Elements (RACW_Type);
+
+         Proc : constant Entity_Id :=
+                  Make_Defining_Identifier (Loc,
+                    Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
+
+         Proc_Spec : Node_Id;
+
+         --  Formal parameters
+
+         Package_Name : constant Entity_Id :=
+                          Make_Defining_Identifier (Loc,
+                            Chars => Name_P);
+
+         --  Target package
+
+         Subp_Id : constant Entity_Id :=
+                     Make_Defining_Identifier (Loc,
+                       Chars => Name_S);
+
+         --  Target subprogram
+
+         Asynch_P : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc,
+                        Chars => Name_Asynchronous);
+         --  Is the procedure to which the 'Access applies asynchronous?
+
+         All_Calls_Remote : constant Entity_Id :=
+                              Make_Defining_Identifier (Loc,
+                                Chars => Name_All_Calls_Remote);
+         --  True if an All_Calls_Remote pragma applies to the RCI unit
+         --  that contains the subprogram.
+
+         --  Common local variables
+
+         Proc_Decls      : List_Id;
+         Proc_Statements : List_Id;
+
+         Subp_Ref : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc, Name_R);
+         --  Reference that designates the target subprogram (returned
+         --  by Get_RAS_Info).
+
+         Is_Local : constant Entity_Id :=
+           Make_Defining_Identifier (Loc, Name_L);
+         Local_Addr : constant Entity_Id :=
+           Make_Defining_Identifier (Loc, Name_A);
+         --  For the call to Get_Local_Address
+
+         --  Additional local variables for the remote case
+
+         Local_Stub : constant Entity_Id :=
+                        Make_Defining_Identifier (Loc,
+                          Chars => New_Internal_Name ('L'));
+
+         Stub_Ptr : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc,
+                        Chars => New_Internal_Name ('S'));
+
+         function Set_Field
+           (Field_Name : Name_Id;
+            Value      : Node_Id) return Node_Id;
+         --  Construct an assignment that sets the named component in the
+         --  returned record
+
+         ---------------
+         -- Set_Field --
+         ---------------
+
+         function Set_Field
+           (Field_Name : Name_Id;
+            Value      : Node_Id) return Node_Id
+         is
+         begin
+            return
+              Make_Assignment_Statement (Loc,
+                Name       =>
+                  Make_Selected_Component (Loc,
+                    Prefix        => Stub_Ptr,
+                    Selector_Name => Field_Name),
+                Expression => Value);
+         end Set_Field;
+
+      --  Start of processing for Add_RAS_Access_TSS
+
+      begin
+         Proc_Decls := New_List (
+
+         --  Common declarations
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Subp_Ref,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Object_Ref), Loc)),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Is_Local,
+             Object_Definition   =>
+               New_Occurrence_Of (Standard_Boolean, Loc)),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Local_Addr,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Address), Loc)),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Local_Stub,
+             Aliased_Present     => True,
+             Object_Definition   =>
+               New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
+
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Stub_Ptr,
+             Object_Definition   =>
+               New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
+             Expression          =>
+               Make_Attribute_Reference (Loc,
+                 Prefix => New_Occurrence_Of (Local_Stub, Loc),
+                 Attribute_Name => Name_Unchecked_Access)));
+
+         Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
+         --  Build_Get_Unique_RP_Call needs this information
+
+         --  Get_RAS_Info (Pkg, Subp, R);
+         --  Obtain a reference to the target subprogram
+
+         Proc_Statements := New_List (
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
+             Parameter_Associations => New_List (
+               New_Occurrence_Of (Package_Name, Loc),
+               New_Occurrence_Of (Subp_Id, Loc),
+               New_Occurrence_Of (Subp_Ref, Loc))),
+
+         --  Get_Local_Address (R, L, A);
+         --  Determine whether the subprogram is local (L), and if so
+         --  obtain the local address of its proxy (A).
+
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
+             Parameter_Associations => New_List (
+               New_Occurrence_Of (Subp_Ref, Loc),
+               New_Occurrence_Of (Is_Local, Loc),
+               New_Occurrence_Of (Local_Addr, Loc))));
+
+         --  Note: Here we assume that the Fat_Type is a record containing just
+         --  an access to a proxy or stub object.
+
+         Append_To (Proc_Statements,
+
+         --  if L then
+
+           Make_Implicit_If_Statement (N,
+             Condition => New_Occurrence_Of (Is_Local, Loc),
+
+             Then_Statements => New_List (
+
+         --     if A.Target = null then
+
+               Make_Implicit_If_Statement (N,
+                 Condition =>
+                   Make_Op_Eq (Loc,
+                     Make_Selected_Component (Loc,
+                       Prefix        =>
+                         Unchecked_Convert_To
+                           (RTE (RE_RAS_Proxy_Type_Access),
+                            New_Occurrence_Of (Local_Addr, Loc)),
+                       Selector_Name => Make_Identifier (Loc, Name_Target)),
+                     Make_Null (Loc)),
+
+                 Then_Statements => New_List (
+
+         --        A.Target := Entity_Of (Ref);
+
+                   Make_Assignment_Statement (Loc,
+                     Name =>
+                       Make_Selected_Component (Loc,
+                         Prefix        =>
+                           Unchecked_Convert_To
+                             (RTE (RE_RAS_Proxy_Type_Access),
+                              New_Occurrence_Of (Local_Addr, Loc)),
+                         Selector_Name => Make_Identifier (Loc, Name_Target)),
+                     Expression =>
+                       Make_Function_Call (Loc,
+                         Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
+                         Parameter_Associations => New_List (
+                           New_Occurrence_Of (Subp_Ref, Loc)))),
+
+         --        Inc_Usage (A.Target);
+
+                   Make_Procedure_Call_Statement (Loc,
+                     Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
+                     Parameter_Associations => New_List (
+                       Make_Selected_Component (Loc,
+                         Prefix        =>
+                           Unchecked_Convert_To
+                             (RTE (RE_RAS_Proxy_Type_Access),
+                              New_Occurrence_Of (Local_Addr, Loc)),
+                         Selector_Name =>
+                           Make_Identifier (Loc, Name_Target)))))),
+
+         --     end if;
+         --     if not All_Calls_Remote then
+         --        return Fat_Type!(A);
+         --     end if;
+
+                 Make_Implicit_If_Statement (N,
+                   Condition =>
+                     Make_Op_Not (Loc,
+                       Right_Opnd =>
+                         New_Occurrence_Of (All_Calls_Remote, Loc)),
+
+                   Then_Statements => New_List (
+                     Make_Simple_Return_Statement (Loc,
+                     Expression =>
+                       Unchecked_Convert_To
+                         (Fat_Type, New_Occurrence_Of (Local_Addr, Loc))))))));
+
+         Append_List_To (Proc_Statements, New_List (
+
+         --  Stub.Target := Entity_Of (Ref);
+
+           Set_Field (Name_Target,
+             Make_Function_Call (Loc,
+               Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
+               Parameter_Associations => New_List (
+                 New_Occurrence_Of (Subp_Ref, Loc)))),
+
+         --  Inc_Usage (Stub.Target);
+
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
+             Parameter_Associations => New_List (
+               Make_Selected_Component (Loc,
+                 Prefix        => Stub_Ptr,
+                 Selector_Name => Name_Target))),
+
+         --  E.4.1(9) A remote call is asynchronous if it is a call to
+         --  a procedure, or a call through a value of an access-to-procedure
+         --  type, to which a pragma Asynchronous applies.
+
+         --    Parameter Asynch_P is true when the procedure is asynchronous;
+         --    Expression Asynch_T is true when the type is asynchronous.
+
+           Set_Field (Name_Asynchronous,
+             Make_Or_Else (Loc,
+               Left_Opnd  => New_Occurrence_Of (Asynch_P, Loc),
+               Right_Opnd =>
+                 New_Occurrence_Of
+                   (Boolean_Literals (Is_Asynchronous (Ras_Type)), Loc)))));
+
+         Append_List_To (Proc_Statements,
+           Build_Get_Unique_RP_Call (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
+
+         Append_To (Proc_Statements,
+           Make_Simple_Return_Statement (Loc,
+             Expression =>
+               Unchecked_Convert_To (Fat_Type,
+                 New_Occurrence_Of (Stub_Ptr, Loc))));
+
+         Proc_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name       => Proc,
+             Parameter_Specifications => New_List (
+               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_String, Loc)),
+
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => Asynch_P,
+                 Parameter_Type      =>
+                   New_Occurrence_Of (Standard_Boolean, Loc)),
+
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => All_Calls_Remote,
+                 Parameter_Type      =>
+                   New_Occurrence_Of (Standard_Boolean, Loc))),
+
+            Result_Definition =>
+              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, Fat_Type);
+
+         Discard_Node (
+           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_TSS;
+
+      ----------------------
+      -- Add_RAS_From_Any --
+      ----------------------
+
+      procedure Add_RAS_From_Any (RAS_Type : Entity_Id) is
+         Loc : constant Source_Ptr := Sloc (RAS_Type);
+
+         Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
+                  Make_TSS_Name (RAS_Type, TSS_From_Any));
+
+         Func_Spec : Node_Id;
+
+         Statements : List_Id;
+
+         Any_Parameter : constant Entity_Id :=
+                           Make_Defining_Identifier (Loc, Name_A);
+
+      begin
+         Statements := New_List (
+           Make_Simple_Return_Statement (Loc,
+             Expression =>
+               Make_Aggregate (Loc,
+                 Component_Associations => New_List (
+                   Make_Component_Association (Loc,
+                     Choices => New_List (
+                       Make_Identifier (Loc, Name_Ras)),
+                     Expression =>
+                       PolyORB_Support.Helpers.Build_From_Any_Call (
+                         Underlying_RACW_Type (RAS_Type),
+                         New_Occurrence_Of (Any_Parameter, Loc),
+                         No_List))))));
+
+         Func_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name       => Fnam,
+             Parameter_Specifications => New_List (
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => Any_Parameter,
+                 Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))),
+             Result_Definition => New_Occurrence_Of (RAS_Type, Loc));
+
+         Discard_Node (
+           Make_Subprogram_Body (Loc,
+             Specification              => Func_Spec,
+             Declarations               => No_List,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Statements)));
+         Set_TSS (RAS_Type, Fnam);
+      end Add_RAS_From_Any;
 
-      Target_Partition :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+      --------------------
+      -- Add_RAS_To_Any --
+      --------------------
 
-      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.
+      procedure Add_RAS_To_Any (RAS_Type : Entity_Id) is
+         Loc : constant Source_Ptr := Sloc (RAS_Type);
 
-      if Is_Function then
-         Asynchronous := Empty;
+         Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
+                  Make_TSS_Name (RAS_Type, TSS_To_Any));
 
-      else
-         Asynchronous :=
-           Make_Selected_Component (Loc,
-             Prefix        =>
-               New_Occurrence_Of (Pointer, Loc),
-             Selector_Name =>
-               Make_Identifier (Loc, Name_Async));
+         Decls      : List_Id;
+         Statements : List_Id;
 
-      end if;
+         Func_Spec : Node_Id;
 
-      if Present (Parameter_Specifications (Type_Def)) then
-         Current_Parameter := First (Parameter_Specifications (Type_Def));
+         Any            : constant Entity_Id :=
+                            Make_Defining_Identifier (Loc,
+                              Chars => New_Internal_Name ('A'));
+         RAS_Parameter  : constant Entity_Id :=
+                            Make_Defining_Identifier (Loc,
+                              Chars => New_Internal_Name ('R'));
+         RACW_Parameter : constant Node_Id :=
+                            Make_Selected_Component (Loc,
+                              Prefix        => RAS_Parameter,
+                              Selector_Name => Name_Ras);
 
-         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_Copy_Tree (Parameter_Type (Current_Parameter)),
-                    Expression        =>
-                      New_Copy_Tree (Expression (Current_Parameter))));
-
-            Append_To (Param_Assoc,
-              Make_Identifier (Loc,
-                Chars => Chars (Defining_Identifier (Current_Parameter))));
+      begin
+         --  Object declarations
 
-            Next (Current_Parameter);
-         end loop;
-      end if;
+         Set_Etype (RACW_Parameter, Underlying_RACW_Type (RAS_Type));
+         Decls := New_List (
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Any,
+             Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc),
+             Expression          =>
+               PolyORB_Support.Helpers.Build_To_Any_Call
+                 (RACW_Parameter, No_List)));
 
-      Proc :=
-        Make_Defining_Identifier (Loc,
-          Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Dereference));
+         Statements := New_List (
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
+             Parameter_Associations => New_List (
+               New_Occurrence_Of (Any, Loc),
+               PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
+                 RAS_Type, Decls))),
 
-      if Is_Function then
-         Proc_Spec :=
+           Make_Simple_Return_Statement (Loc,
+             Expression => New_Occurrence_Of (Any, Loc)));
+
+         Func_Spec :=
            Make_Function_Specification (Loc,
-             Defining_Unit_Name       => Proc,
-             Parameter_Specifications => Param_Specs,
-             Subtype_Mark             =>
+             Defining_Unit_Name => Fnam,
+             Parameter_Specifications => New_List (
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => RAS_Parameter,
+                 Parameter_Type      => New_Occurrence_Of (RAS_Type, Loc))),
+             Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
+
+         Discard_Node (
+           Make_Subprogram_Body (Loc,
+             Specification              => Func_Spec,
+             Declarations               => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Statements)));
+         Set_TSS (RAS_Type, Fnam);
+      end Add_RAS_To_Any;
+
+      ----------------------
+      -- Add_RAS_TypeCode --
+      ----------------------
+
+      procedure Add_RAS_TypeCode (RAS_Type : Entity_Id) is
+         Loc : constant Source_Ptr := Sloc (RAS_Type);
+
+         Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
+                  Make_TSS_Name (RAS_Type, TSS_TypeCode));
+
+         Func_Spec      : Node_Id;
+         Decls          : constant List_Id := New_List;
+         Name_String    : String_Id;
+         Repo_Id_String : String_Id;
+
+      begin
+         Func_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name => Fnam,
+             Result_Definition  => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
+
+         PolyORB_Support.Helpers.Build_Name_And_Repository_Id
+           (RAS_Type, Name_Str => Name_String, Repo_Id_Str => Repo_Id_String);
+
+         Discard_Node (
+           Make_Subprogram_Body (Loc,
+             Specification              => Func_Spec,
+             Declarations               => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => New_List (
+                   Make_Simple_Return_Statement (Loc,
+                     Expression =>
+                       Make_Function_Call (Loc,
+                         Name => New_Occurrence_Of (RTE (RE_TC_Build), Loc),
+                         Parameter_Associations => New_List (
+                           New_Occurrence_Of (RTE (RE_TC_Object), Loc),
+                           Make_Aggregate (Loc,
+                             Expressions =>
+                               New_List (
+                                 Make_Function_Call (Loc,
+                                   Name =>
+                                     New_Occurrence_Of
+                                       (RTE (RE_TA_String), Loc),
+                                   Parameter_Associations => New_List (
+                                     Make_String_Literal (Loc, Name_String))),
+                                 Make_Function_Call (Loc,
+                                   Name =>
+                                     New_Occurrence_Of
+                                       (RTE (RE_TA_String), Loc),
+                                   Parameter_Associations => New_List (
+                                     Make_String_Literal (Loc,
+                                       Strval => Repo_Id_String))))))))))));
+         Set_TSS (RAS_Type, Fnam);
+      end Add_RAS_TypeCode;
+
+      -----------------------------------------
+      -- Add_Receiving_Stubs_To_Declarations --
+      -----------------------------------------
+
+      procedure Add_Receiving_Stubs_To_Declarations
+        (Pkg_Spec : Node_Id;
+         Decls    : List_Id;
+         Stmts    : List_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (Pkg_Spec);
+
+         Pkg_RPC_Receiver            : constant Entity_Id :=
+                                         Make_Defining_Identifier (Loc,
+                                           New_Internal_Name ('H'));
+         Pkg_RPC_Receiver_Object     : Node_Id;
+         Pkg_RPC_Receiver_Body       : Node_Id;
+         Pkg_RPC_Receiver_Decls      : List_Id;
+         Pkg_RPC_Receiver_Statements : List_Id;
+
+         Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
+         --  A Pkg_RPC_Receiver is built to decode the request
+
+         Request : Node_Id;
+         --  Request object received from neutral layer
+
+         Subp_Id : Entity_Id;
+         --  Subprogram identifier as received from the neutral
+         --  distribution core.
+
+         Subp_Index : Entity_Id;
+         --  Internal index as determined by matching either the method name
+         --  from the request structure, or the local subprogram address (in
+         --  case of a RAS).
+
+         Is_Local : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc,
+                        Chars => New_Internal_Name ('L'));
+
+         Local_Address : constant Entity_Id :=
+                           Make_Defining_Identifier (Loc,
+                             Chars => New_Internal_Name ('A'));
+         --  Address of a local subprogram designated by a reference
+         --  corresponding to a RAS.
+
+         Dispatch_On_Address : constant List_Id := New_List;
+         Dispatch_On_Name    : constant List_Id := New_List;
+
+         Current_Declaration       : Node_Id;
+         Current_Stubs             : Node_Id;
+         Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
+
+         Subp_Info_Array : constant Entity_Id :=
+                             Make_Defining_Identifier (Loc,
+                               Chars => New_Internal_Name ('I'));
+
+         Subp_Info_List : constant List_Id := New_List;
+
+         Register_Pkg_Actuals : constant List_Id := New_List;
+
+         All_Calls_Remote_E  : Entity_Id;
+
+         procedure Append_Stubs_To
+           (RPC_Receiver_Cases : List_Id;
+            Declaration        : Node_Id;
+            Stubs              : Node_Id;
+            Subp_Number        : Int;
+            Subp_Dist_Name     : Entity_Id;
+            Subp_Proxy_Addr    : Entity_Id);
+         --  Add one case to the specified RPC receiver case list associating
+         --  Subprogram_Number with the subprogram declared by Declaration, for
+         --  which we have receiving stubs in Stubs. Subp_Number is an internal
+         --  subprogram index. Subp_Dist_Name is the string used to call the
+         --  subprogram by name, and Subp_Dist_Addr is the address of the proxy
+         --  object, used in the context of calls through remote
+         --  access-to-subprogram types.
+
+         ---------------------
+         -- Append_Stubs_To --
+         ---------------------
+
+         procedure Append_Stubs_To
+           (RPC_Receiver_Cases : List_Id;
+            Declaration        : Node_Id;
+            Stubs              : Node_Id;
+            Subp_Number        : Int;
+            Subp_Dist_Name     : Entity_Id;
+            Subp_Proxy_Addr    : Entity_Id)
+         is
+            Case_Stmts : List_Id;
+         begin
+            Case_Stmts := New_List (
+              Make_Procedure_Call_Statement (Loc,
+                Name                   =>
+                  New_Occurrence_Of (
+                    Defining_Entity (Stubs), Loc),
+                Parameter_Associations =>
+                  New_List (New_Occurrence_Of (Request, Loc))));
+
+            if Nkind (Specification (Declaration)) = N_Function_Specification
+              or else not
+                Is_Asynchronous (Defining_Entity (Specification (Declaration)))
+            then
+               Append_To (Case_Stmts, Make_Simple_Return_Statement (Loc));
+            end if;
+
+            Append_To (RPC_Receiver_Cases,
+              Make_Case_Statement_Alternative (Loc,
+                Discrete_Choices =>
+                   New_List (Make_Integer_Literal (Loc, Subp_Number)),
+                Statements       => Case_Stmts));
+
+            Append_To (Dispatch_On_Name,
+              Make_Elsif_Part (Loc,
+                Condition =>
+                  Make_Function_Call (Loc,
+                    Name =>
+                      New_Occurrence_Of (RTE (RE_Caseless_String_Eq), Loc),
+                    Parameter_Associations => New_List (
+                      New_Occurrence_Of (Subp_Id, Loc),
+                      New_Occurrence_Of (Subp_Dist_Name, Loc))),
+
+                Then_Statements => New_List (
+                  Make_Assignment_Statement (Loc,
+                    New_Occurrence_Of (Subp_Index, Loc),
+                    Make_Integer_Literal (Loc, Subp_Number)))));
+
+            Append_To (Dispatch_On_Address,
+              Make_Elsif_Part (Loc,
+                Condition =>
+                  Make_Op_Eq (Loc,
+                    Left_Opnd  => New_Occurrence_Of (Local_Address, Loc),
+                    Right_Opnd => New_Occurrence_Of (Subp_Proxy_Addr, Loc)),
+
+                Then_Statements => New_List (
+                  Make_Assignment_Statement (Loc,
+                    New_Occurrence_Of (Subp_Index, Loc),
+                    Make_Integer_Literal (Loc, Subp_Number)))));
+         end Append_Stubs_To;
+
+      --  Start of processing for Add_Receiving_Stubs_To_Declarations
+
+      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 each 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.
+
+         Build_RPC_Receiver_Body (
+           RPC_Receiver => Pkg_RPC_Receiver,
+           Request      => Request,
+           Subp_Id      => Subp_Id,
+           Subp_Index   => Subp_Index,
+           Stmts        => Pkg_RPC_Receiver_Statements,
+           Decl         => Pkg_RPC_Receiver_Body);
+         Pkg_RPC_Receiver_Decls := Declarations (Pkg_RPC_Receiver_Body);
+
+         --  Extract local address information from the target reference:
+         --  if non-null, that means that this is a reference that denotes
+         --  one particular operation, and hence that the operation name
+         --  must not be taken into account for dispatching.
+
+         Append_To (Pkg_RPC_Receiver_Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Is_Local,
+             Object_Definition   =>
+               New_Occurrence_Of (Standard_Boolean, Loc)));
+
+         Append_To (Pkg_RPC_Receiver_Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Local_Address,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Address), Loc)));
+
+         Append_To (Pkg_RPC_Receiver_Statements,
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
+             Parameter_Associations => New_List (
+               Make_Selected_Component (Loc,
+                 Prefix        => Request,
+                 Selector_Name => Name_Target),
+               New_Occurrence_Of (Is_Local, Loc),
+               New_Occurrence_Of (Local_Address, 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.
+
+         All_Calls_Remote_E := Boolean_Literals (
+           Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
+
+         Overload_Counter_Table.Reset;
+         Reserve_NamingContext_Methods;
+
+         Current_Declaration := First (Visible_Declarations (Pkg_Spec));
+         while Present (Current_Declaration) loop
+            if Nkind (Current_Declaration) = N_Subprogram_Declaration
+              and then Comes_From_Source (Current_Declaration)
+            then
+               declare
+                  Loc : constant Source_Ptr := Sloc (Current_Declaration);
+                  --  While specifically processing Current_Declaration, use
+                  --  its Sloc as the location of all generated nodes.
+
+                  Subp_Def : constant Entity_Id :=
+                               Defining_Unit_Name
+                                 (Specification (Current_Declaration));
+
+                  Subp_Val : String_Id;
+
+                  Subp_Dist_Name : constant Entity_Id :=
+                                     Make_Defining_Identifier (Loc,
+                                       Chars =>
+                                         New_External_Name
+                                           (Related_Id   => Chars (Subp_Def),
+                                            Suffix       => 'D',
+                                            Suffix_Index => -1));
+
+                  Proxy_Object_Addr : Entity_Id;
+
+               begin
+                  --  Build receiving stub
+
+                  Current_Stubs :=
+                    Build_Subprogram_Receiving_Stubs
+                      (Vis_Decl     => Current_Declaration,
+                       Asynchronous =>
+                         Nkind (Specification (Current_Declaration)) =
+                             N_Procedure_Specification
+                           and then Is_Asynchronous (Subp_Def));
+
+                  Append_To (Decls, Current_Stubs);
+                  Analyze (Current_Stubs);
+
+                  --  Build RAS proxy
+
+                  Add_RAS_Proxy_And_Analyze (Decls,
+                    Vis_Decl           => Current_Declaration,
+                    All_Calls_Remote_E => All_Calls_Remote_E,
+                    Proxy_Object_Addr  => Proxy_Object_Addr);
+
+                  --  Compute distribution identifier
+
+                  Assign_Subprogram_Identifier
+                    (Subp_Def,
+                     Current_Subprogram_Number,
+                     Subp_Val);
+
+                  pragma Assert
+                    (Current_Subprogram_Number = Get_Subprogram_Id (Subp_Def));
+
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Subp_Dist_Name,
+                      Constant_Present    => True,
+                      Object_Definition   =>
+                        New_Occurrence_Of (Standard_String, Loc),
+                      Expression          =>
+                        Make_String_Literal (Loc, Subp_Val)));
+                  Analyze (Last (Decls));
+
+                  --  Add subprogram descriptor (RCI_Subp_Info) to the
+                  --  subprograms table for this receiver. The aggregate
+                  --  below must be kept consistent with the declaration
+                  --  of type RCI_Subp_Info in System.Partition_Interface.
+
+                  Append_To (Subp_Info_List,
+                    Make_Component_Association (Loc,
+                      Choices => New_List (
+                        Make_Integer_Literal (Loc, Current_Subprogram_Number)),
+
+                      Expression =>
+                        Make_Aggregate (Loc,
+                          Expressions => New_List (
+                            Make_Attribute_Reference (Loc,
+                              Prefix =>
+                                New_Occurrence_Of (Subp_Dist_Name, Loc),
+                              Attribute_Name => Name_Address),
+
+                            Make_Attribute_Reference (Loc,
+                              Prefix         =>
+                                New_Occurrence_Of (Subp_Dist_Name, Loc),
+                              Attribute_Name => Name_Length),
+
+                            New_Occurrence_Of (Proxy_Object_Addr, Loc)))));
+
+                  Append_Stubs_To (Pkg_RPC_Receiver_Cases,
+                    Declaration     => Current_Declaration,
+                    Stubs           => Current_Stubs,
+                    Subp_Number     => Current_Subprogram_Number,
+                    Subp_Dist_Name  => Subp_Dist_Name,
+                    Subp_Proxy_Addr => Proxy_Object_Addr);
+               end;
+
+               Current_Subprogram_Number := Current_Subprogram_Number + 1;
+            end if;
+
+            Next (Current_Declaration);
+         end loop;
+
+         Append_To (Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Subp_Info_Array,
+             Constant_Present    => True,
+             Aliased_Present     => True,
+             Object_Definition   =>
+               Make_Subtype_Indication (Loc,
+                 Subtype_Mark =>
+                   New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
+                 Constraint =>
+                   Make_Index_Or_Discriminant_Constraint (Loc,
+                     New_List (
+                       Make_Range (Loc,
+                         Low_Bound  =>
+                           Make_Integer_Literal (Loc,
+                             Intval => First_RCI_Subprogram_Id),
+                         High_Bound =>
+                           Make_Integer_Literal (Loc,
+                             Intval =>
+                               First_RCI_Subprogram_Id
+                               + List_Length (Subp_Info_List) - 1)))))));
+
+         if Present (First (Subp_Info_List)) then
+            Set_Expression (Last (Decls),
+              Make_Aggregate (Loc,
+                Component_Associations => Subp_Info_List));
+
+            --  Generate the dispatch statement to determine the subprogram id
+            --  of the called subprogram.
+
+            --  We first test whether the reference that was used to make the
+            --  call was the base RCI reference (in which case Local_Address is
+            --  zero, and the method identifier from the request must be used
+            --  to determine which subprogram is called) or a reference
+            --  identifying one particular subprogram (in which case
+            --  Local_Address is the address of that subprogram, and the
+            --  method name from the request is ignored). The latter occurs
+            --  for the case of a call through a remote access-to-subprogram.
+
+            --  In each case, cascaded elsifs are used to determine the proper
+            --  subprogram index. Using hash tables might be more efficient.
+
+            Append_To (Pkg_RPC_Receiver_Statements,
+              Make_Implicit_If_Statement (Pkg_Spec,
+                Condition =>
+                  Make_Op_Ne (Loc,
+                    Left_Opnd  => New_Occurrence_Of (Local_Address, Loc),
+                    Right_Opnd => New_Occurrence_Of
+                                    (RTE (RE_Null_Address), Loc)),
+
+                Then_Statements => New_List (
+                  Make_Implicit_If_Statement (Pkg_Spec,
+                    Condition       => New_Occurrence_Of (Standard_False, Loc),
+                    Then_Statements => New_List (
+                      Make_Null_Statement (Loc)),
+                    Elsif_Parts     => Dispatch_On_Address)),
+
+                Else_Statements => New_List (
+                  Make_Implicit_If_Statement (Pkg_Spec,
+                    Condition       => New_Occurrence_Of (Standard_False, Loc),
+                    Then_Statements => New_List (Make_Null_Statement (Loc)),
+                    Elsif_Parts     => Dispatch_On_Name))));
+
+         else
+            --  For a degenerate RCI with no visible subprograms,
+            --  Subp_Info_List has zero length, and the declaration is for an
+            --  empty array, in which case no initialization aggregate must be
+            --  generated. We do not generate a Dispatch_Statement either.
+
+            --  No initialization provided: remove CONSTANT so that the
+            --  declaration is not an incomplete deferred constant.
+
+            Set_Constant_Present (Last (Decls), False);
+         end if;
+
+         --  Analyze Subp_Info_Array declaration
+
+         Analyze (Last (Decls));
+
+         --  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_Index, Loc),
+             Alternatives => Pkg_RPC_Receiver_Cases));
+
+         --  Pkg_RPC_Receiver body is now complete: insert it into the tree and
+         --  analyze it.
+
+         Append_To (Decls, Pkg_RPC_Receiver_Body);
+         Analyze (Last (Decls));
+
+         Pkg_RPC_Receiver_Object :=
+           Make_Object_Declaration (Loc,
+             Defining_Identifier =>
+               Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
+             Aliased_Present     => True,
+             Object_Definition   => New_Occurrence_Of (RTE (RE_Servant), Loc));
+         Append_To (Decls, Pkg_RPC_Receiver_Object);
+         Analyze (Last (Decls));
+
+         Get_Library_Unit_Name_String (Pkg_Spec);
+
+         --  Name
+
+         Append_To (Register_Pkg_Actuals,
+           Make_String_Literal (Loc,
+             Strval => String_From_Name_Buffer));
+
+         --  Version
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         =>
+               New_Occurrence_Of
+                 (Defining_Entity (Pkg_Spec), Loc),
+             Attribute_Name => Name_Version));
+
+         --  Handler
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix          =>
+               New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
+             Attribute_Name  => Name_Access));
+
+         --  Receiver
+
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         =>
                New_Occurrence_Of (
-                 Entity (Subtype_Mark (Spec)), Loc));
+                 Defining_Identifier (Pkg_RPC_Receiver_Object), Loc),
+             Attribute_Name => Name_Access));
 
-         Set_Ekind (Proc, E_Function);
+         --  Subp_Info
 
-         Set_Etype (Proc,
-           New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Address));
 
-      else
-         Proc_Spec :=
-           Make_Procedure_Specification (Loc,
-             Defining_Unit_Name       => Proc,
-             Parameter_Specifications => Param_Specs);
+         --  Subp_Info_Len
 
-         Set_Ekind (Proc, E_Procedure);
-         Set_Etype (Proc, Standard_Void_Type);
-      end if;
+         Append_To (Register_Pkg_Actuals,
+           Make_Attribute_Reference (Loc,
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Length));
 
-      --  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))));
+         --  Is_All_Calls_Remote
 
-      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)));
+         Append_To (Register_Pkg_Actuals,
+           New_Occurrence_Of (All_Calls_Remote_E, Loc));
 
-      else
-         Append_To (Direct_Statements,
+         --  ???
+
+         Append_To (Stmts,
            Make_Procedure_Call_Statement (Loc,
              Name                   =>
-               Make_Explicit_Dereference (Loc,
-                 Prefix => Converted_Ras),
-             Parameter_Associations => Param_Assoc));
-      end if;
+               New_Occurrence_Of (RTE (RE_Register_Pkg_Receiving_Stub), Loc),
+             Parameter_Associations => Register_Pkg_Actuals));
+         Analyze (Last (Stmts));
+      end Add_Receiving_Stubs_To_Declarations;
+
+      ---------------------------------
+      -- Build_General_Calling_Stubs --
+      ---------------------------------
+
+      procedure Build_General_Calling_Stubs
+        (Decls                     : List_Id;
+         Statements                : List_Id;
+         Target_Object             : 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;
+         Stub_Type                 : Entity_Id := Empty;
+         RACW_Type                 : Entity_Id := Empty;
+         Nod                       : Node_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (Nod);
 
-      Prepend_To (Param_Specs,
-        Make_Parameter_Specification (Loc,
-          Defining_Identifier => Pointer,
-          In_Present          => True,
-          Parameter_Type      =>
-            New_Occurrence_Of (Fat_Type, Loc)));
+         Arguments : Node_Id;
+         --  Name of the named values list used to transmit parameters
+         --  to the remote package
 
-      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)))),
+         Request : Node_Id;
+         --  The request object constructed by these stubs
 
-          Then_Statements =>
-            Direct_Statements,
+         Result : Node_Id;
+         --  Name of the result named value (in non-APC cases) which get the
+         --  result of the remote subprogram.
 
-          Else_Statements => New_List (
-            Make_Block_Statement (Loc,
-              Declarations               => Inner_Decls,
-              Handled_Statement_Sequence =>
-                Make_Handled_Sequence_Of_Statements (Loc,
-                  Statements => Inner_Statements)))));
+         Result_TC : Node_Id;
+         --  Typecode expression for the result of the request (void
+         --  typecode for procedures).
+
+         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_P : Node_Id;
+         --  A Boolean expression indicating whether this call is asynchronous
+
+         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.
+
+         After_Statements : constant List_Id := New_List;
+         --  Statements to be executed after call returns (to assign
+         --  in out or out parameter values).
+
+         Etyp : Entity_Id;
+         --  The type of the formal parameter being processed
+
+         Is_Controlling_Formal         : Boolean;
+         Is_First_Controlling_Formal   : Boolean;
+         First_Controlling_Formal_Seen : Boolean := False;
+         --  Controlling formal parameters of distributed object primitives
+         --  require special handling, and the first such parameter needs even
+         --  more special handling.
+
+      begin
+         --  ??? document general form of stub subprograms for the PolyORB case
+         Request := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+
+         Append_To (Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Request,
+             Aliased_Present     => False,
+             Object_Definition   =>
+                 New_Occurrence_Of (RTE (RE_Request_Access), Loc)));
+
+         Result :=
+           Make_Defining_Identifier (Loc,
+             Chars => New_Internal_Name ('R'));
+
+         if Is_Function then
+            Result_TC :=
+              PolyORB_Support.Helpers.Build_TypeCode_Call
+                (Loc, Etype (Result_Definition (Spec)), Decls);
+         else
+            Result_TC := New_Occurrence_Of (RTE (RE_TC_Void), Loc);
+         end if;
+
+         Append_To (Decls,
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Result,
+             Aliased_Present     => False,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_NamedValue), Loc),
+             Expression =>
+               Make_Aggregate (Loc,
+                 Component_Associations => New_List (
+                   Make_Component_Association (Loc,
+                     Choices    => New_List (Make_Identifier (Loc, Name_Name)),
+                     Expression =>
+                       New_Occurrence_Of (RTE (RE_Result_Name), Loc)),
+                   Make_Component_Association (Loc,
+                     Choices => New_List (
+                       Make_Identifier (Loc, Name_Argument)),
+                     Expression =>
+                       Make_Function_Call (Loc,
+                         Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
+                         Parameter_Associations => New_List (Result_TC))),
+                   Make_Component_Association (Loc,
+                     Choices    => New_List (
+                       Make_Identifier (Loc, Name_Arg_Modes)),
+                     Expression => Make_Integer_Literal (Loc, 0))))));
+
+         if not Is_Known_Asynchronous then
+            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
+            Exception_Return_Parameter := Empty;
+         end if;
+
+         --  Initialize and fill in arguments list
+
+         Arguments :=
+           Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+         Declare_Create_NVList (Loc, Arguments, Decls, Statements);
+
+         Current_Parameter := First (Ordered_Parameters_List);
+         while Present (Current_Parameter) loop
+            if Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) then
+               Is_Controlling_Formal := True;
+               Is_First_Controlling_Formal :=
+                 not First_Controlling_Formal_Seen;
+               First_Controlling_Formal_Seen := True;
+
+            else
+               Is_Controlling_Formal := False;
+               Is_First_Controlling_Formal := False;
+            end if;
+
+            if Is_Controlling_Formal then
+
+               --  For a controlling formal argument, we send its reference
+
+               Etyp := RACW_Type;
+
+            else
+               Etyp := Etype (Parameter_Type (Current_Parameter));
+            end if;
+
+            --  The first controlling formal parameter is treated specially:
+            --  it is used to set the target object of the call.
+
+            if not Is_First_Controlling_Formal then
+               declare
+                  Constrained : constant Boolean :=
+                                  Is_Constrained (Etyp)
+                                    or else Is_Elementary_Type (Etyp);
+
+                  Any : constant Entity_Id :=
+                          Make_Defining_Identifier (Loc,
+                            New_Internal_Name ('A'));
+
+                  Actual_Parameter : Node_Id :=
+                                       New_Occurrence_Of (
+                                         Defining_Identifier (
+                                           Current_Parameter), Loc);
+
+                  Expr : Node_Id;
+
+               begin
+                  if Is_Controlling_Formal then
+
+                     --  For a controlling formal parameter (other than the
+                     --  first one), use the corresponding RACW. If the
+                     --  parameter is not an anonymous access parameter, that
+                     --  involves taking its 'Unrestricted_Access.
+
+                     if Nkind (Parameter_Type (Current_Parameter))
+                       = N_Access_Definition
+                     then
+                        Actual_Parameter := OK_Convert_To
+                          (Etyp, Actual_Parameter);
+                     else
+                        Actual_Parameter := OK_Convert_To (Etyp,
+                          Make_Attribute_Reference (Loc,
+                            Prefix         => Actual_Parameter,
+                            Attribute_Name => Name_Unrestricted_Access));
+                     end if;
+
+                  end if;
+
+                  if In_Present (Current_Parameter)
+                    or else not Out_Present (Current_Parameter)
+                    or else not Constrained
+                    or else Is_Controlling_Formal
+                  then
+                     --  The parameter has an input value, is constrained at
+                     --  runtime by an input value, or is a controlling formal
+                     --  parameter (always passed as a reference) other than
+                     --  the first one.
+
+                     Expr := PolyORB_Support.Helpers.Build_To_Any_Call
+                               (Actual_Parameter, Decls);
+
+                  else
+                     Expr := Make_Function_Call (Loc,
+                       Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
+                       Parameter_Associations => New_List (
+                         PolyORB_Support.Helpers.Build_TypeCode_Call
+                           (Loc, Etyp, Decls)));
+                  end if;
+
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Any,
+                      Aliased_Present     => False,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_Any), Loc),
+                      Expression          => Expr));
+
+                  Append_To (Statements,
+                    Add_Parameter_To_NVList (Loc,
+                      Parameter   => Current_Parameter,
+                      NVList      => Arguments,
+                      Constrained => Constrained,
+                      Any         => Any));
+
+                  if Out_Present (Current_Parameter)
+                    and then not Is_Controlling_Formal
+                  then
+                     Append_To (After_Statements,
+                       Make_Assignment_Statement (Loc,
+                         Name =>
+                           New_Occurrence_Of (
+                             Defining_Identifier (Current_Parameter), Loc),
+                           Expression =>
+                             PolyORB_Support.Helpers.Build_From_Any_Call
+                               (Etype (Parameter_Type (Current_Parameter)),
+                                New_Occurrence_Of (Any, Loc),
+                                Decls)));
+
+                  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.
 
-      Discard_Node (
-        Make_Subprogram_Body (Loc,
-          Specification              => Proc_Spec,
-          Declarations               => Proc_Decls,
-          Handled_Statement_Sequence =>
-            Make_Handled_Sequence_Of_Statements (Loc,
-              Statements => Proc_Statements)));
+               declare
+                  Extra_Any_Parameter : constant Entity_Id :=
+                                          Make_Defining_Identifier
+                                            (Loc, New_Internal_Name ('P'));
 
-      Set_TSS (Fat_Type, Defining_Unit_Name (Proc_Spec));
+                  Parameter_Exp : constant Node_Id :=
+                     Make_Attribute_Reference (Loc,
+                       Prefix         => New_Occurrence_Of (
+                         Defining_Identifier (Current_Parameter), Loc),
+                       Attribute_Name => Name_Constrained);
 
-   end Add_RAS_Dereference_Attribute;
+               begin
+                  Set_Etype (Parameter_Exp, Etype (Standard_Boolean));
 
-   -----------------------
-   -- Add_RAST_Features --
-   -----------------------
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Extra_Any_Parameter,
+                      Aliased_Present     => False,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_Any), Loc),
+                      Expression          =>
+                        PolyORB_Support.Helpers.Build_To_Any_Call
+                          (Parameter_Exp, Decls)));
 
-   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 ???
+                  Append_To (Extra_Formal_Statements,
+                    Add_Parameter_To_NVList (Loc,
+                      Parameter   => Extra_Any_Parameter,
+                      NVList      => Arguments,
+                      Constrained => True,
+                      Any         => Extra_Any_Parameter));
+               end;
+            end if;
 
-      if Present (TSS (Equivalent_Type (Defining_Identifier (Vis_Decl)),
-                       TSS_RAS_Access))
-      then
-         return;
-      end if;
+            Next (Current_Parameter);
+         end loop;
 
-      Add_RAS_Dereference_Attribute (Vis_Decl);
-      Add_RAS_Access_Attribute (Vis_Decl);
-   end Add_RAST_Features;
+         --  Append the formal statements list to the statements
 
-   -----------------------------------------
-   -- Add_Receiving_Stubs_To_Declarations --
-   -----------------------------------------
+         Append_List_To (Statements, Extra_Formal_Statements);
 
-   procedure Add_Receiving_Stubs_To_Declarations
-     (Pkg_Spec : in Node_Id;
-      Decls    : in List_Id)
-   is
-      Loc : constant Source_Ptr := Sloc (Pkg_Spec);
+         Append_To (Statements,
+           Make_Procedure_Call_Statement (Loc,
+             Name =>
+               New_Occurrence_Of (RTE (RE_Request_Create), Loc),
 
-      Stream_Parameter : Node_Id;
-      Result_Parameter : Node_Id;
+             Parameter_Associations => New_List (
+               Target_Object,
+               Subprogram_Id,
+               New_Occurrence_Of (Arguments, Loc),
+               New_Occurrence_Of (Result, Loc),
+               New_Occurrence_Of (RTE (RE_Nil_Exc_List), Loc))));
 
-      Pkg_RPC_Receiver            : Node_Id;
-      Pkg_RPC_Receiver_Spec       : Node_Id;
-      Pkg_RPC_Receiver_Decls      : List_Id;
-      Pkg_RPC_Receiver_Statements : List_Id;
-      Pkg_RPC_Receiver_Cases      : constant List_Id := New_List;
-      Pkg_RPC_Receiver_Body       : Node_Id;
-      --  A Pkg_RPC_Receiver is built to decode the request
+         Append_To (Parameter_Associations (Last (Statements)),
+               New_Occurrence_Of (Request, Loc));
 
-      Subp_Id                     : Node_Id;
-      --  Subprogram_Id as read from the incoming stream
+         pragma Assert
+           (not (Is_Known_Non_Asynchronous and Is_Known_Asynchronous));
 
-      Current_Declaration       : Node_Id;
-      Current_Subprogram_Number : Int := 0;
-      Current_Stubs             : Node_Id;
+         if Is_Known_Non_Asynchronous or Is_Known_Asynchronous then
+            Asynchronous_P :=
+              New_Occurrence_Of
+                (Boolean_Literals (Is_Known_Asynchronous), Loc);
 
-      Actuals : List_Id;
+         else
+            pragma Assert (Present (Asynchronous));
+            Asynchronous_P := New_Copy_Tree (Asynchronous);
 
-      Dummy_Register_Name : Name_Id;
-      Dummy_Register_Spec : Node_Id;
-      Dummy_Register_Decl : Node_Id;
-      Dummy_Register_Body : Node_Id;
+            --  The expression node Asynchronous will be used to build an 'if'
+            --  statement at the end of Build_General_Calling_Stubs: we need to
+            --  make a copy here.
+         end if;
 
-   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_Spec :=
-        Build_RPC_Receiver_Specification
-          (RPC_Receiver     => Pkg_RPC_Receiver,
-           Stream_Parameter => Stream_Parameter,
-           Result_Parameter => Result_Parameter);
-
-      Pkg_RPC_Receiver_Decls := New_List (
-        Make_Object_Declaration (Loc,
-          Defining_Identifier => Subp_Id,
-          Object_Definition   =>
-            New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
+         Append_To (Parameter_Associations (Last (Statements)),
+           Make_Indexed_Component (Loc,
+             Prefix =>
+               New_Occurrence_Of (
+                 RTE (RE_Asynchronous_P_To_Sync_Scope), Loc),
+             Expressions => New_List (Asynchronous_P)));
 
-      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))));
+         Append_To (Statements,
+             Make_Procedure_Call_Statement (Loc,
+               Name                   =>
+                 New_Occurrence_Of (RTE (RE_Request_Invoke), Loc),
+               Parameter_Associations => New_List (
+                 New_Occurrence_Of (Request, 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.
+         Non_Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
+         Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
 
-      Current_Declaration := First (Visible_Declarations (Pkg_Spec));
+         if not Is_Known_Asynchronous then
 
-      while Current_Declaration /= Empty loop
+            --  Reraise an exception occurrence from the completed request.
+            --  If the exception occurrence is empty, this is a no-op.
 
-         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))));
+            Append_To (Non_Asynchronous_Statements,
+              Make_Procedure_Call_Statement (Loc,
+                Name                   =>
+                  New_Occurrence_Of (RTE (RE_Request_Raise_Occurrence), Loc),
+                Parameter_Associations => New_List (
+                  New_Occurrence_Of (Request, Loc))));
+
+            if Is_Function then
+
+               --  If this is a function call, read the value and return it
+
+               Append_To (Non_Asynchronous_Statements,
+                 Make_Tag_Check (Loc,
+                   Make_Simple_Return_Statement (Loc,
+                     PolyORB_Support.Helpers.Build_From_Any_Call
+                       (Etype (Result_Definition (Spec)),
+                        Make_Selected_Component (Loc,
+                          Prefix        => Result,
+                          Selector_Name => Name_Argument),
+                        Decls))));
+            end if;
+         end if;
 
-            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_List_To (Non_Asynchronous_Statements, After_Statements);
 
-            Append_To (Decls, Current_Stubs);
+         if Is_Known_Asynchronous then
+            Append_List_To (Statements, Asynchronous_Statements);
 
-            Analyze (Current_Stubs);
+         elsif Is_Known_Non_Asynchronous then
+            Append_List_To (Statements, Non_Asynchronous_Statements);
 
-            Actuals := New_List (New_Occurrence_Of (Stream_Parameter, Loc));
+         else
+            pragma Assert (Present (Asynchronous));
+            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;
 
-            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.
+      -----------------------
+      -- Build_Stub_Target --
+      -----------------------
 
-               Append_To (Actuals,
-                 New_Occurrence_Of (Result_Parameter, Loc));
+      function Build_Stub_Target
+        (Loc                   : Source_Ptr;
+         Decls                 : List_Id;
+         RCI_Locator           : Entity_Id;
+         Controlling_Parameter : Entity_Id) return RPC_Target
+      is
+         Target_Info : RPC_Target (PCS_Kind => Name_PolyORB_DSA);
+         Target_Reference : constant Entity_Id :=
+                              Make_Defining_Identifier (Loc,
+                                New_Internal_Name ('T'));
+      begin
+         if Present (Controlling_Parameter) then
+            Append_To (Decls,
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Target_Reference,
 
-            end if;
+                Object_Definition   =>
+                  New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
 
-            Append_To (Pkg_RPC_Receiver_Cases,
-              Make_Case_Statement_Alternative (Loc,
-                Discrete_Choices =>
-                  New_List (
-                    Make_Integer_Literal (Loc, Current_Subprogram_Number)),
+                Expression          =>
+                  Make_Function_Call (Loc,
+                    Name =>
+                      New_Occurrence_Of (RTE (RE_Make_Ref), Loc),
+                    Parameter_Associations => New_List (
+                      Make_Selected_Component (Loc,
+                        Prefix        => Controlling_Parameter,
+                        Selector_Name => Name_Target)))));
 
-                Statements       =>
-                  New_List (
-                    Make_Procedure_Call_Statement (Loc,
-                      Name                   =>
-                        New_Occurrence_Of (
-                          Defining_Entity (Current_Stubs), Loc),
-                      Parameter_Associations =>
-                        Actuals))));
+            --  Note: Controlling_Parameter has the same components as
+            --  System.Partition_Interface.RACW_Stub_Type.
 
-            Current_Subprogram_Number := Current_Subprogram_Number + 1;
+            Target_Info.Object := New_Occurrence_Of (Target_Reference, Loc);
+
+         else
+            Target_Info.Object :=
+              Make_Selected_Component (Loc,
+                Prefix        => Make_Identifier (Loc, Chars (RCI_Locator)),
+                Selector_Name =>
+                  Make_Identifier (Loc, Name_Get_RCI_Package_Ref));
          end if;
 
-         Next (Current_Declaration);
-      end loop;
+         return Target_Info;
+      end Build_Stub_Target;
 
-      --  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));
+      ---------------------
+      -- Build_Stub_Type --
+      ---------------------
 
-      Append_To (Decls, Pkg_RPC_Receiver_Body);
-      Analyze (Pkg_RPC_Receiver_Body);
+      procedure Build_Stub_Type
+        (RACW_Type         : Entity_Id;
+         Stub_Type         : Entity_Id;
+         Stub_Type_Decl    : out Node_Id;
+         RPC_Receiver_Decl : out Node_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (Stub_Type);
+         pragma Warnings (Off);
+         pragma Unreferenced (RACW_Type);
+         pragma Warnings (On);
 
-      --  Construction of the dummy package used to register the package
-      --  receiving stubs on the nameserver.
+      begin
+         Stub_Type_Decl :=
+           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_Target),
+                         Component_Definition =>
+                           Make_Component_Definition (Loc,
+                             Aliased_Present     => False,
+                             Subtype_Indication  =>
+                               New_Occurrence_Of (RTE (RE_Entity_Ptr), Loc))),
+
+                       Make_Component_Declaration (Loc,
+                         Defining_Identifier =>
+                           Make_Defining_Identifier (Loc, Name_Asynchronous),
+
+                         Component_Definition =>
+                           Make_Component_Definition (Loc,
+                             Aliased_Present    => False,
+                             Subtype_Indication =>
+                               New_Occurrence_Of (Standard_Boolean, Loc)))))));
+
+         RPC_Receiver_Decl :=
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Make_Defining_Identifier (Loc,
+                                      New_Internal_Name ('R')),
+             Aliased_Present     => True,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Servant), Loc));
+      end Build_Stub_Type;
+
+      -----------------------------
+      -- Build_RPC_Receiver_Body --
+      -----------------------------
+
+      procedure Build_RPC_Receiver_Body
+        (RPC_Receiver : Entity_Id;
+         Request      : out Entity_Id;
+         Subp_Id      : out Entity_Id;
+         Subp_Index   : out Entity_Id;
+         Stmts        : out List_Id;
+         Decl         : out Node_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (RPC_Receiver);
 
-      Dummy_Register_Name := New_Internal_Name ('P');
+         RPC_Receiver_Spec  : Node_Id;
+         RPC_Receiver_Decls : List_Id;
 
-      Dummy_Register_Spec :=
-        Make_Package_Specification (Loc,
-          Defining_Unit_Name   =>
-            Make_Defining_Identifier (Loc, Dummy_Register_Name),
-          Visible_Declarations => No_List,
-          End_Label => Empty);
+      begin
+         Request := Make_Defining_Identifier (Loc, Name_R);
 
-      Dummy_Register_Decl :=
-        Make_Package_Declaration (Loc,
-          Specification => Dummy_Register_Spec);
+         RPC_Receiver_Spec :=
+           Build_RPC_Receiver_Specification (
+             RPC_Receiver      => RPC_Receiver,
+             Request_Parameter => Request);
 
-      Append_To (Decls,
-        Dummy_Register_Decl);
-      Analyze (Dummy_Register_Decl);
+         Subp_Id    := Make_Defining_Identifier (Loc, Name_P);
+         Subp_Index := Make_Defining_Identifier (Loc, Name_I);
 
-      Dummy_Register_Body :=
-        Make_Package_Body (Loc,
-          Defining_Unit_Name         =>
-            Make_Defining_Identifier (Loc, Dummy_Register_Name),
-          Declarations               => No_List,
+         RPC_Receiver_Decls := New_List (
+           Make_Object_Renaming_Declaration (Loc,
+             Defining_Identifier => Subp_Id,
+             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
+             Name                =>
+               Make_Explicit_Dereference (Loc,
+                 Prefix =>
+                   Make_Selected_Component (Loc,
+                     Prefix        => Request,
+                     Selector_Name => Name_Operation))),
 
-          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))))));
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Subp_Index,
+             Object_Definition   =>
+               New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
+             Expression          =>
+               Make_Attribute_Reference (Loc,
+                 Prefix         =>
+                   New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
+                 Attribute_Name => Name_Last)));
 
-      Append_To (Decls, Dummy_Register_Body);
-      Analyze (Dummy_Register_Body);
-   end Add_Receiving_Stubs_To_Declarations;
+         Stmts := New_List;
 
-   -------------------
-   -- Add_Stub_Type --
-   -------------------
+         Decl :=
+           Make_Subprogram_Body (Loc,
+             Specification              => RPC_Receiver_Spec,
+             Declarations               => RPC_Receiver_Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Stmts));
+      end Build_RPC_Receiver_Body;
+
+      --------------------------------------
+      -- 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);
 
-   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);
+         Request_Parameter : constant Entity_Id :=
+                               Make_Defining_Identifier (Loc,
+                                 New_Internal_Name ('R'));
+         --  Formal parameter for receiving stubs: a descriptor for an incoming
+         --  request.
 
-      Stub_Elements : constant Stub_Structure :=
-                        Stubs_Table.Get (Designated_Type);
+         Outer_Decls : constant List_Id := New_List;
+         --  At the outermost level, an NVList and Any's are declared for all
+         --  parameters. The Dynamic_Async flag also needs to be declared there
+         --  to be visible from the exception handling code.
 
-      Stub_Type_Declaration           : Node_Id;
-      Stub_Type_Access_Declaration    : Node_Id;
-      Object_RPC_Receiver_Declaration : Node_Id;
+         Outer_Statements : constant List_Id := New_List;
+         --  Statements that occur prior to the declaration of the actual
+         --  parameter variables.
 
-      RPC_Receiver_Stream             : Entity_Id;
-      RPC_Receiver_Result             : Entity_Id;
+         Outer_Extra_Formal_Statements : constant List_Id := New_List;
+         --  Statements concerning extra formal parameters, prior to the
+         --  declaration of the actual parameter variables.
 
-   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;
+         Decls : constant List_Id := New_List;
+         --  All the parameters will get declared before calling the real
+         --  subprograms. Also the out parameters will be declared.
+         --  At this level, parameters may be unconstrained.
 
-      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));
+         Statements : constant List_Id := New_List;
 
-      --  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.
+         After_Statements : constant List_Id := New_List;
+         --  Statements to be executed after the subprogram call
 
-      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),
-                      Component_Definition =>
-                        Make_Component_Definition (Loc,
-                          Aliased_Present    => False,
-                          Subtype_Indication =>
-                            New_Occurrence_Of (RTE (RE_Partition_ID), Loc))),
-
-                    Make_Component_Declaration (Loc,
-                      Defining_Identifier =>
-                        Make_Defining_Identifier (Loc, Name_Receiver),
-                      Component_Definition =>
-                        Make_Component_Definition (Loc,
-                          Aliased_Present    => False,
-                          Subtype_Indication =>
-                            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
-
-                    Make_Component_Declaration (Loc,
-                      Defining_Identifier =>
-                        Make_Defining_Identifier (Loc, Name_Addr),
-                      Component_Definition =>
-                        Make_Component_Definition (Loc,
-                          Aliased_Present    => False,
-                          Subtype_Indication =>
-                            New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
-
-                    Make_Component_Declaration (Loc,
-                      Defining_Identifier =>
-                        Make_Defining_Identifier (Loc, Name_Asynchronous),
-                      Component_Definition =>
-                        Make_Component_Definition (Loc,
-                          Aliased_Present    => False,
-                          Subtype_Indication =>
-                            New_Occurrence_Of (Standard_Boolean, Loc)))))));
+         Inner_Decls : List_Id := No_List;
+         --  In case of a function, the inner declarations are needed since
+         --  the result may be unconstrained.
 
-      Append_To (Decls, Stub_Type_Declaration);
-      Analyze (Stub_Type_Declaration);
+         Excep_Handlers : List_Id := No_List;
 
-      --  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.
+         Parameter_List : constant List_Id := New_List;
+         --  List of parameters to be passed to the subprogram
 
-      Derive_Subprograms (Parent_Type  => Designated_Type,
-                          Derived_Type => Stub_Type);
+         First_Controlling_Formal_Seen : Boolean := False;
 
-      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)));
+         Current_Parameter : Node_Id;
 
-      Append_To (Decls, Stub_Type_Access_Declaration);
-      Analyze (Stub_Type_Access_Declaration);
+         Ordered_Parameters_List : constant List_Id :=
+                                     Build_Ordered_Parameters_List
+                                       (Specification (Vis_Decl));
 
-      Object_RPC_Receiver_Declaration :=
-        Make_Subprogram_Declaration (Loc,
-          Build_RPC_Receiver_Specification (
-            RPC_Receiver     => Object_RPC_Receiver,
-            Stream_Parameter => RPC_Receiver_Stream,
-            Result_Parameter => RPC_Receiver_Result));
+         Arguments : constant Entity_Id :=
+                       Make_Defining_Identifier (Loc,
+                         New_Internal_Name ('A'));
+         --  Name of the named values list used to retrieve parameters
 
-      Append_To (Decls, Object_RPC_Receiver_Declaration);
-   end Add_Stub_Type;
+         Subp_Spec : Node_Id;
+         --  Subprogram specification
 
-   ---------------------------------
-   -- Build_General_Calling_Stubs --
-   ---------------------------------
+         Called_Subprogram : Node_Id;
+         --  The subprogram to call
 
-   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);
+      begin
+         if Present (RACW_Type) 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 : Node_Id;
-      --  Name of the stream used to transmit parameters to the remote package
+         Declare_Create_NVList (Loc, Arguments, Outer_Decls, Outer_Statements);
 
-      Result_Parameter : Node_Id;
-      --  Name of the result parameter (in non-APC cases) which get the
-      --  result of the remote subprogram.
+         --  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.
 
-      Exception_Return_Parameter : Node_Id;
-      --  Name of the parameter which will hold the exception sent by the
-      --  remote subprogram.
+         Current_Parameter := First (Ordered_Parameters_List);
+         while Present (Current_Parameter) loop
+            declare
+               Etyp        : Entity_Id;
+               Constrained : Boolean;
+               Any         : Entity_Id := Empty;
+               Object      : constant Entity_Id :=
+                               Make_Defining_Identifier (Loc,
+                                 Chars => New_Internal_Name ('P'));
+               Expr        : Node_Id   := Empty;
 
-      Current_Parameter : Node_Id;
-      --  Current parameter being handled
+               Is_Controlling_Formal : constant Boolean :=
+                                         Is_RACW_Controlling_Formal
+                                           (Current_Parameter, Stub_Type);
 
-      Ordered_Parameters_List : constant List_Id :=
-                                  Build_Ordered_Parameters_List (Spec);
+               Is_First_Controlling_Formal : Boolean := False;
 
-      Asynchronous_Statements     : List_Id := No_List;
-      Non_Asynchronous_Statements : List_Id := No_List;
-      --  Statements specifics to the Asynchronous/Non-Asynchronous cases.
+               Need_Extra_Constrained : Boolean;
+               --  True when an extra constrained actual is required
 
-      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
+               if Is_Controlling_Formal then
 
-   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'));
+                  --  Controlling formals in distributed object primitive
+                  --  operations are handled specially:
+                  --    - the first controlling formal is used as the
+                  --      target of the call;
+                  --    - the remaining controlling formals are transmitted
+                  --      as RACWs.
 
-      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'));
+                  Etyp := RACW_Type;
+                  Is_First_Controlling_Formal :=
+                    not First_Controlling_Formal_Seen;
+                  First_Controlling_Formal_Seen := True;
 
-         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))))));
+               else
+                  Etyp := Etype (Parameter_Type (Current_Parameter));
+               end if;
 
-         Exception_Return_Parameter :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
+               Constrained :=
+                 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
 
-         Append_To (Decls,
-           Make_Object_Declaration (Loc,
-             Defining_Identifier => Exception_Return_Parameter,
-             Object_Definition   =>
-               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
+               if not Is_First_Controlling_Formal then
+                  Any :=
+                    Make_Defining_Identifier (Loc,
+                      Chars => New_Internal_Name ('A'));
 
-      else
-         Result_Parameter := Empty;
-         Exception_Return_Parameter := Empty;
-      end if;
+                  Append_To (Outer_Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Any,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_Any), Loc),
+                      Expression =>
+                        Make_Function_Call (Loc,
+                          Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
+                          Parameter_Associations => New_List (
+                            PolyORB_Support.Helpers.Build_TypeCode_Call
+                              (Loc, Etyp, Outer_Decls)))));
+
+                  Append_To (Outer_Statements,
+                    Add_Parameter_To_NVList (Loc,
+                      Parameter   => Current_Parameter,
+                      NVList      => Arguments,
+                      Constrained => Constrained,
+                      Any         => Any));
+               end if;
 
-      --  Put first the RPC receiver corresponding to the remote package
+               if Is_First_Controlling_Formal then
+                  declare
+                     Addr : constant Entity_Id :=
+                              Make_Defining_Identifier (Loc,
+                                Chars => New_Internal_Name ('A'));
+
+                     Is_Local : constant Entity_Id :=
+                                  Make_Defining_Identifier (Loc,
+                                    Chars => New_Internal_Name ('L'));
+
+                  begin
+                     --  Special case: obtain the first controlling formal
+                     --  from the target of the remote call, instead of the
+                     --  argument list.
+
+                     Append_To (Outer_Decls,
+                       Make_Object_Declaration (Loc,
+                         Defining_Identifier => Addr,
+                         Object_Definition =>
+                           New_Occurrence_Of (RTE (RE_Address), Loc)));
+
+                     Append_To (Outer_Decls,
+                       Make_Object_Declaration (Loc,
+                         Defining_Identifier => Is_Local,
+                         Object_Definition =>
+                           New_Occurrence_Of (Standard_Boolean, Loc)));
+
+                     Append_To (Outer_Statements,
+                       Make_Procedure_Call_Statement (Loc,
+                         Name =>
+                           New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
+                         Parameter_Associations => New_List (
+                           Make_Selected_Component (Loc,
+                             Prefix =>
+                               New_Occurrence_Of (
+                                 Request_Parameter, Loc),
+                             Selector_Name =>
+                               Make_Identifier (Loc, Name_Target)),
+                           New_Occurrence_Of (Is_Local, Loc),
+                           New_Occurrence_Of (Addr, Loc))));
+
+                     Expr := Unchecked_Convert_To (RACW_Type,
+                       New_Occurrence_Of (Addr, Loc));
+                  end;
+
+               elsif In_Present (Current_Parameter)
+                  or else not Out_Present (Current_Parameter)
+                  or else not Constrained
+               then
+                  --  If an input parameter is constrained, 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.
+
+                  Expr := PolyORB_Support.Helpers.Build_From_Any_Call (
+                            Etyp, New_Occurrence_Of (Any, Loc), Decls);
+
+                  if Constrained then
+                     Append_To (Statements,
+                       Make_Assignment_Statement (Loc,
+                         Name       => New_Occurrence_Of (Object, Loc),
+                         Expression => Expr));
+                     Expr := Empty;
+                  else
+                     null;
 
-      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)));
+                     --  Expr will be used to initialize (and constrain) the
+                     --  parameter when it is declared.
+                  end if;
 
-      --  Then put the Subprogram_Id of the subprogram we want to call in
-      --  the stream.
+               end if;
 
-      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)));
+               Need_Extra_Constrained :=
+                 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)));
+
+               --  We may not associate an extra constrained actual to a
+               --  constant object, so if one is needed, declare the actual
+               --  as a variable even if it won't be modified.
+
+               Build_Actual_Object_Declaration
+                 (Object   => Object,
+                  Etyp     => Etyp,
+                  Variable => Need_Extra_Constrained
+                                or else Out_Present (Current_Parameter),
+                  Expr     => Expr,
+                  Decls    => Decls);
+               Set_Etype (Object, Etyp);
+
+               --  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 not Is_Controlling_Formal
+               then
+                  Append_To (After_Statements,
+                    Make_Procedure_Call_Statement (Loc,
+                      Name => New_Occurrence_Of (RTE (RE_Move_Any_Value), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Any, Loc),
+                        PolyORB_Support.Helpers.Build_To_Any_Call
+                          (New_Occurrence_Of (Object, Loc), Decls))));
+               end if;
 
-      Current_Parameter := First (Ordered_Parameters_List);
+               --  For RACW controlling formals, the Etyp of Object is always
+               --  an RACW, even if the parameter is not of an anonymous access
+               --  type. In such case, we need to dereference it at call time.
 
-      while Current_Parameter /= Empty loop
+               if Is_Controlling_Formal 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,
+                             Prefix =>
+                               Unchecked_Convert_To (RACW_Type,
+                                 OK_Convert_To (RTE (RE_Address),
+                                   New_Occurrence_Of (Object, Loc))))));
 
-         declare
-            Typ             : constant Node_Id :=
-              Parameter_Type (Current_Parameter);
-            Etyp            : Entity_Id;
-            Constrained     : Boolean;
-            Value           : Node_Id;
-            Extra_Parameter : Entity_Id;
+                  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;
 
-         begin
+               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 Is_RACW_Controlling_Formal (Current_Parameter, Object_Type) then
+               --  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 Need_Extra_Constrained then
+                  declare
+                     Extra_Parameter : constant Entity_Id :=
+                                         Extra_Constrained
+                                           (Defining_Identifier
+                                             (Current_Parameter));
+
+                     Extra_Any : constant Entity_Id :=
+                                   Make_Defining_Identifier (Loc,
+                                     Chars => New_Internal_Name ('A'));
+
+                     Formal_Entity : constant Entity_Id :=
+                                       Make_Defining_Identifier (Loc,
+                                         Chars => Chars (Extra_Parameter));
+
+                     Formal_Type : constant Entity_Id :=
+                                     Etype (Extra_Parameter);
+
+                  begin
+                     Append_To (Outer_Decls,
+                       Make_Object_Declaration (Loc,
+                         Defining_Identifier => Extra_Any,
+                         Object_Definition   =>
+                           New_Occurrence_Of (RTE (RE_Any), Loc),
+                         Expression =>
+                           Make_Function_Call (Loc,
+                             Name =>
+                               New_Occurrence_Of (RTE (RE_Create_Any), Loc),
+                             Parameter_Associations => New_List (
+                               PolyORB_Support.Helpers.Build_TypeCode_Call
+                                 (Loc, Formal_Type, Outer_Decls)))));
+
+                     Append_To (Outer_Extra_Formal_Statements,
+                       Add_Parameter_To_NVList (Loc,
+                         Parameter   => Extra_Parameter,
+                         NVList      => Arguments,
+                         Constrained => True,
+                         Any         => Extra_Any));
+
+                     Append_To (Decls,
+                       Make_Object_Declaration (Loc,
+                         Defining_Identifier => Formal_Entity,
+                         Object_Definition   =>
+                           New_Occurrence_Of (Formal_Type, Loc)));
+
+                     Append_To (Statements,
+                       Make_Assignment_Statement (Loc,
+                         Name => New_Occurrence_Of (Formal_Entity, Loc),
+                         Expression =>
+                           PolyORB_Support.Helpers.Build_From_Any_Call
+                             (Formal_Type,
+                              New_Occurrence_Of (Extra_Any, Loc),
+                              Decls)));
+                     Set_Extra_Constrained (Object, Formal_Entity);
+                  end;
+               end if;
+            end;
 
-               --  In the case of a controlling formal argument, we marshall
-               --  its addr field rather than the local stub.
+            Next (Current_Parameter);
+         end loop;
 
-               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)));
+         --  Extra Formals should go after all the other parameters
 
-            else
-               Value := New_Occurrence_Of
-                 (Defining_Identifier (Current_Parameter), Loc);
+         Append_List_To (Outer_Statements, Outer_Extra_Formal_Statements);
 
-               --  Access type parameters are transmitted as in out
-               --  parameters. However, a dereference is needed so that
-               --  we marshall the designated object.
+         Append_To (Outer_Statements,
+           Make_Procedure_Call_Statement (Loc,
+             Name => New_Occurrence_Of (RTE (RE_Request_Arguments), Loc),
+             Parameter_Associations => New_List (
+               New_Occurrence_Of (Request_Parameter, Loc),
+               New_Occurrence_Of (Arguments, Loc))));
 
-               if Nkind (Typ) = N_Access_Definition then
-                  Value := Make_Explicit_Dereference (Loc, Value);
-                  Etyp  := Etype (Subtype_Mark (Typ));
-               else
-                  Etyp := Etype (Typ);
-               end if;
+         if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
 
-               Constrained :=
-                 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
+            --  The remote subprogram is a function: Build an inner block to be
+            --  able to hold a potentially unconstrained result in a variable.
 
-               --  Any parameter but unconstrained out parameters are
-               --  transmitted to the peer.
+            declare
+               Etyp   : constant Entity_Id :=
+                          Etype (Result_Definition (Specification (Vis_Decl)));
+               Result : constant Node_Id   :=
+                          Make_Defining_Identifier (Loc,
+                            Chars => New_Internal_Name ('R'));
 
-               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),
-                        Value)));
-               end if;
-            end if;
+            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)));
+
+               if Is_Class_Wide_Type (Etyp) then
+
+                  --  For a remote call to a function with a class-wide type,
+                  --  check that the returned value satisfies the requirements
+                  --  of (RM E.4(18)).
+
+                  Append_To (Inner_Decls,
+                    Make_Transportable_Check (Loc,
+                      New_Occurrence_Of (Result, Loc)));
 
-            --  If the current parameter has a dynamic constrained status,
-            --  then this status is transmitted as well.
-            --  This should be done for accessibility as well ???
+               end if;
 
-            if Nkind (Typ) /= 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.
+               Set_Etype (Result, Etyp);
+               Append_To (After_Statements,
+                 Make_Procedure_Call_Statement (Loc,
+                   Name => New_Occurrence_Of (RTE (RE_Set_Result), Loc),
+                   Parameter_Associations => New_List (
+                     New_Occurrence_Of (Request_Parameter, Loc),
+                     PolyORB_Support.Helpers.Build_To_Any_Call
+                       (New_Occurrence_Of (Result, Loc), Decls))));
+
+               --  A DSA function does not have out or inout arguments
+            end;
 
-               Extra_Parameter := Make_Defining_Identifier
-                                    (Loc, New_Internal_Name ('P'));
+            Append_To (Statements,
+              Make_Block_Statement (Loc,
+                Declarations               => Inner_Decls,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => After_Statements)));
 
-               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)));
+         else
+            --  The remote subprogram is a procedure. We do not need any inner
+            --  block in this case. No specific processing is required here for
+            --  the dynamically asynchronous case: the indication of whether
+            --  call is asynchronous or not is managed by the Sync_Scope
+            --  attibute of the request, and is handled entirely in the
+            --  protocol layer.
 
-               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 if;
+            Append_To (After_Statements,
+              Make_Procedure_Call_Statement (Loc,
+                Name => New_Occurrence_Of (RTE (RE_Request_Set_Out), Loc),
+                Parameter_Associations => New_List (
+                  New_Occurrence_Of (Request_Parameter, Loc))));
 
-            Next (Current_Parameter);
-         end;
-      end loop;
+            Append_To (Statements,
+              Make_Procedure_Call_Statement (Loc,
+                Name                   => Called_Subprogram,
+                Parameter_Associations => Parameter_List));
 
-      --  Append the formal statements list to the statements
+            Append_List_To (Statements, After_Statements);
+         end if;
 
-      Append_List_To (Statements, Extra_Formal_Statements);
+         Subp_Spec :=
+           Make_Procedure_Specification (Loc,
+             Defining_Unit_Name       =>
+               Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
 
-      if not Is_Known_Non_Asynchronous then
+             Parameter_Specifications => New_List (
+               Make_Parameter_Specification (Loc,
+                 Defining_Identifier => Request_Parameter,
+                 Parameter_Type      =>
+                   New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
 
-         --  Build the call to System.RPC.Do_APC
+         --  An exception raised during the execution of an incoming
+         --  remote subprogram call and that needs to be sent back
+         --  to the caller is propagated by the receiving stubs, and
+         --  will be handled by the caller (the distribution runtime).
 
-         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 Asynchronous and then not Dynamically_Asynchronous then
 
-      if not Is_Known_Asynchronous then
+            --  For an asynchronous procedure, add a null exception handler
 
-         --  Build the call to System.RPC.Do_RPC
+            Excep_Handlers := New_List (
+              Make_Implicit_Exception_Handler (Loc,
+                Exception_Choices => New_List (Make_Others_Choice (Loc)),
+                Statements        => New_List (Make_Null_Statement (Loc))));
 
-         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),
+         else
+            --  In the other cases, if an exception is raised, then the
+            --  exception occurrence is propagated.
 
-               Make_Attribute_Reference (Loc,
-                 Prefix         =>
-                   New_Occurrence_Of (Stream_Parameter, Loc),
-                 Attribute_Name =>
-                   Name_Access),
+            null;
+         end if;
 
-               Make_Attribute_Reference (Loc,
-                 Prefix         =>
-                   New_Occurrence_Of (Result_Parameter, Loc),
-                 Attribute_Name =>
-                   Name_Access))));
+         Append_To (Outer_Statements,
+           Make_Block_Statement (Loc,
+             Declarations => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Statements)));
 
-         --  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.
+         return
+           Make_Subprogram_Body (Loc,
+             Specification              => Subp_Spec,
+             Declarations               => Outer_Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements         => Outer_Statements,
+                 Exception_Handlers => Excep_Handlers));
+      end Build_Subprogram_Receiving_Stubs;
+
+      -------------
+      -- Helpers --
+      -------------
+
+      package body Helpers is
+
+         -----------------------
+         -- Local Subprograms --
+         -----------------------
+
+         function Find_Numeric_Representation
+           (Typ : Entity_Id) return Entity_Id;
+         --  Given a numeric type Typ, return the smallest integer or floating
+         --  point type from Standard, or the smallest unsigned (modular) type
+         --  from System.Unsigned_Types, whose range encompasses that of Typ.
+
+         function Make_Helper_Function_Name
+           (Loc : Source_Ptr;
+            Typ : Entity_Id;
+            Nam : Name_Id) return Entity_Id;
+         --  Return the name to be assigned for helper subprogram Nam of Typ
+
+         ------------------------------------------------------------
+         -- Common subprograms for building various tree fragments --
+         ------------------------------------------------------------
+
+         function Build_Get_Aggregate_Element
+           (Loc : Source_Ptr;
+            Any : Entity_Id;
+            TC  : Node_Id;
+            Idx : Node_Id) return Node_Id;
+         --  Build a call to Get_Aggregate_Element on Any for typecode TC,
+         --  returning the Idx'th element.
+
+         generic
+            Subprogram : Entity_Id;
+            --  Reference location for constructed nodes
+
+            Arry : Entity_Id;
+            --  For 'Range and Etype
+
+            Indices : List_Id;
+            --  For the construction of the innermost element expression
+
+            with procedure Add_Process_Element
+              (Stmts   : List_Id;
+               Any     : Entity_Id;
+               Counter : Entity_Id;
+               Datum   : Node_Id);
+
+         procedure Append_Array_Traversal
+           (Stmts   : List_Id;
+            Any     : Entity_Id;
+            Counter : Entity_Id := Empty;
+            Depth   : Pos       := 1);
+         --  Build nested loop statements that iterate over the elements of an
+         --  array Arry. The statement(s) built by Add_Process_Element are
+         --  executed for each element; Indices is the list of indices to be
+         --  used in the construction of the indexed component that denotes the
+         --  current element. Subprogram is the entity for the subprogram for
+         --  which this iterator is generated. The generated statements are
+         --  appended to Stmts.
+
+         generic
+            Rec : Entity_Id;
+            --  The record entity being dealt with
+
+            with procedure Add_Process_Element
+              (Stmts     : List_Id;
+               Container : Node_Or_Entity_Id;
+               Counter   : in out Int;
+               Rec       : Entity_Id;
+               Field     : Node_Id);
+            --  Rec is the instance of the record type, or Empty.
+            --  Field is either the N_Defining_Identifier for a component,
+            --  or an N_Variant_Part.
+
+         procedure Append_Record_Traversal
+           (Stmts     : List_Id;
+            Clist     : Node_Id;
+            Container : Node_Or_Entity_Id;
+            Counter   : in out Int);
+         --  Process component list Clist. Individual fields are passed
+         --  to Field_Processing. Each variant part is also processed.
+         --  Container is the outer Any (for From_Any/To_Any),
+         --  the outer typecode (for TC) to which the operation applies.
+
+         -----------------------------
+         -- Append_Record_Traversal --
+         -----------------------------
+
+         procedure Append_Record_Traversal
+           (Stmts     : List_Id;
+            Clist     : Node_Id;
+            Container : Node_Or_Entity_Id;
+            Counter   : in out Int)
+         is
+            CI : List_Id;
+            VP : Node_Id;
+            --  Clist's Component_Items and Variant_Part
+
+            Item : Node_Id;
+            Def  : Entity_Id;
 
-         Append_To (Non_Asynchronous_Statements,
-           Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
+         begin
+            if No (Clist) then
+               return;
+            end if;
 
-             Attribute_Name =>
-               Name_Read,
+            CI := Component_Items (Clist);
+            VP := Variant_Part (Clist);
 
-             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))));
+            Item := First (CI);
+            while Present (Item) loop
+               Def := Defining_Identifier (Item);
 
-         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 not Is_Internal_Name (Chars (Def)) then
+                  Add_Process_Element
+                    (Stmts, Container, Counter, Rec, Def);
+               end if;
 
-         if Is_Function then
+               Next (Item);
+            end loop;
 
-            --  If this is a function call, then read the value and return
-            --  it. The return value is written/read using 'Output/'Input.
+            if Present (VP) then
+               Add_Process_Element (Stmts, Container, Counter, Rec, VP);
+            end if;
+         end Append_Record_Traversal;
 
-            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),
+         -------------------------
+         -- Build_From_Any_Call --
+         -------------------------
 
-                      Attribute_Name => Name_Input,
+         function Build_From_Any_Call
+           (Typ   : Entity_Id;
+            N     : Node_Id;
+            Decls : List_Id) return Node_Id
+         is
+            Loc : constant Source_Ptr := Sloc (N);
 
-                      Expressions    => New_List (
-                        Make_Attribute_Reference (Loc,
-                          Prefix         =>
-                            New_Occurrence_Of (Result_Parameter, Loc),
-                          Attribute_Name => Name_Access))))));
+            U_Type : Entity_Id  := Underlying_Type (Typ);
 
-         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.
+            Fnam    : Entity_Id := Empty;
+            Lib_RE  : RE_Id := RE_Null;
+            Result  : Node_Id;
 
-            Current_Parameter :=
-              First (Ordered_Parameters_List);
+         begin
+            --  First simple case where the From_Any function is present
+            --  in the type's TSS.
 
-            while Current_Parameter /= Empty loop
+            Fnam := Find_Inherited_TSS (U_Type, TSS_From_Any);
 
-               declare
-                  Typ   : constant Node_Id :=
-                    Parameter_Type (Current_Parameter);
-                  Etyp  : Entity_Id;
-                  Value : Node_Id;
-               begin
-                  Value := New_Occurrence_Of
-                    (Defining_Identifier (Current_Parameter), Loc);
+            if Sloc (U_Type) <= Standard_Location then
+               U_Type := Base_Type (U_Type);
+            end if;
 
-                  if Nkind (Typ) = N_Access_Definition then
-                     Value := Make_Explicit_Dereference (Loc, Value);
-                     Etyp  := Etype (Subtype_Mark (Typ));
-                  else
-                     Etyp := Etype (Typ);
-                  end if;
+            --  Check first for Boolean and Character. These are enumeration
+            --  types, but we treat them specially, since they may require
+            --  special handling in the transfer protocol. However, this
+            --  special handling only applies if they have standard
+            --  representation, otherwise they are treated like any other
+            --  enumeration type.
 
-                  if (Out_Present (Current_Parameter)
-                      or else Nkind (Typ) = N_Access_Definition)
-                    and then Etyp /= Object_Type
-                  then
-                     Append_To (Non_Asynchronous_Statements,
-                        Make_Attribute_Reference (Loc,
-                          Prefix         =>
-                            New_Occurrence_Of (Etyp, Loc),
+            if Present (Fnam) then
+               null;
 
-                          Attribute_Name => Name_Read,
+            elsif U_Type = Standard_Boolean then
+               Lib_RE := RE_FA_B;
 
-                          Expressions    => New_List (
-                            Make_Attribute_Reference (Loc,
-                              Prefix         =>
-                                New_Occurrence_Of (Result_Parameter, Loc),
-                              Attribute_Name =>
-                                Name_Access),
-                            Value)));
-                  end if;
-               end;
+            elsif U_Type = Standard_Character then
+               Lib_RE := RE_FA_C;
 
-               Next (Current_Parameter);
-            end loop;
-         end if;
-      end if;
+            elsif U_Type = Standard_Wide_Character then
+               Lib_RE := RE_FA_WC;
 
-      if Is_Known_Asynchronous then
-         Append_List_To (Statements, Asynchronous_Statements);
+            elsif U_Type = Standard_Wide_Wide_Character then
+               Lib_RE := RE_FA_WWC;
 
-      elsif Is_Known_Non_Asynchronous then
-         Append_List_To (Statements, Non_Asynchronous_Statements);
+            --  Floating point types
 
-      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;
+            elsif U_Type = Standard_Short_Float then
+               Lib_RE := RE_FA_SF;
 
-   -----------------------------------
-   -- Build_Ordered_Parameters_List --
-   -----------------------------------
+            elsif U_Type = Standard_Float then
+               Lib_RE := RE_FA_F;
 
-   function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
-      Constrained_List   : List_Id;
-      Unconstrained_List : List_Id;
-      Current_Parameter  : Node_Id;
+            elsif U_Type = Standard_Long_Float then
+               Lib_RE := RE_FA_LF;
 
-   begin
-      if not Present (Parameter_Specifications (Spec)) then
-         return New_List;
-      end if;
+            elsif U_Type = Standard_Long_Long_Float then
+               Lib_RE := RE_FA_LLF;
 
-      Constrained_List   := New_List;
-      Unconstrained_List := New_List;
+            --  Integer types
 
-      --  Loop through the parameters and add them to the right list
+            elsif U_Type = Etype (Standard_Short_Short_Integer) then
+                  Lib_RE := RE_FA_SSI;
 
-      Current_Parameter := First (Parameter_Specifications (Spec));
-      while Current_Parameter /= Empty loop
+            elsif U_Type = Etype (Standard_Short_Integer) then
+               Lib_RE := RE_FA_SI;
 
-         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;
+            elsif U_Type = Etype (Standard_Integer) then
+               Lib_RE := RE_FA_I;
 
-         Next (Current_Parameter);
-      end loop;
+            elsif U_Type = Etype (Standard_Long_Integer) then
+               Lib_RE := RE_FA_LI;
 
-      --  Unconstrained parameters are returned first
+            elsif U_Type = Etype (Standard_Long_Long_Integer) then
+               Lib_RE := RE_FA_LLI;
 
-      Append_List_To (Unconstrained_List, Constrained_List);
+            --  Unsigned integer types
 
-      return Unconstrained_List;
+            elsif U_Type = RTE (RE_Short_Short_Unsigned) then
+               Lib_RE := RE_FA_SSU;
 
-   end Build_Ordered_Parameters_List;
+            elsif U_Type = RTE (RE_Short_Unsigned) then
+               Lib_RE := RE_FA_SU;
 
-   ----------------------------------
-   -- Build_Passive_Partition_Stub --
-   ----------------------------------
+            elsif U_Type = RTE (RE_Unsigned) then
+               Lib_RE := RE_FA_U;
 
-   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);
+            elsif U_Type = RTE (RE_Long_Unsigned) then
+               Lib_RE := RE_FA_LU;
 
-   begin
-      --  Verify that the implementation supports distribution, by accessing
-      --  a type defined in the proper version of system.rpc
+            elsif U_Type = RTE (RE_Long_Long_Unsigned) then
+               Lib_RE := RE_FA_LLU;
 
-      declare
-         Dist_OK : Entity_Id;
-         pragma Warnings (Off, Dist_OK);
+            elsif U_Type = Standard_String then
+               Lib_RE := RE_FA_String;
 
-      begin
-         Dist_OK := RTE (RE_Params_Stream_Type);
-      end;
+            --  Special DSA types
 
-      --  Use body if present, spec otherwise
+            elsif Is_RTE (U_Type, RE_Any_Content_Ptr) then
+               Lib_RE := RE_FA_A;
 
-      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;
+            --  Other (non-primitive) types
 
-      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;
+            else
+               declare
+                  Decl : Entity_Id;
+               begin
+                  Build_From_Any_Function (Loc, U_Type, Decl, Fnam);
+                  Append_To (Decls, Decl);
+               end;
+            end if;
 
-   --------------------------------------
-   -- Build_RPC_Receiver_Specification --
-   --------------------------------------
+            --  Call the function
 
-   function Build_RPC_Receiver_Specification
-     (RPC_Receiver     : Entity_Id;
-      Stream_Parameter : Entity_Id;
-      Result_Parameter : Entity_Id)
-      return             Node_Id
-   is
-      Loc : constant Source_Ptr := Sloc (RPC_Receiver);
+            if Lib_RE /= RE_Null then
+               pragma Assert (No (Fnam));
+               Fnam := RTE (Lib_RE);
+            end if;
 
-   begin
-      return
-        Make_Procedure_Specification (Loc,
-          Defining_Unit_Name       => RPC_Receiver,
-          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))),
+            Result :=
+              Make_Function_Call (Loc,
+                Name                   => New_Occurrence_Of (Fnam, Loc),
+                Parameter_Associations => New_List (N));
 
-            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 Build_RPC_Receiver_Specification;
+            --  We must set the type of Result, so the unchecked conversion
+            --  from the underlying type to the base type is properly done.
 
-   ------------------------------------
-   -- Build_Subprogram_Calling_Stubs --
-   ------------------------------------
+            Set_Etype (Result, U_Type);
 
-   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);
+            return Unchecked_Convert_To (Typ, Result);
+         end Build_From_Any_Call;
 
-      Target_Partition : Node_Id;
-      --  Contains the name of the target partition
+         -----------------------------
+         -- Build_From_Any_Function --
+         -----------------------------
 
-      Decls      : constant List_Id := New_List;
-      Statements : constant List_Id := New_List;
+         procedure Build_From_Any_Function
+           (Loc  : Source_Ptr;
+            Typ  : Entity_Id;
+            Decl : out Node_Id;
+            Fnam : out Entity_Id)
+         is
+            Spec  : Node_Id;
+            Decls : constant List_Id := New_List;
+            Stms  : constant List_Id := New_List;
 
-      Subp_Spec : Node_Id;
-      --  The specification of the body
+            Any_Parameter : constant Entity_Id :=
+                              Make_Defining_Identifier (Loc,
+                                New_Internal_Name ('A'));
 
-      Controlling_Parameter : Entity_Id := Empty;
-      RPC_Receiver          : Node_Id;
+            Use_Opaque_Representation : Boolean;
 
-      Asynchronous_Expr : Node_Id := Empty;
+         begin
+            if Is_Itype (Typ) then
+               Build_From_Any_Function
+                  (Loc  => Loc,
+                   Typ  => Etype (Typ),
+                   Decl => Decl,
+                   Fnam => Fnam);
+               return;
+            end if;
 
-      RCI_Locator : Entity_Id;
+            Fnam := Make_Helper_Function_Name (Loc, Typ, Name_From_Any);
 
-      Spec_To_Use : Node_Id;
+            Spec :=
+              Make_Function_Specification (Loc,
+                Defining_Unit_Name => Fnam,
+                Parameter_Specifications => New_List (
+                  Make_Parameter_Specification (Loc,
+                    Defining_Identifier => Any_Parameter,
+                    Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))),
+                Result_Definition => New_Occurrence_Of (Typ, Loc));
 
-      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)).
+            --  The following  is taken care of by Exp_Dist.Add_RACW_From_Any
 
-      ----------------------------
-      -- Insert_Partition_Check --
-      ----------------------------
+            pragma Assert
+              (not (Is_Remote_Access_To_Class_Wide_Type (Typ)));
 
-      procedure Insert_Partition_Check (Parameter : in Node_Id) is
-         Parameter_Entity  : constant Entity_Id :=
-                               Defining_Identifier (Parameter);
-         Condition         : Node_Id;
+            Use_Opaque_Representation := False;
 
-         Designated_Object : Node_Id;
-         pragma Warnings (Off, Designated_Object);
-         --  Is it really right that this is unreferenced ???
+            if Has_Stream_Attribute_Definition
+                 (Typ, TSS_Stream_Output, At_Any_Place => True)
+              or else
+               Has_Stream_Attribute_Definition
+                 (Typ, TSS_Stream_Write, At_Any_Place => True)
+            then
+               --  If user-defined stream attributes are specified for this
+               --  type, use them and transmit data as an opaque sequence of
+               --  stream elements.
+
+               Use_Opaque_Representation := True;
+
+            elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
+               Append_To (Stms,
+                 Make_Simple_Return_Statement (Loc,
+                   Expression =>
+                     OK_Convert_To (Typ,
+                       Build_From_Any_Call
+                         (Root_Type (Typ),
+                          New_Occurrence_Of (Any_Parameter, Loc),
+                          Decls))));
+
+            elsif Is_Record_Type (Typ)
+              and then not Is_Derived_Type (Typ)
+              and then not Is_Tagged_Type (Typ)
+            then
+               if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
+                  Append_To (Stms,
+                    Make_Simple_Return_Statement (Loc,
+                      Expression =>
+                        OK_Convert_To (Typ,
+                          Build_From_Any_Call
+                            (Etype (Typ),
+                             New_Occurrence_Of (Any_Parameter, Loc),
+                             Decls))));
 
-      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;
+               else
+                  declare
+                     Disc                      : Entity_Id := Empty;
+                     Discriminant_Associations : List_Id;
+                     Rdef                      : constant Node_Id :=
+                                                   Type_Definition
+                                                     (Declaration_Node (Typ));
+                     Component_Counter         : Int := 0;
+
+                     --  The returned object
+
+                     Res : constant Entity_Id :=
+                             Make_Defining_Identifier (Loc,
+                               New_Internal_Name ('R'));
+
+                     Res_Definition : Node_Id := New_Occurrence_Of (Typ, Loc);
+
+                     procedure FA_Rec_Add_Process_Element
+                       (Stmts   : List_Id;
+                        Any     : Entity_Id;
+                        Counter : in out Int;
+                        Rec     : Entity_Id;
+                        Field   : Node_Id);
+
+                     procedure FA_Append_Record_Traversal is
+                        new Append_Record_Traversal
+                          (Rec                 => Res,
+                           Add_Process_Element => FA_Rec_Add_Process_Element);
+
+                     --------------------------------
+                     -- FA_Rec_Add_Process_Element --
+                     --------------------------------
+
+                     procedure FA_Rec_Add_Process_Element
+                       (Stmts   : List_Id;
+                        Any     : Entity_Id;
+                        Counter : in out Int;
+                        Rec     : Entity_Id;
+                        Field   : Node_Id)
+                     is
+                     begin
+                        if Nkind (Field) = N_Defining_Identifier then
+
+                           --  A regular component
+
+                           Append_To (Stmts,
+                             Make_Assignment_Statement (Loc,
+                               Name => Make_Selected_Component (Loc,
+                                 Prefix        =>
+                                   New_Occurrence_Of (Rec, Loc),
+                                 Selector_Name =>
+                                   New_Occurrence_Of (Field, Loc)),
+                               Expression =>
+                                 Build_From_Any_Call (Etype (Field),
+                                   Build_Get_Aggregate_Element (Loc,
+                                     Any => Any,
+                                     TC  => Build_TypeCode_Call (Loc,
+                                              Etype (Field), Decls),
+                                     Idx => Make_Integer_Literal (Loc,
+                                              Counter)),
+                                   Decls)));
+
+                        else
+                           --  A variant part
+
+                           declare
+                              Variant        : Node_Id;
+                              Struct_Counter : Int := 0;
+
+                              Block_Decls : constant List_Id := New_List;
+                              Block_Stmts : constant List_Id := New_List;
+                              VP_Stmts    : List_Id;
+
+                              Alt_List    : constant List_Id := New_List;
+                              Choice_List : List_Id;
+
+                              Struct_Any : constant Entity_Id :=
+                                             Make_Defining_Identifier (Loc,
+                                               New_Internal_Name ('S'));
+
+                           begin
+                              Append_To (Decls,
+                                Make_Object_Declaration (Loc,
+                                  Defining_Identifier => Struct_Any,
+                                  Constant_Present    => True,
+                                  Object_Definition   =>
+                                     New_Occurrence_Of (RTE (RE_Any), Loc),
+                                  Expression          =>
+                                    Make_Function_Call (Loc,
+                                      Name =>
+                                        New_Occurrence_Of
+                                          (RTE (RE_Extract_Union_Value), Loc),
+
+                                      Parameter_Associations => New_List (
+                                        Build_Get_Aggregate_Element (Loc,
+                                          Any => Any,
+                                          TC  =>
+                                            Make_Function_Call (Loc,
+                                              Name => New_Occurrence_Of (
+                                                RTE (RE_Any_Member_Type), Loc),
+                                              Parameter_Associations =>
+                                                New_List (
+                                                  New_Occurrence_Of (Any, Loc),
+                                                  Make_Integer_Literal (Loc,
+                                                    Intval => Counter))),
+                                          Idx =>
+                                            Make_Integer_Literal (Loc,
+                                             Intval => Counter))))));
+
+                              Append_To (Stmts,
+                                Make_Block_Statement (Loc,
+                                  Declarations => Block_Decls,
+                                  Handled_Statement_Sequence =>
+                                    Make_Handled_Sequence_Of_Statements (Loc,
+                                      Statements => Block_Stmts)));
+
+                              Append_To (Block_Stmts,
+                                Make_Case_Statement (Loc,
+                                    Expression =>
+                                      Make_Selected_Component (Loc,
+                                        Prefix        => Rec,
+                                        Selector_Name => Chars (Name (Field))),
+                                    Alternatives => Alt_List));
+
+                              Variant := First_Non_Pragma (Variants (Field));
+                              while Present (Variant) loop
+                                 Choice_List :=
+                                   New_Copy_List_Tree
+                                     (Discrete_Choices (Variant));
+
+                                 VP_Stmts := New_List;
+
+                                 --  Struct_Counter should be reset before
+                                 --  handling a variant part. Indeed only one
+                                 --  of the case statement alternatives will be
+                                 --  executed at run-time, so the counter must
+                                 --  start at 0 for every case statement.
+
+                                 Struct_Counter := 0;
+
+                                 FA_Append_Record_Traversal (
+                                   Stmts     => VP_Stmts,
+                                   Clist     => Component_List (Variant),
+                                   Container => Struct_Any,
+                                   Counter   => Struct_Counter);
+
+                                 Append_To (Alt_List,
+                                   Make_Case_Statement_Alternative (Loc,
+                                     Discrete_Choices => Choice_List,
+                                     Statements       => VP_Stmts));
+                                 Next_Non_Pragma (Variant);
+                              end loop;
+                           end;
+                        end if;
+
+                        Counter := Counter + 1;
+                     end FA_Rec_Add_Process_Element;
+
+                  begin
+                     --  First all discriminants
+
+                     if Has_Discriminants (Typ) then
+                        Discriminant_Associations := New_List;
+
+                        Disc := First_Discriminant (Typ);
+                        while Present (Disc) loop
+                           declare
+                              Disc_Var_Name : constant Entity_Id :=
+                                                Make_Defining_Identifier (Loc,
+                                                  Chars => Chars (Disc));
+                              Disc_Type     : constant Entity_Id :=
+                                                Etype (Disc);
+
+                           begin
+                              Append_To (Decls,
+                                Make_Object_Declaration (Loc,
+                                  Defining_Identifier => Disc_Var_Name,
+                                  Constant_Present    => True,
+                                  Object_Definition   =>
+                                    New_Occurrence_Of (Disc_Type, Loc),
+
+                                  Expression =>
+                                    Build_From_Any_Call (Disc_Type,
+                                      Build_Get_Aggregate_Element (Loc,
+                                        Any => Any_Parameter,
+                                        TC  => Build_TypeCode_Call
+                                                 (Loc, Disc_Type, Decls),
+                                        Idx => Make_Integer_Literal (Loc,
+                                               Intval => Component_Counter)),
+                                      Decls)));
+
+                              Component_Counter := Component_Counter + 1;
+
+                              Append_To (Discriminant_Associations,
+                                Make_Discriminant_Association (Loc,
+                                  Selector_Names => New_List (
+                                    New_Occurrence_Of (Disc, Loc)),
+                                  Expression =>
+                                    New_Occurrence_Of (Disc_Var_Name, Loc)));
+                           end;
+                           Next_Discriminant (Disc);
+                        end loop;
+
+                        Res_Definition :=
+                          Make_Subtype_Indication (Loc,
+                            Subtype_Mark => Res_Definition,
+                            Constraint   =>
+                              Make_Index_Or_Discriminant_Constraint (Loc,
+                                Discriminant_Associations));
+                     end if;
+
+                     --  Now we have all the discriminants in variables, we can
+                     --  declared a constrained object. Note that we are not
+                     --  initializing (non-discriminant) components directly in
+                     --  the object declarations, because which fields to
+                     --  initialize depends (at run time) on the discriminant
+                     --  values.
+
+                     Append_To (Decls,
+                       Make_Object_Declaration (Loc,
+                         Defining_Identifier => Res,
+                         Object_Definition   => Res_Definition));
+
+                     --  ... then all components
+
+                     FA_Append_Record_Traversal (Stms,
+                       Clist     => Component_List (Rdef),
+                       Container => Any_Parameter,
+                       Counter   => Component_Counter);
+
+                     Append_To (Stms,
+                       Make_Simple_Return_Statement (Loc,
+                         Expression => New_Occurrence_Of (Res, Loc)));
+                  end;
+               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)),
+            elsif Is_Array_Type (Typ) then
+               declare
+                  Constrained : constant Boolean := Is_Constrained (Typ);
+
+                  procedure FA_Ary_Add_Process_Element
+                    (Stmts   : List_Id;
+                     Any     : Entity_Id;
+                     Counter : Entity_Id;
+                     Datum   : Node_Id);
+                  --  Assign the current element (as identified by Counter) of
+                  --  Any to the variable denoted by name Datum, and advance
+                  --  Counter by 1. If Datum is not an Any, a call to From_Any
+                  --  for its type is inserted.
+
+                  --------------------------------
+                  -- FA_Ary_Add_Process_Element --
+                  --------------------------------
+
+                  procedure FA_Ary_Add_Process_Element
+                    (Stmts   : List_Id;
+                     Any     : Entity_Id;
+                     Counter : Entity_Id;
+                     Datum   : Node_Id)
+                  is
+                     Assignment : constant Node_Id :=
+                       Make_Assignment_Statement (Loc,
+                         Name       => Datum,
+                         Expression => Empty);
+
+                     Element_Any : Node_Id;
+
+                  begin
+                     declare
+                        Element_TC : Node_Id;
+
+                     begin
+                        if Etype (Datum) = RTE (RE_Any) then
+
+                           --  When Datum is an Any the Etype field is not
+                           --  sufficient to determine the typecode of Datum
+                           --  (which can be a TC_SEQUENCE or TC_ARRAY
+                           --  depending on the value of Constrained).
+
+                           --  Therefore we retrieve the typecode which has
+                           --  been constructed in Append_Array_Traversal with
+                           --  a call to Get_Any_Type.
+
+                           Element_TC :=
+                             Make_Function_Call (Loc,
+                               Name => New_Occurrence_Of (
+                                 RTE (RE_Get_Any_Type), Loc),
+                               Parameter_Associations => New_List (
+                                 New_Occurrence_Of (Entity (Datum), Loc)));
+                        else
+                           --  For non Any Datum we simply construct a typecode
+                           --  matching the Etype of the Datum.
+
+                           Element_TC := Build_TypeCode_Call
+                              (Loc, Etype (Datum), Decls);
+                        end if;
+
+                        Element_Any :=
+                          Build_Get_Aggregate_Element (Loc,
+                            Any => Any,
+                            TC  => Element_TC,
+                            Idx => New_Occurrence_Of (Counter, Loc));
+                     end;
+
+                     --  Note: here we *prepend* statements to Stmts, so
+                     --  we must do it in reverse order.
+
+                     Prepend_To (Stmts,
+                       Make_Assignment_Statement (Loc,
+                         Name =>
+                           New_Occurrence_Of (Counter, Loc),
+                         Expression =>
+                           Make_Op_Add (Loc,
+                             Left_Opnd  => New_Occurrence_Of (Counter, Loc),
+                             Right_Opnd => Make_Integer_Literal (Loc, 1))));
+
+                     if Nkind (Datum) /= N_Attribute_Reference then
+
+                        --  We ignore the value of the length of each
+                        --  dimension, since the target array has already
+                        --  been constrained anyway.
+
+                        if Etype (Datum) /= RTE (RE_Any) then
+                           Set_Expression (Assignment,
+                              Build_From_Any_Call
+                                (Component_Type (Typ), Element_Any, Decls));
+                        else
+                           Set_Expression (Assignment, Element_Any);
+                        end if;
+
+                        Prepend_To (Stmts, Assignment);
+                     end if;
+                  end FA_Ary_Add_Process_Element;
+
+                  ------------------------
+                  -- Local Declarations --
+                  ------------------------
+
+                  Counter : constant Entity_Id :=
+                              Make_Defining_Identifier (Loc, Name_J);
+
+                  Initial_Counter_Value : Int := 0;
+
+                  Component_TC : constant Entity_Id :=
+                                   Make_Defining_Identifier (Loc, Name_T);
+
+                  Res : constant Entity_Id :=
+                          Make_Defining_Identifier (Loc, Name_R);
+
+                  procedure Append_From_Any_Array_Iterator is
+                    new Append_Array_Traversal (
+                      Subprogram => Fnam,
+                      Arry       => Res,
+                      Indices    => New_List,
+                      Add_Process_Element => FA_Ary_Add_Process_Element);
+
+                  Res_Subtype_Indication : Node_Id :=
+                                             New_Occurrence_Of (Typ, Loc);
 
-             Right_Opnd =>
-               Make_Selected_Component (Loc,
-                 Prefix        =>
-                   New_Occurrence_Of (Controlling_Parameter, Loc),
-               Selector_Name =>
-                 Make_Identifier (Loc, Name_Origin)));
+               begin
+                  if not Constrained then
+                     declare
+                        Ndim : constant Int := Number_Dimensions (Typ);
+                        Lnam : Name_Id;
+                        Hnam : Name_Id;
+                        Indx : Node_Id := First_Index (Typ);
+                        Indt : Entity_Id;
+
+                        Ranges : constant List_Id := New_List;
+
+                     begin
+                        for J in 1 .. Ndim loop
+                           Lnam := New_External_Name ('L', J);
+                           Hnam := New_External_Name ('H', J);
+                           Indt := Etype (Indx);
+
+                           Append_To (Decls,
+                             Make_Object_Declaration (Loc,
+                               Defining_Identifier =>
+                                 Make_Defining_Identifier (Loc, Lnam),
+                               Constant_Present    => True,
+                               Object_Definition   =>
+                                 New_Occurrence_Of (Indt, Loc),
+                               Expression          =>
+                                 Build_From_Any_Call
+                                   (Indt,
+                                    Build_Get_Aggregate_Element (Loc,
+                                      Any => Any_Parameter,
+                                      TC  => Build_TypeCode_Call
+                                               (Loc, Indt, Decls),
+                                      Idx =>
+                                        Make_Integer_Literal (Loc, J - 1)),
+                                   Decls)));
+
+                           Append_To (Decls,
+                             Make_Object_Declaration (Loc,
+                               Defining_Identifier =>
+                                 Make_Defining_Identifier (Loc, Hnam),
+
+                               Constant_Present => True,
+
+                               Object_Definition =>
+                                 New_Occurrence_Of (Indt, Loc),
+
+                               Expression => Make_Attribute_Reference (Loc,
+                                 Prefix         =>
+                                   New_Occurrence_Of (Indt, Loc),
+
+                                 Attribute_Name => Name_Val,
+
+                                 Expressions    => New_List (
+                                   Make_Op_Subtract (Loc,
+                                     Left_Opnd =>
+                                       Make_Op_Add (Loc,
+                                         Left_Opnd =>
+                                           OK_Convert_To (
+                                             Standard_Long_Integer,
+                                             Make_Identifier (Loc, Lnam)),
+
+                                         Right_Opnd =>
+                                           OK_Convert_To (
+                                             Standard_Long_Integer,
+                                             Make_Function_Call (Loc,
+                                               Name =>
+                                                 New_Occurrence_Of (RTE (
+                                                 RE_Get_Nested_Sequence_Length
+                                                 ), Loc),
+                                               Parameter_Associations =>
+                                                 New_List (
+                                                   New_Occurrence_Of (
+                                                     Any_Parameter, Loc),
+                                                   Make_Integer_Literal (Loc,
+                                                     Intval => J))))),
+
+                                     Right_Opnd =>
+                                       Make_Integer_Literal (Loc, 1))))));
+
+                           Append_To (Ranges,
+                             Make_Range (Loc,
+                               Low_Bound  => Make_Identifier (Loc, Lnam),
+                               High_Bound => Make_Identifier (Loc, Hnam)));
+
+                           Next_Index (Indx);
+                        end loop;
+
+                        --  Now we have all the necessary bound information:
+                        --  apply the set of range constraints to the
+                        --  (unconstrained) nominal subtype of Res.
+
+                        Initial_Counter_Value := Ndim;
+                        Res_Subtype_Indication := Make_Subtype_Indication (Loc,
+                          Subtype_Mark => Res_Subtype_Indication,
+                          Constraint   =>
+                            Make_Index_Or_Discriminant_Constraint (Loc,
+                              Constraints => Ranges));
+                     end;
+                  end if;
 
-         Append_To (Decls,
-           Make_Raise_Constraint_Error (Loc,
-             Condition       =>
-               Make_Op_Not (Loc, Right_Opnd => Condition),
-             Reason => CE_Partition_Check_Failed));
-      end Insert_Partition_Check;
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Res,
+                      Object_Definition => Res_Subtype_Indication));
+                  Set_Etype (Res, Typ);
 
-   --  Start of processing for Build_Subprogram_Calling_Stubs
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Counter,
+                      Object_Definition =>
+                        New_Occurrence_Of (RTE (RE_Long_Unsigned), Loc),
+                      Expression =>
+                        Make_Integer_Literal (Loc, Initial_Counter_Value)));
 
-   begin
-      Target_Partition :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Component_TC,
+                      Constant_Present    => True,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_TypeCode), Loc),
+                      Expression          =>
+                        Build_TypeCode_Call (Loc,
+                          Component_Type (Typ), Decls)));
 
-      Subp_Spec := Copy_Specification (Loc,
-        Spec     => Specification (Vis_Decl),
-        New_Name => New_Name);
+                  Append_From_Any_Array_Iterator
+                    (Stms, Any_Parameter, Counter);
 
-      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;
+                  Append_To (Stms,
+                    Make_Simple_Return_Statement (Loc,
+                      Expression => New_Occurrence_Of (Res, Loc)));
+               end;
 
-      --  Find a controlling argument if we have a stub type. Also check
-      --  if this subprogram can be made asynchronous.
+            elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
+               Append_To (Stms,
+                 Make_Simple_Return_Statement (Loc,
+                   Expression =>
+                     Unchecked_Convert_To (Typ,
+                       Build_From_Any_Call
+                         (Find_Numeric_Representation (Typ),
+                          New_Occurrence_Of (Any_Parameter, Loc),
+                          Decls))));
 
-      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
+            else
+               Use_Opaque_Representation := True;
+            end if;
 
-               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;
+            if Use_Opaque_Representation then
 
-               Next (Current_Parameter);
-            end loop;
-         end;
-      end if;
+               --  Default: type is represented as an opaque sequence of bytes
 
-      if Stub_Type /= Empty then
-         pragma Assert (Controlling_Parameter /= Empty);
+               declare
+                  Strm : constant Entity_Id :=
+                           Make_Defining_Identifier (Loc,
+                             Chars => New_Internal_Name ('S'));
+                  Res  : constant Entity_Id :=
+                           Make_Defining_Identifier (Loc,
+                             Chars => New_Internal_Name ('R'));
 
-         Append_To (Decls,
-           Make_Object_Declaration (Loc,
-             Defining_Identifier => Target_Partition,
-             Constant_Present    => True,
-             Object_Definition   =>
-               New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
+               begin
+                  --  Strm : Buffer_Stream_Type;
 
-             Expression          =>
-               Make_Selected_Component (Loc,
-                 Prefix        =>
-                   New_Occurrence_Of (Controlling_Parameter, Loc),
-                 Selector_Name =>
-                   Make_Identifier (Loc, Name_Origin))));
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Strm,
+                      Aliased_Present     => True,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
 
-         RPC_Receiver :=
-           Make_Selected_Component (Loc,
-             Prefix        =>
-               New_Occurrence_Of (Controlling_Parameter, Loc),
-             Selector_Name =>
-               Make_Identifier (Loc, Name_Receiver));
+                  --  Allocate_Buffer (Strm);
 
-      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),
+                  Append_To (Stms,
+                    Make_Procedure_Call_Statement (Loc,
+                      Name =>
+                        New_Occurrence_Of (RTE (RE_Allocate_Buffer), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Strm, 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)))));
+                  --  Any_To_BS (Strm, A);
 
-         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;
+                  Append_To (Stms,
+                    Make_Procedure_Call_Statement (Loc,
+                      Name => New_Occurrence_Of (RTE (RE_Any_To_BS), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Any_Parameter, Loc),
+                        New_Occurrence_Of (Strm, Loc))));
+
+                  --  declare
+                  --     Res : constant T := T'Input (Strm);
+                  --  begin
+                  --     Release_Buffer (Strm);
+                  --     return Res;
+                  --  end;
+
+                  Append_To (Stms, Make_Block_Statement (Loc,
+                    Declarations => New_List (
+                      Make_Object_Declaration (Loc,
+                        Defining_Identifier => Res,
+                        Constant_Present    => True,
+                        Object_Definition   => New_Occurrence_Of (Typ, Loc),
+                        Expression          =>
+                            Make_Attribute_Reference (Loc,
+                              Prefix         => New_Occurrence_Of (Typ, Loc),
+                              Attribute_Name => Name_Input,
+                              Expressions => New_List (
+                                Make_Attribute_Reference (Loc,
+                                  Prefix => New_Occurrence_Of (Strm, Loc),
+                                  Attribute_Name => Name_Access))))),
+
+                    Handled_Statement_Sequence =>
+                      Make_Handled_Sequence_Of_Statements (Loc,
+                        Statements => New_List (
+                          Make_Procedure_Call_Statement (Loc,
+                            Name =>
+                              New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
+                            Parameter_Associations =>
+                              New_List (New_Occurrence_Of (Strm, Loc))),
+                          Make_Simple_Return_Statement (Loc,
+                            Expression => New_Occurrence_Of (Res, Loc))))));
 
-      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;
+               end;
+            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);
+            Decl :=
+              Make_Subprogram_Body (Loc,
+                Specification => Spec,
+                Declarations => Decls,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => Stms));
+         end Build_From_Any_Function;
+
+         ---------------------------------
+         -- Build_Get_Aggregate_Element --
+         ---------------------------------
+
+         function Build_Get_Aggregate_Element
+           (Loc : Source_Ptr;
+            Any : Entity_Id;
+            TC  : Node_Id;
+            Idx : Node_Id) return Node_Id
+         is
+         begin
+            return Make_Function_Call (Loc,
+              Name =>
+                New_Occurrence_Of (RTE (RE_Get_Aggregate_Element), Loc),
+              Parameter_Associations => New_List (
+                New_Occurrence_Of (Any, Loc),
+                TC,
+                Idx));
+         end Build_Get_Aggregate_Element;
+
+         -------------------------
+         -- Build_Reposiroty_Id --
+         -------------------------
+
+         procedure Build_Name_And_Repository_Id
+           (E           : Entity_Id;
+            Name_Str    : out String_Id;
+            Repo_Id_Str : out String_Id)
+         is
+         begin
+            Start_String;
+            Store_String_Chars ("DSA:");
+            Get_Library_Unit_Name_String (Scope (E));
+            Store_String_Chars
+              (Name_Buffer (Name_Buffer'First ..
+               Name_Buffer'First + Name_Len - 1));
+            Store_String_Char ('.');
+            Get_Name_String (Chars (E));
+            Store_String_Chars
+              (Name_Buffer (Name_Buffer'First ..
+               Name_Buffer'First + Name_Len - 1));
+            Store_String_Chars (":1.0");
+            Repo_Id_Str := End_String;
+            Name_Str    := String_From_Name_Buffer;
+         end Build_Name_And_Repository_Id;
+
+         -----------------------
+         -- Build_To_Any_Call --
+         -----------------------
+
+         function Build_To_Any_Call
+           (N     : Node_Id;
+            Decls : List_Id) return Node_Id
+         is
+            Loc : constant Source_Ptr := Sloc (N);
+
+            Typ     : Entity_Id := Etype (N);
+            U_Type  : Entity_Id;
+            Fnam    : Entity_Id := Empty;
+            Lib_RE  : RE_Id := RE_Null;
 
-      RCI_Calling_Stubs_Table.Set
-        (Defining_Unit_Name (Specification (Vis_Decl)),
-         Defining_Unit_Name (Spec_To_Use));
+         begin
+            --  If N is a selected component, then maybe its Etype has not been
+            --  set yet: try to use Etype of the selector_name in that case.
 
-      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;
+            if No (Typ) and then Nkind (N) = N_Selected_Component then
+               Typ := Etype (Selector_Name (N));
+            end if;
+            pragma Assert (Present (Typ));
 
-   -------------------------
-   -- Build_Subprogram_Id --
-   -------------------------
+            --  Get full view for private type, completion for incomplete type
 
-   function Build_Subprogram_Id
-     (Loc : Source_Ptr;
-      E   : Entity_Id) return Node_Id
-   is
-   begin
-      return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
-   end Build_Subprogram_Id;
+            U_Type := Underlying_Type (Typ);
 
-   --------------------------------------
-   -- Build_Subprogram_Receiving_Stubs --
-   --------------------------------------
+            --  First simple case where the To_Any function is present in the
+            --  type's TSS.
 
-   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);
+            Fnam := Find_Inherited_TSS (U_Type, TSS_To_Any);
 
-      Stream_Parameter : Node_Id;
-      Result_Parameter : Node_Id;
-      --  See explanations of those in Build_Subprogram_Calling_Stubs
+            --  Check first for Boolean and Character. These are enumeration
+            --  types, but we treat them specially, since they may require
+            --  special handling in the transfer protocol. However, this
+            --  special handling only applies if they have standard
+            --  representation, otherwise they are treated like any other
+            --  enumeration type.
 
-      Decls : constant List_Id := New_List;
-      --  All the parameters will get declared before calling the real
-      --  subprograms. Also the out parameters will be declared.
+            if Sloc (U_Type) <= Standard_Location then
+               U_Type := Base_Type (U_Type);
+            end if;
 
-      Statements : constant List_Id := New_List;
+            if Present (Fnam) then
+               null;
 
-      Extra_Formal_Statements : constant List_Id := New_List;
-      --  Statements concerning extra formal parameters
+            elsif U_Type = Standard_Boolean then
+               Lib_RE := RE_TA_B;
 
-      After_Statements : constant List_Id := New_List;
-      --  Statements to be executed after the subprogram call
+            elsif U_Type = Standard_Character then
+               Lib_RE := RE_TA_C;
 
-      Inner_Decls : List_Id := No_List;
-      --  In case of a function, the inner declarations are needed since
-      --  the result may be unconstrained.
+            elsif U_Type = Standard_Wide_Character then
+               Lib_RE := RE_TA_WC;
 
-      Excep_Handler : Node_Id;
-      Excep_Choice  : Entity_Id;
-      Excep_Code    : List_Id;
+            elsif U_Type = Standard_Wide_Wide_Character then
+               Lib_RE := RE_TA_WWC;
 
-      Parameter_List : constant List_Id := New_List;
-      --  List of parameters to be passed to the subprogram
+            --  Floating point types
 
-      Current_Parameter : Node_Id;
+            elsif U_Type = Standard_Short_Float then
+               Lib_RE := RE_TA_SF;
 
-      Ordered_Parameters_List : constant List_Id :=
-                                  Build_Ordered_Parameters_List
-                                    (Specification (Vis_Decl));
+            elsif U_Type = Standard_Float then
+               Lib_RE := RE_TA_F;
 
-      Subp_Spec : Node_Id;
-      --  Subprogram specification
+            elsif U_Type = Standard_Long_Float then
+               Lib_RE := RE_TA_LF;
 
-      Called_Subprogram : Node_Id;
-      --  The subprogram to call
+            elsif U_Type = Standard_Long_Long_Float then
+               Lib_RE := RE_TA_LLF;
 
-      Null_Raise_Statement : Node_Id;
+            --  Integer types
 
-      Dynamic_Async : Entity_Id;
+            elsif U_Type = Etype (Standard_Short_Short_Integer) then
+                  Lib_RE := RE_TA_SSI;
 
-   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;
+            elsif U_Type = Etype (Standard_Short_Integer) then
+               Lib_RE := RE_TA_SI;
 
-      Stream_Parameter :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+            elsif U_Type = Etype (Standard_Integer) then
+               Lib_RE := RE_TA_I;
 
-      if Dynamically_Asynchronous then
-         Dynamic_Async :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
-      else
-         Dynamic_Async := Empty;
-      end if;
+            elsif U_Type = Etype (Standard_Long_Integer) then
+               Lib_RE := RE_TA_LI;
 
-      if not Asynchronous or else Dynamically_Asynchronous then
-         Result_Parameter :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+            elsif U_Type = Etype (Standard_Long_Long_Integer) then
+               Lib_RE := RE_TA_LLI;
 
-         --  The first statement after the subprogram call is a statement to
-         --  writes a Null_Occurrence into the result stream.
+            --  Unsigned integer types
 
-         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)));
+            elsif U_Type = RTE (RE_Short_Short_Unsigned) then
+               Lib_RE := RE_TA_SSU;
 
-         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;
+            elsif U_Type = RTE (RE_Short_Unsigned) then
+               Lib_RE := RE_TA_SU;
 
-         Append_To (After_Statements, Null_Raise_Statement);
+            elsif U_Type = RTE (RE_Unsigned) then
+               Lib_RE := RE_TA_U;
 
-      else
-         Result_Parameter := Empty;
-      end if;
+            elsif U_Type = RTE (RE_Long_Unsigned) then
+               Lib_RE := RE_TA_LU;
 
-      --  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.
+            elsif U_Type = RTE (RE_Long_Long_Unsigned) then
+               Lib_RE := RE_TA_LLU;
 
-      Current_Parameter := First (Ordered_Parameters_List);
+            elsif U_Type = Standard_String then
+               Lib_RE := RE_TA_String;
 
-      while Current_Parameter /= Empty loop
+            --  Special DSA types
 
-         declare
-            Etyp        : Entity_Id;
-            Constrained : Boolean;
-            Object      : Entity_Id;
-            Expr        : Node_Id := Empty;
+            elsif Is_RTE (U_Type, RE_Any_Content_Ptr) then
+               Lib_RE := RE_TA_A;
 
-         begin
-            Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
-            Set_Ekind (Object, E_Variable);
+            elsif U_Type = Underlying_Type (RTE (RE_TypeCode)) then
+               --  No corresponding FA_TC ???
+               Lib_RE := RE_TA_TC;
 
-            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.
+            --  Other (non-primitive) types
 
-               Etyp := RTE (RE_Unsigned_64);
             else
-               Etyp := Etype (Parameter_Type (Current_Parameter));
+               declare
+                  Decl : Entity_Id;
+               begin
+                  Build_To_Any_Function (Loc, U_Type, Decl, Fnam);
+                  Append_To (Decls, Decl);
+               end;
             end if;
 
-            Constrained :=
-              Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
+            --  Call the function
 
-            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 Lib_RE /= RE_Null then
+               pragma Assert (No (Fnam));
+               Fnam := RTE (Lib_RE);
+            end if;
 
-               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))));
+            return
+                Make_Function_Call (Loc,
+                  Name                   => New_Occurrence_Of (Fnam, Loc),
+                  Parameter_Associations =>
+                    New_List (Unchecked_Convert_To (U_Type, N)));
+         end Build_To_Any_Call;
+
+         ---------------------------
+         -- Build_To_Any_Function --
+         ---------------------------
+
+         procedure Build_To_Any_Function
+           (Loc  : Source_Ptr;
+            Typ  : Entity_Id;
+            Decl : out Node_Id;
+            Fnam : out Entity_Id)
+         is
+            Spec  : Node_Id;
+            Decls : constant List_Id := New_List;
+            Stms  : constant List_Id := New_List;
+
+            Expr_Parameter : constant Entity_Id :=
+                               Make_Defining_Identifier (Loc, Name_E);
+
+            Any : constant Entity_Id :=
+                    Make_Defining_Identifier (Loc, Name_A);
+
+            Any_Decl  : Node_Id;
+            Result_TC : Node_Id := Build_TypeCode_Call (Loc, Typ, Decls);
+
+            Use_Opaque_Representation : Boolean;
+            --  When True, use stream attributes and represent type as an
+            --  opaque sequence of bytes.
 
-               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;
+         begin
+            if Is_Itype (Typ) then
+               Build_To_Any_Function
+                  (Loc  => Loc,
+                  Typ  => Etype (Typ),
+                  Decl => Decl,
+                  Fnam => Fnam);
+               return;
             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.
+            Fnam := Make_Helper_Function_Name (Loc, Typ, Name_To_Any);
 
-            Append_To (Decls,
+            Spec :=
+              Make_Function_Specification (Loc,
+                Defining_Unit_Name => Fnam,
+                Parameter_Specifications => New_List (
+                  Make_Parameter_Specification (Loc,
+                    Defining_Identifier => Expr_Parameter,
+                    Parameter_Type => New_Occurrence_Of (Typ, Loc))),
+                Result_Definition  => New_Occurrence_Of (RTE (RE_Any), Loc));
+            Set_Etype (Expr_Parameter, Typ);
+
+            Any_Decl :=
               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;
+                Defining_Identifier => Any,
+                Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc));
+
+            Use_Opaque_Representation := False;
 
-            if
-              Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
+            if Has_Stream_Attribute_Definition
+                 (Typ, TSS_Stream_Output, At_Any_Place => True)
+              or else
+               Has_Stream_Attribute_Definition
+                 (Typ, TSS_Stream_Write,  At_Any_Place => True)
             then
+               --  If user-defined stream attributes are specified for this
+               --  type, use them and transmit data as an opaque sequence of
+               --  stream elements.
+
+               Use_Opaque_Representation := True;
+
+            elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
+
+               --  Non-tagged derived type: convert to root type
+
+               declare
+                  Rt_Type : constant Entity_Id := Root_Type (Typ);
+                  Expr    : constant Node_Id :=
+                              OK_Convert_To
+                                (Rt_Type,
+                                 New_Occurrence_Of (Expr_Parameter, Loc));
+               begin
+                  Set_Expression (Any_Decl, Build_To_Any_Call (Expr, Decls));
+               end;
+
+            elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then
+
+               --  Non-tagged record type
+
+               if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
+                  declare
+                     Rt_Type : constant Entity_Id := Etype (Typ);
+                     Expr    : constant Node_Id :=
+                                 OK_Convert_To (Rt_Type,
+                                   New_Occurrence_Of (Expr_Parameter, Loc));
+
+                  begin
+                     Set_Expression
+                       (Any_Decl, Build_To_Any_Call (Expr, Decls));
+                  end;
+
+               --  Comment needed here (and label on declare block ???)
 
-               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)))));
+                  declare
+                     Disc     : Entity_Id := Empty;
+                     Rdef     : constant Node_Id :=
+                                  Type_Definition (Declaration_Node (Typ));
+                     Counter  : Int := 0;
+                     Elements : constant List_Id := New_List;
+
+                     procedure TA_Rec_Add_Process_Element
+                       (Stmts     : List_Id;
+                        Container : Node_Or_Entity_Id;
+                        Counter   : in out Int;
+                        Rec       : Entity_Id;
+                        Field     : Node_Id);
+                     --  Processing routine for traversal below
+
+                     procedure TA_Append_Record_Traversal is
+                        new Append_Record_Traversal
+                          (Rec                 => Expr_Parameter,
+                           Add_Process_Element => TA_Rec_Add_Process_Element);
+
+                     --------------------------------
+                     -- TA_Rec_Add_Process_Element --
+                     --------------------------------
+
+                     procedure TA_Rec_Add_Process_Element
+                       (Stmts     : List_Id;
+                        Container : Node_Or_Entity_Id;
+                        Counter   : in out Int;
+                        Rec       : Entity_Id;
+                        Field     : Node_Id)
+                     is
+                        Field_Ref : Node_Id;
+
+                     begin
+                        if Nkind (Field) = N_Defining_Identifier then
+
+                           --  A regular component
+
+                           Field_Ref := Make_Selected_Component (Loc,
+                             Prefix        => New_Occurrence_Of (Rec, Loc),
+                             Selector_Name => New_Occurrence_Of (Field, Loc));
+                           Set_Etype (Field_Ref, Etype (Field));
+
+                           Append_To (Stmts,
+                             Make_Procedure_Call_Statement (Loc,
+                               Name =>
+                                 New_Occurrence_Of (
+                                   RTE (RE_Add_Aggregate_Element), Loc),
+                               Parameter_Associations => New_List (
+                                 New_Occurrence_Of (Container, Loc),
+                                 Build_To_Any_Call (Field_Ref, Decls))));
+
+                        else
+                           --  A variant part
+
+                           Variant_Part : declare
+                              Variant        : Node_Id;
+                              Struct_Counter : Int := 0;
+
+                              Block_Decls : constant List_Id := New_List;
+                              Block_Stmts : constant List_Id := New_List;
+                              VP_Stmts    : List_Id;
+
+                              Alt_List    : constant List_Id := New_List;
+                              Choice_List : List_Id;
+
+                              Union_Any : constant Entity_Id :=
+                                            Make_Defining_Identifier (Loc,
+                                              New_Internal_Name ('V'));
+
+                              Struct_Any : constant Entity_Id :=
+                                             Make_Defining_Identifier (Loc,
+                                                New_Internal_Name ('S'));
+
+                              function Make_Discriminant_Reference
+                                return Node_Id;
+                              --  Build reference to the discriminant for this
+                              --  variant part.
+
+                              ---------------------------------
+                              -- Make_Discriminant_Reference --
+                              ---------------------------------
+
+                              function Make_Discriminant_Reference
+                                return Node_Id
+                              is
+                                 Nod : constant Node_Id :=
+                                         Make_Selected_Component (Loc,
+                                           Prefix        => Rec,
+                                           Selector_Name =>
+                                             Chars (Name (Field)));
+                              begin
+                                 Set_Etype (Nod, Etype (Name (Field)));
+                                 return Nod;
+                              end Make_Discriminant_Reference;
+
+                           --  Start processing for Variant_Part
+
+                           begin
+                              Append_To (Stmts,
+                                Make_Block_Statement (Loc,
+                                  Declarations =>
+                                    Block_Decls,
+                                  Handled_Statement_Sequence =>
+                                    Make_Handled_Sequence_Of_Statements (Loc,
+                                      Statements => Block_Stmts)));
+
+                              --  Declare variant part aggregate (Union_Any).
+                              --  Knowing the position of this VP in the
+                              --  variant record, we can fetch the VP typecode
+                              --  from Container.
+
+                              Append_To (Block_Decls,
+                                Make_Object_Declaration (Loc,
+                                  Defining_Identifier => Union_Any,
+                                  Object_Definition   =>
+                                    New_Occurrence_Of (RTE (RE_Any), Loc),
+                                  Expression =>
+                                    Make_Function_Call (Loc,
+                                      Name => New_Occurrence_Of (
+                                                RTE (RE_Create_Any), Loc),
+                                      Parameter_Associations => New_List (
+                                        Make_Function_Call (Loc,
+                                          Name =>
+                                            New_Occurrence_Of (
+                                              RTE (RE_Any_Member_Type), Loc),
+                                          Parameter_Associations => New_List (
+                                            New_Occurrence_Of (Container, Loc),
+                                            Make_Integer_Literal (Loc,
+                                              Counter)))))));
+
+                              --  Declare inner struct aggregate (which
+                              --  contains the components of this VP).
+
+                              Append_To (Block_Decls,
+                                Make_Object_Declaration (Loc,
+                                  Defining_Identifier => Struct_Any,
+                                  Object_Definition   =>
+                                    New_Occurrence_Of (RTE (RE_Any), Loc),
+                                  Expression =>
+                                    Make_Function_Call (Loc,
+                                      Name => New_Occurrence_Of (
+                                        RTE (RE_Create_Any), Loc),
+                                      Parameter_Associations => New_List (
+                                        Make_Function_Call (Loc,
+                                          Name =>
+                                            New_Occurrence_Of (
+                                              RTE (RE_Any_Member_Type), Loc),
+                                          Parameter_Associations => New_List (
+                                            New_Occurrence_Of (Union_Any, Loc),
+                                            Make_Integer_Literal (Loc,
+                                              Uint_1)))))));
+
+                              --  Build case statement
+
+                              Append_To (Block_Stmts,
+                                Make_Case_Statement (Loc,
+                                  Expression   => Make_Discriminant_Reference,
+                                  Alternatives => Alt_List));
+
+                              Variant := First_Non_Pragma (Variants (Field));
+                              while Present (Variant) loop
+                                 Choice_List := New_Copy_List_Tree
+                                   (Discrete_Choices (Variant));
+
+                                 VP_Stmts := New_List;
+
+                                 --  Append discriminant val to union aggregate
+
+                                 Append_To (VP_Stmts,
+                                    Make_Procedure_Call_Statement (Loc,
+                                      Name =>
+                                        New_Occurrence_Of (
+                                          RTE (RE_Add_Aggregate_Element), Loc),
+                                      Parameter_Associations => New_List (
+                                        New_Occurrence_Of (Union_Any, Loc),
+                                          Build_To_Any_Call
+                                            (Make_Discriminant_Reference,
+                                             Block_Decls))));
+
+                                 --  Populate inner struct aggregate
+
+                                 --  Struct_Counter should be reset before
+                                 --  handling a variant part. Indeed only one
+                                 --  of the case statement alternatives will be
+                                 --  executed at run-time, so the counter must
+                                 --  start at 0 for every case statement.
+
+                                 Struct_Counter := 0;
+
+                                 TA_Append_Record_Traversal (
+                                   Stmts     => VP_Stmts,
+                                   Clist     => Component_List (Variant),
+                                   Container => Struct_Any,
+                                   Counter   => Struct_Counter);
+
+                                 --  Append inner struct to union aggregate
+
+                                 Append_To (VP_Stmts,
+                                   Make_Procedure_Call_Statement (Loc,
+                                     Name =>
+                                       New_Occurrence_Of (
+                                         RTE (RE_Add_Aggregate_Element), Loc),
+                                     Parameter_Associations => New_List (
+                                       New_Occurrence_Of (Union_Any, Loc),
+                                       New_Occurrence_Of (Struct_Any, Loc))));
+
+                                 --  Append union to outer aggregate
+
+                                 Append_To (VP_Stmts,
+                                   Make_Procedure_Call_Statement (Loc,
+                                     Name =>
+                                       New_Occurrence_Of (
+                                         RTE (RE_Add_Aggregate_Element), Loc),
+                                       Parameter_Associations => New_List (
+                                          New_Occurrence_Of (Container, Loc),
+                                          New_Occurrence_Of
+                                            (Union_Any, Loc))));
+
+                                 Append_To (Alt_List,
+                                   Make_Case_Statement_Alternative (Loc,
+                                     Discrete_Choices => Choice_List,
+                                     Statements       => VP_Stmts));
+
+                                 Next_Non_Pragma (Variant);
+                              end loop;
+                           end Variant_Part;
+                        end if;
+
+                        Counter := Counter + 1;
+                     end TA_Rec_Add_Process_Element;
+
+                  begin
+                     --  Records are encoded in a TC_STRUCT aggregate:
+
+                     --  -- Outer aggregate (TC_STRUCT)
+                     --  | [discriminant1]
+                     --  | [discriminant2]
+                     --  | ...
+                     --  |
+                     --  | [component1]
+                     --  | [component2]
+                     --  | ...
+
+                     --  A component can be a common component or variant part
+
+                     --  A variant part is encoded as a TC_UNION aggregate:
+
+                     --  -- Variant Part Aggregate (TC_UNION)
+                     --  | [discriminant choice for this Variant Part]
+                     --  |
+                     --  | -- Inner struct (TC_STRUCT)
+                     --  | |  [component1]
+                     --  | |  [component2]
+                     --  | |  ...
+
+                     --  Let's start by building the outer aggregate. First we
+                     --  construct Elements array containing all discriminants.
+
+                     if Has_Discriminants (Typ) then
+                        Disc := First_Discriminant (Typ);
+                        while Present (Disc) loop
+                           declare
+                              Discriminant : constant Entity_Id :=
+                                               Make_Selected_Component (Loc,
+                                                 Prefix        =>
+                                                   Expr_Parameter,
+                                                 Selector_Name =>
+                                                   Chars (Disc));
+
+                           begin
+                              Set_Etype (Discriminant, Etype (Disc));
+
+                              Append_To (Elements,
+                                Make_Component_Association (Loc,
+                                  Choices => New_List (
+                                    Make_Integer_Literal (Loc, Counter)),
+                                  Expression =>
+                                    Build_To_Any_Call (Discriminant, Decls)));
+                           end;
+
+                           Counter := Counter + 1;
+                           Next_Discriminant (Disc);
+                        end loop;
+
+                     else
+                        --  If there are no discriminants, we declare an empty
+                        --  Elements array.
+
+                        declare
+                           Dummy_Any : constant Entity_Id :=
+                                         Make_Defining_Identifier (Loc,
+                                           Chars => New_Internal_Name ('A'));
+
+                        begin
+                           Append_To (Decls,
+                             Make_Object_Declaration (Loc,
+                               Defining_Identifier => Dummy_Any,
+                               Object_Definition   =>
+                                 New_Occurrence_Of (RTE (RE_Any), Loc)));
+
+                           Append_To (Elements,
+                             Make_Component_Association (Loc,
+                               Choices => New_List (
+                                 Make_Range (Loc,
+                                   Low_Bound  =>
+                                     Make_Integer_Literal (Loc, 1),
+                                   High_Bound =>
+                                     Make_Integer_Literal (Loc, 0))),
+                               Expression =>
+                                 New_Occurrence_Of (Dummy_Any, Loc)));
+                        end;
+                     end if;
+
+                     --  We build the result aggregate with discriminants
+                     --  as the first elements.
+
+                     Set_Expression (Any_Decl,
+                       Make_Function_Call (Loc,
+                         Name => New_Occurrence_Of (
+                                   RTE (RE_Any_Aggregate_Build), Loc),
+                         Parameter_Associations => New_List (
+                           Result_TC,
+                           Make_Aggregate (Loc,
+                             Component_Associations => Elements))));
+                     Result_TC := Empty;
+
+                     --  Then we append all the components to the result
+                     --  aggregate.
+
+                     TA_Append_Record_Traversal (Stms,
+                       Clist     => Component_List (Rdef),
+                       Container => Any,
+                       Counter   => Counter);
+                  end;
                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.
+            elsif Is_Array_Type (Typ) then
 
-            --  The case of Extra_Accessibility should also be handled ???
+               --  Constrained and unconstrained array types
 
-            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));
+                  Constrained : constant Boolean := Is_Constrained (Typ);
+
+                  procedure TA_Ary_Add_Process_Element
+                    (Stmts   : List_Id;
+                     Any     : Entity_Id;
+                     Counter : Entity_Id;
+                     Datum   : Node_Id);
+
+                  --------------------------------
+                  -- TA_Ary_Add_Process_Element --
+                  --------------------------------
+
+                  procedure TA_Ary_Add_Process_Element
+                    (Stmts   : List_Id;
+                     Any     : Entity_Id;
+                     Counter : Entity_Id;
+                     Datum   : Node_Id)
+                  is
+                     pragma Warnings (Off);
+                     pragma Unreferenced (Counter);
+                     pragma Warnings (On);
+
+                     Element_Any : Node_Id;
+
+                  begin
+                     if Etype (Datum) = RTE (RE_Any) then
+                        Element_Any := Datum;
+                     else
+                        Element_Any := Build_To_Any_Call (Datum, Decls);
+                     end if;
+
+                     Append_To (Stmts,
+                       Make_Procedure_Call_Statement (Loc,
+                         Name => New_Occurrence_Of (
+                                   RTE (RE_Add_Aggregate_Element), Loc),
+                         Parameter_Associations => New_List (
+                           New_Occurrence_Of (Any, Loc),
+                           Element_Any)));
+                  end TA_Ary_Add_Process_Element;
+
+                  procedure Append_To_Any_Array_Iterator is
+                    new Append_Array_Traversal (
+                      Subprogram => Fnam,
+                      Arry       => Expr_Parameter,
+                      Indices    => New_List,
+                      Add_Process_Element => TA_Ary_Add_Process_Element);
+
+                  Index : Node_Id;
+
+               begin
+                  Set_Expression (Any_Decl,
+                    Make_Function_Call (Loc,
+                      Name =>
+                        New_Occurrence_Of (RTE (RE_Create_Any), Loc),
+                      Parameter_Associations => New_List (Result_TC)));
+                  Result_TC := Empty;
+
+                  if not Constrained then
+                     Index := First_Index (Typ);
+                     for J in 1 .. Number_Dimensions (Typ) loop
+                        Append_To (Stms,
+                          Make_Procedure_Call_Statement (Loc,
+                            Name =>
+                              New_Occurrence_Of (
+                                RTE (RE_Add_Aggregate_Element), Loc),
+                            Parameter_Associations => New_List (
+                              New_Occurrence_Of (Any, Loc),
+                              Build_To_Any_Call (
+                                OK_Convert_To (Etype (Index),
+                                  Make_Attribute_Reference (Loc,
+                                    Prefix         =>
+                                      New_Occurrence_Of (Expr_Parameter, Loc),
+                                    Attribute_Name => Name_First,
+                                    Expressions    => New_List (
+                                      Make_Integer_Literal (Loc, J)))),
+                                Decls))));
+                        Next_Index (Index);
+                     end loop;
+                  end if;
+
+                  Append_To_Any_Array_Iterator (Stms, Any);
+               end;
+
+            elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
 
-                  Formal_Entity : constant Entity_Id :=
-                                    Make_Defining_Identifier
-                                        (Loc, Chars (Extra_Parameter));
+               --  Integer types
 
-                  Formal_Type : constant Entity_Id :=
-                                  Etype (Extra_Parameter);
+               Set_Expression (Any_Decl,
+                 Build_To_Any_Call (
+                   OK_Convert_To (
+                     Find_Numeric_Representation (Typ),
+                     New_Occurrence_Of (Expr_Parameter, Loc)),
+                   Decls));
+
+            else
+               --  Default case, including tagged types: opaque representation
+
+               Use_Opaque_Representation := True;
+            end if;
+
+            if Use_Opaque_Representation then
+               declare
+                  Strm : constant Entity_Id :=
+                           Make_Defining_Identifier (Loc,
+                             Chars => New_Internal_Name ('S'));
+                  --  Stream used to store data representation produced by
+                  --  stream attribute.
 
                begin
+                  --  Generate:
+                  --    Strm : aliased Buffer_Stream_Type;
+
                   Append_To (Decls,
                     Make_Object_Declaration (Loc,
-                      Defining_Identifier => Formal_Entity,
+                      Defining_Identifier =>
+                        Strm,
+                      Aliased_Present     =>
+                        True,
                       Object_Definition   =>
-                        New_Occurrence_Of (Formal_Type, Loc)));
+                        New_Occurrence_Of (RTE (RE_Buffer_Stream_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
+                  --  Generate:
+                  --    Allocate_Buffer (Strm);
 
-      Append_List_To (Statements, Extra_Formal_Statements);
+                  Append_To (Stms,
+                    Make_Procedure_Call_Statement (Loc,
+                      Name =>
+                        New_Occurrence_Of (RTE (RE_Allocate_Buffer), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Strm, Loc))));
 
-      if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
+                  --  Generate:
+                  --    T'Output (Strm'Access, E);
 
-         --  The remote subprogram is a function. We build an inner block to
-         --  be able to hold a potentially unconstrained result in a variable.
+                  Append_To (Stms,
+                      Make_Attribute_Reference (Loc,
+                        Prefix         => New_Occurrence_Of (Typ, Loc),
+                        Attribute_Name => Name_Output,
+                        Expressions    => New_List (
+                          Make_Attribute_Reference (Loc,
+                            Prefix         => New_Occurrence_Of (Strm, Loc),
+                            Attribute_Name => Name_Access),
+                          New_Occurrence_Of (Expr_Parameter, Loc))));
+
+                  --  Generate:
+                  --    BS_To_Any (Strm, A);
+
+                  Append_To (Stms,
+                    Make_Procedure_Call_Statement (Loc,
+                      Name => New_Occurrence_Of (RTE (RE_BS_To_Any), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Strm, Loc),
+                        New_Occurrence_Of (Any, Loc))));
 
-         declare
-            Etyp   : constant Entity_Id :=
-                       Etype (Subtype_Mark (Specification (Vis_Decl)));
-            Result : constant Node_Id   :=
-                       Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+                  --  Generate:
+                  --    Release_Buffer (Strm);
 
-         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 (Stms,
+                    Make_Procedure_Call_Statement (Loc,
+                      Name => New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
+                      Parameter_Associations => New_List (
+                        New_Occurrence_Of (Strm, Loc))));
+               end;
+            end if;
 
-            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 (Decls, Any_Decl);
 
-         Append_To (Statements,
-           Make_Block_Statement (Loc,
-             Declarations               => Inner_Decls,
-             Handled_Statement_Sequence =>
-               Make_Handled_Sequence_Of_Statements (Loc,
-                 Statements => After_Statements)));
+            if Present (Result_TC) then
+               Append_To (Stms,
+                 Make_Procedure_Call_Statement (Loc,
+                   Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
+                   Parameter_Associations => New_List (
+                     New_Occurrence_Of (Any, Loc),
+                     Result_TC)));
+            end if;
 
-      else
-         --  The remote subprogram is a procedure. We do not need any inner
-         --  block in this case.
+            Append_To (Stms,
+              Make_Simple_Return_Statement (Loc,
+                Expression => New_Occurrence_Of (Any, Loc)));
+
+            Decl :=
+              Make_Subprogram_Body (Loc,
+                Specification              => Spec,
+                Declarations               => Decls,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => Stms));
+         end Build_To_Any_Function;
+
+         -------------------------
+         -- Build_TypeCode_Call --
+         -------------------------
+
+         function Build_TypeCode_Call
+           (Loc   : Source_Ptr;
+            Typ   : Entity_Id;
+            Decls : List_Id) return Node_Id
+         is
+            U_Type : Entity_Id := Underlying_Type (Typ);
+            --  The full view, if Typ is private; the completion,
+            --  if Typ is incomplete.
+
+            Fnam   : Entity_Id := Empty;
+            Lib_RE : RE_Id := RE_Null;
+            Expr   : Node_Id;
 
-         if Dynamically_Asynchronous then
-            Append_To (Decls,
-              Make_Object_Declaration (Loc,
-                Defining_Identifier => Dynamic_Async,
-                Object_Definition   =>
-                  New_Occurrence_Of (Standard_Boolean, Loc)));
+         begin
+            --  Special case System.PolyORB.Interface.Any: its primitives have
+            --  not been set yet, so can't call Find_Inherited_TSS.
 
-            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;
+            if Typ = RTE (RE_Any) then
+               Fnam := RTE (RE_TC_A);
 
-         Append_To (Statements,
-           Make_Procedure_Call_Statement (Loc,
-             Name                   => Called_Subprogram,
-             Parameter_Associations => Parameter_List));
+            else
+               --  First simple case where the TypeCode is present
+               --  in the type's TSS.
 
-         Append_List_To (Statements, After_Statements);
+               Fnam := Find_Inherited_TSS (U_Type, TSS_TypeCode);
+            end if;
 
-      end if;
+            if No (Fnam) then
+               if Sloc (U_Type) <= Standard_Location then
 
-      if Asynchronous and then not Dynamically_Asynchronous then
+                  --  Do not try to build alias typecodes for subtypes from
+                  --  Standard.
 
-         --  An asynchronous procedure does not want a Result
-         --  parameter. Also, we put an exception handler with an others
-         --  clause that does nothing.
+                  U_Type := Base_Type (U_Type);
+               end if;
 
-         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)))));
+               if U_Type = Standard_Boolean then
+                  Lib_RE := RE_TC_B;
 
-         Excep_Handler :=
-           Make_Exception_Handler (Loc,
-             Exception_Choices =>
-               New_List (Make_Others_Choice (Loc)),
-             Statements        => New_List (
-               Make_Null_Statement (Loc)));
+               elsif U_Type = Standard_Character then
+                  Lib_RE := RE_TC_C;
 
-      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.
+               elsif U_Type = Standard_Wide_Character then
+                  Lib_RE := RE_TC_WC;
 
-         Excep_Choice :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
+               elsif U_Type = Standard_Wide_Wide_Character then
+                  Lib_RE := RE_TC_WWC;
 
-         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))));
+               --  Floating point types
 
-         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;
+               elsif U_Type = Standard_Short_Float then
+                  Lib_RE := RE_TC_SF;
 
-         Excep_Handler :=
-           Make_Exception_Handler (Loc,
-             Choice_Parameter   => Excep_Choice,
-             Exception_Choices  => New_List (Make_Others_Choice (Loc)),
-             Statements         => Excep_Code);
+               elsif U_Type = Standard_Float then
+                  Lib_RE := RE_TC_F;
 
-         Subp_Spec :=
-           Make_Procedure_Specification (Loc,
-             Defining_Unit_Name       =>
-               Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
+               elsif U_Type = Standard_Long_Float then
+                  Lib_RE := RE_TC_LF;
 
-             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))),
+               elsif U_Type = Standard_Long_Long_Float then
+                  Lib_RE := RE_TC_LLF;
 
-               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;
+               --  Integer types (walk back to the base type)
 
-      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)));
+               elsif U_Type = Etype (Standard_Short_Short_Integer) then
+                     Lib_RE := RE_TC_SSI;
 
-   end Build_Subprogram_Receiving_Stubs;
+               elsif U_Type = Etype (Standard_Short_Integer) then
+                  Lib_RE := RE_TC_SI;
 
-   ------------------------
-   -- Copy_Specification --
-   ------------------------
+               elsif U_Type = Etype (Standard_Integer) then
+                  Lib_RE := RE_TC_I;
 
-   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;
+               elsif U_Type = Etype (Standard_Long_Integer) then
+                  Lib_RE := RE_TC_LI;
 
-      Current_Parameter : Node_Id;
-      Current_Type      : Node_Id;
-      Current_Etype     : Entity_Id;
+               elsif U_Type = Etype (Standard_Long_Long_Integer) then
+                  Lib_RE := RE_TC_LLI;
 
-      Name_For_New_Spec : Name_Id;
+               --  Unsigned integer types
 
-      New_Identifier : Entity_Id;
+               elsif U_Type = RTE (RE_Short_Short_Unsigned) then
+                  Lib_RE := RE_TC_SSU;
 
-   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;
+               elsif U_Type = RTE (RE_Short_Unsigned) then
+                  Lib_RE := RE_TC_SU;
 
-      if Present (Parameter_Specifications (Spec)) then
+               elsif U_Type = RTE (RE_Unsigned) then
+                  Lib_RE := RE_TC_U;
 
-         Parameters        := New_List;
-         Current_Parameter := First (Parameter_Specifications (Spec));
+               elsif U_Type = RTE (RE_Long_Unsigned) then
+                  Lib_RE := RE_TC_LU;
 
-         while Current_Parameter /= Empty loop
+               elsif U_Type = RTE (RE_Long_Long_Unsigned) then
+                  Lib_RE := RE_TC_LLU;
 
-            Current_Type := Parameter_Type (Current_Parameter);
+               elsif U_Type = Standard_String then
+                  Lib_RE := RE_TC_String;
 
-            if Nkind (Current_Type) = N_Access_Definition then
-               Current_Etype := Entity (Subtype_Mark (Current_Type));
+               --  Special DSA types
 
-               if Object_Type = Empty then
-                  Current_Type :=
-                    Make_Access_Definition (Loc,
-                      Subtype_Mark =>
-                        New_Occurrence_Of (Current_Etype, Loc));
-               else
-                  pragma Assert
-                    (Root_Type (Current_Etype) = Root_Type (Object_Type));
-                  Current_Type :=
-                    Make_Access_Definition (Loc,
-                      Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc));
-               end if;
+               elsif Is_RTE (U_Type, RE_Any_Content_Ptr) then
+                  Lib_RE := RE_TC_A;
 
-            else
-               Current_Etype := Entity (Current_Type);
+               --  Other (non-primitive) types
 
-               if Object_Type /= Empty
-                 and then Current_Etype = Object_Type
-               then
-                  Current_Type := New_Occurrence_Of (Stub_Type, Loc);
                else
-                  Current_Type := New_Occurrence_Of (Current_Etype, Loc);
+                  declare
+                     Decl : Entity_Id;
+                  begin
+                     Build_TypeCode_Function (Loc, U_Type, Decl, Fnam);
+                     Append_To (Decls, Decl);
+                  end;
+               end if;
+
+               if Lib_RE /= RE_Null then
+                  Fnam := RTE (Lib_RE);
                end if;
             end if;
 
-            New_Identifier := Make_Defining_Identifier (Loc,
-              Chars (Defining_Identifier (Current_Parameter)));
+            --  Call the function
 
-            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))));
+            Expr :=
+              Make_Function_Call (Loc, Name => New_Occurrence_Of (Fnam, Loc));
 
-            Next (Current_Parameter);
-         end loop;
-      end if;
+            --  Allow Expr to be used as arg to Build_To_Any_Call immediately
 
-      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 (Entity (Subtype_Mark (Spec)), Loc));
+            Set_Etype (Expr, RTE (RE_TypeCode));
 
-      else
-         return
-           Make_Procedure_Specification (Loc,
-             Defining_Unit_Name       =>
-               Make_Defining_Identifier (Loc,
-                 Chars => Name_For_New_Spec),
-             Parameter_Specifications => Parameters);
-      end if;
+            return Expr;
+         end Build_TypeCode_Call;
 
-   end Copy_Specification;
+         -----------------------------
+         -- Build_TypeCode_Function --
+         -----------------------------
 
-   ---------------------------
-   -- Could_Be_Asynchronous --
-   ---------------------------
+         procedure Build_TypeCode_Function
+           (Loc  : Source_Ptr;
+            Typ  : Entity_Id;
+            Decl : out Node_Id;
+            Fnam : out Entity_Id)
+         is
+            Spec  : Node_Id;
+            Decls : constant List_Id := New_List;
+            Stms  : constant List_Id := New_List;
 
-   function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
-      Current_Parameter : Node_Id;
+            TCNam : constant Entity_Id :=
+                      Make_Helper_Function_Name (Loc, Typ, Name_TypeCode);
 
-   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;
+            Parameters : List_Id;
 
-            Next (Current_Parameter);
-         end loop;
-      end if;
+            procedure Add_String_Parameter
+              (S              : String_Id;
+               Parameter_List : List_Id);
+            --  Add a literal for S to Parameters
 
-      return True;
-   end Could_Be_Asynchronous;
+            procedure Add_TypeCode_Parameter
+              (TC_Node        : Node_Id;
+               Parameter_List : List_Id);
+            --  Add the typecode for Typ to Parameters
 
-   ---------------------------------------------
-   -- Expand_All_Calls_Remote_Subprogram_Call --
-   ---------------------------------------------
+            procedure Add_Long_Parameter
+              (Expr_Node      : Node_Id;
+               Parameter_List : List_Id);
+            --  Add a signed long integer expression to Parameters
 
-   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;
+            procedure Initialize_Parameter_List
+              (Name_String    : String_Id;
+               Repo_Id_String : String_Id;
+               Parameter_List : out List_Id);
+            --  Return a list that contains the first two parameters
+            --  for a parameterized typecode: name and repository id.
 
-   begin
-      E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
+            function Make_Constructed_TypeCode
+              (Kind       : Entity_Id;
+               Parameters : List_Id) return Node_Id;
+            --  Call TC_Build with the given kind and parameters
 
-      if E_Calling_Stubs = Empty then
-         RCI_Cache := RCI_Locator_Table.Get (RCI_Package);
+            procedure Return_Constructed_TypeCode (Kind : Entity_Id);
+            --  Make a return statement that calls TC_Build with the given
+            --  typecode kind, and the constructed parameters list.
 
-         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);
+            procedure Return_Alias_TypeCode (Base_TypeCode  : Node_Id);
+            --  Return a typecode that is a TC_Alias for the given typecode
 
-            --  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.
+            --------------------------
+            -- Add_String_Parameter --
+            --------------------------
 
-            declare
-               Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
+            procedure Add_String_Parameter
+              (S              : String_Id;
+               Parameter_List : List_Id)
+            is
+            begin
+               Append_To (Parameter_List,
+                 Make_Function_Call (Loc,
+                   Name => New_Occurrence_Of (RTE (RE_TA_String), Loc),
+                   Parameter_Associations => New_List (
+                     Make_String_Literal (Loc, S))));
+            end Add_String_Parameter;
+
+            ----------------------------
+            -- Add_TypeCode_Parameter --
+            ----------------------------
+
+            procedure Add_TypeCode_Parameter
+              (TC_Node        : Node_Id;
+               Parameter_List : List_Id)
+            is
+            begin
+               Append_To (Parameter_List,
+                 Make_Function_Call (Loc,
+                   Name => New_Occurrence_Of (RTE (RE_TA_TC), Loc),
+                   Parameter_Associations => New_List (TC_Node)));
+            end Add_TypeCode_Parameter;
+
+            ------------------------
+            -- Add_Long_Parameter --
+            ------------------------
+
+            procedure Add_Long_Parameter
+              (Expr_Node      : Node_Id;
+               Parameter_List : List_Id)
+            is
+            begin
+               Append_To (Parameter_List,
+                 Make_Function_Call (Loc,
+                   Name => New_Occurrence_Of (RTE (RE_TA_LI), Loc),
+                   Parameter_Associations => New_List (Expr_Node)));
+            end Add_Long_Parameter;
+
+            -------------------------------
+            -- Initialize_Parameter_List --
+            -------------------------------
+
+            procedure Initialize_Parameter_List
+              (Name_String    : String_Id;
+               Repo_Id_String : String_Id;
+               Parameter_List : out List_Id)
+            is
+            begin
+               Parameter_List := New_List;
+               Add_String_Parameter (Name_String, Parameter_List);
+               Add_String_Parameter (Repo_Id_String, Parameter_List);
+            end Initialize_Parameter_List;
+
+            ---------------------------
+            -- Return_Alias_TypeCode --
+            ---------------------------
+
+            procedure Return_Alias_TypeCode
+              (Base_TypeCode  : Node_Id)
+            is
+            begin
+               Add_TypeCode_Parameter (Base_TypeCode, Parameters);
+               Return_Constructed_TypeCode (RTE (RE_TC_Alias));
+            end Return_Alias_TypeCode;
+
+            -------------------------------
+            -- Make_Constructed_TypeCode --
+            -------------------------------
+
+            function Make_Constructed_TypeCode
+              (Kind       : Entity_Id;
+               Parameters : List_Id) return Node_Id
+            is
+               Constructed_TC : constant Node_Id :=
+                 Make_Function_Call (Loc,
+                   Name =>
+                     New_Occurrence_Of (RTE (RE_TC_Build), Loc),
+                   Parameter_Associations => New_List (
+                     New_Occurrence_Of (Kind, Loc),
+                     Make_Aggregate (Loc,
+                        Expressions => Parameters)));
+            begin
+               Set_Etype (Constructed_TC, RTE (RE_TypeCode));
+               return Constructed_TC;
+            end Make_Constructed_TypeCode;
 
+            ---------------------------------
+            -- Return_Constructed_TypeCode --
+            ---------------------------------
+
+            procedure Return_Constructed_TypeCode (Kind : Entity_Id) is
             begin
-               if Ekind (Scop) = E_Package_Body then
-                  New_Scope (Spec_Entity (Scop));
+               Append_To (Stms,
+                 Make_Simple_Return_Statement (Loc,
+                   Expression =>
+                     Make_Constructed_TypeCode (Kind, Parameters)));
+            end Return_Constructed_TypeCode;
+
+            ------------------
+            -- Record types --
+            ------------------
+
+            procedure TC_Rec_Add_Process_Element
+              (Params  : List_Id;
+               Any     : Entity_Id;
+               Counter : in out Int;
+               Rec     : Entity_Id;
+               Field   : Node_Id);
+
+            procedure TC_Append_Record_Traversal is
+              new Append_Record_Traversal (
+                Rec                 => Empty,
+                Add_Process_Element => TC_Rec_Add_Process_Element);
+
+            --------------------------------
+            -- TC_Rec_Add_Process_Element --
+            --------------------------------
+
+            procedure TC_Rec_Add_Process_Element
+              (Params  : List_Id;
+               Any     : Entity_Id;
+               Counter : in out Int;
+               Rec     : Entity_Id;
+               Field   : Node_Id)
+            is
+               pragma Warnings (Off);
+               pragma Unreferenced (Any, Counter, Rec);
+               pragma Warnings (On);
 
-               elsif Ekind (Scop) = E_Subprogram_Body then
-                  New_Scope
-                     (Corresponding_Spec (Unit_Declaration_Node (Scop)));
+            begin
+               if Nkind (Field) = N_Defining_Identifier then
+
+                  --  A regular component
+
+                  Add_TypeCode_Parameter
+                    (Build_TypeCode_Call (Loc, Etype (Field), Decls), Params);
+                  Get_Name_String (Chars (Field));
+                  Add_String_Parameter (String_From_Name_Buffer, Params);
 
                else
-                  New_Scope (Scop);
+
+                  --  A variant part
+
+                  declare
+                     Discriminant_Type : constant Entity_Id :=
+                                           Etype (Name (Field));
+
+                     Is_Enum : constant Boolean :=
+                                 Is_Enumeration_Type (Discriminant_Type);
+
+                     Union_TC_Params : List_Id;
+
+                     U_Name : constant Name_Id :=
+                                New_External_Name (Chars (Typ), 'V', -1);
+
+                     Name_Str         : String_Id;
+                     Struct_TC_Params : List_Id;
+
+                     Variant : Node_Id;
+                     Choice  : Node_Id;
+                     Default : constant Node_Id :=
+                                 Make_Integer_Literal (Loc, -1);
+
+                     Dummy_Counter : Int := 0;
+
+                     Choice_Index : Int := 0;
+
+                     procedure Add_Params_For_Variant_Components;
+                     --  Add a struct TypeCode and a corresponding member name
+                     --  to the union parameter list.
+
+                     --  Ordering of declarations is a complete mess in this
+                     --  area, it is supposed to be types/varibles, then
+                     --  subprogram specs, then subprogram bodies ???
+
+                     ---------------------------------------
+                     -- Add_Params_For_Variant_Components --
+                     ---------------------------------------
+
+                     procedure Add_Params_For_Variant_Components
+                     is
+                        S_Name : constant Name_Id :=
+                                   New_External_Name (U_Name, 'S', -1);
+
+                     begin
+                        Get_Name_String (S_Name);
+                        Name_Str := String_From_Name_Buffer;
+                        Initialize_Parameter_List
+                          (Name_Str, Name_Str, Struct_TC_Params);
+
+                        --  Build struct parameters
+
+                        TC_Append_Record_Traversal (Struct_TC_Params,
+                          Component_List (Variant),
+                          Empty,
+                          Dummy_Counter);
+
+                        Add_TypeCode_Parameter
+                          (Make_Constructed_TypeCode
+                           (RTE (RE_TC_Struct), Struct_TC_Params),
+                           Union_TC_Params);
+
+                        Add_String_Parameter (Name_Str, Union_TC_Params);
+                     end Add_Params_For_Variant_Components;
+
+                  begin
+                     Get_Name_String (U_Name);
+                     Name_Str := String_From_Name_Buffer;
+
+                     Initialize_Parameter_List
+                       (Name_Str, Name_Str, Union_TC_Params);
+
+                     --  Add union in enclosing parameter list
+
+                     Add_TypeCode_Parameter
+                       (Make_Constructed_TypeCode
+                        (RTE (RE_TC_Union), Union_TC_Params),
+                        Params);
+
+                     Add_String_Parameter (Name_Str, Params);
+
+                     --  Build union parameters
+
+                     Add_TypeCode_Parameter
+                       (Build_TypeCode_Call
+                          (Loc, Discriminant_Type, Decls),
+                        Union_TC_Params);
+
+                     Add_Long_Parameter (Default, Union_TC_Params);
+
+                     Variant := First_Non_Pragma (Variants (Field));
+                     while Present (Variant) loop
+                        Choice := First (Discrete_Choices (Variant));
+                        while Present (Choice) loop
+                           case Nkind (Choice) is
+                              when N_Range =>
+                                 declare
+                                    L : constant Uint :=
+                                          Expr_Value (Low_Bound (Choice));
+                                    H : constant Uint :=
+                                          Expr_Value (High_Bound (Choice));
+                                    J : Uint := L;
+                                    --  3.8.1(8) guarantees that the bounds of
+                                    --  this range are static.
+
+                                    Expr : Node_Id;
+
+                                 begin
+                                    while J <= H loop
+                                       if Is_Enum then
+                                          Expr := New_Occurrence_Of (
+                                            Get_Enum_Lit_From_Pos (
+                                              Discriminant_Type, J, Loc), Loc);
+                                       else
+                                          Expr :=
+                                            Make_Integer_Literal (Loc, J);
+                                       end if;
+                                       Append_To (Union_TC_Params,
+                                         Build_To_Any_Call (Expr, Decls));
+
+                                       Add_Params_For_Variant_Components;
+                                       J := J + Uint_1;
+                                    end loop;
+                                 end;
+
+                              when N_Others_Choice =>
+
+                                 --  This variant possess a default choice.
+                                 --  We must therefore set the default
+                                 --  parameter to the current choice index. The
+                                 --  default parameter is by construction the
+                                 --  fourth in the Union_TC_Params list.
+
+                                 declare
+                                    Default_Node : constant Node_Id :=
+                                                     Pick (Union_TC_Params, 4);
+
+                                    New_Default_Node : constant Node_Id :=
+                                      Make_Function_Call (Loc,
+                                       Name =>
+                                         New_Occurrence_Of
+                                           (RTE (RE_TA_LI), Loc),
+                                       Parameter_Associations =>
+                                         New_List (
+                                           Make_Integer_Literal
+                                             (Loc, Choice_Index)));
+                                 begin
+                                    Insert_Before (
+                                      Default_Node,
+                                      New_Default_Node);
+
+                                    Remove (Default_Node);
+                                 end;
+
+                                 --  Add a placeholder member label
+                                 --  for the default case.
+                                 --  It must be of the discriminant type.
+
+                                 declare
+                                    Exp : constant Node_Id :=
+                                      Make_Attribute_Reference (Loc,
+                                       Prefix => New_Occurrence_Of
+                                         (Discriminant_Type, Loc),
+                                       Attribute_Name => Name_First);
+                                 begin
+                                    Set_Etype (Exp, Discriminant_Type);
+                                    Append_To (Union_TC_Params,
+                                      Build_To_Any_Call (Exp, Decls));
+                                 end;
+
+                                 Add_Params_For_Variant_Components;
+
+                              when others =>
+
+                                 --  Case of an explicit choice
+
+                                 declare
+                                    Exp : constant Node_Id :=
+                                            New_Copy_Tree (Choice);
+                                 begin
+                                    Append_To (Union_TC_Params,
+                                      Build_To_Any_Call (Exp, Decls));
+                                 end;
+
+                                 Add_Params_For_Variant_Components;
+                           end case;
+
+                           Next (Choice);
+                           Choice_Index := Choice_Index + 1;
+                        end loop;
+
+                        Next_Non_Pragma (Variant);
+                     end loop;
+                  end;
                end if;
+            end TC_Rec_Add_Process_Element;
 
-               Analyze (RCI_Locator);
-               Pop_Scope;
-            end;
+            Type_Name_Str    : String_Id;
+            Type_Repo_Id_Str : String_Id;
 
-            RCI_Cache   := Defining_Unit_Name (RCI_Locator);
+         begin
+            if Is_Itype (Typ) then
+               Build_TypeCode_Function
+                  (Loc  => Loc,
+                  Typ  => Etype (Typ),
+                  Decl => Decl,
+                  Fnam => Fnam);
+               return;
+            end if;
 
-         else
-            RCI_Locator := Parent (RCI_Cache);
-         end if;
+            Fnam := TCNam;
 
-         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;
+            Spec :=
+              Make_Function_Specification (Loc,
+                Defining_Unit_Name       => Fnam,
+                Parameter_Specifications => Empty_List,
+                Result_Definition        =>
+                  New_Occurrence_Of (RTE (RE_TypeCode), Loc));
 
-      Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
-   end Expand_All_Calls_Remote_Subprogram_Call;
+            Build_Name_And_Repository_Id (Typ,
+              Name_Str => Type_Name_Str, Repo_Id_Str => Type_Repo_Id_Str);
 
-   ---------------------------------
-   -- Expand_Calling_Stubs_Bodies --
-   ---------------------------------
+            Initialize_Parameter_List
+              (Type_Name_Str, Type_Repo_Id_Str, Parameters);
 
-   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);
+            if Has_Stream_Attribute_Definition
+                 (Typ, TSS_Stream_Output, At_Any_Place => True)
+              or else
+               Has_Stream_Attribute_Definition
+                 (Typ, TSS_Stream_Write, At_Any_Place => True)
+            then
+               --  If user-defined stream attributes are specified for this
+               --  type, use them and transmit data as an opaque sequence of
+               --  stream elements.
+
+               Return_Alias_TypeCode
+                 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
+
+            elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
+               Return_Alias_TypeCode (
+                 Build_TypeCode_Call (Loc, Etype (Typ), Decls));
+
+            elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
+               Return_Alias_TypeCode (
+                 Build_TypeCode_Call (Loc,
+                   Find_Numeric_Representation (Typ), Decls));
+
+            elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then
+
+               --  Record typecodes are encoded as follows:
+               --  -- TC_STRUCT
+               --  |
+               --  |  [Name]
+               --  |  [Repository Id]
+               --
+               --  Then for each discriminant:
+               --
+               --  |  [Discriminant Type Code]
+               --  |  [Discriminant Name]
+               --  |  ...
+               --
+               --  Then for each component:
+               --
+               --  |  [Component Type Code]
+               --  |  [Component Name]
+               --  |  ...
+               --
+               --  Variants components type codes are encoded as follows:
+               --  --  TC_UNION
+               --  |
+               --  |  [Name]
+               --  |  [Repository Id]
+               --  |  [Discriminant Type Code]
+               --  |  [Index of Default Variant Part or -1 for no default]
+               --
+               --  Then for each Variant Part :
+               --
+               --  |  [VP Label]
+               --  |
+               --  |  -- TC_STRUCT
+               --  |  | [Variant Part Name]
+               --  |  | [Variant Part Repository Id]
+               --  |  |
+               --  |    Then for each VP component:
+               --  |  | [VP component Typecode]
+               --  |  | [VP component Name]
+               --  |  | ...
+               --  |  --
+               --  |
+               --  |  [VP Name]
+
+               if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
+                  Return_Alias_TypeCode
+                    (Build_TypeCode_Call (Loc, Etype (Typ), Decls));
 
-   begin
-      New_Scope (Scope_Of_Spec (Spec));
-      Add_Calling_Stubs_To_Declarations (Specification (Unit_Node),
-                                         Decls);
-      Pop_Scope;
-   end Expand_Calling_Stubs_Bodies;
+               else
+                  declare
+                     Disc : Entity_Id := Empty;
+                     Rdef : constant Node_Id :=
+                              Type_Definition (Declaration_Node (Typ));
+                     Dummy_Counter : Int := 0;
+
+                  begin
+                     --  Construct the discriminants typecodes
+
+                     if Has_Discriminants (Typ) then
+                        Disc := First_Discriminant (Typ);
+                     end if;
+
+                     while Present (Disc) loop
+                        Add_TypeCode_Parameter (
+                          Build_TypeCode_Call (Loc, Etype (Disc), Decls),
+                          Parameters);
+                        Get_Name_String (Chars (Disc));
+                        Add_String_Parameter (
+                          String_From_Name_Buffer,
+                          Parameters);
+                        Next_Discriminant (Disc);
+                     end loop;
+
+                     --  then the components typecodes
+
+                     TC_Append_Record_Traversal
+                       (Parameters, Component_List (Rdef),
+                        Empty, Dummy_Counter);
+                     Return_Constructed_TypeCode (RTE (RE_TC_Struct));
+                  end;
+               end if;
 
-   -----------------------------------
-   -- Expand_Receiving_Stubs_Bodies --
-   -----------------------------------
+            elsif Is_Array_Type (Typ) then
+               declare
+                  Ndim           : constant Pos := Number_Dimensions (Typ);
+                  Inner_TypeCode : Node_Id;
+                  Constrained    : constant Boolean := Is_Constrained (Typ);
+                  Indx           : Node_Id          := First_Index (Typ);
 
-   procedure Expand_Receiving_Stubs_Bodies (Unit_Node : in Node_Id) is
-      Spec  : Node_Id;
-      Decls : List_Id;
-      Temp  : List_Id;
+               begin
+                  Inner_TypeCode :=
+                    Build_TypeCode_Call (Loc, Component_Type (Typ), Decls);
+
+                  for J in 1 .. Ndim loop
+                     if Constrained then
+                        Inner_TypeCode := Make_Constructed_TypeCode
+                          (RTE (RE_TC_Array), New_List (
+                            Build_To_Any_Call (
+                              OK_Convert_To (RTE (RE_Long_Unsigned),
+                                Make_Attribute_Reference (Loc,
+                                  Prefix => New_Occurrence_Of (Typ, Loc),
+                                  Attribute_Name => Name_Length,
+                                  Expressions => New_List (
+                                    Make_Integer_Literal (Loc,
+                                      Intval => Ndim - J + 1)))),
+                              Decls),
+                            Build_To_Any_Call (Inner_TypeCode, Decls)));
+
+                     else
+                        --  Unconstrained case: add low bound for each
+                        --  dimension.
+
+                        Add_TypeCode_Parameter
+                          (Build_TypeCode_Call (Loc, Etype (Indx), Decls),
+                           Parameters);
+                        Get_Name_String (New_External_Name ('L', J));
+                        Add_String_Parameter (
+                          String_From_Name_Buffer,
+                          Parameters);
+                        Next_Index (Indx);
+
+                        Inner_TypeCode := Make_Constructed_TypeCode
+                          (RTE (RE_TC_Sequence), New_List (
+                            Build_To_Any_Call (
+                              OK_Convert_To (RTE (RE_Long_Unsigned),
+                                Make_Integer_Literal (Loc, 0)),
+                              Decls),
+                            Build_To_Any_Call (Inner_TypeCode, Decls)));
+                     end if;
+                  end loop;
+
+                  if Constrained then
+                     Return_Alias_TypeCode (Inner_TypeCode);
+                  else
+                     Add_TypeCode_Parameter (Inner_TypeCode, Parameters);
+                     Start_String;
+                     Store_String_Char ('V');
+                     Add_String_Parameter (End_String, Parameters);
+                     Return_Constructed_TypeCode (RTE (RE_TC_Struct));
+                  end if;
+               end;
 
-   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
+               --  Default: type is represented as an opaque sequence of bytes
 
-      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;
+               Return_Alias_TypeCode
+                 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
+            end if;
 
-      Pop_Scope;
-   end Expand_Receiving_Stubs_Bodies;
+            Decl :=
+              Make_Subprogram_Body (Loc,
+                Specification              => Spec,
+                Declarations               => Decls,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => Stms));
+         end Build_TypeCode_Function;
+
+         ---------------------------------
+         -- Find_Numeric_Representation --
+         ---------------------------------
+
+         function Find_Numeric_Representation
+           (Typ : Entity_Id) return Entity_Id
+         is
+            FST    : constant Entity_Id := First_Subtype (Typ);
+            P_Size : constant Uint      := Esize (FST);
 
-   ----------------------------
-   -- Get_Pkg_Name_string_Id --
-   ----------------------------
+         begin
+            if Is_Unsigned_Type (Typ) then
+               if P_Size <= Standard_Short_Short_Integer_Size then
+                  return RTE (RE_Short_Short_Unsigned);
 
-   function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id is
-      Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
+               elsif P_Size <= Standard_Short_Integer_Size then
+                  return RTE (RE_Short_Unsigned);
 
-   begin
-      Get_Unit_Name_String (Unit_Name_Id);
+               elsif P_Size <= Standard_Integer_Size then
+                  return RTE (RE_Unsigned);
 
-      --  Remove seven last character (" (spec)" or " (body)").
+               elsif P_Size <= Standard_Long_Integer_Size then
+                  return RTE (RE_Long_Unsigned);
 
-      Name_Len := Name_Len - 7;
-      pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
+               else
+                  return RTE (RE_Long_Long_Unsigned);
+               end if;
 
-      return Get_String_Id (Name_Buffer (1 .. Name_Len));
-   end Get_Pkg_Name_String_Id;
+            elsif Is_Integer_Type (Typ) then
+               if P_Size <= Standard_Short_Short_Integer_Size then
+                  return Standard_Short_Short_Integer;
 
-   -------------------
-   -- Get_String_Id --
-   -------------------
+               elsif P_Size <= Standard_Short_Integer_Size then
+                  return Standard_Short_Integer;
 
-   function Get_String_Id (Val : String) return String_Id is
-   begin
-      Start_String;
-      Store_String_Chars (Val);
-      return End_String;
-   end Get_String_Id;
+               elsif P_Size <= Standard_Integer_Size then
+                  return Standard_Integer;
 
-   -----------------------
-   -- Get_Subprogram_Id --
-   -----------------------
+               elsif P_Size <= Standard_Long_Integer_Size then
+                  return Standard_Long_Integer;
 
-   function Get_Subprogram_Id (E : Entity_Id) return Int is
-      Current_Declaration : Node_Id;
-      Result              : Int := 0;
+               else
+                  return Standard_Long_Long_Integer;
+               end if;
 
-   begin
-      pragma Assert
-        (Is_Remote_Call_Interface (Scope (E))
-           and then
-             (Nkind (Parent (E)) = N_Procedure_Specification
-                or else
-              Nkind (Parent (E)) = N_Function_Specification));
-
-      Current_Declaration :=
-        First (Visible_Declarations
-          (Package_Specification_Of_Scope (Scope (E))));
-
-      while Current_Declaration /= Empty loop
-         if Nkind (Current_Declaration) = N_Subprogram_Declaration
-           and then Comes_From_Source (Current_Declaration)
-         then
-            if Defining_Unit_Name
-                 (Specification (Current_Declaration)) = E
-            then
-               return Result;
+            elsif Is_Floating_Point_Type (Typ) then
+               if P_Size <= Standard_Short_Float_Size then
+                  return Standard_Short_Float;
+
+               elsif P_Size <= Standard_Float_Size then
+                  return Standard_Float;
+
+               elsif P_Size <= Standard_Long_Float_Size then
+                  return Standard_Long_Float;
+
+               else
+                  return Standard_Long_Long_Float;
+               end if;
+
+            else
+               raise Program_Error;
             end if;
 
-            Result := Result + 1;
-         end if;
+            --  TBD: fixed point types???
+            --  TBverified numeric types with a biased representation???
 
-         Next (Current_Declaration);
-      end loop;
+         end Find_Numeric_Representation;
 
-      --  Error if we do not find it
+         ---------------------------
+         -- Append_Array_Traversal --
+         ---------------------------
 
-      raise Program_Error;
-   end Get_Subprogram_Id;
+         procedure Append_Array_Traversal
+           (Stmts   : List_Id;
+            Any     : Entity_Id;
+            Counter : Entity_Id := Empty;
+            Depth   : Pos       := 1)
+         is
+            Loc         : constant Source_Ptr := Sloc (Subprogram);
+            Typ         : constant Entity_Id  := Etype (Arry);
+            Constrained : constant Boolean    := Is_Constrained (Typ);
+            Ndim        : constant Pos        := Number_Dimensions (Typ);
 
-   ----------
-   -- Hash --
-   ----------
+            Inner_Any, Inner_Counter : Entity_Id;
 
-   function Hash (F : Entity_Id) return Hash_Index is
-   begin
-      return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
-   end Hash;
+            Loop_Stm    : Node_Id;
+            Inner_Stmts : constant List_Id := New_List;
 
-   --------------------------
-   -- Input_With_Tag_Check --
-   --------------------------
+         begin
+            if Depth > Ndim then
 
-   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;
+               --  Processing for one element of an array
 
-   --------------------------------
-   -- Is_RACW_Controlling_Formal --
-   --------------------------------
+               declare
+                  Element_Expr : constant Node_Id :=
+                                   Make_Indexed_Component (Loc,
+                                     New_Occurrence_Of (Arry, Loc),
+                                     Indices);
+               begin
+                  Set_Etype (Element_Expr, Component_Type (Typ));
+                  Add_Process_Element (Stmts,
+                    Any     => Any,
+                    Counter => Counter,
+                    Datum   => Element_Expr);
+               end;
 
-   function Is_RACW_Controlling_Formal
-     (Parameter : Node_Id;
-      Stub_Type : Entity_Id)
-      return      Boolean
-   is
-      Typ : Entity_Id;
+               return;
+            end if;
 
-   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).
+            Append_To (Indices,
+              Make_Identifier (Loc, New_External_Name ('L', Depth)));
 
-      if Ekind (Defining_Identifier (Parameter)) = E_Void then
-         return False;
-      end if;
+            if not Constrained or else Depth > 1 then
+               Inner_Any := Make_Defining_Identifier (Loc,
+                              New_External_Name ('A', Depth));
+               Set_Etype (Inner_Any, RTE (RE_Any));
+            else
+               Inner_Any := Empty;
+            end if;
 
-      --  If the parameter is not a controlling formal, then it cannot
-      --  be possibly a RACW_Controlling_Formal.
+            if Present (Counter) then
+               Inner_Counter := Make_Defining_Identifier (Loc,
+                                  New_External_Name ('J', Depth));
+            else
+               Inner_Counter := Empty;
+            end if;
 
-      if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
-         return False;
-      end if;
+            declare
+               Loop_Any : Node_Id := Inner_Any;
 
-      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;
+            begin
+               --  For the first dimension of a constrained array, we add
+               --  elements directly in the corresponding Any; there is no
+               --  intervening inner Any.
 
-   --------------------
-   -- Make_Tag_Check --
-   --------------------
+               if No (Loop_Any) then
+                  Loop_Any := Any;
+               end if;
 
-   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'));
+               Append_Array_Traversal (Inner_Stmts,
+                 Any     => Loop_Any,
+                 Counter => Inner_Counter,
+                 Depth   => Depth + 1);
+            end;
 
-   begin
-      return Make_Block_Statement (Loc,
-        Handled_Statement_Sequence =>
-          Make_Handled_Sequence_Of_Statements (Loc,
-            Statements         => New_List (N),
+            Loop_Stm :=
+              Make_Implicit_Loop_Statement (Subprogram,
+                Iteration_Scheme =>
+                  Make_Iteration_Scheme (Loc,
+                    Loop_Parameter_Specification =>
+                      Make_Loop_Parameter_Specification (Loc,
+                        Defining_Identifier =>
+                          Make_Defining_Identifier (Loc,
+                            Chars => New_External_Name ('L', Depth)),
+
+                        Discrete_Subtype_Definition =>
+                          Make_Attribute_Reference (Loc,
+                            Prefix         => New_Occurrence_Of (Arry, Loc),
+                            Attribute_Name => Name_Range,
+
+                            Expressions => New_List (
+                              Make_Integer_Literal (Loc, Depth))))),
+                Statements => Inner_Stmts);
 
-            Exception_Handlers => New_List (
-              Make_Exception_Handler (Loc,
-                Choice_Parameter => Occ,
+            declare
+               Decls       : constant List_Id := New_List;
+               Dimen_Stmts : constant List_Id := New_List;
+               Length_Node : Node_Id;
 
-                Exception_Choices =>
-                  New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
+               Inner_Any_TypeCode : constant Entity_Id :=
+                                      Make_Defining_Identifier (Loc,
+                                        New_External_Name ('T', Depth));
 
-                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;
+               Inner_Any_TypeCode_Expr : Node_Id;
 
-   ----------------------------
-   -- Need_Extra_Constrained --
-   ----------------------------
+            begin
+               if Depth = 1 then
+                  if Constrained then
+                     Inner_Any_TypeCode_Expr :=
+                       Make_Function_Call (Loc,
+                         Name => New_Occurrence_Of (RTE (RE_Get_TC), Loc),
+                         Parameter_Associations => New_List (
+                           New_Occurrence_Of (Any, Loc)));
+                  else
+                     Inner_Any_TypeCode_Expr :=
+                       Make_Function_Call (Loc,
+                         Name =>
+                           New_Occurrence_Of (RTE (RE_Any_Member_Type), Loc),
+                             Parameter_Associations => New_List (
+                               New_Occurrence_Of (Any, Loc),
+                               Make_Integer_Literal (Loc, Ndim)));
+                  end if;
+               else
+                  Inner_Any_TypeCode_Expr :=
+                    Make_Function_Call (Loc,
+                      Name => New_Occurrence_Of (RTE (RE_Content_Type), Loc),
+                      Parameter_Associations => New_List (
+                        Make_Identifier (Loc,
+                          Chars => New_External_Name ('T', Depth - 1))));
+               end if;
 
-   function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
-      Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
+               Append_To (Decls,
+                 Make_Object_Declaration (Loc,
+                   Defining_Identifier => Inner_Any_TypeCode,
+                   Constant_Present    => True,
+                   Object_Definition   => New_Occurrence_Of (
+                                            RTE (RE_TypeCode), Loc),
+                   Expression          => Inner_Any_TypeCode_Expr));
+
+               if Present (Inner_Any) then
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Inner_Any,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_Any), Loc),
+                      Expression          =>
+                        Make_Function_Call (Loc,
+                          Name =>
+                            New_Occurrence_Of (
+                              RTE (RE_Create_Any), Loc),
+                          Parameter_Associations => New_List (
+                            New_Occurrence_Of (Inner_Any_TypeCode, Loc)))));
+               end if;
 
-   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;
+               if Present (Inner_Counter) then
+                  Append_To (Decls,
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Inner_Counter,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RE_Long_Unsigned), Loc),
+                      Expression          =>
+                        Make_Integer_Literal (Loc, 0)));
+               end if;
 
-   ------------------------------------
-   -- Pack_Entity_Into_Stream_Access --
-   ------------------------------------
+               if not Constrained then
+                  Length_Node := Make_Attribute_Reference (Loc,
+                        Prefix         => New_Occurrence_Of (Arry, Loc),
+                        Attribute_Name => Name_Length,
+                        Expressions    =>
+                          New_List (Make_Integer_Literal (Loc, Depth)));
+                  Set_Etype (Length_Node, RTE (RE_Long_Unsigned));
+
+                  Add_Process_Element (Dimen_Stmts,
+                    Datum   => Length_Node,
+                    Any     => Inner_Any,
+                    Counter => Inner_Counter);
+               end if;
 
-   function Pack_Entity_Into_Stream_Access
-     (Loc    : Source_Ptr;
-      Stream : Node_Id;
-      Object : Entity_Id;
-      Etyp   : Entity_Id := Empty)
-      return   Node_Id
-   is
-      Typ : Entity_Id;
+               --  Loop_Stm does appropriate processing for each element
+               --  of Inner_Any.
 
-   begin
-      if Etyp /= Empty then
-         Typ := Etyp;
-      else
-         Typ := Etype (Object);
-      end if;
+               Append_To (Dimen_Stmts, Loop_Stm);
 
-      return
-        Pack_Node_Into_Stream_Access (Loc,
-          Stream => Stream,
-          Object => New_Occurrence_Of (Object, Loc),
-          Etyp   => Typ);
-   end Pack_Entity_Into_Stream_Access;
+               --  Link outer and inner any
 
-   ---------------------------
-   -- Pack_Node_Into_Stream --
-   ---------------------------
+               if Present (Inner_Any) then
+                  Add_Process_Element (Dimen_Stmts,
+                    Any     => Any,
+                    Counter => Counter,
+                    Datum   => New_Occurrence_Of (Inner_Any, Loc));
+               end if;
 
-   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;
+               Append_To (Stmts,
+                 Make_Block_Statement (Loc,
+                   Declarations =>
+                     Decls,
+                   Handled_Statement_Sequence =>
+                     Make_Handled_Sequence_Of_Statements (Loc,
+                       Statements => Dimen_Stmts)));
+            end;
+         end Append_Array_Traversal;
 
-   begin
-      if not Is_Constrained (Etyp) then
-         Write_Attribute := Name_Output;
-      end if;
+         -------------------------------
+         -- Make_Helper_Function_Name --
+         -------------------------------
 
-      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;
+         function Make_Helper_Function_Name
+           (Loc : Source_Ptr;
+            Typ : Entity_Id;
+            Nam : Name_Id) return Entity_Id
+         is
+         begin
 
-   ----------------------------------
-   -- Pack_Node_Into_Stream_Access --
-   ----------------------------------
+            declare
+               Serial : Nat := 0;
+               --  For tagged types, we use a canonical name so that it matches
+               --  the primitive spec. For all other cases, we use a serialized
+               --  name so that multiple generations of the same procedure do
+               --  not clash.
+            begin
+               if not Is_Tagged_Type (Typ) then
+                  Serial := Increment_Serial_Number;
+               end if;
 
-   function Pack_Node_Into_Stream_Access
-     (Loc    : Source_Ptr;
-      Stream : Node_Id;
-      Object : Node_Id;
-      Etyp   : Entity_Id)
-      return   Node_Id
-   is
-      Write_Attribute : Name_Id := Name_Write;
+               --  Use prefixed underscore to avoid potential clash with used
+               --  identifier (we use attribute names for Nam).
 
-   begin
-      if not Is_Constrained (Etyp) then
-         Write_Attribute := Name_Output;
-      end if;
+               return
+                 Make_Defining_Identifier (Loc,
+                   Chars =>
+                     New_External_Name
+                       (Related_Id => Nam,
+                        Suffix => ' ', Suffix_Index => Serial,
+                        Prefix => '_'));
+            end;
+         end Make_Helper_Function_Name;
+      end Helpers;
 
-      return
-        Make_Attribute_Reference (Loc,
-          Prefix         => New_Occurrence_Of (Etyp, Loc),
-          Attribute_Name => Write_Attribute,
-          Expressions    => New_List (
-            Stream,
-            Object));
-   end Pack_Node_Into_Stream_Access;
+      -----------------------------------
+      -- Reserve_NamingContext_Methods --
+      -----------------------------------
+
+      procedure Reserve_NamingContext_Methods is
+         Str_Resolve : constant String := "resolve";
+      begin
+         Name_Buffer (1 .. Str_Resolve'Length) := Str_Resolve;
+         Name_Len := Str_Resolve'Length;
+         Overload_Counter_Table.Set (Name_Find, 1);
+      end Reserve_NamingContext_Methods;
+
+   end PolyORB_Support;
 
    -------------------------------
    -- 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);
-
+   procedure RACW_Type_Is_Asynchronous (RACW_Type : Entity_Id) is
+      Asynchronous_Flag : constant Entity_Id :=
+                            Asynchronous_Flags_Table.Get (RACW_Type);
    begin
-      Replace (N, New_Occurrence_Of (Standard_True, Sloc (N)));
+      Replace (Expression (Parent (Asynchronous_Flag)),
+        New_Occurrence_Of (Standard_True, Sloc (Asynchronous_Flag)));
    end RACW_Type_Is_Asynchronous;
 
    -------------------------
@@ -3791,24 +11063,37 @@ package body Exp_Dist is
 
    function RCI_Package_Locator
      (Loc          : Source_Ptr;
-      Package_Spec : Node_Id)
-      return         Node_Id
+      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)))));
+      Inst     : Node_Id;
+      Pkg_Name : String_Id;
 
    begin
+      Get_Library_Unit_Name_String (Package_Spec);
+      Pkg_Name := String_From_Name_Buffer;
+      Inst :=
+        Make_Package_Instantiation (Loc,
+          Defining_Unit_Name   =>
+            Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
+          Name                 =>
+            New_Occurrence_Of (RTE (RE_RCI_Locator), 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 => Pkg_Name)),
+            Make_Generic_Association (Loc,
+              Selector_Name                     =>
+                Make_Identifier (Loc, Name_Version),
+              Explicit_Generic_Actual_Parameter =>
+                Make_Attribute_Reference (Loc,
+                  Prefix         =>
+                    New_Occurrence_Of (Defining_Entity (Package_Spec), Loc),
+                  Attribute_Name =>
+                    Name_Version))));
+
       RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
         Defining_Unit_Name (Inst));
       return Inst;
@@ -3819,17 +11104,40 @@ package body Exp_Dist is
    -----------------------------------------------
 
    procedure Remote_Types_Tagged_Full_View_Encountered
-     (Full_View : in Entity_Id)
+     (Full_View : Entity_Id)
    is
       Stub_Elements : constant Stub_Structure :=
                         Stubs_Table.Get (Full_View);
 
    begin
+      --  For an RACW encountered before the freeze point of its designated
+      --  type, the stub type is generated at the point of the RACW declaration
+      --  but the primitives are generated only once the designated type is
+      --  frozen. That freeze can occur in another scope, for example when the
+      --  RACW is declared in a nested package. In that case we need to
+      --  reestablish the stub type's scope prior to generating its primitive
+      --  operations.
+
       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)));
+         declare
+            Saved_Scope : constant Entity_Id := Current_Scope;
+            Stubs_Scope : constant Entity_Id :=
+                            Scope (Stub_Elements.Stub_Type);
+
+         begin
+            if Current_Scope /= Stubs_Scope then
+               Push_Scope (Stubs_Scope);
+            end if;
+
+            Add_RACW_Primitive_Declarations_And_Bodies
+              (Full_View,
+               Stub_Elements.RPC_Receiver_Decl,
+               Stub_Elements.Body_Decls);
+
+            if Current_Scope /= Saved_Scope then
+               Pop_Scope;
+            end if;
+         end;
       end if;
    end Remote_Types_Tagged_Full_View_Encountered;
 
@@ -3838,9 +11146,10 @@ package body Exp_Dist is
    -------------------
 
    function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
-      Unit_Name : Node_Id := Defining_Unit_Name (Spec);
+      Unit_Name : Node_Id;
 
    begin
+      Unit_Name := Defining_Unit_Name (Spec);
       while Nkind (Unit_Name) /= N_Defining_Identifier loop
          Unit_Name := Defining_Identifier (Unit_Name);
       end loop;
@@ -3848,4 +11157,328 @@ package body Exp_Dist is
       return Unit_Name;
    end Scope_Of_Spec;
 
+   ----------------------
+   -- Set_Renaming_TSS --
+   ----------------------
+
+   procedure Set_Renaming_TSS
+     (Typ     : Entity_Id;
+      Nam     : Entity_Id;
+      TSS_Nam : TSS_Name_Type)
+   is
+      Loc  : constant Source_Ptr := Sloc (Nam);
+      Spec : constant Node_Id := Parent (Nam);
+
+      TSS_Node : constant Node_Id :=
+                   Make_Subprogram_Renaming_Declaration (Loc,
+                     Specification =>
+                       Copy_Specification (Loc,
+                         Spec     => Spec,
+                         New_Name => Make_TSS_Name (Typ, TSS_Nam)),
+                       Name => New_Occurrence_Of (Nam, Loc));
+
+      Snam : constant Entity_Id :=
+               Defining_Unit_Name (Specification (TSS_Node));
+
+   begin
+      if Nkind (Spec) = N_Function_Specification then
+         Set_Ekind (Snam, E_Function);
+         Set_Etype (Snam, Entity (Result_Definition (Spec)));
+      else
+         Set_Ekind (Snam, E_Procedure);
+         Set_Etype (Snam, Standard_Void_Type);
+      end if;
+
+      Set_TSS (Typ, Snam);
+   end Set_Renaming_TSS;
+
+   ----------------------------------------------
+   -- Specific_Add_Obj_RPC_Receiver_Completion --
+   ----------------------------------------------
+
+   procedure Specific_Add_Obj_RPC_Receiver_Completion
+     (Loc           : Source_Ptr;
+      Decls         : List_Id;
+      RPC_Receiver  : Entity_Id;
+      Stub_Elements : Stub_Structure)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Add_Obj_RPC_Receiver_Completion (Loc,
+              Decls, RPC_Receiver, Stub_Elements);
+         when others =>
+            GARLIC_Support.Add_Obj_RPC_Receiver_Completion (Loc,
+              Decls, RPC_Receiver, Stub_Elements);
+      end case;
+   end Specific_Add_Obj_RPC_Receiver_Completion;
+
+   --------------------------------
+   -- Specific_Add_RACW_Features --
+   --------------------------------
+
+   procedure Specific_Add_RACW_Features
+     (RACW_Type         : Entity_Id;
+      Desig             : Entity_Id;
+      Stub_Type         : Entity_Id;
+      Stub_Type_Access  : Entity_Id;
+      RPC_Receiver_Decl : Node_Id;
+      Body_Decls        : List_Id)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Add_RACW_Features
+              (RACW_Type,
+               Desig,
+               Stub_Type,
+               Stub_Type_Access,
+               RPC_Receiver_Decl,
+               Body_Decls);
+
+         when others =>
+            GARLIC_Support.Add_RACW_Features
+              (RACW_Type,
+               Stub_Type,
+               Stub_Type_Access,
+               RPC_Receiver_Decl,
+               Body_Decls);
+      end case;
+   end Specific_Add_RACW_Features;
+
+   --------------------------------
+   -- Specific_Add_RAST_Features --
+   --------------------------------
+
+   procedure Specific_Add_RAST_Features
+     (Vis_Decl : Node_Id;
+      RAS_Type : Entity_Id)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
+         when others =>
+            GARLIC_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
+      end case;
+   end Specific_Add_RAST_Features;
+
+   --------------------------------------------------
+   -- Specific_Add_Receiving_Stubs_To_Declarations --
+   --------------------------------------------------
+
+   procedure Specific_Add_Receiving_Stubs_To_Declarations
+     (Pkg_Spec : Node_Id;
+      Decls    : List_Id;
+      Stmts    : List_Id)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Add_Receiving_Stubs_To_Declarations
+              (Pkg_Spec, Decls, Stmts);
+         when others =>
+            GARLIC_Support.Add_Receiving_Stubs_To_Declarations
+              (Pkg_Spec, Decls, Stmts);
+      end case;
+   end Specific_Add_Receiving_Stubs_To_Declarations;
+
+   ------------------------------------------
+   -- Specific_Build_General_Calling_Stubs --
+   ------------------------------------------
+
+   procedure Specific_Build_General_Calling_Stubs
+     (Decls                     : List_Id;
+      Statements                : List_Id;
+      Target                    : RPC_Target;
+      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;
+      Stub_Type                 : Entity_Id := Empty;
+      RACW_Type                 : Entity_Id := Empty;
+      Nod                       : Node_Id)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Build_General_Calling_Stubs
+              (Decls,
+               Statements,
+               Target.Object,
+               Subprogram_Id,
+               Asynchronous,
+               Is_Known_Asynchronous,
+               Is_Known_Non_Asynchronous,
+               Is_Function,
+               Spec,
+               Stub_Type,
+               RACW_Type,
+               Nod);
+
+         when others =>
+            GARLIC_Support.Build_General_Calling_Stubs
+              (Decls,
+               Statements,
+               Target.Partition,
+               Target.RPC_Receiver,
+               Subprogram_Id,
+               Asynchronous,
+               Is_Known_Asynchronous,
+               Is_Known_Non_Asynchronous,
+               Is_Function,
+               Spec,
+               Stub_Type,
+               RACW_Type,
+               Nod);
+      end case;
+   end Specific_Build_General_Calling_Stubs;
+
+   --------------------------------------
+   -- Specific_Build_RPC_Receiver_Body --
+   --------------------------------------
+
+   procedure Specific_Build_RPC_Receiver_Body
+     (RPC_Receiver : Entity_Id;
+      Request      : out Entity_Id;
+      Subp_Id      : out Entity_Id;
+      Subp_Index   : out Entity_Id;
+      Stmts        : out List_Id;
+      Decl         : out Node_Id)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Build_RPC_Receiver_Body
+              (RPC_Receiver,
+               Request,
+               Subp_Id,
+               Subp_Index,
+               Stmts,
+               Decl);
+
+         when others =>
+            GARLIC_Support.Build_RPC_Receiver_Body
+              (RPC_Receiver,
+               Request,
+               Subp_Id,
+               Subp_Index,
+               Stmts,
+               Decl);
+      end case;
+   end Specific_Build_RPC_Receiver_Body;
+
+   --------------------------------
+   -- Specific_Build_Stub_Target --
+   --------------------------------
+
+   function Specific_Build_Stub_Target
+     (Loc                   : Source_Ptr;
+      Decls                 : List_Id;
+      RCI_Locator           : Entity_Id;
+      Controlling_Parameter : Entity_Id) return RPC_Target
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            return PolyORB_Support.Build_Stub_Target (Loc,
+                     Decls, RCI_Locator, Controlling_Parameter);
+
+         when others =>
+            return GARLIC_Support.Build_Stub_Target (Loc,
+                     Decls, RCI_Locator, Controlling_Parameter);
+      end case;
+   end Specific_Build_Stub_Target;
+
+   ------------------------------
+   -- Specific_Build_Stub_Type --
+   ------------------------------
+
+   procedure Specific_Build_Stub_Type
+     (RACW_Type         : Entity_Id;
+      Stub_Type         : Entity_Id;
+      Stub_Type_Decl    : out Node_Id;
+      RPC_Receiver_Decl : out Node_Id)
+   is
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            PolyORB_Support.Build_Stub_Type (
+              RACW_Type, Stub_Type,
+              Stub_Type_Decl, RPC_Receiver_Decl);
+
+         when others =>
+            GARLIC_Support.Build_Stub_Type (
+              RACW_Type, Stub_Type,
+              Stub_Type_Decl, RPC_Receiver_Decl);
+      end case;
+   end Specific_Build_Stub_Type;
+
+   function Specific_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
+   begin
+      case Get_PCS_Name is
+         when Name_PolyORB_DSA =>
+            return PolyORB_Support.Build_Subprogram_Receiving_Stubs
+                     (Vis_Decl,
+                      Asynchronous,
+                      Dynamically_Asynchronous,
+                      Stub_Type,
+                      RACW_Type,
+                      Parent_Primitive);
+
+         when others =>
+            return GARLIC_Support.Build_Subprogram_Receiving_Stubs
+                     (Vis_Decl,
+                      Asynchronous,
+                      Dynamically_Asynchronous,
+                      Stub_Type,
+                      RACW_Type,
+                      Parent_Primitive);
+      end case;
+   end Specific_Build_Subprogram_Receiving_Stubs;
+
+   -------------------------------
+   -- Transmit_As_Unconstrained --
+   -------------------------------
+
+   function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean is
+   begin
+      return
+        not (Is_Elementary_Type (Typ) or else Is_Constrained (Typ))
+          or else (Is_Access_Type (Typ) and then Can_Never_Be_Null (Typ));
+   end Transmit_As_Unconstrained;
+
+   --------------------------
+   -- Underlying_RACW_Type --
+   --------------------------
+
+   function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is
+      Record_Type : Entity_Id;
+
+   begin
+      if Ekind (RAS_Typ) = E_Record_Type then
+         Record_Type := RAS_Typ;
+      else
+         pragma Assert (Present (Equivalent_Type (RAS_Typ)));
+         Record_Type := Equivalent_Type (RAS_Typ);
+      end if;
+
+      return
+        Etype (Subtype_Indication
+                (Component_Definition
+                  (First (Component_Items
+                           (Component_List
+                             (Type_Definition
+                               (Declaration_Node (Record_Type))))))));
+   end Underlying_RACW_Type;
+
 end Exp_Dist;