OSDN Git Service

PR target/50678
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_dist.adb
index b3801f6..82d5898 100644 (file)
@@ -6,56 +6,58 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2005 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2010, 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,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, 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_Disp; use Exp_Disp;
+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_Aux;  use Sem_Aux;
+with Sem_Cat;  use Sem_Cat;
+with Sem_Ch3;  use Sem_Ch3;
+with Sem_Ch8;  use Sem_Ch8;
+with Sem_Ch12; use Sem_Ch12;
+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_Eval;    use Sem_Eval;
-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 Ttypes;      use Ttypes;
-with Uintp;       use Uintp;
 
 package body Exp_Dist is
 
    --  The following model has been used to implement distributed objects:
-   --  given a designated type D and a RACW type R, then a record of the
-   --  form:
+   --  given a designated type D and a RACW type R, then a record of the form:
 
    --    type Stub is tagged record
    --       [...declaration similar to s-parint.ads RACW_Stub_Type...]
@@ -63,10 +65,10 @@ package body Exp_Dist is
 
    --  is built. This type has two properties:
 
-   --    1) Since it has the same structure than RACW_Stub_Type, it can be
-   --       converted to and from this type to make it suitable for
+   --    1) Since it has the same structure as RACW_Stub_Type, it can
+   --       be converted to and from this type to make it suitable for
    --       System.Partition_Interface.Get_Unique_Remote_Pointer in order
-   --       to avoid memory leaks when the same remote object arrive on the
+   --       to avoid memory leaks when the same remote object arrives on the
    --       same partition through several paths;
 
    --    2) It also has the same dispatching table as the designated type D,
@@ -81,11 +83,10 @@ package body Exp_Dist is
    --  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.)
+   --  (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;
 
@@ -94,13 +95,13 @@ package body Exp_Dist is
    -----------------------
 
    function Hash (F : Entity_Id) return Hash_Index;
-   --  DSA expansion associates stubs to distributed object types using
-   --  a hash table on entity ids.
+   --  DSA expansion associates stubs to distributed object types using a hash
+   --  table on entity ids.
 
-   function Hash (F : Name_Id)   return Hash_Index;
+   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.
+   --  to be associated with each remote subprogram name. These counters are
+   --  maintained in a hash table on name ids.
 
    type Subprogram_Identifiers is record
       Str_Identifier : String_Id;
@@ -114,8 +115,8 @@ package body Exp_Dist is
                          Key        => Entity_Id,
                          Hash       => Hash,
                          Equal      => "=");
-   --  Mapping between a remote subprogram and the corresponding
-   --  subprogram identifiers.
+   --  Mapping between a remote subprogram and the corresponding subprogram
+   --  identifiers.
 
    package Overload_Counter_Table is
       new Simple_HTable (Header_Num => Hash_Index,
@@ -124,9 +125,9 @@ package body Exp_Dist is
                          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).
+   --  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;
@@ -160,20 +161,19 @@ package body Exp_Dist is
       Vis_Decl           : Node_Id;
       All_Calls_Remote_E : Entity_Id;
       Proxy_Object_Addr  : out Entity_Id);
-   --  Add the proxy type necessary to call 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.
+   --  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.
+   --  Build and return a tagged record type definition for an RCI subprogram
+   --  proxy type. ACR_Expression is used as the initialization value for the
+   --  All_Calls_Remote component.
 
    function Build_Get_Unique_RP_Call
      (Loc       : Source_Ptr;
@@ -183,6 +183,12 @@ package body Exp_Dist is
    --  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                  : Node_Id;
@@ -194,13 +200,13 @@ package body Exp_Dist is
       New_Name                 : Name_Id   := No_Name) return Node_Id;
    --  Build the calling stub for a given subprogram with the subprogram ID
    --  being Subp_Id. If Stub_Type is given, then the "addr" field of
-   --  parameters of this type will be marshalled instead of the object
-   --  itself. It will then be converted into Stub_Type before performing
-   --  the real call. If Dynamically_Asynchronous is True, then it will be
-   --  computed at run time whether the call is asynchronous or not.
-   --  Otherwise, the value of the formal Asynchronous will be used.
-   --  If Locator is not Empty, it will be used instead of RCI_Cache. If
-   --  New_Name is given, then it will be used instead of the original name.
+   --  parameters of this type will be marshalled instead of the object itself.
+   --  It will then be converted into Stub_Type before performing the real
+   --  call. If Dynamically_Asynchronous is True, then it will be computed at
+   --  run time whether the call is asynchronous or not. Otherwise, the value
+   --  of the formal Asynchronous will be used. If Locator is not Empty, it
+   --  will be used instead of RCI_Cache. If New_Name is given, then it will
+   --  be used instead of the original name.
 
    function Build_RPC_Receiver_Specification
      (RPC_Receiver      : Entity_Id;
@@ -215,14 +221,17 @@ package body Exp_Dist is
    --  the controlling formal of the equivalent RACW operation for a RAS
    --  type is always left in first position.
 
-   procedure Add_Calling_Stubs_To_Declarations
-     (Pkg_Spec : Node_Id;
-      Decls    : List_Id);
+   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 : Node_Id);
    --  Add calling stubs to the declarative part
 
    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).
+   --  given to be asynchronous (i.e. no [IN] OUT parameters).
 
    function Pack_Entity_Into_Stream_Access
      (Loc    : Source_Ptr;
@@ -252,8 +261,8 @@ package body Exp_Dist is
      (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.
+   --  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
@@ -262,15 +271,16 @@ package body Exp_Dist is
      (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.
+   --  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.
 
@@ -289,30 +299,53 @@ package body Exp_Dist is
       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.
+   --  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: 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.
-   --
-   --  For a 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.
 
    Empty_Stub_Structure : constant Stub_Structure :=
-     (Empty, Empty, Empty, Empty);
+     (Empty, Empty, Empty, No_List, Empty);
 
    package Stubs_Table is
       new Simple_HTable (Header_Num => Hash_Index,
@@ -352,6 +385,9 @@ 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   : Entity_Id;
       RACW_Type         : Entity_Id;
@@ -359,12 +395,17 @@ package body Exp_Dist is
       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.
 
+   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);
@@ -410,6 +451,19 @@ 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 --
    --------------------------------------------
@@ -426,11 +480,12 @@ package body Exp_Dist is
       Stub_Type           : Entity_Id;
       Stub_Type_Access    : Entity_Id;
       RPC_Receiver_Decl   : Node_Id;
-      Declarations        : List_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, while the
-   --  bodies are inserted at the end of Decls. Runtime-specific ancillary
-   --  subprogram for Add_RACW_Features.
+   --  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;
@@ -445,12 +500,13 @@ package body Exp_Dist is
    type RPC_Target (PCS_Kind : PCS_Names) is record
       case PCS_Kind is
          when Name_PolyORB_DSA =>
-            Object       : Node_Id;
+            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 parition
+            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
@@ -483,7 +539,7 @@ package body Exp_Dist is
    --    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
+   --                        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
@@ -504,11 +560,10 @@ package body Exp_Dist is
 
    procedure Specific_Build_Stub_Type
      (RACW_Type         : Entity_Id;
-      Stub_Type         : Entity_Id;
-      Stub_Type_Decl    : out Node_Id;
+      Stub_Type_Comps   : out List_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
+   --  Build a components list for the stub type associated with an RACW type,
+   --  and build 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.
 
@@ -553,23 +608,27 @@ package body Exp_Dist is
 
    procedure Specific_Add_Receiving_Stubs_To_Declarations
      (Pkg_Spec : Node_Id;
-      Decls    : List_Id);
+      Decls    : List_Id;
+      Stmts    : List_Id);
    --  Add receiving stubs to the declarative part of an RCI unit
 
+   --------------------
+   -- GARLIC_Support --
+   --------------------
+
    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.
+      --  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;
-         Declarations      : List_Id);
+         Body_Decls        : List_Id);
 
       procedure Add_RAST_Features
         (Vis_Decl : Node_Id;
@@ -597,9 +656,8 @@ package body Exp_Dist is
          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;
+        (RACW_Type         : Entity_Id;
+         Stub_Type_Comps   : out List_Id;
          RPC_Receiver_Decl : out Node_Id);
 
       function Build_Subprogram_Receiving_Stubs
@@ -618,7 +676,8 @@ package body Exp_Dist is
 
       procedure Add_Receiving_Stubs_To_Declarations
         (Pkg_Spec : Node_Id;
-         Decls    : List_Id);
+         Decls    : List_Id;
+         Stmts    : List_Id);
 
       procedure Build_RPC_Receiver_Body
         (RPC_Receiver : Entity_Id;
@@ -630,13 +689,16 @@ package body Exp_Dist is
 
    end GARLIC_Support;
 
+   ---------------------
+   -- PolyORB_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.
+      --  The subprograms below provide the PolyORB versions of the
+      --  corresponding Specific_<subprogram> routine declared above.
 
       procedure Add_RACW_Features
         (RACW_Type         : Entity_Id;
@@ -644,7 +706,7 @@ package body Exp_Dist is
          Stub_Type         : Entity_Id;
          Stub_Type_Access  : Entity_Id;
          RPC_Receiver_Decl : Node_Id;
-         Declarations      : List_Id);
+         Body_Decls        : List_Id);
 
       procedure Add_RAST_Features
         (Vis_Decl : Node_Id;
@@ -672,8 +734,7 @@ package body Exp_Dist is
 
       procedure Build_Stub_Type
         (RACW_Type         : Entity_Id;
-         Stub_Type         : Entity_Id;
-         Stub_Type_Decl    : out Node_Id;
+         Stub_Type_Comps   : out List_Id;
          RPC_Receiver_Decl : out Node_Id);
 
       function Build_Subprogram_Receiving_Stubs
@@ -692,7 +753,8 @@ package body Exp_Dist is
 
       procedure Add_Receiving_Stubs_To_Declarations
         (Pkg_Spec : Node_Id;
-         Decls    : List_Id);
+         Decls    : List_Id;
+         Stmts    : List_Id);
 
       procedure Build_RPC_Receiver_Body
         (RPC_Receiver : Entity_Id;
@@ -709,20 +771,26 @@ package body Exp_Dist is
       --  their methods to be accessed as objects, for the implementation of
       --  remote access-to-subprogram types).
 
+      -------------
+      -- Helpers --
+      -------------
+
       package Helpers is
 
-         --  Routines to build distribtion helper subprograms for user-defined
+         --  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.
+
+         --    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;
@@ -793,10 +861,44 @@ package body Exp_Dist is
          --  for entity E (a distributed object type or operation): one
          --  containing the name of E, the second containing its repository id.
 
+         procedure Assign_Opaque_From_Any
+           (Loc    : Source_Ptr;
+            Stms   : List_Id;
+            Typ    : Entity_Id;
+            N      : Node_Id;
+            Target : Entity_Id);
+         --  For a Target object of type Typ, which has opaque representation
+         --  as a sequence of octets determined by stream attributes (which
+         --  includes all limited types), append code to Stmts performing the
+         --  equivalent of:
+         --    Target := Typ'From_Any (N)
+         --
+         --  or, if Target is Empty:
+         --    return Typ'From_Any (N)
+
       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 --
    ------------------------------------
@@ -812,78 +914,170 @@ package body Exp_Dist is
    --  since this require separate mechanisms ('Input is a function while
    --  'Read is a procedure).
 
+   generic
+      with procedure Process_Subprogram_Declaration (Decl : Node_Id);
+      --  Generate calling or receiving stub for this subprogram declaration
+
+   procedure Build_Package_Stubs (Pkg_Spec : Node_Id);
+   --  Recursively visit the given RCI Package_Specification, calling
+   --  Process_Subprogram_Declaration for each remote subprogram.
+
+   -------------------------
+   -- Build_Package_Stubs --
+   -------------------------
+
+   procedure Build_Package_Stubs (Pkg_Spec : Node_Id) is
+      Decls : constant List_Id := Visible_Declarations (Pkg_Spec);
+      Decl  : Node_Id;
+
+      procedure Visit_Nested_Pkg (Nested_Pkg_Decl : Node_Id);
+      --  Recurse for the given nested package declaration
+
+      -----------------------
+      -- Visit_Nested_Spec --
+      -----------------------
+
+      procedure Visit_Nested_Pkg (Nested_Pkg_Decl : Node_Id) is
+         Nested_Pkg_Spec : constant Node_Id := Specification (Nested_Pkg_Decl);
+      begin
+         Push_Scope (Scope_Of_Spec (Nested_Pkg_Spec));
+         Build_Package_Stubs (Nested_Pkg_Spec);
+         Pop_Scope;
+      end Visit_Nested_Pkg;
+
+   --  Start of processing for Build_Package_Stubs
+
+   begin
+      Decl := First (Decls);
+      while Present (Decl) loop
+         case Nkind (Decl) is
+            when N_Subprogram_Declaration =>
+
+               --  Note: we test Comes_From_Source on Spec, not Decl, because
+               --  in the case of a subprogram instance, only the specification
+               --  (not the declaration) is marked as coming from source.
+
+               if Comes_From_Source (Specification (Decl)) then
+                  Process_Subprogram_Declaration (Decl);
+               end if;
+
+            when N_Package_Declaration =>
+
+               --  Case of a nested package or package instantiation coming
+               --  from source. Note that the anonymous wrapper package for
+               --  subprogram instances is not flagged Is_Generic_Instance at
+               --  this point, so there is a distinct circuit to handle them
+               --  (see case N_Subprogram_Instantiation below).
+
+               declare
+                  Pkg_Ent : constant Entity_Id :=
+                              Defining_Unit_Name (Specification (Decl));
+               begin
+                  if Comes_From_Source (Decl)
+                    or else
+                      (Is_Generic_Instance (Pkg_Ent)
+                         and then Comes_From_Source
+                                    (Get_Package_Instantiation_Node (Pkg_Ent)))
+                  then
+                     Visit_Nested_Pkg (Decl);
+                  end if;
+               end;
+
+            when N_Subprogram_Instantiation =>
+
+               --  The subprogram declaration for an instance of a generic
+               --  subprogram is wrapped in a package that does not come from
+               --  source, so we need to explicitly traverse it here.
+
+               if Comes_From_Source (Decl) then
+                  Visit_Nested_Pkg (Instance_Spec (Decl));
+               end if;
+
+            when others =>
+               null;
+         end case;
+         Next (Decl);
+      end loop;
+   end Build_Package_Stubs;
+
    ---------------------------------------
    -- Add_Calling_Stubs_To_Declarations --
    ---------------------------------------
 
-   procedure Add_Calling_Stubs_To_Declarations
-     (Pkg_Spec : Node_Id;
-      Decls    : List_Id)
-   is
+   procedure Add_Calling_Stubs_To_Declarations (Pkg_Spec : Node_Id) is
+      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.
 
-      Current_Declaration       : Node_Id;
-      Loc                       : constant Source_Ptr := Sloc (Pkg_Spec);
-      RCI_Instantiation         : Node_Id;
-      Subp_Stubs                : Node_Id;
-      Subp_Str                  : String_Id;
+      RCI_Instantiation : Node_Id;
+
+      procedure Visit_Subprogram (Decl : Node_Id);
+      --  Generate calling stub for one remote subprogram
+
+      ----------------------
+      -- Visit_Subprogram --
+      ----------------------
+
+      procedure Visit_Subprogram (Decl : Node_Id) is
+         Loc        : constant Source_Ptr := Sloc (Decl);
+         Spec       : constant Node_Id := Specification (Decl);
+         Subp_Stubs : Node_Id;
+
+         Subp_Str : String_Id;
+         pragma Warnings (Off, Subp_Str);
+
+      begin
+         Assign_Subprogram_Identifier
+           (Defining_Unit_Name (Spec), Current_Subprogram_Number, Subp_Str);
+
+         Subp_Stubs :=
+           Build_Subprogram_Calling_Stubs
+             (Vis_Decl     => Decl,
+              Subp_Id      =>
+                Build_Subprogram_Id (Loc, Defining_Unit_Name (Spec)),
+              Asynchronous =>
+                Nkind (Spec) = N_Procedure_Specification
+                  and then Is_Asynchronous (Defining_Unit_Name (Spec)));
+
+         Append_To (List_Containing (Decl), Subp_Stubs);
+         Analyze (Subp_Stubs);
+
+         Current_Subprogram_Number := Current_Subprogram_Number + 1;
+      end Visit_Subprogram;
+
+      procedure Visit_Spec is new Build_Package_Stubs (Visit_Subprogram);
+
+   --  Start of processing for Add_Calling_Stubs_To_Declarations
 
    begin
+      Push_Scope (Scope_Of_Spec (Pkg_Spec));
+
       --  The first thing added is an instantiation of the generic 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.
+      --  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);
 
-      Append_To (Decls, RCI_Instantiation);
+      Append_To (Visible_Declarations (Pkg_Spec), 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.
+      --  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 subprogram. The receiving stubs processing uses the same
+      --  mechanism and will thus assign the same Id and do the correct
+      --  dispatching.
 
       Overload_Counter_Table.Reset;
       PolyORB_Support.Reserve_NamingContext_Methods;
 
-      Current_Declaration := First (Visible_Declarations (Pkg_Spec));
+      Visit_Spec (Pkg_Spec);
 
-      while Present (Current_Declaration) loop
-         if Nkind (Current_Declaration) = N_Subprogram_Declaration
-           and then Comes_From_Source (Current_Declaration)
-         then
-            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      =>
-                  Build_Subprogram_Id (Loc,
-                    Defining_Unit_Name (Specification (Current_Declaration))),
-                Asynchronous =>
-                  Nkind (Specification (Current_Declaration)) =
-                    N_Procedure_Specification
-                  and then
-                    Is_Asynchronous (Defining_Unit_Name (Specification
-                      (Current_Declaration))));
-
-            Append_To (Decls, Subp_Stubs);
-            Analyze (Subp_Stubs);
-
-            Current_Subprogram_Number := Current_Subprogram_Number + 1;
-         end if;
-
-         Next (Current_Declaration);
-      end loop;
+      Pop_Scope;
    end Add_Calling_Stubs_To_Declarations;
 
    -----------------------------
@@ -905,9 +1099,9 @@ package body Exp_Dist is
         (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.
+      --  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 --
@@ -947,18 +1141,23 @@ package body Exp_Dist is
       if Nkind (Parameter) = N_Defining_Identifier then
          Get_Name_String (Chars (Parameter));
       else
-         Get_Name_String (Chars (Defining_Identifier
-                                  (Parameter)));
+         Get_Name_String (Chars (Defining_Identifier (Parameter)));
       end if;
 
       Parameter_Name_String := String_From_Name_Buffer;
 
-      if RACW_Ctrl then
-         Parameter_Mode := New_Occurrence_Of
-           (RTE (RE_Mode_In), Loc);
+      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);
+         Parameter_Mode :=
+           Parameter_Passing_Mode (Loc, Parameter, Constrained);
       end if;
 
       return
@@ -1011,45 +1210,65 @@ package body Exp_Dist is
    -- Add_RACW_Features --
    -----------------------
 
-   procedure Add_RACW_Features (RACW_Type : 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;
       RPC_Receiver_Decl : Node_Id;
-      Existing          : Boolean;
+
+      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;
@@ -1062,8 +1281,16 @@ package body Exp_Dist is
          Stub_Type           => Stub_Type,
          Stub_Type_Access    => Stub_Type_Access,
          RPC_Receiver_Decl   => RPC_Receiver_Decl,
+         Body_Decls          => Body_Decls,
          Existing            => Existing);
 
+      --  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);
@@ -1074,20 +1301,26 @@ package body Exp_Dist is
          Stub_Type           => Stub_Type,
          Stub_Type_Access    => Stub_Type_Access,
          RPC_Receiver_Decl   => RPC_Receiver_Decl,
-         Declarations        => Decls);
+         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   => RPC_Receiver_Decl,
-            Decls            => Decls);
+            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;
@@ -1099,19 +1332,26 @@ package body Exp_Dist is
    procedure Add_RACW_Primitive_Declarations_And_Bodies
      (Designated_Type : Entity_Id;
       Insertion_Node  : Node_Id;
-      Decls           : List_Id)
+      Body_Decls      : List_Id)
    is
+      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.
 
-      Loc : constant Source_Ptr := Sloc (Insertion_Node);
-
       Stub_Elements : constant Stub_Structure :=
                         Stubs_Table.Get (Designated_Type);
 
       pragma Assert (Stub_Elements /= Empty_Stub_Structure);
+
       Is_RAS : constant Boolean :=
-        not Comes_From_Source (Stub_Elements.RACW_Type);
+                 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;
 
@@ -1131,15 +1371,11 @@ 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;
+      Current_Receiver         : Entity_Id;
+      Current_Receiver_Body    : Node_Id;
+      RPC_Receiver_Decl        : Node_Id;
+      Possibly_Asynchronous    : Boolean;
 
    begin
       if not Expander_Active then
@@ -1147,70 +1383,87 @@ package body Exp_Dist is
       end if;
 
       if not Is_RAS then
-         RPC_Receiver := Make_Defining_Identifier (Loc,
-                           New_Internal_Name ('P'));
-         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);
+         RPC_Receiver := Make_Temporary (Loc, 'P');
+
+         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);
 
          if Get_PCS_Name = Name_PolyORB_DSA then
 
             --  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.
+            --  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.
+      --  receiver for this type. Note that we use Direct_Primitive_Operations,
+      --  not Primitive_Operations, because we really want just the primitives
+      --  of the tagged type itself, and in the case of a tagged synchronized
+      --  type we do not want to get the primitives of the corresponding
+      --  record type).
 
-      if Present (Primitive_Operations (Designated_Type)) then
+      if Present (Direct_Primitive_Operations (Designated_Type)) then
          Overload_Counter_Table.Reset;
 
          Current_Primitive_Elmt :=
-           First_Elmt (Primitive_Operations (Designated_Type));
+           First_Elmt (Direct_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)
+                   or else
+                     Is_Predefined_Interface_Primitive (Current_Primitive))
+              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 Controlling_Type
                --  transformed into formals referencing Stub_Type. Since this
                --  primitive may have been inherited, go back the alias chain
                --  until the real primitive has been found.
 
-               Current_Primitive_Alias := Current_Primitive;
-               while Present (Alias (Current_Primitive_Alias)) loop
-                  pragma Assert
-                    (Current_Primitive_Alias
-                      /= Alias (Current_Primitive_Alias));
-                  Current_Primitive_Alias := Alias (Current_Primitive_Alias);
-               end loop;
+               Current_Primitive_Alias := Ultimate_Alias (Current_Primitive);
+
+               --  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 Controlling_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 :=
@@ -1222,26 +1475,30 @@ package body Exp_Dist is
                  Current_Primitive_Number,
                  Subp_Str);
 
-               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 (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.
+               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).
+
+               end if;
 
                --  Build the receiver stubs
 
-               if not Is_RAS then
+               if Build_Bodies and then not Is_RAS then
                   Current_Receiver_Body :=
                     Specific_Build_Subprogram_Receiving_Stubs
                       (Vis_Decl                 => Current_Primitive_Decl,
@@ -1251,10 +1508,10 @@ package body Exp_Dist is
                        RACW_Type                => Stub_Elements.RACW_Type,
                        Parent_Primitive         => Current_Primitive);
 
-                  Current_Receiver := Defining_Unit_Name (
-                    Specification (Current_Receiver_Body));
+                  Current_Receiver :=
+                    Defining_Unit_Name (Specification (Current_Receiver_Body));
 
-                  Append_To (Decls, Current_Receiver_Body);
+                  Append_To (Body_Decls, Current_Receiver_Body);
 
                   --  Add a case alternative to the receiver
 
@@ -1269,13 +1526,14 @@ package body Exp_Dist is
                              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,
-                                  Current_Primitive_Number)))));
+                                  Intval => Current_Primitive_Number)))));
                   end if;
 
                   Append_To (RPC_Receiver_Case_Alternatives,
@@ -1302,7 +1560,7 @@ package body Exp_Dist is
 
       --  Build the case statement and the heart of the subprogram
 
-      if not Is_RAS then
+      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
@@ -1324,15 +1582,15 @@ package body Exp_Dist is
                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,
-           Decls, RPC_Receiver, Stub_Elements);
-      end if;
+           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;
 
    -----------------------------
@@ -1342,15 +1600,10 @@ package body Exp_Dist is
    procedure Add_RAS_Dereference_TSS (N : Node_Id) is
       Loc : constant Source_Ptr := Sloc (N);
 
-      Type_Def : constant Node_Id   := Type_Definition (N);
-
+      Type_Def  : constant Node_Id   := Type_Definition (N);
       RAS_Type  : constant Entity_Id := Defining_Identifier (N);
       Fat_Type  : constant Entity_Id := Equivalent_Type (RAS_Type);
       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);
 
       RACW_Primitive_Name : Node_Id;
 
@@ -1363,16 +1616,14 @@ package body Exp_Dist is
       Param_Assoc : constant List_Id := New_List;
       Stmts       : constant List_Id := New_List;
 
-      RAS_Parameter : constant Entity_Id :=
-                        Make_Defining_Identifier (Loc,
-                          Chars => New_Internal_Name ('P'));
+      RAS_Parameter : constant Entity_Id := Make_Temporary (Loc, 'P');
 
       Is_Function : constant Boolean :=
                       Nkind (Type_Def) = N_Access_Function_Definition;
 
       Is_Degenerate : Boolean;
-      --  Set to True if the subprogram_specification for this RAS has
-      --  an anonymous access parameter (see Process_Remote_AST_Declaration).
+      --  Set to True if the subprogram_specification for this RAS has an
+      --  anonymous access parameter (see Process_Remote_AST_Declaration).
 
       Spec : constant Node_Id := Type_Def;
 
@@ -1381,8 +1632,8 @@ package body Exp_Dist is
    --  Start of processing for Add_RAS_Dereference_TSS
 
    begin
-      --  The Dereference TSS for a remote access-to-subprogram type
-      --  has the form:
+      --  The Dereference TSS for a remote access-to-subprogram type has the
+      --  form:
 
       --    [function|procedure] ras_typeRD (RAS_Value, <RAS_Parameters>)
       --       [return <>]
@@ -1405,11 +1656,12 @@ package body Exp_Dist is
       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
+         if Nkind (Parameter_Type (Current_Parameter)) =
+                                            N_Access_Definition
          then
             Is_Degenerate := True;
          end if;
