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

with Atree;          use Atree;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Exp_Atag;       use Exp_Atag;
with Exp_Strm;       use Exp_Strm;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Lib;            use Lib;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_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 Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
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;

package body Exp_Dist is

   --  The following model has been used to implement distributed objects:
   --  given a designated type D and a RACW type R, then a record of the form:

   --    type Stub is tagged record
   --       [...declaration similar to s-parint.ads RACW_Stub_Type...]
   --    end record;

   --  is built. This type has two properties:

   --    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 arrives on the
   --       same partition through several paths;

   --    2) It also has the same dispatching table as the designated type D,
   --       and thus can be used as an object designated by a value of type
   --       R on any partition other than the one on which the object has
   --       been created, since only dispatching calls will be performed and
   --       the fields themselves will not be used. We call Derive_Subprograms
   --       to fake half a derivation to ensure that the subprograms do have
   --       the same dispatching table.

   First_RCI_Subprogram_Id : constant := 2;
   --  RCI subprograms are numbered starting at 2. The RCI receiver for
   --  an RCI package can thus identify calls received through remote
   --  access-to-subprogram dereferences by the fact that they have a
   --  (primitive) subprogram id of 0, and 1 is used for the internal RAS
   --  information lookup operation. (This is for the Garlic code generation,
   --  where subprograms are identified by numbers; in the PolyORB version,
   --  they are identified by name, with a numeric suffix for homonyms.)

   type Hash_Index is range 0 .. 50;

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

   function Hash (F : Entity_Id) return Hash_Index;
   --  DSA expansion associates stubs to distributed object types using a hash
   --  table on entity ids.

   function Hash (F : Name_Id) return Hash_Index;
   --  The generation of subprogram identifiers requires an overload counter
   --  to be associated with each remote subprogram name. These counters are
   --  maintained in a hash table on name ids.

   type Subprogram_Identifiers is record
      Str_Identifier : String_Id;
      Int_Identifier : Int;
   end record;

   package Subprogram_Identifier_Table is
      new Simple_HTable (Header_Num => Hash_Index,
                         Element    => Subprogram_Identifiers,
                         No_Element => (No_String, 0),
                         Key        => Entity_Id,
                         Hash       => Hash,
                         Equal      => "=");
   --  Mapping between a remote subprogram and the corresponding subprogram
   --  identifiers.

   package Overload_Counter_Table is
      new Simple_HTable (Header_Num => Hash_Index,
                         Element    => Int,
                         No_Element => 0,
                         Key        => Name_Id,
                         Hash       => Hash,
                         Equal      => "=");
   --  Mapping between a subprogram name and an integer that counts the number
   --  of defining subprogram names with that Name_Id encountered so far in a
   --  given context (an interface).

   function Get_Subprogram_Ids (Def : Entity_Id) return Subprogram_Identifiers;
   function Get_Subprogram_Id  (Def : Entity_Id) return String_Id;
   function Get_Subprogram_Id  (Def : Entity_Id) return Int;
   --  Given a subprogram defined in a RCI package, get its distribution
   --  subprogram identifiers (the distribution identifiers are a unique
   --  subprogram number, and the non-qualified subprogram name, in the
   --  casing used for the subprogram declaration; if the name is overloaded,
   --  a double underscore and a serial number are appended.
   --
   --  The integer identifier is used to perform remote calls with GARLIC;
   --  the string identifier is used in the case of PolyORB.
   --
   --  Although the PolyORB DSA receiving stubs will make a caseless comparison
   --  when receiving a call, the calling stubs will create requests with the
   --  exact casing of the defining unit name of the called subprogram, so as
   --  to allow calls to subprograms on distributed nodes that do distinguish
   --  between casings.
   --
   --  NOTE: Another design would be to allow a representation clause on
   --  subprogram specs: for Subp'Distribution_Identifier use "fooBar";

   pragma Warnings (Off, Get_Subprogram_Id);
   --  One homonym only is unreferenced (specific to the GARLIC version)

   procedure Add_RAS_Dereference_TSS (N : Node_Id);
   --  Add a subprogram body for RAS Dereference TSS

   procedure Add_RAS_Proxy_And_Analyze
     (Decls              : List_Id;
      Vis_Decl           : Node_Id;
      All_Calls_Remote_E : Entity_Id;
      Proxy_Object_Addr  : out Entity_Id);
   --  Add the proxy type required, on the receiving (server) side, to handle
   --  calls to the subprogram declared by Vis_Decl through a remote access
   --  to subprogram type. All_Calls_Remote_E must be Standard_True if a pragma
   --  All_Calls_Remote applies, Standard_False otherwise. The new proxy type
   --  is appended to Decls. Proxy_Object_Addr is a constant of type
   --  System.Address that designates an instance of the proxy object.

   function Build_Remote_Subprogram_Proxy_Type
     (Loc            : Source_Ptr;
      ACR_Expression : Node_Id) return Node_Id;
   --  Build and return a tagged record type definition for an RCI subprogram
   --  proxy type. ACR_Expression is used as the initialization value for the
   --  All_Calls_Remote component.

   function Build_Get_Unique_RP_Call
     (Loc       : Source_Ptr;
      Pointer   : Entity_Id;
      Stub_Type : Entity_Id) return List_Id;
   --  Build a call to Get_Unique_Remote_Pointer (Pointer), followed by a
   --  tag fixup (Get_Unique_Remote_Pointer may have changed Pointer'Tag to
   --  RACW_Stub_Type'Tag, while the desired tag is that of Stub_Type).

   function Build_Stub_Tag
     (Loc       : Source_Ptr;
      RACW_Type : Entity_Id) return Node_Id;
   --  Return an expression denoting the tag of the stub type associated with
   --  RACW_Type.

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

   function Build_RPC_Receiver_Specification
     (RPC_Receiver      : Entity_Id;
      Request_Parameter : Entity_Id) return Node_Id;
   --  Make a subprogram specification for an RPC receiver, with the given
   --  defining unit name and formal parameter.

   function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
   --  Return an ordered parameter list: unconstrained parameters are put
   --  at the beginning of the list and constrained ones are put after. If
   --  there are no parameters, an empty list is returned. Special case:
   --  the controlling formal of the equivalent RACW operation for a RAS
   --  type is always left in first position.

   function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean;
   --  True when Typ is an unconstrained type, or a null-excluding access type.
   --  In either case, this means stubs cannot contain a default-initialized
   --  object declaration of such type.

   procedure Add_Calling_Stubs_To_Declarations (Pkg_Spec : 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 [IN] OUT parameters).

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

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

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

   function Make_Selected_Component
     (Loc           : Source_Ptr;
      Prefix        : Entity_Id;
      Selector_Name : Name_Id) return Node_Id;
   --  Return a selected_component whose prefix denotes the given entity, and
   --  with the given Selector_Name.

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

   procedure Set_Renaming_TSS
     (Typ     : Entity_Id;
      Nam     : Entity_Id;
      TSS_Nam : TSS_Name_Type);
   --  Create a renaming declaration of subprogram Nam, and register it as a
   --  TSS for Typ with name TSS_Nam.

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

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

   procedure Declare_Create_NVList
     (Loc    : Source_Ptr;
      NVList : Entity_Id;
      Decls  : List_Id;
      Stmts  : List_Id);
   --  Append the declaration of NVList to Decls, and its
   --  initialization to Stmts.

   function Add_Parameter_To_NVList
     (Loc         : Source_Ptr;
      NVList      : Entity_Id;
      Parameter   : Entity_Id;
      Constrained : Boolean;
      RACW_Ctrl   : Boolean := False;
      Any         : Entity_Id) return Node_Id;
   --  Return a call to Add_Item to add the Any corresponding to the designated
   --  formal Parameter (with the indicated Constrained status) to NVList.
   --  RACW_Ctrl must be set to True for controlling formals of distributed
   --  object primitive operations.

   --------------------
   -- Stub_Structure --
   --------------------

   --  This record describes various tree fragments associated with the
   --  generation of RACW calling stubs. One such record exists for every
   --  distributed object type, i.e. each tagged type that is the designated
   --  type of one or more RACW type.

   type Stub_Structure is record
      Stub_Type         : Entity_Id;
      --  Stub type: 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, in the case of GARLIC, for 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;

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

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

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

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

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

   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;
      Decls             : List_Id;
      Stub_Type         : out Entity_Id;
      Stub_Type_Access  : out Entity_Id;
      RPC_Receiver_Decl : out Node_Id;
      Body_Decls        : out List_Id;
      Existing          : out Boolean);
   --  Add the declaration of the stub type, the access to stub type and the
   --  object RPC receiver at the end of Decls. If these already exist,
   --  then nothing is added in the tree but the right values are returned
   --  anyhow and Existing is set to True.

   function Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id;
   --  Retrieve the Body_Decls list associated to RACW_Type in the stub
   --  structure table, reset it to No_List, and return the previous value.

   procedure Add_RACW_Asynchronous_Flag
     (Declarations : List_Id;
      RACW_Type    : Entity_Id);
   --  Declare a boolean constant associated with RACW_Type whose value
   --  indicates at run time whether a pragma Asynchronous applies to it.

   procedure Assign_Subprogram_Identifier
     (Def : Entity_Id;
      Spn : Int;
      Id  : out String_Id);
   --  Determine the distribution subprogram identifier to
   --  be used for remote subprogram Def, return it in Id and
   --  store it in a hash table for later retrieval by
   --  Get_Subprogram_Id. Spn is the subprogram number.

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

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

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

   procedure Build_Actual_Object_Declaration
     (Object   : Entity_Id;
      Etyp     : Entity_Id;
      Variable : Boolean;
      Expr     : Node_Id;
      Decls    : List_Id);
   --  Build the declaration of an object with the given defining identifier,
   --  initialized with Expr if provided, to serve as actual parameter in a
   --  server stub. If Variable is true, the declared object will be a variable
   --  (case of an out or in out formal), else it will be a constant. Object's
   --  Ekind is set accordingly. The declaration, as well as any other
   --  declarations it requires, are appended to Decls.

   --------------------------------------------
   -- Hooks for PCS-specific code generation --
   --------------------------------------------

   --  Part of the code generation circuitry for distribution needs to be
   --  tailored for each implementation of the PCS. For each routine that
   --  needs to be specialized, a Specific_<routine> wrapper is created,
   --  which calls the corresponding <routine> in package
   --  <pcs_implementation>_Support.

   procedure Specific_Add_RACW_Features
     (RACW_Type           : Entity_Id;
      Desig               : Entity_Id;
      Stub_Type           : Entity_Id;
      Stub_Type_Access    : Entity_Id;
      RPC_Receiver_Decl   : Node_Id;
      Body_Decls          : List_Id);
   --  Add declaration for TSSs for a given RACW type. The declarations are
   --  added just after the declaration of the RACW type itself. If the RACW
   --  appears in the main unit, Body_Decls is a list of declarations to which
   --  the bodies are appended. Else Body_Decls is No_List.
   --  PCS-specific ancillary subprogram for Add_RACW_Features.

   procedure Specific_Add_RAST_Features
     (Vis_Decl : Node_Id;
      RAS_Type : Entity_Id);
   --  Add declaration for TSSs for a given RAS type. PCS-specific ancillary
   --  subprogram for Add_RAST_Features.

   --  An RPC_Target record is used during construction of calling stubs
   --  to pass PCS-specific tree fragments corresponding to the information
   --  necessary to locate the target of a remote subprogram call.

   type RPC_Target (PCS_Kind : PCS_Names) is record
      case PCS_Kind is
         when Name_PolyORB_DSA =>
            Object : Node_Id;
            --  An expression whose value is a PolyORB reference to the target
            --  object.

         when others =>
            Partition : Entity_Id;
            --  A variable containing the Partition_ID of the target partition

            RPC_Receiver : Node_Id;
            --  An expression whose value is the address of the target RPC
            --  receiver.
      end case;
   end record;

   procedure Specific_Build_General_Calling_Stubs
     (Decls                     : List_Id;
      Statements                : List_Id;
      Target                    : RPC_Target;
      Subprogram_Id             : Node_Id;
      Asynchronous              : Node_Id := Empty;
      Is_Known_Asynchronous     : Boolean := False;
      Is_Known_Non_Asynchronous : Boolean := False;
      Is_Function               : Boolean;
      Spec                      : Node_Id;
      Stub_Type                 : Entity_Id := Empty;
      RACW_Type                 : Entity_Id := Empty;
      Nod                       : Node_Id);
   --  Build calling stubs for general purpose. The parameters are:
   --    Decls             : A place to put declarations
   --    Statements        : A place to put statements
   --    Target            : PCS-specific target information (see details in
   --                        RPC_Target declaration).
   --    Subprogram_Id     : A node containing the subprogram ID
   --    Asynchronous      : True if an APC must be made instead of an RPC.
   --                        The value needs not be supplied if one of the
   --                        Is_Known_... is True.
   --    Is_Known_Async... : True if we know that this is asynchronous
   --    Is_Known_Non_A... : True if we know that this is not asynchronous
   --    Spec              : Node with a Parameter_Specifications and a
   --                        Result_Definition if applicable
   --    Stub_Type         : For case of RACW stubs, parameters of type access
   --                        to Stub_Type will be marshalled using the address
   --                        address of the object (the addr field) rather
   --                        than using the 'Write on the stub itself
   --    Nod               : Used to provide sloc for generated code

   function Specific_Build_Stub_Target
     (Loc                   : Source_Ptr;
      Decls                 : List_Id;
      RCI_Locator           : Entity_Id;
      Controlling_Parameter : Entity_Id) return RPC_Target;
   --  Build call target information nodes for use within calling stubs. In the
   --  RCI case, RCI_Locator is the entity for the instance of RCI_Locator. If
   --  for an RACW, Controlling_Parameter is the entity for the controlling
   --  formal parameter used to determine the location of the target of the
   --  call. Decls provides a location where variable declarations can be
   --  appended to construct the necessary values.

   function Specific_RPC_Receiver_Decl
     (RACW_Type : Entity_Id) return Node_Id;
   --  Build the RPC receiver, for RACW, if applicable, else return Empty

   procedure Specific_Build_RPC_Receiver_Body
     (RPC_Receiver : Entity_Id;
      Request      : out Entity_Id;
      Subp_Id      : out Entity_Id;
      Subp_Index   : out Entity_Id;
      Stmts        : out List_Id;
      Decl         : out Node_Id);
   --  Make a subprogram body for an RPC receiver, with the given
   --  defining unit name. On return:
   --    - Subp_Id is the subprogram identifier from the PCS.
   --    - Subp_Index is the index in the list of subprograms
   --      used for dispatching (a variable of type Subprogram_Id).
   --    - Stmts is the place where the request dispatching
   --      statements can occur,
   --    - Decl is the subprogram body declaration.

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

   procedure Specific_Add_Obj_RPC_Receiver_Completion
     (Loc           : Source_Ptr;
      Decls         : List_Id;
      RPC_Receiver  : Entity_Id;
      Stub_Elements : Stub_Structure);
   --  Add the necessary code to Decls after the completion of generation
   --  of the RACW RPC receiver described by Stub_Elements.

   procedure Specific_Add_Receiving_Stubs_To_Declarations
     (Pkg_Spec : Node_Id;
      Decls    : List_Id;
      Stmts    : List_Id);
   --  Add receiving stubs to the declarative part of an RCI unit

   --------------------
   -- 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.

      procedure Add_RACW_Features
        (RACW_Type         : Entity_Id;
         Stub_Type         : Entity_Id;
         Stub_Type_Access  : Entity_Id;
         RPC_Receiver_Decl : Node_Id;
         Body_Decls        : List_Id);

      procedure Add_RAST_Features
        (Vis_Decl : Node_Id;
         RAS_Type : Entity_Id);

      procedure Build_General_Calling_Stubs
        (Decls                     : List_Id;
         Statements                : List_Id;
         Target_Partition          : Entity_Id; --  From RPC_Target
         Target_RPC_Receiver       : Node_Id;   --  From RPC_Target
         Subprogram_Id             : Node_Id;
         Asynchronous              : Node_Id := Empty;
         Is_Known_Asynchronous     : Boolean := False;
         Is_Known_Non_Asynchronous : Boolean := False;
         Is_Function               : Boolean;
         Spec                      : Node_Id;
         Stub_Type                 : Entity_Id := Empty;
         RACW_Type                 : Entity_Id := Empty;
         Nod                       : Node_Id);

      function Build_Stub_Target
        (Loc                   : Source_Ptr;
         Decls                 : List_Id;
         RCI_Locator           : Entity_Id;
         Controlling_Parameter : Entity_Id) return RPC_Target;

      function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id;

      function Build_Subprogram_Receiving_Stubs
        (Vis_Decl                 : Node_Id;
         Asynchronous             : Boolean;
         Dynamically_Asynchronous : Boolean   := False;
         Stub_Type                : Entity_Id := Empty;
         RACW_Type                : Entity_Id := Empty;
         Parent_Primitive         : Entity_Id := Empty) return Node_Id;

      procedure Add_Obj_RPC_Receiver_Completion
        (Loc           : Source_Ptr;
         Decls         : List_Id;
         RPC_Receiver  : Entity_Id;
         Stub_Elements : Stub_Structure);

      procedure Add_Receiving_Stubs_To_Declarations
        (Pkg_Spec : Node_Id;
         Decls    : List_Id;
         Stmts    : List_Id);

      procedure Build_RPC_Receiver_Body
        (RPC_Receiver : Entity_Id;
         Request      : out Entity_Id;
         Subp_Id      : out Entity_Id;
         Subp_Index   : out Entity_Id;
         Stmts        : out List_Id;
         Decl         : out Node_Id);

   end GARLIC_Support;

   ---------------------
   -- 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.

      procedure Add_RACW_Features
        (RACW_Type         : Entity_Id;
         Desig             : Entity_Id;
         Stub_Type         : Entity_Id;
         Stub_Type_Access  : Entity_Id;
         RPC_Receiver_Decl : Node_Id;
         Body_Decls        : List_Id);

      procedure Add_RAST_Features
        (Vis_Decl : Node_Id;
         RAS_Type : Entity_Id);

      procedure Build_General_Calling_Stubs
        (Decls                     : List_Id;
         Statements                : List_Id;
         Target_Object             : Node_Id; --  From RPC_Target
         Subprogram_Id             : Node_Id;
         Asynchronous              : Node_Id := Empty;
         Is_Known_Asynchronous     : Boolean := False;
         Is_Known_Non_Asynchronous : Boolean := False;
         Is_Function               : Boolean;
         Spec                      : Node_Id;
         Stub_Type                 : Entity_Id := Empty;
         RACW_Type                 : Entity_Id := Empty;
         Nod                       : Node_Id);

      function Build_Stub_Target
        (Loc                   : Source_Ptr;
         Decls                 : List_Id;
         RCI_Locator           : Entity_Id;
         Controlling_Parameter : Entity_Id) return RPC_Target;

      function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id;

      function Build_Subprogram_Receiving_Stubs
        (Vis_Decl                 : Node_Id;
         Asynchronous             : Boolean;
         Dynamically_Asynchronous : Boolean   := False;
         Stub_Type                : Entity_Id := Empty;
         RACW_Type                : Entity_Id := Empty;
         Parent_Primitive         : Entity_Id := Empty) return Node_Id;

      procedure Add_Obj_RPC_Receiver_Completion
        (Loc           : Source_Ptr;
         Decls         : List_Id;
         RPC_Receiver  : Entity_Id;
         Stub_Elements : Stub_Structure);

      procedure Add_Receiving_Stubs_To_Declarations
        (Pkg_Spec : Node_Id;
         Decls    : List_Id;
         Stmts    : List_Id);

      procedure Build_RPC_Receiver_Body
        (RPC_Receiver : Entity_Id;
         Request      : out Entity_Id;
         Subp_Id      : out Entity_Id;
         Subp_Index   : out Entity_Id;
         Stmts        : out List_Id;
         Decl         : out Node_Id);

      procedure Reserve_NamingContext_Methods;
      --  Mark the method names for interface NamingContext as already used in
      --  the overload table, so no clashes occur with user code (with the
      --  PolyORB PCS, RCIs Implement The NamingContext interface to allow
      --  their methods to be accessed as objects, for the implementation of
      --  remote access-to-subprogram types).

      -------------
      -- Helpers --
      -------------

      package Helpers is

         --  Routines to build distribution helper subprograms for user-defined
         --  types. For implementation of the Distributed systems annex (DSA)
         --  over the PolyORB generic middleware components, it is necessary to
         --  generate several supporting subprograms for each application data
         --  type used in inter-partition communication. These subprograms are:

         --    A Typecode function returning a high-level description of the
         --    type's structure;

         --    Two conversion functions allowing conversion of values of the
         --    type from and to the generic data containers used by PolyORB.
         --    These generic containers are called 'Any' type values after the
         --    CORBA terminology, and hence the conversion subprograms are
         --    named To_Any and From_Any.

         function Build_From_Any_Call
           (Typ   : Entity_Id;
            N     : Node_Id;
            Decls : List_Id) return Node_Id;
         --  Build call to From_Any attribute function of type Typ with
         --  expression N as actual parameter. Decls is the declarations list
         --  for an appropriate enclosing scope of the point where the call
         --  will be inserted; if the From_Any attribute for Typ needs to be
         --  generated at this point, its declaration is appended to Decls.

         procedure Build_From_Any_Function
           (Loc  : Source_Ptr;
            Typ  : Entity_Id;
            Decl : out Node_Id;
            Fnam : out Entity_Id);
         --  Build From_Any attribute function for Typ. Loc is the reference
         --  location for generated nodes, Typ is the type for which the
         --  conversion function is generated. On return, Decl and Fnam contain
         --  the declaration and entity for the newly-created function.

         function Build_To_Any_Call
           (Loc         : Source_Ptr;
            N           : Node_Id;
            Decls       : List_Id;
            Constrained : Boolean := False) return Node_Id;
         --  Build call to To_Any attribute function with expression as actual
         --  parameter. Loc is the reference location of generated nodes,
         --  Decls is the declarations list for an appropriate enclosing scope
         --  of the point where the call will be inserted; if the To_Any
         --  attribute for the type of N needs to be generated at this point,
         --  its declaration is appended to Decls. For the case of a limited
         --  type, there is an additional parameter Constrained indicating
         --  whether 'Write (when True) or 'Output (when False) is used.

         procedure Build_To_Any_Function
           (Loc  : Source_Ptr;
            Typ  : Entity_Id;
            Decl : out Node_Id;
            Fnam : out Entity_Id);
         --  Build To_Any attribute function for Typ. Loc is the reference
         --  location for generated nodes, Typ is the type for which the
         --  conversion function is generated. On return, Decl and Fnam contain
         --  the declaration and entity for the newly-created function.

         function Build_TypeCode_Call
           (Loc   : Source_Ptr;
            Typ   : Entity_Id;
            Decls : List_Id) return Node_Id;
         --  Build call to TypeCode attribute function for Typ. Decls is the
         --  declarations list for an appropriate enclosing scope of the point
         --  where the call will be inserted; if the To_Any attribute for Typ
         --  needs to be generated at this point, its declaration is appended
         --  to Decls.

         procedure Build_TypeCode_Function
           (Loc  : Source_Ptr;
            Typ  : Entity_Id;
            Decl : out Node_Id;
            Fnam : out Entity_Id);
         --  Build TypeCode attribute function for Typ. Loc is the reference
         --  location for generated nodes, Typ is the type for which the
         --  typecode function is generated. On return, Decl and Fnam contain
         --  the declaration and entity for the newly-created function.

         procedure Build_Name_And_Repository_Id
           (E           : Entity_Id;
            Name_Str    : out String_Id;
            Repo_Id_Str : out String_Id);
         --  In the PolyORB distribution model, each distributed object type
         --  and each distributed operation has a globally unique identifier,
         --  its Repository Id. This subprogram builds and returns two strings
         --  for entity E (a distributed object type or operation): one
         --  containing the name of E, the second containing its repository id.

         procedure Assign_Opaque_From_Any
           (Loc         : Source_Ptr;
            Stms        : List_Id;
            Typ         : Entity_Id;
            N           : Node_Id;
            Target      : Entity_Id;
            Constrained : Boolean := False);
         --  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)
         --
         --  Constrained determines whether 'Input (when False) or 'Read
         --  (when True) is used.

      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
     (Loc         : Source_Ptr;
      N           : Node_Id;
      Decls       : List_Id;
      Constrained : Boolean := False) return Node_Id
     renames PolyORB_Support.Helpers.Build_To_Any_Call;

   function Build_TypeCode_Call
     (Loc   : Source_Ptr;
      Typ   : Entity_Id;
      Decls : List_Id) return Node_Id
     renames PolyORB_Support.Helpers.Build_TypeCode_Call;

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

   RCI_Cache : Node_Id := Empty;
   --  Needs comments ???

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

   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_Pkg --
      ----------------------

      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, including the wrapper package for an instance
               --  of a generic subprogram.

               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_Unit_Instantiation_Node (Pkg_Ent)))
                  then
                     Visit_Nested_Pkg (Decl);
                  end if;
               end;

            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) 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.

      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
         --  Disable expansion of stubs if serious errors have been diagnosed,
         --  because otherwise some illegal remote subprogram declarations
         --  could cause cascaded errors in stubs.

         if Serious_Errors_Detected /= 0 then
            return;
         end if;

         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.

      RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
      RCI_Cache         := Defining_Unit_Name (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 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;

      Visit_Spec (Pkg_Spec);

      Pop_Scope;
   end Add_Calling_Stubs_To_Declarations;

   -----------------------------
   -- Add_Parameter_To_NVList --
   -----------------------------

   function Add_Parameter_To_NVList
     (Loc         : Source_Ptr;
      NVList      : Entity_Id;
      Parameter   : Entity_Id;
      Constrained : Boolean;
      RACW_Ctrl   : Boolean := False;
      Any         : Entity_Id) return Node_Id
   is
      Parameter_Name_String : String_Id;
      Parameter_Mode        : Node_Id;

      function Parameter_Passing_Mode
        (Loc         : Source_Ptr;
         Parameter   : Entity_Id;
         Constrained : Boolean) return Node_Id;
      --  Return an expression that denotes the parameter passing mode to be
      --  used for Parameter in distribution stubs, where Constrained is
      --  Parameter's constrained status.

      ----------------------------
      -- Parameter_Passing_Mode --
      ----------------------------

      function Parameter_Passing_Mode
        (Loc         : Source_Ptr;
         Parameter   : Entity_Id;
         Constrained : Boolean) return Node_Id
      is
         Lib_RE : RE_Id;

      begin
         if Out_Present (Parameter) then
            if In_Present (Parameter)
              or else not Constrained
            then
               --  Unconstrained formals must be translated
               --  to 'in' or 'inout', not 'out', because
               --  they need to be constrained by the actual.

               Lib_RE := RE_Mode_Inout;
            else
               Lib_RE := RE_Mode_Out;
            end if;

         else
            Lib_RE := RE_Mode_In;
         end if;

         return New_Occurrence_Of (RTE (Lib_RE), Loc);
      end Parameter_Passing_Mode;

   --  Start of processing for Add_Parameter_To_NVList

   begin
      if Nkind (Parameter) = N_Defining_Identifier then
         Get_Name_String (Chars (Parameter));
      else
         Get_Name_String (Chars (Defining_Identifier (Parameter)));
      end if;

      Parameter_Name_String := String_From_Name_Buffer;

      if RACW_Ctrl or else Nkind (Parameter) = N_Defining_Identifier then

         --  When the parameter passed to Add_Parameter_To_NVList is an
         --  Extra_Constrained parameter, Parameter is an N_Defining_
         --  Identifier, instead of a complete N_Parameter_Specification.
         --  Thus, we explicitly set 'in' mode in this case.

         Parameter_Mode := New_Occurrence_Of (RTE (RE_Mode_In), Loc);

      else
         Parameter_Mode :=
           Parameter_Passing_Mode (Loc, Parameter, Constrained);
      end if;

      return
        Make_Procedure_Call_Statement (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_NVList_Add_Item), Loc),
          Parameter_Associations => New_List (
            New_Occurrence_Of (NVList, Loc),
            Make_Function_Call (Loc,
              Name                   =>
                New_Occurrence_Of (RTE (RE_To_PolyORB_String), Loc),
              Parameter_Associations => New_List (
                Make_String_Literal (Loc, Strval => Parameter_Name_String))),
            New_Occurrence_Of (Any, Loc),
            Parameter_Mode));
   end Add_Parameter_To_NVList;

   --------------------------------
   -- Add_RACW_Asynchronous_Flag --
   --------------------------------

   procedure Add_RACW_Asynchronous_Flag
     (Declarations : List_Id;
      RACW_Type    : Entity_Id)
   is
      Loc : constant Source_Ptr := Sloc (RACW_Type);

      Asynchronous_Flag : constant Entity_Id :=
                            Make_Defining_Identifier (Loc,
                              New_External_Name (Chars (RACW_Type), 'A'));

   begin
      --  Declare the asynchronous flag. This flag will be changed to True
      --  whenever it is known that the RACW type is asynchronous.

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

      Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Flag);
   end Add_RACW_Asynchronous_Flag;

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

   procedure Add_RACW_Features (RACW_Type : Entity_Id) is
      Desig      : constant Entity_Id := Etype (Designated_Type (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;
      --  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

         --  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.

         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));

      end if;

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

      if No (Decls) then
         return;
      end if;

      Add_Stub_Type
        (Designated_Type     => Desig,
         RACW_Type           => RACW_Type,
         Decls               => Decls,
         Stub_Type           => Stub_Type,
         Stub_Type_Access    => Stub_Type_Access,
         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);

      Specific_Add_RACW_Features
        (RACW_Type           => RACW_Type,
         Desig               => Desig,
         Stub_Type           => Stub_Type,
         Stub_Type_Access    => Stub_Type_Access,
         RPC_Receiver_Decl   => RPC_Receiver_Decl,
         Body_Decls          => Body_Decls);

      --  If we already have stubs for this designated type, nothing to do

      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,
            Body_Decls       => Body_Decls);

      else
         --  Validate_RACW_Primitives requires the list of all primitives of
         --  the designated type, so defer processing until Desig is frozen.
         --  See Exp_Ch3.Freeze_Type.

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

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

   procedure Add_RACW_Primitive_Declarations_And_Bodies
     (Designated_Type : Entity_Id;
      Insertion_Node  : Node_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.

      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);
      --  Case of the RACW generated to implement a remote access-to-
      --  subprogram type.

      Build_Bodies : constant Boolean :=
                       In_Extended_Main_Code_Unit (Stub_Elements.Stub_Type);
      --  True when bodies must be prepared in Body_Decls. Bodies are generated
      --  only when the main unit is the unit that contains the stub type.

      Current_Insertion_Node : Node_Id := Insertion_Node;

      RPC_Receiver                   : Entity_Id;
      RPC_Receiver_Statements        : List_Id;
      RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
      RPC_Receiver_Elsif_Parts       : List_Id          := No_List;
      RPC_Receiver_Request           : Entity_Id        := Empty;
      RPC_Receiver_Subp_Id           : Entity_Id        := Empty;
      RPC_Receiver_Subp_Index        : Entity_Id        := Empty;

      Subp_Str : String_Id;

      Current_Primitive_Elmt   : Elmt_Id;
      Current_Primitive        : Entity_Id;
      Current_Primitive_Body   : Node_Id;
      Current_Primitive_Spec   : Node_Id;
      Current_Primitive_Decl   : Node_Id;
      Current_Primitive_Number : Int := 0;
      Current_Primitive_Alias  : Node_Id;
      Current_Receiver         : Entity_Id;
      Current_Receiver_Body    : Node_Id;
      RPC_Receiver_Decl        : Node_Id;
      Possibly_Asynchronous    : Boolean;

   begin
      if not Expander_Active then
         return;
      end if;

      if not Is_RAS then
         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.

            RPC_Receiver_Elsif_Parts := New_List;
         end if;
      end if;

      --  Build callers, receivers for every primitive operations and a RPC
      --  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 (Direct_Primitive_Operations (Designated_Type)) then
         Overload_Counter_Table.Reset;

         Current_Primitive_Elmt :=
           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. 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) or else
                 Is_TSS (Current_Primitive, TSS_Put_Image)     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 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 := 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),
                   Ctrl_Type   => Stub_Elements.Stub_Type);

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

               Insert_After_And_Analyze (Current_Insertion_Node,
                 Current_Primitive_Decl);
               Current_Insertion_Node := Current_Primitive_Decl;

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

               Assign_Subprogram_Identifier (
                 Defining_Unit_Name (Current_Primitive_Spec),
                 Current_Primitive_Number,
                 Subp_Str);

               if Build_Bodies then
                  Current_Primitive_Body :=
                    Build_Subprogram_Calling_Stubs
                      (Vis_Decl                 => Current_Primitive_Decl,
                       Subp_Id                  =>
                         Build_Subprogram_Id (Loc,
                           Defining_Unit_Name (Current_Primitive_Spec)),
                       Asynchronous             => Possibly_Asynchronous,
                       Dynamically_Asynchronous => Possibly_Asynchronous,
                       Stub_Type                => Stub_Elements.Stub_Type,
                       RACW_Type                => Stub_Elements.RACW_Type);
                  Append_To (Body_Decls, Current_Primitive_Body);

                  --  Analyzing the body here would cause the Stub type to
                  --  be frozen, thus preventing subsequent primitive
                  --  declarations. For this reason, it will be analyzed
                  --  later in the regular flow (and in the context of the
                  --  appropriate unit body, see Append_RACW_Bodies).

               end if;

               --  Build the receiver stubs

               if Build_Bodies and then not Is_RAS then
                  Current_Receiver_Body :=
                    Specific_Build_Subprogram_Receiving_Stubs
                      (Vis_Decl                 => Current_Primitive_Decl,
                       Asynchronous             => Possibly_Asynchronous,
                       Dynamically_Asynchronous => Possibly_Asynchronous,
                       Stub_Type                => Stub_Elements.Stub_Type,
                       RACW_Type                => Stub_Elements.RACW_Type,
                       Parent_Primitive         => Current_Primitive);

                  Current_Receiver :=
                    Defining_Unit_Name (Specification (Current_Receiver_Body));

                  Append_To (Body_Decls, Current_Receiver_Body);

                  --  Add a case alternative to the receiver

                  if Get_PCS_Name = Name_PolyORB_DSA then
                     Append_To (RPC_Receiver_Elsif_Parts,
                       Make_Elsif_Part (Loc,
                         Condition =>
                           Make_Function_Call (Loc,
                             Name =>
                               New_Occurrence_Of (
                                 RTE (RE_Caseless_String_Eq), Loc),
                             Parameter_Associations => New_List (
                               New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
                               Make_String_Literal (Loc, Subp_Str))),

                         Then_Statements => New_List (
                           Make_Assignment_Statement (Loc,
                             Name => New_Occurrence_Of (
                                       RPC_Receiver_Subp_Index, Loc),
                             Expression =>
                               Make_Integer_Literal (Loc,
                                  Intval => Current_Primitive_Number)))));
                  end if;

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

                      Statements       => New_List (
                        Make_Procedure_Call_Statement (Loc,
                          Name                   =>
                            New_Occurrence_Of (Current_Receiver, Loc),
                          Parameter_Associations => New_List (
                            New_Occurrence_Of (RPC_Receiver_Request, Loc))))));
               end if;

               --  Increment the index of current primitive

               Current_Primitive_Number := Current_Primitive_Number + 1;
            end if;

            Next_Elmt (Current_Primitive_Elmt);
         end loop;
      end if;

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

      if Build_Bodies and then not Is_RAS then
         if Get_PCS_Name = Name_PolyORB_DSA
           and then Present (First (RPC_Receiver_Elsif_Parts))
         then
            Append_To (RPC_Receiver_Statements,
              Make_Implicit_If_Statement (Designated_Type,
                Condition       => New_Occurrence_Of (Standard_False, Loc),
                Then_Statements => New_List,
                Elsif_Parts     => RPC_Receiver_Elsif_Parts));
         end if;

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

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

         Append_To (Body_Decls, RPC_Receiver_Decl);
         Specific_Add_Obj_RPC_Receiver_Completion (Loc,
           Body_Decls, RPC_Receiver, Stub_Elements);

      --  Do not analyze RPC receiver body at this stage since it references
      --  subprograms that have not been analyzed yet. It will be analyzed in
      --  the regular flow (see Append_RACW_Bodies).

      end if;
   end Add_RACW_Primitive_Declarations_And_Bodies;

   -----------------------------
   -- Add_RAS_Dereference_TSS --
   -----------------------------

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

      Type_Def  : constant Node_Id   := Type_Definition (N);
      RAS_Type  : constant Entity_Id := Defining_Identifier (N);
      Fat_Type  : constant Entity_Id := Equivalent_Type (RAS_Type);
      RACW_Type : constant Entity_Id := Underlying_RACW_Type (RAS_Type);

      RACW_Primitive_Name : Node_Id;

      Proc : constant Entity_Id :=
               Make_Defining_Identifier (Loc,
                 Chars => Make_TSS_Name (RAS_Type, TSS_RAS_Dereference));

      Proc_Spec   : Node_Id;
      Param_Specs : List_Id;
      Param_Assoc : constant List_Id := New_List;
      Stmts       : constant List_Id := New_List;

      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).

      Spec : constant Node_Id := Type_Def;

      Current_Parameter : Node_Id;

   --  Start of processing for Add_RAS_Dereference_TSS

   begin
      --  The Dereference TSS for a remote access-to-subprogram type has the
      --  form:

      --    [function|procedure] ras_typeRD (RAS_Value, <RAS_Parameters>)
      --       [return <>]

      --  This is called whenever a value of a RAS type is dereferenced

      --  First construct a list of parameter specifications:

      --  The first formal is the RAS values

      Param_Specs := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => RAS_Parameter,
          In_Present          => True,
          Parameter_Type      =>
            New_Occurrence_Of (Fat_Type, Loc)));

      --  The following formals are copied from the type declaration

      Is_Degenerate := False;
      Current_Parameter := First (Parameter_Specifications (Type_Def));
      Parameters : while Present (Current_Parameter) loop
         if Nkind (Parameter_Type (Current_Parameter)) =
                                            N_Access_Definition
         then
            Is_Degenerate := True;
         end if;

         Append_To (Param_Specs,
           Make_Parameter_Specification (Loc,
             Defining_Identifier =>
               Make_Defining_Identifier (Loc,
                 Chars => Chars (Defining_Identifier (Current_Parameter))),
             In_Present        => In_Present (Current_Parameter),
             Out_Present       => Out_Present (Current_Parameter),
             Parameter_Type    =>
               New_Copy_Tree (Parameter_Type (Current_Parameter)),
             Expression        =>
               New_Copy_Tree (Expression (Current_Parameter))));

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

         Next (Current_Parameter);
      end loop Parameters;

      if Is_Degenerate then
         Prepend_To (Param_Assoc, New_Occurrence_Of (RAS_Parameter, Loc));

         --  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.

         Append_To (Stmts,
           Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
         RACW_Primitive_Name := New_Occurrence_Of (Proc, Loc);

      else
         --  For a normal RAS type, we cast the RAS formal to the corresponding
         --  tagged type, and perform a dispatching call to its Call primitive
         --  operation.

         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_uCall);
      end if;

      if Is_Function then
         Append_To (Stmts,
            Make_Simple_Return_Statement (Loc,
              Expression =>
                Make_Function_Call (Loc,
                  Name                   => RACW_Primitive_Name,
                  Parameter_Associations => Param_Assoc)));

      else
         Append_To (Stmts,
           Make_Procedure_Call_Statement (Loc,
             Name                   => RACW_Primitive_Name,
             Parameter_Associations => Param_Assoc));
      end if;

      --  Build the complete subprogram

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

         Mutate_Ekind (Proc, E_Function);
         Set_Etype (Proc,
           New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));

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

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

      Discard_Node (
        Make_Subprogram_Body (Loc,
          Specification              => Proc_Spec,
          Declarations               => New_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Stmts)));

      Set_TSS (Fat_Type, Proc);
   end Add_RAS_Dereference_TSS;

   -------------------------------
   -- Add_RAS_Proxy_And_Analyze --
   -------------------------------

   procedure Add_RAS_Proxy_And_Analyze
     (Decls              : List_Id;
      Vis_Decl           : Node_Id;
      All_Calls_Remote_E : Entity_Id;
      Proxy_Object_Addr  : out Entity_Id)
   is
      Loc : constant Source_Ptr := Sloc (Vis_Decl);

      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));

      Proxy_Type : constant Entity_Id :=
                     Make_Defining_Identifier (Loc,
                       Chars =>
                         New_External_Name
                           (Related_Id => Chars (Subp_Name),
                            Suffix     => 'P'));

      Proxy_Type_Full_View : constant Entity_Id :=
                               Make_Defining_Identifier (Loc,
                                 Chars (Proxy_Type));

      Subp_Decl_Spec : constant Node_Id :=
                         Build_RAS_Primitive_Specification
                           (Subp_Spec          => Specification (Vis_Decl),
                            Remote_Object_Type => Proxy_Type);

      Subp_Body_Spec : constant Node_Id :=
                         Build_RAS_Primitive_Specification
                           (Subp_Spec          => Specification (Vis_Decl),
                            Remote_Object_Type => Proxy_Type);

      Vis_Decls    : constant List_Id := New_List;
      Pvt_Decls    : constant List_Id := New_List;
      Actuals      : constant List_Id := New_List;
      Formal       : Node_Id;
      Perform_Call : Node_Id;

   begin
      --  type subpP is tagged limited private;

      Append_To (Vis_Decls,
        Make_Private_Type_Declaration (Loc,
          Defining_Identifier => Proxy_Type,
          Tagged_Present      => True,
          Limited_Present     => True));

      --  [subprogram] Call
      --    (Self : access subpP;
      --     ...other-formals...)
      --     [return T];

      Append_To (Vis_Decls,
        Make_Subprogram_Declaration (Loc,
          Specification => Subp_Decl_Spec));

      --  A : constant System.Address;

      Proxy_Object_Addr := Make_Defining_Identifier (Loc, Name_uA);

      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)));

      --  private

      --  type subpP is tagged limited record
      --     All_Calls_Remote : Boolean := [All_Calls_Remote?];
      --     ...
      --  end record;

      Append_To (Pvt_Decls,
        Make_Full_Type_Declaration (Loc,
          Defining_Identifier => Proxy_Type_Full_View,
          Type_Definition     =>
            Build_Remote_Subprogram_Proxy_Type (Loc,
              New_Occurrence_Of (All_Calls_Remote_E, Loc))));

      --  Trick semantic analysis into swapping the public and full view when
      --  freezing the public view.

      Set_Comes_From_Source (Proxy_Type_Full_View, True);

      --  procedure Call
      --    (Self : access O;
      --     ...other-formals...) is
      --  begin
      --    P (...other-formals...);
      --  end Call;

      --  function Call
      --    (Self : access O;
      --     ...other-formals...)
      --     return T is
      --  begin
      --    return F (...other-formals...);
      --  end Call;

      if Nkind (Subp_Decl_Spec) = N_Procedure_Specification then
         Perform_Call :=
           Make_Procedure_Call_Statement (Loc,
             Name                   => New_Occurrence_Of (Subp_Name, Loc),
             Parameter_Associations => Actuals);
      else
         Perform_Call :=
           Make_Simple_Return_Statement (Loc,
             Expression =>
               Make_Function_Call (Loc,
                 Name                   => New_Occurrence_Of (Subp_Name, Loc),
                 Parameter_Associations => Actuals));
      end if;

      Formal := First (Parameter_Specifications (Subp_Decl_Spec));
      pragma Assert (Present (Formal));
      loop
         Next (Formal);
         exit when No (Formal);
         Append_To (Actuals,
           New_Occurrence_Of (Defining_Identifier (Formal), Loc));
      end loop;

      --  O : aliased subpP;

      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)));

      --  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),
          Expression =>
            Make_Attribute_Reference (Loc,
              Prefix => New_Occurrence_Of (
                Defining_Identifier (Last (Pvt_Decls)), Loc),
              Attribute_Name => Name_Address)));

      Append_To (Decls,
        Make_Package_Declaration (Loc,
          Specification => Make_Package_Specification (Loc,
            Defining_Unit_Name   => Pkg_Name,
            Visible_Declarations => Vis_Decls,
            Private_Declarations => Pvt_Decls,
            End_Label            => Empty)));
      Analyze (Last (Decls));

      Append_To (Decls,
        Make_Package_Body (Loc,
          Defining_Unit_Name =>
            Make_Defining_Identifier (Loc, Chars (Pkg_Name)),
          Declarations => New_List (
            Make_Subprogram_Body (Loc,
              Specification  => Subp_Body_Spec,
              Declarations   => New_List,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => New_List (Perform_Call))))));
      Analyze (Last (Decls));
   end Add_RAS_Proxy_And_Analyze;

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

   procedure Add_RAST_Features (Vis_Decl : Node_Id) is
      RAS_Type : constant Entity_Id :=
                   Equivalent_Type (Defining_Identifier (Vis_Decl));
   begin
      pragma Assert (No (TSS (RAS_Type, TSS_RAS_Access)));
      Add_RAS_Dereference_TSS (Vis_Decl);
      Specific_Add_RAST_Features (Vis_Decl, RAS_Type);
   end Add_RAST_Features;

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

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

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

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

      Existing := False;
      Stub_Type := Make_Temporary (Loc, 'S');
      Mutate_Ekind (Stub_Type, E_Record_Type);
      Set_Is_RACW_Stub_Type (Stub_Type);
      Stub_Type_Access :=
        Make_Defining_Identifier (Loc,
          Chars => New_External_Name
                     (Related_Id => Chars (Stub_Type), Suffix => 'A'));

      RPC_Receiver_Decl := Specific_RPC_Receiver_Decl (RACW_Type);

      --  Create new stub type, copying components from generic RACW_Stub_Type

      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 =>
                    Copy_Component_List (RTE (RE_RACW_Stub_Type), Loc))));

      --  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,
          Defining_Identifier => Stub_Type_Access,
          Type_Definition     =>
            Make_Access_To_Object_Definition (Loc,
              All_Present        => True,
              Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));

      Append_To (Decls, Stub_Type_Decl);
      Analyze (Last (Decls));
      Append_To (Decls, Stub_Type_Access_Decl);
      Analyze (Last (Decls));

      --  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);

      if Present (RPC_Receiver_Decl) then
         Append_To (Decls, RPC_Receiver_Decl);

      else
         --  Case of RACW implementing a RAS with the GARLIC PCS: there is
         --  no RPC receiver in that case, this is just an indication of
         --  where to insert code in the tree (see comment in declaration of
         --  type Stub_Structure).

         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 --
   ----------------------------------

   procedure Assign_Subprogram_Identifier
     (Def : Entity_Id;
      Spn : Int;
      Id  : out String_Id)
   is
      N : constant Name_Id := Chars (Def);

      Overload_Order : constant Int := Overload_Counter_Table.Get (N) + 1;

   begin
      Overload_Counter_Table.Set (N, Overload_Order);

      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.

      if Overload_Order > 1 then
         Name_Buffer (Name_Len + 1 .. Name_Len + 2) := "__";
         Name_Len := Name_Len + 2;
         Add_Nat_To_Name_Buffer (Overload_Order);
      end if;

      Id := String_From_Name_Buffer;
      Subprogram_Identifier_Table.Set
        (Def,
         Subprogram_Identifiers'(Str_Identifier => Id, Int_Identifier => Spn));
   end Assign_Subprogram_Identifier;

   -------------------------------------
   -- Build_Actual_Object_Declaration --
   -------------------------------------

   procedure Build_Actual_Object_Declaration
     (Object   : Entity_Id;
      Etyp     : Entity_Id;
      Variable : Boolean;
      Expr     : Node_Id;
      Decls    : List_Id)
   is
      Loc : constant Source_Ptr := Sloc (Object);

   begin
      --  Declare a temporary object for the actual, possibly initialized with
      --  a 'Input/From_Any call.

      --  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)));
               Mutate_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
            Mutate_Ekind (Object, E_Constant);
         else
            Mutate_Ekind (Object, E_Variable);
         end if;
      end if;
   end Build_Actual_Object_Declaration;

   ------------------------------
   -- Build_Get_Unique_RP_Call --
   ------------------------------

   function Build_Get_Unique_RP_Call
     (Loc       : Source_Ptr;
      Pointer   : Entity_Id;
      Stub_Type : Entity_Id) return List_Id
   is
   begin
      return New_List (
        Make_Procedure_Call_Statement (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
          Parameter_Associations => New_List (
            Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
              New_Occurrence_Of (Pointer, Loc)))),

        Make_Assignment_Statement (Loc,
          Name =>
            Make_Selected_Component (Loc,
              Prefix => New_Occurrence_Of (Pointer, Loc),
              Selector_Name =>
                New_Occurrence_Of (First_Tag_Component
                  (Designated_Type (Etype (Pointer))), Loc)),
          Expression =>
            Make_Attribute_Reference (Loc,
              Prefix         => New_Occurrence_Of (Stub_Type, Loc),
              Attribute_Name => Name_Tag)));

      --  Note: The assignment to Pointer._Tag is safe here because
      --  we carefully ensured that Stub_Type has exactly the same layout
      --  as System.Partition_Interface.RACW_Stub_Type.

   end Build_Get_Unique_RP_Call;

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

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

      First_Parameter : Node_Id;
      For_RAS         : Boolean := False;

   begin
      if No (Parameter_Specifications (Spec)) then
         return New_List;
      end if;

      Constrained_List   := New_List;
      Unconstrained_List := New_List;
      First_Parameter    := First (Parameter_Specifications (Spec));

      if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition
        and then Chars (Defining_Identifier (First_Parameter)) = Name_uS
      then
         For_RAS := True;
      end if;

      --  Loop through the parameters and add them to the right list. Note that
      --  we treat a parameter of a null-excluding access type as unconstrained
      --  because we can't declare an object of such a type with default
      --  initialization.

      Current_Parameter := First_Parameter;
      while Present (Current_Parameter) loop
         Ptyp := Parameter_Type (Current_Parameter);

         if (Nkind (Ptyp) = N_Access_Definition
               or else not Transmit_As_Unconstrained (Etype (Ptyp)))
           and then not (For_RAS and then Current_Parameter = First_Parameter)
         then
            Append_To (Constrained_List, New_Copy (Current_Parameter));
         else
            Append_To (Unconstrained_List, New_Copy (Current_Parameter));
         end if;

         Next (Current_Parameter);
      end loop;

      --  Unconstrained parameters are returned first

      Append_List_To (Unconstrained_List, Constrained_List);

      return Unconstrained_List;
   end Build_Ordered_Parameters_List;

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

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

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

      declare
         Dist_OK : Entity_Id;
         pragma Warnings (Off, Dist_OK);
      begin
         Dist_OK := RTE (RE_Params_Stream_Type);
      end;

      --  Use body if present, spec otherwise

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

      Reg :=
        Make_Procedure_Call_Statement (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
          Parameter_Associations => New_List (
            Make_String_Literal (Loc,
              Fully_Qualified_Name_String (Pkg_Ent, Append_NUL => False)),
            Make_Attribute_Reference (Loc,
              Prefix         => New_Occurrence_Of (Pkg_Ent, Loc),
              Attribute_Name => Name_Version)));
      Append_To (L, Reg);
      Analyze (Reg);
   end Build_Passive_Partition_Stub;

   --------------------------------------
   -- Build_RPC_Receiver_Specification --
   --------------------------------------

   function Build_RPC_Receiver_Specification
     (RPC_Receiver      : Entity_Id;
      Request_Parameter : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (RPC_Receiver);
   begin
      return
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       => RPC_Receiver,
          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier => Request_Parameter,
              Parameter_Type      =>
                New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
   end Build_RPC_Receiver_Specification;

   ----------------------------------------
   -- Build_Remote_Subprogram_Proxy_Type --
   ----------------------------------------

   function Build_Remote_Subprogram_Proxy_Type
     (Loc            : Source_Ptr;
      ACR_Expression : Node_Id) return Node_Id
   is
   begin
      return
        Make_Record_Definition (Loc,
          Tagged_Present  => True,
          Limited_Present => True,
          Component_List  =>
            Make_Component_List (Loc,
              Component_Items => New_List (
                Make_Component_Declaration (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc,
                      Name_All_Calls_Remote),
                  Component_Definition =>
                    Make_Component_Definition (Loc,
                      Subtype_Indication =>
                        New_Occurrence_Of (Standard_Boolean, Loc)),
                  Expression =>
                    ACR_Expression),

                Make_Component_Declaration (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc,
                      Name_Receiver),
                  Component_Definition =>
                    Make_Component_Definition (Loc,
                      Subtype_Indication =>
                        New_Occurrence_Of (RTE (RE_Address), Loc)),
                  Expression =>
                    New_Occurrence_Of (RTE (RE_Null_Address), Loc)),

                Make_Component_Declaration (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc,
                      Name_Subp_Id),
                  Component_Definition =>
                    Make_Component_Definition (Loc,
                      Subtype_Indication =>
                        New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))))));
   end Build_Remote_Subprogram_Proxy_Type;

   --------------------
   -- Build_Stub_Tag --
   --------------------

   function Build_Stub_Tag
     (Loc       : Source_Ptr;
      RACW_Type : Entity_Id) return Node_Id
   is
      Stub_Type : constant Entity_Id := Corresponding_Stub_Type (RACW_Type);
   begin
      return
        Make_Attribute_Reference (Loc,
          Prefix         => New_Occurrence_Of (Stub_Type, Loc),
          Attribute_Name => Name_Tag);
   end Build_Stub_Tag;

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

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

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

      Subp_Spec : Node_Id;
      --  The specification of the body

      Controlling_Parameter : Entity_Id := Empty;

      Asynchronous_Expr : Node_Id := Empty;

      RCI_Locator : Entity_Id;

      Spec_To_Use : Node_Id;

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

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

      procedure Insert_Partition_Check (Parameter : Node_Id) is
         Parameter_Entity : constant Entity_Id :=
                              Defining_Identifier (Parameter);
      begin
         --  The expression that will be built is of the form:

         --    if not Same_Partition (Parameter, Controlling_Parameter) then
         --      raise Constraint_Error;
         --    end if;

         --  We do not check that Parameter is in Stub_Type since such a check
         --  has been inserted at the point of call already (a tag check since
         --  we have multiple controlling operands).

         Append_To (Decls,
           Make_Raise_Constraint_Error (Loc,
             Condition       =>
               Make_Op_Not (Loc,
                 Right_Opnd =>
                   Make_Function_Call (Loc,
                     Name =>
                       New_Occurrence_Of (RTE (RE_Same_Partition), Loc),
                     Parameter_Associations =>
                       New_List (
                         Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
                           New_Occurrence_Of (Parameter_Entity, Loc)),
                         Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
                           New_Occurrence_Of (Controlling_Parameter, Loc))))),
             Reason => CE_Partition_Check_Failed));
      end Insert_Partition_Check;

   --  Start of processing for Build_Subprogram_Calling_Stubs

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

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

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

      if Present (Stub_Type)
         and then Present (Parameter_Specifications (Spec_To_Use))
      then
         declare
            Current_Parameter : Node_Id :=
                                  First (Parameter_Specifications
                                           (Spec_To_Use));
         begin
            while Present (Current_Parameter) loop
               if
                 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
               then
                  if Controlling_Parameter = Empty then
                     Controlling_Parameter :=
                       Defining_Identifier (Current_Parameter);
                  else
                     Insert_Partition_Check (Current_Parameter);
                  end if;
               end if;

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

      pragma Assert (No (Stub_Type) or else Present (Controlling_Parameter));

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

      Specific_Build_General_Calling_Stubs
        (Decls                 => Decls,
         Statements            => Statements,
         Target                => Specific_Build_Stub_Target (Loc,
                                    Decls, RCI_Locator, Controlling_Parameter),
         Subprogram_Id         => Subp_Id,
         Asynchronous          => Asynchronous_Expr,
         Is_Known_Asynchronous => Asynchronous
                                    and then not Dynamically_Asynchronous,
         Is_Known_Non_Asynchronous
                               => not Asynchronous
                                    and then not Dynamically_Asynchronous,
         Is_Function           => Nkind (Spec_To_Use) =
                                    N_Function_Specification,
         Spec                  => Spec_To_Use,
         Stub_Type             => Stub_Type,
         RACW_Type             => RACW_Type,
         Nod                   => Vis_Decl);

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

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

   -------------------------
   -- Build_Subprogram_Id --
   -------------------------

   function Build_Subprogram_Id
     (Loc : Source_Ptr;
      E   : Entity_Id) return Node_Id
   is
   begin
      if Get_Subprogram_Ids (E).Str_Identifier = No_String then
         declare
            Current_Declaration : Node_Id;
            Current_Subp        : Entity_Id;
            Current_Subp_Str    : String_Id;
            Current_Subp_Number : Int := First_RCI_Subprogram_Id;

            pragma Warnings (Off, Current_Subp_Str);

         begin
            --  Build_Subprogram_Id is called outside of the context of
            --  generating calling or receiving stubs. Hence we are processing
            --  an 'Access attribute_reference for an RCI subprogram, for the
            --  purpose of obtaining a RAS value.

            pragma Assert
              (Is_Remote_Call_Interface (Scope (E))
                 and then
                  (Nkind (Parent (E)) = N_Procedure_Specification
                     or else
                   Nkind (Parent (E)) = N_Function_Specification));

            Current_Declaration :=
              First (Visible_Declarations
                (Package_Specification_Of_Scope (Scope (E))));
            while Present (Current_Declaration) loop
               if Nkind (Current_Declaration) = N_Subprogram_Declaration
                 and then Comes_From_Source (Current_Declaration)
               then
                  Current_Subp := Defining_Unit_Name (Specification (
                    Current_Declaration));

                  Assign_Subprogram_Identifier
                    (Current_Subp, Current_Subp_Number, Current_Subp_Str);

                  Current_Subp_Number := Current_Subp_Number + 1;
               end if;

               Next (Current_Declaration);
            end loop;
         end;
      end if;

      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            return Make_String_Literal (Loc, Get_Subprogram_Id (E));

         when others =>
            return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
      end case;
   end Build_Subprogram_Id;

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

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

      Current_Parameter  : Node_Id;
      Current_Identifier : Entity_Id;
      Current_Type       : Node_Id;

      Name_For_New_Spec : Name_Id;

      New_Identifier : Entity_Id;

   --  Comments needed in body below ???

   begin
      if New_Name = No_Name then
         pragma Assert (Nkind (Spec) = N_Function_Specification
                or else Nkind (Spec) = N_Procedure_Specification);

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

      if Present (Parameter_Specifications (Spec)) then
         Parameters        := New_List;
         Current_Parameter := First (Parameter_Specifications (Spec));
         while Present (Current_Parameter) loop
            Current_Identifier := Defining_Identifier (Current_Parameter);
            Current_Type       := Parameter_Type (Current_Parameter);

            if Nkind (Current_Type) = N_Access_Definition then
               if Present (Ctrl_Type) then
                  pragma Assert (Is_Controlling_Formal (Current_Identifier));
                  Current_Type :=
                    Make_Access_Definition (Loc,
                      Subtype_Mark => New_Occurrence_Of (Ctrl_Type, Loc),
                      Null_Exclusion_Present =>
                        Null_Exclusion_Present (Current_Type));

               else
                  Current_Type :=
                    Make_Access_Definition (Loc,
                      Subtype_Mark =>
                        New_Copy_Tree (Subtype_Mark (Current_Type)),
                      Null_Exclusion_Present =>
                        Null_Exclusion_Present (Current_Type));
               end if;

            else
               if Present (Ctrl_Type)
                 and then Is_Controlling_Formal (Current_Identifier)
               then
                  Current_Type := New_Occurrence_Of (Ctrl_Type, Loc);
               else
                  Current_Type := New_Copy_Tree (Current_Type);
               end if;
            end if;

            New_Identifier := Make_Defining_Identifier (Loc,
              Chars (Current_Identifier));

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

            --  For a regular formal parameter (that needs to be marshalled
            --  in the context of remote calls), set the Etype now, because
            --  marshalling processing might need it.

            if Is_Entity_Name (Current_Type) then
               Set_Etype (New_Identifier, Entity (Current_Type));

            --  Current_Type is an access definition, special processing
            --  (not requiring etype) will occur for marshalling.

            else
               null;
            end if;

            Next (Current_Parameter);
         end loop;
      end if;

      case Nkind (Spec) is
         when N_Access_Function_Definition
            | N_Function_Specification
         =>
            return
              Make_Function_Specification (Loc,
                Defining_Unit_Name       =>
                  Make_Defining_Identifier (Loc,
                    Chars => Name_For_New_Spec),
                Parameter_Specifications => Parameters,
                Result_Definition        =>
                  New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));

         when N_Access_Procedure_Definition
            | N_Procedure_Specification
         =>
            return
              Make_Procedure_Specification (Loc,
                Defining_Unit_Name       =>
                  Make_Defining_Identifier (Loc,
                    Chars => Name_For_New_Spec),
                Parameter_Specifications => Parameters);

         when others =>
            raise Program_Error;
      end case;
   end Copy_Specification;

   -----------------------------
   -- Corresponding_Stub_Type --
   -----------------------------

   function Corresponding_Stub_Type (RACW_Type : Entity_Id) return Entity_Id is
      Desig         : constant Entity_Id      :=
                        Etype (Designated_Type (RACW_Type));
      Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
   begin
      return Stub_Elements.Stub_Type;
   end Corresponding_Stub_Type;

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

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

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

            Next (Current_Parameter);
         end loop;
      end if;

      return True;
   end Could_Be_Asynchronous;

   ---------------------------
   -- Declare_Create_NVList --
   ---------------------------

   procedure Declare_Create_NVList
     (Loc    : Source_Ptr;
      NVList : Entity_Id;
      Decls  : List_Id;
      Stmts  : List_Id)
   is
   begin
      Append_To (Decls,
        Make_Object_Declaration (Loc,
          Defining_Identifier => NVList,
          Aliased_Present     => False,
          Object_Definition   =>
              New_Occurrence_Of (RTE (RE_NVList_Ref), Loc)));

      Append_To (Stmts,
        Make_Procedure_Call_Statement (Loc,
          Name => New_Occurrence_Of (RTE (RE_NVList_Create), Loc),
          Parameter_Associations => New_List (
            New_Occurrence_Of (NVList, Loc))));
   end Declare_Create_NVList;

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

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

   begin
      E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);

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

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

         declare
            Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
         begin
            if Ekind (Scop) = E_Package_Body then
               Push_Scope (Spec_Entity (Scop));
            elsif Ekind (Scop) = E_Subprogram_Body then
               Push_Scope
                 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
            else
               Push_Scope (Scop);
            end if;
         end;

         if RCI_Locator = Empty then
            RCI_Locator_Decl :=
              RCI_Package_Locator (Loc, Package_Specification (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_Decl := Parent (RCI_Locator);
         end if;

         Calling_Stubs := Build_Subprogram_Calling_Stubs
           (Vis_Decl               => Parent (Parent (Called_Subprogram)),
            Subp_Id                =>
              Build_Subprogram_Id (Loc, Called_Subprogram),
            Asynchronous           => Nkind (N) = N_Procedure_Call_Statement
                                        and then
                                      Is_Asynchronous (Called_Subprogram),
            Locator                => RCI_Locator,
            New_Name               => New_Internal_Name ('S'));
         Insert_After (RCI_Locator_Decl, Calling_Stubs);
         Analyze (Calling_Stubs);
         Pop_Scope;

         E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
      end if;

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

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

   procedure Expand_Calling_Stubs_Bodies (Unit_Node : Node_Id) is
      Spec  : constant Node_Id := Specification (Unit_Node);
   begin
      Add_Calling_Stubs_To_Declarations (Spec);
   end Expand_Calling_Stubs_Bodies;

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

   procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is
      Spec        : Node_Id;
      Decls       : List_Id;
      Stubs_Decls : List_Id;
      Stubs_Stmts : List_Id;

   begin
      if Nkind (Unit_Node) = N_Package_Declaration then
         Spec  := Specification (Unit_Node);
         Decls := Private_Declarations (Spec);

         if No (Decls) then
            Decls := Visible_Declarations (Spec);
         end if;

         Push_Scope (Scope_Of_Spec (Spec));
         Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls, Decls);

      else
         Spec :=
           Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
         Decls := Declarations (Unit_Node);

         Push_Scope (Scope_Of_Spec (Unit_Node));
         Stubs_Decls := New_List;
         Stubs_Stmts := New_List;
         Specific_Add_Receiving_Stubs_To_Declarations
           (Spec, Stubs_Decls, Stubs_Stmts);

         Insert_List_Before (First (Decls), Stubs_Decls);

         declare
            HSS_Stmts : constant List_Id :=
                          Statements (Handled_Statement_Sequence (Unit_Node));

            First_HSS_Stmt : constant Node_Id := First (HSS_Stmts);

         begin
            if No (First_HSS_Stmt) then
               Append_List_To (HSS_Stmts, Stubs_Stmts);
            else
               Insert_List_Before (First_HSS_Stmt, Stubs_Stmts);
            end if;
         end;
      end if;

      Pop_Scope;
   end Expand_Receiving_Stubs_Bodies;

   --------------------
   -- GARLIC_Support --
   --------------------

   package body GARLIC_Support is

      --  Local subprograms

      procedure Add_RACW_Read_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         Body_Decls       : List_Id);
      --  Add Read attribute for the RACW type. The declaration and attribute
      --  definition clauses are inserted right after the declaration of
      --  RACW_Type. If Body_Decls is not No_List, the subprogram body is
      --  appended to it (case where the RACW declaration is in the main unit).

      procedure Add_RACW_Write_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         RPC_Receiver     : Node_Id;
         Body_Decls       : List_Id);
      --  Same as above for the Write attribute

      function Stream_Parameter return Node_Id;
      function Result return Node_Id;
      function Object return Node_Id renames Result;
      --  Functions to create occurrences of the formal parameter names of the
      --  'Read and 'Write attributes.

      Loc : Source_Ptr;
      --  Shared source location used by Add_{Read,Write}_Read_Attribute and
      --  their ancillary subroutines (set on entry by Add_RACW_Features).

      procedure Add_RAS_Access_TSS (N : Node_Id);
      --  Add a subprogram body for RAS Access TSS

      -------------------------------------
      -- Add_Obj_RPC_Receiver_Completion --
      -------------------------------------

      procedure Add_Obj_RPC_Receiver_Completion
        (Loc           : Source_Ptr;
         Decls         : List_Id;
         RPC_Receiver  : Entity_Id;
         Stub_Elements : Stub_Structure)
      is
      begin
         --  The RPC receiver body should not be the completion of the
         --  declaration recorded in the stub structure, because then the
         --  occurrences of the formal parameters within the body should refer
         --  to the entities from the declaration, not from the completion, to
         --  which we do not have easy access. Instead, the RPC receiver body
         --  acts as its own declaration, and the RPC receiver declaration is
         --  completed by a renaming-as-body.

         Append_To (Decls,
           Make_Subprogram_Renaming_Declaration (Loc,
             Specification =>
               Copy_Specification (Loc,
                 Specification (Stub_Elements.RPC_Receiver_Decl)),
             Name          => New_Occurrence_Of (RPC_Receiver, Loc)));
      end Add_Obj_RPC_Receiver_Completion;

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

      procedure Add_RACW_Features
        (RACW_Type         : Entity_Id;
         Stub_Type         : Entity_Id;
         Stub_Type_Access  : Entity_Id;
         RPC_Receiver_Decl : Node_Id;
         Body_Decls        : List_Id)
      is
         RPC_Receiver : Node_Id;
         Is_RAS       : constant Boolean := not Comes_From_Source (RACW_Type);

      begin
         Loc := Sloc (RACW_Type);

         if Is_RAS then

            --  For a RAS, the RPC receiver is that of the RCI unit, not that
            --  of the corresponding distributed object type. We retrieve its
            --  address from the local proxy object.

            RPC_Receiver := Make_Selected_Component (Loc,
              Prefix         =>
                Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object),
              Selector_Name  => Make_Identifier (Loc, Name_Receiver));

         else
            RPC_Receiver := Make_Attribute_Reference (Loc,
              Prefix         => New_Occurrence_Of (
                Defining_Unit_Name (Specification (RPC_Receiver_Decl)), Loc),
              Attribute_Name => Name_Address);
         end if;

         Add_RACW_Write_Attribute
           (RACW_Type,
            Stub_Type,
            Stub_Type_Access,
            RPC_Receiver,
            Body_Decls);

         Add_RACW_Read_Attribute
           (RACW_Type,
            Stub_Type,
            Stub_Type_Access,
            Body_Decls);
      end Add_RACW_Features;

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

      procedure Add_RACW_Read_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         Body_Decls       : List_Id)
      is
         Proc_Decl : Node_Id;
         Attr_Decl : Node_Id;

         Body_Node : Node_Id;

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

         Pnam              : constant Entity_Id := Make_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 (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Source_Partition,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),

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

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

           Make_Object_Declaration (Loc,
             Defining_Identifier => Local_Stub,
             Aliased_Present     => True,
             Object_Definition   => New_Occurrence_Of (Stub_Type, Loc)),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Stubbed_Result,
             Object_Definition   =>
               New_Occurrence_Of (Stub_Type_Access, Loc),
             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix =>
                   New_Occurrence_Of (Local_Stub, Loc),
                 Attribute_Name =>
                   Name_Unchecked_Access)));

         --  Read the source Partition_ID and RPC_Receiver from incoming stream

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

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

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

         --  Build_Get_Unique_RP_Call needs the type of Stubbed_Result

         Set_Etype (Stubbed_Result, Stub_Type_Access);

         --  If the Address is Null_Address, then return a null object, unless
         --  RACW_Type is null-excluding, in which case unconditionally raise
         --  CONSTRAINT_ERROR instead.

         declare
            Zero_Statements : List_Id;
            --  Statements executed when a zero value is received

         begin
            if Can_Never_Be_Null (RACW_Type) then
               Zero_Statements := New_List (
                 Make_Raise_Constraint_Error (Loc,
                   Reason => CE_Null_Not_Allowed));
            else
               Zero_Statements := New_List (
                 Make_Assignment_Statement (Loc,
                   Name       => Result,
                   Expression => Make_Null (Loc)),
                 Make_Simple_Return_Statement (Loc));
            end if;

            Append_To (Statements,
              Make_Implicit_If_Statement (RACW_Type,
                Condition       =>
                  Make_Op_Eq (Loc,
                    Left_Opnd  => New_Occurrence_Of (Source_Address, Loc),
                    Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
                Then_Statements => Zero_Statements));
         end;

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

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

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

         Remote_Statements := New_List (

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

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

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

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

         Append_List_To (Remote_Statements,
           Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
         --  ??? Issue with asynchronous calls here: the Asynchronous flag is
         --  set on the stub type if, and only if, the RACW type has a pragma
         --  Asynchronous. This is incorrect for RACWs that implement RAS
         --  types, because in that case the /designated subprogram/ (not the
         --  type) might be asynchronous, and that causes the stub to need to
         --  be asynchronous too. A solution is to transport a RAS as a struct
         --  containing a RACW and an asynchronous flag, and to properly alter
         --  the Asynchronous component in the stub type in the RAS's Input
         --  TSS.

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

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

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

         Set_Declarations (Body_Node, Decls);
         Append_To (Body_Decls, Body_Node);
      end Add_RACW_Read_Attribute;

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

      procedure Add_RACW_Write_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         RPC_Receiver     : Node_Id;
         Body_Decls       : List_Id)
      is
         Body_Node : Node_Id;
         Proc_Decl : Node_Id;
         Attr_Decl : Node_Id;

         Statements        : constant List_Id := New_List;
         Local_Statements  : List_Id;
         Remote_Statements : List_Id;
         Null_Statements   : List_Id;

         Pnam : constant Entity_Id := Make_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.

         Local_Statements := New_List (

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

           Pack_Node_Into_Stream_Access (Loc,
             Stream => Stream_Parameter,
             Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
             Etyp   => RTE (RE_Unsigned_64)),

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

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

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

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

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

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

         Null_Statements := New_List (

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

           Pack_Node_Into_Stream_Access (Loc,
             Stream => Stream_Parameter,
             Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
             Etyp   => RTE (RE_Unsigned_64)),

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

         Append_To (Statements,
           Make_Implicit_If_Statement (RACW_Type,
             Condition       =>
               Make_Op_Eq (Loc,
                 Left_Opnd  => Object,
                 Right_Opnd => Make_Null (Loc)),

             Then_Statements => Null_Statements,

             Elsif_Parts     => New_List (
               Make_Elsif_Part (Loc,
                 Condition       =>
                   Make_Op_Eq (Loc,
                     Left_Opnd  =>
                       Make_Attribute_Reference (Loc,
                         Prefix         => Object,
                         Attribute_Name => Name_Tag),

                     Right_Opnd =>
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Stub_Type, Loc),
                         Attribute_Name => Name_Tag)),
                 Then_Statements => Remote_Statements)),
             Else_Statements => Local_Statements));

         Append_To (Body_Decls, Body_Node);
      end Add_RACW_Write_Attribute;

      ------------------------
      -- Add_RAS_Access_TSS --
      ------------------------

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

         Ras_Type : constant Entity_Id := Defining_Identifier (N);
         Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
         --  Ras_Type is the access to subprogram type while Fat_Type is the
         --  corresponding record type.

         RACW_Type : constant Entity_Id :=
                       Underlying_RACW_Type (Ras_Type);
         Desig     : constant Entity_Id :=
                       Etype (Designated_Type (RACW_Type));

         Stub_Elements : constant Stub_Structure :=
                           Stubs_Table.Get (Desig);
         pragma Assert (Stub_Elements /= Empty_Stub_Structure);

         Proc : constant Entity_Id :=
                  Make_Defining_Identifier (Loc,
                    Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));

         Proc_Spec : Node_Id;

         --  Formal parameters

         Package_Name : constant Entity_Id :=
                          Make_Defining_Identifier (Loc,
                            Chars => Name_P);
         --  Target package

         Subp_Id : constant Entity_Id :=
                     Make_Defining_Identifier (Loc,
                       Chars => Name_S);
         --  Target subprogram

         Asynch_P : constant Entity_Id :=
                      Make_Defining_Identifier (Loc,
                        Chars => Name_Asynchronous);
         --  Is the procedure to which the 'Access applies asynchronous?

         All_Calls_Remote : constant Entity_Id :=
                              Make_Defining_Identifier (Loc,
                                Chars => Name_All_Calls_Remote);
         --  True if an All_Calls_Remote pragma applies to the RCI unit
         --  that contains the subprogram.

         --  Common local variables

         Proc_Decls      : List_Id;
         Proc_Statements : List_Id;

         Origin : constant Entity_Id := Make_Temporary (Loc, 'P');

         --  Additional local variables for the local case

         Proxy_Addr : constant Entity_Id := Make_Temporary (Loc, 'P');

         --  Additional local variables for the remote case

         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;
            Value      : Node_Id) return Node_Id;
         --  Construct an assignment that sets the named component in the
         --  returned record

         ---------------
         -- Set_Field --
         ---------------

         function Set_Field
           (Field_Name : Name_Id;
            Value      : Node_Id) return Node_Id
         is
         begin
            return
              Make_Assignment_Statement (Loc,
                Name       =>
                  Make_Selected_Component (Loc,
                    Prefix        => Stub_Ptr,
                    Selector_Name => Field_Name),
                Expression => Value);
         end Set_Field;

      --  Start of processing for Add_RAS_Access_TSS

      begin
         Proc_Decls := New_List (

            --  Common declarations

           Make_Object_Declaration (Loc,
             Defining_Identifier => Origin,
             Constant_Present    => True,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
             Expression          =>
               Make_Function_Call (Loc,
                 Name                   =>
                   New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
                 Parameter_Associations => New_List (
                   New_Occurrence_Of (Package_Name, Loc)))),

            --  Declaration use only in the local case: proxy address

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

            --  Declarations used only in the remote case: stub object and
            --  stub pointer.

           Make_Object_Declaration (Loc,
             Defining_Identifier => Local_Stub,
             Aliased_Present     => True,
             Object_Definition   =>
               New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),

           Make_Object_Declaration (Loc,
             Defining_Identifier =>
               Stub_Ptr,
             Object_Definition   =>
               New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix => New_Occurrence_Of (Local_Stub, Loc),
                 Attribute_Name => Name_Unchecked_Access)));

         Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);

         --  Build_Get_Unique_RP_Call needs above information

         --  Note: Here we assume that the Fat_Type is a record
         --  containing just a pointer to a proxy or stub object.

         Proc_Statements := New_List (

         --  Generate:

         --    Get_RAS_Info (Pkg, Subp, PA);
         --    if Origin = Local_Partition_Id
         --      and then not All_Calls_Remote
         --    then
         --       return Fat_Type!(PA);
         --    end if;

            Make_Procedure_Call_Statement (Loc,
              Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
              Parameter_Associations => New_List (
                New_Occurrence_Of (Package_Name, Loc),
                New_Occurrence_Of (Subp_Id, Loc),
                New_Occurrence_Of (Proxy_Addr, Loc))),

           Make_Implicit_If_Statement (N,
             Condition =>
               Make_And_Then (Loc,
                 Left_Opnd  =>
                   Make_Op_Eq (Loc,
                     Left_Opnd =>
                       New_Occurrence_Of (Origin, Loc),
                     Right_Opnd =>
                       Make_Function_Call (Loc,
                         New_Occurrence_Of (
                           RTE (RE_Get_Local_Partition_Id), Loc))),

                 Right_Opnd =>
                   Make_Op_Not (Loc,
                     New_Occurrence_Of (All_Calls_Remote, Loc))),

             Then_Statements => New_List (
               Make_Simple_Return_Statement (Loc,
                 Unchecked_Convert_To (Fat_Type,
                   OK_Convert_To (RTE (RE_Address),
                     New_Occurrence_Of (Proxy_Addr, Loc)))))),

           Set_Field (Name_Origin,
               New_Occurrence_Of (Origin, Loc)),

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

           Set_Field (Name_Addr, New_Occurrence_Of (Proxy_Addr, Loc)),

            --  E.4.1(9) A remote call is asynchronous if it is a call to
            --  a procedure or a call through a value of an access-to-procedure
            --  type to which a pragma Asynchronous applies.

            --  Asynch_P is true when the procedure is asynchronous;
            --  Asynch_T is true when the type is asynchronous.

           Set_Field (Name_Asynchronous,
             Make_Or_Else (Loc,
               New_Occurrence_Of (Asynch_P, Loc),
               New_Occurrence_Of (Boolean_Literals (
                 Is_Asynchronous (Ras_Type)), Loc))));

         Append_List_To (Proc_Statements,
           Build_Get_Unique_RP_Call
             (Loc, Stub_Ptr, Stub_Elements.Stub_Type));

         --  Return the newly created value

         Append_To (Proc_Statements,
           Make_Simple_Return_Statement (Loc,
             Expression =>
               Unchecked_Convert_To (Fat_Type,
                 New_Occurrence_Of (Stub_Ptr, Loc))));

         Proc_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name       => Proc,
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Package_Name,
                 Parameter_Type      =>
                   New_Occurrence_Of (Standard_String, Loc)),

               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Subp_Id,
                 Parameter_Type      =>
                   New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)),

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

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

            Result_Definition =>
              New_Occurrence_Of (Fat_Type, Loc));

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

         Mutate_Ekind (Proc, E_Function);
         Set_Etype (Proc, Fat_Type);

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

         Set_TSS (Fat_Type, Proc);
      end Add_RAS_Access_TSS;

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

      procedure Add_RAST_Features
        (Vis_Decl : Node_Id;
         RAS_Type : Entity_Id)
      is
         pragma Unreferenced (RAS_Type);
      begin
         Add_RAS_Access_TSS (Vis_Decl);
      end Add_RAST_Features;

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

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

         Request_Parameter : Node_Id;

         Pkg_RPC_Receiver            : constant Entity_Id :=
                                         Make_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      : 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_Subp_Number : Int := First_RCI_Subprogram_Id;
         Current_Stubs       : Node_Id;

         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;

         All_Calls_Remote_E  : Entity_Id;
         Proxy_Object_Addr   : Entity_Id;

         procedure Append_Stubs_To
           (RPC_Receiver_Cases : List_Id;
            Stubs              : Node_Id;
            Subprogram_Number  : Int);
         --  Add one case to the specified RPC receiver case list
         --  associating Subprogram_Number with the subprogram declared
         --  by Declaration, for which we have receiving stubs in Stubs.

         procedure Visit_Subprogram (Decl : Node_Id);
         --  Generate receiving stub for one remote subprogram

         ---------------------
         -- Append_Stubs_To --
         ---------------------

         procedure Append_Stubs_To
           (RPC_Receiver_Cases : List_Id;
            Stubs              : Node_Id;
            Subprogram_Number  : Int)
         is
         begin
            Append_To (RPC_Receiver_Cases,
              Make_Case_Statement_Alternative (Loc,
                Discrete_Choices =>
                   New_List (Make_Integer_Literal (Loc, Subprogram_Number)),
                Statements       =>
                  New_List (
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of (Defining_Entity (Stubs), Loc),
                      Parameter_Associations => New_List (
                        New_Occurrence_Of (Request_Parameter, Loc))))));
         end Append_Stubs_To;

         ----------------------
         -- 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
            --  Disable expansion of stubs if serious errors have been
            --  diagnosed, because otherwise some illegal remote subprogram
            --  declarations could cause cascaded errors in stubs.

            if Serious_Errors_Detected /= 0 then
               return;
            end if;

            --  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
         --  Building receiving stubs consist in several operations:

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

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

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

         Build_RPC_Receiver_Body (
           RPC_Receiver => Pkg_RPC_Receiver,
           Request      => Request_Parameter,
           Subp_Id      => Subp_Id,
           Subp_Index   => Subp_Index,
           Stmts        => Pkg_RPC_Receiver_Statements,
           Decl         => Pkg_RPC_Receiver_Body);
         pragma Assert (Subp_Id = Subp_Index);

         --  A null subp_id denotes a call through a RAS, in which case the
         --  next Uint_64 element in the stream is the address of the local
         --  proxy object, from which we can retrieve the actual subprogram id.

         Append_To (Pkg_RPC_Receiver_Statements,
           Make_Implicit_If_Statement (Pkg_Spec,
             Condition =>
               Make_Op_Eq (Loc,
                 New_Occurrence_Of (Subp_Id, Loc),
                 Make_Integer_Literal (Loc, 0)),

             Then_Statements => New_List (
               Make_Assignment_Statement (Loc,
                 Name =>
                   New_Occurrence_Of (Subp_Id, Loc),

                 Expression =>
                   Make_Selected_Component (Loc,
                     Prefix =>
                       Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
                         OK_Convert_To (RTE (RE_Address),
                           Make_Attribute_Reference (Loc,
                             Prefix =>
                               New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
                             Attribute_Name =>
                               Name_Input,
                             Expressions => New_List (
                               Make_Selected_Component (Loc,
                                 Prefix        => Request_Parameter,
                                 Selector_Name => Name_Params))))),

                     Selector_Name => Make_Identifier (Loc, Name_Subp_Id))))));

         --  Build a subprogram for RAS information lookups

         Lookup_RAS :=
           Make_Subprogram_Declaration (Loc,
             Specification =>
               Make_Function_Specification (Loc,
                 Defining_Unit_Name =>
                   Lookup_RAS_Info,
                 Parameter_Specifications => New_List (
                   Make_Parameter_Specification (Loc,
                     Defining_Identifier =>
                       Make_Defining_Identifier (Loc, Name_Subp_Id),
                     In_Present =>
                       True,
                     Parameter_Type =>
                       New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
                 Result_Definition =>
                   New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
         Append_To (Decls, Lookup_RAS);
         Analyze (Lookup_RAS);

         Current_Stubs := Build_Subprogram_Receiving_Stubs
           (Vis_Decl     => Lookup_RAS,
            Asynchronous => False);
         Append_To (Decls, Current_Stubs);
         Analyze (Current_Stubs);

         Append_Stubs_To (Pkg_RPC_Receiver_Cases,
           Stubs             => Current_Stubs,
           Subprogram_Number => 1);

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

         All_Calls_Remote_E :=
           Boolean_Literals
             (Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));

         Overload_Counter_Table.Reset;

         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
         --  to crash a remote partition by sending invalid subprogram ids.
         --  This is consistent with the other parts of the case statement
         --  since even in presence of incorrect parameters in the stream,
         --  every exception will be caught and (if the subprogram is not an
         --  APC) put into the result stream and sent away.

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

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

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Info_Array,
             Constant_Present    => True,
             Aliased_Present     => True,
             Object_Definition   =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark =>
                   New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
                 Constraint =>
                   Make_Index_Or_Discriminant_Constraint (Loc,
                     New_List (
                       Make_Range (Loc,
                         Low_Bound  => Make_Integer_Literal (Loc,
                           First_RCI_Subprogram_Id),
                         High_Bound =>
                           Make_Integer_Literal (Loc,
                             Intval =>
                               First_RCI_Subprogram_Id
                               + List_Length (Subp_Info_List) - 1)))))));

         --  For a degenerate RCI with no visible subprograms, Subp_Info_List
         --  has zero length, and the declaration is for an empty array, in
         --  which case no initialization aggregate must be generated.

         if Present (First (Subp_Info_List)) then
            Set_Expression (Last (Decls),
              Make_Aggregate (Loc,
                Component_Associations => Subp_Info_List));

         --  No initialization provided: remove CONSTANT so that the
         --  declaration is not an incomplete deferred constant.

         else
            Set_Constant_Present (Last (Decls), False);
         end if;

         Analyze (Last (Decls));

         declare
            Subp_Info_Addr : Node_Id;
            --  Return statement for Lookup_RAS_Info: address of the subprogram
            --  information record for the requested subprogram id.

         begin
            if Present (First (Subp_Info_List)) then
               Subp_Info_Addr :=
                 Make_Selected_Component (Loc,
                   Prefix =>
                     Make_Indexed_Component (Loc,
                       Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
                       Expressions => New_List (
                         Convert_To (Standard_Integer,
                           Make_Identifier (Loc, Name_Subp_Id)))),
                   Selector_Name => Make_Identifier (Loc, Name_Addr));

            --  Case of no visible subprogram: just raise Constraint_Error, we
            --  know for sure we got junk from a remote partition.

            else
               Subp_Info_Addr :=
                 Make_Raise_Constraint_Error (Loc,
                    Reason => CE_Range_Check_Failed);
               Set_Etype (Subp_Info_Addr, RTE (RE_Unsigned_64));
            end if;

            Append_To (Decls,
              Make_Subprogram_Body (Loc,
                Specification =>
                  Copy_Specification (Loc, Parent (Lookup_RAS_Info)),
                Declarations  => No_List,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => New_List (
                      Make_Simple_Return_Statement (Loc,
                        Expression =>
                          OK_Convert_To
                            (RTE (RE_Unsigned_64), Subp_Info_Addr))))));
         end;

         Analyze (Last (Decls));

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

         --  Name

         Append_To (Register_Pkg_Actuals,
           Make_String_Literal (Loc,
             Strval =>
               Fully_Qualified_Name_String
                 (Defining_Entity (Pkg_Spec), Append_NUL => False)));

         --  Receiver

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
             Attribute_Name => Name_Unrestricted_Access));

         --  Version

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
             Attribute_Name => Name_Version));

         --  Subp_Info

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
             Attribute_Name => Name_Address));

         --  Subp_Info_Len

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
             Attribute_Name => Name_Length));

         --  Generate the call

         Append_To (Stmts,
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
             Parameter_Associations => Register_Pkg_Actuals));
         Analyze (Last (Stmts));
      end Add_Receiving_Stubs_To_Declarations;

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

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

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

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

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

         Current_Parameter : Node_Id;
         --  Current parameter being handled

         Ordered_Parameters_List : constant List_Id :=
                                     Build_Ordered_Parameters_List (Spec);

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

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

         pragma Unreferenced (RACW_Type);
         --  Used only for the PolyORB case

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

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

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

         Stream_Parameter := Make_Temporary (Loc, 'S');

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

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

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

            Exception_Return_Parameter := Make_Temporary (Loc, 'E');

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

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

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

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

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

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

         Current_Parameter := First (Ordered_Parameters_List);
         while Present (Current_Parameter) loop
            declare
               Typ             : constant Node_Id :=
                                   Parameter_Type (Current_Parameter);
               Etyp            : Entity_Id;
               Constrained     : Boolean;
               Value           : Node_Id;
               Extra_Parameter : Entity_Id;

            begin
               if Is_RACW_Controlling_Formal
                    (Current_Parameter, Stub_Type)
               then
                  --  In the case of a controlling formal argument, we marshall
                  --  its addr field rather than the local stub.

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

               else
                  Value :=
                    New_Occurrence_Of
                      (Defining_Identifier (Current_Parameter), Loc);

                  --  Access type parameters are transmitted as in out
                  --  parameters. However, a dereference is needed so that
                  --  we marshall the designated object.

                  if Nkind (Typ) = N_Access_Definition then
                     Value := Make_Explicit_Dereference (Loc, Value);
                     Etyp  := Etype (Subtype_Mark (Typ));
                  else
                     Etyp := Etype (Typ);
                  end if;

                  Constrained := not Transmit_As_Unconstrained (Etyp);

                  --  Any parameter but unconstrained out parameters are
                  --  transmitted to the peer.

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

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

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

                  Extra_Parameter := Make_Temporary (Loc, 'P');

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

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

               Next (Current_Parameter);
            end;
         end loop;

         --  Append the formal statements list to the statements

         Append_List_To (Statements, Extra_Formal_Statements);

         if not Is_Known_Non_Asynchronous then

            --  Build the call to System.RPC.Do_APC

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

         if not Is_Known_Asynchronous then

            --  Build the call to System.RPC.Do_RPC

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

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

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

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

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

                Attribute_Name => Name_Read,

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

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

            if Is_Function then

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

               Append_To (Non_Asynchronous_Statements,
                 Make_Tag_Check (Loc,
                   Make_Simple_Return_Statement (Loc,
                     Expression =>
                       Make_Attribute_Reference (Loc,
                         Prefix         =>
                           New_Occurrence_Of (
                             Etype (Result_Definition (Spec)), Loc),

                         Attribute_Name => Name_Input,

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

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

               Current_Parameter := First (Ordered_Parameters_List);
               while Present (Current_Parameter) loop
                  declare
                     Typ   : constant Node_Id :=
                               Parameter_Type (Current_Parameter);
                     Etyp  : Entity_Id;
                     Value : Node_Id;

                  begin
                     Value :=
                       New_Occurrence_Of
                         (Defining_Identifier (Current_Parameter), Loc);

                     if Nkind (Typ) = N_Access_Definition then
                        Value := Make_Explicit_Dereference (Loc, Value);
                        Etyp  := Etype (Subtype_Mark (Typ));
                     else
                        Etyp := Etype (Typ);
                     end if;

                     if (Out_Present (Current_Parameter)
                          or else Nkind (Typ) = N_Access_Definition)
                       and then Etyp /= Stub_Type
                     then
                        Append_To (Non_Asynchronous_Statements,
                           Make_Attribute_Reference (Loc,
                             Prefix         =>
                               New_Occurrence_Of (Etyp, Loc),

                             Attribute_Name => Name_Read,

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

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

         if Is_Known_Asynchronous then
            Append_List_To (Statements, Asynchronous_Statements);

         elsif Is_Known_Non_Asynchronous then
            Append_List_To (Statements, Non_Asynchronous_Statements);

         else
            pragma Assert (Present (Asynchronous));
            Prepend_To (Asynchronous_Statements,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Standard_Boolean, Loc),
                Attribute_Name => Name_Write,
                Expressions    => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                      New_Occurrence_Of (Stream_Parameter, Loc),
                    Attribute_Name => Name_Access),
                  New_Occurrence_Of (Standard_True, Loc))));

            Prepend_To (Non_Asynchronous_Statements,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Standard_Boolean, Loc),
                Attribute_Name => Name_Write,
                Expressions    => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                      New_Occurrence_Of (Stream_Parameter, Loc),
                    Attribute_Name => Name_Access),
                  New_Occurrence_Of (Standard_False, Loc))));

            Append_To (Statements,
              Make_Implicit_If_Statement (Nod,
                Condition       => Asynchronous,
                Then_Statements => Asynchronous_Statements,
                Else_Statements => Non_Asynchronous_Statements));
         end if;
      end Build_General_Calling_Stubs;

      -----------------------------
      -- Build_RPC_Receiver_Body --
      -----------------------------

      procedure Build_RPC_Receiver_Body
        (RPC_Receiver : Entity_Id;
         Request      : out Entity_Id;
         Subp_Id      : out Entity_Id;
         Subp_Index   : out Entity_Id;
         Stmts        : out List_Id;
         Decl         : out Node_Id)
      is
         Loc : constant Source_Ptr := Sloc (RPC_Receiver);

         RPC_Receiver_Spec  : Node_Id;
         RPC_Receiver_Decls : List_Id;

      begin
         Request := Make_Defining_Identifier (Loc, Name_R);

         RPC_Receiver_Spec :=
           Build_RPC_Receiver_Specification
             (RPC_Receiver      => RPC_Receiver,
              Request_Parameter => Request);

         Subp_Id    := Make_Temporary (Loc, 'P');
         Subp_Index := Subp_Id;

         --  Subp_Id may not be a constant, because in the case of the RPC
         --  receiver for an RCI package, when a call is received from a RAS
         --  dereference, it will be assigned during subsequent processing.

         RPC_Receiver_Decls := New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Id,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix          =>
                   New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
                 Attribute_Name  => Name_Input,
                 Expressions     => New_List (
                   Make_Selected_Component (Loc,
                     Prefix        => Request,
                     Selector_Name => Name_Params)))));

         Stmts := New_List;

         Decl :=
           Make_Subprogram_Body (Loc,
             Specification              => RPC_Receiver_Spec,
             Declarations               => RPC_Receiver_Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Stmts));
      end Build_RPC_Receiver_Body;

      -----------------------
      -- Build_Stub_Target --
      -----------------------

      function Build_Stub_Target
        (Loc                   : Source_Ptr;
         Decls                 : List_Id;
         RCI_Locator           : Entity_Id;
         Controlling_Parameter : Entity_Id) return RPC_Target
      is
         Target_Info : RPC_Target (PCS_Kind => Name_GARLIC_DSA);

      begin
         Target_Info.Partition := Make_Temporary (Loc, 'P');

         if Present (Controlling_Parameter) then
            Append_To (Decls,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Target_Info.Partition,
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Partition_ID), Loc),

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

            Target_Info.RPC_Receiver :=
              Make_Selected_Component (Loc,
                Prefix        => Controlling_Parameter,
                Selector_Name => Name_Receiver);

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

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

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

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

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

         Request_Parameter : constant Entity_Id := Make_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
         --  subprograms. Also the out parameters will be declared.

         Statements : constant List_Id := New_List;

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

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

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

         Excep_Handlers : List_Id := No_List;
         Excep_Choice   : Entity_Id;
         Excep_Code     : List_Id;

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

         Current_Parameter : Node_Id;

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

         Subp_Spec : Node_Id;
         --  Subprogram specification

         Called_Subprogram : Node_Id;
         --  The subprogram to call

         Null_Raise_Statement : Node_Id;

         Dynamic_Async : Entity_Id;

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

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

         if not Asynchronous or Dynamically_Asynchronous then

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

            Null_Raise_Statement :=
              Make_Attribute_Reference (Loc,
                Prefix         =>
                  New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
                Attribute_Name => Name_Write,
                Expressions    => New_List (
                  Make_Selected_Component (Loc,
                    Prefix        => Request_Parameter,
                    Selector_Name => Name_Result),
                  New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));

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

            Append_To (After_Statements, Null_Raise_Statement);
         end if;

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

         Current_Parameter := First (Ordered_Parameters_List);
         while Present (Current_Parameter) loop
            declare
               Etyp        : Entity_Id;
               Constrained : Boolean;

               Need_Extra_Constrained : Boolean;
               --  True when an Extra_Constrained actual is required

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

               Expr : Node_Id := Empty;

               Is_Controlling_Formal : constant Boolean :=
                                         Is_RACW_Controlling_Formal
                                           (Current_Parameter, Stub_Type);

            begin
               if Is_Controlling_Formal then

                  --  We have a controlling formal parameter. Read its address
                  --  rather than a real object. The address is in Unsigned_64
                  --  form.

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

               Constrained := not Transmit_As_Unconstrained (Etyp);

               if In_Present (Current_Parameter)
                 or else not Out_Present (Current_Parameter)
                 or else not Constrained
                 or else Is_Controlling_Formal
               then
                  --  If an input parameter is constrained, then the read of
                  --  the parameter is deferred until the beginning of the
                  --  subprogram body. If it is unconstrained, then an
                  --  expression is built for the object declaration and the
                  --  variable is set using 'Input instead of 'Read. Note that
                  --  this deferral does not change the order in which the
                  --  actuals are read because Build_Ordered_Parameter_List
                  --  puts them unconstrained first.

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

                  else

                     --  Build and append Input_With_Tag_Check function

                     Append_To (Decls,
                       Input_With_Tag_Check (Loc,
                         Var_Type => Etyp,
                         Stream   =>
                           Make_Selected_Component (Loc,
                             Prefix        => Request_Parameter,
                             Selector_Name => Name_Params)));

                     --  Prepare function call expression

                     Expr :=
                       Make_Function_Call (Loc,
                         Name =>
                           New_Occurrence_Of
                             (Defining_Unit_Name
                               (Specification (Last (Decls))), Loc));
                  end if;
               end if;

               Need_Extra_Constrained :=
                 Nkind (Parameter_Type (Current_Parameter)) /=
                                                        N_Access_Definition
                   and then
                     Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
                   and then
                      Present (Extra_Constrained
                                (Defining_Identifier (Current_Parameter)));

               --  We may not associate an extra constrained actual to a
               --  constant object, so if one is needed, declare the actual
               --  as a variable even if it won't be modified.

               Build_Actual_Object_Declaration
                 (Object   => Object,
                  Etyp     => Etyp,
                  Variable => Need_Extra_Constrained
                                or else Out_Present (Current_Parameter),
                  Expr     => Expr,
                  Decls    => Decls);

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

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

               --  For RACW controlling formals, the Etyp of Object is always
               --  an RACW, even if the parameter is not of an anonymous access
               --  type. In such case, we need to dereference it at call time.

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

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

               else
                  Append_To (Parameter_List,
                    Make_Parameter_Association (Loc,
                      Selector_Name             =>
                        New_Occurrence_Of (
                          Defining_Identifier (Current_Parameter), Loc),
                      Explicit_Actual_Parameter =>
                        New_Occurrence_Of (Object, Loc)));
               end if;

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

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

               if Need_Extra_Constrained then
                  declare
                     Extra_Parameter : constant Entity_Id :=
                                         Extra_Constrained
                                           (Defining_Identifier
                                             (Current_Parameter));

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

                     Formal_Type : constant Entity_Id :=
                                     Etype (Extra_Parameter);

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

                     Append_To (Extra_Formal_Statements,
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (
                                             Formal_Type, Loc),
                         Attribute_Name => Name_Read,
                         Expressions    => New_List (
                           Make_Selected_Component (Loc,
                             Prefix        => Request_Parameter,
                             Selector_Name => Name_Params),
                           New_Occurrence_Of (Formal_Entity, Loc))));

                     --  Note: the call to Set_Extra_Constrained below relies
                     --  on the fact that Object's Ekind has been set by
                     --  Build_Actual_Object_Declaration.

                     Set_Extra_Constrained (Object, Formal_Entity);
                  end;
               end if;
            end;

            Next (Current_Parameter);
         end loop;

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

         Append_List_To (Statements, Extra_Formal_Statements);

         if Nkind (Specification (Vis_Decl)) = N_Function_Specification then

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

            declare
               Etyp   : constant Entity_Id :=
                          Etype (Result_Definition (Specification (Vis_Decl)));
               Result : constant Node_Id   := Make_Temporary (Loc, 'R');

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

               if Is_Class_Wide_Type (Etyp) then

                  --  For a remote call to a function with a class-wide type,
                  --  check that the returned value satisfies the requirements
                  --  of E.4(18).

                  Append_To (Inner_Decls,
                    Make_Transportable_Check (Loc,
                      New_Occurrence_Of (Result, Loc)));

               end if;

               Append_To (After_Statements,
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Occurrence_Of (Etyp, Loc),
                   Attribute_Name => Name_Output,
                   Expressions    => New_List (
                     Make_Selected_Component (Loc,
                       Prefix        => Request_Parameter,
                       Selector_Name => Name_Result),
                     New_Occurrence_Of (Result, Loc))));
            end;

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

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

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

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

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

            Append_List_To (Statements, After_Statements);
         end if;

         if Asynchronous and then not Dynamically_Asynchronous then

            --  For an asynchronous procedure, add a null exception handler

            Excep_Handlers := New_List (
              Make_Implicit_Exception_Handler (Loc,
                Exception_Choices => New_List (Make_Others_Choice (Loc)),
                Statements        => New_List (Make_Null_Statement (Loc))));

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

            Excep_Choice := Make_Temporary (Loc, 'E');

            Excep_Code := New_List (
              Make_Attribute_Reference (Loc,
                Prefix         =>
                  New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
                Attribute_Name => Name_Write,
                Expressions    => New_List (
                                    Make_Selected_Component (Loc,
                                      Prefix        => Request_Parameter,
                                      Selector_Name => Name_Result),
                                    New_Occurrence_Of (Excep_Choice, Loc))));

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

            Excep_Handlers := New_List (
              Make_Implicit_Exception_Handler (Loc,
                Choice_Parameter   => Excep_Choice,
                Exception_Choices  => New_List (Make_Others_Choice (Loc)),
                Statements         => Excep_Code));

         end if;

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

             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Request_Parameter,
                 Parameter_Type      =>
                   New_Occurrence_Of (RTE (RE_Request_Access), Loc))));

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

      ------------
      -- Result --
      ------------

      function Result return Node_Id is
      begin
         return Make_Identifier (Loc, Name_V);
      end Result;

      -----------------------
      -- RPC_Receiver_Decl --
      -----------------------

      function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id is
         Loc    : constant Source_Ptr := Sloc (RACW_Type);
         Is_RAS : constant Boolean    := not Comes_From_Source (RACW_Type);

      begin
         --  No RPC receiver for remote access-to-subprogram

         if Is_RAS then
            return Empty;
         end if;

         return
           Make_Subprogram_Declaration (Loc,
             Build_RPC_Receiver_Specification
               (RPC_Receiver      => Make_Temporary (Loc, 'R'),
                Request_Parameter => Make_Defining_Identifier (Loc, Name_R)));
      end RPC_Receiver_Decl;

      ----------------------
      -- Stream_Parameter --
      ----------------------

      function Stream_Parameter return Node_Id is
      begin
         return Make_Identifier (Loc, Name_S);
      end Stream_Parameter;

   end GARLIC_Support;

   -------------------------------
   -- Get_And_Reset_RACW_Bodies --
   -------------------------------

   function Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id is
      Desig         : constant Entity_Id :=
                        Etype (Designated_Type (RACW_Type));

      Stub_Elements : Stub_Structure := Stubs_Table.Get (Desig);

      Body_Decls : List_Id;
      --  Returned list of declarations

   begin
      if Stub_Elements = Empty_Stub_Structure then

         --  Stub elements may be missing as a consequence of a previously
         --  detected error.

         return No_List;
      end if;

      Body_Decls := Stub_Elements.Body_Decls;
      Stub_Elements.Body_Decls := No_List;
      Stubs_Table.Set (Desig, Stub_Elements);
      return Body_Decls;
   end Get_And_Reset_RACW_Bodies;

   -----------------------
   -- Get_Stub_Elements --
   -----------------------

   function Get_Stub_Elements (RACW_Type : Entity_Id) return Stub_Structure is
      Desig         : constant Entity_Id :=
                        Etype (Designated_Type (RACW_Type));
      Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
   begin
      pragma Assert (Stub_Elements /= Empty_Stub_Structure);
      return Stub_Elements;
   end Get_Stub_Elements;

   -----------------------
   -- Get_Subprogram_Id --
   -----------------------

   function Get_Subprogram_Id (Def : Entity_Id) return String_Id is
      Result : constant String_Id := Get_Subprogram_Ids (Def).Str_Identifier;
   begin
      pragma Assert (Result /= No_String);
      return Result;
   end Get_Subprogram_Id;

   -----------------------
   -- Get_Subprogram_Id --
   -----------------------

   function Get_Subprogram_Id (Def : Entity_Id) return Int is
   begin
      return Get_Subprogram_Ids (Def).Int_Identifier;
   end Get_Subprogram_Id;

   ------------------------
   -- Get_Subprogram_Ids --
   ------------------------

   function Get_Subprogram_Ids
     (Def : Entity_Id) return Subprogram_Identifiers
   is
   begin
      return Subprogram_Identifier_Table.Get (Def);
   end Get_Subprogram_Ids;

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

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

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

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

   function Input_With_Tag_Check
     (Loc      : Source_Ptr;
      Var_Type : Entity_Id;
      Stream   : Node_Id) return Node_Id
   is
   begin
      return
        Make_Subprogram_Body (Loc,
          Specification              =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name => Make_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_Simple_Return_Statement (Loc,
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Occurrence_Of (Var_Type, Loc),
                    Attribute_Name => Name_Input,
                    Expressions    =>
                      New_List (Stream)))))));
   end Input_With_Tag_Check;

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

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

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

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

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

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

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

   ------------------------------
   -- Make_Transportable_Check --
   ------------------------------

   function Make_Transportable_Check
     (Loc  : Source_Ptr;
      Expr : Node_Id) return Node_Id is
   begin
      return
        Make_Raise_Program_Error (Loc,
          Condition       =>
            Make_Op_Not (Loc,
              Build_Get_Transportable (Loc,
                Make_Selected_Component (Loc,
                  Prefix        => Expr,
                  Selector_Name => Make_Identifier (Loc, Name_uTag)))),
          Reason => PE_Non_Transportable_Actual);
   end Make_Transportable_Check;

   -----------------------------
   -- Make_Selected_Component --
   -----------------------------

   function Make_Selected_Component
     (Loc           : Source_Ptr;
      Prefix        : Entity_Id;
      Selector_Name : Name_Id) return Node_Id
   is
   begin
      return Make_Selected_Component (Loc,
               Prefix        => New_Occurrence_Of (Prefix, Loc),
               Selector_Name => Make_Identifier (Loc, Selector_Name));
   end Make_Selected_Component;

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

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

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

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

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

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

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

   function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
      Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
   begin
      return Out_Present (Parameter)
        and then Has_Discriminants (Etyp)
        and then not Is_Constrained (Etyp)
        and then Is_Definite_Subtype (Etyp);
   end Need_Extra_Constrained;

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

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

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

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

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

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

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

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

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

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

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

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

   ---------------------
   -- PolyORB_Support --
   ---------------------

   package body PolyORB_Support is

      --  Local subprograms

      procedure Add_RACW_Read_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         Body_Decls       : List_Id);
      --  Add Read attribute for the RACW type. The declaration and attribute
      --  definition clauses are inserted right after the declaration of
      --  RACW_Type. If Body_Decls is not No_List, the subprogram body is
      --  appended to it (case where the RACW declaration is in the main unit).

      procedure Add_RACW_Write_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         Body_Decls       : List_Id);
      --  Same as above for the Write attribute

      procedure Add_RACW_From_Any
        (RACW_Type        : Entity_Id;
         Body_Decls       : List_Id);
      --  Add the From_Any TSS for this RACW type

      procedure Add_RACW_To_Any
        (RACW_Type        : Entity_Id;
         Body_Decls       : List_Id);
      --  Add the To_Any TSS for this RACW type

      procedure Add_RACW_TypeCode
        (Designated_Type : Entity_Id;
         RACW_Type       : Entity_Id;
         Body_Decls      : List_Id);
      --  Add the TypeCode TSS for this RACW type

      procedure Add_RAS_From_Any (RAS_Type : Entity_Id);
      --  Add the From_Any TSS for this RAS type

      procedure Add_RAS_To_Any   (RAS_Type : Entity_Id);
      --  Add the To_Any TSS for this RAS type

      procedure Add_RAS_TypeCode (RAS_Type : Entity_Id);
      --  Add the TypeCode TSS for this RAS type

      procedure Add_RAS_Access_TSS (N : Node_Id);
      --  Add a subprogram body for RAS Access TSS

      -------------------------------------
      -- Add_Obj_RPC_Receiver_Completion --
      -------------------------------------

      procedure Add_Obj_RPC_Receiver_Completion
        (Loc           : Source_Ptr;
         Decls         : List_Id;
         RPC_Receiver  : Entity_Id;
         Stub_Elements : Stub_Structure)
      is
         Desig : constant Entity_Id :=
           Etype (Designated_Type (Stub_Elements.RACW_Type));
      begin
         Append_To (Decls,
           Make_Procedure_Call_Statement (Loc,
              Name =>
                New_Occurrence_Of (
                  RTE (RE_Register_Obj_Receiving_Stub), Loc),

                Parameter_Associations => New_List (

               --  Name

                Make_String_Literal (Loc,
                  Fully_Qualified_Name_String (Desig, Append_NUL => False)),

               --  Handler

                Make_Attribute_Reference (Loc,
                  Prefix =>
                    New_Occurrence_Of (
                      Defining_Unit_Name (Parent (RPC_Receiver)), Loc),
                  Attribute_Name =>
                    Name_Access),

               --  Receiver

                Make_Attribute_Reference (Loc,
                  Prefix =>
                    New_Occurrence_Of (
                      Defining_Identifier (
                        Stub_Elements.RPC_Receiver_Decl), Loc),
                  Attribute_Name =>
                    Name_Access))));
      end Add_Obj_RPC_Receiver_Completion;

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

      procedure Add_RACW_Features
        (RACW_Type         : Entity_Id;
         Desig             : Entity_Id;
         Stub_Type         : Entity_Id;
         Stub_Type_Access  : Entity_Id;
         RPC_Receiver_Decl : Node_Id;
         Body_Decls        : List_Id)
      is
         pragma Unreferenced (RPC_Receiver_Decl);

      begin
         Add_RACW_From_Any
           (RACW_Type           => RACW_Type,
            Body_Decls          => Body_Decls);

         Add_RACW_To_Any
           (RACW_Type           => RACW_Type,
            Body_Decls          => Body_Decls);

         Add_RACW_Write_Attribute
           (RACW_Type           => RACW_Type,
            Stub_Type           => Stub_Type,
            Stub_Type_Access    => Stub_Type_Access,
            Body_Decls          => Body_Decls);

         Add_RACW_Read_Attribute
           (RACW_Type           => RACW_Type,
            Stub_Type           => Stub_Type,
            Stub_Type_Access    => Stub_Type_Access,
            Body_Decls          => Body_Decls);

         Add_RACW_TypeCode
           (Designated_Type     => Desig,
            RACW_Type           => RACW_Type,
            Body_Decls          => Body_Decls);
      end Add_RACW_Features;

      -----------------------
      -- Add_RACW_From_Any --
      -----------------------

      procedure Add_RACW_From_Any
        (RACW_Type        : Entity_Id;
         Body_Decls       : List_Id)
      is
         Loc    : constant Source_Ptr := Sloc (RACW_Type);
         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
         Fnam   : constant Entity_Id :=
                    Make_Defining_Identifier (Loc,
                      Chars => New_External_Name (Chars (RACW_Type), 'F'));

         Func_Spec : Node_Id;
         Func_Decl : Node_Id;
         Func_Body : Node_Id;

         Statements       : List_Id;
         --  Various parts of the subprogram

         Any_Parameter : constant Entity_Id :=
                           Make_Defining_Identifier (Loc, Name_A);

         Asynchronous_Flag : constant Entity_Id :=
                               Asynchronous_Flags_Table.Get (RACW_Type);
         --  The flag object declared in Add_RACW_Asynchronous_Flag

      begin
         Func_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name =>
               Fnam,
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier =>
                   Any_Parameter,
                 Parameter_Type =>
                   New_Occurrence_Of (RTE (RE_Any), Loc))),
             Result_Definition => New_Occurrence_Of (RACW_Type, Loc));

         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
         --  entity in the declaration spec, not those of the body spec.

         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
         Set_Renaming_TSS (RACW_Type, Fnam, TSS_From_Any);

         if No (Body_Decls) then
            return;
         end if;

         --  ??? Issue with asynchronous calls here: the Asynchronous flag is
         --  set on the stub type if, and only if, the RACW type has a pragma
         --  Asynchronous. This is incorrect for RACWs that implement RAS
         --  types, because in that case the /designated subprogram/ (not the
         --  type) might be asynchronous, and that causes the stub to need to
         --  be asynchronous too. A solution is to transport a RAS as a struct
         --  containing a RACW and an asynchronous flag, and to properly alter
         --  the Asynchronous component in the stub type in the RAS's _From_Any
         --  TSS.

         Statements := New_List (
           Make_Simple_Return_Statement (Loc,
             Expression => Unchecked_Convert_To (RACW_Type,
               Make_Function_Call (Loc,
                 Name => New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
                 Parameter_Associations => New_List (
                   Make_Function_Call (Loc,
                     Name => New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
                     Parameter_Associations => New_List (
                       New_Occurrence_Of (Any_Parameter, Loc))),
                   Build_Stub_Tag (Loc, RACW_Type),
                   New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
                   New_Occurrence_Of (Asynchronous_Flag, Loc))))));

         Func_Body :=
           Make_Subprogram_Body (Loc,
             Specification => Copy_Specification (Loc, Func_Spec),
             Declarations  => No_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Statements));

         Append_To (Body_Decls, Func_Body);
      end Add_RACW_From_Any;

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

      procedure Add_RACW_Read_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         Body_Decls       : List_Id)
      is
         pragma Unreferenced (Stub_Type, Stub_Type_Access);

         Loc : constant Source_Ptr := Sloc (RACW_Type);

         Proc_Decl : Node_Id;
         Attr_Decl : Node_Id;

         Body_Node : Node_Id;

         Decls      : constant List_Id   := New_List;
         Statements : constant List_Id   := New_List;
         Reference  : constant Entity_Id :=
                        Make_Defining_Identifier (Loc, Name_R);
         --  Various parts of the procedure

         Pnam : constant Entity_Id := Make_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

         ------------
         -- Result --
         ------------

         function Result return Node_Id is
         begin
            return Make_Identifier (Loc, Name_V);
         end Result;

         ----------------------
         -- Stream_Parameter --
         ----------------------

         function Stream_Parameter return Node_Id is
         begin
            return Make_Identifier (Loc, Name_S);
         end Stream_Parameter;

      --  Start of processing for Add_RACW_Read_Attribute

      begin
         Build_Stream_Procedure
           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => True);

         Proc_Decl := Make_Subprogram_Declaration (Loc,
           Copy_Specification (Loc, Specification (Body_Node)));

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

         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
         Insert_After (Proc_Decl, Attr_Decl);

         if No (Body_Decls) then
            return;
         end if;

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier =>
               Reference,
             Object_Definition =>
               New_Occurrence_Of (RTE (RE_Object_Ref), Loc)));

         Append_List_To (Statements, New_List (
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
             Attribute_Name => Name_Read,
             Expressions    => New_List (
               Stream_Parameter,
               New_Occurrence_Of (Reference, Loc))),

           Make_Assignment_Statement (Loc,
             Name       =>
               Result,
             Expression =>
               Unchecked_Convert_To (RACW_Type,
                 Make_Function_Call (Loc,
                   Name                   =>
                     New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
                   Parameter_Associations => New_List (
                     New_Occurrence_Of (Reference, Loc),
                     Build_Stub_Tag (Loc, RACW_Type),
                     New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
                     New_Occurrence_Of (Asynchronous_Flag, Loc)))))));

         Set_Declarations (Body_Node, Decls);
         Append_To (Body_Decls, Body_Node);
      end Add_RACW_Read_Attribute;

      ---------------------
      -- Add_RACW_To_Any --
      ---------------------

      procedure Add_RACW_To_Any
        (RACW_Type        : Entity_Id;
         Body_Decls       : List_Id)
      is
         Loc : constant Source_Ptr := Sloc (RACW_Type);

         Fnam : constant Entity_Id :=
                  Make_Defining_Identifier (Loc,
                    Chars => New_External_Name (Chars (RACW_Type), 'T'));

         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);

         Stub_Elements : constant Stub_Structure :=
                           Get_Stub_Elements (RACW_Type);

         Func_Spec : Node_Id;
         Func_Decl : Node_Id;
         Func_Body : Node_Id;

         Decls      : List_Id;
         Statements : List_Id;
         --  Various parts of the subprogram

         RACW_Parameter : constant Entity_Id :=
                            Make_Defining_Identifier (Loc, Name_R);

         Reference : constant Entity_Id := Make_Temporary (Loc, 'R');
         Any       : constant Entity_Id := Make_Temporary (Loc, 'A');

      begin
         Func_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name =>
               Fnam,
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier =>
                   RACW_Parameter,
                 Parameter_Type =>
                   New_Occurrence_Of (RACW_Type, Loc))),
             Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));

         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
         --  entity in the declaration spec, not in the body spec.

         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);

         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
         Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any);

         if No (Body_Decls) then
            return;
         end if;

         --  Generate:

         --    R : constant Object_Ref :=
         --          Get_Reference
         --            (Address!(RACW),
         --             "typ",
         --             Stub_Type'Tag,
         --             Is_RAS,
         --             RPC_Receiver'Access);
         --    A : Any;

         Decls := New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Reference,
             Constant_Present    => True,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
             Expression          =>
               Make_Function_Call (Loc,
                 Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
                 Parameter_Associations => New_List (
                   Unchecked_Convert_To (RTE (RE_Address),
                     New_Occurrence_Of (RACW_Parameter, Loc)),
                   Make_String_Literal (Loc,
                     Strval => Fully_Qualified_Name_String
                                 (Etype (Designated_Type (RACW_Type)),
                                  Append_NUL => False)),
                   Build_Stub_Tag (Loc, RACW_Type),
                   New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       New_Occurrence_Of
                         (Defining_Identifier
                           (Stub_Elements.RPC_Receiver_Decl), Loc),
                     Attribute_Name => Name_Access)))),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Any,
             Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc)));

         --  Generate:

         --    Any := TA_ObjRef (Reference);
         --    Set_TC (Any, RPC_Receiver.Obj_TypeCode);
         --    return Any;

         Statements := New_List (
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Any, Loc),
             Expression =>
               Make_Function_Call (Loc,
                 Name => New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc),
                 Parameter_Associations => New_List (
                   New_Occurrence_Of (Reference, Loc)))),

           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Any, Loc),
               Make_Selected_Component (Loc,
                 Prefix =>
                     Defining_Identifier (
                       Stub_Elements.RPC_Receiver_Decl),
                 Selector_Name => Name_Obj_TypeCode))),

           Make_Simple_Return_Statement (Loc,
             Expression => New_Occurrence_Of (Any, Loc)));

         Func_Body :=
           Make_Subprogram_Body (Loc,
             Specification              => Copy_Specification (Loc, Func_Spec),
             Declarations               => Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Statements));
         Append_To (Body_Decls, Func_Body);
      end Add_RACW_To_Any;

      -----------------------
      -- Add_RACW_TypeCode --
      -----------------------

      procedure Add_RACW_TypeCode
        (Designated_Type  : Entity_Id;
         RACW_Type        : Entity_Id;
         Body_Decls       : List_Id)
      is
         Loc : constant Source_Ptr := Sloc (RACW_Type);

         Fnam : constant Entity_Id :=
                  Make_Defining_Identifier (Loc,
                    Chars => New_External_Name (Chars (RACW_Type), 'Y'));

         Stub_Elements : constant Stub_Structure :=
                           Stubs_Table.Get (Designated_Type);
         pragma Assert (Stub_Elements /= Empty_Stub_Structure);

         Func_Spec : Node_Id;
         Func_Decl : Node_Id;
         Func_Body : Node_Id;

      begin
         --  The spec for this subprogram has a dummy 'access RACW' argument,
         --  which serves only for overloading purposes.

         Func_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name => Fnam,
             Result_Definition  => New_Occurrence_Of (RTE (RE_TypeCode), Loc));

         --  NOTE: The usage occurrences of RACW_Parameter must refer to the
         --  entity in the declaration spec, not those of the body spec.

         Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
         Insert_After (Declaration_Node (RACW_Type), Func_Decl);
         Set_Renaming_TSS (RACW_Type, Fnam, TSS_TypeCode);

         if No (Body_Decls) then
            return;
         end if;

         Func_Body :=
           Make_Subprogram_Body (Loc,
             Specification              => Copy_Specification (Loc, Func_Spec),
             Declarations               => Empty_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => New_List (
                   Make_Simple_Return_Statement (Loc,
                     Expression =>
                       Make_Selected_Component (Loc,
                         Prefix =>
                           Defining_Identifier
                             (Stub_Elements.RPC_Receiver_Decl),
                         Selector_Name => Name_Obj_TypeCode)))));

         Append_To (Body_Decls, Func_Body);
      end Add_RACW_TypeCode;

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

      procedure Add_RACW_Write_Attribute
        (RACW_Type        : Entity_Id;
         Stub_Type        : Entity_Id;
         Stub_Type_Access : Entity_Id;
         Body_Decls       : List_Id)
      is
         pragma Unreferenced (Stub_Type, Stub_Type_Access);

         Loc : constant Source_Ptr := Sloc (RACW_Type);

         Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);

         Stub_Elements : constant Stub_Structure :=
                            Get_Stub_Elements (RACW_Type);

         Body_Node : Node_Id;
         Proc_Decl : Node_Id;
         Attr_Decl : Node_Id;

         Statements : constant List_Id := New_List;
         Pnam : constant Entity_Id := Make_Temporary (Loc, 'R');

         function Stream_Parameter return Node_Id;
         function Object return Node_Id;
         --  Functions to create occurrences of the formal parameter names

         ------------
         -- Object --
         ------------

         function Object return Node_Id is
         begin
            return Make_Identifier (Loc, Name_V);
         end Object;

         ----------------------
         -- Stream_Parameter --
         ----------------------

         function Stream_Parameter return Node_Id is
         begin
            return Make_Identifier (Loc, Name_S);
         end Stream_Parameter;

      --  Start of processing for Add_RACW_Write_Attribute

      begin
         Build_Stream_Procedure
           (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => False);

         Proc_Decl :=
           Make_Subprogram_Declaration (Loc,
             Copy_Specification (Loc, Specification (Body_Node)));

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

         Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
         Insert_After (Proc_Decl, Attr_Decl);

         if No (Body_Decls) then
            return;
         end if;

         Append_To (Statements,
           Pack_Node_Into_Stream_Access (Loc,
             Stream => Stream_Parameter,
             Object =>
               Make_Function_Call (Loc,
                 Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
                 Parameter_Associations => New_List (
                   Unchecked_Convert_To (RTE (RE_Address), Object),
                  Make_String_Literal (Loc,
                    Strval => Fully_Qualified_Name_String
                                (Etype (Designated_Type (RACW_Type)),
                                 Append_NUL => False)),
                  Build_Stub_Tag (Loc, RACW_Type),
                  New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                       New_Occurrence_Of
                         (Defining_Identifier
                           (Stub_Elements.RPC_Receiver_Decl), Loc),
                    Attribute_Name => Name_Access))),

             Etyp => RTE (RE_Object_Ref)));

         Append_To (Body_Decls, Body_Node);
      end Add_RACW_Write_Attribute;

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

      procedure Add_RAST_Features
        (Vis_Decl : Node_Id;
         RAS_Type : Entity_Id)
      is
      begin
         Add_RAS_Access_TSS (Vis_Decl);

         Add_RAS_From_Any (RAS_Type);
         Add_RAS_TypeCode (RAS_Type);

         --  To_Any uses TypeCode, and therefore needs to be generated last

         Add_RAS_To_Any   (RAS_Type);
      end Add_RAST_Features;

      ------------------------
      -- Add_RAS_Access_TSS --
      ------------------------

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

         Ras_Type : constant Entity_Id := Defining_Identifier (N);
         Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
         --  Ras_Type is the access to subprogram type; Fat_Type is the
         --  corresponding record type.

         RACW_Type : constant Entity_Id :=
                       Underlying_RACW_Type (Ras_Type);

         Stub_Elements : constant Stub_Structure :=
                           Get_Stub_Elements (RACW_Type);

         Proc : constant Entity_Id :=
                  Make_Defining_Identifier (Loc,
                    Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));

         Proc_Spec : Node_Id;

         --  Formal parameters

         Package_Name : constant Entity_Id :=
                          Make_Defining_Identifier (Loc,
                            Chars => Name_P);

         --  Target package

         Subp_Id : constant Entity_Id :=
                     Make_Defining_Identifier (Loc,
                       Chars => Name_S);

         --  Target subprogram

         Asynch_P : constant Entity_Id :=
                      Make_Defining_Identifier (Loc,
                        Chars => Name_Asynchronous);
         --  Is the procedure to which the 'Access applies asynchronous?

         All_Calls_Remote : constant Entity_Id :=
                              Make_Defining_Identifier (Loc,
                                Chars => Name_All_Calls_Remote);
         --  True if an All_Calls_Remote pragma applies to the RCI unit
         --  that contains the subprogram.

         --  Common local variables

         Proc_Decls      : List_Id;
         Proc_Statements : List_Id;

         Subp_Ref : constant Entity_Id :=
                      Make_Defining_Identifier (Loc, Name_R);
         --  Reference that designates the target subprogram (returned
         --  by Get_RAS_Info).

         Is_Local : constant Entity_Id :=
           Make_Defining_Identifier (Loc, Name_L);
         Local_Addr : constant Entity_Id :=
           Make_Defining_Identifier (Loc, Name_A);
         --  For the call to Get_Local_Address

         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

         function Set_Field
           (Field_Name : Name_Id;
            Value      : Node_Id) return Node_Id;
         --  Construct an assignment that sets the named component in the
         --  returned record

         ---------------
         -- Set_Field --
         ---------------

         function Set_Field
           (Field_Name : Name_Id;
            Value      : Node_Id) return Node_Id
         is
         begin
            return
              Make_Assignment_Statement (Loc,
                Name       =>
                  Make_Selected_Component (Loc,
                    Prefix        => Stub_Ptr,
                    Selector_Name => Field_Name),
                Expression => Value);
         end Set_Field;

      --  Start of processing for Add_RAS_Access_TSS

      begin
         Proc_Decls := New_List (

         --  Common declarations

           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Ref,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Object_Ref), Loc)),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Is_Local,
             Object_Definition   =>
               New_Occurrence_Of (Standard_Boolean, Loc)),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Local_Addr,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Address), Loc)),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Local_Stub,
             Aliased_Present     => True,
             Object_Definition   =>
               New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Stub_Ptr,
             Object_Definition   =>
               New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix => New_Occurrence_Of (Local_Stub, Loc),
                 Attribute_Name => Name_Unchecked_Access)));

         Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
         --  Build_Get_Unique_RP_Call needs this information

         --  Get_RAS_Info (Pkg, Subp, R);
         --  Obtain a reference to the target subprogram

         Proc_Statements := New_List (
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Package_Name, Loc),
               New_Occurrence_Of (Subp_Id, Loc),
               New_Occurrence_Of (Subp_Ref, Loc))),

         --  Get_Local_Address (R, L, A);
         --  Determine whether the subprogram is local (L), and if so
         --  obtain the local address of its proxy (A).

           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Subp_Ref, Loc),
               New_Occurrence_Of (Is_Local, Loc),
               New_Occurrence_Of (Local_Addr, Loc))));

         --  Note: Here we assume that the Fat_Type is a record containing just
         --  an access to a proxy or stub object.

         Append_To (Proc_Statements,

           --  if L then

           Make_Implicit_If_Statement (N,
             Condition => New_Occurrence_Of (Is_Local, Loc),

             Then_Statements => New_List (

               --  if A.Target = null then

               Make_Implicit_If_Statement (N,
                 Condition =>
                   Make_Op_Eq (Loc,
                     Make_Selected_Component (Loc,
                       Prefix        =>
                         Unchecked_Convert_To
                           (RTE (RE_RAS_Proxy_Type_Access),
                            New_Occurrence_Of (Local_Addr, Loc)),
                       Selector_Name => Make_Identifier (Loc, Name_Target)),
                     Make_Null (Loc)),

                 Then_Statements => New_List (

                   --    A.Target := Entity_Of (Ref);

                   Make_Assignment_Statement (Loc,
                     Name =>
                       Make_Selected_Component (Loc,
                         Prefix        =>
                           Unchecked_Convert_To
                             (RTE (RE_RAS_Proxy_Type_Access),
                              New_Occurrence_Of (Local_Addr, Loc)),
                         Selector_Name => Make_Identifier (Loc, Name_Target)),
                     Expression =>
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
                         Parameter_Associations => New_List (
                           New_Occurrence_Of (Subp_Ref, Loc)))),

                   --    Inc_Usage (A.Target);
                   --  end if;

                   Make_Procedure_Call_Statement (Loc,
                     Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
                     Parameter_Associations => New_List (
                       Make_Selected_Component (Loc,
                         Prefix        =>
                           Unchecked_Convert_To
                             (RTE (RE_RAS_Proxy_Type_Access),
                              New_Occurrence_Of (Local_Addr, Loc)),
                         Selector_Name =>
                           Make_Identifier (Loc, Name_Target)))))),

                 --     if not All_Calls_Remote then
                 --        return Fat_Type!(A);
                 --     end if;

                 Make_Implicit_If_Statement (N,
                   Condition =>
                     Make_Op_Not (Loc,
                       Right_Opnd =>
                         New_Occurrence_Of (All_Calls_Remote, Loc)),

                   Then_Statements => New_List (
                     Make_Simple_Return_Statement (Loc,
                     Expression =>
                       Unchecked_Convert_To
                         (Fat_Type, New_Occurrence_Of (Local_Addr, Loc))))))));

         Append_List_To (Proc_Statements, New_List (

           --  Stub.Target := Entity_Of (Ref);

           Set_Field (Name_Target,
             Make_Function_Call (Loc,
               Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
               Parameter_Associations => New_List (
                 New_Occurrence_Of (Subp_Ref, Loc)))),

           --  Inc_Usage (Stub.Target);

           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
             Parameter_Associations => New_List (
               Make_Selected_Component (Loc,
                 Prefix        => Stub_Ptr,
                 Selector_Name => Name_Target))),

           --  E.4.1(9) A remote call is asynchronous if it is a call to
           --  a procedure, or a call through a value of an access-to-procedure
           --  type, to which a pragma Asynchronous applies.

           --    Parameter Asynch_P is true when the procedure is asynchronous;
           --    Expression Asynch_T is true when the type is asynchronous.

           Set_Field (Name_Asynchronous,
             Make_Or_Else (Loc,
               Left_Opnd  => New_Occurrence_Of (Asynch_P, Loc),
               Right_Opnd =>
                 New_Occurrence_Of
                   (Boolean_Literals (Is_Asynchronous (Ras_Type)), Loc)))));

         Append_List_To (Proc_Statements,
           Build_Get_Unique_RP_Call (Loc, Stub_Ptr, Stub_Elements.Stub_Type));

         Append_To (Proc_Statements,
           Make_Simple_Return_Statement (Loc,
             Expression =>
               Unchecked_Convert_To (Fat_Type,
                 New_Occurrence_Of (Stub_Ptr, Loc))));

         Proc_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name       => Proc,
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Package_Name,
                 Parameter_Type      =>
                   New_Occurrence_Of (Standard_String, Loc)),

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

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

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

            Result_Definition =>
              New_Occurrence_Of (Fat_Type, Loc));

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

         Mutate_Ekind (Proc, E_Function);
         Set_Etype (Proc, Fat_Type);

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

         Set_TSS (Fat_Type, Proc);
      end Add_RAS_Access_TSS;

      ----------------------
      -- Add_RAS_From_Any --
      ----------------------

      procedure Add_RAS_From_Any (RAS_Type : Entity_Id) is
         Loc : constant Source_Ptr := Sloc (RAS_Type);

         Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
                  Make_TSS_Name (RAS_Type, TSS_From_Any));

         Func_Spec : Node_Id;

         Statements : List_Id;

         Any_Parameter : constant Entity_Id :=
                           Make_Defining_Identifier (Loc, Name_A);

      begin
         Statements := New_List (
           Make_Simple_Return_Statement (Loc,
             Expression =>
               Make_Aggregate (Loc,
                 Component_Associations => New_List (
                   Make_Component_Association (Loc,
                     Choices    => New_List (Make_Identifier (Loc, Name_Ras)),
                     Expression =>
                       PolyORB_Support.Helpers.Build_From_Any_Call
                         (Underlying_RACW_Type (RAS_Type),
                          New_Occurrence_Of (Any_Parameter, Loc),
                          No_List))))));

         Func_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name       => Fnam,
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Any_Parameter,
                 Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))),
             Result_Definition => New_Occurrence_Of (RAS_Type, Loc));

         Discard_Node (
           Make_Subprogram_Body (Loc,
             Specification              => Func_Spec,
             Declarations               => No_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Statements)));
         Set_TSS (RAS_Type, Fnam);
      end Add_RAS_From_Any;

      --------------------
      -- Add_RAS_To_Any --
      --------------------

      procedure Add_RAS_To_Any (RAS_Type : Entity_Id) is
         Loc : constant Source_Ptr := Sloc (RAS_Type);

         Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
                  Make_TSS_Name (RAS_Type, TSS_To_Any));

         Decls      : List_Id;
         Statements : List_Id;

         Func_Spec : Node_Id;

         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,
                              Selector_Name => Name_Ras);

      begin
         --  Object declarations

         Set_Etype (RACW_Parameter, Underlying_RACW_Type (RAS_Type));
         Decls := New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Any,
             Object_Definition   => New_Occurrence_Of (RTE (RE_Any), Loc),
             Expression          =>
               PolyORB_Support.Helpers.Build_To_Any_Call
                 (Loc, RACW_Parameter, No_List)));

         Statements := New_List (
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Any, Loc),
               PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
                 RAS_Type, Decls))),

           Make_Simple_Return_Statement (Loc,
             Expression => New_Occurrence_Of (Any, Loc)));

         Func_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name => Fnam,
             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => RAS_Parameter,
                 Parameter_Type      => New_Occurrence_Of (RAS_Type, Loc))),
             Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));

         Discard_Node (
           Make_Subprogram_Body (Loc,
             Specification              => Func_Spec,
             Declarations               => Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Statements)));
         Set_TSS (RAS_Type, Fnam);
      end Add_RAS_To_Any;

      ----------------------
      -- Add_RAS_TypeCode --
      ----------------------

      procedure Add_RAS_TypeCode (RAS_Type : Entity_Id) is
         Loc : constant Source_Ptr := Sloc (RAS_Type);

         Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
                  Make_TSS_Name (RAS_Type, TSS_TypeCode));

         Func_Spec      : Node_Id;
         Decls          : constant List_Id := New_List;
         Name_String    : String_Id;
         Repo_Id_String : String_Id;

      begin
         Func_Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name => Fnam,
             Result_Definition  => New_Occurrence_Of (RTE (RE_TypeCode), Loc));

         PolyORB_Support.Helpers.Build_Name_And_Repository_Id
           (RAS_Type, Name_Str => Name_String, Repo_Id_Str => Repo_Id_String);

         Discard_Node (
           Make_Subprogram_Body (Loc,
             Specification              => Func_Spec,
             Declarations               => Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => New_List (
                   Make_Simple_Return_Statement (Loc,
                     Expression =>
                       Make_Function_Call (Loc,
                         Name =>
                           New_Occurrence_Of (RTE (RE_Build_Complex_TC), Loc),
                         Parameter_Associations => New_List (
                           New_Occurrence_Of (RTE (RE_Tk_Objref), Loc),
                           Make_Aggregate (Loc,
                             Expressions =>
                               New_List (
                                 Make_Function_Call (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_Std_String), Loc),
                                   Parameter_Associations => New_List (
                                     Make_String_Literal (Loc,
                                       Strval => Repo_Id_String))))))))))));
         Set_TSS (RAS_Type, Fnam);
      end Add_RAS_TypeCode;

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

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

         Pkg_RPC_Receiver            : constant Entity_Id :=
                                         Make_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;
         --  A Pkg_RPC_Receiver is built to decode the request

         Request : Node_Id;
         --  Request object received from neutral layer

         Subp_Id : Entity_Id;
         --  Subprogram identifier as received from the neutral distribution
         --  core.

         Subp_Index : Entity_Id;
         --  Internal index as determined by matching either the method name
         --  from the request structure, or the local subprogram address (in
         --  case of a RAS).

         Is_Local : constant Entity_Id := Make_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_Subp_Number : Int := First_RCI_Subprogram_Id;

         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;

         All_Calls_Remote_E  : Entity_Id;

         procedure Append_Stubs_To
           (RPC_Receiver_Cases : List_Id;
            Declaration        : Node_Id;
            Stubs              : Node_Id;
            Subp_Number        : Int;
            Subp_Dist_Name     : Entity_Id;
            Subp_Proxy_Addr    : Entity_Id);
         --  Add one case to the specified RPC receiver case list associating
         --  Subprogram_Number with the subprogram declared by Declaration, for
         --  which we have receiving stubs in Stubs. Subp_Number is an internal
         --  subprogram index. Subp_Dist_Name is the string used to call the
         --  subprogram by name, and Subp_Dist_Addr is the address of the proxy
         --  object, used in the context of calls through remote
         --  access-to-subprogram types.

         procedure Visit_Subprogram (Decl : Node_Id);
         --  Generate receiving stub for one remote subprogram

         ---------------------
         -- Append_Stubs_To --
         ---------------------

         procedure Append_Stubs_To
           (RPC_Receiver_Cases : List_Id;
            Declaration        : Node_Id;
            Stubs              : Node_Id;
            Subp_Number        : Int;
            Subp_Dist_Name     : Entity_Id;
            Subp_Proxy_Addr    : Entity_Id)
         is
            Case_Stmts : List_Id;
         begin
            Case_Stmts := New_List (
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (
                    Defining_Entity (Stubs), Loc),
                Parameter_Associations =>
                  New_List (New_Occurrence_Of (Request, Loc))));

            if Nkind (Specification (Declaration)) = N_Function_Specification
              or else not
                Is_Asynchronous (Defining_Entity (Specification (Declaration)))
            then
               Append_To (Case_Stmts, Make_Simple_Return_Statement (Loc));
            end if;

            Append_To (RPC_Receiver_Cases,
              Make_Case_Statement_Alternative (Loc,
                Discrete_Choices =>
                   New_List (Make_Integer_Literal (Loc, Subp_Number)),
                Statements       => Case_Stmts));

            Append_To (Dispatch_On_Name,
              Make_Elsif_Part (Loc,
                Condition =>
                  Make_Function_Call (Loc,
                    Name =>
                      New_Occurrence_Of (RTE (RE_Caseless_String_Eq), Loc),
                    Parameter_Associations => New_List (
                      New_Occurrence_Of (Subp_Id, Loc),
                      New_Occurrence_Of (Subp_Dist_Name, Loc))),

                Then_Statements => New_List (
                  Make_Assignment_Statement (Loc,
                    New_Occurrence_Of (Subp_Index, Loc),
                    Make_Integer_Literal (Loc, Subp_Number)))));

            Append_To (Dispatch_On_Address,
              Make_Elsif_Part (Loc,
                Condition =>
                  Make_Op_Eq (Loc,
                    Left_Opnd  => New_Occurrence_Of (Local_Address, Loc),
                    Right_Opnd => New_Occurrence_Of (Subp_Proxy_Addr, Loc)),

                Then_Statements => New_List (
                  Make_Assignment_Statement (Loc,
                    New_Occurrence_Of (Subp_Index, Loc),
                    Make_Integer_Literal (Loc, Subp_Number)))));
         end Append_Stubs_To;

         ----------------------
         -- 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
            --  Disable expansion of stubs if serious errors have been
            --  diagnosed, because otherwise some illegal remote subprogram
            --  declarations could cause cascaded errors in stubs.

            if Serious_Errors_Detected /= 0 then
               return;
            end if;

            --  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 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;

         Build_RPC_Receiver_Body (
           RPC_Receiver => Pkg_RPC_Receiver,
           Request      => Request,
           Subp_Id      => Subp_Id,
           Subp_Index   => Subp_Index,
           Stmts        => Pkg_RPC_Receiver_Statements,
           Decl         => Pkg_RPC_Receiver_Body);
         Pkg_RPC_Receiver_Decls := Declarations (Pkg_RPC_Receiver_Body);

         --  Extract local address information from the target reference:
         --  if non-null, that means that this is a reference that denotes
         --  one particular operation, and hence that the operation name
         --  must not be taken into account for dispatching.

         Append_To (Pkg_RPC_Receiver_Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Is_Local,
             Object_Definition   =>
               New_Occurrence_Of (Standard_Boolean, Loc)));

         Append_To (Pkg_RPC_Receiver_Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Local_Address,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Address), Loc)));

         Append_To (Pkg_RPC_Receiver_Statements,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
             Parameter_Associations => New_List (
               Make_Selected_Component (Loc,
                 Prefix        => Request,
                 Selector_Name => Name_Target),
               New_Occurrence_Of (Is_Local, Loc),
               New_Occurrence_Of (Local_Address, Loc))));

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

         All_Calls_Remote_E := Boolean_Literals (
           Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));

         Overload_Counter_Table.Reset;
         Reserve_NamingContext_Methods;

         Visit_Spec (Pkg_Spec);

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Info_Array,
             Constant_Present    => True,
             Aliased_Present     => True,
             Object_Definition   =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark =>
                   New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
                 Constraint =>
                   Make_Index_Or_Discriminant_Constraint (Loc,
                     New_List (
                       Make_Range (Loc,
                         Low_Bound  =>
                           Make_Integer_Literal (Loc,
                             Intval => First_RCI_Subprogram_Id),
                         High_Bound =>
                           Make_Integer_Literal (Loc,
                             Intval =>
                               First_RCI_Subprogram_Id
                               + List_Length (Subp_Info_List) - 1)))))));

         if Present (First (Subp_Info_List)) then
            Set_Expression (Last (Decls),
              Make_Aggregate (Loc,
                Component_Associations => Subp_Info_List));

            --  Generate the dispatch statement to determine the subprogram id
            --  of the called subprogram.

            --  We first test whether the reference that was used to make the
            --  call was the base RCI reference (in which case Local_Address is
            --  zero, and the method identifier from the request must be used
            --  to determine which subprogram is called) or a reference
            --  identifying one particular subprogram (in which case
            --  Local_Address is the address of that subprogram, and the
            --  method name from the request is ignored). The latter occurs
            --  for the case of a call through a remote access-to-subprogram.

            --  In each case, cascaded elsifs are used to determine the proper
            --  subprogram index. Using hash tables might be more efficient.

            Append_To (Pkg_RPC_Receiver_Statements,
              Make_Implicit_If_Statement (Pkg_Spec,
                Condition =>
                  Make_Op_Ne (Loc,
                    Left_Opnd  => New_Occurrence_Of (Local_Address, Loc),
                    Right_Opnd => New_Occurrence_Of
                                    (RTE (RE_Null_Address), Loc)),

                Then_Statements => New_List (
                  Make_Implicit_If_Statement (Pkg_Spec,
                    Condition       => New_Occurrence_Of (Standard_False, Loc),
                    Then_Statements => New_List (
                      Make_Null_Statement (Loc)),
                    Elsif_Parts     => Dispatch_On_Address)),

                Else_Statements => New_List (
                  Make_Implicit_If_Statement (Pkg_Spec,
                    Condition       => New_Occurrence_Of (Standard_False, Loc),
                    Then_Statements => New_List (Make_Null_Statement (Loc)),
                    Elsif_Parts     => Dispatch_On_Name))));

         else
            --  For a degenerate RCI with no visible subprograms,
            --  Subp_Info_List has zero length, and the declaration is for an
            --  empty array, in which case no initialization aggregate must be
            --  generated. We do not generate a Dispatch_Statement either.

            --  No initialization provided: remove CONSTANT so that the
            --  declaration is not an incomplete deferred constant.

            Set_Constant_Present (Last (Decls), False);
         end if;

         --  Analyze Subp_Info_Array declaration

         Analyze (Last (Decls));

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

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

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

         --  Pkg_RPC_Receiver body is now complete: insert it into the tree and
         --  analyze it.

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

         Pkg_RPC_Receiver_Object :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Make_Temporary (Loc, 'R'),
             Aliased_Present     => True,
             Object_Definition   => New_Occurrence_Of (RTE (RE_Servant), Loc));
         Append_To (Decls, Pkg_RPC_Receiver_Object);
         Analyze (Last (Decls));

         --  Name

         Append_To (Register_Pkg_Actuals,
           Make_String_Literal (Loc,
             Strval =>
               Fully_Qualified_Name_String
                 (Defining_Entity (Pkg_Spec), Append_NUL => False)));

         --  Version

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of
                 (Defining_Entity (Pkg_Spec), Loc),
             Attribute_Name => Name_Version));

         --  Handler

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix          =>
               New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
             Attribute_Name  => Name_Access));

         --  Receiver

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (
                 Defining_Identifier (Pkg_RPC_Receiver_Object), Loc),
             Attribute_Name => Name_Access));

         --  Subp_Info

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
             Attribute_Name => Name_Address));

         --  Subp_Info_Len

         Append_To (Register_Pkg_Actuals,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Subp_Info_Array, Loc),
             Attribute_Name => Name_Length));

         --  Is_All_Calls_Remote

         Append_To (Register_Pkg_Actuals,
           New_Occurrence_Of (All_Calls_Remote_E, Loc));

         --  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 (Stmts));
      end Add_Receiving_Stubs_To_Declarations;

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

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

         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

         Result : Node_Id;
         --  Name of the result named value (in non-APC cases) which get the
         --  result of the remote subprogram.

         Result_TC : Node_Id;
         --  Typecode expression for the result of the request (void
         --  typecode for procedures).

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

         Current_Parameter : Node_Id;
         --  Current parameter being handled

         Ordered_Parameters_List : constant List_Id :=
                                     Build_Ordered_Parameters_List (Spec);

         Asynchronous_P : Node_Id;
         --  A Boolean expression indicating whether this call is asynchronous

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

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

         After_Statements : constant List_Id := New_List;
         --  Statements to be executed after call returns (to assign IN OUT or
         --  OUT parameter values).

         Etyp : Entity_Id;
         --  The type of the formal parameter being processed

         Is_Controlling_Formal         : Boolean;
         Is_First_Controlling_Formal   : Boolean;
         First_Controlling_Formal_Seen : Boolean := False;
         --  Controlling formal parameters of distributed object primitives
         --  require special handling, and the first such parameter needs even
         --  more special handling.

      begin
         --  ??? document general form of stub subprograms for the PolyORB case

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Request,
             Aliased_Present     => True,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Request), Loc)));

         Result := Make_Temporary (Loc, 'R');

         if Is_Function then
            Result_TC :=
              PolyORB_Support.Helpers.Build_TypeCode_Call
                (Loc, Etype (Result_Definition (Spec)), Decls);
         else
            Result_TC := New_Occurrence_Of (RTE (RE_TC_Void), Loc);
         end if;

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Result,
             Aliased_Present     => False,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_NamedValue), Loc),
             Expression =>
               Make_Aggregate (Loc,
                 Component_Associations => New_List (
                   Make_Component_Association (Loc,
                     Choices    => New_List (Make_Identifier (Loc, Name_Name)),
                     Expression =>
                       New_Occurrence_Of (RTE (RE_Result_Name), Loc)),
                   Make_Component_Association (Loc,
                     Choices => New_List (
                       Make_Identifier (Loc, Name_Argument)),
                     Expression =>
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                         Parameter_Associations => New_List (Result_TC))),
                   Make_Component_Association (Loc,
                     Choices    => New_List (
                       Make_Identifier (Loc, Name_Arg_Modes)),
                     Expression => Make_Integer_Literal (Loc, 0))))));

         if not Is_Known_Asynchronous then
            Exception_Return_Parameter := Make_Temporary (Loc, 'E');

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

         else
            Exception_Return_Parameter := Empty;
         end if;

         --  Initialize and fill in arguments list

         Arguments := Make_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;
            end if;

            if Is_Controlling_Formal then

               --  For a controlling formal argument, we send its reference

               Etyp := RACW_Type;

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

            --  The first controlling formal parameter is treated specially:
            --  it is used to set the target object of the call.

            if not Is_First_Controlling_Formal then
               declare
                  Constrained : constant Boolean :=
                                  Is_Constrained (Etyp)
                                    or else Is_Elementary_Type (Etyp);

                  Any : constant Entity_Id := Make_Temporary (Loc, 'A');

                  Actual_Parameter : Node_Id :=
                                       New_Occurrence_Of (
                                         Defining_Identifier (
                                           Current_Parameter), Loc);

                  Expr : Node_Id;

               begin
                  if Is_Controlling_Formal then

                     --  For a controlling formal parameter (other than the
                     --  first one), use the corresponding RACW. If the
                     --  parameter is not an anonymous access parameter, that
                     --  involves taking its 'Unrestricted_Access.

                     if Nkind (Parameter_Type (Current_Parameter))
                       = N_Access_Definition
                     then
                        Actual_Parameter := OK_Convert_To
                          (Etyp, Actual_Parameter);
                     else
                        Actual_Parameter := OK_Convert_To (Etyp,
                          Make_Attribute_Reference (Loc,
                            Prefix         => Actual_Parameter,
                            Attribute_Name => Name_Unrestricted_Access));
                     end if;

                  end if;

                  if In_Present (Current_Parameter)
                    or else not Out_Present (Current_Parameter)
                    or else not Constrained
                    or else Is_Controlling_Formal
                  then
                     --  The parameter has an input value, is constrained at
                     --  runtime by an input value, or is a controlling formal
                     --  parameter (always passed as a reference) other than
                     --  the first one.

                     Expr := PolyORB_Support.Helpers.Build_To_Any_Call
                               (Loc, Actual_Parameter, Decls);

                  else
                     Expr := Make_Function_Call (Loc,
                       Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                       Parameter_Associations => New_List (
                         PolyORB_Support.Helpers.Build_TypeCode_Call
                           (Loc, Etyp, Decls)));
                  end if;

                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Any,
                      Aliased_Present     => False,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_Any), Loc),
                      Expression          => Expr));

                  Append_To (Statements,
                    Add_Parameter_To_NVList (Loc,
                      Parameter   => Current_Parameter,
                      NVList      => Arguments,
                      Constrained => Constrained,
                      Any         => Any));

                  if Out_Present (Current_Parameter)
                    and then not Is_Controlling_Formal
                  then
                     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),
                           Constrained => True);

                     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.

            --  This should be done for accessibility as well ???

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

               declare
                  Extra_Any_Parameter : constant Entity_Id :=
                                          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,
                      Aliased_Present     => False,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_Any), Loc),
                      Expression          =>
                        PolyORB_Support.Helpers.Build_To_Any_Call
                          (Loc, Parameter_Exp, Decls)));

                  Append_To (Extra_Formal_Statements,
                    Add_Parameter_To_NVList (Loc,
                      Parameter   => Extra_Any_Parameter,
                      NVList      => Arguments,
                      Constrained => True,
                      Any         => Extra_Any_Parameter));
               end;
            end if;

            Next (Current_Parameter);
         end loop;

         --  Append the formal statements list to the statements

         Append_List_To (Statements, Extra_Formal_Statements);

         Append_To (Statements,
           Make_Procedure_Call_Statement (Loc,
             Name =>
               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))));

         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);

         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.
         end if;

         Append_To (Parameter_Associations (Last (Statements)),
           Make_Indexed_Component (Loc,
             Prefix =>
               New_Occurrence_Of (
                 RTE (RE_Asynchronous_P_To_Sync_Scope), Loc),
             Expressions => New_List (Asynchronous_P)));

         Append_To (Statements, Make_Request_RTE_Call (RE_Request_Invoke));

         --  Asynchronous case

         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.

            Non_Asynchronous_Statements := New_List (
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (RTE (RE_Request_Raise_Occurrence), Loc),
                Parameter_Associations => New_List (
                  New_Occurrence_Of (Request, Loc))));

            if Is_Function then
               --  If this is a function call, read the value and return it

               Append_To (Non_Asynchronous_Statements,
                 Make_Tag_Check (Loc,
                   Make_Simple_Return_Statement (Loc,
                     PolyORB_Support.Helpers.Build_From_Any_Call
                       (Etype (Result_Definition (Spec)),
                        Make_Selected_Component (Loc,
                          Prefix        => Result,
                          Selector_Name => Name_Argument),
                        Decls))));

            else

               --  Case of a procedure: deal with IN OUT and OUT formals

               Append_List_To (Non_Asynchronous_Statements, After_Statements);
            end if;
         end if;

         if Is_Known_Asynchronous then
            Append_List_To (Statements, Asynchronous_Statements);

         elsif Is_Known_Non_Asynchronous then
            Append_List_To (Statements, Non_Asynchronous_Statements);

         else
            pragma Assert (Present (Asynchronous));
            Append_To (Statements,
              Make_Implicit_If_Statement (Nod,
                Condition       => Asynchronous,
                Then_Statements => Asynchronous_Statements,
                Else_Statements => Non_Asynchronous_Statements));
         end if;
      end Build_General_Calling_Stubs;

      -----------------------
      -- Build_Stub_Target --
      -----------------------

      function Build_Stub_Target
        (Loc                   : Source_Ptr;
         Decls                 : List_Id;
         RCI_Locator           : Entity_Id;
         Controlling_Parameter : Entity_Id) return RPC_Target
      is
         Target_Info : RPC_Target (PCS_Kind => Name_PolyORB_DSA);
         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 =>
                      New_Occurrence_Of (RTE (RE_Make_Ref), Loc),
                    Parameter_Associations => New_List (
                      Make_Selected_Component (Loc,
                        Prefix        => Controlling_Parameter,
                        Selector_Name => Name_Target)))));

            --  Note: Controlling_Parameter has the same components as
            --  System.Partition_Interface.RACW_Stub_Type.

            Target_Info.Object := New_Occurrence_Of (Target_Reference, Loc);

         else
            Target_Info.Object :=
              Make_Selected_Component (Loc,
                Prefix        =>
                  Make_Identifier (Loc, Chars (RCI_Locator)),
                Selector_Name =>
                  Make_Identifier (Loc, Name_Get_RCI_Package_Ref));
         end if;

         return Target_Info;
      end Build_Stub_Target;

      -----------------------------
      -- Build_RPC_Receiver_Body --
      -----------------------------

      procedure Build_RPC_Receiver_Body
        (RPC_Receiver : Entity_Id;
         Request      : out Entity_Id;
         Subp_Id      : out Entity_Id;
         Subp_Index   : out Entity_Id;
         Stmts        : out List_Id;
         Decl         : out Node_Id)
      is
         Loc : constant Source_Ptr := Sloc (RPC_Receiver);

         RPC_Receiver_Spec  : Node_Id;
         RPC_Receiver_Decls : List_Id;

      begin
         Request := Make_Defining_Identifier (Loc, Name_R);

         RPC_Receiver_Spec :=
           Build_RPC_Receiver_Specification
             (RPC_Receiver      => RPC_Receiver,
              Request_Parameter => Request);

         Subp_Id    := Make_Defining_Identifier (Loc, Name_P);
         Subp_Index := Make_Defining_Identifier (Loc, Name_I);

         RPC_Receiver_Decls := New_List (
           Make_Object_Renaming_Declaration (Loc,
             Defining_Identifier => Subp_Id,
             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
             Name                =>
               Make_Explicit_Dereference (Loc,
                 Prefix =>
                   Make_Selected_Component (Loc,
                     Prefix        => Request,
                     Selector_Name => Name_Operation))),

           Make_Object_Declaration (Loc,
             Defining_Identifier => Subp_Index,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
                 Attribute_Name => Name_Last)));

         Stmts := New_List;

         Decl :=
           Make_Subprogram_Body (Loc,
             Specification              => RPC_Receiver_Spec,
             Declarations               => RPC_Receiver_Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Stmts));
      end Build_RPC_Receiver_Body;

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

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

         Request_Parameter : constant Entity_Id := Make_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.

         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.

         Statements : constant List_Id := New_List;

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

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

         Excep_Handlers : List_Id := No_List;

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

         First_Controlling_Formal_Seen : Boolean := False;

         Current_Parameter : Node_Id;

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

         Arguments : constant Entity_Id := Make_Temporary (Loc, 'A');
         --  Name of the named values list used to retrieve parameters

         Subp_Spec : Node_Id;
         --  Subprogram specification

         Called_Subprogram : Node_Id;
         --  The subprogram to call

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

         Declare_Create_NVList (Loc, Arguments, Outer_Decls, Outer_Statements);

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

         Current_Parameter := First (Ordered_Parameters_List);
         while Present (Current_Parameter) loop
            declare
               Etyp        : Entity_Id;
               Constrained : Boolean;
               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_First_Controlling_Formal : Boolean := False;

               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.

                  Etyp := RACW_Type;
                  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);

               if not Is_First_Controlling_Formal then
                  Any := Make_Temporary (Loc, 'A');

                  Append_To (Outer_Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Any,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_Any), Loc),
                      Expression =>
                        Make_Function_Call (Loc,
                          Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                          Parameter_Associations => New_List (
                            PolyORB_Support.Helpers.Build_TypeCode_Call
                              (Loc, Etyp, Outer_Decls)))));

                  Append_To (Outer_Statements,
                    Add_Parameter_To_NVList (Loc,
                      Parameter   => Current_Parameter,
                      NVList      => Arguments,
                      Constrained => Constrained,
                      Any         => Any));
               end if;

               if Is_First_Controlling_Formal then
                  declare
                     Addr : constant Entity_Id := Make_Temporary (Loc, 'A');

                     Is_Local : constant Entity_Id :=
                                  Make_Temporary (Loc, 'L');

                  begin
                     --  Special case: obtain the first controlling formal
                     --  from the target of the remote call, instead of the
                     --  argument list.

                     Append_To (Outer_Decls,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Addr,
                         Object_Definition =>
                           New_Occurrence_Of (RTE (RE_Address), Loc)));

                     Append_To (Outer_Decls,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Is_Local,
                         Object_Definition =>
                           New_Occurrence_Of (Standard_Boolean, Loc)));

                     Append_To (Outer_Statements,
                       Make_Procedure_Call_Statement (Loc,
                         Name =>
                           New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
                         Parameter_Associations => New_List (
                           Make_Selected_Component (Loc,
                             Prefix        =>
                               New_Occurrence_Of (
                                 Request_Parameter, Loc),
                             Selector_Name =>
                               Make_Identifier (Loc, Name_Target)),
                           New_Occurrence_Of (Is_Local, Loc),
                           New_Occurrence_Of (Addr, Loc))));

                     Expr := Unchecked_Convert_To (RACW_Type,
                       New_Occurrence_Of (Addr, Loc));
                  end;

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

                  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);

                  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;
                  end if;
               end if;

               Need_Extra_Constrained :=
                 Nkind (Parameter_Type (Current_Parameter)) /=
                                                         N_Access_Definition
                   and then
                     Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
                   and then
                     Present (Extra_Constrained
                       (Defining_Identifier (Current_Parameter)));

               --  We may not associate an extra constrained actual to a
               --  constant object, so if one is needed, declare the actual
               --  as a variable even if it won't be modified.

               Build_Actual_Object_Declaration
                 (Object   => Object,
                  Etyp     => Etyp,
                  Variable => Need_Extra_Constrained
                                or else Out_Present (Current_Parameter),
                  Expr     => Expr,
                  Decls    => Decls);
               Set_Etype (Object, Etyp);

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

               if Out_Present (Current_Parameter)
                 and then not Is_Controlling_Formal
               then
                  Append_To (After_Statements,
                    Make_Procedure_Call_Statement (Loc,
                      Name => New_Occurrence_Of (RTE (RE_Move_Any_Value), Loc),
                      Parameter_Associations => New_List (
                        New_Occurrence_Of (Any, Loc),
                        PolyORB_Support.Helpers.Build_To_Any_Call
                          (Loc,
                           New_Occurrence_Of (Object, Loc),
                           Decls,
                           Constrained => True))));
               end if;

               --  For RACW controlling formals, the Etyp of Object is always
               --  an RACW, even if the parameter is not of an anonymous access
               --  type. In such case, we need to dereference it at call time.

               if Is_Controlling_Formal then
                  if Nkind (Parameter_Type (Current_Parameter)) /=
                                                        N_Access_Definition
                  then
                     Append_To (Parameter_List,
                       Make_Parameter_Association (Loc,
                         Selector_Name             =>
                           New_Occurrence_Of
                             (Defining_Identifier (Current_Parameter), Loc),
                         Explicit_Actual_Parameter =>
                           Make_Explicit_Dereference (Loc,
                             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),

                         Explicit_Actual_Parameter =>
                           New_Occurrence_Of (Object, Loc)));
                  end if;

               else
                  Append_To (Parameter_List,
                    Make_Parameter_Association (Loc,
                      Selector_Name             =>
                        New_Occurrence_Of (
                          Defining_Identifier (Current_Parameter), Loc),
                      Explicit_Actual_Parameter =>
                        New_Occurrence_Of (Object, Loc)));
               end if;

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

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

               if Need_Extra_Constrained then
                  declare
                     Extra_Parameter : constant Entity_Id :=
                                         Extra_Constrained
                                           (Defining_Identifier
                                             (Current_Parameter));

                     Extra_Any : constant Entity_Id :=
                                   Make_Temporary (Loc, 'A');

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

                     Formal_Type : constant Entity_Id :=
                                     Etype (Extra_Parameter);

                  begin
                     Append_To (Outer_Decls,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Extra_Any,
                         Object_Definition   =>
                           New_Occurrence_Of (RTE (RE_Any), Loc),
                         Expression =>
                           Make_Function_Call (Loc,
                             Name =>
                               New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                             Parameter_Associations => New_List (
                               PolyORB_Support.Helpers.Build_TypeCode_Call
                                 (Loc, Formal_Type, Outer_Decls)))));

                     Append_To (Outer_Extra_Formal_Statements,
                       Add_Parameter_To_NVList (Loc,
                         Parameter   => Extra_Parameter,
                         NVList      => Arguments,
                         Constrained => True,
                         Any         => Extra_Any));

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

                     Append_To (Statements,
                       Make_Assignment_Statement (Loc,
                         Name => New_Occurrence_Of (Formal_Entity, Loc),
                         Expression =>
                           PolyORB_Support.Helpers.Build_From_Any_Call
                             (Formal_Type,
                              New_Occurrence_Of (Extra_Any, Loc),
                              Decls)));
                     Set_Extra_Constrained (Object, Formal_Entity);
                  end;
               end if;
            end;

            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),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Request_Parameter, Loc),
               New_Occurrence_Of (Arguments, Loc))));

         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 (Result_Definition (Specification (Vis_Decl)));
               Result : constant Node_Id   := Make_Temporary (Loc, 'R');

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

               if Is_Class_Wide_Type (Etyp) then

                  --  For a remote call to a function with a class-wide type,
                  --  check that the returned value satisfies the requirements
                  --  of (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),
                   Parameter_Associations => New_List (
                     New_Occurrence_Of (Request_Parameter, Loc),
                     PolyORB_Support.Helpers.Build_To_Any_Call
                       (Loc, New_Occurrence_Of (Result, Loc), Decls))));

               --  A DSA function does not have out or inout arguments
            end;

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

         else
            --  The remote subprogram is a procedure. We do not need any inner
            --  block in this case. No specific processing is required here for
            --  the dynamically asynchronous case: the indication of whether
            --  call is asynchronous or not is managed by the Sync_Scope
            --  attibute of the request, and is handled entirely in the
            --  protocol layer.

            Append_To (After_Statements,
              Make_Procedure_Call_Statement (Loc,
                Name => New_Occurrence_Of (RTE (RE_Request_Set_Out), Loc),
                Parameter_Associations => New_List (
                  New_Occurrence_Of (Request_Parameter, Loc))));

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

            Append_List_To (Statements, After_Statements);
         end if;

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

             Parameter_Specifications => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Request_Parameter,
                 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).

         if Asynchronous and then not Dynamically_Asynchronous then

            --  For an asynchronous procedure, add a null exception handler

            Excep_Handlers := New_List (
              Make_Implicit_Exception_Handler (Loc,
                Exception_Choices => New_List (Make_Others_Choice (Loc)),
                Statements        => New_List (Make_Null_Statement (Loc))));

         else
            --  In the other cases, if an exception is raised, then the
            --  exception occurrence is propagated.

            null;
         end if;

         Append_To (Outer_Statements,
           Make_Block_Statement (Loc,
             Declarations => Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Statements)));

         return
           Make_Subprogram_Body (Loc,
             Specification              => Subp_Spec,
             Declarations               => Outer_Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements         => Outer_Statements,
                 Exception_Handlers => Excep_Handlers));
      end Build_Subprogram_Receiving_Stubs;

      -------------
      -- Helpers --
      -------------

      package body Helpers is

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

         function Find_Numeric_Representation
           (Typ : Entity_Id) return Entity_Id;
         --  Given a numeric type Typ, return the smallest integer or modular
         --  type from Interfaces, or the smallest floating point type from
         --  Standard whose range encompasses that of Typ.

         function Is_Generic_Actual_Subtype (Typ : Entity_Id) return Boolean;
         --  Return true if Typ is a subtype representing a generic formal type
         --  as a subtype of the actual type in an instance. This is needed to
         --  recognize these subtypes because the Is_Generic_Actual_Type flag
         --  can only be relied upon within the instance.

         function Make_Helper_Function_Name
           (Loc : Source_Ptr;
            Typ : Entity_Id;
            Nam : Name_Id) return Entity_Id;
         --  Return the name to be assigned for helper subprogram Nam of Typ

         ------------------------------------------------------------
         -- Common subprograms for building various tree fragments --
         ------------------------------------------------------------

         function Build_Get_Aggregate_Element
           (Loc : Source_Ptr;
            Any : Entity_Id;
            TC  : Node_Id;
            Idx : Node_Id) return Node_Id;
         --  Build a call to Get_Aggregate_Element on Any for typecode TC,
         --  returning the Idx'th element.

         generic
            Subprogram : Entity_Id;
            --  Reference location for constructed nodes

            Arry : Entity_Id;
            --  For 'Range and Etype

            Indexes : List_Id;
            --  For the construction of the innermost element expression

            with procedure Add_Process_Element
              (Stmts   : List_Id;
               Any     : Entity_Id;
               Counter : Entity_Id;
               Datum   : Node_Id);

         procedure Append_Array_Traversal
           (Stmts   : List_Id;
            Any     : Entity_Id;
            Counter : Entity_Id := Empty;
            Depth   : Pos       := 1);
         --  Build nested loop statements that iterate over the elements of an
         --  array Arry. The statement(s) built by Add_Process_Element are
         --  executed for each element; 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
         --  appended to Stmts.

         generic
            Rec : Entity_Id;
            --  The record entity being dealt with

            with procedure Add_Process_Element
              (Stmts     : List_Id;
               Container : Node_Or_Entity_Id;
               Counter   : in out Nat;
               Rec       : Entity_Id;
               Field     : Node_Id);
            --  Rec is the instance of the record type, or Empty.
            --  Field is either the N_Defining_Identifier for a component,
            --  or an N_Variant_Part.

         procedure Append_Record_Traversal
           (Stmts     : List_Id;
            Clist     : Node_Id;
            Container : Node_Or_Entity_Id;
            Counter   : in out Nat);
         --  Process component list Clist. Individual fields are passed
         --  to Field_Processing. Each variant part is also processed.
         --  Container is the outer Any (for From_Any/To_Any),
         --  the outer typecode (for TC) to which the operation applies.

         -----------------------------
         -- Append_Record_Traversal --
         -----------------------------

         procedure Append_Record_Traversal
           (Stmts     : List_Id;
            Clist     : Node_Id;
            Container : Node_Or_Entity_Id;
            Counter   : in out Nat)
         is
            CI : List_Id;
            VP : Node_Id;
            --  Clist's Component_Items and Variant_Part

            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;

            if Present (VP) then
               Add_Process_Element (Stmts, Container, Counter, Rec, VP);
            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;
            Constrained : Boolean := False)
         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) and then not Constrained 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 --
         -------------------------

         function Build_From_Any_Call
           (Typ   : Entity_Id;
            N     : Node_Id;
            Decls : List_Id) return Node_Id
         is
            Loc : constant Source_Ptr := Sloc (N);

            U_Type : Entity_Id := Underlying_Type (Typ);

            Fnam    : Entity_Id;
            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_Subtype (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);

            --  For a user subtype, go to first subtype

            elsif Comes_From_Source (U_Type)
              and then Nkind (Declaration_Node (U_Type))
                         = N_Subtype_Declaration
            then
               U_Type := First_Subtype (U_Type);
            end if;

            --  Check first for Boolean and Character. These are enumeration
            --  types, but we treat them specially, since they may require
            --  special handling in the transfer protocol. However, this
            --  special handling only applies if they have standard
            --  representation, otherwise they are treated like any other
            --  enumeration type.

            if Present (Fnam) then
               null;

            elsif U_Type = Standard_Boolean then
               Lib_RE := RE_FA_B;

            elsif U_Type = Standard_Character then
               Lib_RE := RE_FA_C;

            elsif U_Type = Standard_Wide_Character then
               Lib_RE := RE_FA_WC;

            elsif U_Type = Standard_Wide_Wide_Character then
               Lib_RE := RE_FA_WWC;

            --  Floating point types

            elsif U_Type = Standard_Short_Float then
               Lib_RE := RE_FA_SF;

            elsif U_Type = Standard_Float then
               Lib_RE := RE_FA_F;

            elsif U_Type = Standard_Long_Float then
               Lib_RE := RE_FA_LF;

            elsif U_Type = Standard_Long_Long_Float then
               Lib_RE := RE_FA_LLF;

            --  Integer types

            elsif U_Type = RTE (RE_Integer_8) then
               Lib_RE := RE_FA_I8;

            elsif U_Type = RTE (RE_Integer_16) then
               Lib_RE := RE_FA_I16;

            elsif U_Type = RTE (RE_Integer_32) then
               Lib_RE := RE_FA_I32;

            elsif U_Type = RTE (RE_Integer_64) then
               Lib_RE := RE_FA_I64;

            --  Unsigned integer types

            elsif U_Type = RTE (RE_Unsigned_8) then
               Lib_RE := RE_FA_U8;

            elsif U_Type = RTE (RE_Unsigned_16) then
               Lib_RE := RE_FA_U16;

            elsif U_Type = RTE (RE_Unsigned_32) then
               Lib_RE := RE_FA_U32;

            elsif U_Type = RTE (RE_Unsigned_64) then
               Lib_RE := RE_FA_U64;

            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);
               end;
            end if;

            --  Call the function

            if Lib_RE /= RE_Null then
               pragma Assert (No (Fnam));
               Fnam := RTE (Lib_RE);
            end if;

            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;

         -----------------------------
         -- Build_From_Any_Function --
         -----------------------------

         procedure Build_From_Any_Function
           (Loc  : Source_Ptr;
            Typ  : Entity_Id;
            Decl : out Node_Id;
            Fnam : out Entity_Id)
         is
            Spec  : Node_Id;
            Decls : constant List_Id := New_List;
            Stms  : constant List_Id := New_List;

            Any_Parameter : constant Entity_Id := Make_Temporary (Loc, 'A');

            Use_Opaque_Representation : Boolean;

         begin
            --  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))),
                Result_Definition => New_Occurrence_Of (Typ, Loc));

            --  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)));

            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_Simple_Return_Statement (Loc,
                   Expression =>
                     OK_Convert_To (Typ,
                       Build_From_Any_Call
                         (Root_Type (Typ),
                          New_Occurrence_Of (Any_Parameter, Loc),
                          Decls))));

            elsif Is_Record_Type (Typ)
              and then not Is_Derived_Type (Typ)
              and then not Is_Tagged_Type (Typ)
            then
               if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
                  Append_To (Stms,
                    Make_Simple_Return_Statement (Loc,
                      Expression =>
                        Build_From_Any_Call
                          (Etype (Typ),
                           New_Occurrence_Of (Any_Parameter, Loc),
                           Decls)));

               else
                  declare
                     Disc                      : Entity_Id := Empty;
                     Discriminant_Associations : List_Id;
                     Rdef                      : constant Node_Id :=
                                                   Type_Definition
                                                     (Declaration_Node (Typ));
                     Component_Counter         : Nat := 0;

                     --  The returned object

                     Res : constant Entity_Id := Make_Temporary (Loc, 'R');

                     Res_Definition : Node_Id := New_Occurrence_Of (Typ, Loc);

                     procedure FA_Rec_Add_Process_Element
                       (Stmts   : List_Id;
                        Any     : Entity_Id;
                        Counter : in out Nat;
                        Rec     : Entity_Id;
                        Field   : Node_Id);

                     procedure FA_Append_Record_Traversal is
                        new Append_Record_Traversal
                          (Rec                 => Res,
                           Add_Process_Element => FA_Rec_Add_Process_Element);

                     --------------------------------
                     -- FA_Rec_Add_Process_Element --
                     --------------------------------

                     procedure FA_Rec_Add_Process_Element
                       (Stmts   : List_Id;
                        Any     : Entity_Id;
                        Counter : in out Nat;
                        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,
                                 Prefix        =>
                                   New_Occurrence_Of (Rec, Loc),
                                 Selector_Name =>
                                   New_Occurrence_Of (Field, Loc)),

                               Expression =>
                                 Build_From_Any_Call (Ctyp,
                                   Build_Get_Aggregate_Element (Loc,
                                     Any => Any,
                                     TC  =>
                                       Build_TypeCode_Call (Loc, Ctyp, Decls),
                                     Idx =>
                                       Make_Integer_Literal (Loc, Counter)),
                                   Decls)));

                        else
                           --  A variant part

                           declare
                              Variant        : Node_Id;
                              Struct_Counter : Nat := 0;

                              Block_Decls : constant List_Id := New_List;
                              Block_Stmts : constant List_Id := New_List;
                              VP_Stmts    : List_Id;

                              Alt_List    : constant List_Id := New_List;
                              Choice_List : List_Id;

                              Struct_Any : constant Entity_Id :=
                                             Make_Temporary (Loc, 'S');

                           begin
                              Append_To (Decls,
                                Make_Object_Declaration (Loc,
                                  Defining_Identifier => Struct_Any,
                                  Constant_Present    => True,
                                  Object_Definition   =>
                                     New_Occurrence_Of (RTE (RE_Any), Loc),
                                  Expression          =>
                                    Make_Function_Call (Loc,
                                      Name =>
                                        New_Occurrence_Of
                                          (RTE (RE_Extract_Union_Value), Loc),

                                      Parameter_Associations => New_List (
                                        Build_Get_Aggregate_Element (Loc,
                                          Any => Any,
                                          TC  =>
                                            Make_Function_Call (Loc,
                                              Name => New_Occurrence_Of (
                                                RTE (RE_Any_Member_Type), Loc),
                                              Parameter_Associations =>
                                                New_List (
                                                  New_Occurrence_Of (Any, Loc),
                                                  Make_Integer_Literal (Loc,
                                                    Intval => Counter))),
                                          Idx =>
                                            Make_Integer_Literal (Loc,
                                             Intval => Counter))))));

                              Append_To (Stmts,
                                Make_Block_Statement (Loc,
                                  Declarations => Block_Decls,
                                  Handled_Statement_Sequence =>
                                    Make_Handled_Sequence_Of_Statements (Loc,
                                      Statements => Block_Stmts)));

                              Append_To (Block_Stmts,
                                Make_Case_Statement (Loc,
                                    Expression =>
                                      Make_Selected_Component (Loc,
                                        Prefix        => Rec,
                                        Selector_Name => Chars (Name (Field))),
                                    Alternatives => Alt_List));

                              Variant := First_Non_Pragma (Variants (Field));
                              while Present (Variant) loop
                                 Choice_List :=
                                   New_Copy_List_Tree
                                     (Discrete_Choices (Variant));

                                 VP_Stmts := New_List;

                                 --  Struct_Counter should be reset before
                                 --  handling a variant part. Indeed only one
                                 --  of the case statement alternatives will be
                                 --  executed at run time, so the counter must
                                 --  start at 0 for every case statement.

                                 Struct_Counter := 0;

                                 FA_Append_Record_Traversal (
                                   Stmts     => VP_Stmts,
                                   Clist     => Component_List (Variant),
                                   Container => Struct_Any,
                                   Counter   => Struct_Counter);

                                 Append_To (Alt_List,
                                   Make_Case_Statement_Alternative (Loc,
                                     Discrete_Choices => Choice_List,
                                     Statements       => VP_Stmts));
                                 Next_Non_Pragma (Variant);
                              end loop;
                           end;
                        end if;

                        Counter := Counter + 1;
                     end FA_Rec_Add_Process_Element;

                  begin
                     --  First all discriminants

                     if Has_Discriminants (Typ) then
                        Discriminant_Associations := New_List;

                        Disc := First_Discriminant (Typ);
                        while Present (Disc) loop
                           declare
                              Disc_Var_Name : constant Entity_Id :=
                                                Make_Defining_Identifier (Loc,
                                                  Chars => Chars (Disc));
                              Disc_Type     : constant Entity_Id :=
                                                Etype (Disc);

                           begin
                              Append_To (Decls,
                                Make_Object_Declaration (Loc,
                                  Defining_Identifier => Disc_Var_Name,
                                  Constant_Present    => True,
                                  Object_Definition   =>
                                    New_Occurrence_Of (Disc_Type, Loc),

                                  Expression =>
                                    Build_From_Any_Call (Disc_Type,
                                      Build_Get_Aggregate_Element (Loc,
                                        Any => Any_Parameter,
                                        TC  => Build_TypeCode_Call
                                                 (Loc, Disc_Type, Decls),
                                        Idx => Make_Integer_Literal (Loc,
                                               Intval => Component_Counter)),
                                      Decls)));

                              Component_Counter := Component_Counter + 1;

                              Append_To (Discriminant_Associations,
                                Make_Discriminant_Association (Loc,
                                  Selector_Names => New_List (
                                    New_Occurrence_Of (Disc, Loc)),
                                  Expression =>
                                    New_Occurrence_Of (Disc_Var_Name, Loc)));
                           end;
                           Next_Discriminant (Disc);
                        end loop;

                        Res_Definition :=
                          Make_Subtype_Indication (Loc,
                            Subtype_Mark => Res_Definition,
                            Constraint   =>
                              Make_Index_Or_Discriminant_Constraint (Loc,
                                Discriminant_Associations));
                     end if;

                     --  Now we have all the discriminants in variables, we can
                     --  declared a constrained object. Note that we are not
                     --  initializing (non-discriminant) components directly in
                     --  the object declarations, because which fields to
                     --  initialize depends (at run time) on the discriminant
                     --  values.

                     Append_To (Decls,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Res,
                         Object_Definition   => Res_Definition));

                     --  ... then all components

                     FA_Append_Record_Traversal (Stms,
                       Clist     => Component_List (Rdef),
                       Container => Any_Parameter,
                       Counter   => Component_Counter);

                     Append_To (Stms,
                       Make_Simple_Return_Statement (Loc,
                         Expression => New_Occurrence_Of (Res, Loc)));
                  end;
               end if;

            elsif Is_Array_Type (Typ) then
               declare
                  Constrained : constant Boolean := Is_Constrained (Typ);

                  procedure FA_Ary_Add_Process_Element
                    (Stmts   : List_Id;
                     Any     : Entity_Id;
                     Counter : Entity_Id;
                     Datum   : Node_Id);
                  --  Assign the current element (as identified by Counter) of
                  --  Any to the variable denoted by name Datum, and advance
                  --  Counter by 1. If Datum is not an Any, a call to From_Any
                  --  for its type is inserted.

                  --------------------------------
                  -- FA_Ary_Add_Process_Element --
                  --------------------------------

                  procedure FA_Ary_Add_Process_Element
                    (Stmts   : List_Id;
                     Any     : Entity_Id;
                     Counter : Entity_Id;
                     Datum   : Node_Id)
                  is
                     Assignment : constant Node_Id :=
                       Make_Assignment_Statement (Loc,
                         Name       => Datum,
                         Expression => Empty);

                     Element_Any : Node_Id;

                  begin
                     declare
                        Element_TC : Node_Id;

                     begin
                        if Etype (Datum) = RTE (RE_Any) then

                           --  When Datum is an Any the Etype field is not
                           --  sufficient to determine the typecode of Datum
                           --  (which can be a TC_SEQUENCE or TC_ARRAY
                           --  depending on the value of Constrained).

                           --  Therefore we retrieve the typecode which has
                           --  been constructed in Append_Array_Traversal with
                           --  a call to Get_Any_Type.

                           Element_TC :=
                             Make_Function_Call (Loc,
                               Name => New_Occurrence_Of (
                                 RTE (RE_Get_Any_Type), Loc),
                               Parameter_Associations => New_List (
                                 New_Occurrence_Of (Entity (Datum), Loc)));
                        else
                           --  For non Any Datum we simply construct a typecode
                           --  matching the Etype of the Datum.

                           Element_TC := Build_TypeCode_Call
                              (Loc, Etype (Datum), Decls);
                        end if;

                        Element_Any :=
                          Build_Get_Aggregate_Element (Loc,
                            Any => Any,
                            TC  => Element_TC,
                            Idx => New_Occurrence_Of (Counter, Loc));
                     end;

                     --  Note: here we *prepend* statements to Stmts, so
                     --  we must do it in reverse order.

                     Prepend_To (Stmts,
                       Make_Assignment_Statement (Loc,
                         Name =>
                           New_Occurrence_Of (Counter, Loc),
                         Expression =>
                           Make_Op_Add (Loc,
                             Left_Opnd  => New_Occurrence_Of (Counter, Loc),
                             Right_Opnd => Make_Integer_Literal (Loc, 1))));

                     if Nkind (Datum) /= N_Attribute_Reference then

                        --  We ignore the value of the length of each
                        --  dimension, since the target array has already been
                        --  constrained anyway.

                        if Etype (Datum) /= RTE (RE_Any) then
                           Set_Expression (Assignment,
                              Build_From_Any_Call
                                (Component_Type (Typ), Element_Any, Decls));
                        else
                           Set_Expression (Assignment, Element_Any);
                        end if;

                        Prepend_To (Stmts, Assignment);
                     end if;
                  end FA_Ary_Add_Process_Element;

                  ------------------------
                  -- Local Declarations --
                  ------------------------

                  Counter : constant Entity_Id :=
                              Make_Defining_Identifier (Loc, Name_J);

                  Initial_Counter_Value : Int := 0;

                  Component_TC : constant Entity_Id :=
                                   Make_Defining_Identifier (Loc, Name_T);

                  Res : constant Entity_Id :=
                          Make_Defining_Identifier (Loc, Name_R);

                  procedure Append_From_Any_Array_Iterator is
                    new Append_Array_Traversal (
                      Subprogram => Fnam,
                      Arry       => Res,
                      Indexes    => New_List,
                      Add_Process_Element => FA_Ary_Add_Process_Element);

                  Res_Subtype_Indication : Node_Id :=
                                             New_Occurrence_Of (Typ, Loc);

               begin
                  if not Constrained then
                     declare
                        Ndim : constant Int := Number_Dimensions (Typ);
                        Lnam : Name_Id;
                        Hnam : Name_Id;
                        Indx : Node_Id := First_Index (Typ);
                        Indt : Entity_Id;

                        Ranges : constant List_Id := New_List;

                     begin
                        for J in 1 .. Ndim loop
                           Lnam := New_External_Name ('L', J);
                           Hnam := New_External_Name ('H', J);

                           --  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,
                               Object_Definition   =>
                                 New_Occurrence_Of (Indt, Loc),
                               Expression          =>
                                 Build_From_Any_Call
                                   (Indt,
                                    Build_Get_Aggregate_Element (Loc,
                                      Any => Any_Parameter,
                                      TC  => Build_TypeCode_Call
                                               (Loc, Indt, Decls),
                                      Idx =>
                                        Make_Integer_Literal (Loc, J - 1)),
                                   Decls)));

                           Append_To (Decls,
                             Make_Object_Declaration (Loc,
                               Defining_Identifier =>
                                 Make_Defining_Identifier (Loc, Hnam),

                               Constant_Present => True,

                               Object_Definition =>
                                 New_Occurrence_Of (Indt, Loc),

                               Expression => Make_Attribute_Reference (Loc,
                                 Prefix         =>
                                   New_Occurrence_Of (Indt, Loc),

                                 Attribute_Name => Name_Val,

                                 Expressions    => New_List (
                                   Make_Op_Subtract (Loc,
                                     Left_Opnd =>
                                       Make_Op_Add (Loc,
                                         Left_Opnd =>
                                           OK_Convert_To
                                             (Standard_Long_Integer,
                                              Make_Identifier (Loc, Lnam)),

                                         Right_Opnd =>
                                           OK_Convert_To
                                             (Standard_Long_Integer,
                                              Make_Function_Call (Loc,
                                                Name =>
                                                  New_Occurrence_Of (RTE (
                                                  RE_Get_Nested_Sequence_Length
                                                  ), Loc),
                                                Parameter_Associations =>
                                                  New_List (
                                                    New_Occurrence_Of (
                                                      Any_Parameter, Loc),
                                                    Make_Integer_Literal (Loc,
                                                      Intval => J))))),

                                     Right_Opnd =>
                                       Make_Integer_Literal (Loc, 1))))));

                           Append_To (Ranges,
                             Make_Range (Loc,
                               Low_Bound  => Make_Identifier (Loc, Lnam),
                               High_Bound => Make_Identifier (Loc, Hnam)));

                           Next_Index (Indx);
                        end loop;

                        --  Now we have all the necessary bound information:
                        --  apply the set of range constraints to the
                        --  (unconstrained) nominal subtype of Res.

                        Initial_Counter_Value := Ndim;
                        Res_Subtype_Indication := Make_Subtype_Indication (Loc,
                          Subtype_Mark => Res_Subtype_Indication,
                          Constraint   =>
                            Make_Index_Or_Discriminant_Constraint (Loc,
                              Constraints => Ranges));
                     end;
                  end if;

                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Res,
                      Object_Definition => Res_Subtype_Indication));
                  Set_Etype (Res, Typ);

                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Counter,
                      Object_Definition =>
                        New_Occurrence_Of (RTE (RE_Unsigned_32), Loc),
                      Expression =>
                        Make_Integer_Literal (Loc, Initial_Counter_Value)));

                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Component_TC,
                      Constant_Present    => True,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_TypeCode), Loc),
                      Expression          =>
                        Build_TypeCode_Call (Loc,
                          Component_Type (Typ), Decls)));

                  Append_From_Any_Array_Iterator
                    (Stms, Any_Parameter, Counter);

                  Append_To (Stms,
                    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_Simple_Return_Statement (Loc,
                   Expression =>
                     Unchecked_Convert_To (Typ,
                       Build_From_Any_Call
                         (Find_Numeric_Representation (Typ),
                          New_Occurrence_Of (Any_Parameter, Loc),
                          Decls))));

            else
               Use_Opaque_Representation := True;
            end if;

            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 :=
              Make_Subprogram_Body (Loc,
                Specification => Spec,
                Declarations => Decls,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => Stms));
         end Build_From_Any_Function;

         ---------------------------------
         -- Build_Get_Aggregate_Element --
         ---------------------------------

         function Build_Get_Aggregate_Element
           (Loc : Source_Ptr;
            Any : Entity_Id;
            TC  : Node_Id;
            Idx : Node_Id) return Node_Id
         is
         begin
            return Make_Function_Call (Loc,
              Name =>
                New_Occurrence_Of (RTE (RE_Get_Aggregate_Element), Loc),
              Parameter_Associations => New_List (
                New_Occurrence_Of (Any, Loc),
                TC,
                Idx));
         end Build_Get_Aggregate_Element;

         ----------------------------------
         -- Build_Name_And_Repository_Id --
         ----------------------------------

         procedure Build_Name_And_Repository_Id
           (E           : Entity_Id;
            Name_Str    : out String_Id;
            Repo_Id_Str : out String_Id)
         is
         begin
            Name_Str := Fully_Qualified_Name_String (E, Append_NUL => False);
            Start_String;
            Store_String_Chars ("DSA:");
            Store_String_Chars (Name_Str);
            Store_String_Chars (":1.0");
            Repo_Id_Str := End_String;
         end Build_Name_And_Repository_Id;

         -----------------------
         -- Build_To_Any_Call --
         -----------------------

         function Build_To_Any_Call
           (Loc         : Source_Ptr;
            N           : Node_Id;
            Decls       : List_Id;
            Constrained : Boolean := False) return Node_Id
         is
            Typ    : Entity_Id := Etype (N);
            U_Type : Entity_Id;
            C_Type : Entity_Id;
            Fnam   : Entity_Id;
            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 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));

            --  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.

            Fnam := Find_Inherited_TSS (U_Type, TSS_To_Any);

            --  For the subtype representing a generic actual type, go to the
            --  actual type.

            if Is_Generic_Actual_Subtype (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);

            --  For a user subtype, go to first subtype

            elsif Comes_From_Source (U_Type)
              and then Nkind (Declaration_Node (U_Type))
                         = N_Subtype_Declaration
            then
               U_Type := First_Subtype (U_Type);
            end if;

            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;

            elsif U_Type = Standard_Character then
               Lib_RE := RE_TA_C;

            elsif U_Type = Standard_Wide_Character then
               Lib_RE := RE_TA_WC;

            elsif U_Type = Standard_Wide_Wide_Character then
               Lib_RE := RE_TA_WWC;

            --  Floating point types

            elsif U_Type = Standard_Short_Float then
               Lib_RE := RE_TA_SF;

            elsif U_Type = Standard_Float then
               Lib_RE := RE_TA_F;

            elsif U_Type = Standard_Long_Float then
               Lib_RE := RE_TA_LF;

            elsif U_Type = Standard_Long_Long_Float then
               Lib_RE := RE_TA_LLF;

            --  Integer types

            elsif U_Type = RTE (RE_Integer_8) then
               Lib_RE := RE_TA_I8;

            elsif U_Type = RTE (RE_Integer_16) then
               Lib_RE := RE_TA_I16;

            elsif U_Type = RTE (RE_Integer_32) then
               Lib_RE := RE_TA_I32;

            elsif U_Type = RTE (RE_Integer_64) then
               Lib_RE := RE_TA_I64;

            --  Unsigned integer types

            elsif U_Type = RTE (RE_Unsigned_8) then
               Lib_RE := RE_TA_U8;

            elsif U_Type = RTE (RE_Unsigned_16) then
               Lib_RE := RE_TA_U16;

            elsif U_Type = RTE (RE_Unsigned_32) then
               Lib_RE := RE_TA_U32;

            elsif U_Type = RTE (RE_Unsigned_64) then
               Lib_RE := RE_TA_U64;

            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

            else
               declare
                  Decl : Entity_Id;
               begin
                  Build_To_Any_Function (Loc, U_Type, Decl, Fnam);
                  Append_To (Decls, Decl);
               end;
            end if;

            --  Call the function

            if Lib_RE /= RE_Null then
               pragma Assert (No (Fnam));
               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;

            declare
               Params : constant List_Id :=
                 New_List (OK_Convert_To (C_Type, N));
            begin
               if Is_Limited_Type (C_Type) then
                  Append_To (Params,
                    New_Occurrence_Of (Boolean_Literals (Constrained), Loc));
               end if;

               return
                   Make_Function_Call (Loc,
                     Name                   => New_Occurrence_Of (Fnam, Loc),
                     Parameter_Associations => Params);
            end;
         end Build_To_Any_Call;

         ---------------------------
         -- Build_To_Any_Function --
         ---------------------------

         procedure Build_To_Any_Function
           (Loc  : Source_Ptr;
            Typ  : Entity_Id;
            Decl : out Node_Id;
            Fnam : out Entity_Id)
         is
            Spec   : Node_Id;
            Params : List_Id;
            Decls  : List_Id;
            Stms   : List_Id;

            Expr_Formal : Entity_Id;
            Cstr_Formal : Entity_Id := Empty;  -- initialize to prevent warning
            Any         : Entity_Id;
            Result_TC   : Node_Id;

            Any_Decl  : Node_Id;

            Use_Opaque_Representation : Boolean;
            --  When True, use stream attributes and represent type as an
            --  opaque sequence of bytes.

         begin
            --  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;

            Decls := New_List;
            Stms  := New_List;

            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);

            Expr_Formal := Make_Defining_Identifier (Loc, Name_E);
            Params := New_List (
              Make_Parameter_Specification (Loc,
                Defining_Identifier => Expr_Formal,
                Parameter_Type      => New_Occurrence_Of (Typ, Loc)));
            Set_Etype (Expr_Formal, Typ);

            if Is_Limited_Type (Typ) then
               Cstr_Formal := Make_Defining_Identifier (Loc, Name_C);
               Append_To (Params,
                 Make_Parameter_Specification (Loc,
                   Defining_Identifier => Cstr_Formal,
                   Parameter_Type      =>
                     New_Occurrence_Of (Standard_Boolean, Loc)));
            end if;

            Spec :=
              Make_Function_Specification (Loc,
                Defining_Unit_Name       => Fnam,
                Parameter_Specifications => Params,
                Result_Definition        =>
                  New_Occurrence_Of (RTE (RE_Any), Loc));

            Any_Decl :=
              Make_Object_Declaration (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

               --  Untagged derived type: convert to root type

               declare
                  Rt_Type : constant Entity_Id := Root_Type (Typ);
                  Expr    : constant Node_Id :=
                              OK_Convert_To
                                (Rt_Type,
                                 New_Occurrence_Of (Expr_Formal, Loc));
               begin
                  Set_Expression (Any_Decl,
                    Build_To_Any_Call (Loc, Expr, Decls));
               end;

            elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then

               --  Untagged 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_Formal, Loc));

                  begin
                     Set_Expression
                       (Any_Decl, Build_To_Any_Call (Loc, 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  : Nat := 0;
                     Elements : constant List_Id := New_List;

                     procedure TA_Rec_Add_Process_Element
                       (Stmts     : List_Id;
                        Container : Node_Or_Entity_Id;
                        Counter   : in out Nat;
                        Rec       : Entity_Id;
                        Field     : Node_Id);
                     --  Processing routine for traversal below

                     procedure TA_Append_Record_Traversal is
                        new Append_Record_Traversal
                          (Rec                 => Expr_Formal,
                           Add_Process_Element => TA_Rec_Add_Process_Element);

                     --------------------------------
                     -- TA_Rec_Add_Process_Element --
                     --------------------------------

                     procedure TA_Rec_Add_Process_Element
                       (Stmts     : List_Id;
                        Container : Node_Or_Entity_Id;
                        Counter   : in out Nat;
                        Rec       : Entity_Id;
                        Field     : Node_Id)
                     is
                        Field_Ref : Node_Id;

                     begin
                        if Nkind (Field) = N_Defining_Identifier then

                           --  A regular component

                           Field_Ref := Make_Selected_Component (Loc,
                             Prefix        => New_Occurrence_Of (Rec, Loc),
                             Selector_Name => New_Occurrence_Of (Field, Loc));
                           Set_Etype (Field_Ref, Etype (Field));

                           Append_To (Stmts,
                             Make_Procedure_Call_Statement (Loc,
                               Name =>
                                 New_Occurrence_Of (
                                   RTE (RE_Add_Aggregate_Element), Loc),
                               Parameter_Associations => New_List (
                                 New_Occurrence_Of (Container, Loc),
                                 Build_To_Any_Call (Loc, Field_Ref, Decls))));

                        else
                           --  A variant part

                           Variant_Part : declare
                              Variant        : Node_Id;
                              Struct_Counter : Nat := 0;

                              Block_Decls : constant List_Id := New_List;
                              Block_Stmts : constant List_Id := New_List;
                              VP_Stmts    : List_Id;

                              Alt_List    : constant List_Id := New_List;
                              Choice_List : List_Id;

                              Union_Any : constant Entity_Id :=
                                            Make_Temporary (Loc, 'V');

                              Struct_Any : constant Entity_Id :=
                                             Make_Temporary (Loc, 'S');

                              function Make_Discriminant_Reference
                                return Node_Id;
                              --  Build reference to the discriminant for this
                              --  variant part.

                              ---------------------------------
                              -- Make_Discriminant_Reference --
                              ---------------------------------

                              function Make_Discriminant_Reference
                                return Node_Id
                              is
                                 Nod : constant Node_Id :=
                                         Make_Selected_Component (Loc,
                                           Prefix        => Rec,
                                           Selector_Name =>
                                             Chars (Name (Field)));
                              begin
                                 Set_Etype (Nod, Etype (Name (Field)));
                                 return Nod;
                              end Make_Discriminant_Reference;

                           --  Start of processing for Variant_Part

                           begin
                              Append_To (Stmts,
                                Make_Block_Statement (Loc,
                                  Declarations =>
                                    Block_Decls,
                                  Handled_Statement_Sequence =>
                                    Make_Handled_Sequence_Of_Statements (Loc,
                                      Statements => Block_Stmts)));

                              --  Declare variant part aggregate (Union_Any).
                              --  Knowing the position of this VP in the
                              --  variant record, we can fetch the VP typecode
                              --  from Container.

                              Append_To (Block_Decls,
                                Make_Object_Declaration (Loc,
                                  Defining_Identifier => Union_Any,
                                  Object_Definition   =>
                                    New_Occurrence_Of (RTE (RE_Any), Loc),
                                  Expression =>
                                    Make_Function_Call (Loc,
                                      Name => New_Occurrence_Of (
                                                RTE (RE_Create_Any), Loc),
                                      Parameter_Associations => New_List (
                                        Make_Function_Call (Loc,
                                          Name =>
                                            New_Occurrence_Of (
                                              RTE (RE_Any_Member_Type), Loc),
                                          Parameter_Associations => New_List (
                                            New_Occurrence_Of (Container, Loc),
                                            Make_Integer_Literal (Loc,
                                              Counter)))))));

                              --  Declare inner struct aggregate (which
                              --  contains the components of this VP).

                              Append_To (Block_Decls,
                                Make_Object_Declaration (Loc,
                                  Defining_Identifier => Struct_Any,
                                  Object_Definition   =>
                                    New_Occurrence_Of (RTE (RE_Any), Loc),
                                  Expression =>
                                    Make_Function_Call (Loc,
                                      Name => New_Occurrence_Of (
                                        RTE (RE_Create_Any), Loc),
                                      Parameter_Associations => New_List (
                                        Make_Function_Call (Loc,
                                          Name =>
                                            New_Occurrence_Of (
                                              RTE (RE_Any_Member_Type), Loc),
                                          Parameter_Associations => New_List (
                                            New_Occurrence_Of (Union_Any, Loc),
                                            Make_Integer_Literal (Loc,
                                              Uint_1)))))));

                              --  Build case statement

                              Append_To (Block_Stmts,
                                Make_Case_Statement (Loc,
                                  Expression   => Make_Discriminant_Reference,
                                  Alternatives => Alt_List));

                              Variant := First_Non_Pragma (Variants (Field));
                              while Present (Variant) loop
                                 Choice_List := New_Copy_List_Tree
                                   (Discrete_Choices (Variant));

                                 VP_Stmts := New_List;

                                 --  Append discriminant val to union aggregate

                                 Append_To (VP_Stmts,
                                    Make_Procedure_Call_Statement (Loc,
                                      Name =>
                                        New_Occurrence_Of (
                                          RTE (RE_Add_Aggregate_Element), Loc),
                                      Parameter_Associations => New_List (
                                        New_Occurrence_Of (Union_Any, Loc),
                                          Build_To_Any_Call
                                            (Loc,
                                             Make_Discriminant_Reference,
                                             Block_Decls))));

                                 --  Populate inner struct aggregate

                                 --  Struct_Counter should be reset before
                                 --  handling a variant part. Indeed only one
                                 --  of the case statement alternatives will be
                                 --  executed at run time, so the counter must
                                 --  start at 0 for every case statement.

                                 Struct_Counter := 0;

                                 TA_Append_Record_Traversal
                                   (Stmts     => VP_Stmts,
                                    Clist     => Component_List (Variant),
                                    Container => Struct_Any,
                                    Counter   => Struct_Counter);

                                 --  Append inner struct to union aggregate

                                 Append_To (VP_Stmts,
                                   Make_Procedure_Call_Statement (Loc,
                                     Name =>
                                       New_Occurrence_Of
                                         (RTE (RE_Add_Aggregate_Element), Loc),
                                     Parameter_Associations => New_List (
                                       New_Occurrence_Of (Union_Any, Loc),
                                       New_Occurrence_Of (Struct_Any, Loc))));

                                 --  Append union to outer aggregate

                                 Append_To (VP_Stmts,
                                   Make_Procedure_Call_Statement (Loc,
                                     Name =>
                                       New_Occurrence_Of
                                         (RTE (RE_Add_Aggregate_Element), Loc),
                                       Parameter_Associations => New_List (
                                          New_Occurrence_Of (Container, Loc),
                                          New_Occurrence_Of
                                            (Union_Any, Loc))));

                                 Append_To (Alt_List,
                                   Make_Case_Statement_Alternative (Loc,
                                     Discrete_Choices => Choice_List,
                                     Statements       => VP_Stmts));

                                 Next_Non_Pragma (Variant);
                              end loop;
                           end Variant_Part;
                        end if;

                        Counter := Counter + 1;
                     end TA_Rec_Add_Process_Element;

                  begin
                     --  Records are encoded in a TC_STRUCT aggregate:

                     --  -- Outer aggregate (TC_STRUCT)
                     --  | [discriminant1]
                     --  | [discriminant2]
                     --  | ...
                     --  |
                     --  | [component1]
                     --  | [component2]
                     --  | ...

                     --  A component can be a common component or variant part

                     --  A variant part is encoded as a TC_UNION aggregate:

                     --  -- Variant Part Aggregate (TC_UNION)
                     --  | [discriminant choice for this Variant Part]
                     --  |
                     --  | -- Inner struct (TC_STRUCT)
                     --  | |  [component1]
                     --  | |  [component2]
                     --  | |  ...

                     --  Let's start by building the outer aggregate. First we
                     --  construct Elements array containing all discriminants.

                     if Has_Discriminants (Typ) then
                        Disc := First_Discriminant (Typ);
                        while Present (Disc) loop
                           declare
                              Discriminant : constant Entity_Id :=
                                Make_Selected_Component (Loc,
                                  Prefix        => Expr_Formal,
                                  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 (Loc,
                                      Discriminant, Decls)));
                           end;

                           Counter := Counter + 1;
                           Next_Discriminant (Disc);
                        end loop;

                     else
                        --  If there are no discriminants, we declare an empty
                        --  Elements array.

                        declare
                           Dummy_Any : constant Entity_Id :=
                                         Make_Temporary (Loc, 'A');

                        begin
                           Append_To (Decls,
                             Make_Object_Declaration (Loc,
                               Defining_Identifier => Dummy_Any,
                               Object_Definition   =>
                                 New_Occurrence_Of (RTE (RE_Any), Loc)));

                           Append_To (Elements,
                             Make_Component_Association (Loc,
                               Choices => New_List (
                                 Make_Range (Loc,
                                   Low_Bound  =>
                                     Make_Integer_Literal (Loc, 1),
                                   High_Bound =>
                                     Make_Integer_Literal (Loc, 0))),
                               Expression =>
                                 New_Occurrence_Of (Dummy_Any, Loc)));
                        end;
                     end if;

                     --  We build the result aggregate with discriminants
                     --  as the first elements.

                     Set_Expression (Any_Decl,
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of
                                   (RTE (RE_Any_Aggregate_Build), Loc),
                         Parameter_Associations => New_List (
                           Result_TC,
                           Make_Aggregate (Loc,
                             Component_Associations => Elements))));
                     Result_TC := Empty;

                     --  Then we append all the components to the result
                     --  aggregate.

                     TA_Append_Record_Traversal (Stms,
                       Clist     => Component_List (Rdef),
                       Container => Any,
                       Counter   => Counter);
                  end;
               end if;

            elsif Is_Array_Type (Typ) then

               --  Constrained and unconstrained array types

               declare
                  Constrained : constant Boolean :=
                                  not Transmit_As_Unconstrained (Typ);

                  procedure TA_Ary_Add_Process_Element
                    (Stmts   : List_Id;
                     Any     : Entity_Id;
                     Counter : Entity_Id;
                     Datum   : Node_Id);

                  --------------------------------
                  -- TA_Ary_Add_Process_Element --
                  --------------------------------

                  procedure TA_Ary_Add_Process_Element
                    (Stmts   : List_Id;
                     Any     : Entity_Id;
                     Counter : Entity_Id;
                     Datum   : Node_Id)
                  is
                     pragma Unreferenced (Counter);

                     Element_Any : Node_Id;

                  begin
                     if Etype (Datum) = RTE (RE_Any) then
                        Element_Any := Datum;
                     else
                        Element_Any := Build_To_Any_Call (Loc, Datum, Decls);
                     end if;

                     Append_To (Stmts,
                       Make_Procedure_Call_Statement (Loc,
                         Name => New_Occurrence_Of (
                                   RTE (RE_Add_Aggregate_Element), Loc),
                         Parameter_Associations => New_List (
                           New_Occurrence_Of (Any, Loc),
                           Element_Any)));
                  end TA_Ary_Add_Process_Element;

                  procedure Append_To_Any_Array_Iterator is
                    new Append_Array_Traversal (
                      Subprogram => Fnam,
                      Arry       => Expr_Formal,
                      Indexes    => New_List,
                      Add_Process_Element => TA_Ary_Add_Process_Element);

                  Index : Node_Id;

               begin
                  Set_Expression (Any_Decl,
                    Make_Function_Call (Loc,
                      Name                   =>
                        New_Occurrence_Of (RTE (RE_Create_Any), Loc),
                      Parameter_Associations => New_List (Result_TC)));
                  Result_TC := Empty;

                  if not Constrained then
                     Index := First_Index (Typ);
                     for J in 1 .. Number_Dimensions (Typ) loop
                        Append_To (Stms,
                          Make_Procedure_Call_Statement (Loc,
                            Name                   =>
                              New_Occurrence_Of
                                (RTE (RE_Add_Aggregate_Element), Loc),
                            Parameter_Associations => New_List (
                              New_Occurrence_Of (Any, Loc),
                              Build_To_Any_Call (Loc,
                                OK_Convert_To (Etype (Index),
                                  Make_Attribute_Reference (Loc,
                                    Prefix         =>
                                      New_Occurrence_Of (Expr_Formal, Loc),
                                    Attribute_Name => Name_First,
                                    Expressions    => New_List (
                                      Make_Integer_Literal (Loc, J)))),
                                Decls))));
                        Next_Index (Index);
                     end loop;
                  end if;

                  Append_To_Any_Array_Iterator (Stms, Any);
               end;

            elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then

               --  Integer types

               Set_Expression (Any_Decl,
                 Build_To_Any_Call (Loc,
                   OK_Convert_To (
                     Find_Numeric_Representation (Typ),
                     New_Occurrence_Of (Expr_Formal, Loc)),
                   Decls));

            else
               --  Default case, including tagged types: opaque representation

               Use_Opaque_Representation := True;
            end if;

            if Use_Opaque_Representation then
               declare
                  Strm : constant Entity_Id := Make_Temporary (Loc, 'S');
                  --  Stream used to store data representation produced by
                  --  stream attribute.

               begin
                  --  Generate:
                  --    Strm : aliased Buffer_Stream_Type;

                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Strm,
                      Aliased_Present     => True,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));

                  --  Generate:
                  --    T'Output (Strm'Access, E);
                  --  or
                  --    T'Write (Strm'Access, E);
                  --  depending on whether to transmit as unconstrained.

                  --  For limited types, select at run time depending on
                  --  Constrained parameter.

                  declare
                     function Stream_Call (Attr : Name_Id) return Node_Id;
                     --  Return a call to the named attribute

                     -----------------
                     -- Stream_Call --
                     -----------------

                     function Stream_Call (Attr : Name_Id) return Node_Id is
                     begin
                        return Make_Attribute_Reference (Loc,
                                 Prefix         =>
                                   New_Occurrence_Of (Typ, Loc),
                                 Attribute_Name => Attr,
                                 Expressions    => New_List (
                                   Make_Attribute_Reference (Loc,
                                     Prefix         =>
                                       New_Occurrence_Of (Strm, Loc),
                                     Attribute_Name => Name_Access),
                                   New_Occurrence_Of (Expr_Formal, Loc)));

                     end Stream_Call;

                  begin
                     if Is_Limited_Type (Typ) then
                        Append_To (Stms,
                          Make_Implicit_If_Statement (Typ,
                            Condition       =>
                              New_Occurrence_Of (Cstr_Formal, Loc),
                            Then_Statements => New_List (
                              Stream_Call (Name_Write)),
                            Else_Statements => New_List (
                              Stream_Call (Name_Output))));

                     elsif Transmit_As_Unconstrained (Typ) then
                        Append_To (Stms, Stream_Call (Name_Output));

                     else
                        Append_To (Stms, Stream_Call (Name_Write));
                     end if;
                  end;

                  --  Generate:
                  --    BS_To_Any (Strm, A);

                  Append_To (Stms,
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of (RTE (RE_BS_To_Any), Loc),
                      Parameter_Associations => New_List (
                        New_Occurrence_Of (Strm, Loc),
                        New_Occurrence_Of (Any, Loc))));

                  --  Generate:
                  --    Release_Buffer (Strm);

                  Append_To (Stms,
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
                      Parameter_Associations => New_List (
                        New_Occurrence_Of (Strm, Loc))));
               end;
            end if;

            Append_To (Decls, Any_Decl);

            if Present (Result_TC) then
               Append_To (Stms,
                 Make_Procedure_Call_Statement (Loc,
                   Name                   =>
                     New_Occurrence_Of (RTE (RE_Set_TC), Loc),
                   Parameter_Associations => New_List (
                     New_Occurrence_Of (Any, Loc),
                     Result_TC)));
            end if;

            Append_To (Stms,
              Make_Simple_Return_Statement (Loc,
                Expression => New_Occurrence_Of (Any, Loc)));

            Decl :=
              Make_Subprogram_Body (Loc,
                Specification              => Spec,
                Declarations               => Decls,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => Stms));
         end Build_To_Any_Function;

         -------------------------
         -- Build_TypeCode_Call --
         -------------------------

         function Build_TypeCode_Call
           (Loc   : Source_Ptr;
            Typ   : Entity_Id;
            Decls : List_Id) return Node_Id
         is
            U_Type : Entity_Id := Underlying_Type (Typ);
            --  The full view, if Typ is private; the completion,
            --  if Typ is incomplete.

            Fnam   : Entity_Id;
            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_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;

            --  For the subtype representing a generic actual type, go to the
            --  actual type.

            if Is_Generic_Actual_Subtype (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);

            --  For a user subtype, go to first subtype

            elsif Comes_From_Source (U_Type)
              and then Nkind (Declaration_Node (U_Type))
                         = N_Subtype_Declaration
            then
               U_Type := First_Subtype (U_Type);
            end if;

            if No (Fnam) then
               if U_Type = Standard_Boolean then
                  Lib_RE := RE_TC_B;

               elsif U_Type = Standard_Character then
                  Lib_RE := RE_TC_C;

               elsif U_Type = Standard_Wide_Character then
                  Lib_RE := RE_TC_WC;

               elsif U_Type = Standard_Wide_Wide_Character then
                  Lib_RE := RE_TC_WWC;

               --  Floating point types

               elsif U_Type = Standard_Short_Float then
                  Lib_RE := RE_TC_SF;

               elsif U_Type = Standard_Float then
                  Lib_RE := RE_TC_F;

               elsif U_Type = Standard_Long_Float then
                  Lib_RE := RE_TC_LF;

               elsif U_Type = Standard_Long_Long_Float then
                  Lib_RE := RE_TC_LLF;

               --  Integer types (walk back to the base type)

               elsif U_Type = RTE (RE_Integer_8) then
                  Lib_RE := RE_TC_I8;

               elsif U_Type = RTE (RE_Integer_16) then
                  Lib_RE := RE_TC_I16;

               elsif U_Type = RTE (RE_Integer_32) then
                  Lib_RE := RE_TC_I32;

               elsif U_Type = RTE (RE_Integer_64) then
                  Lib_RE := RE_TC_I64;

               --  Unsigned integer types

               elsif U_Type = RTE (RE_Unsigned_8) then
                  Lib_RE := RE_TC_U8;

               elsif U_Type = RTE (RE_Unsigned_16) then
                  Lib_RE := RE_TC_U16;

               elsif U_Type = RTE (RE_Unsigned_32) then
                  Lib_RE := RE_TC_U32;

               elsif U_Type = RTE (RE_Unsigned_64) then
                  Lib_RE := RE_TC_U64;

               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
                  declare
                     Decl : Entity_Id;
                  begin
                     Build_TypeCode_Function (Loc, U_Type, Decl, Fnam);
                     Append_To (Decls, Decl);
                  end;
               end if;

               if Lib_RE /= RE_Null then
                  Fnam := RTE (Lib_RE);
               end if;
            end if;

            --  Call the function

            Expr :=
              Make_Function_Call (Loc, Name => New_Occurrence_Of (Fnam, Loc));

            --  Allow Expr to be used as arg to Build_To_Any_Call immediately

            Set_Etype (Expr, RTE (RE_TypeCode));

            return Expr;
         end Build_TypeCode_Call;

         -----------------------------
         -- Build_TypeCode_Function --
         -----------------------------

         procedure Build_TypeCode_Function
           (Loc  : Source_Ptr;
            Typ  : Entity_Id;
            Decl : out Node_Id;
            Fnam : out Entity_Id)
         is
            Spec  : Node_Id;
            Decls : constant List_Id := New_List;
            Stms  : constant List_Id := New_List;

            TCNam : constant Entity_Id :=
                      Make_Helper_Function_Name (Loc, Typ, Name_TypeCode);

            Parameters : List_Id;

            procedure Add_String_Parameter
              (S              : String_Id;
               Parameter_List : List_Id);
            --  Add a literal for S to Parameters

            procedure Add_TypeCode_Parameter
              (TC_Node        : Node_Id;
               Parameter_List : List_Id);
            --  Add the typecode for Typ to Parameters

            procedure Add_Long_Parameter
              (Expr_Node      : Node_Id;
               Parameter_List : List_Id);
            --  Add a signed long integer expression to Parameters

            procedure Initialize_Parameter_List
              (Name_String    : String_Id;
               Repo_Id_String : String_Id;
               Parameter_List : out List_Id);
            --  Return a list that contains the first two parameters
            --  for a parameterized typecode: name and repository id.

            function Make_Constructed_TypeCode
              (Kind       : Entity_Id;
               Parameters : List_Id) return Node_Id;
            --  Call Build_Complex_TC with the given kind and parameters

            procedure Return_Constructed_TypeCode (Kind : Entity_Id);
            --  Make a return statement that calls Build_Complex_TC with the
            --  given typecode kind, and the constructed parameters list.

            procedure Return_Alias_TypeCode (Base_TypeCode : Node_Id);
            --  Return a typecode that is a TC_Alias for the given typecode

            --------------------------
            -- Add_String_Parameter --
            --------------------------

            procedure Add_String_Parameter
              (S              : String_Id;
               Parameter_List : List_Id)
            is
            begin
               Append_To (Parameter_List,
                 Make_Function_Call (Loc,
                   Name => New_Occurrence_Of (RTE (RE_TA_Std_String), Loc),
                   Parameter_Associations => New_List (
                     Make_String_Literal (Loc, S))));
            end Add_String_Parameter;

            ----------------------------
            -- Add_TypeCode_Parameter --
            ----------------------------

            procedure Add_TypeCode_Parameter
              (TC_Node        : Node_Id;
               Parameter_List : List_Id)
            is
            begin
               Append_To (Parameter_List,
                 Make_Function_Call (Loc,
                   Name => New_Occurrence_Of (RTE (RE_TA_TC), Loc),
                   Parameter_Associations => New_List (TC_Node)));
            end Add_TypeCode_Parameter;

            ------------------------
            -- Add_Long_Parameter --
            ------------------------

            procedure Add_Long_Parameter
              (Expr_Node      : Node_Id;
               Parameter_List : List_Id)
            is
            begin
               Append_To (Parameter_List,
                 Make_Function_Call (Loc,
                   Name                   =>
                     New_Occurrence_Of (RTE (RE_TA_I32), Loc),
                   Parameter_Associations => New_List (Expr_Node)));
            end Add_Long_Parameter;

            -------------------------------
            -- Initialize_Parameter_List --
            -------------------------------

            procedure Initialize_Parameter_List
              (Name_String    : String_Id;
               Repo_Id_String : String_Id;
               Parameter_List : out List_Id)
            is
            begin
               Parameter_List := New_List;
               Add_String_Parameter (Name_String, Parameter_List);
               Add_String_Parameter (Repo_Id_String, Parameter_List);
            end Initialize_Parameter_List;

            ---------------------------
            -- Return_Alias_TypeCode --
            ---------------------------

            procedure Return_Alias_TypeCode (Base_TypeCode : Node_Id) is
            begin
               Add_TypeCode_Parameter (Base_TypeCode, Parameters);
               Return_Constructed_TypeCode (RTE (RE_Tk_Alias));
            end Return_Alias_TypeCode;

            -------------------------------
            -- Make_Constructed_TypeCode --
            -------------------------------

            function Make_Constructed_TypeCode
              (Kind       : Entity_Id;
               Parameters : List_Id) return Node_Id
            is
               Constructed_TC : constant Node_Id :=
                 Make_Function_Call (Loc,
                   Name                   =>
                     New_Occurrence_Of (RTE (RE_Build_Complex_TC), Loc),
                   Parameter_Associations => New_List (
                     New_Occurrence_Of (Kind, Loc),
                     Make_Aggregate (Loc,
                       Expressions => Parameters)));
            begin
               Set_Etype (Constructed_TC, RTE (RE_TypeCode));
               return Constructed_TC;
            end Make_Constructed_TypeCode;

            ---------------------------------
            -- Return_Constructed_TypeCode --
            ---------------------------------

            procedure Return_Constructed_TypeCode (Kind : Entity_Id) is
            begin
               Append_To (Stms,
                 Make_Simple_Return_Statement (Loc,
                   Expression =>
                     Make_Constructed_TypeCode (Kind, Parameters)));
            end Return_Constructed_TypeCode;

            ------------------
            -- Record types --
            ------------------

            procedure TC_Rec_Add_Process_Element
              (Params  : List_Id;
               Any     : Entity_Id;
               Counter : in out Nat;
               Rec     : Entity_Id;
               Field   : Node_Id);

            procedure TC_Append_Record_Traversal is
              new Append_Record_Traversal (
                Rec                 => Empty,
                Add_Process_Element => TC_Rec_Add_Process_Element);

            --------------------------------
            -- TC_Rec_Add_Process_Element --
            --------------------------------

            procedure TC_Rec_Add_Process_Element
              (Params  : List_Id;
               Any     : Entity_Id;
               Counter : in out Nat;
               Rec     : Entity_Id;
               Field   : Node_Id)
            is
               pragma Unreferenced (Any, Counter, Rec);

            begin
               if Nkind (Field) = N_Defining_Identifier then

                  --  A regular component

                  Add_TypeCode_Parameter
                    (Build_TypeCode_Call (Loc, Etype (Field), Decls), Params);
                  Get_Name_String (Chars (Field));
                  Add_String_Parameter (String_From_Name_Buffer, Params);

               else

                  --  A variant part

                  Variant_Part : declare
                     Disc_Type : constant Entity_Id := Etype (Name (Field));

                     Is_Enum : constant Boolean :=
                                 Is_Enumeration_Type (Disc_Type);

                     Union_TC_Params : List_Id;

                     U_Name : constant Name_Id :=
                                New_External_Name (Chars (Typ), 'V', -1);

                     Name_Str         : String_Id;
                     Struct_TC_Params : List_Id;

                     Variant : Node_Id;
                     Choice  : Node_Id;
                     Default : constant Node_Id :=
                                 Make_Integer_Literal (Loc, -1);

                     Dummy_Counter : Nat := 0;

                     Choice_Index : Int := 0;
                     --  Index of current choice in TypeCode, used to identify
                     --  it as the default choice if it is a "when others".

                     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/variables, then
                     --  subprogram specs, then subprogram bodies ???

                     ---------------------------------------
                     -- Add_Params_For_Variant_Components --
                     ---------------------------------------

                     procedure Add_Params_For_Variant_Components is
                        S_Name : constant Name_Id :=
                                   New_External_Name (U_Name, 'S', -1);

                     begin
                        Get_Name_String (S_Name);
                        Name_Str := String_From_Name_Buffer;
                        Initialize_Parameter_List
                          (Name_Str, Name_Str, Struct_TC_Params);

                        --  Build struct parameters

                        TC_Append_Record_Traversal (Struct_TC_Params,
                          Component_List (Variant),
                          Empty,
                          Dummy_Counter);

                        Add_TypeCode_Parameter
                          (Make_Constructed_TypeCode
                             (RTE (RE_Tk_Struct), Struct_TC_Params),
                           Union_TC_Params);

                        Add_String_Parameter (Name_Str, Union_TC_Params);
                     end Add_Params_For_Variant_Components;

                  --  Start of processing for Variant_Part

                  begin
                     Get_Name_String (U_Name);
                     Name_Str := String_From_Name_Buffer;

                     Initialize_Parameter_List
                       (Name_Str, Name_Str, Union_TC_Params);

                     --  Add union in enclosing parameter list

                     Add_TypeCode_Parameter
                       (Make_Constructed_TypeCode
                          (RTE (RE_Tk_Union), Union_TC_Params),
                        Params);

                     Add_String_Parameter (Name_Str, Params);

                     --  Build union parameters

                     Add_TypeCode_Parameter
                       (Build_TypeCode_Call (Loc, Disc_Type, Decls),
                        Union_TC_Params);

                     Add_Long_Parameter (Default, Union_TC_Params);

                     Variant := First_Non_Pragma (Variants (Field));
                     while Present (Variant) loop
                        Choice := First (Discrete_Choices (Variant));
                        while Present (Choice) loop
                           case Nkind (Choice) is
                              when N_Range =>
                                 declare
                                    L : constant Uint :=
                                          Expr_Value (Low_Bound (Choice));
                                    H : constant Uint :=
                                          Expr_Value (High_Bound (Choice));
                                    J : Uint := L;
                                    --  3.8.1(8) guarantees that the bounds of
                                    --  this range are static.

                                    Expr : Node_Id;

                                 begin
                                    while J <= H loop
                                       if Is_Enum then
                                          Expr := Get_Enum_Lit_From_Pos
                                                    (Disc_Type, J, Loc);
                                       else
                                          Expr :=
                                            Make_Integer_Literal (Loc, J);
                                       end if;

                                       Set_Etype (Expr, Disc_Type);
                                       Append_To (Union_TC_Params,
                                         Build_To_Any_Call (Loc, Expr, Decls));

                                       Add_Params_For_Variant_Components;
                                       J := J + Uint_1;
                                    end loop;

                                    Choice_Index :=
                                      Choice_Index + UI_To_Int (H - L) + 1;
                                 end;

                              when N_Others_Choice =>

                                 --  This variant has a default choice. We must
                                 --  therefore set the default parameter to the
                                 --  current choice index. This parameter is by
                                 --  construction the 4th in Union_TC_Params.

                                 Replace
                                   (Pick (Union_TC_Params, 4),
                                    Make_Function_Call (Loc,
                                      Name =>
                                        New_Occurrence_Of
                                          (RTE (RE_TA_I32), Loc),
                                      Parameter_Associations =>
                                        New_List (
                                          Make_Integer_Literal (Loc,
                                            Intval => Choice_Index))));

                                 --  Add a placeholder member label for the
                                 --  default case, which must have the
                                 --  discriminant type.

                                 declare
                                    Exp : constant Node_Id :=
                                            Make_Attribute_Reference (Loc,
                                              Prefix => New_Occurrence_Of
                                                          (Disc_Type, Loc),
                                              Attribute_Name => Name_First);
                                 begin
                                    Set_Etype (Exp, Disc_Type);
                                    Append_To (Union_TC_Params,
                                      Build_To_Any_Call (Loc, Exp, Decls));
                                 end;

                                 Add_Params_For_Variant_Components;
                                 Choice_Index := Choice_Index + 1;

                              --  Case of an explicit choice

                              when others =>
                                 declare
                                    Exp : constant Node_Id :=
                                            New_Copy_Tree (Choice);
                                 begin
                                    Append_To (Union_TC_Params,
                                      Build_To_Any_Call (Loc, Exp, Decls));
                                 end;

                                 Add_Params_For_Variant_Components;
                                 Choice_Index := Choice_Index + 1;
                           end case;

                           Next (Choice);
                        end loop;

                        Next_Non_Pragma (Variant);
                     end loop;
                  end Variant_Part;
               end if;
            end TC_Rec_Add_Process_Element;

            Type_Name_Str    : String_Id;
            Type_Repo_Id_Str : String_Id;

         --  Start of processing for Build_TypeCode_Function

         begin
            --  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,
                Parameter_Specifications => Empty_List,
                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 Has_Stream_Attribute_Definition
                 (Typ, TSS_Stream_Output, At_Any_Place => True)
              or else
               Has_Stream_Attribute_Definition
                 (Typ, TSS_Stream_Write, At_Any_Place => True)
            then
               --  If user-defined stream attributes are specified for this
               --  type, use them and transmit data as an opaque sequence of
               --  stream elements.

               Return_Alias_TypeCode
                 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));

            elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
               Return_Alias_TypeCode (
                 Build_TypeCode_Call (Loc, Etype (Typ), Decls));

            elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
               Return_Alias_TypeCode (
                 Build_TypeCode_Call (Loc,
                   Find_Numeric_Representation (Typ), Decls));

            elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then

               --  Record typecodes are encoded as follows:
               --  -- TC_STRUCT
               --  |
               --  |  [Name]
               --  |  [Repository Id]
               --
               --  Then for each discriminant:
               --
               --  |  [Discriminant Type Code]
               --  |  [Discriminant Name]
               --  |  ...
               --
               --  Then for each component:
               --
               --  |  [Component Type Code]
               --  |  [Component Name]
               --  |  ...
               --
               --  Variants components type codes are encoded as follows:
               --  --  TC_UNION
               --  |
               --  |  [Name]
               --  |  [Repository Id]
               --  |  [Discriminant Type Code]
               --  |  [Index of Default Variant Part or -1 for no default]
               --
               --  Then for each Variant Part :
               --
               --  |  [VP Label]
               --  |
               --  |  -- TC_STRUCT
               --  |  | [Variant Part Name]
               --  |  | [Variant Part Repository Id]
               --  |  |
               --  |    Then for each VP component:
               --  |  | [VP component Typecode]
               --  |  | [VP component Name]
               --  |  | ...
               --  |  --
               --  |
               --  |  [VP Name]

               if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
                  Return_Alias_TypeCode
                    (Build_TypeCode_Call (Loc, Etype (Typ), Decls));

               else
                  declare
                     Disc : Entity_Id := Empty;
                     Rdef : constant Node_Id :=
                              Type_Definition (Declaration_Node (Typ));
                     Dummy_Counter : Int := 0;

                  begin
                     --  Construct the discriminants typecodes

                     if Has_Discriminants (Typ) then
                        Disc := First_Discriminant (Typ);
                     end if;

                     while Present (Disc) loop
                        Add_TypeCode_Parameter (
                          Build_TypeCode_Call (Loc, Etype (Disc), Decls),
                          Parameters);
                        Get_Name_String (Chars (Disc));
                        Add_String_Parameter (
                          String_From_Name_Buffer,
                          Parameters);
                        Next_Discriminant (Disc);
                     end loop;

                     --  then the components typecodes

                     TC_Append_Record_Traversal
                       (Parameters, Component_List (Rdef),
                        Empty, Dummy_Counter);
                     Return_Constructed_TypeCode (RTE (RE_Tk_Struct));
                  end;
               end if;

            elsif Is_Array_Type (Typ) then
               declare
                  Ndim           : constant Pos := Number_Dimensions (Typ);
                  Inner_TypeCode : Node_Id;
                  Constrained    : constant Boolean := Is_Constrained (Typ);
                  Indx           : Node_Id          := First_Index (Typ);

               begin
                  Inner_TypeCode :=
                    Build_TypeCode_Call (Loc, Component_Type (Typ), Decls);

                  for J in 1 .. Ndim loop
                     if Constrained then
                        Inner_TypeCode := Make_Constructed_TypeCode
                          (RTE (RE_Tk_Array), New_List (
                            Build_To_Any_Call (Loc,
                              OK_Convert_To (RTE (RE_Unsigned_32),
                                Make_Attribute_Reference (Loc,
                                  Prefix => New_Occurrence_Of (Typ, Loc),
                                  Attribute_Name => Name_Length,
                                  Expressions => New_List (
                                    Make_Integer_Literal (Loc,
                                      Intval => Ndim - J + 1)))),
                              Decls),
                            Build_To_Any_Call (Loc, Inner_TypeCode, Decls)));

                     else
                        --  Unconstrained case: add low bound for each
                        --  dimension.

                        Add_TypeCode_Parameter
                          (Build_TypeCode_Call (Loc, Etype (Indx), Decls),
                           Parameters);
                        Get_Name_String (New_External_Name ('L', J));
                        Add_String_Parameter (
                          String_From_Name_Buffer,
                          Parameters);
                        Next_Index (Indx);

                        Inner_TypeCode := Make_Constructed_TypeCode
                          (RTE (RE_Tk_Sequence), New_List (
                            Build_To_Any_Call (Loc,
                              OK_Convert_To (RTE (RE_Unsigned_32),
                                Make_Integer_Literal (Loc, 0)),
                              Decls),
                            Build_To_Any_Call (Loc, Inner_TypeCode, Decls)));
                     end if;
                  end loop;

                  if Constrained then
                     Return_Alias_TypeCode (Inner_TypeCode);
                  else
                     Add_TypeCode_Parameter (Inner_TypeCode, Parameters);
                     Start_String;
                     Store_String_Char ('V');
                     Add_String_Parameter (End_String, Parameters);
                     Return_Constructed_TypeCode (RTE (RE_Tk_Struct));
                  end if;
               end;

            else
               --  Default: type is represented as an opaque sequence of bytes

               Return_Alias_TypeCode
                 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
            end if;

            Decl :=
              Make_Subprogram_Body (Loc,
                Specification              => Spec,
                Declarations               => Decls,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => Stms));
         end Build_TypeCode_Function;

         ---------------------------------
         -- Find_Numeric_Representation --
         ---------------------------------

         function Find_Numeric_Representation
           (Typ : Entity_Id) return Entity_Id
         is
            FST    : constant Entity_Id := First_Subtype (Typ);
            P_Size : constant Uint      := Esize (FST);

         begin
            --  Special case: for Stream_Element_Offset and Storage_Offset,
            --  always force transmission as a 64-bit value.

            if Is_RTE (FST, RE_Stream_Element_Offset)
                 or else
               Is_RTE (FST, RE_Storage_Offset)
            then
               return RTE (RE_Unsigned_64);
            end if;

            if Is_Unsigned_Type (Typ) then
               if P_Size <= 8 then
                  return RTE (RE_Unsigned_8);

               elsif P_Size <= 16 then
                  return RTE (RE_Unsigned_16);

               elsif P_Size <= 32 then
                  return RTE (RE_Unsigned_32);

               else
                  return RTE (RE_Unsigned_64);
               end if;

            elsif Is_Integer_Type (Typ) then
               if P_Size <= 8 then
                  return RTE (RE_Integer_8);

               elsif P_Size <= Standard_Short_Integer_Size then
                  return RTE (RE_Integer_16);

               elsif P_Size <= Standard_Integer_Size then
                  return RTE (RE_Integer_32);

               else
                  return RTE (RE_Integer_64);
               end if;

            elsif Is_Floating_Point_Type (Typ) then
               if P_Size <= Standard_Short_Float_Size then
                  return Standard_Short_Float;

               elsif P_Size <= Standard_Float_Size then
                  return Standard_Float;

               elsif P_Size <= Standard_Long_Float_Size then
                  return Standard_Long_Float;

               else
                  return Standard_Long_Long_Float;
               end if;

            else
               raise Program_Error;
            end if;

            --  What about fixed point types and numeric types with a biased
            --  representation???

         end Find_Numeric_Representation;

         ---------------------------------
         --  Is_Generic_Actual_Subtype  --
         ---------------------------------

         function Is_Generic_Actual_Subtype (Typ : Entity_Id) return Boolean is
         begin
            if Is_Itype (Typ)
              and then Present (Associated_Node_For_Itype (Typ))
            then
               declare
                  N : constant Node_Id := Associated_Node_For_Itype (Typ);
               begin
                  if Nkind (N) = N_Subtype_Declaration
                    and then Nkind (Parent (N)) = N_Package_Specification
                    and then Is_Generic_Instance (Scope_Of_Spec (Parent (N)))
                  then
                     return True;
                  end if;
               end;
            end if;

            return False;
         end Is_Generic_Actual_Subtype;

         ---------------------------
         -- Append_Array_Traversal --
         ---------------------------

         procedure Append_Array_Traversal
           (Stmts   : List_Id;
            Any     : Entity_Id;
            Counter : Entity_Id := Empty;
            Depth   : Pos       := 1)
         is
            Loc         : constant Source_Ptr := Sloc (Subprogram);
            Typ         : constant Entity_Id  := Etype (Arry);
            Constrained : constant Boolean    := Is_Constrained (Typ);
            Ndim        : constant Pos        := Number_Dimensions (Typ);

            Inner_Any, Inner_Counter : Entity_Id;

            Loop_Stm    : Node_Id;
            Inner_Stmts : constant List_Id := New_List;

         begin
            if Depth > Ndim then

               --  Processing for one element of an array

               declare
                  Element_Expr : constant Node_Id :=
                                   Make_Indexed_Component (Loc,
                                     New_Occurrence_Of (Arry, Loc),
                                     Indexes);
               begin
                  Set_Etype (Element_Expr, Component_Type (Typ));
                  Add_Process_Element (Stmts,
                    Any     => Any,
                    Counter => Counter,
                    Datum   => Element_Expr);
               end;

               return;
            end if;

            Append_To (Indexes,
              Make_Identifier (Loc, New_External_Name ('L', Depth)));

            if not Constrained or else Depth > 1 then
               Inner_Any := Make_Defining_Identifier (Loc,
                              New_External_Name ('A', Depth));
               Set_Etype (Inner_Any, RTE (RE_Any));
            else
               Inner_Any := Empty;
            end if;

            if Present (Counter) then
               Inner_Counter := Make_Defining_Identifier (Loc,
                                  New_External_Name ('J', Depth));
            else
               Inner_Counter := Empty;
            end if;

            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,
                Iteration_Scheme =>
                  Make_Iteration_Scheme (Loc,
                    Loop_Parameter_Specification =>
                      Make_Loop_Parameter_Specification (Loc,
                        Defining_Identifier =>
                          Make_Defining_Identifier (Loc,
                            Chars => New_External_Name ('L', Depth)),

                        Discrete_Subtype_Definition =>
                          Make_Attribute_Reference (Loc,
                            Prefix         => New_Occurrence_Of (Arry, Loc),
                            Attribute_Name => Name_Range,

                            Expressions => New_List (
                              Make_Integer_Literal (Loc, Depth))))),
                Statements => Inner_Stmts);

            declare
               Decls       : constant List_Id := New_List;
               Dimen_Stmts : constant List_Id := New_List;
               Length_Node : Node_Id;

               Inner_Any_TypeCode : constant Entity_Id :=
                                      Make_Defining_Identifier (Loc,
                                        New_External_Name ('T', Depth));

               Inner_Any_TypeCode_Expr : Node_Id;

            begin
               if Depth = 1 then
                  if Constrained then
                     Inner_Any_TypeCode_Expr :=
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of (RTE (RE_Get_TC), Loc),
                         Parameter_Associations => New_List (
                           New_Occurrence_Of (Any, Loc)));

                  else
                     Inner_Any_TypeCode_Expr :=
                       Make_Function_Call (Loc,
                         Name =>
                           New_Occurrence_Of (RTE (RE_Any_Member_Type), Loc),
                             Parameter_Associations => New_List (
                               New_Occurrence_Of (Any, Loc),
                               Make_Integer_Literal (Loc, Ndim)));
                  end if;

               else
                  Inner_Any_TypeCode_Expr :=
                    Make_Function_Call (Loc,
                      Name => New_Occurrence_Of (RTE (RE_Content_Type), Loc),
                      Parameter_Associations => New_List (
                        Make_Identifier (Loc,
                          Chars => New_External_Name ('T', Depth - 1))));
               end if;

               Append_To (Decls,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Inner_Any_TypeCode,
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of (
                                            RTE (RE_TypeCode), Loc),
                   Expression          => Inner_Any_TypeCode_Expr));

               if Present (Inner_Any) then
                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Inner_Any,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_Any), Loc),
                      Expression          =>
                        Make_Function_Call (Loc,
                          Name =>
                            New_Occurrence_Of (
                              RTE (RE_Create_Any), Loc),
                          Parameter_Associations => New_List (
                            New_Occurrence_Of (Inner_Any_TypeCode, Loc)))));
               end if;

               if Present (Inner_Counter) then
                  Append_To (Decls,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Inner_Counter,
                      Object_Definition   =>
                        New_Occurrence_Of (RTE (RE_Unsigned_32), Loc),
                      Expression          =>
                        Make_Integer_Literal (Loc, 0)));
               end if;

               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_Unsigned_32));

                  Add_Process_Element (Dimen_Stmts,
                    Datum   => Length_Node,
                    Any     => Inner_Any,
                    Counter => Inner_Counter);
               end if;

               --  Loop_Stm does appropriate processing for each element
               --  of Inner_Any.

               Append_To (Dimen_Stmts, Loop_Stm);

               --  Link outer and inner any

               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,
                   Declarations =>
                     Decls,
                   Handled_Statement_Sequence =>
                     Make_Handled_Sequence_Of_Statements (Loc,
                       Statements => Dimen_Stmts)));
            end;
         end Append_Array_Traversal;

         -------------------------------
         -- Make_Helper_Function_Name --
         -------------------------------

         function Make_Helper_Function_Name
           (Loc : Source_Ptr;
            Typ : Entity_Id;
            Nam : Name_Id) return Entity_Id
         is
         begin
            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.

            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
                       (Related_Id   => Nam,
                        Suffix       => ' ',
                        Suffix_Index => Serial,
                        Prefix       => '_'));
            end;
         end Make_Helper_Function_Name;
      end Helpers;

      -----------------------------------
      -- Reserve_NamingContext_Methods --
      -----------------------------------

      procedure Reserve_NamingContext_Methods is
         Str_Resolve : constant String := "resolve";
      begin
         Name_Buffer (1 .. Str_Resolve'Length) := Str_Resolve;
         Name_Len := Str_Resolve'Length;
         Overload_Counter_Table.Set (Name_Find, 1);
      end Reserve_NamingContext_Methods;

      -----------------------
      -- RPC_Receiver_Decl --
      -----------------------

      function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id is
         Loc : constant Source_Ptr := Sloc (RACW_Type);
      begin
         return
           Make_Object_Declaration (Loc,
             Defining_Identifier => Make_Temporary (Loc, 'R'),
             Aliased_Present     => True,
             Object_Definition   => New_Occurrence_Of (RTE (RE_Servant), Loc));
      end RPC_Receiver_Decl;

   end PolyORB_Support;

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

   procedure RACW_Type_Is_Asynchronous (RACW_Type : Entity_Id) is
      Asynchronous_Flag : constant Entity_Id :=
                            Asynchronous_Flags_Table.Get (RACW_Type);
   begin
      Replace (Expression (Parent (Asynchronous_Flag)),
        New_Occurrence_Of (Standard_True, Sloc (Asynchronous_Flag)));
   end RACW_Type_Is_Asynchronous;

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

   function RCI_Package_Locator
     (Loc          : Source_Ptr;
      Package_Spec : Node_Id) return Node_Id
   is
      Inst     : Node_Id;
      Pkg_Name : constant String_Id :=
        Fully_Qualified_Name_String
          (Defining_Entity (Package_Spec), Append_NUL => False);

   begin
      Inst :=
        Make_Package_Instantiation (Loc,
          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)),

            Make_Generic_Association (Loc,
              Selector_Name                     =>
                Make_Identifier (Loc, Name_Version),
              Explicit_Generic_Actual_Parameter =>
                Make_Attribute_Reference (Loc,
                  Prefix         =>
                    New_Occurrence_Of (Defining_Entity (Package_Spec), Loc),
                  Attribute_Name =>
                    Name_Version))));

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

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

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

   begin
      --  For an RACW encountered before the freeze point of its designated
      --  type, the stub type is generated at the point of the RACW declaration
      --  but the primitives are generated only once the designated type is
      --  frozen. That freeze can occur in another scope, for example when the
      --  RACW is declared in a nested package. In that case we need to
      --  reestablish the stub type's scope prior to generating its primitive
      --  operations.

      if Stub_Elements /= Empty_Stub_Structure then
         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;

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

   function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
      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;

      return Unit_Name;
   end Scope_Of_Spec;

   ----------------------
   -- Set_Renaming_TSS --
   ----------------------

   procedure Set_Renaming_TSS
     (Typ     : Entity_Id;
      Nam     : Entity_Id;
      TSS_Nam : TSS_Name_Type)
   is
      Loc  : constant Source_Ptr := Sloc (Nam);
      Spec : constant Node_Id := Parent (Nam);

      TSS_Node : constant Node_Id :=
                   Make_Subprogram_Renaming_Declaration (Loc,
                     Specification =>
                       Copy_Specification (Loc,
                         Spec     => Spec,
                         New_Name => Make_TSS_Name (Typ, TSS_Nam)),
                       Name => New_Occurrence_Of (Nam, Loc));

      Snam : constant Entity_Id :=
               Defining_Unit_Name (Specification (TSS_Node));

   begin
      if Nkind (Spec) = N_Function_Specification then
         Mutate_Ekind (Snam, E_Function);
         Set_Etype (Snam, Entity (Result_Definition (Spec)));
      else
         Mutate_Ekind (Snam, E_Procedure);
         Set_Etype (Snam, Standard_Void_Type);
      end if;

      Set_TSS (Typ, Snam);
   end Set_Renaming_TSS;

   ----------------------------------------------
   -- Specific_Add_Obj_RPC_Receiver_Completion --
   ----------------------------------------------

   procedure Specific_Add_Obj_RPC_Receiver_Completion
     (Loc           : Source_Ptr;
      Decls         : List_Id;
      RPC_Receiver  : Entity_Id;
      Stub_Elements : Stub_Structure)
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            PolyORB_Support.Add_Obj_RPC_Receiver_Completion
              (Loc, Decls, RPC_Receiver, Stub_Elements);

         when others =>
            GARLIC_Support.Add_Obj_RPC_Receiver_Completion
              (Loc, Decls, RPC_Receiver, Stub_Elements);
      end case;
   end Specific_Add_Obj_RPC_Receiver_Completion;

   --------------------------------
   -- Specific_Add_RACW_Features --
   --------------------------------

   procedure Specific_Add_RACW_Features
     (RACW_Type         : Entity_Id;
      Desig             : Entity_Id;
      Stub_Type         : Entity_Id;
      Stub_Type_Access  : Entity_Id;
      RPC_Receiver_Decl : Node_Id;
      Body_Decls        : List_Id)
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            PolyORB_Support.Add_RACW_Features
              (RACW_Type,
               Desig,
               Stub_Type,
               Stub_Type_Access,
               RPC_Receiver_Decl,
               Body_Decls);

         when others =>
            GARLIC_Support.Add_RACW_Features
              (RACW_Type,
               Stub_Type,
               Stub_Type_Access,
               RPC_Receiver_Decl,
               Body_Decls);
      end case;
   end Specific_Add_RACW_Features;

   --------------------------------
   -- Specific_Add_RAST_Features --
   --------------------------------

   procedure Specific_Add_RAST_Features
     (Vis_Decl : Node_Id;
      RAS_Type : Entity_Id)
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            PolyORB_Support.Add_RAST_Features (Vis_Decl, RAS_Type);

         when others =>
            GARLIC_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
      end case;
   end Specific_Add_RAST_Features;

   --------------------------------------------------
   -- Specific_Add_Receiving_Stubs_To_Declarations --
   --------------------------------------------------

   procedure Specific_Add_Receiving_Stubs_To_Declarations
     (Pkg_Spec : Node_Id;
      Decls    : List_Id;
      Stmts    : List_Id)
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            PolyORB_Support.Add_Receiving_Stubs_To_Declarations
              (Pkg_Spec, Decls, Stmts);

         when others =>
            GARLIC_Support.Add_Receiving_Stubs_To_Declarations
              (Pkg_Spec, Decls, Stmts);
      end case;
   end Specific_Add_Receiving_Stubs_To_Declarations;

   ------------------------------------------
   -- Specific_Build_General_Calling_Stubs --
   ------------------------------------------

   procedure Specific_Build_General_Calling_Stubs
     (Decls                     : List_Id;
      Statements                : List_Id;
      Target                    : RPC_Target;
      Subprogram_Id             : Node_Id;
      Asynchronous              : Node_Id   := Empty;
      Is_Known_Asynchronous     : Boolean   := False;
      Is_Known_Non_Asynchronous : Boolean   := False;
      Is_Function               : Boolean;
      Spec                      : Node_Id;
      Stub_Type                 : Entity_Id := Empty;
      RACW_Type                 : Entity_Id := Empty;
      Nod                       : Node_Id)
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            PolyORB_Support.Build_General_Calling_Stubs
              (Decls,
               Statements,
               Target.Object,
               Subprogram_Id,
               Asynchronous,
               Is_Known_Asynchronous,
               Is_Known_Non_Asynchronous,
               Is_Function,
               Spec,
               Stub_Type,
               RACW_Type,
               Nod);

         when others =>
            GARLIC_Support.Build_General_Calling_Stubs
              (Decls,
               Statements,
               Target.Partition,
               Target.RPC_Receiver,
               Subprogram_Id,
               Asynchronous,
               Is_Known_Asynchronous,
               Is_Known_Non_Asynchronous,
               Is_Function,
               Spec,
               Stub_Type,
               RACW_Type,
               Nod);
      end case;
   end Specific_Build_General_Calling_Stubs;

   --------------------------------------
   -- Specific_Build_RPC_Receiver_Body --
   --------------------------------------

   procedure Specific_Build_RPC_Receiver_Body
     (RPC_Receiver : Entity_Id;
      Request      : out Entity_Id;
      Subp_Id      : out Entity_Id;
      Subp_Index   : out Entity_Id;
      Stmts        : out List_Id;
      Decl         : out Node_Id)
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            PolyORB_Support.Build_RPC_Receiver_Body
              (RPC_Receiver,
               Request,
               Subp_Id,
               Subp_Index,
               Stmts,
               Decl);

         when others =>
            GARLIC_Support.Build_RPC_Receiver_Body
              (RPC_Receiver,
               Request,
               Subp_Id,
               Subp_Index,
               Stmts,
               Decl);
      end case;
   end Specific_Build_RPC_Receiver_Body;

   --------------------------------
   -- Specific_Build_Stub_Target --
   --------------------------------

   function Specific_Build_Stub_Target
     (Loc                   : Source_Ptr;
      Decls                 : List_Id;
      RCI_Locator           : Entity_Id;
      Controlling_Parameter : Entity_Id) return RPC_Target
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            return
              PolyORB_Support.Build_Stub_Target
                (Loc, Decls, RCI_Locator, Controlling_Parameter);

         when others =>
            return
              GARLIC_Support.Build_Stub_Target
                (Loc, Decls, RCI_Locator, Controlling_Parameter);
      end case;
   end Specific_Build_Stub_Target;

   --------------------------------
   -- Specific_RPC_Receiver_Decl --
   --------------------------------

   function Specific_RPC_Receiver_Decl
     (RACW_Type : Entity_Id) return Node_Id
   is
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            return PolyORB_Support.RPC_Receiver_Decl (RACW_Type);

         when others =>
            return GARLIC_Support.RPC_Receiver_Decl (RACW_Type);
      end case;
   end Specific_RPC_Receiver_Decl;

   -----------------------------------------------
   -- 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
   begin
      case Get_PCS_Name is
         when Name_PolyORB_DSA =>
            return
              PolyORB_Support.Build_Subprogram_Receiving_Stubs
                (Vis_Decl,
                 Asynchronous,
                 Dynamically_Asynchronous,
                 Stub_Type,
                 RACW_Type,
                 Parent_Primitive);

         when others =>
            return
              GARLIC_Support.Build_Subprogram_Receiving_Stubs
                (Vis_Decl,
                 Asynchronous,
                 Dynamically_Asynchronous,
                 Stub_Type,
                 RACW_Type,
                 Parent_Primitive);
      end case;
   end Specific_Build_Subprogram_Receiving_Stubs;

   -------------------------------
   -- Transmit_As_Unconstrained --
   -------------------------------

   function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean is
   begin
      return
        not (Is_Elementary_Type (Typ) or else Is_Constrained (Typ))
          or else (Is_Access_Type (Typ) and then Can_Never_Be_Null (Typ));
   end Transmit_As_Unconstrained;

   --------------------------
   -- Underlying_RACW_Type --
   --------------------------

   function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is
      Record_Type : Entity_Id;

   begin
      if Ekind (RAS_Typ) = E_Record_Type then
         Record_Type := RAS_Typ;
      else
         pragma Assert (Present (Equivalent_Type (RAS_Typ)));
         Record_Type := Equivalent_Type (RAS_Typ);
      end if;

      return
        Etype (Subtype_Indication
                (Component_Definition
                  (First (Component_Items
                           (Component_List
                             (Type_Definition
                               (Declaration_Node (Record_Type))))))));
   end Underlying_RACW_Type;

end Exp_Dist;