+
          Append_To (Param_Specs,
            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
@@ -1434,9 +1686,9 @@ package body Exp_Dist is
 
          --  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.
+         --  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.
 
          Append_To (Stmts,
            Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
@@ -1444,32 +1696,31 @@ package body Exp_Dist is
 
       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.
+         --  tagged type, and perform a dispatching call to its Call primitive
+         --  operation.
 
          Prepend_To (Param_Assoc,
            Unchecked_Convert_To (RACW_Type,
              New_Occurrence_Of (RAS_Parameter, Loc)));
 
-         RACW_Primitive_Name := Make_Selected_Component (Loc,
-                                  Prefix        => Scope (RACW_Type),
-                                  Selector_Name => Name_Call);
+         RACW_Primitive_Name :=
+           Make_Selected_Component (Loc,
+             Prefix        => Scope (RACW_Type),
+             Selector_Name => Name_uCall);
       end if;
 
       if Is_Function then
          Append_To (Stmts,
-            Make_Return_Statement (Loc,
+            Make_Simple_Return_Statement (Loc,
               Expression =>
                 Make_Function_Call (Loc,
-              Name                   =>
-                RACW_Primitive_Name,
-              Parameter_Associations => Param_Assoc)));
+                  Name                   => RACW_Primitive_Name,
+                  Parameter_Associations => Param_Assoc)));
 
       else
          Append_To (Stmts,
            Make_Procedure_Call_Statement (Loc,
-             Name                   =>
-               RACW_Primitive_Name,
+             Name                   => RACW_Primitive_Name,
              Parameter_Associations => Param_Assoc));
       end if;
 
@@ -1480,13 +1731,13 @@ package body Exp_Dist is
            Make_Function_Specification (Loc,
              Defining_Unit_Name       => Proc,
              Parameter_Specifications => Param_Specs,
-             Subtype_Mark             =>
+             Result_Definition        =>
                New_Occurrence_Of (
-                 Entity (Subtype_Mark (Spec)), Loc));
+                 Entity (Result_Definition (Spec)), Loc));
 
          Set_Ekind (Proc, E_Function);
          Set_Etype (Proc,
-           New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
+           New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
 
       else
          Proc_Spec :=
@@ -1524,17 +1775,16 @@ package body Exp_Dist is
       Subp_Name : constant Entity_Id :=
                      Defining_Unit_Name (Specification (Vis_Decl));
 
-      Pkg_Name   : constant Entity_Id :=
-                     Make_Defining_Identifier (Loc,
-                       Chars =>
-                         New_External_Name (Chars (Subp_Name), 'P', -1));
+      Pkg_Name : constant Entity_Id :=
+                   Make_Defining_Identifier (Loc,
+                     Chars => New_External_Name (Chars (Subp_Name), 'P', -1));
 
       Proxy_Type : constant Entity_Id :=
                      Make_Defining_Identifier (Loc,
                        Chars =>
-                         New_External_Name (
-                           Related_Id => Chars (Subp_Name),
-                           Suffix     => 'P'));
+                         New_External_Name
+                           (Related_Id => Chars (Subp_Name),
+                            Suffix     => 'P'));
 
       Proxy_Type_Full_View : constant Entity_Id :=
                                Make_Defining_Identifier (Loc,
@@ -1580,12 +1830,9 @@ package body Exp_Dist is
 
       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)));
+          Defining_Identifier => Proxy_Object_Addr,
+          Constant_Present    => True,
+          Object_Definition   => New_Occurrence_Of (RTE (RE_Address), Loc)));
 
       --  private
 
@@ -1596,14 +1843,13 @@ package body Exp_Dist is
 
       Append_To (Pvt_Decls,
         Make_Full_Type_Declaration (Loc,
-          Defining_Identifier =>
-            Proxy_Type_Full_View,
+          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.
+      --  Trick semantic analysis into swapping the public and full view when
+      --  freezing the public view.
 
       Set_Comes_From_Source (Proxy_Type_Full_View, True);
 
@@ -1625,19 +1871,15 @@ package body Exp_Dist is
       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);
+             Name                   => New_Occurrence_Of (Subp_Name, Loc),
+             Parameter_Associations => Actuals);
       else
          Perform_Call :=
-           Make_Return_Statement (Loc,
+           Make_Simple_Return_Statement (Loc,
              Expression =>
-           Make_Function_Call (Loc,
-             Name =>
-               New_Occurrence_Of (Subp_Name, Loc),
-             Parameter_Associations =>
-               Actuals));
+               Make_Function_Call (Loc,
+                 Name                   => New_Occurrence_Of (Subp_Name, Loc),
+                 Parameter_Associations => Actuals));
       end if;
 
       Formal := First (Parameter_Specifications (Subp_Decl_Spec));
@@ -1653,31 +1895,23 @@ package body Exp_Dist is
 
       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)));
+          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO),
+          Aliased_Present     => True,
+          Object_Definition   => New_Occurrence_Of (Proxy_Type, Loc)));
 
       --  A : constant System.Address := O'Address;
 
       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),
+            Make_Defining_Identifier (Loc, Chars (Proxy_Object_Addr)),
+          Constant_Present    => True,
+          Object_Definition   => New_Occurrence_Of (RTE (RE_Address), Loc),
           Expression =>
             Make_Attribute_Reference (Loc,
               Prefix => New_Occurrence_Of (
                 Defining_Identifier (Last (Pvt_Decls)), Loc),
-              Attribute_Name =>
-                Name_Address)));
+              Attribute_Name => Name_Address)));
 
       Append_To (Decls,
         Make_Package_Declaration (Loc,
@@ -1691,12 +1925,10 @@ package body Exp_Dist is
       Append_To (Decls,
         Make_Package_Body (Loc,
           Defining_Unit_Name =>
-            Make_Defining_Identifier (Loc,
-              Chars (Pkg_Name)),
+            Make_Defining_Identifier (Loc, Chars (Pkg_Name)),
           Declarations => New_List (
             Make_Subprogram_Body (Loc,
-              Specification  =>
-                Subp_Body_Spec,
+              Specification  => Subp_Body_Spec,
               Declarations   => New_List,
               Handled_Statement_Sequence =>
                 Make_Handled_Sequence_Of_Statements (Loc,
@@ -1728,12 +1960,14 @@ package body Exp_Dist is
       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);
 
-      Stub_Elements : constant Stub_Structure :=
-                        Stubs_Table.Get (Designated_Type);
+      Stub_Elements         : constant Stub_Structure :=
+                                Stubs_Table.Get (Designated_Type);
+      Stub_Type_Comps       : List_Id;
       Stub_Type_Decl        : Node_Id;
       Stub_Type_Access_Decl : Node_Id;
 
@@ -1742,22 +1976,38 @@ package body Exp_Dist is
          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;
 
-      Existing         := False;
-      Stub_Type        :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+      Existing := False;
+      Stub_Type := Make_Temporary (Loc, 'S');
+      Set_Ekind (Stub_Type, E_Record_Type);
+      Set_Is_RACW_Stub_Type (Stub_Type);
       Stub_Type_Access :=
         Make_Defining_Identifier (Loc,
-          New_External_Name (
-            Related_Id => Chars (Stub_Type),
-            Suffix     => 'A'));
+          Chars => New_External_Name
+                     (Related_Id => Chars (Stub_Type), Suffix => 'A'));
+
+      Specific_Build_Stub_Type (RACW_Type, Stub_Type_Comps, RPC_Receiver_Decl);
 
-      Specific_Build_Stub_Type (
-        RACW_Type, Stub_Type,
-        Stub_Type_Decl, RPC_Receiver_Decl);
+      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 => Stub_Type_Comps)));
+
+      --  Does the stub type need to explicitly implement interfaces from the
+      --  designated type???
+
+      --  In particular are there issues in the case where the designated type
+      --  is a synchronized interface???
 
       Stub_Type_Access_Decl :=
         Make_Full_Type_Declaration (Loc,
@@ -1772,9 +2022,10 @@ package body Exp_Dist is
       Append_To (Decls, Stub_Type_Access_Decl);
       Analyze (Last (Decls));
 
-      --  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.
+      --  We can't directly derive the stub type from the designated type,
+      --  because we don't want any components or discriminants from the real
+      --  type, so instead we manually fake a derivation to get an appropriate
+      --  dispatch table.
 
       Derive_Subprograms (Parent_Type  => Designated_Type,
                           Derived_Type => Stub_Type);
@@ -1785,13 +2036,34 @@ package body Exp_Dist is
          RPC_Receiver_Decl := Last (Decls);
       end if;
 
+      Body_Decls := New_List;
+
       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;
 
+   ------------------------
+   -- Append_RACW_Bodies --
+   ------------------------
+
+   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;
+
+         Next_Entity (E);
+      end loop;
+   end Append_RACW_Bodies;
+
    ----------------------------------
    -- Assign_Subprogram_Identifier --
    ----------------------------------
@@ -1811,10 +2083,9 @@ package body Exp_Dist is
 
       Get_Name_String (N);
 
-      --  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.
+      --  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.
 
       if Overload_Order > 1 then
          Name_Buffer (Name_Len + 1 .. Name_Len + 2) := "__";
@@ -1823,10 +2094,128 @@ package body Exp_Dist is
       end if;
 
       Id := String_From_Name_Buffer;
-      Subprogram_Identifier_Table.Set (Def,
-        Subprogram_Identifiers'(Str_Identifier => Id, Int_Identifier => Spn));
+      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.
+
+      --  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.
+
+      if Ada_Version <= Ada_95
+        and then Is_Limited_Type (Etyp)
+        and then Present (Expr)
+      then
+
+         --  Object : Etyp renames <func-call>
+
+         Append_To (Decls,
+           Make_Object_Renaming_Declaration (Loc,
+             Defining_Identifier => Object,
+             Subtype_Mark        => New_Occurrence_Of (Etyp, Loc),
+             Name                => Expr));
+
+         if Variable then
+
+            --  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.
+
+            declare
+               Constant_Object : constant Entity_Id :=
+                                   Make_Temporary (Loc, 'P');
+
+            begin
+               Set_Defining_Identifier
+                 (Last (Decls), Constant_Object);
+
+               --  We have an unconstrained Etyp: build the actual constrained
+               --  subtype for the value we just read from the stream.
+
+               --  subtype S is <actual subtype of Constant_Object>;
+
+               Append_To (Decls,
+                 Build_Actual_Subtype (Etyp,
+                   New_Occurrence_Of (Constant_Object, Loc)));
+
+               --  Object : S;
+
+               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);
+
+               --  Suppress default initialization:
+               --  pragma Import (Ada, Object);
+
+               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;
+
+               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;
+
+      else
+         --  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.
+
+         --  Object : [constant] Etyp [:= <expr>];
+
+         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 --
    ------------------------------
@@ -1848,17 +2237,14 @@ package body Exp_Dist is
         Make_Assignment_Statement (Loc,
           Name =>
             Make_Selected_Component (Loc,
-              Prefix =>
-                New_Occurrence_Of (Pointer, 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)));
+              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
@@ -1874,12 +2260,13 @@ package body Exp_Dist 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 not Present (Parameter_Specifications (Spec)) then
+      if No (Parameter_Specifications (Spec)) then
          return New_List;
       end if;
 
@@ -1893,15 +2280,17 @@ package body Exp_Dist is
          For_RAS := True;
       end if;
 
-      --  Loop through the parameters and add them to the right list
+      --  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
-         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))))
+         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));
@@ -1962,8 +2351,7 @@ package body Exp_Dist is
             Make_Attribute_Reference (Loc,
               Prefix         =>
                 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
-              Attribute_Name =>
-                Name_Version)));
+              Attribute_Name => Name_Version)));
       Append_To (L, Reg);
       Analyze (Reg);
    end Build_Passive_Partition_Stub;
@@ -2037,6 +2425,22 @@ package body Exp_Dist is
                         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 --
    ------------------------------------
@@ -2109,9 +2513,10 @@ package body Exp_Dist is
    --  Start of processing for Build_Subprogram_Calling_Stubs
 
    begin
-      Subp_Spec := Copy_Specification (Loc,
-        Spec     => Specification (Vis_Decl),
-        New_Name => New_Name);
+      Subp_Spec :=
+        Copy_Specification (Loc,
+          Spec     => Specification (Vis_Decl),
+          New_Name => New_Name);
 
       if Locator = Empty then
          RCI_Locator := RCI_Cache;
@@ -2197,31 +2602,72 @@ package body Exp_Dist is
       E   : Entity_Id) return Node_Id
    is
    begin
-      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;
+      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;
 
-   ------------------------
-   -- Copy_Specification --
-   ------------------------
+            pragma Warnings (Off, Current_Subp_Str);
 
-   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
+         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;
-      Current_Etype      : Entity_Id;
 
       Name_For_New_Spec : Name_Id;
 
@@ -2247,30 +2693,30 @@ package body Exp_Dist is
             Current_Type       := Parameter_Type (Current_Parameter);
 
             if Nkind (Current_Type) = N_Access_Definition then
-               Current_Etype := Entity (Subtype_Mark (Current_Type));
-
-               if Present (Object_Type) then
-                  pragma Assert (
-                    Root_Type (Current_Etype) = Root_Type (Object_Type));
+               if Present (Ctrl_Type) then
+                  pragma Assert (Is_Controlling_Formal (Current_Identifier));
                   Current_Type :=
                     Make_Access_Definition (Loc,
-                      Subtype_Mark => New_Occurrence_Of (Stub_Type, 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_Occurrence_Of (Current_Etype, Loc));
+                        New_Copy_Tree (Subtype_Mark (Current_Type)),
+                      Null_Exclusion_Present =>
+                        Null_Exclusion_Present (Current_Type));
                end if;
 
             else
-               Current_Etype := Entity (Current_Type);
-
-               if Present (Object_Type)
-                 and then Current_Etype = Object_Type
+               if Present (Ctrl_Type)
+                 and then Is_Controlling_Formal (Current_Identifier)
                then
-                  Current_Type := New_Occurrence_Of (Stub_Type, Loc);
+                  Current_Type := New_Occurrence_Of (Ctrl_Type, Loc);
                else
-                  Current_Type := New_Occurrence_Of (Current_Etype, Loc);
+                  Current_Type := New_Copy_Tree (Current_Type);
                end if;
             end if;
 
@@ -2313,8 +2759,8 @@ package body Exp_Dist is
                   Make_Defining_Identifier (Loc,
                     Chars => Name_For_New_Spec),
                 Parameter_Specifications => Parameters,
-                Subtype_Mark             =>
-                  New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
+                Result_Definition        =>
+                  New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
 
          when N_Procedure_Specification | N_Access_Procedure_Definition =>
             return
@@ -2329,6 +2775,18 @@ package body Exp_Dist is
       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 --
    ---------------------------
@@ -2371,8 +2829,7 @@ package body Exp_Dist is
 
       Append_To (Stmts,
         Make_Procedure_Call_Statement (Loc,
-          Name =>
-            New_Occurrence_Of (RTE (RE_NVList_Create), Loc),
+          Name => New_Occurrence_Of (RTE (RE_NVList_Create), Loc),
           Parameter_Associations => New_List (
             New_Occurrence_Of (NVList, Loc))));
    end Declare_Create_NVList;
@@ -2382,11 +2839,11 @@ package body Exp_Dist is
    ---------------------------------------------
 
    procedure Expand_All_Calls_Remote_Subprogram_Call (N : Node_Id) is
+      Loc               : constant Source_Ptr := Sloc (N);
       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;
+      RCI_Locator_Decl  : Node_Id;
+      RCI_Locator       : Entity_Id;
       Calling_Stubs     : Node_Id;
       E_Calling_Stubs   : Entity_Id;
 
@@ -2394,41 +2851,35 @@ package body Exp_Dist is
       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
-                  New_Scope (Spec_Entity (Scop));
-
-               elsif Ekind (Scop) = E_Subprogram_Body then
-                  New_Scope
-                     (Corresponding_Spec (Unit_Declaration_Node (Scop)));
+         RCI_Locator := RCI_Locator_Table.Get (RCI_Package);
 
-               else
-                  New_Scope (Scop);
-               end if;
+         --  The RCI_Locator package and calling stub are 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.
 
-               Analyze (RCI_Locator);
-               Pop_Scope;
-            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;
+         end;
 
-            RCI_Cache   := Defining_Unit_Name (RCI_Locator);
+         if RCI_Locator = Empty then
+            RCI_Locator_Decl :=
+              RCI_Package_Locator
+                (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
+            Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator_Decl);
+            Analyze (RCI_Locator_Decl);
+            RCI_Locator := Defining_Unit_Name (RCI_Locator_Decl);
 
          else
-            RCI_Locator := Parent (RCI_Cache);
+            RCI_Locator_Decl := Parent (RCI_Locator);
          end if;
 
          Calling_Stubs := Build_Subprogram_Calling_Stubs
@@ -2438,10 +2889,12 @@ package body Exp_Dist is
             Asynchronous           => Nkind (N) = N_Procedure_Call_Statement
                                         and then
                                       Is_Asynchronous (Called_Subprogram),
-            Locator                => RCI_Cache,
+            Locator                => RCI_Locator,
             New_Name               => New_Internal_Name ('S'));
-         Insert_After (RCI_Locator, Calling_Stubs);
+         Insert_After (RCI_Locator_Decl, Calling_Stubs);
          Analyze (Calling_Stubs);
+         Pop_Scope;
+
          E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
       end if;
 
@@ -2454,12 +2907,8 @@ package body Exp_Dist is
 
    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
-      New_Scope (Scope_Of_Spec (Spec));
-      Add_Calling_Stubs_To_Declarations
-        (Specification (Unit_Node), Decls);
-      Pop_Scope;
+      Add_Calling_Stubs_To_Declarations (Spec);
    end Expand_Calling_Stubs_Bodies;
 
    -----------------------------------
@@ -2467,9 +2916,10 @@ package body Exp_Dist is
    -----------------------------------
 
    procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is
-      Spec  : Node_Id;
-      Decls : List_Id;
-      Temp  : List_Id;
+      Spec        : Node_Id;
+      Decls       : List_Id;
+      Stubs_Decls : List_Id;
+      Stubs_Stmts : List_Id;
 
    begin
       if Nkind (Unit_Node) = N_Package_Declaration then
@@ -2480,17 +2930,35 @@ package body Exp_Dist is
             Decls := Visible_Declarations (Spec);
          end if;
 
-         New_Scope (Scope_Of_Spec (Spec));
-         Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls);
+         Push_Scope (Scope_Of_Spec (Spec));
+         Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls, Decls);
 
       else
-         Spec  :=
+         Spec :=
            Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
          Decls := Declarations (Unit_Node);
-         New_Scope (Scope_Of_Spec (Unit_Node));
-         Temp := New_List;
-         Specific_Add_Receiving_Stubs_To_Declarations (Spec, Temp);
-         Insert_List_Before (First (Decls), Temp);
+
+         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;
@@ -2508,28 +2976,29 @@ package body Exp_Dist is
         (RACW_Type        : Entity_Id;
          Stub_Type        : Entity_Id;
          Stub_Type_Access : Entity_Id;
-         Declarations     : 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.
+         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;
-         Declarations     : List_Id);
-      --  Same thing for the Write attribute
+         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.
+      --  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).
+      --  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
@@ -2542,15 +3011,16 @@ package body Exp_Dist is
         (Loc           : Source_Ptr;
          Decls         : List_Id;
          RPC_Receiver  : Entity_Id;
-         Stub_Elements : Stub_Structure) is
+         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.
+         --  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,
@@ -2569,7 +3039,7 @@ package body Exp_Dist is
          Stub_Type         : Entity_Id;
          Stub_Type_Access  : Entity_Id;
          RPC_Receiver_Decl : Node_Id;
-         Declarations      : List_Id)
+         Body_Decls        : List_Id)
       is
          RPC_Receiver : Node_Id;
          Is_RAS       : constant Boolean := not Comes_From_Source (RACW_Type);
@@ -2579,9 +3049,9 @@ package body Exp_Dist is
 
          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.
+            --  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         =>
@@ -2595,18 +3065,18 @@ package body Exp_Dist is
               Attribute_Name => Name_Address);
          end if;
 
-         Add_RACW_Write_Attribute (
-           RACW_Type,
-           Stub_Type,
-           Stub_Type_Access,
-           RPC_Receiver,
-           Declarations);
-
-         Add_RACW_Read_Attribute (
-           RACW_Type,
-           Stub_Type,
-           Stub_Type_Access,
-           Declarations);
+         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;
 
       -----------------------------
@@ -2617,43 +3087,67 @@ package body Exp_Dist is
         (RACW_Type        : Entity_Id;
          Stub_Type        : Entity_Id;
          Stub_Type_Access : Entity_Id;
-         Declarations     : List_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;
-         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'));
-         Local_Stub        : constant Entity_Id :=
-                               Make_Defining_Identifier
-                                 (Loc, New_Internal_Name ('L'));
-         Stubbed_Result    : constant Entity_Id :=
-                               Make_Defining_Identifier
-                                 (Loc, New_Internal_Name ('S'));
+         Pnam              : constant Entity_Id := Make_Temporary (Loc, '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_Temporary (Loc, 'P');
+         Source_Receiver  := Make_Temporary (Loc, 'S');
+         Source_Address   := Make_Temporary (Loc, 'P');
+         Local_Stub       := Make_Temporary (Loc, 'L');
+         Stubbed_Result   := Make_Temporary (Loc, 'S');
+
          --  Generate object declarations
 
          Decls := New_List (
@@ -2690,7 +3184,7 @@ package body Exp_Dist is
 
          --  Read the source Partition_ID and RPC_Receiver from incoming stream
 
-         Statements := New_List (
+         Append_List_To (Statements, New_List (
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
@@ -2715,25 +3209,41 @@ package body Exp_Dist is
                Name_Read,
              Expressions    => New_List (
                Stream_Parameter,
-               New_Occurrence_Of (Source_Address, Loc))));
+               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
+         --  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.
 
-         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))));
+         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.
@@ -2783,16 +3293,15 @@ package body Exp_Dist is
 
          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.
+         --  ??? 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,
@@ -2815,26 +3324,8 @@ package body Exp_Dist is
              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));
-
-         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
-         Insert_After (Proc_Decl, Attr_Decl);
-         Append_To (Declarations, Body_Node);
+         Append_To (Body_Decls, Body_Node);
       end Add_RACW_Read_Attribute;
 
       ------------------------------
@@ -2846,20 +3337,41 @@ package body Exp_Dist is
          Stub_Type        : Entity_Id;
          Stub_Type_Access : Entity_Id;
          RPC_Receiver     : Node_Id;
-         Declarations     : List_Id)
+         Body_Decls       : List_Id)
       is
          Body_Node : Node_Id;
          Proc_Decl : Node_Id;
          Attr_Decl : Node_Id;
 
-         Statements        : List_Id;
+         Statements        : constant List_Id := New_List;
          Local_Statements  : List_Id;
          Remote_Statements : List_Id;
          Null_Statements   : List_Id;
 
-         Procedure_Name : constant Name_Id := New_Internal_Name ('R');
+         Pnam : constant Entity_Id := Make_Temporary (Loc, '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.
 
@@ -2888,35 +3400,31 @@ package body Exp_Dist is
          --  a remote object.
 
          Remote_Statements := New_List (
-
            Pack_Node_Into_Stream_Access (Loc,
-            Stream => Stream_Parameter,
-            Object =>
+             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)),
+                 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)),
+                 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)),
+                 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
@@ -2937,13 +3445,15 @@ package body Exp_Dist is
              Object => Make_Integer_Literal (Loc, Uint_0),
              Etyp   => RTE (RE_Unsigned_64)));
 
-         Statements := New_List (
+         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       =>
@@ -2952,6 +3462,7 @@ package body Exp_Dist is
                        Make_Attribute_Reference (Loc,
                          Prefix         => Object,
                          Attribute_Name => Name_Tag),
+
                      Right_Opnd =>
                        Make_Attribute_Reference (Loc,
                          Prefix         => New_Occurrence_Of (Stub_Type, Loc),
@@ -2959,25 +3470,7 @@ package body Exp_Dist is
                  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,
-             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);
+         Append_To (Body_Decls, Body_Node);
       end Add_RACW_Write_Attribute;
 
       ------------------------
@@ -3035,25 +3528,16 @@ package body Exp_Dist is
          Proc_Decls      : List_Id;
          Proc_Statements : List_Id;
 
-         Origin : constant Entity_Id :=
-                    Make_Defining_Identifier (Loc,
-                      Chars => New_Internal_Name ('P'));
+         Origin : constant Entity_Id := Make_Temporary (Loc, 'P');
 
          --  Additional local variables for the local case
 
-         Proxy_Addr : constant Entity_Id :=
-                        Make_Defining_Identifier (Loc,
-                          Chars => New_Internal_Name ('P'));
+         Proxy_Addr : constant Entity_Id := Make_Temporary (Loc, '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'));
+         Local_Stub : constant Entity_Id := Make_Temporary (Loc, 'L');
+         Stub_Ptr   : constant Entity_Id := Make_Temporary (Loc, 'S');
 
          function Set_Field
            (Field_Name : Name_Id;
@@ -3084,7 +3568,7 @@ package body Exp_Dist is
       begin
          Proc_Decls := New_List (
 
-         --  Common declarations
+            --  Common declarations
 
            Make_Object_Declaration (Loc,
              Defining_Identifier => Origin,
@@ -3098,15 +3582,15 @@ package body Exp_Dist is
                  Parameter_Associations => New_List (
                    New_Occurrence_Of (Package_Name, Loc)))),
 
-         --  Declaration use only in the local case: proxy address
+            --  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.
+            --  Declarations used only in the remote case: stub object and
+            --  stub pointer.
 
            Make_Object_Declaration (Loc,
              Defining_Identifier => Local_Stub,
@@ -3125,7 +3609,8 @@ package body Exp_Dist is
                  Attribute_Name => Name_Unchecked_Access)));
 
          Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
-         --  Build_Get_Unique_RP_Call needs this information
+
+         --  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.
@@ -3142,8 +3627,7 @@ package body Exp_Dist is
          --    end if;
 
             Make_Procedure_Call_Statement (Loc,
-              Name =>
-                New_Occurrence_Of (RTE (RE_Get_RAS_Info), 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),
@@ -3160,11 +3644,13 @@ package body Exp_Dist is
                        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_Return_Statement (Loc,
+               Make_Simple_Return_Statement (Loc,
                  Unchecked_Convert_To (Fat_Type,
                    OK_Convert_To (RTE (RE_Address),
                      New_Occurrence_Of (Proxy_Addr, Loc)))))),
@@ -3181,12 +3667,12 @@ package body Exp_Dist is
 
            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.
+            --  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.
+            --  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,
@@ -3201,7 +3687,7 @@ package body Exp_Dist is
          --  Return the newly created value
 
          Append_To (Proc_Statements,
-           Make_Return_Statement (Loc,
+           Make_Simple_Return_Statement (Loc,
              Expression =>
                Unchecked_Convert_To (Fat_Type,
                  New_Occurrence_Of (Stub_Ptr, Loc))));
@@ -3230,7 +3716,7 @@ package body Exp_Dist is
                  Parameter_Type      =>
                    New_Occurrence_Of (Standard_Boolean, Loc))),
 
-            Subtype_Mark =>
+            Result_Definition =>
               New_Occurrence_Of (Fat_Type, Loc));
 
          --  Set the kind and return type of the function to prevent
@@ -3258,9 +3744,7 @@ package body Exp_Dist is
         (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;
@@ -3271,39 +3755,34 @@ package body Exp_Dist is
 
       procedure Add_Receiving_Stubs_To_Declarations
         (Pkg_Spec : Node_Id;
-         Decls    : List_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'));
+                                         Make_Temporary (Loc, '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.
+         Lookup_RAS      : Node_Id;
+         Lookup_RAS_Info : constant Entity_Id := Make_Temporary (Loc, '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;
+         Current_Subp_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;
+         Subp_Info_Array : constant Entity_Id := Make_Temporary (Loc, 'I');
+         Subp_Info_List  : constant List_Id := New_List;
 
          Register_Pkg_Actuals : constant List_Id := New_List;
 
@@ -3318,6 +3797,9 @@ package body Exp_Dist is
          --  associating Subprogram_Number with the subprogram declared
          --  by Declaration, for which we have receiving stubs in Stubs.
 
+         procedure Visit_Subprogram (Decl : Node_Id);
+         --  Generate receiving stub for one remote subprogram
+
          ---------------------
          -- Append_Stubs_To --
          ---------------------
@@ -3336,12 +3818,81 @@ package body Exp_Dist is
                   New_List (
                     Make_Procedure_Call_Statement (Loc,
                       Name                   =>
-                        New_Occurrence_Of (
-                          Defining_Entity (Stubs), Loc),
+                        New_Occurrence_Of (Defining_Entity (Stubs), Loc),
                       Parameter_Associations => New_List (
                         New_Occurrence_Of (Request_Parameter, Loc))))));
          end Append_Stubs_To;
 
+         ----------------------
+         -- Visit_Subprogram --
+         ----------------------
+
+         procedure Visit_Subprogram (Decl : Node_Id) is
+            Loc      : constant Source_Ptr := Sloc (Decl);
+            Spec     : constant Node_Id    := Specification (Decl);
+            Subp_Def : constant Entity_Id  := Defining_Unit_Name (Spec);
+
+            Subp_Val : String_Id;
+            pragma Warnings (Off, Subp_Val);
+
+         begin
+            --  Build receiving stub
+
+            Current_Stubs :=
+              Build_Subprogram_Receiving_Stubs
+                (Vis_Decl     => Decl,
+                 Asynchronous =>
+                   Nkind (Spec) = 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           => Decl,
+              All_Calls_Remote_E => All_Calls_Remote_E,
+              Proxy_Object_Addr  => Proxy_Object_Addr);
+
+            --  Compute distribution identifier
+
+            Assign_Subprogram_Identifier
+              (Subp_Def, Current_Subp_Number,  Subp_Val);
+
+            pragma Assert (Current_Subp_Number = Get_Subprogram_Id (Subp_Def));
+
+            --  Add subprogram descriptor (RCI_Subp_Info) to the subprograms
+            --  table for this receiver. This aggregate must be kept consistent
+            --  with the declaration of RCI_Subp_Info in
+            --  System.Partition_Interface.
+
+            Append_To (Subp_Info_List,
+              Make_Component_Association (Loc,
+                Choices    => New_List (
+                  Make_Integer_Literal (Loc, Current_Subp_Number)),
+
+                Expression =>
+                  Make_Aggregate (Loc,
+                    Component_Associations => New_List (
+
+                      --  Addr =>
+
+                      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_Subp_Number);
+
+            Current_Subp_Number := Current_Subp_Number + 1;
+         end Visit_Subprogram;
+
+         procedure Visit_Spec is new Build_Package_Stubs (Visit_Subprogram);
+
       --  Start of processing for Add_Receiving_Stubs_To_Declarations
 
       begin
@@ -3349,17 +3900,17 @@ package body Exp_Dist is
 
          --    - 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
+         --      and will dispatch the call to the right subprogram;
 
-         --    - a receiving stub for any subprogram visible in the package
+         --    - 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
+         --      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
+         --      by calling System.Partition_Interface.Register_Receiving_Stub.
 
          Build_RPC_Receiver_Body (
            RPC_Receiver => Pkg_RPC_Receiver,
@@ -3380,10 +3931,12 @@ package body Exp_Dist is
                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 =>
@@ -3398,12 +3951,12 @@ package body Exp_Dist is
                                Make_Selected_Component (Loc,
                                  Prefix        => Request_Parameter,
                                  Selector_Name => Name_Params))))),
-                     Selector_Name =>
-                       Make_Identifier (Loc, Name_Subp_Id))))));
+
+                     Selector_Name => Make_Identifier (Loc, Name_Subp_Id))))));
 
          --  Build a subprogram for RAS information lookups
 
-         Current_Declaration :=
+         Lookup_RAS :=
            Make_Subprogram_Declaration (Loc,
              Specification =>
                Make_Function_Specification (Loc,
@@ -3417,114 +3970,32 @@ package body Exp_Dist is
                        True,
                      Parameter_Type =>
                        New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
-                 Subtype_Mark =>
+                 Result_Definition =>
                    New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
-         Append_To (Decls, Current_Declaration);
-         Analyze (Current_Declaration);
+         Append_To (Decls, Lookup_RAS);
+         Analyze (Lookup_RAS);
 
          Current_Stubs := Build_Subprogram_Receiving_Stubs
-           (Vis_Decl     => Current_Declaration,
+           (Vis_Decl     => Lookup_RAS,
             Asynchronous => False);
          Append_To (Decls, Current_Stubs);
          Analyze (Current_Stubs);
 
          Append_Stubs_To (Pkg_RPC_Receiver_Cases,
-           Stubs       =>
-             Current_Stubs,
+           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)));
+         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;
-
-               begin
-                  pragma Assert (Current_Subprogram_Number =
-                    Get_Subprogram_Id (Subp_Def));
-
-                  --  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);
-
-                  --  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;
+         Visit_Spec (Pkg_Spec);
 
          --  If we receive an invalid Subprogram_Id, it is best to do nothing
          --  rather than raising an exception since we do not want someone
@@ -3536,15 +4007,12 @@ package body Exp_Dist is
 
          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))));
+             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),
+             Expression   => New_Occurrence_Of (Subp_Id, Loc),
              Alternatives => Pkg_RPC_Receiver_Cases));
 
          Append_To (Decls,
@@ -3564,83 +4032,119 @@ package body Exp_Dist is
                            First_RCI_Subprogram_Id),
                          High_Bound =>
                            Make_Integer_Literal (Loc,
-                             First_RCI_Subprogram_Id
-                             + List_Length (Subp_Info_List) - 1))))),
-             Expression          =>
-               Make_Aggregate (Loc,
-                 Component_Associations => Subp_Info_List)));
-         Analyze (Last (Decls));
+                             Intval =>
+                               First_RCI_Subprogram_Id
+                               + List_Length (Subp_Info_List) - 1)))))));
 
-         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_Return_Statement (Loc,
-                     Expression => OK_Convert_To (RTE (RE_Unsigned_64),
-                       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))))))));
-         Analyze (Last (Decls));
+         --  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.
 
-         Append_To (Decls, Pkg_RPC_Receiver_Body);
-         Analyze (Last (Decls));
+         if Present (First (Subp_Info_List)) then
+            Set_Expression (Last (Decls),
+              Make_Aggregate (Loc,
+                Component_Associations => Subp_Info_List));
 
-         Get_Library_Unit_Name_String (Pkg_Spec);
-         Append_To (Register_Pkg_Actuals,
-            --  Name
-           Make_String_Literal (Loc,
-             Strval => String_From_Name_Buffer));
+         --  No initialization provided: remove CONSTANT so that the
+         --  declaration is not an incomplete deferred constant.
 
-         Append_To (Register_Pkg_Actuals,
-            --  Receiver
-           Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
-             Attribute_Name =>
-               Name_Unrestricted_Access));
+         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,
-            --  Version
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
-             Attribute_Name =>
-               Name_Version));
+             Attribute_Name => Name_Version));
+
+         --  Subp_Info
 
          Append_To (Register_Pkg_Actuals,
-            --  Subp_Info
            Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (Subp_Info_Array, Loc),
-             Attribute_Name =>
-               Name_Address));
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Address));
+
+         --  Subp_Info_Len
 
          Append_To (Register_Pkg_Actuals,
-            --  Subp_Info_Len
            Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (Subp_Info_Array, Loc),
-             Attribute_Name =>
-               Name_Length));
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Length));
 
-         Append_To (Decls,
+         --  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 (Decls));
+         Analyze (Last (Stmts));
       end Add_Receiving_Stubs_To_Declarations;
 
       ---------------------------------
@@ -3665,8 +4169,8 @@ package body Exp_Dist is
          Loc : constant Source_Ptr := Sloc (Nod);
 
          Stream_Parameter : Node_Id;
-         --  Name of the stream used to transmit parameters to the
-         --  remote package.
+         --  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
@@ -3690,10 +4194,8 @@ package body Exp_Dist is
          --  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:
@@ -3713,8 +4215,7 @@ package body Exp_Dist is
          --  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'));
+         Stream_Parameter := Make_Temporary (Loc, 'S');
 
          Append_To (Decls,
            Make_Object_Declaration (Loc,
@@ -3730,8 +4231,7 @@ package body Exp_Dist is
                        New_List (Make_Integer_Literal (Loc, 0))))));
 
          if not Is_Known_Asynchronous then
-            Result_Parameter :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+            Result_Parameter := Make_Temporary (Loc, 'R');
 
             Append_To (Decls,
               Make_Object_Declaration (Loc,
@@ -3746,8 +4246,7 @@ package body Exp_Dist is
                         Constraints =>
                           New_List (Make_Integer_Literal (Loc, 0))))));
 
-            Exception_Return_Parameter :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
+            Exception_Return_Parameter := Make_Temporary (Loc, 'E');
 
             Append_To (Decls,
               Make_Object_Declaration (Loc,
@@ -3769,10 +4268,8 @@ package body Exp_Dist is
              Attribute_Name => Name_Write,
              Expressions    => New_List (
                Make_Attribute_Reference (Loc,
-                 Prefix         =>
-                   New_Occurrence_Of (Stream_Parameter, Loc),
-                 Attribute_Name =>
-                   Name_Access),
+                 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
@@ -3780,14 +4277,11 @@ package body Exp_Dist is
 
          Append_To (Statements,
            Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
-             Attribute_Name =>
-               Name_Write,
+             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),
+                 Prefix         => New_Occurrence_Of (Stream_Parameter, Loc),
                  Attribute_Name => Name_Access),
                Subprogram_Id)));
 
@@ -3803,7 +4297,7 @@ package body Exp_Dist is
 
             begin
                if Is_RACW_Controlling_Formal
-                 (Current_Parameter, Stub_Type)
+                    (Current_Parameter, Stub_Type)
                then
                   --  In the case of a controlling formal argument, we marshall
                   --  its addr field rather than the local stub.
@@ -3819,8 +4313,9 @@ package body Exp_Dist is
                        Etyp   => RTE (RE_Unsigned_64)));
 
                else
-                  Value := New_Occurrence_Of
-                    (Defining_Identifier (Current_Parameter), Loc);
+                  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
@@ -3833,8 +4328,7 @@ package body Exp_Dist is
                      Etyp := Etype (Typ);
                   end if;
 
-                  Constrained :=
-                    Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
+                  Constrained := not Transmit_As_Unconstrained (Etyp);
 
                   --  Any parameter but unconstrained out parameters are
                   --  transmitted to the peer.
@@ -3845,8 +4339,7 @@ package body Exp_Dist is
                   then
                      Append_To (Statements,
                        Make_Attribute_Reference (Loc,
-                         Prefix         =>
-                           New_Occurrence_Of (Etyp, Loc),
+                         Prefix         => New_Occurrence_Of (Etyp, Loc),
                          Attribute_Name =>
                            Output_From_Constrained (Constrained),
                          Expressions    => New_List (
@@ -3872,8 +4365,7 @@ package body Exp_Dist is
                   --  type and push it in the stream after the regular
                   --  parameters.
 
-                  Extra_Parameter := Make_Defining_Identifier
-                                       (Loc, New_Internal_Name ('P'));
+                  Extra_Parameter := Make_Temporary (Loc, 'P');
 
                   Append_To (Decls,
                      Make_Object_Declaration (Loc,
@@ -3892,13 +4384,12 @@ package body Exp_Dist is
                      Make_Attribute_Reference (Loc,
                        Prefix         =>
                          New_Occurrence_Of (Standard_Boolean, Loc),
-                       Attribute_Name =>
-                         Name_Write,
+                       Attribute_Name => Name_Write,
                        Expressions    => New_List (
                          Make_Attribute_Reference (Loc,
                            Prefix         =>
-                             New_Occurrence_Of (Stream_Parameter, Loc),
-                           Attribute_Name =>
+                             New_Occurrence_Of
+                              (Stream_Parameter, Loc), Attribute_Name =>
                              Name_Access),
                          New_Occurrence_Of (Extra_Parameter, Loc))));
                end if;
@@ -3924,8 +4415,7 @@ package body Exp_Dist is
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       New_Occurrence_Of (Stream_Parameter, Loc),
-                    Attribute_Name =>
-                      Name_Access))));
+                    Attribute_Name => Name_Access))));
          else
             Asynchronous_Statements := No_List;
          end if;
@@ -3944,14 +4434,12 @@ package body Exp_Dist is
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       New_Occurrence_Of (Stream_Parameter, Loc),
-                    Attribute_Name =>
-                      Name_Access),
+                    Attribute_Name => Name_Access),
 
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       New_Occurrence_Of (Result_Parameter, Loc),
-                    Attribute_Name =>
-                      Name_Access))));
+                    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
@@ -3962,15 +4450,13 @@ package body Exp_Dist is
                 Prefix         =>
                   New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
 
-                Attribute_Name =>
-                  Name_Read,
+                Attribute_Name => Name_Read,
 
                 Expressions    => New_List (
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       New_Occurrence_Of (Result_Parameter, Loc),
-                    Attribute_Name =>
-                      Name_Access),
+                    Attribute_Name => Name_Access),
                   New_Occurrence_Of (Exception_Return_Parameter, Loc))));
 
             Append_To (Non_Asynchronous_Statements,
@@ -3987,12 +4473,12 @@ package body Exp_Dist is
 
                Append_To (Non_Asynchronous_Statements,
                  Make_Tag_Check (Loc,
-                   Make_Return_Statement (Loc,
+                   Make_Simple_Return_Statement (Loc,
                      Expression =>
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of (
-                             Etype (Subtype_Mark (Spec)), Loc),
+                             Etype (Result_Definition (Spec)), Loc),
 
                          Attribute_Name => Name_Input,
 
@@ -4005,8 +4491,8 @@ package body Exp_Dist is
             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.
+               --  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
@@ -4043,8 +4529,7 @@ package body Exp_Dist is
                                Make_Attribute_Reference (Loc,
                                  Prefix         =>
                                    New_Occurrence_Of (Result_Parameter, Loc),
-                                 Attribute_Name =>
-                                   Name_Access),
+                                 Attribute_Name => Name_Access),
                                Value)));
                      end if;
                   end;
@@ -4117,7 +4602,7 @@ package body Exp_Dist is
              (RPC_Receiver      => RPC_Receiver,
               Request_Parameter => Request);
 
-         Subp_Id    := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         Subp_Id    := Make_Temporary (Loc, 'P');
          Subp_Index := Subp_Id;
 
          --  Subp_Id may not be a constant, because in the case of the RPC
@@ -4135,9 +4620,9 @@ package body Exp_Dist is
                    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)))));
+                   Make_Selected_Component (Loc,
+                     Prefix        => Request,
+                     Selector_Name => Name_Params)))));
 
          Stmts := New_List;
 
@@ -4161,9 +4646,10 @@ package body Exp_Dist is
          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'));
+         Target_Info.Partition := Make_Temporary (Loc, 'P');
+
          if Present (Controlling_Parameter) then
             Append_To (Decls,
               Make_Object_Declaration (Loc,
@@ -4215,62 +4701,49 @@ package body Exp_Dist is
 
       procedure Build_Stub_Type
         (RACW_Type         : Entity_Id;
-         Stub_Type         : Entity_Id;
-         Stub_Type_Decl    : out Node_Id;
+         Stub_Type_Comps   : out List_Id;
          RPC_Receiver_Decl : out Node_Id)
       is
-         Loc    : constant Source_Ptr := Sloc (Stub_Type);
+         Loc    : constant Source_Ptr := Sloc (RACW_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)))))));
+         Stub_Type_Comps := 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;
@@ -4281,10 +4754,9 @@ package body Exp_Dist is
             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));
+                   Build_RPC_Receiver_Specification
+                     (RPC_Receiver      => Make_Temporary (Loc, 'R'),
+                      Request_Parameter => RPC_Receiver_Request));
             end;
          end if;
       end Build_Stub_Type;
@@ -4303,8 +4775,9 @@ package body Exp_Dist is
       is
          Loc : constant Source_Ptr := Sloc (Vis_Decl);
 
-         Request_Parameter : Node_Id;
-         --  ???
+         Request_Parameter : constant Entity_Id := Make_Temporary (Loc, '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
@@ -4347,20 +4820,15 @@ package body Exp_Dist is
 
       begin
          if Present (RACW_Type) then
-            Called_Subprogram :=
-              New_Occurrence_Of (Parent_Primitive, Loc);
+            Called_Subprogram := New_Occurrence_Of (Parent_Primitive, Loc);
          else
             Called_Subprogram :=
-              New_Occurrence_Of (
-                Defining_Unit_Name (Specification (Vis_Decl)), Loc);
+              New_Occurrence_Of
+                (Defining_Unit_Name (Specification (Vis_Decl)), Loc);
          end if;
 
-         Request_Parameter :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
-
          if Dynamically_Asynchronous then
-            Dynamic_Async :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
+            Dynamic_Async := Make_Temporary (Loc, 'S');
          else
             Dynamic_Async := Empty;
          end if;
@@ -4368,7 +4836,7 @@ package body Exp_Dist is
          if not Asynchronous or Dynamically_Asynchronous then
 
             --  The first statement after the subprogram call is a statement to
-            --  writes a Null_Occurrence into the result stream.
+            --  write a Null_Occurrence into the result stream.
 
             Null_Raise_Statement :=
               Make_Attribute_Reference (Loc,
@@ -4376,9 +4844,9 @@ package body Exp_Dist is
                   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),
+                  Make_Selected_Component (Loc,
+                    Prefix        => Request_Parameter,
+                    Selector_Name => Name_Result),
                   New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
 
             if Dynamically_Asynchronous then
@@ -4402,19 +4870,18 @@ package body Exp_Dist is
                Etyp        : Entity_Id;
                Constrained : Boolean;
 
-               Object : constant Entity_Id :=
-                          Make_Defining_Identifier (Loc,
-                            New_Internal_Name ('P'));
+               Need_Extra_Constrained : Boolean;
+               --  True when an Extra_Constrained actual is required
 
-               Expr : Node_Id   := Empty;
+               Object : constant Entity_Id := Make_Temporary (Loc, 'P');
+
+               Expr : Node_Id := Empty;
 
                Is_Controlling_Formal : constant Boolean :=
                                          Is_RACW_Controlling_Formal
                                            (Current_Parameter, Stub_Type);
 
             begin
-               Set_Ekind (Object, E_Variable);
-
                if Is_Controlling_Formal then
 
                   --  We have a controlling formal parameter. Read its address
@@ -4426,21 +4893,23 @@ package body Exp_Dist is
                   Etyp := Etype (Parameter_Type (Current_Parameter));
                end if;
 
-               Constrained :=
-                 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
+               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 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 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 and then not Is_Controlling_Formal then
+                  if Constrained then
                      Append_To (Statements,
                        Make_Attribute_Reference (Loc,
                          Prefix         => New_Occurrence_Of (Etyp, Loc),
@@ -4452,30 +4921,48 @@ package body Exp_Dist is
                            New_Occurrence_Of (Object, Loc))));
 
                   else
-                     Expr := Input_With_Tag_Check (Loc,
-                       Var_Type => Etyp,
-                       Stream   => Make_Selected_Component (Loc,
-                                     Prefix        => Request_Parameter,
-                                     Selector_Name => Name_Params));
-                     Append_To (Decls, Expr);
-                     Expr := Make_Function_Call (Loc,
-                       New_Occurrence_Of (Defining_Unit_Name
-                         (Specification (Expr)), Loc));
+
+                     --  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;
 
-               --  If we do not have to output the current parameter, then it
-               --  can well be flagged as constant. This may allow further
-               --  optimizations done by the back end.
-
-               Append_To (Decls,
-                 Make_Object_Declaration (Loc,
-                   Defining_Identifier => Object,
-                   Constant_Present    => not Constrained
-                     and then not Out_Present (Current_Parameter),
-                   Object_Definition   =>
-                     New_Occurrence_Of (Etyp, Loc),
-                   Expression          => Expr));
+               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
@@ -4548,14 +5035,7 @@ package body Exp_Dist is
 
                --  The case of Extra_Accessibility should also be handled ???
 
-               if Nkind (Parameter_Type (Current_Parameter)) /=
-                                                         N_Access_Definition
-                 and then
-                   Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
-                 and then
-                   Present (Extra_Constrained
-                     (Defining_Identifier (Current_Parameter)))
-               then
+               if Need_Extra_Constrained then
                   declare
                      Extra_Parameter : constant Entity_Id :=
                                          Extra_Constrained
@@ -4586,6 +5066,11 @@ package body Exp_Dist is
                              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;
@@ -4606,10 +5091,9 @@ package body Exp_Dist is
 
             declare
                Etyp   : constant Entity_Id :=
-                          Etype (Subtype_Mark (Specification (Vis_Decl)));
-               Result : constant Node_Id   :=
-                          Make_Defining_Identifier (Loc,
-                             New_Internal_Name ('R'));
+                          Etype (Result_Definition (Specification (Vis_Decl)));
+               Result : constant Node_Id   := Make_Temporary (Loc, 'R');
+
             begin
                Inner_Decls := New_List (
                  Make_Object_Declaration (Loc,
@@ -4621,6 +5105,18 @@ package body Exp_Dist is
                        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),
@@ -4674,7 +5170,7 @@ package body Exp_Dist is
             --  For an asynchronous procedure, add a null exception handler
 
             Excep_Handlers := New_List (
-              Make_Exception_Handler (Loc,
+              Make_Implicit_Exception_Handler (Loc,
                 Exception_Choices => New_List (Make_Others_Choice (Loc)),
                 Statements        => New_List (Make_Null_Statement (Loc))));
 
@@ -4683,8 +5179,7 @@ package body Exp_Dist is
             --  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_Choice := Make_Temporary (Loc, 'E');
 
             Excep_Code := New_List (
               Make_Attribute_Reference (Loc,
@@ -4706,7 +5201,7 @@ package body Exp_Dist is
             end if;
 
             Excep_Handlers := New_List (
-              Make_Exception_Handler (Loc,
+              Make_Implicit_Exception_Handler (Loc,
                 Choice_Parameter   => Excep_Choice,
                 Exception_Choices  => New_List (Make_Others_Choice (Loc)),
                 Statements         => Excep_Code));
@@ -4715,8 +5210,7 @@ package body Exp_Dist is
 
          Subp_Spec :=
            Make_Procedure_Specification (Loc,
-             Defining_Unit_Name       =>
-               Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
+             Defining_Unit_Name       => Make_Temporary (Loc, 'F'),
 
              Parameter_Specifications => New_List (
                Make_Parameter_Specification (Loc,
@@ -4754,28 +5248,56 @@ package body Exp_Dist is
 
    end GARLIC_Support;
 
-   -----------------------------
-   -- Make_Selected_Component --
-   -----------------------------
+   -------------------------------
+   -- 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
 
-   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;
+      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
-      return Get_Subprogram_Ids (Def).Str_Identifier;
+      pragma Assert (Result /= No_String);
+      return Result;
    end Get_Subprogram_Id;
 
    -----------------------
@@ -4794,54 +5316,8 @@ package body Exp_Dist is
    function Get_Subprogram_Ids
      (Def : Entity_Id) return Subprogram_Identifiers
    is
-      Result : Subprogram_Identifiers :=
-                 Subprogram_Identifier_Table.Get (Def);
-
-      Current_Declaration : Node_Id;
-      Current_Subp        : Entity_Id;
-      Current_Subp_Str    : String_Id;
-      Current_Subp_Number : Int := First_RCI_Subprogram_Id;
-
    begin
-      if Result.Str_Identifier = No_String then
-
-         --  We are looking up this subprogram's identifier 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 (Def))
-              and then
-               (Nkind (Parent (Def)) = N_Procedure_Specification
-                  or else
-                Nkind (Parent (Def)) = N_Function_Specification));
-
-         Current_Declaration :=
-           First (Visible_Declarations
-             (Package_Specification_Of_Scope (Scope (Def))));
-         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);
-
-               if Current_Subp = Def then
-                  Result := (Current_Subp_Str, Current_Subp_Number);
-               end if;
-
-               Current_Subp_Number := Current_Subp_Number + 1;
-            end if;
-
-            Next (Current_Declaration);
-         end loop;
-      end if;
-
-      pragma Assert (Result.Str_Identifier /= No_String);
-      return Result;
+      return Subprogram_Identifier_Table.Get (Def);
    end Get_Subprogram_Ids;
 
    ----------
@@ -4870,15 +5346,15 @@ package body Exp_Dist 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)),
+          Specification              =>
+            Make_Function_Specification (Loc,
+              Defining_Unit_Name => Make_Temporary (Loc, '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_Return_Statement (Loc,
+                Make_Simple_Return_Statement (Loc,
                   Make_Attribute_Reference (Loc,
                     Prefix         => New_Occurrence_Of (Var_Type, Loc),
                     Attribute_Name => Name_Input,
@@ -4897,15 +5373,15 @@ package body Exp_Dist 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 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 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;
@@ -4917,13 +5393,46 @@ package body Exp_Dist is
         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'));
+      Occ : constant Entity_Id := Make_Temporary (Loc, 'E');
 
    begin
       return Make_Block_Statement (Loc,
@@ -4932,7 +5441,7 @@ package body Exp_Dist is
             Statements         => New_List (N),
 
             Exception_Handlers => New_List (
-              Make_Exception_Handler (Loc,
+              Make_Implicit_Exception_Handler (Loc,
                 Choice_Parameter => Occ,
 
                 Exception_Choices =>
@@ -5050,37 +5559,33 @@ package body Exp_Dist is
         (RACW_Type        : Entity_Id;
          Stub_Type        : Entity_Id;
          Stub_Type_Access : Entity_Id;
-         Declarations     : 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.
+         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;
-         Declarations     : List_Id);
-      --  Same thing for the Write attribute
+         Body_Decls       : List_Id);
+      --  Same as above for the Write attribute
 
       procedure Add_RACW_From_Any
         (RACW_Type        : Entity_Id;
-         Stub_Type        : Entity_Id;
-         Stub_Type_Access : Entity_Id;
-         Declarations     : List_Id);
+         Body_Decls       : List_Id);
       --  Add the From_Any TSS for this RACW type
 
       procedure Add_RACW_To_Any
-        (Designated_Type  : Entity_Id;
-         RACW_Type        : Entity_Id;
-         Stub_Type        : Entity_Id;
-         Stub_Type_Access : Entity_Id;
-         Declarations     : List_Id);
+        (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;
-         Declarations    : List_Id);
+         Body_Decls      : List_Id);
       --  Add the TypeCode TSS for this RACW type
 
       procedure Add_RAS_From_Any (RAS_Type : Entity_Id);
@@ -5119,7 +5624,7 @@ package body Exp_Dist is
                --  Name
 
                 Make_String_Literal (Loc,
-                  Full_Qualified_Name (Desig)),
+                  Fully_Qualified_Name_String (Desig)),
 
                --  Handler
 
@@ -5151,46 +5656,35 @@ package body Exp_Dist is
          Stub_Type         : Entity_Id;
          Stub_Type_Access  : Entity_Id;
          RPC_Receiver_Decl : Node_Id;
-         Declarations      : List_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,
-            Stub_Type           => Stub_Type,
-            Stub_Type_Access    => Stub_Type_Access,
-            Declarations        => Declarations);
+            Body_Decls          => Body_Decls);
 
          Add_RACW_To_Any
-           (Designated_Type     => Desig,
-            RACW_Type           => RACW_Type,
-            Stub_Type           => Stub_Type,
-            Stub_Type_Access    => Stub_Type_Access,
-            Declarations        => Declarations);
-
-         --  In the PolyORB case, the RACW 'Read and 'Write attributes
-         --  are implemented in terms of the From_Any and To_Any TSSs,
-         --  so these TSSs must be expanded before 'Read and 'Write.
+           (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,
-            Declarations        => Declarations);
+            Body_Decls          => Body_Decls);
 
          Add_RACW_Read_Attribute
            (RACW_Type           => RACW_Type,
             Stub_Type           => Stub_Type,
             Stub_Type_Access    => Stub_Type_Access,
-            Declarations        => Declarations);
+            Body_Decls          => Body_Decls);
 
          Add_RACW_TypeCode
            (Designated_Type     => Desig,
             RACW_Type           => RACW_Type,
-            Declarations        => Declarations);
+            Body_Decls          => Body_Decls);
       end Add_RACW_Features;
 
       -----------------------
@@ -5199,241 +5693,85 @@ package body Exp_Dist is
 
       procedure Add_RACW_From_Any
         (RACW_Type        : Entity_Id;
-         Stub_Type        : Entity_Id;
-         Stub_Type_Access : Entity_Id;
-         Declarations     : List_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, New_Internal_Name ('F'));
+                    Make_Defining_Identifier (Loc,
+                      Chars => New_External_Name (Chars (RACW_Type), 'F'));
 
          Func_Spec : Node_Id;
          Func_Decl : Node_Id;
          Func_Body : Node_Id;
 
-         Decls            : List_Id;
          Statements       : List_Id;
-         Stub_Statements  : List_Id;
-         Local_Statements : List_Id;
          --  Various parts of the subprogram
 
-         Any_Parameter  : constant Entity_Id :=
-                            Make_Defining_Identifier (Loc, Name_A);
-         Reference      : constant Entity_Id :=
-                            Make_Defining_Identifier
-                              (Loc, New_Internal_Name ('R'));
-         Is_Local       : constant Entity_Id  :=
-                            Make_Defining_Identifier
-                              (Loc, New_Internal_Name ('L'));
-         Addr           : constant Entity_Id  :=
-                            Make_Defining_Identifier
-                              (Loc, New_Internal_Name ('A'));
-         Local_Stub     : constant Entity_Id  :=
-                            Make_Defining_Identifier
-                              (Loc, New_Internal_Name ('L'));
-         Stubbed_Result : constant Entity_Id  :=
-                            Make_Defining_Identifier
-                              (Loc, New_Internal_Name ('S'));
-
-         Stub_Condition : Node_Id;
-         --  An expression that determines whether we create a stub for the
-         --  newly-unpacked RACW. Normally we create a stub only for remote
-         --  objects, but in the case of an RACW used to implement a RAS,
-         --  we also create a stub for local subprograms if a pragma
-         --  All_Calls_Remote applies.
+         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
-         --  Object declarations
-
-         Decls := New_List (
-           Make_Object_Declaration (Loc,
-             Defining_Identifier =>
-               Reference,
-             Object_Definition =>
-               New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
-             Expression =>
-               Make_Function_Call (Loc,
-                 Name =>
-                   New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
-                 Parameter_Associations => New_List (
-                   New_Occurrence_Of (Any_Parameter, Loc)))),
-
-           Make_Object_Declaration (Loc,
-             Defining_Identifier => Local_Stub,
-             Aliased_Present     => True,
-             Object_Definition   => New_Occurrence_Of (Stub_Type, Loc)),
+         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));
 
-           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)),
+         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
+         --  entity in the declaration spec, not those of the body spec.
 
-           Make_Object_Declaration (Loc,
-             Defining_Identifier => Is_Local,
-             Object_Definition   =>
-               New_Occurrence_Of (Standard_Boolean, Loc)),
+         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);
 
-           Make_Object_Declaration (Loc,
-             Defining_Identifier => Addr,
-             Object_Definition =>
-               New_Occurrence_Of (RTE (RE_Address), Loc)));
+         if No (Body_Decls) then
+            return;
+         end if;
 
-         --  Build_Get_Unique_RP_Call needs the type of Stubbed_Result
-
-         Set_Etype (Stubbed_Result, Stub_Type_Access);
-
-         --  If the ref Is_Nil, return a null pointer
+         --  ??? 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_Implicit_If_Statement (RACW_Type,
-             Condition =>
-               Make_Function_Call (Loc,
-                 Name =>
-                   New_Occurrence_Of (RTE (RE_Is_Nil), Loc),
-                 Parameter_Associations => New_List (
-                   New_Occurrence_Of (Reference, Loc))),
-             Then_Statements => New_List (
-               Make_Return_Statement (Loc,
-                 Expression =>
-                   Make_Null (Loc)))));
-
-         Append_To (Statements,
-           Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
-             Parameter_Associations => New_List (
-               New_Occurrence_Of (Reference, Loc),
-               New_Occurrence_Of (Is_Local, Loc),
-               New_Occurrence_Of (Addr, 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. This stanza is always used in the
-         --  case of RAS types, for which a stub is required even for local
-         --  subprograms.
-
-         Stub_Statements := New_List (
-           Make_Assignment_Statement (Loc,
-             Name       => Make_Selected_Component (Loc,
-               Prefix        => Stubbed_Result,
-               Selector_Name => Name_Target),
-             Expression =>
+           Make_Simple_Return_Statement (Loc,
+             Expression => Unchecked_Convert_To (RACW_Type,
                Make_Function_Call (Loc,
-                 Name =>
-                   New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
+                 Name => New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
                  Parameter_Associations => New_List (
-                   New_Occurrence_Of (Reference, Loc)))),
-
-           Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
-             Parameter_Associations => New_List (
-               Make_Selected_Component (Loc,
-                 Prefix        => Stubbed_Result,
-                 Selector_Name => Name_Target))),
-
-           Make_Assignment_Statement (Loc,
-             Name       => Make_Selected_Component (Loc,
-               Prefix        => Stubbed_Result,
-               Selector_Name => Name_Asynchronous),
-             Expression =>
-               New_Occurrence_Of (Asynchronous_Flag, Loc)));
-
-         --  ??? 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.
-
-         Append_List_To (Stub_Statements,
-           Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
-
-         --  Distinguish between the local and remote cases, and execute the
-         --  appropriate piece of code.
-
-         Stub_Condition := New_Occurrence_Of (Is_Local, Loc);
-
-         if Is_RAS then
-            Stub_Condition := Make_And_Then (Loc,
-              Left_Opnd  =>
-                Stub_Condition,
-              Right_Opnd =>
-                Make_Selected_Component (Loc,
-                  Prefix =>
-                    Unchecked_Convert_To (
-                      RTE (RE_RAS_Proxy_Type_Access),
-                      New_Occurrence_Of (Addr, Loc)),
-                  Selector_Name =>
-                    Make_Identifier (Loc,
-                      Name_All_Calls_Remote)));
-         end if;
-
-         Local_Statements := New_List (
-           Make_Return_Statement (Loc,
-             Expression =>
-               Unchecked_Convert_To (RACW_Type,
-                 New_Occurrence_Of (Addr, Loc))));
-
-         Append_To (Statements,
-           Make_Implicit_If_Statement (RACW_Type,
-             Condition =>
-               Stub_Condition,
-             Then_Statements => Local_Statements,
-             Else_Statements => Stub_Statements));
-
-         Append_To (Statements,
-           Make_Return_Statement (Loc,
-             Expression => Unchecked_Convert_To (RACW_Type,
-               New_Occurrence_Of (Stubbed_Result, Loc))));
-
-         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))),
-             Subtype_Mark => 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);
+                   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               => Decls,
+             Specification => Copy_Specification (Loc, Func_Spec),
+             Declarations  => No_List,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => Statements));
 
-         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
-         Append_To (Declarations, Func_Body);
-
-         Set_Renaming_TSS (RACW_Type, Fnam, TSS_From_Any);
+         Append_To (Body_Decls, Func_Body);
       end Add_RACW_From_Any;
 
       -----------------------------
@@ -5444,11 +5782,10 @@ package body Exp_Dist is
         (RACW_Type        : Entity_Id;
          Stub_Type        : Entity_Id;
          Stub_Type_Access : Entity_Id;
-         Declarations     : List_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;
@@ -5456,21 +5793,23 @@ package body Exp_Dist is
 
          Body_Node : Node_Id;
 
-         Decls             : List_Id;
-         Statements        : List_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
 
-         Procedure_Name    : constant Name_Id   :=
-                               New_Internal_Name ('R');
-         Source_Ref        : constant Entity_Id :=
-                               Make_Defining_Identifier
-                                 (Loc, New_Internal_Name ('R'));
+         Pnam : constant Entity_Id := Make_Temporary (Loc, '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
 
          ------------
@@ -5494,55 +5833,59 @@ package body Exp_Dist is
       --  Start of processing for Add_RACW_Read_Attribute
 
       begin
-         --  Generate object declarations
+         Build_Stream_Procedure
+           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => True);
 
-         Decls := New_List (
+         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 => Source_Ref,
-             Object_Definition   =>
+             Defining_Identifier =>
+               Reference,
+             Object_Definition =>
                New_Occurrence_Of (RTE (RE_Object_Ref), Loc)));
 
-         Statements := New_List (
+         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 (Source_Ref, Loc))),
+               New_Occurrence_Of (Reference, Loc))),
+
            Make_Assignment_Statement (Loc,
-             Name =>
+             Name       =>
                Result,
              Expression =>
-               PolyORB_Support.Helpers.Build_From_Any_Call (
-                 RACW_Type,
+               Unchecked_Convert_To (RACW_Type,
                  Make_Function_Call (Loc,
-                   Name =>
-                     New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc),
+                   Name                   =>
+                     New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
                    Parameter_Associations => New_List (
-                     New_Occurrence_Of (Source_Ref, Loc))),
-                 Decls)));
+                     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)))))));
 
-         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));
-
-         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
-         Insert_After (Proc_Decl, Attr_Decl);
-         Append_To (Declarations, Body_Node);
+         Append_To (Body_Decls, Body_Node);
       end Add_RACW_Read_Attribute;
 
       ---------------------
@@ -5550,159 +5893,115 @@ package body Exp_Dist is
       ---------------------
 
       procedure Add_RACW_To_Any
-        (Designated_Type  : Entity_Id;
-         RACW_Type        : Entity_Id;
-         Stub_Type        : Entity_Id;
-         Stub_Type_Access : Entity_Id;
-         Declarations     : List_Id)
+        (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), 'T'));
 
-         Fnam : Entity_Id;
+         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
 
          Stub_Elements : constant Stub_Structure :=
-           Stubs_Table.Get (Designated_Type);
-         pragma Assert (Stub_Elements /= Empty_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;
-         Null_Statements   : List_Id;
-         Local_Statements  : List_Id := No_List;
-         Stub_Statements   : List_Id;
-         If_Node           : Node_Id;
+         Decls      : List_Id;
+         Statements : List_Id;
          --  Various parts of the subprogram
 
-         RACW_Parameter : constant Entity_Id
-           := Make_Defining_Identifier (Loc, Name_R);
+         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'));
+         Reference : constant Entity_Id := Make_Temporary (Loc, 'R');
+         Any       : constant Entity_Id := Make_Temporary (Loc, 'A');
 
       begin
-         --  Object declarations
-
-         Decls := New_List (
-           Make_Object_Declaration (Loc,
-             Defining_Identifier =>
-               Reference,
-             Object_Definition =>
-               New_Occurrence_Of (RTE (RE_Object_Ref), Loc)),
-           Make_Object_Declaration (Loc,
-             Defining_Identifier =>
-               Any,
-             Object_Definition =>
-               New_Occurrence_Of (RTE (RE_Any), Loc)));
-
-         --  If the object is null, nothing to do (Reference is already
-         --  a Nil ref.)
+         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));
 
-         Null_Statements := New_List (Make_Null_Statement (Loc));
+         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
+         --  entity in the declaration spec, not in the body spec.
 
-         if Is_RAS then
+         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
 
-            --  If the object is a RAS designating a local subprogram,
-            --  we already have a target reference.
+         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
+         Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any);
 
-            Local_Statements := New_List (
-              Make_Procedure_Call_Statement (Loc,
-                Name =>
-                  New_Occurrence_Of (RTE (RE_Set_Ref), Loc),
-                Parameter_Associations => New_List (
-                  New_Occurrence_Of (Reference, Loc),
-                  Make_Selected_Component (Loc,
-                    Prefix =>
-                      Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
-                        New_Occurrence_Of (RACW_Parameter, Loc)),
-                    Selector_Name => Make_Identifier (Loc, Name_Target)))));
+         if No (Body_Decls) then
+            return;
+         end if;
 
-         else
-            --  If the object is a local RACW object, use Get_Reference now
-            --  to obtain a reference.
+         --  Generate:
 
-            Local_Statements := New_List (
-              Make_Procedure_Call_Statement (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,
-                    Full_Qualified_Name (Designated_Type)),
-                  Make_Attribute_Reference (Loc,
-                    Prefix =>
-                      New_Occurrence_Of (
-                        Defining_Identifier (
-                          Stub_Elements.RPC_Receiver_Decl), Loc),
-                    Attribute_Name =>
-                      Name_Access),
-                  New_Occurrence_Of (Reference, Loc))));
-         end if;
+         --    R : constant Object_Ref :=
+         --          Get_Reference
+         --            (Address!(RACW),
+         --             "typ",
+         --             Stub_Type'Tag,
+         --             Is_RAS,
+         --             RPC_Receiver'Access);
+         --    A : Any;
 
-         --  If the object is located on another partition, use the target
-         --  from the stub.
+         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 => Fully_Qualified_Name_String
+                                 (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)))),
 
-         Stub_Statements := New_List (
-           Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Set_Ref), Loc),
-             Parameter_Associations => New_List (
-               New_Occurrence_Of (Reference, Loc),
-               Make_Selected_Component (Loc,
-                 Prefix        => Unchecked_Convert_To (Stub_Type_Access,
-                   New_Occurrence_Of (RACW_Parameter, Loc)),
-                 Selector_Name =>
-                   Make_Identifier (Loc, Name_Target)))));
+           Make_Object_Declaration (Loc,
+             Defining_Identifier => Any,
+             Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc)));
 
-         --  Distinguish between the null, local and remote cases,
-         --  and execute the appropriate piece of code.
+         --  Generate:
 
-         If_Node :=
-           Make_Implicit_If_Statement (RACW_Type,
-             Condition       =>
-               Make_Op_Eq (Loc,
-                 Left_Opnd  => New_Occurrence_Of (RACW_Parameter, Loc),
-                 Right_Opnd => Make_Null (Loc)),
-             Then_Statements => Null_Statements,
-             Elsif_Parts     => New_List (
-               Make_Elsif_Part (Loc,
-                 Condition       =>
-                   Make_Op_Ne (Loc,
-                     Left_Opnd  =>
-                        Make_Attribute_Reference (Loc,
-                         Prefix         =>
-                           New_Occurrence_Of (RACW_Parameter, Loc),
-                         Attribute_Name => Name_Tag),
-                     Right_Opnd =>
-                       Make_Attribute_Reference (Loc,
-                         Prefix         => New_Occurrence_Of (Stub_Type, Loc),
-                         Attribute_Name => Name_Tag)),
-                 Then_Statements => Local_Statements)),
-             Else_Statements => Stub_Statements);
+         --    Any := TA_ObjRef (Reference);
+         --    Set_TC (Any, RPC_Receiver.Obj_TypeCode);
+         --    return Any;
 
          Statements := New_List (
-           If_Node,
            Make_Assignment_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (Any, 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),
+             Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
              Parameter_Associations => New_List (
                New_Occurrence_Of (Any, Loc),
                Make_Selected_Component (Loc,
@@ -5710,44 +6009,18 @@ package body Exp_Dist is
                      Defining_Identifier (
                        Stub_Elements.RPC_Receiver_Decl),
                  Selector_Name => Name_Obj_TypeCode))),
-           Make_Return_Statement (Loc,
-             Expression =>
-               New_Occurrence_Of (Any, Loc)));
-
-         Fnam := Make_Defining_Identifier (
-           Loc, New_Internal_Name ('T'));
-
-         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))),
-             Subtype_Mark => 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);
+           Make_Simple_Return_Statement (Loc,
+             Expression => New_Occurrence_Of (Any, Loc)));
 
          Func_Body :=
            Make_Subprogram_Body (Loc,
-             Specification              =>
-               Copy_Specification (Loc, Func_Spec),
+             Specification              => Copy_Specification (Loc, Func_Spec),
              Declarations               => Decls,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => Statements));
-
-         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
-         Append_To (Declarations, Func_Body);
-
-         Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any);
+         Append_To (Body_Decls, Func_Body);
       end Add_RACW_To_Any;
 
       -----------------------
@@ -5757,11 +6030,13 @@ package body Exp_Dist is
       procedure Add_RACW_TypeCode
         (Designated_Type  : Entity_Id;
          RACW_Type        : Entity_Id;
-         Declarations     : List_Id)
+         Body_Decls       : List_Id)
       is
          Loc : constant Source_Ptr := Sloc (RACW_Type);
 
-         Fnam : Entity_Id;
+         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);
@@ -5771,57 +6046,42 @@ package body Exp_Dist is
          Func_Decl : Node_Id;
          Func_Body : Node_Id;
 
-         RACW_Parameter : constant Entity_Id :=
-                            Make_Defining_Identifier (Loc, Name_R);
-
       begin
-         Fnam :=
-           Make_Defining_Identifier (Loc,
-             Chars => New_Internal_Name ('T'));
-
-         --  The spec for this subprogram has a dummy 'access RACW'
-         --  argument, which serves only for overloading purposes.
+         --  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,
-             Parameter_Specifications => New_List (
-               Make_Parameter_Specification (Loc,
-                 Defining_Identifier =>
-                   RACW_Parameter,
-                 Parameter_Type =>
-                   Make_Access_Definition (Loc,
-                     Subtype_Mark =>
-                       New_Occurrence_Of (RACW_Type, Loc)))),
-             Subtype_Mark => New_Occurrence_Of (RTE (RE_TypeCode), 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.
+         --  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),
+             Specification              => Copy_Specification (Loc, Func_Spec),
              Declarations               => Empty_List,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => New_List (
-                   Make_Return_Statement (Loc,
+                   Make_Simple_Return_Statement (Loc,
                      Expression =>
                        Make_Selected_Component (Loc,
                          Prefix =>
-                             Defining_Identifier (
-                               Stub_Elements.RPC_Receiver_Decl),
+                           Defining_Identifier
+                             (Stub_Elements.RPC_Receiver_Decl),
                          Selector_Name => Name_Obj_TypeCode)))));
 
-         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
-         Append_To (Declarations, Func_Body);
-
-         Set_Renaming_TSS (RACW_Type, Fnam, TSS_TypeCode);
+         Append_To (Body_Decls, Func_Body);
       end Add_RACW_TypeCode;
 
       ------------------------------
@@ -5832,24 +6092,23 @@ package body Exp_Dist is
         (RACW_Type        : Entity_Id;
          Stub_Type        : Entity_Id;
          Stub_Type_Access : Entity_Id;
-         Declarations     : List_Id)
+         Body_Decls       : List_Id)
       is
+         pragma Unreferenced (Stub_Type, Stub_Type_Access);
+
          Loc : constant Source_Ptr := Sloc (RACW_Type);
-         pragma Warnings (Off);
-         pragma Unreferenced (
-                  Stub_Type,
-                  Stub_Type_Access);
 
          Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
-         pragma Unreferenced (Is_RAS);
-         pragma Warnings (On);
+
+         Stub_Elements : constant Stub_Structure :=
+                            Get_Stub_Elements (RACW_Type);
 
          Body_Node : Node_Id;
          Proc_Decl : Node_Id;
          Attr_Decl : Node_Id;
 
-         Statements     : List_Id;
-         Procedure_Name : constant Name_Id := New_Internal_Name ('R');
+         Statements : constant List_Id := New_List;
+         Pnam : constant Entity_Id := Make_Temporary (Loc, 'R');
 
          function Stream_Parameter return Node_Id;
          function Object return Node_Id;
@@ -5860,15 +6119,8 @@ package body Exp_Dist is
          ------------
 
          function Object return Node_Id is
-            Object_Ref : constant Node_Id :=
-                           Make_Identifier (Loc, Name_V);
-
          begin
-            --  Etype must be set for Build_To_Any_Call
-
-            Set_Etype (Object_Ref, RACW_Type);
-
-            return Object_Ref;
+            return Make_Identifier (Loc, Name_V);
          end Object;
 
          ----------------------
@@ -5883,22 +6135,8 @@ package body Exp_Dist is
       --  Start of processing for Add_RACW_Write_Attribute
 
       begin
-         Statements := New_List (
-           Pack_Node_Into_Stream_Access (Loc,
-             Stream => Stream_Parameter,
-             Object =>
-               Make_Function_Call (Loc,
-                 Name =>
-                   New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
-                 Parameter_Associations => New_List (
-                   PolyORB_Support.Helpers.Build_To_Any_Call
-                     (Object, Declarations))),
-             Etyp => RTE (RE_Object_Ref)));
-
          Build_Stream_Procedure
-           (Loc, RACW_Type, Body_Node,
-            Make_Defining_Identifier (Loc, Procedure_Name),
-            Statements, Outp => False);
+           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => False);
 
          Proc_Decl :=
            Make_Subprogram_Declaration (Loc,
@@ -5914,7 +6152,34 @@ package body Exp_Dist is
 
          Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
          Insert_After (Proc_Decl, Attr_Decl);
-         Append_To (Declarations, Body_Node);
+
+         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 => Fully_Qualified_Name_String
+                                (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;
 
       -----------------------
@@ -5949,13 +6214,10 @@ package body Exp_Dist is
          --  corresponding record type.
 
          RACW_Type : constant Entity_Id :=
-           Underlying_RACW_Type (Ras_Type);
-         Desig     : constant Entity_Id :=
-           Etype (Designated_Type (RACW_Type));
+                       Underlying_RACW_Type (Ras_Type);
 
          Stub_Elements : constant Stub_Structure :=
-           Stubs_Table.Get (Desig);
-         pragma Assert (Stub_Elements /= Empty_Stub_Structure);
+                           Get_Stub_Elements (RACW_Type);
 
          Proc : constant Entity_Id :=
                   Make_Defining_Identifier (Loc,
@@ -6004,16 +6266,10 @@ package body Exp_Dist is
            Make_Defining_Identifier (Loc, Name_A);
          --  For the call to Get_Local_Address
 
+         Local_Stub : constant Entity_Id := Make_Temporary (Loc, 'L');
+         Stub_Ptr   : constant Entity_Id := Make_Temporary (Loc, 'S');
          --  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;
@@ -6067,8 +6323,7 @@ package body Exp_Dist is
                New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
 
            Make_Object_Declaration (Loc,
-             Defining_Identifier =>
-               Stub_Ptr,
+             Defining_Identifier => Stub_Ptr,
              Object_Definition   =>
                New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
              Expression          =>
@@ -6084,8 +6339,7 @@ package body Exp_Dist is
 
          Proc_Statements := New_List (
            Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Get_RAS_Info), 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),
@@ -6096,8 +6350,7 @@ package body Exp_Dist is
          --  obtain the local address of its proxy (A).
 
            Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Get_Local_Address), 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),
@@ -6108,117 +6361,112 @@ package body Exp_Dist is
 
          Append_To (Proc_Statements,
 
-         --  if L then
+           --  if L then
 
            Make_Implicit_If_Statement (N,
-             Condition =>
-               New_Occurrence_Of (Is_Local, Loc),
+             Condition => New_Occurrence_Of (Is_Local, Loc),
 
              Then_Statements => New_List (
 
-         --     if A.Target = null then
+               --  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)),
+                       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);
+                   --    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)),
+                         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),
+                         Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
                          Parameter_Associations => New_List (
                            New_Occurrence_Of (Subp_Ref, Loc)))),
 
-         --        Inc_Usage (A.Target);
+                   --    Inc_Usage (A.Target);
+                   --  end if;
 
                    Make_Procedure_Call_Statement (Loc,
-                     Name =>
-                       New_Occurrence_Of (RTE (RE_Inc_Usage), 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)))))),
+                           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;
+                 --     if not All_Calls_Remote then
+                 --        return Fat_Type!(A);
+                 --     end if;
 
                  Make_Implicit_If_Statement (N,
                    Condition =>
                      Make_Op_Not (Loc,
-                       New_Occurrence_Of (All_Calls_Remote, Loc)),
+                       Right_Opnd =>
+                         New_Occurrence_Of (All_Calls_Remote, Loc)),
 
                    Then_Statements => New_List (
-                     Make_Return_Statement (Loc,
-                       Unchecked_Convert_To (Fat_Type,
-                         New_Occurrence_Of (Local_Addr, Loc))))))));
+                     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);
+           --  Stub.Target := Entity_Of (Ref);
 
            Set_Field (Name_Target,
              Make_Function_Call (Loc,
-               Name =>
-                 New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
+               Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
                Parameter_Associations => New_List (
                  New_Occurrence_Of (Subp_Ref, Loc)))),
 
-         --  Inc_Usage (Stub.Target);
+           --  Inc_Usage (Stub.Target);
 
            Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Inc_Usage), 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.
+           --  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.
+           --    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,
-               New_Occurrence_Of (Asynch_P, Loc),
-               New_Occurrence_Of (Boolean_Literals (
-                 Is_Asynchronous (Ras_Type)), 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));
+           Build_Get_Unique_RP_Call (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
 
          Append_To (Proc_Statements,
-           Make_Return_Statement (Loc,
+           Make_Simple_Return_Statement (Loc,
              Expression =>
                Unchecked_Convert_To (Fat_Type,
                  New_Occurrence_Of (Stub_Ptr, Loc))));
@@ -6247,7 +6495,7 @@ package body Exp_Dist is
                  Parameter_Type      =>
                    New_Occurrence_Of (Standard_Boolean, Loc))),
 
-            Subtype_Mark =>
+            Result_Definition =>
               New_Occurrence_Of (Fat_Type, Loc));
 
          --  Set the kind and return type of the function to prevent
@@ -6286,13 +6534,12 @@ package body Exp_Dist is
 
       begin
          Statements := New_List (
-           Make_Return_Statement (Loc,
+           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)),
+                     Choices => New_List (Make_Identifier (Loc, Name_Ras)),
                      Expression =>
                        PolyORB_Support.Helpers.Build_From_Any_Call (
                          Underlying_RACW_Type (RAS_Type),
@@ -6301,15 +6548,12 @@ package body Exp_Dist is
 
          Func_Spec :=
            Make_Function_Specification (Loc,
-             Defining_Unit_Name =>
-               Fnam,
+             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))),
-             Subtype_Mark => New_Occurrence_Of (RAS_Type, 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,
@@ -6336,12 +6580,8 @@ package body Exp_Dist is
 
          Func_Spec : Node_Id;
 
-         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'));
+         Any            : constant Entity_Id := Make_Temporary (Loc, 'A');
+         RAS_Parameter  : constant Entity_Id := Make_Temporary (Loc, 'R');
          RACW_Parameter : constant Node_Id :=
                             Make_Selected_Component (Loc,
                               Prefix        => RAS_Parameter,
@@ -6353,37 +6593,31 @@ package body Exp_Dist is
          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 =>
+             Defining_Identifier => Any,
+             Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc),
+             Expression          =>
                PolyORB_Support.Helpers.Build_To_Any_Call
                  (RACW_Parameter, No_List)));
 
          Statements := New_List (
            Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Set_TC), 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))),
-           Make_Return_Statement (Loc,
-             Expression =>
-               New_Occurrence_Of (Any, Loc)));
+
+           Make_Simple_Return_Statement (Loc,
+             Expression => New_Occurrence_Of (Any, Loc)));
 
          Func_Spec :=
            Make_Function_Specification (Loc,
-             Defining_Unit_Name =>
-               Fnam,
+             Defining_Unit_Name => Fnam,
              Parameter_Specifications => New_List (
                Make_Parameter_Specification (Loc,
-                 Defining_Identifier =>
-                   RAS_Parameter,
-                 Parameter_Type =>
-                   New_Occurrence_Of (RAS_Type, Loc))),
-             Subtype_Mark => New_Occurrence_Of (RTE (RE_Any), 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,
@@ -6405,30 +6639,16 @@ package body Exp_Dist is
          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, Repo_Id_String : String_Id;
-
-         RAS_Parameter : constant Entity_Id :=
-                           Make_Defining_Identifier (Loc, Name_R);
+         Func_Spec      : Node_Id;
+         Decls          : constant List_Id := New_List;
+         Name_String    : String_Id;
+         Repo_Id_String : String_Id;
 
       begin
-         --  The spec for this subprogram has a dummy 'access RAS'
-         --  argument, which serves only for overloading purposes.
-
          Func_Spec :=
            Make_Function_Specification (Loc,
-             Defining_Unit_Name =>
-               Fnam,
-             Parameter_Specifications => New_List (
-               Make_Parameter_Specification (Loc,
-                 Defining_Identifier =>
-                   RAS_Parameter,
-                 Parameter_Type =>
-                   Make_Access_Definition (Loc,
-                     Subtype_Mark => New_Occurrence_Of (RAS_Type, Loc)))),
-             Subtype_Mark => New_Occurrence_Of (RTE (RE_TypeCode), 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);
@@ -6440,27 +6660,28 @@ package body Exp_Dist is
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => New_List (
-                   Make_Return_Statement (Loc,
+                   Make_Simple_Return_Statement (Loc,
                      Expression =>
                        Make_Function_Call (Loc,
-                         Name =>
-                           New_Occurrence_Of (RTE (RE_TC_Build), 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),
+                                   Name =>
+                                     New_Occurrence_Of
+                                       (RTE (RE_TA_Std_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),
+                                   Name =>
+                                     New_Occurrence_Of
+                                       (RTE (RE_TA_Std_String), Loc),
                                    Parameter_Associations => New_List (
                                      Make_String_Literal (Loc,
-                                       Repo_Id_String))))))))))));
+                                       Strval => Repo_Id_String))))))))))));
          Set_TSS (RAS_Type, Fnam);
       end Add_RAS_TypeCode;
 
@@ -6470,52 +6691,46 @@ package body Exp_Dist is
 
       procedure Add_Receiving_Stubs_To_Declarations
         (Pkg_Spec : Node_Id;
-         Decls    : List_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'));
+                                         Make_Temporary (Loc, '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;
+
+         Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
          --  A Pkg_RPC_Receiver is built to decode the request
 
-         Request                     : Node_Id;
+         Request : Node_Id;
          --  Request object received from neutral layer
 
          Subp_Id : Entity_Id;
-         --  Subprogram identifier as received from the neutral
-         --  distribution core.
+         --  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).
+         --  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, New_Internal_Name ('L'));
-         Local_Address : constant Entity_Id :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-         --  Address of a local subprogram designated by a
-         --  reference corresponding to a RAS.
+         Is_Local : constant Entity_Id := Make_Temporary (Loc, 'L');
+
+         Local_Address : constant Entity_Id := Make_Temporary (Loc, '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'));
+         Current_Subp_Number : Int := First_RCI_Subprogram_Id;
 
-         Subp_Info_List : constant List_Id := New_List;
+         Subp_Info_Array : constant Entity_Id := Make_Temporary (Loc, 'I');
+         Subp_Info_List  : constant List_Id := New_List;
 
          Register_Pkg_Actuals : constant List_Id := New_List;
 
@@ -6536,6 +6751,9 @@ package body Exp_Dist is
          --  object, used in the context of calls through remote
          --  access-to-subprogram types.
 
+         procedure Visit_Subprogram (Decl : Node_Id);
+         --  Generate receiving stub for one remote subprogram
+
          ---------------------
          -- Append_Stubs_To --
          ---------------------
@@ -6557,20 +6775,19 @@ package body Exp_Dist is
                     Defining_Entity (Stubs), Loc),
                 Parameter_Associations =>
                   New_List (New_Occurrence_Of (Request, Loc))));
-            if Nkind (Specification (Declaration))
-              = N_Function_Specification
+
+            if Nkind (Specification (Declaration)) = N_Function_Specification
               or else not
                 Is_Asynchronous (Defining_Entity (Specification (Declaration)))
             then
-               Append_To (Case_Stmts, Make_Return_Statement (Loc));
+               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));
+                Statements       => Case_Stmts));
 
             Append_To (Dispatch_On_Name,
               Make_Elsif_Part (Loc,
@@ -6581,45 +6798,141 @@ package body Exp_Dist is
                     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)))));
+                    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)),
+                    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)))));
+                    Make_Integer_Literal (Loc, Subp_Number)))));
          end Append_Stubs_To;
 
+         ----------------------
+         -- Visit_Subprogram --
+         ----------------------
+
+         procedure Visit_Subprogram (Decl : Node_Id) is
+            Loc      : constant Source_Ptr := Sloc (Decl);
+            Spec     : constant Node_Id    := Specification (Decl);
+            Subp_Def : constant Entity_Id  := Defining_Unit_Name (Spec);
+
+            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));
+
+            Current_Stubs  : Node_Id;
+            Proxy_Obj_Addr : Entity_Id;
+
+         begin
+            --  Build receiving stub
+
+            Current_Stubs :=
+              Build_Subprogram_Receiving_Stubs
+                (Vis_Decl     => Decl,
+                 Asynchronous => Nkind (Spec) = 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           => Decl,
+              All_Calls_Remote_E => All_Calls_Remote_E,
+              Proxy_Object_Addr  => Proxy_Obj_Addr);
+
+            --  Compute distribution identifier
+
+            Assign_Subprogram_Identifier
+              (Subp_Def, Current_Subp_Number, Subp_Val);
+
+            pragma Assert
+              (Current_Subp_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 RCI_Subp_Info in
+            --  System.Partition_Interface.
+
+            Append_To (Subp_Info_List,
+              Make_Component_Association (Loc,
+                Choices    =>
+                  New_List (Make_Integer_Literal (Loc, Current_Subp_Number)),
+
+                Expression =>
+                  Make_Aggregate (Loc,
+                    Expressions => New_List (
+
+                      --  Name =>
+
+                      Make_Attribute_Reference (Loc,
+                        Prefix         =>
+                          New_Occurrence_Of (Subp_Dist_Name, Loc),
+                        Attribute_Name => Name_Address),
+
+                      --  Name_Length =>
+
+                      Make_Attribute_Reference (Loc,
+                        Prefix         =>
+                          New_Occurrence_Of (Subp_Dist_Name, Loc),
+                        Attribute_Name => Name_Length),
+
+                      --  Addr =>
+
+                      New_Occurrence_Of (Proxy_Obj_Addr, Loc)))));
+
+            Append_Stubs_To (Pkg_RPC_Receiver_Cases,
+              Declaration     => Decl,
+              Stubs           => Current_Stubs,
+              Subp_Number     => Current_Subp_Number,
+              Subp_Dist_Name  => Subp_Dist_Name,
+              Subp_Proxy_Addr => Proxy_Obj_Addr);
+
+            Current_Subp_Number := Current_Subp_Number + 1;
+         end Visit_Subprogram;
+
+         procedure Visit_Spec is new Build_Package_Stubs (Visit_Subprogram);
+
       --  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 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
+         --    - 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
+         --      output stream;
 
          Build_RPC_Receiver_Body (
            RPC_Receiver => Pkg_RPC_Receiver,
@@ -6637,20 +6950,19 @@ package body Exp_Dist is
 
          Append_To (Pkg_RPC_Receiver_Decls,
            Make_Object_Declaration (Loc,
-             Defining_Identifier =>
-               Is_Local,
+             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,
+             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),
+             Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
              Parameter_Associations => New_List (
                Make_Selected_Component (Loc,
                  Prefix        => Request,
@@ -6658,159 +6970,96 @@ package body Exp_Dist is
                New_Occurrence_Of (Is_Local, Loc),
                New_Occurrence_Of (Local_Address, Loc))));
 
-         --  Determine whether the reference that was used to make
-         --  the call was the base RCI reference (in which case
-         --  Local_Address is 0, 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).
-         --  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))));
-
-         --  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,
-                      New_External_Name (
-                        Related_Id   => Chars (Subp_Def),
-                        Suffix       => 'D',
-                        Suffix_Index => -1));
-
-                  Proxy_Object_Addr : Entity_Id;
-
-               begin
-                  pragma Assert (Current_Subprogram_Number =
-                    Get_Subprogram_Id (Subp_Def));
+         --  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.
 
-                  --  Build receiving stub
+         All_Calls_Remote_E := Boolean_Literals (
+           Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
 
-                  Current_Stubs :=
-                    Build_Subprogram_Receiving_Stubs
-                      (Vis_Decl     => Current_Declaration,
-                       Asynchronous =>
-                         Nkind (Specification (Current_Declaration)) =
-                             N_Procedure_Specification
-                           and then Is_Asynchronous (Subp_Def));
+         Overload_Counter_Table.Reset;
+         Reserve_NamingContext_Methods;
 
-                  Append_To (Decls, Current_Stubs);
-                  Analyze (Current_Stubs);
+         Visit_Spec (Pkg_Spec);
 
-                  --  Build RAS proxy
+         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)),
 
-                  Add_RAS_Proxy_And_Analyze (Decls,
-                    Vis_Decl           =>
-                      Current_Declaration,
-                    All_Calls_Remote_E =>
-                      All_Calls_Remote_E,
-                    Proxy_Object_Addr  =>
-                      Proxy_Object_Addr);
+                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))));
 
-                  --  Compute distribution identifier
+         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.
 
-                  Assign_Subprogram_Identifier (
-                    Subp_Def,
-                    Current_Subprogram_Number,
-                    Subp_Val);
+            --  No initialization provided: remove CONSTANT so that the
+            --  declaration is not an incomplete deferred constant.
 
-                  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;
+            Set_Constant_Present (Last (Decls), False);
+         end if;
 
-               Current_Subprogram_Number := Current_Subprogram_Number + 1;
-            end if;
+         --  Analyze Subp_Info_Array declaration
 
-            Next (Current_Declaration);
-         end loop;
+         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
@@ -6822,113 +7071,89 @@ package body Exp_Dist is
 
          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))));
+             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),
+             Expression   => New_Occurrence_Of (Subp_Index, 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,
-                             First_RCI_Subprogram_Id
-                             + List_Length (Subp_Info_List) - 1))))),
-             Expression          =>
-               Make_Aggregate (Loc,
-                 Component_Associations => Subp_Info_List)));
-         Analyze (Last (Decls));
+         --  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')),
+             Defining_Identifier => Make_Temporary (Loc, 'R'),
              Aliased_Present     => True,
-             Object_Definition   =>
-               New_Occurrence_Of (RTE (RE_Servant), Loc));
+             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,
-            --  Name
            Make_String_Literal (Loc,
              Strval => String_From_Name_Buffer));
 
+         --  Version
+
          Append_To (Register_Pkg_Actuals,
-            --  Version
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of
                  (Defining_Entity (Pkg_Spec), Loc),
-             Attribute_Name =>
-               Name_Version));
+             Attribute_Name => Name_Version));
+
+         --  Handler
 
          Append_To (Register_Pkg_Actuals,
-            --  Handler
            Make_Attribute_Reference (Loc,
              Prefix          =>
                New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
              Attribute_Name  => Name_Access));
 
+         --  Receiver
+
          Append_To (Register_Pkg_Actuals,
-            --  Receiver
            Make_Attribute_Reference (Loc,
              Prefix         =>
                New_Occurrence_Of (
-                 Defining_Identifier (
-                   Pkg_RPC_Receiver_Object), Loc),
-             Attribute_Name =>
-               Name_Access));
+                 Defining_Identifier (Pkg_RPC_Receiver_Object), Loc),
+             Attribute_Name => Name_Access));
+
+         --  Subp_Info
 
          Append_To (Register_Pkg_Actuals,
-            --  Subp_Info
            Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (Subp_Info_Array, Loc),
-             Attribute_Name =>
-               Name_Address));
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Address));
+
+         --  Subp_Info_Len
 
          Append_To (Register_Pkg_Actuals,
-            --  Subp_Info_Len
            Make_Attribute_Reference (Loc,
-             Prefix         =>
-               New_Occurrence_Of (Subp_Info_Array, Loc),
-             Attribute_Name =>
-               Name_Length));
+             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
+             Attribute_Name => Name_Length));
+
+         --  Is_All_Calls_Remote
 
          Append_To (Register_Pkg_Actuals,
-            --  Is_All_Calls_Remote
            New_Occurrence_Of (All_Calls_Remote_E, Loc));
 
-         Append_To (Decls,
+         --  Finally call Register_Pkg_Receiving_Stub with the above parameters
+
+         Append_To (Stmts,
            Make_Procedure_Call_Statement (Loc,
              Name                   =>
                New_Occurrence_Of (RTE (RE_Register_Pkg_Receiving_Stub), Loc),
              Parameter_Associations => Register_Pkg_Actuals));
-         Analyze (Last (Decls));
-
+         Analyze (Last (Stmts));
       end Add_Receiving_Stubs_To_Declarations;
 
       ---------------------------------
@@ -6951,13 +7176,39 @@ package body Exp_Dist is
       is
          Loc : constant Source_Ptr := Sloc (Nod);
 
+         Request : constant Entity_Id := Make_Temporary (Loc, 'R');
+         --  The request object constructed by these stubs
+         --  Could we use Name_R instead??? (see GLADE client stubs)
+
+         function Make_Request_RTE_Call
+           (RE      : RE_Id;
+            Actuals : List_Id := New_List) return Node_Id;
+         --  Generate a procedure call statement calling RE with the given
+         --  actuals. Request'Access is appended to the list.
+
+         ---------------------------
+         -- Make_Request_RTE_Call --
+         ---------------------------
+
+         function Make_Request_RTE_Call
+           (RE      : RE_Id;
+            Actuals : List_Id := New_List) return Node_Id
+         is
+         begin
+            Append_To (Actuals,
+              Make_Attribute_Reference (Loc,
+                Prefix         => New_Occurrence_Of (Request, Loc),
+                Attribute_Name => Name_Access));
+            return Make_Procedure_Call_Statement (Loc,
+                     Name                   =>
+                       New_Occurrence_Of (RTE (RE), Loc),
+                     Parameter_Associations => Actuals);
+         end Make_Request_RTE_Call;
+
          Arguments : Node_Id;
          --  Name of the named values list used to transmit parameters
          --  to the remote package
 
-         Request : Node_Id;
-         --  The request object constructed by these stubs
-
          Result : Node_Id;
          --  Name of the result named value (in non-APC cases) which get the
          --  result of the remote subprogram.
@@ -6988,8 +7239,8 @@ package body Exp_Dist is
          --  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).
+         --  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
@@ -6997,28 +7248,26 @@ package body Exp_Dist is
          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.
+         --  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,
+             Aliased_Present     => True,
              Object_Definition   =>
-                 New_Occurrence_Of (RTE (RE_Request_Access), Loc)));
+               New_Occurrence_Of (RTE (RE_Request), Loc)));
 
-         Result :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+         Result := Make_Temporary (Loc, 'R');
 
          if Is_Function then
-            Result_TC := PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
-              Etype (Subtype_Mark (Spec)), Decls);
+            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;
@@ -7033,8 +7282,7 @@ package body Exp_Dist is
                Make_Aggregate (Loc,
                  Component_Associations => New_List (
                    Make_Component_Association (Loc,
-                     Choices => New_List (
-                       Make_Identifier (Loc, Name_Name)),
+                     Choices    => New_List (Make_Identifier (Loc, Name_Name)),
                      Expression =>
                        New_Occurrence_Of (RTE (RE_Result_Name), Loc)),
                    Make_Component_Association (Loc,
@@ -7042,19 +7290,15 @@ package body Exp_Dist is
                        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))),
+                         Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
+                         Parameter_Associations => New_List (Result_TC))),
                    Make_Component_Association (Loc,
-                     Choices => New_List (
+                     Choices    => New_List (
                        Make_Identifier (Loc, Name_Arg_Modes)),
-                     Expression =>
-                       Make_Integer_Literal (Loc, 0))))));
+                     Expression => Make_Integer_Literal (Loc, 0))))));
 
          if not Is_Known_Asynchronous then
-            Exception_Return_Parameter :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
+            Exception_Return_Parameter := Make_Temporary (Loc, 'E');
 
             Append_To (Decls,
               Make_Object_Declaration (Loc,
@@ -7068,18 +7312,17 @@ package body Exp_Dist is
 
          --  Initialize and fill in arguments list
 
-         Arguments :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+         Arguments := Make_Temporary (Loc, '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;
@@ -7087,8 +7330,7 @@ package body Exp_Dist is
 
             if Is_Controlling_Formal then
 
-               --  In the case of a controlling formal argument, we send
-               --  its reference.
+               --  For a controlling formal argument, we send its reference
 
                Etyp := RACW_Type;
 
@@ -7096,20 +7338,16 @@ package body Exp_Dist is
                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.
+            --  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'));
+                  Any : constant Entity_Id := Make_Temporary (Loc, 'A');
 
                   Actual_Parameter : Node_Id :=
                                        New_Occurrence_Of (
@@ -7121,11 +7359,10 @@ package body Exp_Dist is
                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.
+                     --  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
@@ -7135,10 +7372,8 @@ package body Exp_Dist is
                      else
                         Actual_Parameter := OK_Convert_To (Etyp,
                           Make_Attribute_Reference (Loc,
-                            Prefix =>
-                              Actual_Parameter,
-                            Attribute_Name =>
-                              Name_Unrestricted_Access));
+                            Prefix         => Actual_Parameter,
+                            Attribute_Name => Name_Unrestricted_Access));
                      end if;
 
                   end if;
@@ -7148,31 +7383,29 @@ package body Exp_Dist is
                     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.
+                     --  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);
 
-                     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),
+                       Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                        Parameter_Associations => New_List (
-                         PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
-                           Etyp, Decls)));
+                         PolyORB_Support.Helpers.Build_TypeCode_Call
+                           (Loc, Etyp, Decls)));
                   end if;
 
                   Append_To (Decls,
                     Make_Object_Declaration (Loc,
-                      Defining_Identifier =>
-                        Any,
+                      Defining_Identifier => Any,
                       Aliased_Present     => False,
                       Object_Definition   =>
                         New_Occurrence_Of (RTE (RE_Any), Loc),
-                      Expression          =>
-                        Expr));
+                      Expression          => Expr));
 
                   Append_To (Statements,
                     Add_Parameter_To_NVList (Loc,
@@ -7184,27 +7417,35 @@ package body Exp_Dist is
                   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)));
-
+                     if Is_Limited_Type (Etyp) then
+                        Helpers.Assign_Opaque_From_Any (Loc,
+                           Stms   => After_Statements,
+                           Typ    => Etyp,
+                           N      => New_Occurrence_Of (Any, Loc),
+                           Target =>
+                             Defining_Identifier (Current_Parameter));
+                     else
+                        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
+                                  (Etyp,
+                                   New_Occurrence_Of (Any, Loc),
+                                   Decls)));
+                     end if;
                   end if;
                end;
             end if;
 
-            --  If the current parameter has a dynamic constrained status,
-            --  then this status is transmitted as well.
+            --  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
+            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
@@ -7215,25 +7456,27 @@ package body Exp_Dist is
 
                declare
                   Extra_Any_Parameter : constant Entity_Id :=
-                                      Make_Defining_Identifier
-                                        (Loc, New_Internal_Name ('P'));
+                                          Make_Temporary (Loc, 'P');
+
+                  Parameter_Exp : constant Node_Id :=
+                     Make_Attribute_Reference (Loc,
+                       Prefix         => New_Occurrence_Of (
+                         Defining_Identifier (Current_Parameter), Loc),
+                       Attribute_Name => Name_Constrained);
 
                begin
+                  Set_Etype (Parameter_Exp, Etype (Standard_Boolean));
+
                   Append_To (Decls,
                     Make_Object_Declaration (Loc,
-                      Defining_Identifier =>
-                        Extra_Any_Parameter,
+                      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 (
-                          Make_Attribute_Reference (Loc,
-                            Prefix         =>
-                              New_Occurrence_Of (
-                                Defining_Identifier (Current_Parameter), Loc),
-                            Attribute_Name => Name_Constrained),
-                          Decls)));
+                        PolyORB_Support.Helpers.Build_To_Any_Call
+                          (Parameter_Exp, Decls)));
+
                   Append_To (Extra_Formal_Statements,
                     Add_Parameter_To_NVList (Loc,
                       Parameter   => Extra_Any_Parameter,
@@ -7253,28 +7496,30 @@ package body Exp_Dist is
          Append_To (Statements,
            Make_Procedure_Call_Statement (Loc,
              Name =>
-               New_Occurrence_Of (RTE (RE_Request_Create), Loc),
+               New_Occurrence_Of (RTE (RE_Request_Setup), Loc),
              Parameter_Associations => New_List (
+               New_Occurrence_Of (Request, Loc),
                Target_Object,
                Subprogram_Id,
                New_Occurrence_Of (Arguments, Loc),
                New_Occurrence_Of (Result, Loc),
                New_Occurrence_Of (RTE (RE_Nil_Exc_List), Loc))));
 
-         Append_To (Parameter_Associations (Last (Statements)),
-               New_Occurrence_Of (Request, Loc));
+         pragma Assert
+           (not (Is_Known_Non_Asynchronous and Is_Known_Asynchronous));
 
-         pragma Assert (
-           not (Is_Known_Non_Asynchronous and Is_Known_Asynchronous));
          if Is_Known_Non_Asynchronous or Is_Known_Asynchronous then
-            Asynchronous_P := New_Occurrence_Of (
-              Boolean_Literals (Is_Known_Asynchronous), Loc);
+            Asynchronous_P :=
+              New_Occurrence_Of
+                (Boolean_Literals (Is_Known_Asynchronous), Loc);
+
          else
             pragma Assert (Present (Asynchronous));
             Asynchronous_P := New_Copy_Tree (Asynchronous);
-            --  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.
+
+            --  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;
 
          Append_To (Parameter_Associations (Last (Statements)),
@@ -7284,22 +7529,21 @@ package body Exp_Dist is
                  RTE (RE_Asynchronous_P_To_Sync_Scope), Loc),
              Expressions => New_List (Asynchronous_P)));
 
-         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))));
+         Append_To (Statements, Make_Request_RTE_Call (RE_Request_Invoke));
 
-         Non_Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
-         Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
+         --  Asynchronous case
 
-         if not Is_Known_Asynchronous then
+         if not Is_Known_Non_Asynchronous then
+            Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
+         end if;
+
+         --  Non-asynchronous case
 
+         if not Is_Known_Asynchronous then
             --  Reraise an exception occurrence from the completed request.
             --  If the exception occurrence is empty, this is a no-op.
 
-            Append_To (Non_Asynchronous_Statements,
+            Non_Asynchronous_Statements := New_List (
               Make_Procedure_Call_Statement (Loc,
                 Name                   =>
                   New_Occurrence_Of (RTE (RE_Request_Raise_Occurrence), Loc),
@@ -7307,25 +7551,26 @@ package body Exp_Dist is
                   New_Occurrence_Of (Request, Loc))));
 
             if Is_Function then
-
-               --  If this is a function call, then read the value and
-               --  return it.
+               --  If this is a function call, read the value and return it
 
                Append_To (Non_Asynchronous_Statements,
                  Make_Tag_Check (Loc,
-                   Make_Return_Statement (Loc,
-                     PolyORB_Support.Helpers.Build_From_Any_Call (
-                         Etype (Subtype_Mark (Spec)),
-                         Make_Selected_Component (Loc,
-                           Prefix        => Result,
-                           Selector_Name => Name_Argument),
-                         Decls))));
+                   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))));
+
+            else
+
+               --  Case of a procedure: deal with IN OUT and OUT formals
+
+               Append_List_To (Non_Asynchronous_Statements, After_Statements);
             end if;
          end if;
 
-         Append_List_To (Non_Asynchronous_Statements,
-           After_Statements);
-
          if Is_Known_Asynchronous then
             Append_List_To (Statements, Asynchronous_Statements);
 
@@ -7353,16 +7598,17 @@ package body Exp_Dist is
          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'));
+         Target_Reference : constant Entity_Id := Make_Temporary (Loc, 'T');
+
       begin
          if Present (Controlling_Parameter) then
             Append_To (Decls,
               Make_Object_Declaration (Loc,
                 Defining_Identifier => Target_Reference,
+
                 Object_Definition   =>
                   New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
+
                 Expression          =>
                   Make_Function_Call (Loc,
                     Name =>
@@ -7371,8 +7617,9 @@ package body Exp_Dist is
                       Make_Selected_Component (Loc,
                         Prefix        => Controlling_Parameter,
                         Selector_Name => Name_Target)))));
-            --  Controlling_Parameter has the same components
-            --  as System.Partition_Interface.RACW_Stub_Type.
+
+            --  Note: Controlling_Parameter has the same components as
+            --  System.Partition_Interface.RACW_Stub_Type.
 
             Target_Info.Object := New_Occurrence_Of (Target_Reference, Loc);
 
@@ -7384,6 +7631,7 @@ package body Exp_Dist is
                 Selector_Name =>
                   Make_Identifier (Loc, Name_Get_RCI_Package_Ref));
          end if;
+
          return Target_Info;
       end Build_Stub_Target;
 
@@ -7393,51 +7641,35 @@ package body Exp_Dist is
 
       procedure Build_Stub_Type
         (RACW_Type         : Entity_Id;
-         Stub_Type         : Entity_Id;
-         Stub_Type_Decl    : out Node_Id;
+         Stub_Type_Comps   : out List_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);
+         Loc : constant Source_Ptr := Sloc (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_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)))))));
+         Stub_Type_Comps := 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')),
+             Defining_Identifier => Make_Temporary (Loc, 'R'),
              Aliased_Present     => True,
              Object_Definition   =>
                New_Occurrence_Of (RTE (RE_Servant), Loc));
@@ -7464,9 +7696,9 @@ package body Exp_Dist is
          Request := Make_Defining_Identifier (Loc, Name_R);
 
          RPC_Receiver_Spec :=
-           Build_RPC_Receiver_Specification (
-             RPC_Receiver      => RPC_Receiver,
-             Request_Parameter => Request);
+           Build_RPC_Receiver_Specification
+             (RPC_Receiver      => RPC_Receiver,
+              Request_Parameter => Request);
 
          Subp_Id    := Make_Defining_Identifier (Loc, Name_P);
          Subp_Index := Make_Defining_Identifier (Loc, Name_I);
@@ -7517,29 +7749,30 @@ package body Exp_Dist is
       is
          Loc : constant Source_Ptr := Sloc (Vis_Decl);
 
-         Request_Parameter : Node_Id;
-         --  ???
+         Request_Parameter : constant Entity_Id := Make_Temporary (Loc, 'R');
+         --  Formal parameter for receiving stubs: a descriptor for an incoming
+         --  request.
 
          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.
+         --  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.
 
          Outer_Statements : constant List_Id := New_List;
          --  Statements that occur prior to the declaration of the actual
          --  parameter variables.
 
+         Outer_Extra_Formal_Statements : constant List_Id := New_List;
+         --  Statements concerning extra formal parameters, prior to the
+         --  declaration of the actual parameter variables.
+
          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.
+         --  subprograms. Also the out parameters will be declared. At this
+         --  level, parameters may be unconstrained.
 
          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
 
@@ -7560,7 +7793,7 @@ package body Exp_Dist is
                                      Build_Ordered_Parameters_List
                                        (Specification (Vis_Decl));
 
-         Arguments : Node_Id;
+         Arguments : constant Entity_Id := Make_Temporary (Loc, 'A');
          --  Name of the named values list used to retrieve parameters
 
          Subp_Spec : Node_Id;
@@ -7575,15 +7808,10 @@ package body Exp_Dist is
               New_Occurrence_Of (Parent_Primitive, Loc);
          else
             Called_Subprogram :=
-              New_Occurrence_Of (
-                Defining_Unit_Name (Specification (Vis_Decl)), Loc);
+              New_Occurrence_Of
+                (Defining_Unit_Name (Specification (Vis_Decl)), Loc);
          end if;
 
-         Request_Parameter :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
-
-         Arguments :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
          Declare_Create_NVList (Loc, Arguments, Outer_Decls, Outer_Statements);
 
          --  Loop through every parameter and get its value from the stream. If
@@ -7595,25 +7823,28 @@ package body Exp_Dist is
             declare
                Etyp        : Entity_Id;
                Constrained : Boolean;
-               Any         : Entity_Id := Empty;
-               Object      : constant Entity_Id :=
-                               Make_Defining_Identifier (Loc,
-                                 New_Internal_Name ('P'));
-               Expr        : Node_Id   := Empty;
+               Any         : Entity_Id          := Empty;
+               Object      : constant Entity_Id := Make_Temporary (Loc, 'P');
+               Expr        : Node_Id            := Empty;
 
-               Is_Controlling_Formal : constant Boolean
-                 := Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type);
+               Is_Controlling_Formal : constant Boolean :=
+                                         Is_RACW_Controlling_Formal
+                                           (Current_Parameter, Stub_Type);
 
                Is_First_Controlling_Formal : Boolean := False;
-            begin
-               Set_Ekind (Object, E_Variable);
 
+               Need_Extra_Constrained : Boolean;
+               --  True when an extra constrained actual is required
+
+            begin
                if Is_Controlling_Formal then
 
                   --  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.
 
@@ -7621,30 +7852,28 @@ package body Exp_Dist is
                   Is_First_Controlling_Formal :=
                     not First_Controlling_Formal_Seen;
                   First_Controlling_Formal_Seen := True;
+
                else
                   Etyp := Etype (Parameter_Type (Current_Parameter));
                end if;
 
                Constrained :=
-                 Is_Constrained (Etyp)
-                 or else Is_Elementary_Type (Etyp);
+                 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
 
                if not Is_First_Controlling_Formal then
-                  Any := Make_Defining_Identifier (Loc,
-                           New_Internal_Name ('A'));
+                  Any := Make_Temporary (Loc, 'A');
+
                   Append_To (Outer_Decls,
                     Make_Object_Declaration (Loc,
-                      Defining_Identifier =>
-                        Any,
+                      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),
+                          Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                           Parameter_Associations => New_List (
-                            PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
-                              Etyp, Outer_Decls)))));
+                            PolyORB_Support.Helpers.Build_TypeCode_Call
+                              (Loc, Etyp, Outer_Decls)))));
 
                   Append_To (Outer_Statements,
                     Add_Parameter_To_NVList (Loc,
@@ -7656,38 +7885,35 @@ package body Exp_Dist is
 
                if Is_First_Controlling_Formal then
                   declare
-                     Addr : constant Entity_Id :=
-                       Make_Defining_Identifier (Loc,
-                         New_Internal_Name ('A'));
+                     Addr : constant Entity_Id := Make_Temporary (Loc, 'A');
+
                      Is_Local : constant Entity_Id :=
-                       Make_Defining_Identifier (Loc,
-                         New_Internal_Name ('L'));
-                  begin
+                                  Make_Temporary (Loc, 'L');
 
-                     --  Special case: obtain the first controlling
-                     --  formal from the target of the remote call,
-                     --  instead of the argument list.
+                  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,
+                         Defining_Identifier => Addr,
                          Object_Definition =>
                            New_Occurrence_Of (RTE (RE_Address), Loc)));
+
                      Append_To (Outer_Decls,
                        Make_Object_Declaration (Loc,
-                         Defining_Identifier =>
-                           Is_Local,
+                         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),
+                           New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
                          Parameter_Associations => New_List (
                            Make_Selected_Component (Loc,
-                             Prefix =>
+                             Prefix        =>
                                New_Occurrence_Of (
                                  Request_Parameter, Loc),
                              Selector_Name =>
@@ -7703,44 +7929,60 @@ package body Exp_Dist is
                   or else not Out_Present (Current_Parameter)
                   or else not Constrained
                then
-                  --  If an input parameter is contrained, then its reading is
+                  --  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
+                  if Constrained and then Is_Limited_Type (Etyp) then
+                     Helpers.Assign_Opaque_From_Any (Loc,
+                        Stms   => Statements,
+                        Typ    => Etyp,
+                        N      => New_Occurrence_Of (Any, Loc),
+                        Target => Object);
 
-                     Append_To (Statements,
-                       Make_Assignment_Statement (Loc,
-                         Name =>
-                           New_Occurrence_Of (Object, Loc),
-                         Expression =>
-                            Expr));
-                     Expr := Empty;
                   else
+                     Expr := 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
+                        --  Expr will be used to initialize (and constrain) the
+                        --  parameter when it is declared.
+                        null;
+                     end if;
+
                      null;
-                     --  Expr will be used to initialize (and constrain)
-                     --  the parameter when it is declared.
                   end if;
-
                end if;
 
-               --  If we do not have to output the current parameter, then
-               --  it can well be flagged as constant. This may allow further
-               --  optimizations done by the back end.
-
-               Append_To (Decls,
-                 Make_Object_Declaration (Loc,
-                   Defining_Identifier => Object,
-                   Constant_Present    => not Constrained
-                     and then not Out_Present (Current_Parameter),
-                   Object_Definition   =>
-                     New_Occurrence_Of (Etyp, Loc),
-                   Expression          => Expr));
+               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
@@ -7755,13 +7997,11 @@ package body Exp_Dist is
                then
                   Append_To (After_Statements,
                     Make_Procedure_Call_Statement (Loc,
-                      Name =>
-                        New_Occurrence_Of (RTE (RE_Copy_Any_Value), 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))));
+                        PolyORB_Support.Helpers.Build_To_Any_Call
+                          (New_Occurrence_Of (Object, Loc), Decls))));
                end if;
 
                --  For RACW controlling formals, the Etyp of Object is always
@@ -7770,29 +8010,26 @@ package body Exp_Dist is
 
                if Is_Controlling_Formal then
                   if Nkind (Parameter_Type (Current_Parameter)) /=
-                    N_Access_Definition
+                                                        N_Access_Definition
                   then
                      Append_To (Parameter_List,
                        Make_Parameter_Association (Loc,
                          Selector_Name             =>
-                           New_Occurrence_Of (
-                             Defining_Identifier (Current_Parameter), Loc),
+                           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))))));
+                             Prefix => New_Occurrence_Of (Object, Loc))));
 
                   else
                      Append_To (Parameter_List,
                        Make_Parameter_Association (Loc,
                          Selector_Name             =>
-                           New_Occurrence_Of (
-                             Defining_Identifier (Current_Parameter), Loc),
+                           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)))));
+                           New_Occurrence_Of (Object, Loc)));
                   end if;
 
                else
@@ -7813,37 +8050,38 @@ package body Exp_Dist is
 
                --  The case of Extra_Accessibility should also be handled ???
 
-               if Nkind (Parameter_Type (Current_Parameter)) /=
-                                                         N_Access_Definition
-                 and then
-                   Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
-                 and then
-                   Present (Extra_Constrained
-                     (Defining_Identifier (Current_Parameter)))
-               then
+               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, New_Internal_Name ('A'));
+                                   Make_Temporary (Loc, 'A');
+
                      Formal_Entity : constant Entity_Id :=
-                                       Make_Defining_Identifier
-                                           (Loc, Chars (Extra_Parameter));
+                                       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,
+                         Defining_Identifier => Extra_Any,
                          Object_Definition   =>
-                           New_Occurrence_Of (RTE (RE_Any), Loc)));
+                           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_Statements,
+                     Append_To (Outer_Extra_Formal_Statements,
                        Add_Parameter_To_NVList (Loc,
                          Parameter   => Extra_Parameter,
                          NVList      => Arguments,
@@ -7856,17 +8094,15 @@ package body Exp_Dist is
                          Object_Definition   =>
                            New_Occurrence_Of (Formal_Type, Loc)));
 
-                     Append_To (Extra_Formal_Statements,
+                     Append_To (Statements,
                        Make_Assignment_Statement (Loc,
-                         Name =>
-                           New_Occurrence_Of (Extra_Parameter, Loc),
+                         Name => New_Occurrence_Of (Formal_Entity, Loc),
                          Expression =>
-                           PolyORB_Support.Helpers.Build_From_Any_Call (
-                             Etype (Extra_Parameter),
-                             New_Occurrence_Of (Extra_Any, Loc),
-                       Decls)));
+                           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;
@@ -7874,28 +8110,27 @@ package body Exp_Dist is
             Next (Current_Parameter);
          end loop;
 
+         --  Extra Formals should go after all the other parameters
+
+         Append_List_To (Outer_Statements, Outer_Extra_Formal_Statements);
+
          Append_To (Outer_Statements,
            Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Occurrence_Of (RTE (RE_Request_Arguments), 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))));
 
-         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.
+         if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
+
+            --  The remote subprogram is a function: Build an inner block to be
+            --  able to hold a potentially unconstrained result in a variable.
 
             declare
                Etyp   : constant Entity_Id :=
-                          Etype (Subtype_Mark (Specification (Vis_Decl)));
-               Result : constant Node_Id   :=
-                          Make_Defining_Identifier (Loc,
-                            New_Internal_Name ('R'));
+                          Etype (Result_Definition (Specification (Vis_Decl)));
+               Result : constant Node_Id   := Make_Temporary (Loc, 'R');
+
             begin
                Inner_Decls := New_List (
                  Make_Object_Declaration (Loc,
@@ -7907,16 +8142,27 @@ package body Exp_Dist is
                        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)));
+
+               end if;
+
                Set_Etype (Result, Etyp);
                Append_To (After_Statements,
                  Make_Procedure_Call_Statement (Loc,
-                   Name =>
-                     New_Occurrence_Of (RTE (RE_Set_Result), 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))));
+                     PolyORB_Support.Helpers.Build_To_Any_Call
+                       (New_Occurrence_Of (Result, Loc), Decls))));
+
                --  A DSA function does not have out or inout arguments
             end;
 
@@ -7937,8 +8183,7 @@ package body Exp_Dist is
 
             Append_To (After_Statements,
               Make_Procedure_Call_Statement (Loc,
-                Name =>
-                  New_Occurrence_Of (RTE (RE_Request_Set_Out), Loc),
+                Name => New_Occurrence_Of (RTE (RE_Request_Set_Out), Loc),
                 Parameter_Associations => New_List (
                   New_Occurrence_Of (Request_Parameter, Loc))));
 
@@ -7952,8 +8197,7 @@ package body Exp_Dist is
 
          Subp_Spec :=
            Make_Procedure_Specification (Loc,
-             Defining_Unit_Name       =>
-               Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
+             Defining_Unit_Name       => Make_Temporary (Loc, 'F'),
 
              Parameter_Specifications => New_List (
                Make_Parameter_Specification (Loc,
@@ -7961,22 +8205,21 @@ package body Exp_Dist is
                  Parameter_Type      =>
                    New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
 
-         --  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).
+         --  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).
 
          if Asynchronous and then not Dynamically_Asynchronous then
 
             --  For an asynchronous procedure, add a null exception handler
 
             Excep_Handlers := New_List (
-              Make_Exception_Handler (Loc,
+              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 propagated.
 
@@ -7985,8 +8228,7 @@ package body Exp_Dist is
 
          Append_To (Outer_Statements,
            Make_Block_Statement (Loc,
-             Declarations =>
-               Decls,
+             Declarations => Decls,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => Statements)));
@@ -8000,6 +8242,7 @@ package body Exp_Dist is
                  Statements         => Outer_Statements,
                  Exception_Handlers => Excep_Handlers));
       end Build_Subprogram_Receiving_Stubs;
+
       -------------
       -- Helpers --
       -------------
@@ -8012,16 +8255,15 @@ package body Exp_Dist is
 
          function Find_Numeric_Representation
            (Typ : Entity_Id) return Entity_Id;
-         --  Given a numeric type Typ, return the smallest integer or floarting
+         --  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_Stream_Procedure_Function_Name
+         function Make_Helper_Function_Name
            (Loc : Source_Ptr;
             Typ : Entity_Id;
             Nam : Name_Id) return Entity_Id;
-         --  Return the name to be assigned for stream subprogram Nam of Typ.
-         --  (copied from exp_strm.adb, should be shared???)
+         --  Return the name to be assigned for helper subprogram Nam of Typ
 
          ------------------------------------------------------------
          -- Common subprograms for building various tree fragments --
@@ -8032,8 +8274,8 @@ package body Exp_Dist is
             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.
+         --  Build a call to Get_Aggregate_Element on Any for typecode TC,
+         --  returning the Idx'th element.
 
          generic
             Subprogram : Entity_Id;
@@ -8042,7 +8284,7 @@ package body Exp_Dist is
             Arry : Entity_Id;
             --  For 'Range and Etype
 
-            Indices : List_Id;
+            Indexes : List_Id;
             --  For the construction of the innermost element expression
 
             with procedure Add_Process_Element
@@ -8058,7 +8300,7 @@ package body Exp_Dist is
             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
+         --  executed for each element; Indexes is the list of indexes 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
@@ -8098,19 +8340,30 @@ package body Exp_Dist is
             Container : Node_Or_Entity_Id;
             Counter   : in out Int)
          is
-            CI : constant List_Id := Component_Items (Clist);
-            VP : constant Node_Id := Variant_Part (Clist);
+            CI : List_Id;
+            VP : Node_Id;
+            --  Clist's Component_Items and Variant_Part
 
-            Item : Node_Id := First (CI);
+            Item : Node_Id;
             Def  : Entity_Id;
 
          begin
+            if No (Clist) then
+               return;
+            end if;
+
+            CI := Component_Items (Clist);
+            VP := Variant_Part (Clist);
+
+            Item := First (CI);
             while Present (Item) loop
                Def := Defining_Identifier (Item);
+
                if not Is_Internal_Name (Chars (Def)) then
                   Add_Process_Element
                     (Stmts, Container, Counter, Rec, Def);
                end if;
+
                Next (Item);
             end loop;
 
@@ -8119,6 +8372,118 @@ package body Exp_Dist is
             end if;
          end Append_Record_Traversal;
 
+         -----------------------------
+         -- Assign_Opaque_From_Any --
+         -----------------------------
+
+         procedure Assign_Opaque_From_Any
+           (Loc    : Source_Ptr;
+            Stms   : List_Id;
+            Typ    : Entity_Id;
+            N      : Node_Id;
+            Target : Entity_Id)
+         is
+            Strm : constant Entity_Id := Make_Temporary (Loc, 'S');
+            Expr : Node_Id;
+
+            Read_Call_List : List_Id;
+            --  List on which to place the 'Read attribute reference
+
+         begin
+            --  Strm : Buffer_Stream_Type;
+
+            Append_To (Stms,
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Strm,
+                Aliased_Present     => True,
+                Object_Definition   =>
+                  New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
+
+            --  Any_To_BS (Strm, A);
+
+            Append_To (Stms,
+              Make_Procedure_Call_Statement (Loc,
+                Name => New_Occurrence_Of (RTE (RE_Any_To_BS), Loc),
+                Parameter_Associations => New_List (
+                  N,
+                  New_Occurrence_Of (Strm, Loc))));
+
+            if Transmit_As_Unconstrained (Typ) then
+               Expr :=
+                 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)));
+
+               --  Target := Typ'Input (Strm'Access)
+
+               if Present (Target) then
+                  Append_To (Stms,
+                    Make_Assignment_Statement (Loc,
+                      Name       => New_Occurrence_Of (Target, Loc),
+                      Expression => Expr));
+
+               --  return Typ'Input (Strm'Access);
+
+               else
+                  Append_To (Stms,
+                    Make_Simple_Return_Statement (Loc,
+                      Expression => Expr));
+               end if;
+
+            else
+               if Present (Target) then
+                  Read_Call_List := Stms;
+                  Expr := New_Occurrence_Of (Target, Loc);
+
+               else
+                  declare
+                     Temp : constant Entity_Id := Make_Temporary (Loc, 'R');
+
+                  begin
+                     Read_Call_List := New_List;
+                     Expr := New_Occurrence_Of (Temp, Loc);
+
+                     Append_To (Stms, Make_Block_Statement (Loc,
+                       Declarations               => New_List (
+                         Make_Object_Declaration (Loc,
+                           Defining_Identifier =>
+                             Temp,
+                           Object_Definition   =>
+                             New_Occurrence_Of (Typ, Loc))),
+
+                       Handled_Statement_Sequence =>
+                         Make_Handled_Sequence_Of_Statements (Loc,
+                           Statements => Read_Call_List)));
+                  end;
+               end if;
+
+               --  Typ'Read (Strm'Access, [Target|Temp])
+
+               Append_To (Read_Call_List,
+                 Make_Attribute_Reference (Loc,
+                   Prefix         => New_Occurrence_Of (Typ, Loc),
+                   Attribute_Name => Name_Read,
+                   Expressions    => New_List (
+                     Make_Attribute_Reference (Loc,
+                       Prefix         => New_Occurrence_Of (Strm, Loc),
+                       Attribute_Name => Name_Access),
+                     Expr)));
+
+               if No (Target) then
+
+                  --  return Temp
+
+                  Append_To (Read_Call_List,
+                    Make_Simple_Return_Statement (Loc,
+                       Expression => New_Copy (Expr)));
+               end if;
+            end if;
+         end Assign_Opaque_From_Any;
+
          -------------------------
          -- Build_From_Any_Call --
          -------------------------
@@ -8134,14 +8499,23 @@ package body Exp_Dist is
 
             Fnam    : Entity_Id := Empty;
             Lib_RE  : RE_Id := RE_Null;
+            Result  : Node_Id;
 
          begin
-
             --  First simple case where the From_Any function is present
             --  in the type's TSS.
 
             Fnam := Find_Inherited_TSS (U_Type, TSS_From_Any);
 
+            --  For the subtype representing a generic actual type, go to the
+            --  actual type.
+
+            if Is_Generic_Actual_Type (U_Type) then
+               U_Type := Underlying_Type (Base_Type (U_Type));
+            end if;
+
+            --  For a standard subtype, go to the base type
+
             if Sloc (U_Type) <= Standard_Location then
                U_Type := Base_Type (U_Type);
             end if;
@@ -8216,14 +8590,20 @@ package body Exp_Dist is
             elsif U_Type = RTE (RE_Long_Long_Unsigned) then
                Lib_RE := RE_FA_LLU;
 
-            elsif U_Type = Standard_String then
+            elsif Is_RTE (U_Type, RE_Unbounded_String) then
                Lib_RE := RE_FA_String;
 
+            --  Special DSA types
+
+            elsif Is_RTE (U_Type, RE_Any_Container_Ptr) then
+               Lib_RE := RE_FA_A;
+
             --  Other (non-primitive) types
 
             else
                declare
                   Decl : Entity_Id;
+
                begin
                   Build_From_Any_Function (Loc, U_Type, Decl, Fnam);
                   Append_To (Decls, Decl);
@@ -8237,10 +8617,17 @@ package body Exp_Dist is
                Fnam := RTE (Lib_RE);
             end if;
 
-            return
-                Make_Function_Call (Loc,
-                  Name => New_Occurrence_Of (Fnam, Loc),
-                  Parameter_Associations => New_List (N));
+            Result :=
+              Make_Function_Call (Loc,
+                Name                   => New_Occurrence_Of (Fnam, Loc),
+                Parameter_Associations => New_List (N));
+
+            --  We must set the type of Result, so the unchecked conversion
+            --  from the underlying type to the base type is properly done.
+
+            Set_Etype (Result, U_Type);
+
+            return Unchecked_Convert_To (Typ, Result);
          end Build_From_Any_Call;
 
          -----------------------------
@@ -8253,43 +8640,68 @@ package body Exp_Dist is
             Decl : out Node_Id;
             Fnam : out Entity_Id)
          is
-            Spec : Node_Id;
+            Spec  : Node_Id;
             Decls : constant List_Id := New_List;
-            Stms : constant List_Id := New_List;
-            Any_Parameter : constant Entity_Id
-              := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+            Stms  : constant List_Id := New_List;
+
+            Any_Parameter : constant Entity_Id := Make_Temporary (Loc, 'A');
+
+            Use_Opaque_Representation : Boolean;
+
          begin
-            Fnam := Make_Stream_Procedure_Function_Name (Loc,
-                      Typ, Name_uFrom_Any);
+            --  For a derived type, we can't go past the base type (to the
+            --  parent type) here, because that would cause the attribute's
+            --  formal parameter to have the wrong type; hence the Base_Type
+            --  check here.
+
+            if Is_Itype (Typ) and then Typ /= Base_Type (Typ) then
+               Build_From_Any_Function
+                  (Loc  => Loc,
+                   Typ  => Etype (Typ),
+                   Decl => Decl,
+                   Fnam => Fnam);
+               return;
+            end if;
+
+            Fnam := Make_Helper_Function_Name (Loc, Typ, Name_From_Any);
 
             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))),
-                Subtype_Mark => New_Occurrence_Of (Typ, Loc));
+                    Defining_Identifier => Any_Parameter,
+                    Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))),
+                Result_Definition => New_Occurrence_Of (Typ, Loc));
 
-            --  The following  is taken care of by Exp_Dist.Add_RACW_From_Any
+            --  The RACW case is taken care of by Exp_Dist.Add_RACW_From_Any
 
             pragma Assert
               (not (Is_Remote_Access_To_Class_Wide_Type (Typ)));
 
-            if Is_Derived_Type (Typ)
-              and then not Is_Tagged_Type (Typ)
+            Use_Opaque_Representation := False;
+
+            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_Return_Statement (Loc,
+                 Make_Simple_Return_Statement (Loc,
                    Expression =>
-                     OK_Convert_To (
-                       Typ,
-                       Build_From_Any_Call (
-                         Root_Type (Typ),
-                         New_Occurrence_Of (Any_Parameter, Loc),
-                         Decls))));
+                     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)
@@ -8297,27 +8709,25 @@ package body Exp_Dist is
             then
                if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
                   Append_To (Stms,
-                    Make_Return_Statement (Loc,
+                    Make_Simple_Return_Statement (Loc,
                       Expression =>
-                        OK_Convert_To (
-                          Typ,
-                          Build_From_Any_Call (
-                            Etype (Typ),
-                            New_Occurrence_Of (Any_Parameter, Loc),
-                            Decls))));
+                        Build_From_Any_Call
+                          (Etype (Typ),
+                           New_Occurrence_Of (Any_Parameter, Loc),
+                           Decls)));
+
                else
                   declare
-                     Disc : Entity_Id := Empty;
+                     Disc                      : Entity_Id := Empty;
                      Discriminant_Associations : List_Id;
-                     Rdef : constant Node_Id :=
-                       Type_Definition (Declaration_Node (Typ));
-                     Component_Counter : Int := 0;
+                     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 : constant Entity_Id := Make_Temporary (Loc, 'R');
 
                      Res_Definition : Node_Id := New_Occurrence_Of (Typ, Loc);
 
@@ -8330,8 +8740,8 @@ package body Exp_Dist is
 
                      procedure FA_Append_Record_Traversal is
                         new Append_Record_Traversal
-                       (Rec                 => Res,
-                        Add_Process_Element => FA_Rec_Add_Process_Element);
+                          (Rec                 => Res,
+                           Add_Process_Element => FA_Rec_Add_Process_Element);
 
                      --------------------------------
                      -- FA_Rec_Add_Process_Element --
@@ -8344,11 +8754,13 @@ package body Exp_Dist is
                         Rec     : Entity_Id;
                         Field   : Node_Id)
                      is
+                        Ctyp : Entity_Id;
                      begin
                         if Nkind (Field) = N_Defining_Identifier then
-
                            --  A regular component
 
+                           Ctyp := Etype (Field);
+
                            Append_To (Stmts,
                              Make_Assignment_Statement (Loc,
                                Name => Make_Selected_Component (Loc,
@@ -8356,21 +8768,22 @@ package body Exp_Dist is
                                    New_Occurrence_Of (Rec, Loc),
                                  Selector_Name =>
                                    New_Occurrence_Of (Field, Loc)),
+
                                Expression =>
-                                 Build_From_Any_Call (Etype (Field),
+                                 Build_From_Any_Call (Ctyp,
                                    Build_Get_Aggregate_Element (Loc,
                                      Any => Any,
-                                     Tc  => Build_TypeCode_Call (Loc,
-                                              Etype (Field), Decls),
-                                     Idx => Make_Integer_Literal (Loc,
-                                              Counter)),
+                                     TC  =>
+                                       Build_TypeCode_Call (Loc, Ctyp, Decls),
+                                     Idx =>
+                                       Make_Integer_Literal (Loc, Counter)),
                                    Decls)));
 
                         else
                            --  A variant part
 
                            declare
-                              Variant : Node_Id;
+                              Variant        : Node_Id;
                               Struct_Counter : Int := 0;
 
                               Block_Decls : constant List_Id := New_List;
@@ -8381,40 +8794,40 @@ package body Exp_Dist is
                               Choice_List : List_Id;
 
                               Struct_Any : constant Entity_Id :=
-                                             Make_Defining_Identifier (Loc,
-                                               New_Internal_Name ('S'));
+                                             Make_Temporary (Loc, 'S');
 
                            begin
                               Append_To (Decls,
                                 Make_Object_Declaration (Loc,
-                                  Defining_Identifier =>
-                                    Struct_Any,
-                                  Constant_Present =>
-                                     True,
-                                  Object_Definition =>
+                                  Defining_Identifier => Struct_Any,
+                                  Constant_Present    => True,
+                                  Object_Definition   =>
                                      New_Occurrence_Of (RTE (RE_Any), Loc),
-                                  Expression =>
+                                  Expression          =>
                                     Make_Function_Call (Loc,
-                                      Name => New_Occurrence_Of (
-                                        RTE (RE_Extract_Union_Value), 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,
-                                                  Counter))),
-                                          Idx => Make_Integer_Literal (Loc,
-                                            Counter))))));
+                                          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,
+                                  Declarations => Block_Decls,
                                   Handled_Statement_Sequence =>
                                     Make_Handled_Sequence_Of_Statements (Loc,
                                       Statements => Block_Stmts)));
@@ -8424,18 +8837,25 @@ package body Exp_Dist is
                                     Expression =>
                                       Make_Selected_Component (Loc,
                                         Prefix        => Rec,
-                                        Selector_Name =>
-                                          Chars (Name (Field))),
-                                    Alternatives =>
-                                      Alt_List));
+                                        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));
+                                 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),
@@ -8445,12 +8865,12 @@ package body Exp_Dist is
                                  Append_To (Alt_List,
                                    Make_Case_Statement_Alternative (Loc,
                                      Discrete_Choices => Choice_List,
-                                     Statements =>
-                                       VP_Stmts));
+                                     Statements       => VP_Stmts));
                                  Next_Non_Pragma (Variant);
                               end loop;
                            end;
                         end if;
+
                         Counter := Counter + 1;
                      end FA_Rec_Add_Process_Element;
 
@@ -8458,32 +8878,35 @@ package body Exp_Dist is
                      --  First all discriminants
 
                      if Has_Discriminants (Typ) then
-                        Disc := First_Discriminant (Typ);
                         Discriminant_Associations := New_List;
 
+                        Disc := First_Discriminant (Typ);
                         while Present (Disc) loop
                            declare
                               Disc_Var_Name : constant Entity_Id :=
-                                Make_Defining_Identifier (Loc, Chars (Disc));
-                              Disc_Type : constant Entity_Id :=
-                                Etype (Disc);
+                                                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 =>
+                                  Defining_Identifier => Disc_Var_Name,
+                                  Constant_Present    => True,
+                                  Object_Definition   =>
                                     New_Occurrence_Of (Disc_Type, Loc),
+
                                   Expression =>
-                                    Build_From_Any_Call (Etype (Disc),
+                                    Build_From_Any_Call (Disc_Type,
                                       Build_Get_Aggregate_Element (Loc,
                                         Any => Any_Parameter,
-                                        Tc  => Build_TypeCode_Call
-                                                 (Loc, Etype (Disc), Decls),
-                                        Idx => Make_Integer_Literal
-                                                 (Loc, Component_Counter)),
+                                        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,
@@ -8496,11 +8919,12 @@ package body Exp_Dist is
                            Next_Discriminant (Disc);
                         end loop;
 
-                        Res_Definition := Make_Subtype_Indication (Loc,
-                          Subtype_Mark => Res_Definition,
-                          Constraint   =>
-                            Make_Index_Or_Discriminant_Constraint (Loc,
-                              Discriminant_Associations));
+                        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
@@ -8512,10 +8936,8 @@ package body Exp_Dist is
 
                      Append_To (Decls,
                        Make_Object_Declaration (Loc,
-                         Defining_Identifier =>
-                           Res,
-                         Object_Definition =>
-                           Res_Definition));
+                         Defining_Identifier => Res,
+                         Object_Definition   => Res_Definition));
 
                      --  ... then all components
 
@@ -8525,7 +8947,7 @@ package body Exp_Dist is
                        Counter   => Component_Counter);
 
                      Append_To (Stms,
-                       Make_Return_Statement (Loc,
+                       Make_Simple_Return_Statement (Loc,
                          Expression => New_Occurrence_Of (Res, Loc)));
                   end;
                end if;
@@ -8559,14 +8981,45 @@ package body Exp_Dist is
                          Name       => Datum,
                          Expression => Empty);
 
-                     Element_Any : constant Node_Id :=
-                       Build_Get_Aggregate_Element (Loc,
-                         Any => Any,
-                         Tc  => Build_TypeCode_Call (Loc,
-                                  Etype (Datum), Decls),
-                         Idx => New_Occurrence_Of (Counter, Loc));
+                     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.
 
@@ -8576,10 +9029,8 @@ package body Exp_Dist is
                            New_Occurrence_Of (Counter, Loc),
                          Expression =>
                            Make_Op_Add (Loc,
-                             Left_Opnd =>
-                               New_Occurrence_Of (Counter, Loc),
-                             Right_Opnd =>
-                               Make_Integer_Literal (Loc, 1))));
+                             Left_Opnd  => New_Occurrence_Of (Counter, Loc),
+                             Right_Opnd => Make_Integer_Literal (Loc, 1))));
 
                      if Nkind (Datum) /= N_Attribute_Reference then
 
@@ -8589,17 +9040,20 @@ package body Exp_Dist is
 
                         if Etype (Datum) /= RTE (RE_Any) then
                            Set_Expression (Assignment,
-                              Build_From_Any_Call (
-                                Component_Type (Typ),
-                                Element_Any,
-                                Decls));
+                              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);
 
@@ -8615,7 +9069,7 @@ package body Exp_Dist is
                     new Append_Array_Traversal (
                       Subprogram => Fnam,
                       Arry       => Res,
-                      Indices    => New_List,
+                      Indexes    => New_List,
                       Add_Process_Element => FA_Ary_Add_Process_Element);
 
                   Res_Subtype_Indication : Node_Id :=
@@ -8636,61 +9090,70 @@ package body Exp_Dist is
                         for J in 1 .. Ndim loop
                            Lnam := New_External_Name ('L', J);
                            Hnam := New_External_Name ('H', J);
-                           Indt := Etype (Indx);
+
+                           --  Note, for empty arrays bounds may be out of
+                           --  the range of Etype (Indx).
+
+                           Indt := Base_Type (Etype (Indx));
 
                            Append_To (Decls,
                              Make_Object_Declaration (Loc,
                                Defining_Identifier =>
                                  Make_Defining_Identifier (Loc, Lnam),
-                               Constant_Present    =>
-                                 True,
+                               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)),
+                                 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,
+
+                               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 =>
-                                           Make_Attribute_Reference (Loc,
-                                             Prefix         =>
-                                               New_Occurrence_Of (Indt, Loc),
-                                             Attribute_Name =>
-                                               Name_Pos,
-                                             Expressions    => New_List (
-                                               Make_Identifier (Loc, Lnam))),
+                                           OK_Convert_To
+                                             (Standard_Long_Integer,
+                                              Make_Identifier (Loc, Lnam)),
+
                                          Right_Opnd =>
-                                           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,
-                                                   J)))),
+                                           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))))));
 
@@ -8708,8 +9171,7 @@ package body Exp_Dist is
 
                         Initial_Counter_Value := Ndim;
                         Res_Subtype_Indication := Make_Subtype_Indication (Loc,
-                          Subtype_Mark =>
-                            Res_Subtype_Indication,
+                          Subtype_Mark => Res_Subtype_Indication,
                           Constraint   =>
                             Make_Index_Or_Discriminant_Constraint (Loc,
                               Constraints => Ranges));
@@ -8733,101 +9195,41 @@ package body Exp_Dist is
                   Append_To (Decls,
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => Component_TC,
-                      Constant_Present => True,
-                      Object_Definition =>
+                      Constant_Present    => True,
+                      Object_Definition   =>
                         New_Occurrence_Of (RTE (RE_TypeCode), Loc),
-                      Expression =>
+                      Expression          =>
                         Build_TypeCode_Call (Loc,
                           Component_Type (Typ), Decls)));
 
-                  Append_From_Any_Array_Iterator (Stms,
-                    Any_Parameter, Counter);
+                  Append_From_Any_Array_Iterator
+                    (Stms, Any_Parameter, Counter);
 
                   Append_To (Stms,
-                    Make_Return_Statement (Loc,
+                    Make_Simple_Return_Statement (Loc,
                       Expression => New_Occurrence_Of (Res, Loc)));
                end;
 
             elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
                Append_To (Stms,
-                 Make_Return_Statement (Loc,
+                 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))));
+                     Unchecked_Convert_To (Typ,
+                       Build_From_Any_Call
+                         (Find_Numeric_Representation (Typ),
+                          New_Occurrence_Of (Any_Parameter, Loc),
+                          Decls))));
 
             else
-               --  Default: type is represented as an opaque sequence of bytes
-
-               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'));
-
-               begin
-                  --  Strm : Buffer_Stream_Type;
-
-                  Append_To (Decls,
-                    Make_Object_Declaration (Loc,
-                      Defining_Identifier =>
-                        Strm,
-                      Aliased_Present     =>
-                        True,
-                      Object_Definition   =>
-                        New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
-
-                  --  Any_To_BS (Strm, A);
-
-                  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_Return_Statement (Loc,
-                            Expression => New_Occurrence_Of (Res, Loc))))));
+               Use_Opaque_Representation := True;
+            end if;
 
-               end;
+            if Use_Opaque_Representation then
+               Assign_Opaque_From_Any (Loc,
+                  Stms   => Stms,
+                  Typ    => Typ,
+                  N      => New_Occurrence_Of (Any_Parameter, Loc),
+                  Target => Empty);
             end if;
 
             Decl :=
@@ -8852,8 +9254,7 @@ package body Exp_Dist is
          begin
             return Make_Function_Call (Loc,
               Name =>
-                New_Occurrence_Of (
-                  RTE (RE_Get_Aggregate_Element), Loc),
+                New_Occurrence_Of (RTE (RE_Get_Aggregate_Element), Loc),
               Parameter_Associations => New_List (
                 New_Occurrence_Of (Any, Loc),
                 TC,
@@ -8873,14 +9274,14 @@ package body Exp_Dist is
             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_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
+              (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;
@@ -8896,38 +9297,39 @@ package body Exp_Dist is
          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;
+            Typ    : Entity_Id := Etype (N);
+            U_Type : Entity_Id;
+            C_Type : Entity_Id;
+            Fnam   : Entity_Id := Empty;
+            Lib_RE : RE_Id := RE_Null;
 
          begin
-            --  If N is a selected component, then maybe its Etype
-            --  has not been set yet: try to use the Etype of the
-            --  selector_name in that case.
+            --  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.
 
             if No (Typ) and then Nkind (N) = N_Selected_Component then
                Typ := Etype (Selector_Name (N));
             end if;
+
             pragma Assert (Present (Typ));
 
-            --  The full view, if Typ is private; the completion,
-            --  if Typ is incomplete.
+            --  Get full view for private type, completion for incomplete type
 
             U_Type := Underlying_Type (Typ);
 
-            --  First simple case where the To_Any function is present
-            --  in the type's TSS.
+            --  First simple case where the To_Any function is present in the
+            --  type's TSS.
 
             Fnam := Find_Inherited_TSS (U_Type, TSS_To_Any);
 
-            --  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.
+            --  For the subtype representing a generic actual type, go to the
+            --  actual type.
+
+            if Is_Generic_Actual_Type (U_Type) then
+               U_Type := Underlying_Type (Base_Type (U_Type));
+            end if;
+
+            --  For a standard subtype, go to the base type
 
             if Sloc (U_Type) <= Standard_Location then
                U_Type := Base_Type (U_Type);
@@ -8936,6 +9338,13 @@ package body Exp_Dist is
             if Present (Fnam) then
                null;
 
+            --  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.
+
             elsif U_Type = Standard_Boolean then
                Lib_RE := RE_TA_B;
 
@@ -8996,10 +9405,19 @@ package body Exp_Dist is
             elsif U_Type = RTE (RE_Long_Long_Unsigned) then
                Lib_RE := RE_TA_LLU;
 
-            elsif U_Type = Standard_String then
+            elsif Is_RTE (U_Type, RE_Unbounded_String) then
                Lib_RE := RE_TA_String;
 
+            --  Special DSA types
+
+            elsif Is_RTE (U_Type, RE_Any_Container_Ptr) then
+               Lib_RE := RE_TA_A;
+               U_Type := Typ;
+
             elsif U_Type = Underlying_Type (RTE (RE_TypeCode)) then
+
+               --  No corresponding FA_TC ???
+
                Lib_RE := RE_TA_TC;
 
             --  Other (non-primitive) types
@@ -9020,10 +9438,23 @@ package body Exp_Dist is
                Fnam := RTE (Lib_RE);
             end if;
 
+            --  If Fnam is already analyzed, find the proper expected type,
+            --  else we have a newly constructed To_Any function and we know
+            --  that the expected type of its parameter is U_Type.
+
+            if Ekind (Fnam) = E_Function
+              and then Present (First_Formal (Fnam))
+            then
+               C_Type := Etype (First_Formal (Fnam));
+            else
+               C_Type := U_Type;
+            end if;
+
             return
                 Make_Function_Call (Loc,
-                  Name => New_Occurrence_Of (Fnam, Loc),
-                  Parameter_Associations => New_List (N));
+                  Name                   => New_Occurrence_Of (Fnam, Loc),
+                  Parameter_Associations =>
+                    New_List (OK_Convert_To (C_Type, N)));
          end Build_To_Any_Call;
 
          ---------------------------
@@ -9040,71 +9471,104 @@ package body Exp_Dist is
             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);
+            Expr_Parameter : Entity_Id;
+            Any            : Entity_Id;
+            Result_TC      : Node_Id;
 
             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.
 
          begin
-            Fnam := Make_Stream_Procedure_Function_Name (Loc,
-                      Typ, Name_uTo_Any);
+            --  For a derived type, we can't go past the base type (to the
+            --  parent type) here, because that would cause the attribute's
+            --  formal parameter to have the wrong type; hence the Base_Type
+            --  check here.
+
+            if Is_Itype (Typ) and then Typ /= Base_Type (Typ) then
+               Build_To_Any_Function
+                 (Loc  => Loc,
+                  Typ  => Etype (Typ),
+                  Decl => Decl,
+                  Fnam => Fnam);
+               return;
+            end if;
+
+            Expr_Parameter := Make_Defining_Identifier (Loc, Name_E);
+            Any            := Make_Defining_Identifier (Loc, Name_A);
+            Result_TC      := Build_TypeCode_Call (Loc, Typ, Decls);
+
+            Fnam := Make_Helper_Function_Name (Loc, Typ, Name_To_Any);
 
             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))),
-                Subtype_Mark => New_Occurrence_Of (RTE (RE_Any), 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 =>
-                  Any,
-                Object_Definition   =>
-                  New_Occurrence_Of (RTE (RE_Any), Loc));
+                Defining_Identifier => Any,
+                Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc));
+
+            Use_Opaque_Representation := False;
+
+            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
 
-            if Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
                declare
-                  Rt_Type : constant Entity_Id
-                    := Root_Type (Typ);
-                  Expr : constant Node_Id
-                    := OK_Convert_To (
-                         Rt_Type,
-                         New_Occurrence_Of (Expr_Parameter, Loc));
+                  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));
+                     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));
+                     Set_Expression
+                       (Any_Decl, Build_To_Any_Call (Expr, Decls));
                   end;
 
+               --  Comment needed here (and label on declare block ???)
+
                else
                   declare
-                     Disc : Entity_Id := Empty;
-                     Rdef : constant Node_Id :=
-                              Type_Definition (Declaration_Node (Typ));
-                     Counter : Int := 0;
+                     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
@@ -9113,6 +9577,7 @@ package body Exp_Dist is
                         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
@@ -9148,35 +9613,33 @@ package body Exp_Dist is
                                  New_Occurrence_Of (
                                    RTE (RE_Add_Aggregate_Element), Loc),
                                Parameter_Associations => New_List (
-                                 New_Occurrence_Of (Any, Loc),
+                                 New_Occurrence_Of (Container, Loc),
                                  Build_To_Any_Call (Field_Ref, Decls))));
 
                         else
                            --  A variant part
 
-                           declare
-                              Variant : Node_Id;
+                           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;
+                              Alt_List    : constant List_Id := New_List;
                               Choice_List : List_Id;
 
                               Union_Any : constant Entity_Id :=
-                                            Make_Defining_Identifier (Loc,
-                                              New_Internal_Name ('U'));
+                                            Make_Temporary (Loc, 'V');
 
                               Struct_Any : constant Entity_Id :=
-                                             Make_Defining_Identifier (Loc,
-                                                New_Internal_Name ('S'));
+                                             Make_Temporary (Loc, 'S');
 
                               function Make_Discriminant_Reference
                                 return Node_Id;
-                              --  Build a selected component for the
-                              --  discriminant of this variant part.
+                              --  Build reference to the discriminant for this
+                              --  variant part.
 
                               ---------------------------------
                               -- Make_Discriminant_Reference --
@@ -9191,10 +9654,12 @@ package body Exp_Dist is
                                            Selector_Name =>
                                              Chars (Name (Field)));
                               begin
-                                 Set_Etype (Nod, Name (Field));
+                                 Set_Etype (Nod, Etype (Name (Field)));
                                  return Nod;
                               end Make_Discriminant_Reference;
 
+                           --  Start of processing for Variant_Part
+
                            begin
                               Append_To (Stmts,
                                 Make_Block_Statement (Loc,
@@ -9204,6 +9669,11 @@ package body Exp_Dist is
                                     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,
@@ -9223,6 +9693,9 @@ package body Exp_Dist is
                                             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,
@@ -9240,29 +9713,23 @@ package body Exp_Dist is
                                           Parameter_Associations => New_List (
                                             New_Occurrence_Of (Union_Any, Loc),
                                             Make_Integer_Literal (Loc,
-                                              Uint_0)))))));
+                                              Uint_1)))))));
+
+                              --  Build case statement
 
                               Append_To (Block_Stmts,
                                 Make_Case_Statement (Loc,
-                                    Expression =>
-                                      Make_Discriminant_Reference,
-                                    Alternatives =>
-                                      Alt_List));
+                                  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;
-                                 TA_Append_Record_Traversal (
-                                   Stmts     => VP_Stmts,
-                                   Clist     => Component_List (Variant),
-                                   Container => Struct_Any,
-                                   Counter   => Struct_Counter);
+                                 VP_Stmts := New_List;
 
-                                 --  Append discriminant value and inner struct
-                                 --  to union aggregate.
+                                 --  Append discriminant val to union aggregate
 
                                  Append_To (VP_Stmts,
                                     Make_Procedure_Call_Statement (Loc,
@@ -9271,15 +9738,33 @@ package body Exp_Dist is
                                           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))));
+                                          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),
+                                       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))));
@@ -9289,56 +9774,86 @@ package body Exp_Dist is
                                  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),
-                                       Make_Function_Call (Loc,
-                                         Name => New_Occurrence_Of (
-                                           RTE (RE_Any_Aggregate_Build), Loc),
-                                         Parameter_Associations => New_List (
-                                           New_Occurrence_Of (
-                                             Union_Any, Loc))))));
+                                       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));
+                                     Statements       => VP_Stmts));
+
                                  Next_Non_Pragma (Variant);
                               end loop;
-                           end;
+                           end Variant_Part;
                         end if;
+
+                        Counter := Counter + 1;
                      end TA_Rec_Add_Process_Element;
 
                   begin
-                     --  First all discriminants
+                     --  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
-                           Append_To (Elements,
-                             Make_Component_Association (Loc,
-                               Choices => New_List (
-                                 Make_Integer_Literal (Loc, Counter)),
-                               Expression =>
-                                 Build_To_Any_Call (
-                                   Make_Selected_Component (Loc,
-                                     Prefix        => Expr_Parameter,
-                                     Selector_Name => Chars (Disc)),
-                                   Decls)));
+                           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
-                        --  Make elements an empty array
+                        --  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'));
+                                         Make_Temporary (Loc, 'A');
 
                         begin
                            Append_To (Decls,
@@ -9360,17 +9875,21 @@ package body Exp_Dist is
                         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),
+                         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 all components
+                     --  Then we append all the components to the result
+                     --  aggregate.
 
                      TA_Append_Record_Traversal (Stms,
                        Clist     => Component_List (Rdef),
@@ -9380,6 +9899,9 @@ package body Exp_Dist is
                end if;
 
             elsif Is_Array_Type (Typ) then
+
+               --  Constrained and unconstrained array types
+
                declare
                   Constrained : constant Boolean := Is_Constrained (Typ);
 
@@ -9399,9 +9921,7 @@ package body Exp_Dist is
                      Counter : Entity_Id;
                      Datum   : Node_Id)
                   is
-                     pragma Warnings (Off);
                      pragma Unreferenced (Counter);
-                     pragma Warnings (On);
 
                      Element_Any : Node_Id;
 
@@ -9425,7 +9945,7 @@ package body Exp_Dist is
                     new Append_Array_Traversal (
                       Subprogram => Fnam,
                       Arry       => Expr_Parameter,
-                      Indices    => New_List,
+                      Indexes    => New_List,
                       Add_Process_Element => TA_Ary_Add_Process_Element);
 
                   Index : Node_Id;
@@ -9465,6 +9985,9 @@ package body Exp_Dist is
                end;
 
             elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
+
+               --  Integer types
+
                Set_Expression (Any_Decl,
                  Build_To_Any_Call (
                    OK_Convert_To (
@@ -9473,14 +9996,20 @@ package body Exp_Dist is
                    Decls));
 
             else
-               --  Default: type is represented as an opaque sequence of bytes
+               --  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,
-                           New_Internal_Name ('S'));
+                  Strm : constant Entity_Id := Make_Temporary (Loc, 'S');
+                  --  Stream used to store data representation produced by
+                  --  stream attribute.
 
                begin
-                  --  Strm : aliased Buffer_Stream_Type;
+                  --  Generate:
+                  --    Strm : aliased Buffer_Stream_Type;
 
                   Append_To (Decls,
                     Make_Object_Declaration (Loc,
@@ -9491,43 +10020,35 @@ package body Exp_Dist is
                       Object_Definition   =>
                         New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
 
-                  --  Allocate_Buffer (Strm);
-
-                  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))));
-
-                  --  T'Output (Strm'Access, E);
+                  --  Generate:
+                  --    T'Output (Strm'Access, E);
 
                   Append_To (Stms,
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Typ, Loc),
                         Attribute_Name => Name_Output,
-                        Expressions => New_List (
+                        Expressions    => New_List (
                           Make_Attribute_Reference (Loc,
-                            Prefix => New_Occurrence_Of (Strm, Loc),
+                            Prefix         => New_Occurrence_Of (Strm, Loc),
                             Attribute_Name => Name_Access),
                           New_Occurrence_Of (Expr_Parameter, Loc))));
 
-                  --  BS_To_Any (Strm, A);
+                  --  Generate:
+                  --    BS_To_Any (Strm, A);
 
                   Append_To (Stms,
                     Make_Procedure_Call_Statement (Loc,
-                      Name =>
-                        New_Occurrence_Of (RTE (RE_BS_To_Any), 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))));
 
-                  --  Release_Buffer (Strm);
+                  --  Generate:
+                  --    Release_Buffer (Strm);
 
                   Append_To (Stms,
                     Make_Procedure_Call_Statement (Loc,
-                      Name =>
-                        New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
+                      Name => New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
                       Parameter_Associations => New_List (
                         New_Occurrence_Of (Strm, Loc))));
                end;
@@ -9545,13 +10066,13 @@ package body Exp_Dist is
             end if;
 
             Append_To (Stms,
-              Make_Return_Statement (Loc,
+              Make_Simple_Return_Statement (Loc,
                 Expression => New_Occurrence_Of (Any, Loc)));
 
             Decl :=
               Make_Subprogram_Body (Loc,
-                Specification => Spec,
-                Declarations => Decls,
+                Specification              => Spec,
+                Declarations               => Decls,
                 Handled_Statement_Sequence =>
                   Make_Handled_Sequence_Of_Statements (Loc,
                     Statements => Stms));
@@ -9566,78 +10087,42 @@ package body Exp_Dist is
             Typ   : Entity_Id;
             Decls : List_Id) return Node_Id
          is
-            U_Type : Entity_Id  := Underlying_Type (Typ);
+            U_Type : Entity_Id := Underlying_Type (Typ);
             --  The full view, if Typ is private; the completion,
             --  if Typ is incomplete.
 
-            Fnam    : Entity_Id := Empty;
-            Tnam    : Entity_Id := Empty;
-            Pnam    : Entity_Id := Empty;
-            Args    : List_Id := Empty_List;
-            Lib_RE  : RE_Id := RE_Null;
-
-            Expr : Node_Id;
+            Fnam   : Entity_Id := Empty;
+            Lib_RE : RE_Id := RE_Null;
+            Expr   : Node_Id;
 
          begin
             --  Special case System.PolyORB.Interface.Any: its primitives have
             --  not been set yet, so can't call Find_Inherited_TSS.
 
             if Typ = RTE (RE_Any) then
-               Fnam := RTE (RE_TC_Any);
+               Fnam := RTE (RE_TC_A);
 
             else
                --  First simple case where the TypeCode is present
                --  in the type's TSS.
 
                Fnam := Find_Inherited_TSS (U_Type, TSS_TypeCode);
+            end if;
 
-               if Present (Fnam) then
-
-                  --  When a TypeCode TSS exists, it has a single parameter
-                  --  that is an anonymous access to the corresponding type.
-                  --  This parameter is not used in any way; its purpose is
-                  --  solely to provide overloading of the TSS.
-
-                  Tnam :=
-                    Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
-                  Pnam :=
-                    Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
-
-                  Append_To (Decls,
-                    Make_Full_Type_Declaration (Loc,
-                      Defining_Identifier => Tnam,
-                      Type_Definition =>
-                        Make_Access_To_Object_Definition (Loc,
-                          Subtype_Indication =>
-                            New_Occurrence_Of (U_Type, Loc))));
-                  Append_To (Decls,
-                    Make_Object_Declaration (Loc,
-                      Defining_Identifier => Pnam,
-                      Constant_Present    => True,
-                      Object_Definition   => New_Occurrence_Of (Tnam, Loc),
-
-                     --  Use a variable here to force proper freezing of Tnam
+            --  For the subtype representing a generic actual type, go to the
+            --  actual type.
 
-                      Expression          => Make_Null (Loc)));
+            if Is_Generic_Actual_Type (U_Type) then
+               U_Type := Underlying_Type (Base_Type (U_Type));
+            end if;
 
-                  --  Normally, calling _TypeCode with a null access parameter
-                  --  should raise Constraint_Error, but this check is
-                  --  suppressed for expanded code, and we do not care anyway
-                  --  because we do not actually ever use this value.
+            --  For a standard subtype, go to the base type
 
-                  Args := New_List (New_Occurrence_Of (Pnam, Loc));
-               end if;
+            if Sloc (U_Type) <= Standard_Location then
+               U_Type := Base_Type (U_Type);
             end if;
 
             if No (Fnam) then
-               if Sloc (U_Type) <= Standard_Location then
-
-                  --  Do not try to build alias typecodes for subtypes from
-                  --  Standard.
-
-                  U_Type := Base_Type (U_Type);
-               end if;
-
                if U_Type = Standard_Boolean then
                   Lib_RE := RE_TC_B;
 
@@ -9698,9 +10183,14 @@ package body Exp_Dist is
                elsif U_Type = RTE (RE_Long_Long_Unsigned) then
                   Lib_RE := RE_TC_LLU;
 
-               elsif U_Type = Standard_String then
+               elsif Is_RTE (U_Type, RE_Unbounded_String) then
                   Lib_RE := RE_TC_String;
 
+               --  Special DSA types
+
+               elsif Is_RTE (U_Type, RE_Any_Container_Ptr) then
+                  Lib_RE := RE_TC_A;
+
                --  Other (non-primitive) types
 
                else
@@ -9720,9 +10210,7 @@ package body Exp_Dist is
             --  Call the function
 
             Expr :=
-              Make_Function_Call (Loc,
-                Name => New_Occurrence_Of (Fnam, Loc),
-                Parameter_Associations => Args);
+              Make_Function_Call (Loc, Name => New_Occurrence_Of (Fnam, Loc));
 
             --  Allow Expr to be used as arg to Build_To_Any_Call immediately
 
@@ -9746,8 +10234,7 @@ package body Exp_Dist is
             Stms  : constant List_Id := New_List;
 
             TCNam : constant Entity_Id :=
-                      Make_Stream_Procedure_Function_Name (Loc,
-                        Typ, Name_uTypeCode);
+                      Make_Helper_Function_Name (Loc, Typ, Name_TypeCode);
 
             Parameters : List_Id;
 
@@ -9796,8 +10283,7 @@ package body Exp_Dist is
             begin
                Append_To (Parameter_List,
                  Make_Function_Call (Loc,
-                   Name =>
-                     New_Occurrence_Of (RTE (RE_TA_String), Loc),
+                   Name => New_Occurrence_Of (RTE (RE_TA_Std_String), Loc),
                    Parameter_Associations => New_List (
                      Make_String_Literal (Loc, S))));
             end Add_String_Parameter;
@@ -9813,10 +10299,8 @@ package body Exp_Dist 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)));
+                   Name => New_Occurrence_Of (RTE (RE_TA_TC), Loc),
+                   Parameter_Associations => New_List (TC_Node)));
             end Add_TypeCode_Parameter;
 
             ------------------------
@@ -9830,8 +10314,7 @@ package body Exp_Dist is
             begin
                Append_To (Parameter_List,
                  Make_Function_Call (Loc,
-                   Name =>
-                     New_Occurrence_Of (RTE (RE_TA_LI), Loc),
+                   Name => New_Occurrence_Of (RTE (RE_TA_LI), Loc),
                    Parameter_Associations => New_List (Expr_Node)));
             end Add_Long_Parameter;
 
@@ -9890,9 +10373,9 @@ package body Exp_Dist is
             procedure Return_Constructed_TypeCode (Kind : Entity_Id) is
             begin
                Append_To (Stms,
-                 Make_Return_Statement (Loc,
+                 Make_Simple_Return_Statement (Loc,
                    Expression =>
-                      Make_Constructed_TypeCode (Kind, Parameters)));
+                     Make_Constructed_TypeCode (Kind, Parameters)));
             end Return_Constructed_TypeCode;
 
             ------------------
@@ -9922,17 +10405,15 @@ package body Exp_Dist is
                Rec     : Entity_Id;
                Field   : Node_Id)
             is
-               pragma Warnings (Off);
                pragma Unreferenced (Any, Counter, Rec);
-               pragma Warnings (On);
 
             begin
                if Nkind (Field) = N_Defining_Identifier then
 
                   --  A regular component
 
-                  Add_TypeCode_Parameter (
-                    Build_TypeCode_Call (Loc, Etype (Field), Decls), Params);
+                  Add_TypeCode_Parameter
+                    (Build_TypeCode_Call (Loc, Etype (Field), Decls), Params);
                   Get_Name_String (Chars (Field));
                   Add_String_Parameter (String_From_Name_Buffer, Params);
 
@@ -9950,7 +10431,7 @@ package body Exp_Dist is
                      Union_TC_Params : List_Id;
 
                      U_Name : constant Name_Id :=
-                                New_External_Name (Chars (Typ), 'U', -1);
+                                New_External_Name (Chars (Typ), 'V', -1);
 
                      Name_Str         : String_Id;
                      Struct_TC_Params : List_Id;
@@ -9962,12 +10443,14 @@ package body Exp_Dist is
 
                      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
+                     --  area, it is supposed to be types/variables, then
                      --  subprogram specs, then subprogram bodies ???
 
                      ---------------------------------------
@@ -10007,19 +10490,22 @@ package body Exp_Dist is
                      Initialize_Parameter_List
                        (Name_Str, Name_Str, Union_TC_Params);
 
-                     Add_String_Parameter (Name_Str, Params);
-
                      --  Add union in enclosing parameter list
 
                      Add_TypeCode_Parameter
                        (Make_Constructed_TypeCode
                         (RTE (RE_TC_Union), Union_TC_Params),
-                        Parameters);
+                        Params);
+
+                     Add_String_Parameter (Name_Str, Params);
 
                      --  Build union parameters
 
                      Add_TypeCode_Parameter
-                       (Discriminant_Type, Union_TC_Params);
+                       (Build_TypeCode_Call
+                          (Loc, Discriminant_Type, Decls),
+                        Union_TC_Params);
+
                      Add_Long_Parameter (Default, Union_TC_Params);
 
                      Variant := First_Non_Pragma (Variants (Field));
@@ -10051,29 +10537,80 @@ package body Exp_Dist is
                                        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 =>
-                                 Add_Long_Parameter (
-                                   Make_Integer_Literal (Loc, 0),
-                                   Union_TC_Params);
+
+                                 --  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 =>
-                                 Append_To (Union_TC_Params,
-                                   Build_To_Any_Call (Choice, Decls));
-                                 Add_Params_For_Variant_Components;
 
+                                 --  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;
@@ -10081,64 +10618,122 @@ package body Exp_Dist is
             Type_Name_Str    : String_Id;
             Type_Repo_Id_Str : String_Id;
 
+         --  Start of processing for Build_TypeCode_Function
+
          begin
-            pragma Assert (not Is_Itype (Typ));
+            --  For a derived type, we can't go past the base type (to the
+            --  parent type) here, because that would cause the attribute's
+            --  formal parameter to have the wrong type; hence the Base_Type
+            --  check here.
+
+            if Is_Itype (Typ) and then Typ /= Base_Type (Typ) then
+               Build_TypeCode_Function
+                  (Loc  => Loc,
+                   Typ  => Etype (Typ),
+                   Decl => Decl,
+                   Fnam => Fnam);
+               return;
+            end if;
+
             Fnam := TCNam;
 
             Spec :=
               Make_Function_Specification (Loc,
-                Defining_Unit_Name => Fnam,
+                Defining_Unit_Name       => Fnam,
                 Parameter_Specifications => Empty_List,
-                Subtype_Mark => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
+                Result_Definition        =>
+                  New_Occurrence_Of (RTE (RE_TypeCode), Loc));
 
             Build_Name_And_Repository_Id (Typ,
               Name_Str => Type_Name_Str, Repo_Id_Str => Type_Repo_Id_Str);
+
             Initialize_Parameter_List
               (Type_Name_Str, Type_Repo_Id_Str, Parameters);
 
-            if Is_Derived_Type (Typ)
-              and then not Is_Tagged_Type (Typ)
+            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
-               declare
-                  Parent_Type : Entity_Id := Etype (Typ);
-               begin
-
-                  if Is_Itype (Parent_Type) then
-
-                     --  Skip implicit base type
+               --  If user-defined stream attributes are specified for this
+               --  type, use them and transmit data as an opaque sequence of
+               --  stream elements.
 
-                     Parent_Type := Etype (Parent_Type);
-                  end if;
+               Return_Alias_TypeCode
+                 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
 
-                  Return_Alias_TypeCode (
-                    Build_TypeCode_Call (Loc, Parent_Type, Decls));
-               end;
+            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
+            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
+            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));
+                  Return_Alias_TypeCode
+                    (Build_TypeCode_Call (Loc, Etype (Typ), Decls));
+
                else
                   declare
                      Disc : Entity_Id := Empty;
                      Rdef : constant Node_Id :=
-                       Type_Definition (Declaration_Node (Typ));
+                              Type_Definition (Declaration_Node (Typ));
                      Dummy_Counter : Int := 0;
+
                   begin
-                     --  First all discriminants
+                     --  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),
@@ -10150,7 +10745,7 @@ package body Exp_Dist is
                         Next_Discriminant (Disc);
                      end loop;
 
-                     --  ... then all components
+                     --  then the components typecodes
 
                      TC_Append_Record_Traversal
                        (Parameters, Component_List (Rdef),
@@ -10167,9 +10762,8 @@ package body Exp_Dist is
                   Indx           : Node_Id          := First_Index (Typ);
 
                begin
-                  Inner_TypeCode := Build_TypeCode_Call (Loc,
-                    Component_Type (Typ),
-                    Decls);
+                  Inner_TypeCode :=
+                    Build_TypeCode_Call (Loc, Component_Type (Typ), Decls);
 
                   for J in 1 .. Ndim loop
                      if Constrained then
@@ -10178,13 +10772,11 @@ package body Exp_Dist is
                             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,
+                                  Prefix => New_Occurrence_Of (Typ, Loc),
+                                  Attribute_Name => Name_Length,
                                   Expressions => New_List (
                                     Make_Integer_Literal (Loc,
-                                      Ndim - J + 1)))),
+                                      Intval => Ndim - J + 1)))),
                               Decls),
                             Build_To_Any_Call (Inner_TypeCode, Decls)));
 
@@ -10231,8 +10823,8 @@ package body Exp_Dist is
 
             Decl :=
               Make_Subprogram_Body (Loc,
-                Specification => Spec,
-                Declarations => Decls,
+                Specification              => Spec,
+                Declarations               => Decls,
                 Handled_Statement_Sequence =>
                   Make_Handled_Sequence_Of_Statements (Loc,
                     Statements => Stms));
@@ -10242,8 +10834,8 @@ package body Exp_Dist is
          -- Find_Numeric_Representation --
          ---------------------------------
 
-         function Find_Numeric_Representation (Typ : Entity_Id)
-           return Entity_Id
+         function Find_Numeric_Representation
+           (Typ : Entity_Id) return Entity_Id
          is
             FST    : constant Entity_Id := First_Subtype (Typ);
             P_Size : constant Uint      := Esize (FST);
@@ -10335,8 +10927,7 @@ package body Exp_Dist is
                   Element_Expr : constant Node_Id :=
                                    Make_Indexed_Component (Loc,
                                      New_Occurrence_Of (Arry, Loc),
-                                     Indices);
-
+                                     Indexes);
                begin
                   Set_Etype (Element_Expr, Component_Type (Typ));
                   Add_Process_Element (Stmts,
@@ -10348,29 +10939,41 @@ package body Exp_Dist is
                return;
             end if;
 
-            Append_To (Indices,
+            Append_To (Indexes,
               Make_Identifier (Loc, New_External_Name ('L', Depth)));
 
-            if Constrained then
-               Inner_Any := Any;
-               Inner_Counter := Counter;
-            else
+            if not Constrained or else Depth > 1 then
                Inner_Any := Make_Defining_Identifier (Loc,
-                 New_External_Name ('A', Depth));
+                              New_External_Name ('A', Depth));
                Set_Etype (Inner_Any, RTE (RE_Any));
+            else
+               Inner_Any := Empty;
+            end if;
 
-               if Present (Counter) then
-                  Inner_Counter := Make_Defining_Identifier (Loc,
-                    New_External_Name ('J', Depth));
-               else
-                  Inner_Counter := Empty;
-               end if;
+            if Present (Counter) then
+               Inner_Counter := Make_Defining_Identifier (Loc,
+                                  New_External_Name ('J', Depth));
+            else
+               Inner_Counter := Empty;
             end if;
 
-            Append_Array_Traversal (Inner_Stmts,
-              Any     => Inner_Any,
-              Counter => Inner_Counter,
-              Depth   => Depth + 1);
+            declare
+               Loop_Any : Node_Id := Inner_Any;
+
+            begin
+               --  For the first dimension of a constrained array, we add
+               --  elements directly in the corresponding Any; there is no
+               --  intervening inner Any.
+
+               if No (Loop_Any) then
+                  Loop_Any := Any;
+               end if;
+
+               Append_Array_Traversal (Inner_Stmts,
+                 Any     => Loop_Any,
+                 Counter => Inner_Counter,
+                 Depth   => Depth + 1);
+            end;
 
             Loop_Stm :=
               Make_Implicit_Loop_Statement (Subprogram,
@@ -10391,11 +10994,6 @@ package body Exp_Dist is
                               Make_Integer_Literal (Loc, Depth))))),
                 Statements => Inner_Stmts);
 
-            if Constrained then
-               Append_To (Stmts, Loop_Stm);
-               return;
-            end if;
-
             declare
                Decls       : constant List_Id := New_List;
                Dimen_Stmts : constant List_Id := New_List;
@@ -10409,21 +11007,30 @@ package body Exp_Dist is
 
             begin
                if Depth = 1 then
-                  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)));
+                  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),
+                      Name => New_Occurrence_Of (RTE (RE_Content_Type), Loc),
                       Parameter_Associations => New_List (
                         Make_Identifier (Loc,
-                          New_External_Name ('T', Depth - 1))));
+                          Chars => New_External_Name ('T', Depth - 1))));
                end if;
 
                Append_To (Decls,
@@ -10433,18 +11040,21 @@ package body Exp_Dist is
                    Object_Definition   => New_Occurrence_Of (
                                             RTE (RE_TypeCode), Loc),
                    Expression          => Inner_Any_TypeCode_Expr));
-               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)))));
+
+               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;
 
                if Present (Inner_Counter) then
                   Append_To (Decls,
@@ -10456,29 +11066,33 @@ package body Exp_Dist is
                         Make_Integer_Literal (Loc, 0)));
                end if;
 
-               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);
+               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;
 
-               --  Loop_Stm does approrpriate processing for each element
+               --  Loop_Stm does appropriate processing for each element
                --  of Inner_Any.
 
                Append_To (Dimen_Stmts, Loop_Stm);
 
                --  Link outer and inner any
 
-               Add_Process_Element (Dimen_Stmts,
-                 Any     => Any,
-                 Counter => Counter,
-                 Datum   => New_Occurrence_Of (Inner_Any, Loc));
+               if Present (Inner_Any) then
+                  Add_Process_Element (Dimen_Stmts,
+                    Any     => Any,
+                    Counter => Counter,
+                    Datum   => New_Occurrence_Of (Inner_Any, Loc));
+               end if;
 
                Append_To (Stmts,
                  Make_Block_Statement (Loc,
@@ -10490,29 +11104,43 @@ package body Exp_Dist is
             end;
          end Append_Array_Traversal;
 
-         -----------------------------------------
-         -- Make_Stream_Procedure_Function_Name --
-         -----------------------------------------
+         -------------------------------
+         -- Make_Helper_Function_Name --
+         -------------------------------
 
-         function Make_Stream_Procedure_Function_Name
+         function Make_Helper_Function_Name
            (Loc : Source_Ptr;
             Typ : Entity_Id;
             Nam : Name_Id) return Entity_Id
          is
          begin
-            --  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.
+            declare
+               Serial : Nat := 0;
+               --  For tagged types that aren't frozen yet, generate the helper
+               --  under its 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.
 
-            if Is_Tagged_Type (Typ) then
-               return Make_Defining_Identifier (Loc, Nam);
-            else
-               return Make_Defining_Identifier (Loc,
+            begin
+               if Is_Tagged_Type (Typ) and then not Is_Frozen (Typ) then
+                  null;
+               else
+                  Serial := Increment_Serial_Number;
+               end if;
+
+               --  Use prefixed underscore to avoid potential clash with user
+               --  identifier (we use attribute names for Nam).
+
+               return
+                 Make_Defining_Identifier (Loc,
                    Chars =>
-                     New_External_Name (Nam, ' ', Increment_Serial_Number));
-            end if;
-         end Make_Stream_Procedure_Function_Name;
+                     New_External_Name
+                       (Related_Id   => Nam,
+                        Suffix       => ' ',
+                        Suffix_Index => Serial,
+                        Prefix       => '_'));
+            end;
+         end Make_Helper_Function_Name;
       end Helpers;
 
       -----------------------------------
@@ -10557,20 +11185,32 @@ package body Exp_Dist is
       Pkg_Name := String_From_Name_Buffer;
       Inst :=
         Make_Package_Instantiation (Loc,
-          Defining_Unit_Name   =>
-            Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
+          Defining_Unit_Name   => Make_Temporary (Loc, '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))));
+                  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));
+      RCI_Locator_Table.Set
+        (Defining_Unit_Name (Package_Spec),
+         Defining_Unit_Name (Inst));
       return Inst;
    end RCI_Package_Locator;
 
@@ -10583,12 +11223,36 @@ package body Exp_Dist is
    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,
-            Stub_Elements.RPC_Receiver_Decl,
-            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;
 
@@ -10597,9 +11261,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;
@@ -10633,7 +11298,7 @@ package body Exp_Dist is
    begin
       if Nkind (Spec) = N_Function_Specification then
          Set_Ekind (Snam, E_Function);
-         Set_Etype (Snam, Entity (Subtype_Mark (Spec)));
+         Set_Etype (Snam, Entity (Result_Definition (Spec)));
       else
          Set_Ekind (Snam, E_Procedure);
          Set_Etype (Snam, Standard_Void_Type);
@@ -10650,15 +11315,16 @@ package body Exp_Dist is
      (Loc           : Source_Ptr;
       Decls         : List_Id;
       RPC_Receiver  : Entity_Id;
-      Stub_Elements : Stub_Structure) is
+      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);
+            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);
+            GARLIC_Support.Add_Obj_RPC_Receiver_Completion
+              (Loc, Decls, RPC_Receiver, Stub_Elements);
       end case;
    end Specific_Add_Obj_RPC_Receiver_Completion;
 
@@ -10672,25 +11338,26 @@ package body Exp_Dist is
       Stub_Type         : Entity_Id;
       Stub_Type_Access  : Entity_Id;
       RPC_Receiver_Decl : Node_Id;
-      Declarations      : List_Id) is
+      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,
-              Declarations);
+            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,
-              Declarations);
+            GARLIC_Support.Add_RACW_Features
+              (RACW_Type,
+               Stub_Type,
+               Stub_Type_Access,
+               RPC_Receiver_Decl,
+               Body_Decls);
       end case;
    end Specific_Add_RACW_Features;
 
@@ -10700,7 +11367,8 @@ package body Exp_Dist is
 
    procedure Specific_Add_RAST_Features
      (Vis_Decl : Node_Id;
-      RAS_Type : Entity_Id) is
+      RAS_Type : Entity_Id)
+   is
    begin
       case Get_PCS_Name is
          when Name_PolyORB_DSA =>
@@ -10716,16 +11384,17 @@ package body Exp_Dist is
 
    procedure Specific_Add_Receiving_Stubs_To_Declarations
      (Pkg_Spec : Node_Id;
-      Decls    : List_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);
+            PolyORB_Support.Add_Receiving_Stubs_To_Declarations
+              (Pkg_Spec, Decls, Stmts);
          when others =>
-            GARLIC_Support.Add_Receiving_Stubs_To_Declarations (
-              Pkg_Spec, Decls);
+            GARLIC_Support.Add_Receiving_Stubs_To_Declarations
+              (Pkg_Spec, Decls, Stmts);
       end case;
    end Specific_Add_Receiving_Stubs_To_Declarations;
 
@@ -10750,34 +11419,35 @@ package body Exp_Dist 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);
+            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);
+            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;
 
@@ -10803,6 +11473,7 @@ package body Exp_Dist is
                Subp_Index,
                Stmts,
                Decl);
+
          when others =>
             GARLIC_Support.Build_RPC_Receiver_Body
               (RPC_Receiver,
@@ -10822,15 +11493,19 @@ package body Exp_Dist is
      (Loc                   : Source_Ptr;
       Decls                 : List_Id;
       RCI_Locator           : Entity_Id;
-      Controlling_Parameter : Entity_Id) return RPC_Target is
+      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);
+            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);
+            return
+              GARLIC_Support.Build_Stub_Target
+                (Loc, Decls, RCI_Locator, Controlling_Parameter);
       end case;
    end Specific_Build_Stub_Target;
 
@@ -10840,51 +11515,68 @@ package body Exp_Dist is
 
    procedure Specific_Build_Stub_Type
      (RACW_Type         : Entity_Id;
-      Stub_Type         : Entity_Id;
-      Stub_Type_Decl    : out Node_Id;
+      Stub_Type_Comps   : out List_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);
+            PolyORB_Support.Build_Stub_Type
+              (RACW_Type, Stub_Type_Comps, RPC_Receiver_Decl);
+
          when others =>
-            GARLIC_Support.Build_Stub_Type (
-              RACW_Type, Stub_Type,
-              Stub_Type_Decl, RPC_Receiver_Decl);
+            GARLIC_Support.Build_Stub_Type
+              (RACW_Type, Stub_Type_Comps, RPC_Receiver_Decl);
       end case;
    end Specific_Build_Stub_Type;
 
+   -----------------------------------------------
+   -- Specific_Build_Subprogram_Receiving_Stubs --
+   -----------------------------------------------
+
    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
+      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);
+            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);
+            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 --
    --------------------------
@@ -10901,10 +11593,12 @@ package body Exp_Dist is
       end if;
 
       return
-        Etype (Subtype_Indication (
-          Component_Definition (
-           First (Component_Items (Component_List (
-            Type_Definition (Declaration_Node (Record_Type))))))));
+        Etype (Subtype_Indication
+                (Component_Definition
+                  (First (Component_Items
+                           (Component_List
+                             (Type_Definition
+                               (Declaration_Node (Record_Type))))))));
    end Underlying_RACW_Type;
 
 end Exp_Dist;