diff options
Diffstat (limited to 'gcc-4.4.0/gcc/ada/exp_dist.adb')
-rw-r--r-- | gcc-4.4.0/gcc/ada/exp_dist.adb | 11487 |
1 files changed, 0 insertions, 11487 deletions
diff --git a/gcc-4.4.0/gcc/ada/exp_dist.adb b/gcc-4.4.0/gcc/ada/exp_dist.adb deleted file mode 100644 index 546bbcc57..000000000 --- a/gcc-4.4.0/gcc/ada/exp_dist.adb +++ /dev/null @@ -1,11487 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- E X P_ D I S T -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 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 Elists; use Elists; -with Exp_Atag; use Exp_Atag; -with Exp_Strm; use Exp_Strm; -with Exp_Tss; use Exp_Tss; -with Exp_Util; use Exp_Util; -with Lib; use Lib; -with Nlists; use Nlists; -with Nmake; use Nmake; -with Opt; use Opt; -with Rtsfind; use Rtsfind; -with Sem; use Sem; -with Sem_Cat; use Sem_Cat; -with Sem_Ch3; use Sem_Ch3; -with Sem_Ch8; use Sem_Ch8; -with Sem_Dist; use Sem_Dist; -with Sem_Eval; use Sem_Eval; -with Sem_Util; use Sem_Util; -with Sinfo; use Sinfo; -with Stand; use Stand; -with Stringt; use Stringt; -with Tbuild; use Tbuild; -with Ttypes; use Ttypes; -with Uintp; use Uintp; - -with GNAT.HTable; use GNAT.HTable; - -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 than RACW_Stub_Type, it can be - -- converted to and from this type to make it suitable for - -- System.Partition_Interface.Get_Unique_Remote_Pointer in order - -- to avoid memory leaks when the same remote object arrive on the - -- same partition 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 names. These counters - -- are maintained in a hash table on name ids. - - type Subprogram_Identifiers is record - Str_Identifier : String_Id; - Int_Identifier : Int; - end record; - - package Subprogram_Identifier_Table is - new Simple_HTable (Header_Num => Hash_Index, - Element => Subprogram_Identifiers, - No_Element => (No_String, 0), - Key => Entity_Id, - Hash => Hash, - Equal => "="); - -- Mapping between a remote subprogram and the corresponding - -- subprogram identifiers. - - package Overload_Counter_Table is - new Simple_HTable (Header_Num => Hash_Index, - Element => Int, - No_Element => 0, - Key => Name_Id, - Hash => Hash, - Equal => "="); - -- Mapping between a subprogram name and an integer that - -- counts the number of defining subprogram names with that - -- Name_Id encountered so far in a given context (an interface). - - function Get_Subprogram_Ids (Def : Entity_Id) return Subprogram_Identifiers; - function Get_Subprogram_Id (Def : Entity_Id) return String_Id; - function Get_Subprogram_Id (Def : Entity_Id) return Int; - -- Given a subprogram defined in a RCI package, get its distribution - -- subprogram identifiers (the distribution identifiers are a unique - -- subprogram number, and the non-qualified subprogram name, in the - -- casing used for the subprogram declaration; if the name is overloaded, - -- a double underscore and a serial number are appended. - -- - -- The integer identifier is used to perform remote calls with GARLIC; - -- the string identifier is used in the case of PolyORB. - -- - -- Although the PolyORB DSA receiving stubs will make a caseless comparison - -- when receiving a call, the calling stubs will create requests with the - -- exact casing of the defining unit name of the called subprogram, so as - -- to allow calls to subprograms on distributed nodes that do distinguish - -- between casings. - -- - -- NOTE: Another design would be to allow a representation clause on - -- subprogram specs: for Subp'Distribution_Identifier use "fooBar"; - - pragma Warnings (Off, Get_Subprogram_Id); - -- One homonym only is unreferenced (specific to the GARLIC version) - - procedure Add_RAS_Dereference_TSS (N : Node_Id); - -- Add a subprogram body for RAS Dereference TSS - - procedure Add_RAS_Proxy_And_Analyze - (Decls : List_Id; - Vis_Decl : Node_Id; - All_Calls_Remote_E : Entity_Id; - Proxy_Object_Addr : out Entity_Id); - -- Add the proxy type required, on the receiving (server) side, to handle - -- calls to the subprogram declared by Vis_Decl through a remote access - -- to subprogram type. All_Calls_Remote_E must be Standard_True if a pragma - -- All_Calls_Remote applies, Standard_False otherwise. The new proxy type - -- is appended to Decls. Proxy_Object_Addr is a constant of type - -- System.Address that designates an instance of the proxy object. - - function Build_Remote_Subprogram_Proxy_Type - (Loc : Source_Ptr; - ACR_Expression : Node_Id) return Node_Id; - -- Build and return a tagged record type definition for an RCI - -- subprogram proxy type. - -- ACR_Expression is use as the initialization value for - -- the All_Calls_Remote component. - - function Build_Get_Unique_RP_Call - (Loc : Source_Ptr; - Pointer : Entity_Id; - Stub_Type : Entity_Id) return List_Id; - -- Build a call to Get_Unique_Remote_Pointer (Pointer), followed by a - -- tag fixup (Get_Unique_Remote_Pointer may have changed Pointer'Tag to - -- RACW_Stub_Type'Tag, while the desired tag is that of Stub_Type). - - function Build_Stub_Tag - (Loc : Source_Ptr; - RACW_Type : Entity_Id) return Node_Id; - -- Return an expression denoting the tag of the stub type associated with - -- RACW_Type. - - function Build_Subprogram_Calling_Stubs - (Vis_Decl : Node_Id; - Subp_Id : 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; - Decls : List_Id); - -- Add calling stubs to the declarative part - - function Could_Be_Asynchronous (Spec : Node_Id) return Boolean; - -- Return True if nothing prevents the program whose specification is - -- given to be asynchronous (i.e. no out parameter). - - 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, for the case of an RACW that - -- implements a RAS, no object RPC receiver is generated. Instead, - -- RPC_Receiver_Decl is the declaration after which the RPC receiver - -- would have been inserted. - - Body_Decls : List_Id; - -- List of subprogram bodies to be included in generated code: bodies - -- for the RACW's stream attributes, and for the primitive operations - -- of the stub type. - - RACW_Type : Entity_Id; - -- One of the RACW types designating this distributed object type - -- (they are all interchangeable; we use any one of them in order to - -- avoid having to create various anonymous access types). - - end record; - - 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 : a node with a Parameter_Specifications and - -- a Result_Definition if applicable - -- Stub_Type : in case of RACW stubs, parameters of type access - -- to Stub_Type will be marshalled using the - -- address of the object (the addr field) rather - -- than using the 'Write on the stub itself - -- Nod : used to provide sloc for generated code - - function Specific_Build_Stub_Target - (Loc : Source_Ptr; - Decls : List_Id; - RCI_Locator : Entity_Id; - Controlling_Parameter : Entity_Id) return RPC_Target; - -- Build call target information nodes for use within calling stubs. In the - -- RCI case, RCI_Locator is the entity for the instance of RCI_Locator. If - -- for an RACW, Controlling_Parameter is the entity for the controlling - -- formal parameter used to determine the location of the target of the - -- call. Decls provides a location where variable declarations can be - -- appended to construct the necessary values. - - procedure Specific_Build_Stub_Type - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Decl : out Node_Id; - RPC_Receiver_Decl : out Node_Id); - -- Build a type declaration for the stub type associated with an RACW - -- type, and the necessary RPC receiver, if applicable. PCS-specific - -- ancillary subprogram for Add_Stub_Type. If no RPC receiver declaration - -- is generated, then RPC_Receiver_Decl is set to Empty. - - procedure Specific_Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Request : out Entity_Id; - Subp_Id : out Entity_Id; - Subp_Index : out Entity_Id; - Stmts : out List_Id; - Decl : out Node_Id); - -- Make a subprogram body for an RPC receiver, with the given - -- defining unit name. On return: - -- - Subp_Id is the subprogram identifier from the PCS. - -- - Subp_Index is the index in the list of subprograms - -- used for dispatching (a variable of type Subprogram_Id). - -- - Stmts is the place where the request dispatching - -- statements can occur, - -- - Decl is the subprogram body declaration. - - function Specific_Build_Subprogram_Receiving_Stubs - (Vis_Decl : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Parent_Primitive : Entity_Id := Empty) return Node_Id; - -- Build the receiving stub for a given subprogram. The subprogram - -- declaration is also built by this procedure, and the value returned - -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is - -- found in the specification, then its address is read from the stream - -- instead of the object itself and converted into an access to - -- class-wide type before doing the real call using any of the RACW type - -- pointing on the designated type. - - procedure Specific_Add_Obj_RPC_Receiver_Completion - (Loc : Source_Ptr; - Decls : List_Id; - RPC_Receiver : Entity_Id; - Stub_Elements : Stub_Structure); - -- Add the necessary code to Decls after the completion of generation - -- of the RACW RPC receiver described by Stub_Elements. - - procedure Specific_Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id; - Stmts : List_Id); - -- Add receiving stubs to the declarative part of an RCI unit - - package GARLIC_Support is - - -- Support for generating DSA code that uses the GARLIC PCS - - -- The subprograms below provide the GARLIC versions of the - -- corresponding Specific_<subprogram> routine declared above. - - procedure Add_RACW_Features - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver_Decl : Node_Id; - Body_Decls : List_Id); - - procedure Add_RAST_Features - (Vis_Decl : Node_Id; - RAS_Type : Entity_Id); - - procedure Build_General_Calling_Stubs - (Decls : List_Id; - Statements : List_Id; - Target_Partition : Entity_Id; -- From RPC_Target - Target_RPC_Receiver : Node_Id; -- From RPC_Target - Subprogram_Id : Node_Id; - Asynchronous : Node_Id := Empty; - Is_Known_Asynchronous : Boolean := False; - Is_Known_Non_Asynchronous : Boolean := False; - Is_Function : Boolean; - Spec : Node_Id; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Nod : Node_Id); - - function Build_Stub_Target - (Loc : Source_Ptr; - Decls : List_Id; - RCI_Locator : Entity_Id; - Controlling_Parameter : Entity_Id) return RPC_Target; - - procedure Build_Stub_Type - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Decl : out Node_Id; - RPC_Receiver_Decl : out Node_Id); - - function Build_Subprogram_Receiving_Stubs - (Vis_Decl : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Parent_Primitive : Entity_Id := Empty) return Node_Id; - - procedure Add_Obj_RPC_Receiver_Completion - (Loc : Source_Ptr; - Decls : List_Id; - RPC_Receiver : Entity_Id; - Stub_Elements : Stub_Structure); - - procedure Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id; - Stmts : List_Id); - - procedure Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Request : out Entity_Id; - Subp_Id : out Entity_Id; - Subp_Index : out Entity_Id; - Stmts : out List_Id; - Decl : out Node_Id); - - end GARLIC_Support; - - package PolyORB_Support is - - -- Support for generating DSA code that uses the PolyORB PCS - - -- The subprograms below provide the PolyORB versions of the - -- corresponding Specific_<subprogram> routine declared above. - - procedure Add_RACW_Features - (RACW_Type : Entity_Id; - Desig : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver_Decl : Node_Id; - Body_Decls : List_Id); - - procedure Add_RAST_Features - (Vis_Decl : Node_Id; - RAS_Type : Entity_Id); - - procedure Build_General_Calling_Stubs - (Decls : List_Id; - Statements : List_Id; - Target_Object : Node_Id; -- From RPC_Target - Subprogram_Id : Node_Id; - Asynchronous : Node_Id := Empty; - Is_Known_Asynchronous : Boolean := False; - Is_Known_Non_Asynchronous : Boolean := False; - Is_Function : Boolean; - Spec : Node_Id; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Nod : Node_Id); - - function Build_Stub_Target - (Loc : Source_Ptr; - Decls : List_Id; - RCI_Locator : Entity_Id; - Controlling_Parameter : Entity_Id) return RPC_Target; - - procedure Build_Stub_Type - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Decl : out Node_Id; - RPC_Receiver_Decl : out Node_Id); - - function Build_Subprogram_Receiving_Stubs - (Vis_Decl : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Parent_Primitive : Entity_Id := Empty) return Node_Id; - - procedure Add_Obj_RPC_Receiver_Completion - (Loc : Source_Ptr; - Decls : List_Id; - RPC_Receiver : Entity_Id; - Stub_Elements : Stub_Structure); - - procedure Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id; - Stmts : List_Id); - - procedure Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Request : out Entity_Id; - Subp_Id : out Entity_Id; - Subp_Index : out Entity_Id; - Stmts : out List_Id; - Decl : out Node_Id); - - procedure Reserve_NamingContext_Methods; - -- Mark the method names for interface NamingContext as already used in - -- the overload table, so no clashes occur with user code (with the - -- PolyORB PCS, RCIs Implement The NamingContext interface to allow - -- their methods to be accessed as objects, for the implementation of - -- remote access-to-subprogram types). - - package Helpers is - - -- Routines to build distribution helper subprograms for user-defined - -- types. For implementation of the Distributed systems annex (DSA) - -- over the PolyORB generic middleware components, it is necessary to - -- generate several supporting subprograms for each application data - -- type used in inter-partition communication. These subprograms are: - - -- A Typecode function returning a high-level description of the - -- type's structure; - - -- Two conversion functions allowing conversion of values of the - -- type from and to the generic data containers used by PolyORB. - -- These generic containers are called 'Any' type values after the - -- CORBA terminology, and hence the conversion subprograms are - -- named To_Any and From_Any. - - function Build_From_Any_Call - (Typ : Entity_Id; - N : Node_Id; - Decls : List_Id) return Node_Id; - -- Build call to From_Any attribute function of type Typ with - -- expression N as actual parameter. Decls is the declarations list - -- for an appropriate enclosing scope of the point where the call - -- will be inserted; if the From_Any attribute for Typ needs to be - -- generated at this point, its declaration is appended to Decls. - - procedure Build_From_Any_Function - (Loc : Source_Ptr; - Typ : Entity_Id; - Decl : out Node_Id; - Fnam : out Entity_Id); - -- Build From_Any attribute function for Typ. Loc is the reference - -- location for generated nodes, Typ is the type for which the - -- conversion function is generated. On return, Decl and Fnam contain - -- the declaration and entity for the newly-created function. - - function Build_To_Any_Call - (N : Node_Id; - Decls : List_Id) return Node_Id; - -- Build call to To_Any attribute function with expression as actual - -- parameter. Decls is the declarations list for an appropriate - -- enclosing scope of the point where the call will be inserted; if - -- the To_Any attribute for Typ needs to be generated at this point, - -- its declaration is appended to Decls. - - procedure Build_To_Any_Function - (Loc : Source_Ptr; - Typ : Entity_Id; - Decl : out Node_Id; - Fnam : out Entity_Id); - -- Build To_Any attribute function for Typ. Loc is the reference - -- location for generated nodes, Typ is the type for which the - -- conversion function is generated. On return, Decl and Fnam contain - -- the declaration and entity for the newly-created function. - - function Build_TypeCode_Call - (Loc : Source_Ptr; - Typ : Entity_Id; - Decls : List_Id) return Node_Id; - -- Build call to TypeCode attribute function for Typ. Decls is the - -- declarations list for an appropriate enclosing scope of the point - -- where the call will be inserted; if the To_Any attribute for Typ - -- needs to be generated at this point, its declaration is appended - -- to Decls. - - procedure Build_TypeCode_Function - (Loc : Source_Ptr; - Typ : Entity_Id; - Decl : out Node_Id; - Fnam : out Entity_Id); - -- Build TypeCode attribute function for Typ. Loc is the reference - -- location for generated nodes, Typ is the type for which the - -- conversion function is generated. On return, Decl and Fnam contain - -- the declaration and entity for the newly-created function. - - procedure Build_Name_And_Repository_Id - (E : Entity_Id; - Name_Str : out String_Id; - Repo_Id_Str : out String_Id); - -- In the PolyORB distribution model, each distributed object type - -- and each distributed operation has a globally unique identifier, - -- its Repository Id. This subprogram builds and returns two strings - -- for entity E (a distributed object type or operation): one - -- containing the name of E, the second containing its repository id. - - end Helpers; - - end PolyORB_Support; - - -- The following PolyORB-specific subprograms are made visible to Exp_Attr: - - function Build_From_Any_Call - (Typ : Entity_Id; - N : Node_Id; - Decls : List_Id) return Node_Id - renames PolyORB_Support.Helpers.Build_From_Any_Call; - - function Build_To_Any_Call - (N : Node_Id; - Decls : List_Id) return Node_Id - renames PolyORB_Support.Helpers.Build_To_Any_Call; - - function Build_TypeCode_Call - (Loc : Source_Ptr; - Typ : Entity_Id; - Decls : List_Id) return Node_Id - renames PolyORB_Support.Helpers.Build_TypeCode_Call; - - ------------------------------------ - -- Local variables and structures -- - ------------------------------------ - - RCI_Cache : Node_Id; - -- Needs comments ??? - - Output_From_Constrained : constant array (Boolean) of Name_Id := - (False => Name_Output, - True => Name_Write); - -- The attribute to choose depending on the fact that the parameter - -- is constrained or not. There is no such thing as Input_From_Constrained - -- since this require separate mechanisms ('Input is a function while - -- 'Read is a procedure). - - --------------------------------------- - -- Add_Calling_Stubs_To_Declarations -- - --------------------------------------- - - procedure Add_Calling_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id) - is - Current_Subprogram_Number : Int := First_RCI_Subprogram_Id; - -- Subprogram id 0 is reserved for calls received from - -- remote access-to-subprogram dereferences. - - Current_Declaration : Node_Id; - Loc : constant Source_Ptr := Sloc (Pkg_Spec); - RCI_Instantiation : Node_Id; - Subp_Stubs : Node_Id; - Subp_Str : String_Id; - - pragma Warnings (Off, Subp_Str); - - begin - -- 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 (Decls, RCI_Instantiation); - Analyze (RCI_Instantiation); - - -- For each subprogram declaration visible in the spec, we do build a - -- body. We also increment a counter to assign a different Subprogram_Id - -- to each subprograms. The receiving stubs processing do use the same - -- mechanism and will thus assign the same Id and do the correct - -- dispatching. - - Overload_Counter_Table.Reset; - PolyORB_Support.Reserve_NamingContext_Methods; - - Current_Declaration := First (Visible_Declarations (Pkg_Spec)); - while Present (Current_Declaration) loop - if Nkind (Current_Declaration) = N_Subprogram_Declaration - and then Comes_From_Source (Current_Declaration) - then - Assign_Subprogram_Identifier - (Defining_Unit_Name (Specification (Current_Declaration)), - Current_Subprogram_Number, - Subp_Str); - - Subp_Stubs := - Build_Subprogram_Calling_Stubs ( - Vis_Decl => Current_Declaration, - Subp_Id => - Build_Subprogram_Id (Loc, - Defining_Unit_Name (Specification (Current_Declaration))), - Asynchronous => - Nkind (Specification (Current_Declaration)) = - N_Procedure_Specification - and then - Is_Asynchronous (Defining_Unit_Name (Specification - (Current_Declaration)))); - - Append_To (Decls, Subp_Stubs); - Analyze (Subp_Stubs); - - Current_Subprogram_Number := Current_Subprogram_Number + 1; - end if; - - Next (Current_Declaration); - end loop; - 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; - RPC_Receiver_Request : Entity_Id; - RPC_Receiver_Subp_Id : Entity_Id; - RPC_Receiver_Subp_Index : Entity_Id; - - Subp_Str : String_Id; - - Current_Primitive_Elmt : Elmt_Id; - Current_Primitive : Entity_Id; - 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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('P')); - - Specific_Build_RPC_Receiver_Body - (RPC_Receiver => RPC_Receiver, - Request => RPC_Receiver_Request, - Subp_Id => RPC_Receiver_Subp_Id, - Subp_Index => RPC_Receiver_Subp_Index, - Stmts => RPC_Receiver_Statements, - Decl => RPC_Receiver_Decl); - - 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. - - if Present (Primitive_Operations (Designated_Type)) then - Overload_Counter_Table.Reset; - - Current_Primitive_Elmt := - First_Elmt (Primitive_Operations (Designated_Type)); - while Current_Primitive_Elmt /= No_Elmt loop - Current_Primitive := Node (Current_Primitive_Elmt); - - -- Copy the primitive of all the parents, except predefined ones - -- that are not remotely dispatching. 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_Stream_Input) or else - Is_TSS (Current_Primitive, TSS_Stream_Output) or else - Is_TSS (Current_Primitive, TSS_Stream_Read) or else - Is_TSS (Current_Primitive, TSS_Stream_Write)) - and then not Is_Hidden (Current_Primitive) - then - -- The first thing to do is build an up-to-date copy of the - -- spec with all the formals referencing Designated_Type - -- transformed into formals referencing Stub_Type. Since this - -- primitive may have been inherited, go back the alias chain - -- until the real primitive has been found. - - Current_Primitive_Alias := Current_Primitive; - while Present (Alias (Current_Primitive_Alias)) loop - pragma Assert - (Current_Primitive_Alias - /= Alias (Current_Primitive_Alias)); - Current_Primitive_Alias := Alias (Current_Primitive_Alias); - end loop; - - -- Copy the spec from the original declaration for the purpose - -- of declaring an overriding subprogram: we need to replace - -- the type of each controlling formal with Stub_Type. The - -- primitive may have been declared for Designated_Type or - -- inherited from some ancestor type for which we do not have - -- an easily determined Entity_Id. We have no systematic way - -- of knowing which type to substitute Stub_Type for. Instead, - -- Copy_Specification relies on the flag Is_Controlling_Formal - -- to determine which formals to change. - - Current_Primitive_Spec := - Copy_Specification (Loc, - Spec => Parent (Current_Primitive_Alias), - 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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('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)); - - Set_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); - - Set_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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('S')); - Set_Ekind (Stub_Type, E_Record_Type); - Set_Is_RACW_Stub_Type (Stub_Type); - Stub_Type_Access := - Make_Defining_Identifier (Loc, - Chars => New_External_Name - (Related_Id => Chars (Stub_Type), Suffix => 'A')); - - Specific_Build_Stub_Type - (RACW_Type, Stub_Type, - Stub_Type_Decl, RPC_Receiver_Decl); - - 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)); - - -- This is in no way a type derivation, but we fake it to make sure that - -- the dispatching table gets built with the corresponding primitive - -- operations at the right place. - - Derive_Subprograms (Parent_Type => Designated_Type, - Derived_Type => Stub_Type); - - if Present (RPC_Receiver_Decl) then - Append_To (Decls, RPC_Receiver_Decl); - else - 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_Defining_Identifier (Loc, - New_Internal_Name ('P')); - begin - Set_Defining_Identifier - (Last (Decls), Constant_Object); - - -- We have an unconstrained Etyp: build the actual constrained - -- subtype for the value we just read from the stream. - - -- subtype S is <actual subtype of Constant_Object>; - - Append_To (Decls, - Build_Actual_Subtype (Etyp, - New_Occurrence_Of (Constant_Object, Loc))); - - -- Object : S; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Object, - Object_Definition => - New_Occurrence_Of - (Defining_Identifier (Last (Decls)), Loc))); - Set_Ekind (Object, E_Variable); - - -- Suppress default initialization: - -- pragma Import (Ada, Object); - - Append_To (Decls, - Make_Pragma (Loc, - Chars => Name_Import, - Pragma_Argument_Associations => New_List ( - Make_Pragma_Argument_Association (Loc, - Chars => Name_Convention, - Expression => Make_Identifier (Loc, Name_Ada)), - Make_Pragma_Argument_Association (Loc, - Chars => Name_Entity, - Expression => New_Occurrence_Of (Object, Loc))))); - - -- for Object'Address use Constant_Object'Address; - - Append_To (Decls, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (Object, Loc), - Chars => Name_Address, - Expression => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Constant_Object, Loc), - Attribute_Name => Name_Address))); - end; - end if; - - else - - -- General case of a regular object declaration. Object is flagged - -- constant unless it has mode out or in out, to allow the backend - -- to optimize where possible. - - -- Object : [constant] Etyp [:= <expr>]; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Object, - Constant_Present => Present (Expr) and then not Variable, - Object_Definition => New_Occurrence_Of (Etyp, Loc), - Expression => Expr)); - - if Constant_Present (Last (Decls)) then - Set_Ekind (Object, E_Constant); - else - Set_Ekind (Object, E_Variable); - end if; - end if; - end Build_Actual_Object_Declaration; - - ------------------------------ - -- Build_Get_Unique_RP_Call -- - ------------------------------ - - function Build_Get_Unique_RP_Call - (Loc : Source_Ptr; - Pointer : Entity_Id; - Stub_Type : Entity_Id) return List_Id - is - begin - return New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc), - Parameter_Associations => New_List ( - Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access), - New_Occurrence_Of (Pointer, Loc)))), - - Make_Assignment_Statement (Loc, - Name => - Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Pointer, Loc), - Selector_Name => - New_Occurrence_Of (First_Tag_Component - (Designated_Type (Etype (Pointer))), Loc)), - Expression => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Stub_Type, Loc), - Attribute_Name => Name_Tag))); - - -- Note: The assignment to Pointer._Tag is safe here because - -- we carefully ensured that Stub_Type has exactly the same layout - -- as System.Partition_Interface.RACW_Stub_Type. - - end Build_Get_Unique_RP_Call; - - ----------------------------------- - -- Build_Ordered_Parameters_List -- - ----------------------------------- - - function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is - Constrained_List : List_Id; - Unconstrained_List : List_Id; - Current_Parameter : Node_Id; - Ptyp : Node_Id; - - First_Parameter : Node_Id; - For_RAS : Boolean := False; - - begin - if No (Parameter_Specifications (Spec)) then - return New_List; - end if; - - Constrained_List := New_List; - Unconstrained_List := New_List; - First_Parameter := First (Parameter_Specifications (Spec)); - - if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition - and then Chars (Defining_Identifier (First_Parameter)) = Name_uS - then - For_RAS := True; - end if; - - -- Loop through the parameters and add them to the right list. Note that - -- we treat a parameter of a null-excluding access type as unconstrained - -- because we can't declare an object of such a type with default - -- initialization. - - Current_Parameter := First_Parameter; - while Present (Current_Parameter) loop - Ptyp := Parameter_Type (Current_Parameter); - - if (Nkind (Ptyp) = N_Access_Definition - or else not Transmit_As_Unconstrained (Etype (Ptyp))) - and then not (For_RAS and then Current_Parameter = First_Parameter) - then - Append_To (Constrained_List, New_Copy (Current_Parameter)); - else - Append_To (Unconstrained_List, New_Copy (Current_Parameter)); - end if; - - Next (Current_Parameter); - end loop; - - -- Unconstrained parameters are returned first - - Append_List_To (Unconstrained_List, Constrained_List); - - return Unconstrained_List; - end Build_Ordered_Parameters_List; - - ---------------------------------- - -- Build_Passive_Partition_Stub -- - ---------------------------------- - - procedure Build_Passive_Partition_Stub (U : Node_Id) is - Pkg_Spec : Node_Id; - Pkg_Name : String_Id; - L : List_Id; - Reg : Node_Id; - Loc : constant Source_Ptr := Sloc (U); - - begin - -- Verify that the implementation supports distribution, by accessing - -- a type defined in the proper version of system.rpc - - declare - Dist_OK : Entity_Id; - pragma Warnings (Off, Dist_OK); - begin - Dist_OK := RTE (RE_Params_Stream_Type); - end; - - -- Use body if present, spec otherwise - - if Nkind (U) = N_Package_Declaration then - Pkg_Spec := Specification (U); - L := Visible_Declarations (Pkg_Spec); - else - Pkg_Spec := Parent (Corresponding_Spec (U)); - L := Declarations (U); - end if; - - Get_Library_Unit_Name_String (Pkg_Spec); - Pkg_Name := String_From_Name_Buffer; - Reg := - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc), - Parameter_Associations => New_List ( - Make_String_Literal (Loc, Pkg_Name), - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc), - Attribute_Name => Name_Version))); - Append_To (L, Reg); - Analyze (Reg); - end Build_Passive_Partition_Stub; - - -------------------------------------- - -- Build_RPC_Receiver_Specification -- - -------------------------------------- - - function Build_RPC_Receiver_Specification - (RPC_Receiver : Entity_Id; - Request_Parameter : Entity_Id) return Node_Id - is - Loc : constant Source_Ptr := Sloc (RPC_Receiver); - begin - return - Make_Procedure_Specification (Loc, - Defining_Unit_Name => RPC_Receiver, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Request_Parameter, - Parameter_Type => - New_Occurrence_Of (RTE (RE_Request_Access), Loc)))); - end Build_RPC_Receiver_Specification; - - ---------------------------------------- - -- Build_Remote_Subprogram_Proxy_Type -- - ---------------------------------------- - - function Build_Remote_Subprogram_Proxy_Type - (Loc : Source_Ptr; - ACR_Expression : Node_Id) return Node_Id - is - begin - return - Make_Record_Definition (Loc, - Tagged_Present => True, - Limited_Present => True, - Component_List => - Make_Component_List (Loc, - - Component_Items => New_List ( - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, - Name_All_Calls_Remote), - Component_Definition => - Make_Component_Definition (Loc, - Subtype_Indication => - New_Occurrence_Of (Standard_Boolean, Loc)), - Expression => - ACR_Expression), - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, - Name_Receiver), - Component_Definition => - Make_Component_Definition (Loc, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Address), Loc)), - Expression => - New_Occurrence_Of (RTE (RE_Null_Address), Loc)), - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, - Name_Subp_Id), - Component_Definition => - Make_Component_Definition (Loc, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)))))); - end Build_Remote_Subprogram_Proxy_Type; - - -------------------- - -- Build_Stub_Tag -- - -------------------- - - function Build_Stub_Tag - (Loc : Source_Ptr; - RACW_Type : Entity_Id) return Node_Id - is - Stub_Type : constant Entity_Id := Corresponding_Stub_Type (RACW_Type); - begin - return - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Stub_Type, Loc), - Attribute_Name => Name_Tag); - end Build_Stub_Tag; - - ------------------------------------ - -- Build_Subprogram_Calling_Stubs -- - ------------------------------------ - - function Build_Subprogram_Calling_Stubs - (Vis_Decl : Node_Id; - Subp_Id : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Locator : Entity_Id := Empty; - New_Name : Name_Id := No_Name) return Node_Id - is - Loc : constant Source_Ptr := Sloc (Vis_Decl); - - Decls : constant List_Id := New_List; - Statements : constant List_Id := New_List; - - Subp_Spec : Node_Id; - -- The specification of the body - - Controlling_Parameter : Entity_Id := Empty; - - Asynchronous_Expr : Node_Id := Empty; - - RCI_Locator : Entity_Id; - - Spec_To_Use : Node_Id; - - procedure Insert_Partition_Check (Parameter : Node_Id); - -- Check that the parameter has been elaborated on the same partition - -- than the controlling parameter (E.4(19)). - - ---------------------------- - -- Insert_Partition_Check -- - ---------------------------- - - procedure Insert_Partition_Check (Parameter : Node_Id) is - Parameter_Entity : constant Entity_Id := - Defining_Identifier (Parameter); - begin - -- The expression that will be built is of the form: - - -- if not Same_Partition (Parameter, Controlling_Parameter) then - -- raise Constraint_Error; - -- end if; - - -- We do not check that Parameter is in Stub_Type since such a check - -- has been inserted at the point of call already (a tag check since - -- we have multiple controlling operands). - - Append_To (Decls, - Make_Raise_Constraint_Error (Loc, - Condition => - Make_Op_Not (Loc, - Right_Opnd => - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Same_Partition), Loc), - Parameter_Associations => - New_List ( - Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access), - New_Occurrence_Of (Parameter_Entity, Loc)), - Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access), - New_Occurrence_Of (Controlling_Parameter, Loc))))), - Reason => CE_Partition_Check_Failed)); - end Insert_Partition_Check; - - -- Start of processing for Build_Subprogram_Calling_Stubs - - begin - Subp_Spec := Copy_Specification (Loc, - Spec => Specification (Vis_Decl), - New_Name => New_Name); - - if Locator = Empty then - RCI_Locator := RCI_Cache; - Spec_To_Use := Specification (Vis_Decl); - else - RCI_Locator := Locator; - Spec_To_Use := Subp_Spec; - end if; - - -- Find a controlling argument if we have a stub type. Also check - -- if this subprogram can be made asynchronous. - - if Present (Stub_Type) - and then Present (Parameter_Specifications (Spec_To_Use)) - then - declare - Current_Parameter : Node_Id := - First (Parameter_Specifications - (Spec_To_Use)); - begin - while Present (Current_Parameter) loop - if - Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) - then - if Controlling_Parameter = Empty then - Controlling_Parameter := - Defining_Identifier (Current_Parameter); - else - Insert_Partition_Check (Current_Parameter); - end if; - end if; - - Next (Current_Parameter); - end loop; - end; - end if; - - pragma Assert (No (Stub_Type) or else Present (Controlling_Parameter)); - - if Dynamically_Asynchronous then - Asynchronous_Expr := Make_Selected_Component (Loc, - Prefix => Controlling_Parameter, - Selector_Name => Name_Asynchronous); - end if; - - Specific_Build_General_Calling_Stubs - (Decls => Decls, - Statements => Statements, - Target => Specific_Build_Stub_Target (Loc, - Decls, RCI_Locator, Controlling_Parameter), - Subprogram_Id => Subp_Id, - Asynchronous => Asynchronous_Expr, - Is_Known_Asynchronous => Asynchronous - and then not Dynamically_Asynchronous, - Is_Known_Non_Asynchronous - => not Asynchronous - and then not Dynamically_Asynchronous, - Is_Function => Nkind (Spec_To_Use) = - N_Function_Specification, - Spec => Spec_To_Use, - Stub_Type => Stub_Type, - RACW_Type => RACW_Type, - Nod => Vis_Decl); - - RCI_Calling_Stubs_Table.Set - (Defining_Unit_Name (Specification (Vis_Decl)), - Defining_Unit_Name (Spec_To_Use)); - - return - Make_Subprogram_Body (Loc, - Specification => Subp_Spec, - Declarations => Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, Statements)); - end Build_Subprogram_Calling_Stubs; - - ------------------------- - -- Build_Subprogram_Id -- - ------------------------- - - function Build_Subprogram_Id - (Loc : Source_Ptr; - E : Entity_Id) return Node_Id - is - begin - if Get_Subprogram_Ids (E).Str_Identifier = No_String then - declare - Current_Declaration : Node_Id; - Current_Subp : Entity_Id; - Current_Subp_Str : String_Id; - Current_Subp_Number : Int := First_RCI_Subprogram_Id; - - pragma Warnings (Off, Current_Subp_Str); - - begin - -- Build_Subprogram_Id is called outside of the context of - -- generating calling or receiving stubs. Hence we are processing - -- an 'Access attribute_reference for an RCI subprogram, for the - -- purpose of obtaining a RAS value. - - pragma Assert - (Is_Remote_Call_Interface (Scope (E)) - and then - (Nkind (Parent (E)) = N_Procedure_Specification - or else - Nkind (Parent (E)) = N_Function_Specification)); - - Current_Declaration := - First (Visible_Declarations - (Package_Specification_Of_Scope (Scope (E)))); - while Present (Current_Declaration) loop - if Nkind (Current_Declaration) = N_Subprogram_Declaration - and then Comes_From_Source (Current_Declaration) - then - Current_Subp := Defining_Unit_Name (Specification ( - Current_Declaration)); - - Assign_Subprogram_Identifier - (Current_Subp, Current_Subp_Number, Current_Subp_Str); - - Current_Subp_Number := Current_Subp_Number + 1; - end if; - - Next (Current_Declaration); - end loop; - end; - end if; - - case Get_PCS_Name is - when Name_PolyORB_DSA => - return Make_String_Literal (Loc, Get_Subprogram_Id (E)); - when others => - return Make_Integer_Literal (Loc, Get_Subprogram_Id (E)); - end case; - end Build_Subprogram_Id; - - ------------------------ - -- Copy_Specification -- - ------------------------ - - function Copy_Specification - (Loc : Source_Ptr; - Spec : Node_Id; - Ctrl_Type : Entity_Id := Empty; - New_Name : Name_Id := No_Name) return Node_Id - is - Parameters : List_Id := No_List; - - Current_Parameter : Node_Id; - Current_Identifier : Entity_Id; - Current_Type : Node_Id; - - Name_For_New_Spec : Name_Id; - - New_Identifier : Entity_Id; - - -- Comments needed in body below ??? - - begin - if New_Name = No_Name then - pragma Assert (Nkind (Spec) = N_Function_Specification - or else Nkind (Spec) = N_Procedure_Specification); - - Name_For_New_Spec := Chars (Defining_Unit_Name (Spec)); - else - Name_For_New_Spec := New_Name; - end if; - - if Present (Parameter_Specifications (Spec)) then - Parameters := New_List; - Current_Parameter := First (Parameter_Specifications (Spec)); - while Present (Current_Parameter) loop - Current_Identifier := Defining_Identifier (Current_Parameter); - Current_Type := Parameter_Type (Current_Parameter); - - if Nkind (Current_Type) = N_Access_Definition then - if Present (Ctrl_Type) then - pragma Assert (Is_Controlling_Formal (Current_Identifier)); - Current_Type := - Make_Access_Definition (Loc, - Subtype_Mark => New_Occurrence_Of (Ctrl_Type, Loc), - Null_Exclusion_Present => - Null_Exclusion_Present (Current_Type)); - - else - Current_Type := - Make_Access_Definition (Loc, - Subtype_Mark => - New_Copy_Tree (Subtype_Mark (Current_Type)), - Null_Exclusion_Present => - Null_Exclusion_Present (Current_Type)); - end if; - - else - if Present (Ctrl_Type) - and then Is_Controlling_Formal (Current_Identifier) - then - Current_Type := New_Occurrence_Of (Ctrl_Type, Loc); - else - Current_Type := New_Copy_Tree (Current_Type); - end if; - end if; - - New_Identifier := Make_Defining_Identifier (Loc, - Chars (Current_Identifier)); - - Append_To (Parameters, - Make_Parameter_Specification (Loc, - Defining_Identifier => New_Identifier, - Parameter_Type => Current_Type, - In_Present => In_Present (Current_Parameter), - Out_Present => Out_Present (Current_Parameter), - Expression => - New_Copy_Tree (Expression (Current_Parameter)))); - - -- For a regular formal parameter (that needs to be marshalled - -- in the context of remote calls), set the Etype now, because - -- marshalling processing might need it. - - if Is_Entity_Name (Current_Type) then - Set_Etype (New_Identifier, Entity (Current_Type)); - - -- Current_Type is an access definition, special processing - -- (not requiring etype) will occur for marshalling. - - else - null; - end if; - - Next (Current_Parameter); - end loop; - end if; - - case Nkind (Spec) is - - when N_Function_Specification | N_Access_Function_Definition => - return - Make_Function_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, - Chars => Name_For_New_Spec), - Parameter_Specifications => Parameters, - Result_Definition => - New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc)); - - when N_Procedure_Specification | N_Access_Procedure_Definition => - return - Make_Procedure_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, - Chars => Name_For_New_Spec), - Parameter_Specifications => Parameters); - - when others => - raise Program_Error; - end case; - end Copy_Specification; - - ----------------------------- - -- Corresponding_Stub_Type -- - ----------------------------- - - function Corresponding_Stub_Type (RACW_Type : Entity_Id) return Entity_Id is - Desig : constant Entity_Id := - Etype (Designated_Type (RACW_Type)); - Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig); - begin - return Stub_Elements.Stub_Type; - end Corresponding_Stub_Type; - - --------------------------- - -- Could_Be_Asynchronous -- - --------------------------- - - function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is - Current_Parameter : Node_Id; - - begin - if Present (Parameter_Specifications (Spec)) then - Current_Parameter := First (Parameter_Specifications (Spec)); - while Present (Current_Parameter) loop - if Out_Present (Current_Parameter) then - return False; - end if; - - Next (Current_Parameter); - end loop; - end if; - - return True; - end Could_Be_Asynchronous; - - --------------------------- - -- Declare_Create_NVList -- - --------------------------- - - procedure Declare_Create_NVList - (Loc : Source_Ptr; - NVList : Entity_Id; - Decls : List_Id; - Stmts : List_Id) - is - begin - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => NVList, - Aliased_Present => False, - Object_Definition => - New_Occurrence_Of (RTE (RE_NVList_Ref), Loc))); - - Append_To (Stmts, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_NVList_Create), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (NVList, Loc)))); - end Declare_Create_NVList; - - --------------------------------------------- - -- Expand_All_Calls_Remote_Subprogram_Call -- - --------------------------------------------- - - procedure Expand_All_Calls_Remote_Subprogram_Call (N : Node_Id) is - Called_Subprogram : constant Entity_Id := Entity (Name (N)); - RCI_Package : constant Entity_Id := Scope (Called_Subprogram); - Loc : constant Source_Ptr := Sloc (N); - RCI_Locator : Node_Id; - RCI_Cache : Entity_Id; - Calling_Stubs : Node_Id; - E_Calling_Stubs : Entity_Id; - - begin - E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram); - - if E_Calling_Stubs = Empty then - RCI_Cache := RCI_Locator_Table.Get (RCI_Package); - - if RCI_Cache = Empty then - RCI_Locator := - RCI_Package_Locator - (Loc, Specification (Unit_Declaration_Node (RCI_Package))); - Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator); - - -- The RCI_Locator package is inserted at the top level in the - -- current unit, and must appear in the proper scope, so that it - -- is not prematurely removed by the GCC back-end. - - declare - Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit); - - begin - if Ekind (Scop) = E_Package_Body then - Push_Scope (Spec_Entity (Scop)); - - elsif Ekind (Scop) = E_Subprogram_Body then - Push_Scope - (Corresponding_Spec (Unit_Declaration_Node (Scop))); - - else - Push_Scope (Scop); - end if; - - Analyze (RCI_Locator); - Pop_Scope; - end; - - RCI_Cache := Defining_Unit_Name (RCI_Locator); - - else - RCI_Locator := Parent (RCI_Cache); - end if; - - Calling_Stubs := Build_Subprogram_Calling_Stubs - (Vis_Decl => Parent (Parent (Called_Subprogram)), - Subp_Id => - Build_Subprogram_Id (Loc, Called_Subprogram), - Asynchronous => Nkind (N) = N_Procedure_Call_Statement - and then - Is_Asynchronous (Called_Subprogram), - Locator => RCI_Cache, - New_Name => New_Internal_Name ('S')); - Insert_After (RCI_Locator, Calling_Stubs); - Analyze (Calling_Stubs); - E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs)); - end if; - - Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc)); - end Expand_All_Calls_Remote_Subprogram_Call; - - --------------------------------- - -- Expand_Calling_Stubs_Bodies -- - --------------------------------- - - procedure Expand_Calling_Stubs_Bodies (Unit_Node : Node_Id) is - Spec : constant Node_Id := Specification (Unit_Node); - Decls : constant List_Id := Visible_Declarations (Spec); - begin - Push_Scope (Scope_Of_Spec (Spec)); - Add_Calling_Stubs_To_Declarations - (Specification (Unit_Node), Decls); - Pop_Scope; - end Expand_Calling_Stubs_Bodies; - - ----------------------------------- - -- Expand_Receiving_Stubs_Bodies -- - ----------------------------------- - - procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is - Spec : Node_Id; - Decls : List_Id; - Stubs_Decls : List_Id; - Stubs_Stmts : List_Id; - - begin - if Nkind (Unit_Node) = N_Package_Declaration then - Spec := Specification (Unit_Node); - Decls := Private_Declarations (Spec); - - if No (Decls) then - Decls := Visible_Declarations (Spec); - end if; - - Push_Scope (Scope_Of_Spec (Spec)); - Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls, Decls); - - else - Spec := - Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node)); - Decls := Declarations (Unit_Node); - - Push_Scope (Scope_Of_Spec (Unit_Node)); - Stubs_Decls := New_List; - Stubs_Stmts := New_List; - Specific_Add_Receiving_Stubs_To_Declarations - (Spec, Stubs_Decls, Stubs_Stmts); - - Insert_List_Before (First (Decls), Stubs_Decls); - - declare - HSS_Stmts : constant List_Id := - Statements (Handled_Statement_Sequence (Unit_Node)); - - First_HSS_Stmt : constant Node_Id := First (HSS_Stmts); - - begin - if No (First_HSS_Stmt) then - Append_List_To (HSS_Stmts, Stubs_Stmts); - else - Insert_List_Before (First_HSS_Stmt, Stubs_Stmts); - end if; - end; - end if; - - Pop_Scope; - end Expand_Receiving_Stubs_Bodies; - - -------------------- - -- GARLIC_Support -- - -------------------- - - package body GARLIC_Support is - - -- Local subprograms - - procedure Add_RACW_Read_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - Body_Decls : List_Id); - -- Add Read attribute for the RACW type. The declaration and attribute - -- definition clauses are inserted right after the declaration of - -- RACW_Type. If Body_Decls is not No_List, the subprogram body is - -- appended to it (case where the RACW declaration is in the main unit). - - procedure Add_RACW_Write_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver : Node_Id; - Body_Decls : List_Id); - -- Same as above for the Write attribute - - function Stream_Parameter return Node_Id; - function Result return Node_Id; - function Object return Node_Id renames Result; - -- Functions to create occurrences of the formal parameter names of the - -- 'Read and 'Write attributes. - - Loc : Source_Ptr; - -- Shared source location used by Add_{Read,Write}_Read_Attribute and - -- their ancillary subroutines (set on entry by Add_RACW_Features). - - procedure Add_RAS_Access_TSS (N : Node_Id); - -- Add a subprogram body for RAS Access TSS - - ------------------------------------- - -- Add_Obj_RPC_Receiver_Completion -- - ------------------------------------- - - procedure Add_Obj_RPC_Receiver_Completion - (Loc : Source_Ptr; - Decls : List_Id; - RPC_Receiver : Entity_Id; - Stub_Elements : Stub_Structure) - is - begin - -- The RPC receiver body should not be the completion of the - -- declaration recorded in the stub structure, because then the - -- occurrences of the formal parameters within the body should refer - -- to the entities from the declaration, not from the completion, to - -- which we do not have easy access. Instead, the RPC receiver body - -- acts as its own declaration, and the RPC receiver declaration is - -- completed by a renaming-as-body. - - Append_To (Decls, - Make_Subprogram_Renaming_Declaration (Loc, - Specification => - Copy_Specification (Loc, - Specification (Stub_Elements.RPC_Receiver_Decl)), - Name => New_Occurrence_Of (RPC_Receiver, Loc))); - end Add_Obj_RPC_Receiver_Completion; - - ----------------------- - -- Add_RACW_Features -- - ----------------------- - - procedure Add_RACW_Features - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver_Decl : Node_Id; - Body_Decls : List_Id) - is - RPC_Receiver : Node_Id; - Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type); - - begin - Loc := Sloc (RACW_Type); - - if Is_RAS then - - -- For a RAS, the RPC receiver is that of the RCI unit, not that - -- of the corresponding distributed object type. We retrieve its - -- address from the local proxy object. - - RPC_Receiver := Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object), - Selector_Name => Make_Identifier (Loc, Name_Receiver)); - - else - RPC_Receiver := Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of ( - Defining_Unit_Name (Specification (RPC_Receiver_Decl)), Loc), - Attribute_Name => Name_Address); - end if; - - Add_RACW_Write_Attribute - (RACW_Type, - Stub_Type, - Stub_Type_Access, - RPC_Receiver, - Body_Decls); - - Add_RACW_Read_Attribute - (RACW_Type, - Stub_Type, - Stub_Type_Access, - Body_Decls); - end Add_RACW_Features; - - ----------------------------- - -- Add_RACW_Read_Attribute -- - ----------------------------- - - procedure Add_RACW_Read_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - Body_Decls : List_Id) - is - Proc_Decl : Node_Id; - Attr_Decl : Node_Id; - - Body_Node : Node_Id; - - Statements : constant List_Id := New_List; - Decls : List_Id; - Local_Statements : List_Id; - Remote_Statements : List_Id; - -- Various parts of the procedure - - Pnam : constant Entity_Id := - Make_Defining_Identifier - (Loc, New_Internal_Name ('R')); - Asynchronous_Flag : constant Entity_Id := - Asynchronous_Flags_Table.Get (RACW_Type); - pragma Assert (Present (Asynchronous_Flag)); - - -- Prepare local identifiers - - Source_Partition : Entity_Id; - Source_Receiver : Entity_Id; - Source_Address : Entity_Id; - Local_Stub : Entity_Id; - Stubbed_Result : Entity_Id; - - -- Start of processing for Add_RACW_Read_Attribute - - begin - Build_Stream_Procedure (Loc, - RACW_Type, Body_Node, Pnam, Statements, Outp => True); - Proc_Decl := Make_Subprogram_Declaration (Loc, - Copy_Specification (Loc, Specification (Body_Node))); - - Attr_Decl := - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (RACW_Type, Loc), - Chars => Name_Read, - Expression => - New_Occurrence_Of ( - Defining_Unit_Name (Specification (Proc_Decl)), Loc)); - - Insert_After (Declaration_Node (RACW_Type), Proc_Decl); - Insert_After (Proc_Decl, Attr_Decl); - - if No (Body_Decls) then - - -- Case of processing an RACW type from another unit than the - -- main one: do not generate a body. - - return; - end if; - - -- Prepare local identifiers - - Source_Partition := - Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - Source_Receiver := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - Source_Address := - Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - Local_Stub := - Make_Defining_Identifier (Loc, New_Internal_Name ('L')); - Stubbed_Result := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - - -- Generate object declarations - - Decls := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Source_Partition, - Object_Definition => - New_Occurrence_Of (RTE (RE_Partition_ID), Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Source_Receiver, - Object_Definition => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Source_Address, - Object_Definition => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Local_Stub, - Aliased_Present => True, - Object_Definition => New_Occurrence_Of (Stub_Type, Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Stubbed_Result, - Object_Definition => - New_Occurrence_Of (Stub_Type_Access, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Local_Stub, Loc), - Attribute_Name => - Name_Unchecked_Access))); - - -- Read the source Partition_ID and RPC_Receiver from incoming stream - - Append_List_To (Statements, New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Partition_ID), Loc), - Attribute_Name => Name_Read, - Expressions => New_List ( - Stream_Parameter, - New_Occurrence_Of (Source_Partition, Loc))), - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc), - Attribute_Name => - Name_Read, - Expressions => New_List ( - Stream_Parameter, - New_Occurrence_Of (Source_Receiver, Loc))), - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc), - Attribute_Name => - Name_Read, - Expressions => New_List ( - Stream_Parameter, - New_Occurrence_Of (Source_Address, Loc))))); - - -- Build_Get_Unique_RP_Call needs the type of Stubbed_Result - - Set_Etype (Stubbed_Result, Stub_Type_Access); - - -- If the Address is Null_Address, then return a null object, unless - -- RACW_Type is null-excluding, in which case unconditionally raise - -- CONSTRAINT_ERROR instead. - - declare - Zero_Statements : List_Id; - -- Statements executed when a zero value is received - - begin - if Can_Never_Be_Null (RACW_Type) then - Zero_Statements := New_List ( - Make_Raise_Constraint_Error (Loc, - Reason => CE_Null_Not_Allowed)); - else - Zero_Statements := New_List ( - Make_Assignment_Statement (Loc, - Name => Result, - Expression => Make_Null (Loc)), - Make_Simple_Return_Statement (Loc)); - end if; - - Append_To (Statements, - Make_Implicit_If_Statement (RACW_Type, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => New_Occurrence_Of (Source_Address, Loc), - Right_Opnd => Make_Integer_Literal (Loc, Uint_0)), - Then_Statements => Zero_Statements)); - end; - - -- If the RACW denotes an object created on the current partition, - -- Local_Statements will be executed. The real object will be used. - - Local_Statements := New_List ( - Make_Assignment_Statement (Loc, - Name => Result, - Expression => - Unchecked_Convert_To (RACW_Type, - OK_Convert_To (RTE (RE_Address), - New_Occurrence_Of (Source_Address, Loc))))); - - -- If the object is located on another partition, then a stub object - -- will be created with all the information needed to rebuild the - -- real object at the other end. - - Remote_Statements := New_List ( - - Make_Assignment_Statement (Loc, - Name => Make_Selected_Component (Loc, - Prefix => Stubbed_Result, - Selector_Name => Name_Origin), - Expression => - New_Occurrence_Of (Source_Partition, Loc)), - - Make_Assignment_Statement (Loc, - Name => Make_Selected_Component (Loc, - Prefix => Stubbed_Result, - Selector_Name => Name_Receiver), - Expression => - New_Occurrence_Of (Source_Receiver, Loc)), - - Make_Assignment_Statement (Loc, - Name => Make_Selected_Component (Loc, - Prefix => Stubbed_Result, - Selector_Name => Name_Addr), - Expression => - New_Occurrence_Of (Source_Address, Loc))); - - Append_To (Remote_Statements, - Make_Assignment_Statement (Loc, - Name => Make_Selected_Component (Loc, - Prefix => Stubbed_Result, - Selector_Name => Name_Asynchronous), - Expression => - New_Occurrence_Of (Asynchronous_Flag, Loc))); - - Append_List_To (Remote_Statements, - Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type)); - -- ??? Issue with asynchronous calls here: the Asynchronous flag is - -- set on the stub type if, and only if, the RACW type has a pragma - -- Asynchronous. This is incorrect for RACWs that implement RAS - -- types, because in that case the /designated subprogram/ (not the - -- type) might be asynchronous, and that causes the stub to need to - -- be asynchronous too. A solution is to transport a RAS as a struct - -- containing a RACW and an asynchronous flag, and to properly alter - -- the Asynchronous component in the stub type in the RAS's Input - -- TSS. - - Append_To (Remote_Statements, - Make_Assignment_Statement (Loc, - Name => Result, - Expression => Unchecked_Convert_To (RACW_Type, - New_Occurrence_Of (Stubbed_Result, Loc)))); - - -- Distinguish between the local and remote cases, and execute the - -- appropriate piece of code. - - Append_To (Statements, - Make_Implicit_If_Statement (RACW_Type, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => - Make_Function_Call (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Get_Local_Partition_Id), Loc)), - Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)), - Then_Statements => Local_Statements, - Else_Statements => Remote_Statements)); - - Set_Declarations (Body_Node, Decls); - Append_To (Body_Decls, Body_Node); - end Add_RACW_Read_Attribute; - - ------------------------------ - -- Add_RACW_Write_Attribute -- - ------------------------------ - - procedure Add_RACW_Write_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver : Node_Id; - Body_Decls : List_Id) - is - Body_Node : Node_Id; - Proc_Decl : Node_Id; - Attr_Decl : Node_Id; - - Statements : constant List_Id := New_List; - Local_Statements : List_Id; - Remote_Statements : List_Id; - Null_Statements : List_Id; - - Pnam : constant Entity_Id := - Make_Defining_Identifier (Loc, New_Internal_Name ('R')); - - begin - Build_Stream_Procedure - (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => False); - - Proc_Decl := Make_Subprogram_Declaration (Loc, - Copy_Specification (Loc, Specification (Body_Node))); - - Attr_Decl := - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (RACW_Type, Loc), - Chars => Name_Write, - Expression => - New_Occurrence_Of ( - Defining_Unit_Name (Specification (Proc_Decl)), Loc)); - - Insert_After (Declaration_Node (RACW_Type), Proc_Decl); - Insert_After (Proc_Decl, Attr_Decl); - - if No (Body_Decls) then - return; - end if; - - -- Build the code fragment corresponding to the marshalling of a - -- local object. - - Local_Statements := New_List ( - - Pack_Entity_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => RTE (RE_Get_Local_Partition_Id)), - - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver), - Etyp => RTE (RE_Unsigned_64)), - - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => OK_Convert_To (RTE (RE_Unsigned_64), - Make_Attribute_Reference (Loc, - Prefix => - Make_Explicit_Dereference (Loc, - Prefix => Object), - Attribute_Name => Name_Address)), - Etyp => RTE (RE_Unsigned_64))); - - -- Build the code fragment corresponding to the marshalling of - -- a remote object. - - Remote_Statements := New_List ( - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To (Stub_Type_Access, Object), - Selector_Name => Make_Identifier (Loc, Name_Origin)), - Etyp => RTE (RE_Partition_ID)), - - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To (Stub_Type_Access, Object), - Selector_Name => Make_Identifier (Loc, Name_Receiver)), - Etyp => RTE (RE_Unsigned_64)), - - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To (Stub_Type_Access, Object), - Selector_Name => Make_Identifier (Loc, Name_Addr)), - Etyp => RTE (RE_Unsigned_64))); - - -- Build code fragment corresponding to marshalling of a null object - - Null_Statements := New_List ( - - Pack_Entity_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => RTE (RE_Get_Local_Partition_Id)), - - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver), - Etyp => RTE (RE_Unsigned_64)), - - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => Make_Integer_Literal (Loc, Uint_0), - Etyp => RTE (RE_Unsigned_64))); - - Append_To (Statements, - Make_Implicit_If_Statement (RACW_Type, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => Object, - Right_Opnd => Make_Null (Loc)), - - Then_Statements => Null_Statements, - - Elsif_Parts => New_List ( - Make_Elsif_Part (Loc, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => - Make_Attribute_Reference (Loc, - Prefix => Object, - Attribute_Name => Name_Tag), - - Right_Opnd => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Stub_Type, Loc), - Attribute_Name => Name_Tag)), - Then_Statements => Remote_Statements)), - Else_Statements => Local_Statements)); - - Append_To (Body_Decls, Body_Node); - end Add_RACW_Write_Attribute; - - ------------------------ - -- Add_RAS_Access_TSS -- - ------------------------ - - procedure Add_RAS_Access_TSS (N : Node_Id) is - Loc : constant Source_Ptr := Sloc (N); - - Ras_Type : constant Entity_Id := Defining_Identifier (N); - Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type); - -- Ras_Type is the access to subprogram type while Fat_Type is the - -- corresponding record type. - - RACW_Type : constant Entity_Id := - Underlying_RACW_Type (Ras_Type); - Desig : constant Entity_Id := - Etype (Designated_Type (RACW_Type)); - - Stub_Elements : constant Stub_Structure := - Stubs_Table.Get (Desig); - pragma Assert (Stub_Elements /= Empty_Stub_Structure); - - Proc : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access)); - - Proc_Spec : Node_Id; - - -- Formal parameters - - Package_Name : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_P); - -- Target package - - Subp_Id : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_S); - -- Target subprogram - - Asynch_P : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_Asynchronous); - -- Is the procedure to which the 'Access applies asynchronous? - - All_Calls_Remote : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_All_Calls_Remote); - -- True if an All_Calls_Remote pragma applies to the RCI unit - -- that contains the subprogram. - - -- Common local variables - - Proc_Decls : List_Id; - Proc_Statements : List_Id; - - Origin : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('P')); - - -- Additional local variables for the local case - - Proxy_Addr : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('P')); - - -- Additional local variables for the remote case - - Local_Stub : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('L')); - - Stub_Ptr : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('S')); - - function Set_Field - (Field_Name : Name_Id; - Value : Node_Id) return Node_Id; - -- Construct an assignment that sets the named component in the - -- returned record - - --------------- - -- Set_Field -- - --------------- - - function Set_Field - (Field_Name : Name_Id; - Value : Node_Id) return Node_Id - is - begin - return - Make_Assignment_Statement (Loc, - Name => - Make_Selected_Component (Loc, - Prefix => Stub_Ptr, - Selector_Name => Field_Name), - Expression => Value); - end Set_Field; - - -- Start of processing for Add_RAS_Access_TSS - - begin - Proc_Decls := New_List ( - - -- Common declarations - - Make_Object_Declaration (Loc, - Defining_Identifier => Origin, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Partition_ID), Loc), - Expression => - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Package_Name, Loc)))), - - -- Declaration use only in the local case: proxy address - - Make_Object_Declaration (Loc, - Defining_Identifier => Proxy_Addr, - Object_Definition => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)), - - -- Declarations used only in the remote case: stub object and - -- stub pointer. - - Make_Object_Declaration (Loc, - Defining_Identifier => Local_Stub, - Aliased_Present => True, - Object_Definition => - New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => - Stub_Ptr, - Object_Definition => - New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Local_Stub, Loc), - Attribute_Name => Name_Unchecked_Access))); - - Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access); - - -- Build_Get_Unique_RP_Call needs above information - - -- Note: Here we assume that the Fat_Type is a record - -- containing just a pointer to a proxy or stub object. - - Proc_Statements := New_List ( - - -- Generate: - - -- Get_RAS_Info (Pkg, Subp, PA); - -- if Origin = Local_Partition_Id - -- and then not All_Calls_Remote - -- then - -- return Fat_Type!(PA); - -- end if; - - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Package_Name, Loc), - New_Occurrence_Of (Subp_Id, Loc), - New_Occurrence_Of (Proxy_Addr, Loc))), - - Make_Implicit_If_Statement (N, - Condition => - Make_And_Then (Loc, - Left_Opnd => - Make_Op_Eq (Loc, - Left_Opnd => - New_Occurrence_Of (Origin, Loc), - Right_Opnd => - Make_Function_Call (Loc, - New_Occurrence_Of ( - RTE (RE_Get_Local_Partition_Id), Loc))), - - Right_Opnd => - Make_Op_Not (Loc, - New_Occurrence_Of (All_Calls_Remote, Loc))), - - Then_Statements => New_List ( - Make_Simple_Return_Statement (Loc, - Unchecked_Convert_To (Fat_Type, - OK_Convert_To (RTE (RE_Address), - New_Occurrence_Of (Proxy_Addr, Loc)))))), - - Set_Field (Name_Origin, - New_Occurrence_Of (Origin, Loc)), - - Set_Field (Name_Receiver, - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Package_Name, Loc)))), - - Set_Field (Name_Addr, New_Occurrence_Of (Proxy_Addr, Loc)), - - -- E.4.1(9) A remote call is asynchronous if it is a call to - -- a procedure or a call through a value of an access-to-procedure - -- type to which a pragma Asynchronous applies. - - -- Asynch_P is true when the procedure is asynchronous; - -- Asynch_T is true when the type is asynchronous. - - Set_Field (Name_Asynchronous, - Make_Or_Else (Loc, - New_Occurrence_Of (Asynch_P, Loc), - New_Occurrence_Of (Boolean_Literals ( - Is_Asynchronous (Ras_Type)), Loc)))); - - Append_List_To (Proc_Statements, - Build_Get_Unique_RP_Call - (Loc, Stub_Ptr, Stub_Elements.Stub_Type)); - - -- Return the newly created value - - Append_To (Proc_Statements, - Make_Simple_Return_Statement (Loc, - Expression => - Unchecked_Convert_To (Fat_Type, - New_Occurrence_Of (Stub_Ptr, Loc)))); - - Proc_Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => Proc, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Package_Name, - Parameter_Type => - New_Occurrence_Of (Standard_String, Loc)), - - Make_Parameter_Specification (Loc, - Defining_Identifier => Subp_Id, - Parameter_Type => - New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)), - - Make_Parameter_Specification (Loc, - Defining_Identifier => Asynch_P, - Parameter_Type => - New_Occurrence_Of (Standard_Boolean, Loc)), - - Make_Parameter_Specification (Loc, - Defining_Identifier => All_Calls_Remote, - Parameter_Type => - New_Occurrence_Of (Standard_Boolean, Loc))), - - Result_Definition => - New_Occurrence_Of (Fat_Type, Loc)); - - -- Set the kind and return type of the function to prevent - -- ambiguities between Ras_Type and Fat_Type in subsequent analysis. - - Set_Ekind (Proc, E_Function); - Set_Etype (Proc, Fat_Type); - - Discard_Node ( - Make_Subprogram_Body (Loc, - Specification => Proc_Spec, - Declarations => Proc_Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Proc_Statements))); - - Set_TSS (Fat_Type, Proc); - end Add_RAS_Access_TSS; - - ----------------------- - -- Add_RAST_Features -- - ----------------------- - - procedure Add_RAST_Features - (Vis_Decl : Node_Id; - RAS_Type : Entity_Id) - is - pragma Warnings (Off); - pragma Unreferenced (RAS_Type); - pragma Warnings (On); - begin - Add_RAS_Access_TSS (Vis_Decl); - end Add_RAST_Features; - - ----------------------------------------- - -- Add_Receiving_Stubs_To_Declarations -- - ----------------------------------------- - - procedure Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id; - Stmts : List_Id) - is - Loc : constant Source_Ptr := Sloc (Pkg_Spec); - - Request_Parameter : Node_Id; - - Pkg_RPC_Receiver : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('H')); - Pkg_RPC_Receiver_Statements : List_Id; - Pkg_RPC_Receiver_Cases : constant List_Id := New_List; - Pkg_RPC_Receiver_Body : Node_Id; - -- A Pkg_RPC_Receiver is built to decode the request - - Lookup_RAS_Info : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('R')); - -- A remote subprogram is created to allow peers to look up - -- RAS information using subprogram ids. - - Subp_Id : Entity_Id; - Subp_Index : Entity_Id; - -- Subprogram_Id as read from the incoming stream - - Current_Declaration : Node_Id; - Current_Subprogram_Number : Int := First_RCI_Subprogram_Id; - Current_Stubs : Node_Id; - - Subp_Info_Array : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('I')); - - Subp_Info_List : constant List_Id := New_List; - - Register_Pkg_Actuals : constant List_Id := New_List; - - All_Calls_Remote_E : Entity_Id; - Proxy_Object_Addr : Entity_Id; - - procedure Append_Stubs_To - (RPC_Receiver_Cases : List_Id; - Stubs : Node_Id; - Subprogram_Number : Int); - -- Add one case to the specified RPC receiver case list - -- associating Subprogram_Number with the subprogram declared - -- by Declaration, for which we have receiving stubs in Stubs. - - --------------------- - -- Append_Stubs_To -- - --------------------- - - procedure Append_Stubs_To - (RPC_Receiver_Cases : List_Id; - Stubs : Node_Id; - Subprogram_Number : Int) - is - begin - Append_To (RPC_Receiver_Cases, - Make_Case_Statement_Alternative (Loc, - Discrete_Choices => - New_List (Make_Integer_Literal (Loc, Subprogram_Number)), - Statements => - New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (Defining_Entity (Stubs), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Request_Parameter, Loc)))))); - end Append_Stubs_To; - - -- Start of processing for Add_Receiving_Stubs_To_Declarations - - begin - -- Building receiving stubs consist in several operations: - - -- - a package RPC receiver must be built. This subprogram - -- will get a Subprogram_Id from the incoming stream - -- and will dispatch the call to the right subprogram; - - -- - a receiving stub for each subprogram visible in the package - -- spec. This stub will read all the parameters from the stream, - -- and put the result as well as the exception occurrence in the - -- output stream; - - -- - a dummy package with an empty spec and a body made of an - -- elaboration part, whose job is to register the receiving - -- part of this RCI package on the name server. This is done - -- by calling System.Partition_Interface.Register_Receiving_Stub. - - Build_RPC_Receiver_Body ( - RPC_Receiver => Pkg_RPC_Receiver, - Request => Request_Parameter, - Subp_Id => Subp_Id, - Subp_Index => Subp_Index, - Stmts => Pkg_RPC_Receiver_Statements, - Decl => Pkg_RPC_Receiver_Body); - pragma Assert (Subp_Id = Subp_Index); - - -- A null subp_id denotes a call through a RAS, in which case the - -- next Uint_64 element in the stream is the address of the local - -- proxy object, from which we can retrieve the actual subprogram id. - - Append_To (Pkg_RPC_Receiver_Statements, - Make_Implicit_If_Statement (Pkg_Spec, - Condition => - Make_Op_Eq (Loc, - New_Occurrence_Of (Subp_Id, Loc), - Make_Integer_Literal (Loc, 0)), - - Then_Statements => New_List ( - Make_Assignment_Statement (Loc, - Name => - New_Occurrence_Of (Subp_Id, Loc), - - Expression => - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), - OK_Convert_To (RTE (RE_Address), - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc), - Attribute_Name => - Name_Input, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Params))))), - - Selector_Name => - Make_Identifier (Loc, Name_Subp_Id)))))); - - -- Build a subprogram for RAS information lookups - - Current_Declaration := - Make_Subprogram_Declaration (Loc, - Specification => - Make_Function_Specification (Loc, - Defining_Unit_Name => - Lookup_RAS_Info, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Subp_Id), - In_Present => - True, - Parameter_Type => - New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))), - Result_Definition => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))); - - Append_To (Decls, Current_Declaration); - Analyze (Current_Declaration); - - Current_Stubs := Build_Subprogram_Receiving_Stubs - (Vis_Decl => Current_Declaration, - Asynchronous => False); - Append_To (Decls, Current_Stubs); - Analyze (Current_Stubs); - - Append_Stubs_To (Pkg_RPC_Receiver_Cases, - Stubs => - Current_Stubs, - Subprogram_Number => 1); - - -- For each subprogram, the receiving stub will be built and a - -- case statement will be made on the Subprogram_Id to dispatch - -- to the right subprogram. - - All_Calls_Remote_E := - Boolean_Literals - (Has_All_Calls_Remote (Defining_Entity (Pkg_Spec))); - - Overload_Counter_Table.Reset; - - Current_Declaration := First (Visible_Declarations (Pkg_Spec)); - while Present (Current_Declaration) loop - if Nkind (Current_Declaration) = N_Subprogram_Declaration - and then Comes_From_Source (Current_Declaration) - then - declare - Loc : constant Source_Ptr := Sloc (Current_Declaration); - -- While specifically processing Current_Declaration, use - -- its Sloc as the location of all generated nodes. - - Subp_Def : constant Entity_Id := - Defining_Unit_Name - (Specification (Current_Declaration)); - - Subp_Val : String_Id; - pragma Warnings (Off, Subp_Val); - - begin - -- Build receiving stub - - Current_Stubs := - Build_Subprogram_Receiving_Stubs - (Vis_Decl => Current_Declaration, - Asynchronous => - Nkind (Specification (Current_Declaration)) = - N_Procedure_Specification - and then Is_Asynchronous (Subp_Def)); - - Append_To (Decls, Current_Stubs); - Analyze (Current_Stubs); - - -- Build RAS proxy - - Add_RAS_Proxy_And_Analyze (Decls, - Vis_Decl => Current_Declaration, - All_Calls_Remote_E => All_Calls_Remote_E, - Proxy_Object_Addr => Proxy_Object_Addr); - - -- Compute distribution identifier - - Assign_Subprogram_Identifier - (Subp_Def, - Current_Subprogram_Number, - Subp_Val); - - pragma Assert - (Current_Subprogram_Number = Get_Subprogram_Id (Subp_Def)); - - -- Add subprogram descriptor (RCI_Subp_Info) to the - -- subprograms table for this receiver. The aggregate - -- below must be kept consistent with the declaration - -- of type RCI_Subp_Info in System.Partition_Interface. - - Append_To (Subp_Info_List, - Make_Component_Association (Loc, - Choices => New_List ( - Make_Integer_Literal (Loc, - Current_Subprogram_Number)), - - Expression => - Make_Aggregate (Loc, - Component_Associations => New_List ( - Make_Component_Association (Loc, - Choices => New_List ( - Make_Identifier (Loc, Name_Addr)), - Expression => - New_Occurrence_Of ( - Proxy_Object_Addr, Loc)))))); - - Append_Stubs_To (Pkg_RPC_Receiver_Cases, - Stubs => Current_Stubs, - Subprogram_Number => Current_Subprogram_Number); - end; - - Current_Subprogram_Number := Current_Subprogram_Number + 1; - end if; - - Next (Current_Declaration); - end loop; - - -- If we receive an invalid Subprogram_Id, it is best to do nothing - -- rather than raising an exception since we do not want someone - -- to crash a remote partition by sending invalid subprogram ids. - -- This is consistent with the other parts of the case statement - -- since even in presence of incorrect parameters in the stream, - -- every exception will be caught and (if the subprogram is not an - -- APC) put into the result stream and sent away. - - Append_To (Pkg_RPC_Receiver_Cases, - Make_Case_Statement_Alternative (Loc, - Discrete_Choices => New_List (Make_Others_Choice (Loc)), - Statements => New_List (Make_Null_Statement (Loc)))); - - Append_To (Pkg_RPC_Receiver_Statements, - Make_Case_Statement (Loc, - Expression => New_Occurrence_Of (Subp_Id, Loc), - Alternatives => Pkg_RPC_Receiver_Cases)); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Subp_Info_Array, - Constant_Present => True, - Aliased_Present => True, - Object_Definition => - Make_Subtype_Indication (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc), - Constraint => - Make_Index_Or_Discriminant_Constraint (Loc, - New_List ( - Make_Range (Loc, - Low_Bound => Make_Integer_Literal (Loc, - First_RCI_Subprogram_Id), - High_Bound => - Make_Integer_Literal (Loc, - Intval => - First_RCI_Subprogram_Id - + List_Length (Subp_Info_List) - 1))))))); - - -- For a degenerate RCI with no visible subprograms, Subp_Info_List - -- has zero length, and the declaration is for an empty array, in - -- which case no initialization aggregate must be generated. - - if Present (First (Subp_Info_List)) then - Set_Expression (Last (Decls), - Make_Aggregate (Loc, - Component_Associations => Subp_Info_List)); - - -- No initialization provided: remove CONSTANT so that the - -- declaration is not an incomplete deferred constant. - - else - Set_Constant_Present (Last (Decls), False); - end if; - - Analyze (Last (Decls)); - - declare - Subp_Info_Addr : Node_Id; - -- Return statement for Lookup_RAS_Info: address of the subprogram - -- information record for the requested subprogram id. - - begin - if Present (First (Subp_Info_List)) then - Subp_Info_Addr := - Make_Selected_Component (Loc, - Prefix => - Make_Indexed_Component (Loc, - Prefix => New_Occurrence_Of (Subp_Info_Array, Loc), - Expressions => New_List ( - Convert_To (Standard_Integer, - Make_Identifier (Loc, Name_Subp_Id)))), - Selector_Name => Make_Identifier (Loc, Name_Addr)); - - -- Case of no visible subprogram: just raise Constraint_Error, we - -- know for sure we got junk from a remote partition. - - else - Subp_Info_Addr := - Make_Raise_Constraint_Error (Loc, - Reason => CE_Range_Check_Failed); - Set_Etype (Subp_Info_Addr, RTE (RE_Unsigned_64)); - end if; - - Append_To (Decls, - Make_Subprogram_Body (Loc, - Specification => - Copy_Specification (Loc, Parent (Lookup_RAS_Info)), - Declarations => No_List, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List ( - Make_Simple_Return_Statement (Loc, - Expression => - OK_Convert_To - (RTE (RE_Unsigned_64), Subp_Info_Addr)))))); - end; - - Analyze (Last (Decls)); - - Append_To (Decls, Pkg_RPC_Receiver_Body); - Analyze (Last (Decls)); - - Get_Library_Unit_Name_String (Pkg_Spec); - - -- Name - - Append_To (Register_Pkg_Actuals, - Make_String_Literal (Loc, - Strval => String_From_Name_Buffer)); - - -- Receiver - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Pkg_RPC_Receiver, Loc), - Attribute_Name => Name_Unrestricted_Access)); - - -- Version - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc), - Attribute_Name => Name_Version)); - - -- Subp_Info - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Subp_Info_Array, Loc), - Attribute_Name => Name_Address)); - - -- Subp_Info_Len - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Subp_Info_Array, Loc), - Attribute_Name => Name_Length)); - - -- Generate the call - - Append_To (Stmts, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc), - Parameter_Associations => Register_Pkg_Actuals)); - Analyze (Last (Stmts)); - end Add_Receiving_Stubs_To_Declarations; - - --------------------------------- - -- Build_General_Calling_Stubs -- - --------------------------------- - - procedure Build_General_Calling_Stubs - (Decls : List_Id; - Statements : List_Id; - Target_Partition : Entity_Id; - Target_RPC_Receiver : Node_Id; - Subprogram_Id : Node_Id; - Asynchronous : Node_Id := Empty; - Is_Known_Asynchronous : Boolean := False; - Is_Known_Non_Asynchronous : Boolean := False; - Is_Function : Boolean; - Spec : Node_Id; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Nod : Node_Id) - is - Loc : constant Source_Ptr := Sloc (Nod); - - Stream_Parameter : Node_Id; - -- Name of the stream used to transmit parameters to the - -- remote package. - - Result_Parameter : Node_Id; - -- Name of the result parameter (in non-APC cases) which get the - -- result of the remote subprogram. - - Exception_Return_Parameter : Node_Id; - -- Name of the parameter which will hold the exception sent by the - -- remote subprogram. - - Current_Parameter : Node_Id; - -- Current parameter being handled - - Ordered_Parameters_List : constant List_Id := - Build_Ordered_Parameters_List (Spec); - - Asynchronous_Statements : List_Id := No_List; - Non_Asynchronous_Statements : List_Id := No_List; - -- Statements specifics to the Asynchronous/Non-Asynchronous cases - - Extra_Formal_Statements : constant List_Id := New_List; - -- List of statements for extra formal parameters. It will appear - -- after the regular statements for writing out parameters. - - pragma Warnings (Off); - pragma Unreferenced (RACW_Type); - -- Used only for the PolyORB case - pragma Warnings (On); - - begin - -- The general form of a calling stub for a given subprogram is: - - -- procedure X (...) is P : constant Partition_ID := - -- RCI_Cache.Get_Active_Partition_ID; Stream, Result : aliased - -- System.RPC.Params_Stream_Type (0); begin - -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver - -- comes from RCI_Cache.Get_RCI_Package_Receiver) - -- Put_Subprogram_Id_In_Stream; Put_Parameters_In_Stream; Do_RPC - -- (Stream, Result); Read_Exception_Occurrence_From_Result; - -- Raise_It; - -- Read_Out_Parameters_And_Function_Return_From_Stream; end X; - - -- There are some variations: Do_APC is called for an asynchronous - -- procedure and the part after the call is completely ommitted as - -- well as the declaration of Result. For a function call, 'Input is - -- always used to read the result even if it is constrained. - - Stream_Parameter := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Stream_Parameter, - Aliased_Present => True, - Object_Definition => - Make_Subtype_Indication (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc), - Constraint => - Make_Index_Or_Discriminant_Constraint (Loc, - Constraints => - New_List (Make_Integer_Literal (Loc, 0)))))); - - if not Is_Known_Asynchronous then - Result_Parameter := - Make_Defining_Identifier (Loc, New_Internal_Name ('R')); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Result_Parameter, - Aliased_Present => True, - Object_Definition => - Make_Subtype_Indication (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc), - Constraint => - Make_Index_Or_Discriminant_Constraint (Loc, - Constraints => - New_List (Make_Integer_Literal (Loc, 0)))))); - - Exception_Return_Parameter := - Make_Defining_Identifier (Loc, New_Internal_Name ('E')); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Exception_Return_Parameter, - Object_Definition => - New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc))); - - else - Result_Parameter := Empty; - Exception_Return_Parameter := Empty; - end if; - - -- Put first the RPC receiver corresponding to the remote package - - Append_To (Statements, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access), - Target_RPC_Receiver))); - - -- Then put the Subprogram_Id of the subprogram we want to call in - -- the stream. - - Append_To (Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access), - Subprogram_Id))); - - Current_Parameter := First (Ordered_Parameters_List); - while Present (Current_Parameter) loop - declare - Typ : constant Node_Id := - Parameter_Type (Current_Parameter); - Etyp : Entity_Id; - Constrained : Boolean; - Value : Node_Id; - Extra_Parameter : Entity_Id; - - begin - if Is_RACW_Controlling_Formal - (Current_Parameter, Stub_Type) - then - -- In the case of a controlling formal argument, we marshall - -- its addr field rather than the local stub. - - Append_To (Statements, - Pack_Node_Into_Stream (Loc, - Stream => Stream_Parameter, - Object => - Make_Selected_Component (Loc, - Prefix => - Defining_Identifier (Current_Parameter), - Selector_Name => Name_Addr), - Etyp => RTE (RE_Unsigned_64))); - - else - Value := - New_Occurrence_Of - (Defining_Identifier (Current_Parameter), Loc); - - -- Access type parameters are transmitted as in out - -- parameters. However, a dereference is needed so that - -- we marshall the designated object. - - if Nkind (Typ) = N_Access_Definition then - Value := Make_Explicit_Dereference (Loc, Value); - Etyp := Etype (Subtype_Mark (Typ)); - else - Etyp := Etype (Typ); - end if; - - Constrained := not Transmit_As_Unconstrained (Etyp); - - -- Any parameter but unconstrained out parameters are - -- transmitted to the peer. - - if In_Present (Current_Parameter) - or else not Out_Present (Current_Parameter) - or else not Constrained - then - Append_To (Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => - Output_From_Constrained (Constrained), - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access), - Value))); - end if; - end if; - - -- If the current parameter has a dynamic constrained status, - -- then this status is transmitted as well. - -- This should be done for accessibility as well ??? - - if Nkind (Typ) /= N_Access_Definition - and then Need_Extra_Constrained (Current_Parameter) - then - -- In this block, we do not use the extra formal that has - -- been created because it does not exist at the time of - -- expansion when building calling stubs for remote access - -- to subprogram types. We create an extra variable of this - -- type and push it in the stream after the regular - -- parameters. - - Extra_Parameter := Make_Defining_Identifier - (Loc, New_Internal_Name ('P')); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Extra_Parameter, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (Standard_Boolean, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of ( - Defining_Identifier (Current_Parameter), Loc), - Attribute_Name => Name_Constrained))); - - Append_To (Extra_Formal_Statements, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Standard_Boolean, Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of - (Stream_Parameter, Loc), Attribute_Name => - Name_Access), - New_Occurrence_Of (Extra_Parameter, Loc)))); - end if; - - Next (Current_Parameter); - end; - end loop; - - -- Append the formal statements list to the statements - - Append_List_To (Statements, Extra_Formal_Statements); - - if not Is_Known_Non_Asynchronous then - - -- Build the call to System.RPC.Do_APC - - Asynchronous_Statements := New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Do_Apc), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Target_Partition, Loc), - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access)))); - else - Asynchronous_Statements := No_List; - end if; - - if not Is_Known_Asynchronous then - - -- Build the call to System.RPC.Do_RPC - - Non_Asynchronous_Statements := New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Do_Rpc), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Target_Partition, Loc), - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access), - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Result_Parameter, Loc), - Attribute_Name => Name_Access)))); - - -- Read the exception occurrence from the result stream and - -- reraise it. It does no harm if this is a Null_Occurrence since - -- this does nothing. - - Append_To (Non_Asynchronous_Statements, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc), - - Attribute_Name => Name_Read, - - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Result_Parameter, Loc), - Attribute_Name => Name_Access), - New_Occurrence_Of (Exception_Return_Parameter, Loc)))); - - Append_To (Non_Asynchronous_Statements, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Exception_Return_Parameter, Loc)))); - - if Is_Function then - - -- If this is a function call, then read the value and return - -- it. The return value is written/read using 'Output/'Input. - - Append_To (Non_Asynchronous_Statements, - Make_Tag_Check (Loc, - Make_Simple_Return_Statement (Loc, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of ( - Etype (Result_Definition (Spec)), Loc), - - Attribute_Name => Name_Input, - - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Result_Parameter, Loc), - Attribute_Name => Name_Access)))))); - - else - -- Loop around parameters and assign out (or in out) - -- parameters. In the case of RACW, controlling arguments - -- cannot possibly have changed since they are remote, so we do - -- not read them from the stream. - - Current_Parameter := First (Ordered_Parameters_List); - while Present (Current_Parameter) loop - declare - Typ : constant Node_Id := - Parameter_Type (Current_Parameter); - Etyp : Entity_Id; - Value : Node_Id; - - begin - Value := - New_Occurrence_Of - (Defining_Identifier (Current_Parameter), Loc); - - if Nkind (Typ) = N_Access_Definition then - Value := Make_Explicit_Dereference (Loc, Value); - Etyp := Etype (Subtype_Mark (Typ)); - else - Etyp := Etype (Typ); - end if; - - if (Out_Present (Current_Parameter) - or else Nkind (Typ) = N_Access_Definition) - and then Etyp /= Stub_Type - then - Append_To (Non_Asynchronous_Statements, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Etyp, Loc), - - Attribute_Name => Name_Read, - - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Result_Parameter, Loc), - Attribute_Name => Name_Access), - Value))); - end if; - end; - - Next (Current_Parameter); - end loop; - end if; - end if; - - if Is_Known_Asynchronous then - Append_List_To (Statements, Asynchronous_Statements); - - elsif Is_Known_Non_Asynchronous then - Append_List_To (Statements, Non_Asynchronous_Statements); - - else - pragma Assert (Present (Asynchronous)); - Prepend_To (Asynchronous_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Standard_Boolean, Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access), - New_Occurrence_Of (Standard_True, Loc)))); - - Prepend_To (Non_Asynchronous_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Standard_Boolean, Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Stream_Parameter, Loc), - Attribute_Name => Name_Access), - New_Occurrence_Of (Standard_False, Loc)))); - - Append_To (Statements, - Make_Implicit_If_Statement (Nod, - Condition => Asynchronous, - Then_Statements => Asynchronous_Statements, - Else_Statements => Non_Asynchronous_Statements)); - end if; - end Build_General_Calling_Stubs; - - ----------------------------- - -- Build_RPC_Receiver_Body -- - ----------------------------- - - procedure Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Request : out Entity_Id; - Subp_Id : out Entity_Id; - Subp_Index : out Entity_Id; - Stmts : out List_Id; - Decl : out Node_Id) - is - Loc : constant Source_Ptr := Sloc (RPC_Receiver); - - RPC_Receiver_Spec : Node_Id; - RPC_Receiver_Decls : List_Id; - - begin - Request := Make_Defining_Identifier (Loc, Name_R); - - RPC_Receiver_Spec := - Build_RPC_Receiver_Specification - (RPC_Receiver => RPC_Receiver, - Request_Parameter => Request); - - Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - Subp_Index := Subp_Id; - - -- Subp_Id may not be a constant, because in the case of the RPC - -- receiver for an RCI package, when a call is received from a RAS - -- dereference, it will be assigned during subsequent processing. - - RPC_Receiver_Decls := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Subp_Id, - Object_Definition => - New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc), - Attribute_Name => Name_Input, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request, - Selector_Name => Name_Params))))); - - Stmts := New_List; - - Decl := - Make_Subprogram_Body (Loc, - Specification => RPC_Receiver_Spec, - Declarations => RPC_Receiver_Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Stmts)); - end Build_RPC_Receiver_Body; - - ----------------------- - -- Build_Stub_Target -- - ----------------------- - - function Build_Stub_Target - (Loc : Source_Ptr; - Decls : List_Id; - RCI_Locator : Entity_Id; - Controlling_Parameter : Entity_Id) return RPC_Target - is - Target_Info : RPC_Target (PCS_Kind => Name_GARLIC_DSA); - begin - Target_Info.Partition := - Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - if Present (Controlling_Parameter) then - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Target_Info.Partition, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Partition_ID), Loc), - - Expression => - Make_Selected_Component (Loc, - Prefix => Controlling_Parameter, - Selector_Name => Name_Origin))); - - Target_Info.RPC_Receiver := - Make_Selected_Component (Loc, - Prefix => Controlling_Parameter, - Selector_Name => Name_Receiver); - - else - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Target_Info.Partition, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Partition_ID), Loc), - - Expression => - Make_Function_Call (Loc, - Name => Make_Selected_Component (Loc, - Prefix => - Make_Identifier (Loc, Chars (RCI_Locator)), - Selector_Name => - Make_Identifier (Loc, - Name_Get_Active_Partition_ID))))); - - Target_Info.RPC_Receiver := - Make_Selected_Component (Loc, - Prefix => - Make_Identifier (Loc, Chars (RCI_Locator)), - Selector_Name => - Make_Identifier (Loc, Name_Get_RCI_Package_Receiver)); - end if; - return Target_Info; - end Build_Stub_Target; - - --------------------- - -- Build_Stub_Type -- - --------------------- - - procedure Build_Stub_Type - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Decl : out Node_Id; - RPC_Receiver_Decl : out Node_Id) - is - Loc : constant Source_Ptr := Sloc (Stub_Type); - Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type); - - begin - Stub_Type_Decl := - Make_Full_Type_Declaration (Loc, - Defining_Identifier => Stub_Type, - Type_Definition => - Make_Record_Definition (Loc, - Tagged_Present => True, - Limited_Present => True, - Component_List => - Make_Component_List (Loc, - Component_Items => New_List ( - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Origin), - Component_Definition => - Make_Component_Definition (Loc, - Aliased_Present => False, - Subtype_Indication => - New_Occurrence_Of ( - RTE (RE_Partition_ID), Loc))), - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Receiver), - Component_Definition => - Make_Component_Definition (Loc, - Aliased_Present => False, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))), - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Addr), - Component_Definition => - Make_Component_Definition (Loc, - Aliased_Present => False, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))), - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Asynchronous), - Component_Definition => - Make_Component_Definition (Loc, - Aliased_Present => False, - Subtype_Indication => - New_Occurrence_Of ( - Standard_Boolean, Loc))))))); - - if Is_RAS then - RPC_Receiver_Decl := Empty; - else - declare - RPC_Receiver_Request : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_R); - begin - RPC_Receiver_Decl := - Make_Subprogram_Declaration (Loc, - Build_RPC_Receiver_Specification ( - RPC_Receiver => Make_Defining_Identifier (Loc, - New_Internal_Name ('R')), - Request_Parameter => RPC_Receiver_Request)); - end; - end if; - end Build_Stub_Type; - - -------------------------------------- - -- Build_Subprogram_Receiving_Stubs -- - -------------------------------------- - - function Build_Subprogram_Receiving_Stubs - (Vis_Decl : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Parent_Primitive : Entity_Id := Empty) return Node_Id - is - Loc : constant Source_Ptr := Sloc (Vis_Decl); - - Request_Parameter : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('R')); - -- Formal parameter for receiving stubs: a descriptor for an incoming - -- request. - - Decls : constant List_Id := New_List; - -- All the parameters will get declared before calling the real - -- subprograms. Also the out parameters will be declared. - - Statements : constant List_Id := New_List; - - Extra_Formal_Statements : constant List_Id := New_List; - -- Statements concerning extra formal parameters - - After_Statements : constant List_Id := New_List; - -- Statements to be executed after the subprogram call - - Inner_Decls : List_Id := No_List; - -- In case of a function, the inner declarations are needed since - -- the result may be unconstrained. - - Excep_Handlers : List_Id := No_List; - Excep_Choice : Entity_Id; - Excep_Code : List_Id; - - Parameter_List : constant List_Id := New_List; - -- List of parameters to be passed to the subprogram - - Current_Parameter : Node_Id; - - Ordered_Parameters_List : constant List_Id := - Build_Ordered_Parameters_List - (Specification (Vis_Decl)); - - Subp_Spec : Node_Id; - -- Subprogram specification - - Called_Subprogram : Node_Id; - -- The subprogram to call - - Null_Raise_Statement : Node_Id; - - Dynamic_Async : Entity_Id; - - begin - if Present (RACW_Type) then - Called_Subprogram := New_Occurrence_Of (Parent_Primitive, Loc); - else - Called_Subprogram := - New_Occurrence_Of - (Defining_Unit_Name (Specification (Vis_Decl)), Loc); - end if; - - if Dynamically_Asynchronous then - Dynamic_Async := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - else - Dynamic_Async := Empty; - end if; - - if not Asynchronous or Dynamically_Asynchronous then - - -- The first statement after the subprogram call is a statement to - -- write a Null_Occurrence into the result stream. - - Null_Raise_Statement := - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Result), - New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc))); - - if Dynamically_Asynchronous then - Null_Raise_Statement := - Make_Implicit_If_Statement (Vis_Decl, - Condition => - Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)), - Then_Statements => New_List (Null_Raise_Statement)); - end if; - - Append_To (After_Statements, Null_Raise_Statement); - end if; - - -- Loop through every parameter and get its value from the stream. If - -- the parameter is unconstrained, then the parameter is read using - -- 'Input at the point of declaration. - - Current_Parameter := First (Ordered_Parameters_List); - while Present (Current_Parameter) loop - declare - Etyp : Entity_Id; - Constrained : Boolean; - - Need_Extra_Constrained : Boolean; - -- True when an Extra_Constrained actual is required - - Object : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('P')); - - Expr : Node_Id := Empty; - - Is_Controlling_Formal : constant Boolean := - Is_RACW_Controlling_Formal - (Current_Parameter, Stub_Type); - - begin - if Is_Controlling_Formal then - - -- We have a controlling formal parameter. Read its address - -- rather than a real object. The address is in Unsigned_64 - -- form. - - Etyp := RTE (RE_Unsigned_64); - else - Etyp := Etype (Parameter_Type (Current_Parameter)); - end if; - - Constrained := not Transmit_As_Unconstrained (Etyp); - - if In_Present (Current_Parameter) - or else not Out_Present (Current_Parameter) - or else not Constrained - or else Is_Controlling_Formal - then - -- If an input parameter is constrained, then the read of - -- the parameter is deferred until the beginning of the - -- subprogram body. If it is unconstrained, then an - -- expression is built for the object declaration and the - -- variable is set using 'Input instead of 'Read. Note that - -- this deferral does not change the order in which the - -- actuals are read because Build_Ordered_Parameter_List - -- puts them unconstrained first. - - if Constrained then - Append_To (Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Name_Read, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Params), - New_Occurrence_Of (Object, Loc)))); - - else - - -- Build and append Input_With_Tag_Check function - - Append_To (Decls, - Input_With_Tag_Check (Loc, - Var_Type => Etyp, - Stream => - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Params))); - - -- Prepare function call expression - - Expr := - Make_Function_Call (Loc, - Name => - New_Occurrence_Of - (Defining_Unit_Name - (Specification (Last (Decls))), Loc)); - end if; - end if; - - Need_Extra_Constrained := - Nkind (Parameter_Type (Current_Parameter)) /= - N_Access_Definition - and then - Ekind (Defining_Identifier (Current_Parameter)) /= E_Void - and then - Present (Extra_Constrained - (Defining_Identifier (Current_Parameter))); - - -- We may not associate an extra constrained actual to a - -- constant object, so if one is needed, declare the actual - -- as a variable even if it won't be modified. - - Build_Actual_Object_Declaration - (Object => Object, - Etyp => Etyp, - Variable => Need_Extra_Constrained - or else Out_Present (Current_Parameter), - Expr => Expr, - Decls => Decls); - - -- An out parameter may be written back using a 'Write - -- attribute instead of a 'Output because it has been - -- constrained by the parameter given to the caller. Note that - -- out controlling arguments in the case of a RACW are not put - -- back in the stream because the pointer on them has not - -- changed. - - if Out_Present (Current_Parameter) - and then - Etype (Parameter_Type (Current_Parameter)) /= Stub_Type - then - Append_To (After_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Result), - New_Occurrence_Of (Object, Loc)))); - end if; - - -- For RACW controlling formals, the Etyp of Object is always - -- an RACW, even if the parameter is not of an anonymous access - -- type. In such case, we need to dereference it at call time. - - if Is_Controlling_Formal then - if Nkind (Parameter_Type (Current_Parameter)) /= - N_Access_Definition - then - Append_To (Parameter_List, - Make_Parameter_Association (Loc, - Selector_Name => - New_Occurrence_Of ( - Defining_Identifier (Current_Parameter), Loc), - Explicit_Actual_Parameter => - Make_Explicit_Dereference (Loc, - Unchecked_Convert_To (RACW_Type, - OK_Convert_To (RTE (RE_Address), - New_Occurrence_Of (Object, Loc)))))); - - else - Append_To (Parameter_List, - Make_Parameter_Association (Loc, - Selector_Name => - New_Occurrence_Of ( - Defining_Identifier (Current_Parameter), Loc), - Explicit_Actual_Parameter => - Unchecked_Convert_To (RACW_Type, - OK_Convert_To (RTE (RE_Address), - New_Occurrence_Of (Object, Loc))))); - end if; - - else - Append_To (Parameter_List, - Make_Parameter_Association (Loc, - Selector_Name => - New_Occurrence_Of ( - Defining_Identifier (Current_Parameter), Loc), - Explicit_Actual_Parameter => - New_Occurrence_Of (Object, Loc))); - end if; - - -- If the current parameter needs an extra formal, then read it - -- from the stream and set the corresponding semantic field in - -- the variable. If the kind of the parameter identifier is - -- E_Void, then this is a compiler generated parameter that - -- doesn't need an extra constrained status. - - -- The case of Extra_Accessibility should also be handled ??? - - if Need_Extra_Constrained then - declare - Extra_Parameter : constant Entity_Id := - Extra_Constrained - (Defining_Identifier - (Current_Parameter)); - - Formal_Entity : constant Entity_Id := - Make_Defining_Identifier - (Loc, Chars (Extra_Parameter)); - - Formal_Type : constant Entity_Id := - Etype (Extra_Parameter); - - begin - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Formal_Entity, - Object_Definition => - New_Occurrence_Of (Formal_Type, Loc))); - - Append_To (Extra_Formal_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of ( - Formal_Type, Loc), - Attribute_Name => Name_Read, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Params), - New_Occurrence_Of (Formal_Entity, Loc)))); - - -- Note: the call to Set_Extra_Constrained below relies - -- on the fact that Object's Ekind has been set by - -- Build_Actual_Object_Declaration. - - Set_Extra_Constrained (Object, Formal_Entity); - end; - end if; - end; - - Next (Current_Parameter); - end loop; - - -- Append the formal statements list at the end of regular statements - - Append_List_To (Statements, Extra_Formal_Statements); - - if Nkind (Specification (Vis_Decl)) = N_Function_Specification then - - -- The remote subprogram is a function. We build an inner block to - -- be able to hold a potentially unconstrained result in a - -- variable. - - declare - Etyp : constant Entity_Id := - Etype (Result_Definition (Specification (Vis_Decl))); - Result : constant Node_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('R')); - begin - Inner_Decls := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Result, - Constant_Present => True, - Object_Definition => New_Occurrence_Of (Etyp, Loc), - Expression => - Make_Function_Call (Loc, - Name => Called_Subprogram, - Parameter_Associations => Parameter_List))); - - if Is_Class_Wide_Type (Etyp) then - - -- For a remote call to a function with a class-wide type, - -- check that the returned value satisfies the requirements - -- of E.4(18). - - Append_To (Inner_Decls, - Make_Transportable_Check (Loc, - New_Occurrence_Of (Result, Loc))); - - end if; - - Append_To (After_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Name_Output, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Result), - New_Occurrence_Of (Result, Loc)))); - end; - - Append_To (Statements, - Make_Block_Statement (Loc, - Declarations => Inner_Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => After_Statements))); - - else - -- The remote subprogram is a procedure. We do not need any inner - -- block in this case. - - if Dynamically_Asynchronous then - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Dynamic_Async, - Object_Definition => - New_Occurrence_Of (Standard_Boolean, Loc))); - - Append_To (Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Standard_Boolean, Loc), - Attribute_Name => Name_Read, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Params), - New_Occurrence_Of (Dynamic_Async, Loc)))); - end if; - - Append_To (Statements, - Make_Procedure_Call_Statement (Loc, - Name => Called_Subprogram, - Parameter_Associations => Parameter_List)); - - Append_List_To (Statements, After_Statements); - end if; - - if Asynchronous and then not Dynamically_Asynchronous then - - -- For an asynchronous procedure, add a null exception handler - - Excep_Handlers := New_List ( - Make_Implicit_Exception_Handler (Loc, - Exception_Choices => New_List (Make_Others_Choice (Loc)), - Statements => New_List (Make_Null_Statement (Loc)))); - - else - -- In the other cases, if an exception is raised, then the - -- exception occurrence is copied into the output stream and - -- no other output parameter is written. - - Excep_Choice := - Make_Defining_Identifier (Loc, New_Internal_Name ('E')); - - Excep_Code := New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - Make_Selected_Component (Loc, - Prefix => Request_Parameter, - Selector_Name => Name_Result), - New_Occurrence_Of (Excep_Choice, Loc)))); - - if Dynamically_Asynchronous then - Excep_Code := New_List ( - Make_Implicit_If_Statement (Vis_Decl, - Condition => Make_Op_Not (Loc, - New_Occurrence_Of (Dynamic_Async, Loc)), - Then_Statements => Excep_Code)); - end if; - - Excep_Handlers := New_List ( - Make_Implicit_Exception_Handler (Loc, - Choice_Parameter => Excep_Choice, - Exception_Choices => New_List (Make_Others_Choice (Loc)), - Statements => Excep_Code)); - - end if; - - Subp_Spec := - Make_Procedure_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, New_Internal_Name ('F')), - - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Request_Parameter, - Parameter_Type => - New_Occurrence_Of (RTE (RE_Request_Access), Loc)))); - - return - Make_Subprogram_Body (Loc, - Specification => Subp_Spec, - Declarations => Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Statements, - Exception_Handlers => Excep_Handlers)); - end Build_Subprogram_Receiving_Stubs; - - ------------ - -- Result -- - ------------ - - function Result return Node_Id is - begin - return Make_Identifier (Loc, Name_V); - end Result; - - ---------------------- - -- Stream_Parameter -- - ---------------------- - - function Stream_Parameter return Node_Id is - begin - return Make_Identifier (Loc, Name_S); - end Stream_Parameter; - - end GARLIC_Support; - - ------------------------------- - -- Get_And_Reset_RACW_Bodies -- - ------------------------------- - - function Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id is - Desig : constant Entity_Id := Etype (Designated_Type (RACW_Type)); - Stub_Elements : Stub_Structure := Stubs_Table.Get (Desig); - - Body_Decls : List_Id; - -- Returned list of declarations - - begin - if Stub_Elements = Empty_Stub_Structure then - - -- Stub elements may be missing as a consequence of a previously - -- detected error. - - return No_List; - end if; - - Body_Decls := Stub_Elements.Body_Decls; - Stub_Elements.Body_Decls := No_List; - Stubs_Table.Set (Desig, Stub_Elements); - return Body_Decls; - end Get_And_Reset_RACW_Bodies; - - ----------------------- - -- Get_Stub_Elements -- - ----------------------- - - function Get_Stub_Elements (RACW_Type : Entity_Id) return Stub_Structure is - Desig : constant Entity_Id := - Etype (Designated_Type (RACW_Type)); - Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig); - begin - pragma Assert (Stub_Elements /= Empty_Stub_Structure); - return Stub_Elements; - end Get_Stub_Elements; - - ----------------------- - -- Get_Subprogram_Id -- - ----------------------- - - function Get_Subprogram_Id (Def : Entity_Id) return String_Id is - Result : constant String_Id := Get_Subprogram_Ids (Def).Str_Identifier; - begin - pragma Assert (Result /= No_String); - return Result; - end Get_Subprogram_Id; - - ----------------------- - -- Get_Subprogram_Id -- - ----------------------- - - function Get_Subprogram_Id (Def : Entity_Id) return Int is - begin - return Get_Subprogram_Ids (Def).Int_Identifier; - end Get_Subprogram_Id; - - ------------------------ - -- Get_Subprogram_Ids -- - ------------------------ - - function Get_Subprogram_Ids - (Def : Entity_Id) return Subprogram_Identifiers - is - begin - return Subprogram_Identifier_Table.Get (Def); - end Get_Subprogram_Ids; - - ---------- - -- Hash -- - ---------- - - function Hash (F : Entity_Id) return Hash_Index is - begin - return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1)); - end Hash; - - function Hash (F : Name_Id) return Hash_Index is - begin - return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1)); - end Hash; - - -------------------------- - -- Input_With_Tag_Check -- - -------------------------- - - function Input_With_Tag_Check - (Loc : Source_Ptr; - Var_Type : Entity_Id; - Stream : Node_Id) return Node_Id - is - begin - return - Make_Subprogram_Body (Loc, - Specification => Make_Function_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, New_Internal_Name ('S')), - Result_Definition => New_Occurrence_Of (Var_Type, Loc)), - Declarations => No_List, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, New_List ( - Make_Tag_Check (Loc, - Make_Simple_Return_Statement (Loc, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Var_Type, Loc), - Attribute_Name => Name_Input, - Expressions => - New_List (Stream))))))); - end Input_With_Tag_Check; - - -------------------------------- - -- Is_RACW_Controlling_Formal -- - -------------------------------- - - function Is_RACW_Controlling_Formal - (Parameter : Node_Id; - Stub_Type : Entity_Id) return Boolean - is - Typ : Entity_Id; - - begin - -- If the kind of the parameter is E_Void, then it is not a - -- controlling formal (this can happen in the context of RAS). - - if Ekind (Defining_Identifier (Parameter)) = E_Void then - return False; - end if; - - -- If the parameter is not a controlling formal, then it cannot - -- be possibly a RACW_Controlling_Formal. - - if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then - return False; - end if; - - Typ := Parameter_Type (Parameter); - return (Nkind (Typ) = N_Access_Definition - and then Etype (Subtype_Mark (Typ)) = Stub_Type) - or else Etype (Typ) = Stub_Type; - end Is_RACW_Controlling_Formal; - - ------------------------------ - -- Make_Transportable_Check -- - ------------------------------ - - function Make_Transportable_Check - (Loc : Source_Ptr; - Expr : Node_Id) return Node_Id is - begin - return - Make_Raise_Program_Error (Loc, - Condition => - Make_Op_Not (Loc, - Build_Get_Transportable (Loc, - Make_Selected_Component (Loc, - Prefix => Expr, - Selector_Name => Make_Identifier (Loc, Name_uTag)))), - Reason => PE_Non_Transportable_Actual); - end Make_Transportable_Check; - - ----------------------------- - -- Make_Selected_Component -- - ----------------------------- - - function Make_Selected_Component - (Loc : Source_Ptr; - Prefix : Entity_Id; - Selector_Name : Name_Id) return Node_Id - is - begin - return Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Prefix, Loc), - Selector_Name => Make_Identifier (Loc, Selector_Name)); - end Make_Selected_Component; - - -------------------- - -- Make_Tag_Check -- - -------------------- - - function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is - Occ : constant Entity_Id := - Make_Defining_Identifier (Loc, New_Internal_Name ('E')); - - begin - return Make_Block_Statement (Loc, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List (N), - - Exception_Handlers => New_List ( - Make_Implicit_Exception_Handler (Loc, - Choice_Parameter => Occ, - - Exception_Choices => - New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)), - - Statements => - New_List (Make_Procedure_Call_Statement (Loc, - New_Occurrence_Of - (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc), - New_List (New_Occurrence_Of (Occ, Loc)))))))); - end Make_Tag_Check; - - ---------------------------- - -- Need_Extra_Constrained -- - ---------------------------- - - function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is - Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter)); - begin - return Out_Present (Parameter) - and then Has_Discriminants (Etyp) - and then not Is_Constrained (Etyp) - and then not Is_Indefinite_Subtype (Etyp); - end Need_Extra_Constrained; - - ------------------------------------ - -- Pack_Entity_Into_Stream_Access -- - ------------------------------------ - - function Pack_Entity_Into_Stream_Access - (Loc : Source_Ptr; - Stream : Node_Id; - Object : Entity_Id; - Etyp : Entity_Id := Empty) return Node_Id - is - Typ : Entity_Id; - - begin - if Present (Etyp) then - Typ := Etyp; - else - Typ := Etype (Object); - end if; - - return - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream, - Object => New_Occurrence_Of (Object, Loc), - Etyp => Typ); - end Pack_Entity_Into_Stream_Access; - - --------------------------- - -- Pack_Node_Into_Stream -- - --------------------------- - - function Pack_Node_Into_Stream - (Loc : Source_Ptr; - Stream : Entity_Id; - Object : Node_Id; - Etyp : Entity_Id) return Node_Id - is - Write_Attribute : Name_Id := Name_Write; - - begin - if not Is_Constrained (Etyp) then - Write_Attribute := Name_Output; - end if; - - return - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Write_Attribute, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Stream, Loc), - Attribute_Name => Name_Access), - Object)); - end Pack_Node_Into_Stream; - - ---------------------------------- - -- Pack_Node_Into_Stream_Access -- - ---------------------------------- - - function Pack_Node_Into_Stream_Access - (Loc : Source_Ptr; - Stream : Node_Id; - Object : Node_Id; - Etyp : Entity_Id) return Node_Id - is - Write_Attribute : Name_Id := Name_Write; - - begin - if not Is_Constrained (Etyp) then - Write_Attribute := Name_Output; - end if; - - return - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Write_Attribute, - Expressions => New_List ( - Stream, - Object)); - end Pack_Node_Into_Stream_Access; - - --------------------- - -- PolyORB_Support -- - --------------------- - - package body PolyORB_Support is - - -- Local subprograms - - procedure Add_RACW_Read_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - Body_Decls : List_Id); - -- Add Read attribute for the RACW type. The declaration and attribute - -- definition clauses are inserted right after the declaration of - -- RACW_Type. If Body_Decls is not No_List, the subprogram body is - -- appended to it (case where the RACW declaration is in the main unit). - - procedure Add_RACW_Write_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - Body_Decls : List_Id); - -- Same as above for the Write attribute - - procedure Add_RACW_From_Any - (RACW_Type : Entity_Id; - Body_Decls : List_Id); - -- Add the From_Any TSS for this RACW type - - procedure Add_RACW_To_Any - (RACW_Type : Entity_Id; - Body_Decls : List_Id); - -- Add the To_Any TSS for this RACW type - - procedure Add_RACW_TypeCode - (Designated_Type : Entity_Id; - RACW_Type : Entity_Id; - Body_Decls : List_Id); - -- Add the TypeCode TSS for this RACW type - - procedure Add_RAS_From_Any (RAS_Type : Entity_Id); - -- Add the From_Any TSS for this RAS type - - procedure Add_RAS_To_Any (RAS_Type : Entity_Id); - -- Add the To_Any TSS for this RAS type - - procedure Add_RAS_TypeCode (RAS_Type : Entity_Id); - -- Add the TypeCode TSS for this RAS type - - procedure Add_RAS_Access_TSS (N : Node_Id); - -- Add a subprogram body for RAS Access TSS - - ------------------------------------- - -- Add_Obj_RPC_Receiver_Completion -- - ------------------------------------- - - procedure Add_Obj_RPC_Receiver_Completion - (Loc : Source_Ptr; - Decls : List_Id; - RPC_Receiver : Entity_Id; - Stub_Elements : Stub_Structure) - is - Desig : constant Entity_Id := - Etype (Designated_Type (Stub_Elements.RACW_Type)); - begin - Append_To (Decls, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Register_Obj_Receiving_Stub), Loc), - - Parameter_Associations => New_List ( - - -- Name - - Make_String_Literal (Loc, - Full_Qualified_Name (Desig)), - - -- Handler - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of ( - Defining_Unit_Name (Parent (RPC_Receiver)), Loc), - Attribute_Name => - Name_Access), - - -- Receiver - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of ( - Defining_Identifier ( - Stub_Elements.RPC_Receiver_Decl), Loc), - Attribute_Name => - Name_Access)))); - end Add_Obj_RPC_Receiver_Completion; - - ----------------------- - -- Add_RACW_Features -- - ----------------------- - - procedure Add_RACW_Features - (RACW_Type : Entity_Id; - Desig : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver_Decl : Node_Id; - Body_Decls : List_Id) - is - pragma Warnings (Off); - pragma Unreferenced (RPC_Receiver_Decl); - pragma Warnings (On); - - begin - Add_RACW_From_Any - (RACW_Type => RACW_Type, - Body_Decls => Body_Decls); - - Add_RACW_To_Any - (RACW_Type => RACW_Type, - Body_Decls => Body_Decls); - - Add_RACW_Write_Attribute - (RACW_Type => RACW_Type, - Stub_Type => Stub_Type, - Stub_Type_Access => Stub_Type_Access, - Body_Decls => Body_Decls); - - Add_RACW_Read_Attribute - (RACW_Type => RACW_Type, - Stub_Type => Stub_Type, - Stub_Type_Access => Stub_Type_Access, - Body_Decls => Body_Decls); - - Add_RACW_TypeCode - (Designated_Type => Desig, - RACW_Type => RACW_Type, - Body_Decls => Body_Decls); - end Add_RACW_Features; - - ----------------------- - -- Add_RACW_From_Any -- - ----------------------- - - procedure Add_RACW_From_Any - (RACW_Type : Entity_Id; - Body_Decls : List_Id) - is - Loc : constant Source_Ptr := Sloc (RACW_Type); - Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type); - - Fnam : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_External_Name (Chars (RACW_Type), 'F')); - - Func_Spec : Node_Id; - Func_Decl : Node_Id; - Func_Body : Node_Id; - - Statements : List_Id; - -- Various parts of the subprogram - - Any_Parameter : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_A); - - Asynchronous_Flag : constant Entity_Id := - Asynchronous_Flags_Table.Get (RACW_Type); - -- The flag object declared in Add_RACW_Asynchronous_Flag - - begin - Func_Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => - Fnam, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => - Any_Parameter, - Parameter_Type => - New_Occurrence_Of (RTE (RE_Any), Loc))), - Result_Definition => New_Occurrence_Of (RACW_Type, Loc)); - - -- NOTE: The usage occurrences of RACW_Parameter must refer to the - -- entity in the declaration spec, not those of the body spec. - - Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec); - Insert_After (Declaration_Node (RACW_Type), Func_Decl); - Set_Renaming_TSS (RACW_Type, Fnam, TSS_From_Any); - - if No (Body_Decls) then - return; - end if; - - -- ??? Issue with asynchronous calls here: the Asynchronous flag is - -- set on the stub type if, and only if, the RACW type has a pragma - -- Asynchronous. This is incorrect for RACWs that implement RAS - -- types, because in that case the /designated subprogram/ (not the - -- type) might be asynchronous, and that causes the stub to need to - -- be asynchronous too. A solution is to transport a RAS as a struct - -- containing a RACW and an asynchronous flag, and to properly alter - -- the Asynchronous component in the stub type in the RAS's _From_Any - -- TSS. - - Statements := New_List ( - Make_Simple_Return_Statement (Loc, - Expression => Unchecked_Convert_To (RACW_Type, - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_RACW), Loc), - Parameter_Associations => New_List ( - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Any_Parameter, Loc))), - Build_Stub_Tag (Loc, RACW_Type), - New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc), - New_Occurrence_Of (Asynchronous_Flag, Loc)))))); - - Func_Body := - Make_Subprogram_Body (Loc, - Specification => Copy_Specification (Loc, Func_Spec), - Declarations => No_List, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Statements)); - - Append_To (Body_Decls, Func_Body); - end Add_RACW_From_Any; - - ----------------------------- - -- Add_RACW_Read_Attribute -- - ----------------------------- - - procedure Add_RACW_Read_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - Body_Decls : List_Id) - is - pragma Warnings (Off); - pragma Unreferenced (Stub_Type, Stub_Type_Access); - pragma Warnings (On); - Loc : constant Source_Ptr := Sloc (RACW_Type); - - Proc_Decl : Node_Id; - Attr_Decl : Node_Id; - - Body_Node : Node_Id; - - Decls : constant List_Id := New_List; - Statements : constant List_Id := New_List; - Reference : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_R); - -- Various parts of the procedure - - Pnam : constant Entity_Id := Make_Defining_Identifier (Loc, - New_Internal_Name ('R')); - - Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type); - - Asynchronous_Flag : constant Entity_Id := - Asynchronous_Flags_Table.Get (RACW_Type); - pragma Assert (Present (Asynchronous_Flag)); - - function Stream_Parameter return Node_Id; - function Result return Node_Id; - - -- Functions to create occurrences of the formal parameter names - - ------------ - -- Result -- - ------------ - - function Result return Node_Id is - begin - return Make_Identifier (Loc, Name_V); - end Result; - - ---------------------- - -- Stream_Parameter -- - ---------------------- - - function Stream_Parameter return Node_Id is - begin - return Make_Identifier (Loc, Name_S); - end Stream_Parameter; - - -- Start of processing for Add_RACW_Read_Attribute - - begin - Build_Stream_Procedure - (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => True); - - Proc_Decl := Make_Subprogram_Declaration (Loc, - Copy_Specification (Loc, Specification (Body_Node))); - - Attr_Decl := - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (RACW_Type, Loc), - Chars => Name_Read, - Expression => - New_Occurrence_Of ( - Defining_Unit_Name (Specification (Proc_Decl)), Loc)); - - Insert_After (Declaration_Node (RACW_Type), Proc_Decl); - Insert_After (Proc_Decl, Attr_Decl); - - if No (Body_Decls) then - return; - end if; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => - Reference, - Object_Definition => - New_Occurrence_Of (RTE (RE_Object_Ref), Loc))); - - Append_List_To (Statements, New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Object_Ref), Loc), - Attribute_Name => Name_Read, - Expressions => New_List ( - Stream_Parameter, - New_Occurrence_Of (Reference, Loc))), - - Make_Assignment_Statement (Loc, - Name => - Result, - Expression => - Unchecked_Convert_To (RACW_Type, - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Get_RACW), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Reference, Loc), - Build_Stub_Tag (Loc, RACW_Type), - New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc), - New_Occurrence_Of (Asynchronous_Flag, Loc))))))); - - Set_Declarations (Body_Node, Decls); - Append_To (Body_Decls, Body_Node); - end Add_RACW_Read_Attribute; - - --------------------- - -- Add_RACW_To_Any -- - --------------------- - - procedure Add_RACW_To_Any - (RACW_Type : Entity_Id; - Body_Decls : List_Id) - is - Loc : constant Source_Ptr := Sloc (RACW_Type); - - Fnam : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_External_Name (Chars (RACW_Type), 'T')); - - Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type); - - Stub_Elements : constant Stub_Structure := - Get_Stub_Elements (RACW_Type); - - Func_Spec : Node_Id; - Func_Decl : Node_Id; - Func_Body : Node_Id; - - Decls : List_Id; - Statements : List_Id; - -- Various parts of the subprogram - - RACW_Parameter : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_R); - - Reference : constant Entity_Id := - Make_Defining_Identifier - (Loc, New_Internal_Name ('R')); - Any : constant Entity_Id := - Make_Defining_Identifier - (Loc, New_Internal_Name ('A')); - - begin - Func_Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => - Fnam, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => - RACW_Parameter, - Parameter_Type => - New_Occurrence_Of (RACW_Type, Loc))), - Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc)); - - -- NOTE: The usage occurrences of RACW_Parameter must refer to the - -- entity in the declaration spec, not in the body spec. - - Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec); - - Insert_After (Declaration_Node (RACW_Type), Func_Decl); - Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any); - - if No (Body_Decls) then - return; - end if; - - -- Generate: - - -- R : constant Object_Ref := - -- Get_Reference - -- (Address!(RACW), - -- "typ", - -- Stub_Type'Tag, - -- Is_RAS, - -- RPC_Receiver'Access); - -- A : Any; - - Decls := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Reference, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Object_Ref), Loc), - Expression => - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc), - Parameter_Associations => New_List ( - Unchecked_Convert_To (RTE (RE_Address), - New_Occurrence_Of (RACW_Parameter, Loc)), - Make_String_Literal (Loc, - Strval => Full_Qualified_Name - (Etype (Designated_Type (RACW_Type)))), - Build_Stub_Tag (Loc, RACW_Type), - New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc), - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of - (Defining_Identifier - (Stub_Elements.RPC_Receiver_Decl), Loc), - Attribute_Name => Name_Access)))), - - Make_Object_Declaration (Loc, - Defining_Identifier => Any, - Object_Definition => New_Occurrence_Of (RTE (RE_Any), Loc))); - - -- Generate: - - -- Any := TA_ObjRef (Reference); - -- Set_TC (Any, RPC_Receiver.Obj_TypeCode); - -- return Any; - - Statements := New_List ( - Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (Any, Loc), - Expression => - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Reference, Loc)))), - - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Any, Loc), - Make_Selected_Component (Loc, - Prefix => - Defining_Identifier ( - Stub_Elements.RPC_Receiver_Decl), - Selector_Name => Name_Obj_TypeCode))), - - Make_Simple_Return_Statement (Loc, - Expression => New_Occurrence_Of (Any, Loc))); - - Func_Body := - Make_Subprogram_Body (Loc, - Specification => Copy_Specification (Loc, Func_Spec), - Declarations => Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Statements)); - Append_To (Body_Decls, Func_Body); - end Add_RACW_To_Any; - - ----------------------- - -- Add_RACW_TypeCode -- - ----------------------- - - procedure Add_RACW_TypeCode - (Designated_Type : Entity_Id; - RACW_Type : Entity_Id; - Body_Decls : List_Id) - is - Loc : constant Source_Ptr := Sloc (RACW_Type); - - Fnam : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_External_Name (Chars (RACW_Type), 'Y')); - - Stub_Elements : constant Stub_Structure := - Stubs_Table.Get (Designated_Type); - pragma Assert (Stub_Elements /= Empty_Stub_Structure); - - Func_Spec : Node_Id; - Func_Decl : Node_Id; - Func_Body : Node_Id; - - begin - - -- The spec for this subprogram has a dummy 'access RACW' argument, - -- which serves only for overloading purposes. - - Func_Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => Fnam, - Result_Definition => New_Occurrence_Of (RTE (RE_TypeCode), Loc)); - - -- NOTE: The usage occurrences of RACW_Parameter must refer to the - -- entity in the declaration spec, not those of the body spec. - - Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec); - Insert_After (Declaration_Node (RACW_Type), Func_Decl); - Set_Renaming_TSS (RACW_Type, Fnam, TSS_TypeCode); - - if No (Body_Decls) then - return; - end if; - - Func_Body := - Make_Subprogram_Body (Loc, - Specification => Copy_Specification (Loc, Func_Spec), - Declarations => Empty_List, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List ( - Make_Simple_Return_Statement (Loc, - Expression => - Make_Selected_Component (Loc, - Prefix => - Defining_Identifier - (Stub_Elements.RPC_Receiver_Decl), - Selector_Name => Name_Obj_TypeCode))))); - - Append_To (Body_Decls, Func_Body); - end Add_RACW_TypeCode; - - ------------------------------ - -- Add_RACW_Write_Attribute -- - ------------------------------ - - procedure Add_RACW_Write_Attribute - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - Body_Decls : List_Id) - is - pragma Warnings (Off); - pragma Unreferenced (Stub_Type, Stub_Type_Access); - pragma Warnings (On); - - Loc : constant Source_Ptr := Sloc (RACW_Type); - - Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type); - - Stub_Elements : constant Stub_Structure := - Get_Stub_Elements (RACW_Type); - - Body_Node : Node_Id; - Proc_Decl : Node_Id; - Attr_Decl : Node_Id; - - Statements : constant List_Id := New_List; - Pnam : constant Entity_Id := - Make_Defining_Identifier (Loc, New_Internal_Name ('R')); - - function Stream_Parameter return Node_Id; - function Object return Node_Id; - -- Functions to create occurrences of the formal parameter names - - ------------ - -- Object -- - ------------ - - function Object return Node_Id is - begin - return Make_Identifier (Loc, Name_V); - end Object; - - ---------------------- - -- Stream_Parameter -- - ---------------------- - - function Stream_Parameter return Node_Id is - begin - return Make_Identifier (Loc, Name_S); - end Stream_Parameter; - - -- Start of processing for Add_RACW_Write_Attribute - - begin - Build_Stream_Procedure - (Loc, RACW_Type, Body_Node, Pnam, Statements, Outp => False); - - Proc_Decl := - Make_Subprogram_Declaration (Loc, - Copy_Specification (Loc, Specification (Body_Node))); - - Attr_Decl := - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (RACW_Type, Loc), - Chars => Name_Write, - Expression => - New_Occurrence_Of ( - Defining_Unit_Name (Specification (Proc_Decl)), Loc)); - - Insert_After (Declaration_Node (RACW_Type), Proc_Decl); - Insert_After (Proc_Decl, Attr_Decl); - - if No (Body_Decls) then - return; - end if; - - Append_To (Statements, - Pack_Node_Into_Stream_Access (Loc, - Stream => Stream_Parameter, - Object => - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc), - Parameter_Associations => New_List ( - Unchecked_Convert_To (RTE (RE_Address), Object), - Make_String_Literal (Loc, - Strval => Full_Qualified_Name - (Etype (Designated_Type (RACW_Type)))), - Build_Stub_Tag (Loc, RACW_Type), - New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc), - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of - (Defining_Identifier - (Stub_Elements.RPC_Receiver_Decl), Loc), - Attribute_Name => Name_Access))), - - Etyp => RTE (RE_Object_Ref))); - - Append_To (Body_Decls, Body_Node); - end Add_RACW_Write_Attribute; - - ----------------------- - -- Add_RAST_Features -- - ----------------------- - - procedure Add_RAST_Features - (Vis_Decl : Node_Id; - RAS_Type : Entity_Id) - is - begin - Add_RAS_Access_TSS (Vis_Decl); - - Add_RAS_From_Any (RAS_Type); - Add_RAS_TypeCode (RAS_Type); - - -- To_Any uses TypeCode, and therefore needs to be generated last - - Add_RAS_To_Any (RAS_Type); - end Add_RAST_Features; - - ------------------------ - -- Add_RAS_Access_TSS -- - ------------------------ - - procedure Add_RAS_Access_TSS (N : Node_Id) is - Loc : constant Source_Ptr := Sloc (N); - - Ras_Type : constant Entity_Id := Defining_Identifier (N); - Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type); - -- Ras_Type is the access to subprogram type; Fat_Type is the - -- corresponding record type. - - RACW_Type : constant Entity_Id := - Underlying_RACW_Type (Ras_Type); - - Stub_Elements : constant Stub_Structure := - Get_Stub_Elements (RACW_Type); - - Proc : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access)); - - Proc_Spec : Node_Id; - - -- Formal parameters - - Package_Name : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_P); - - -- Target package - - Subp_Id : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_S); - - -- Target subprogram - - Asynch_P : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_Asynchronous); - -- Is the procedure to which the 'Access applies asynchronous? - - All_Calls_Remote : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Name_All_Calls_Remote); - -- True if an All_Calls_Remote pragma applies to the RCI unit - -- that contains the subprogram. - - -- Common local variables - - Proc_Decls : List_Id; - Proc_Statements : List_Id; - - Subp_Ref : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_R); - -- Reference that designates the target subprogram (returned - -- by Get_RAS_Info). - - Is_Local : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_L); - Local_Addr : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_A); - -- For the call to Get_Local_Address - - -- Additional local variables for the remote case - - Local_Stub : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('L')); - - Stub_Ptr : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('S')); - - function Set_Field - (Field_Name : Name_Id; - Value : Node_Id) return Node_Id; - -- Construct an assignment that sets the named component in the - -- returned record - - --------------- - -- Set_Field -- - --------------- - - function Set_Field - (Field_Name : Name_Id; - Value : Node_Id) return Node_Id - is - begin - return - Make_Assignment_Statement (Loc, - Name => - Make_Selected_Component (Loc, - Prefix => Stub_Ptr, - Selector_Name => Field_Name), - Expression => Value); - end Set_Field; - - -- Start of processing for Add_RAS_Access_TSS - - begin - Proc_Decls := New_List ( - - -- Common declarations - - Make_Object_Declaration (Loc, - Defining_Identifier => Subp_Ref, - Object_Definition => - New_Occurrence_Of (RTE (RE_Object_Ref), Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Is_Local, - Object_Definition => - New_Occurrence_Of (Standard_Boolean, Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Local_Addr, - Object_Definition => - New_Occurrence_Of (RTE (RE_Address), Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Local_Stub, - Aliased_Present => True, - Object_Definition => - New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)), - - Make_Object_Declaration (Loc, - Defining_Identifier => Stub_Ptr, - Object_Definition => - New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Local_Stub, Loc), - Attribute_Name => Name_Unchecked_Access))); - - Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access); - -- Build_Get_Unique_RP_Call needs this information - - -- Get_RAS_Info (Pkg, Subp, R); - -- Obtain a reference to the target subprogram - - Proc_Statements := New_List ( - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Package_Name, Loc), - New_Occurrence_Of (Subp_Id, Loc), - New_Occurrence_Of (Subp_Ref, Loc))), - - -- Get_Local_Address (R, L, A); - -- Determine whether the subprogram is local (L), and if so - -- obtain the local address of its proxy (A). - - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Subp_Ref, Loc), - New_Occurrence_Of (Is_Local, Loc), - New_Occurrence_Of (Local_Addr, Loc)))); - - -- Note: Here we assume that the Fat_Type is a record containing just - -- an access to a proxy or stub object. - - Append_To (Proc_Statements, - - -- if L then - - Make_Implicit_If_Statement (N, - Condition => New_Occurrence_Of (Is_Local, Loc), - - Then_Statements => New_List ( - - -- if A.Target = null then - - Make_Implicit_If_Statement (N, - Condition => - Make_Op_Eq (Loc, - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To - (RTE (RE_RAS_Proxy_Type_Access), - New_Occurrence_Of (Local_Addr, Loc)), - Selector_Name => Make_Identifier (Loc, Name_Target)), - Make_Null (Loc)), - - Then_Statements => New_List ( - - -- A.Target := Entity_Of (Ref); - - Make_Assignment_Statement (Loc, - Name => - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To - (RTE (RE_RAS_Proxy_Type_Access), - New_Occurrence_Of (Local_Addr, Loc)), - Selector_Name => Make_Identifier (Loc, Name_Target)), - Expression => - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Subp_Ref, Loc)))), - - -- Inc_Usage (A.Target); - - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc), - Parameter_Associations => New_List ( - Make_Selected_Component (Loc, - Prefix => - Unchecked_Convert_To - (RTE (RE_RAS_Proxy_Type_Access), - New_Occurrence_Of (Local_Addr, Loc)), - Selector_Name => - Make_Identifier (Loc, Name_Target)))))), - - -- end if; - -- if not All_Calls_Remote then - -- return Fat_Type!(A); - -- end if; - - Make_Implicit_If_Statement (N, - Condition => - Make_Op_Not (Loc, - Right_Opnd => - New_Occurrence_Of (All_Calls_Remote, Loc)), - - Then_Statements => New_List ( - Make_Simple_Return_Statement (Loc, - Expression => - Unchecked_Convert_To - (Fat_Type, New_Occurrence_Of (Local_Addr, Loc)))))))); - - Append_List_To (Proc_Statements, New_List ( - - -- Stub.Target := Entity_Of (Ref); - - Set_Field (Name_Target, - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Subp_Ref, Loc)))), - - -- Inc_Usage (Stub.Target); - - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc), - Parameter_Associations => New_List ( - Make_Selected_Component (Loc, - Prefix => Stub_Ptr, - Selector_Name => Name_Target))), - - -- E.4.1(9) A remote call is asynchronous if it is a call to - -- a procedure, or a call through a value of an access-to-procedure - -- type, to which a pragma Asynchronous applies. - - -- Parameter Asynch_P is true when the procedure is asynchronous; - -- Expression Asynch_T is true when the type is asynchronous. - - Set_Field (Name_Asynchronous, - Make_Or_Else (Loc, - Left_Opnd => New_Occurrence_Of (Asynch_P, Loc), - Right_Opnd => - New_Occurrence_Of - (Boolean_Literals (Is_Asynchronous (Ras_Type)), Loc))))); - - Append_List_To (Proc_Statements, - Build_Get_Unique_RP_Call (Loc, Stub_Ptr, Stub_Elements.Stub_Type)); - - Append_To (Proc_Statements, - Make_Simple_Return_Statement (Loc, - Expression => - Unchecked_Convert_To (Fat_Type, - New_Occurrence_Of (Stub_Ptr, Loc)))); - - Proc_Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => Proc, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Package_Name, - Parameter_Type => - New_Occurrence_Of (Standard_String, Loc)), - - Make_Parameter_Specification (Loc, - Defining_Identifier => Subp_Id, - Parameter_Type => - New_Occurrence_Of (Standard_String, Loc)), - - Make_Parameter_Specification (Loc, - Defining_Identifier => Asynch_P, - Parameter_Type => - New_Occurrence_Of (Standard_Boolean, Loc)), - - Make_Parameter_Specification (Loc, - Defining_Identifier => All_Calls_Remote, - Parameter_Type => - New_Occurrence_Of (Standard_Boolean, Loc))), - - Result_Definition => - New_Occurrence_Of (Fat_Type, Loc)); - - -- Set the kind and return type of the function to prevent - -- ambiguities between Ras_Type and Fat_Type in subsequent analysis. - - Set_Ekind (Proc, E_Function); - Set_Etype (Proc, Fat_Type); - - Discard_Node ( - Make_Subprogram_Body (Loc, - Specification => Proc_Spec, - Declarations => Proc_Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Proc_Statements))); - - Set_TSS (Fat_Type, Proc); - end Add_RAS_Access_TSS; - - ---------------------- - -- Add_RAS_From_Any -- - ---------------------- - - procedure Add_RAS_From_Any (RAS_Type : Entity_Id) is - Loc : constant Source_Ptr := Sloc (RAS_Type); - - Fnam : constant Entity_Id := Make_Defining_Identifier (Loc, - Make_TSS_Name (RAS_Type, TSS_From_Any)); - - Func_Spec : Node_Id; - - Statements : List_Id; - - Any_Parameter : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_A); - - begin - Statements := New_List ( - Make_Simple_Return_Statement (Loc, - Expression => - Make_Aggregate (Loc, - Component_Associations => New_List ( - Make_Component_Association (Loc, - Choices => New_List ( - Make_Identifier (Loc, Name_Ras)), - Expression => - PolyORB_Support.Helpers.Build_From_Any_Call ( - Underlying_RACW_Type (RAS_Type), - New_Occurrence_Of (Any_Parameter, Loc), - No_List)))))); - - Func_Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => Fnam, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Any_Parameter, - Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))), - Result_Definition => New_Occurrence_Of (RAS_Type, Loc)); - - Discard_Node ( - Make_Subprogram_Body (Loc, - Specification => Func_Spec, - Declarations => No_List, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Statements))); - Set_TSS (RAS_Type, Fnam); - end Add_RAS_From_Any; - - -------------------- - -- 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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('A')); - RAS_Parameter : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('R')); - RACW_Parameter : constant Node_Id := - Make_Selected_Component (Loc, - Prefix => RAS_Parameter, - Selector_Name => Name_Ras); - - 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 - (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_TC_Build), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (RTE (RE_TC_Object), Loc), - Make_Aggregate (Loc, - Expressions => - New_List ( - Make_Function_Call (Loc, - Name => - New_Occurrence_Of - (RTE (RE_TA_String), Loc), - Parameter_Associations => New_List ( - Make_String_Literal (Loc, Name_String))), - Make_Function_Call (Loc, - Name => - New_Occurrence_Of - (RTE (RE_TA_String), Loc), - Parameter_Associations => New_List ( - Make_String_Literal (Loc, - Strval => Repo_Id_String)))))))))))); - Set_TSS (RAS_Type, Fnam); - end Add_RAS_TypeCode; - - ----------------------------------------- - -- Add_Receiving_Stubs_To_Declarations -- - ----------------------------------------- - - procedure Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id; - Stmts : List_Id) - is - Loc : constant Source_Ptr := Sloc (Pkg_Spec); - - Pkg_RPC_Receiver : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('H')); - Pkg_RPC_Receiver_Object : Node_Id; - Pkg_RPC_Receiver_Body : Node_Id; - Pkg_RPC_Receiver_Decls : List_Id; - Pkg_RPC_Receiver_Statements : List_Id; - - Pkg_RPC_Receiver_Cases : constant List_Id := New_List; - -- A Pkg_RPC_Receiver is built to decode the request - - Request : Node_Id; - -- Request object received from neutral layer - - Subp_Id : Entity_Id; - -- Subprogram identifier as received from the neutral - -- distribution core. - - Subp_Index : Entity_Id; - -- Internal index as determined by matching either the method name - -- from the request structure, or the local subprogram address (in - -- case of a RAS). - - Is_Local : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('L')); - - Local_Address : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('A')); - -- Address of a local subprogram designated by a reference - -- corresponding to a RAS. - - Dispatch_On_Address : constant List_Id := New_List; - Dispatch_On_Name : constant List_Id := New_List; - - Current_Declaration : Node_Id; - Current_Stubs : Node_Id; - Current_Subprogram_Number : Int := First_RCI_Subprogram_Id; - - Subp_Info_Array : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('I')); - - Subp_Info_List : constant List_Id := New_List; - - Register_Pkg_Actuals : constant List_Id := New_List; - - All_Calls_Remote_E : Entity_Id; - - procedure Append_Stubs_To - (RPC_Receiver_Cases : List_Id; - Declaration : Node_Id; - Stubs : Node_Id; - Subp_Number : Int; - Subp_Dist_Name : Entity_Id; - Subp_Proxy_Addr : Entity_Id); - -- Add one case to the specified RPC receiver case list associating - -- Subprogram_Number with the subprogram declared by Declaration, for - -- which we have receiving stubs in Stubs. Subp_Number is an internal - -- subprogram index. Subp_Dist_Name is the string used to call the - -- subprogram by name, and Subp_Dist_Addr is the address of the proxy - -- object, used in the context of calls through remote - -- access-to-subprogram types. - - --------------------- - -- Append_Stubs_To -- - --------------------- - - procedure Append_Stubs_To - (RPC_Receiver_Cases : List_Id; - Declaration : Node_Id; - Stubs : Node_Id; - Subp_Number : Int; - Subp_Dist_Name : Entity_Id; - Subp_Proxy_Addr : Entity_Id) - is - Case_Stmts : List_Id; - begin - Case_Stmts := New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - Defining_Entity (Stubs), Loc), - Parameter_Associations => - New_List (New_Occurrence_Of (Request, Loc)))); - - if Nkind (Specification (Declaration)) = N_Function_Specification - or else not - Is_Asynchronous (Defining_Entity (Specification (Declaration))) - then - Append_To (Case_Stmts, Make_Simple_Return_Statement (Loc)); - end if; - - Append_To (RPC_Receiver_Cases, - Make_Case_Statement_Alternative (Loc, - Discrete_Choices => - New_List (Make_Integer_Literal (Loc, Subp_Number)), - Statements => Case_Stmts)); - - Append_To (Dispatch_On_Name, - Make_Elsif_Part (Loc, - Condition => - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Caseless_String_Eq), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Subp_Id, Loc), - New_Occurrence_Of (Subp_Dist_Name, Loc))), - - Then_Statements => New_List ( - Make_Assignment_Statement (Loc, - New_Occurrence_Of (Subp_Index, Loc), - Make_Integer_Literal (Loc, Subp_Number))))); - - Append_To (Dispatch_On_Address, - Make_Elsif_Part (Loc, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => New_Occurrence_Of (Local_Address, Loc), - Right_Opnd => New_Occurrence_Of (Subp_Proxy_Addr, Loc)), - - Then_Statements => New_List ( - Make_Assignment_Statement (Loc, - New_Occurrence_Of (Subp_Index, Loc), - Make_Integer_Literal (Loc, Subp_Number))))); - end Append_Stubs_To; - - -- Start of processing for Add_Receiving_Stubs_To_Declarations - - begin - -- Building receiving stubs consist in several operations: - - -- - a package RPC receiver must be built. This subprogram - -- will get a Subprogram_Id from the incoming stream - -- and will dispatch the call to the right subprogram; - - -- - a receiving stub for each subprogram visible in the package - -- spec. This stub will read all the parameters from the stream, - -- and put the result as well as the exception occurrence in the - -- output stream; - - -- - a dummy package with an empty spec and a body made of an - -- elaboration part, whose job is to register the receiving - -- part of this RCI package on the name server. This is done - -- by calling System.Partition_Interface.Register_Receiving_Stub. - - Build_RPC_Receiver_Body ( - RPC_Receiver => Pkg_RPC_Receiver, - Request => Request, - Subp_Id => Subp_Id, - Subp_Index => Subp_Index, - Stmts => Pkg_RPC_Receiver_Statements, - Decl => Pkg_RPC_Receiver_Body); - Pkg_RPC_Receiver_Decls := Declarations (Pkg_RPC_Receiver_Body); - - -- Extract local address information from the target reference: - -- if non-null, that means that this is a reference that denotes - -- one particular operation, and hence that the operation name - -- must not be taken into account for dispatching. - - Append_To (Pkg_RPC_Receiver_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Is_Local, - Object_Definition => - New_Occurrence_Of (Standard_Boolean, Loc))); - - Append_To (Pkg_RPC_Receiver_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Local_Address, - Object_Definition => - New_Occurrence_Of (RTE (RE_Address), Loc))); - - Append_To (Pkg_RPC_Receiver_Statements, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc), - Parameter_Associations => New_List ( - Make_Selected_Component (Loc, - Prefix => Request, - Selector_Name => Name_Target), - New_Occurrence_Of (Is_Local, Loc), - New_Occurrence_Of (Local_Address, Loc)))); - - -- For each subprogram, the receiving stub will be built and a - -- case statement will be made on the Subprogram_Id to dispatch - -- to the right subprogram. - - All_Calls_Remote_E := Boolean_Literals ( - Has_All_Calls_Remote (Defining_Entity (Pkg_Spec))); - - Overload_Counter_Table.Reset; - Reserve_NamingContext_Methods; - - Current_Declaration := First (Visible_Declarations (Pkg_Spec)); - while Present (Current_Declaration) loop - if Nkind (Current_Declaration) = N_Subprogram_Declaration - and then Comes_From_Source (Current_Declaration) - then - declare - Loc : constant Source_Ptr := Sloc (Current_Declaration); - -- While specifically processing Current_Declaration, use - -- its Sloc as the location of all generated nodes. - - Subp_Def : constant Entity_Id := - Defining_Unit_Name - (Specification (Current_Declaration)); - - Subp_Val : String_Id; - - Subp_Dist_Name : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => - New_External_Name - (Related_Id => Chars (Subp_Def), - Suffix => 'D', - Suffix_Index => -1)); - - Proxy_Object_Addr : Entity_Id; - - begin - -- Build receiving stub - - Current_Stubs := - Build_Subprogram_Receiving_Stubs - (Vis_Decl => Current_Declaration, - Asynchronous => - Nkind (Specification (Current_Declaration)) = - N_Procedure_Specification - and then Is_Asynchronous (Subp_Def)); - - Append_To (Decls, Current_Stubs); - Analyze (Current_Stubs); - - -- Build RAS proxy - - Add_RAS_Proxy_And_Analyze (Decls, - Vis_Decl => Current_Declaration, - All_Calls_Remote_E => All_Calls_Remote_E, - Proxy_Object_Addr => Proxy_Object_Addr); - - -- Compute distribution identifier - - Assign_Subprogram_Identifier - (Subp_Def, - Current_Subprogram_Number, - Subp_Val); - - pragma Assert - (Current_Subprogram_Number = Get_Subprogram_Id (Subp_Def)); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Subp_Dist_Name, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (Standard_String, Loc), - Expression => - Make_String_Literal (Loc, Subp_Val))); - Analyze (Last (Decls)); - - -- Add subprogram descriptor (RCI_Subp_Info) to the - -- subprograms table for this receiver. The aggregate - -- below must be kept consistent with the declaration - -- of type RCI_Subp_Info in System.Partition_Interface. - - Append_To (Subp_Info_List, - Make_Component_Association (Loc, - Choices => New_List ( - Make_Integer_Literal (Loc, Current_Subprogram_Number)), - - Expression => - Make_Aggregate (Loc, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Subp_Dist_Name, Loc), - Attribute_Name => Name_Address), - - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Subp_Dist_Name, Loc), - Attribute_Name => Name_Length), - - New_Occurrence_Of (Proxy_Object_Addr, Loc))))); - - Append_Stubs_To (Pkg_RPC_Receiver_Cases, - Declaration => Current_Declaration, - Stubs => Current_Stubs, - Subp_Number => Current_Subprogram_Number, - Subp_Dist_Name => Subp_Dist_Name, - Subp_Proxy_Addr => Proxy_Object_Addr); - end; - - Current_Subprogram_Number := Current_Subprogram_Number + 1; - end if; - - Next (Current_Declaration); - end loop; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Subp_Info_Array, - Constant_Present => True, - Aliased_Present => True, - Object_Definition => - Make_Subtype_Indication (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc), - Constraint => - Make_Index_Or_Discriminant_Constraint (Loc, - New_List ( - Make_Range (Loc, - Low_Bound => - Make_Integer_Literal (Loc, - Intval => First_RCI_Subprogram_Id), - High_Bound => - Make_Integer_Literal (Loc, - Intval => - First_RCI_Subprogram_Id - + List_Length (Subp_Info_List) - 1))))))); - - if Present (First (Subp_Info_List)) then - Set_Expression (Last (Decls), - Make_Aggregate (Loc, - Component_Associations => Subp_Info_List)); - - -- Generate the dispatch statement to determine the subprogram id - -- of the called subprogram. - - -- We first test whether the reference that was used to make the - -- call was the base RCI reference (in which case Local_Address is - -- zero, and the method identifier from the request must be used - -- to determine which subprogram is called) or a reference - -- identifying one particular subprogram (in which case - -- Local_Address is the address of that subprogram, and the - -- method name from the request is ignored). The latter occurs - -- for the case of a call through a remote access-to-subprogram. - - -- In each case, cascaded elsifs are used to determine the proper - -- subprogram index. Using hash tables might be more efficient. - - Append_To (Pkg_RPC_Receiver_Statements, - Make_Implicit_If_Statement (Pkg_Spec, - Condition => - Make_Op_Ne (Loc, - Left_Opnd => New_Occurrence_Of (Local_Address, Loc), - Right_Opnd => New_Occurrence_Of - (RTE (RE_Null_Address), Loc)), - - Then_Statements => New_List ( - Make_Implicit_If_Statement (Pkg_Spec, - Condition => New_Occurrence_Of (Standard_False, Loc), - Then_Statements => New_List ( - Make_Null_Statement (Loc)), - Elsif_Parts => Dispatch_On_Address)), - - Else_Statements => New_List ( - Make_Implicit_If_Statement (Pkg_Spec, - Condition => New_Occurrence_Of (Standard_False, Loc), - Then_Statements => New_List (Make_Null_Statement (Loc)), - Elsif_Parts => Dispatch_On_Name)))); - - else - -- For a degenerate RCI with no visible subprograms, - -- Subp_Info_List has zero length, and the declaration is for an - -- empty array, in which case no initialization aggregate must be - -- generated. We do not generate a Dispatch_Statement either. - - -- No initialization provided: remove CONSTANT so that the - -- declaration is not an incomplete deferred constant. - - Set_Constant_Present (Last (Decls), False); - end if; - - -- Analyze Subp_Info_Array declaration - - Analyze (Last (Decls)); - - -- If we receive an invalid Subprogram_Id, it is best to do nothing - -- rather than raising an exception since we do not want someone - -- to crash a remote partition by sending invalid subprogram ids. - -- This is consistent with the other parts of the case statement - -- since even in presence of incorrect parameters in the stream, - -- every exception will be caught and (if the subprogram is not an - -- APC) put into the result stream and sent away. - - Append_To (Pkg_RPC_Receiver_Cases, - Make_Case_Statement_Alternative (Loc, - Discrete_Choices => New_List (Make_Others_Choice (Loc)), - Statements => New_List (Make_Null_Statement (Loc)))); - - Append_To (Pkg_RPC_Receiver_Statements, - Make_Case_Statement (Loc, - Expression => New_Occurrence_Of (Subp_Index, Loc), - Alternatives => Pkg_RPC_Receiver_Cases)); - - -- Pkg_RPC_Receiver body is now complete: insert it into the tree and - -- analyze it. - - Append_To (Decls, Pkg_RPC_Receiver_Body); - Analyze (Last (Decls)); - - Pkg_RPC_Receiver_Object := - Make_Object_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, New_Internal_Name ('R')), - Aliased_Present => True, - Object_Definition => New_Occurrence_Of (RTE (RE_Servant), Loc)); - Append_To (Decls, Pkg_RPC_Receiver_Object); - Analyze (Last (Decls)); - - Get_Library_Unit_Name_String (Pkg_Spec); - - -- Name - - Append_To (Register_Pkg_Actuals, - Make_String_Literal (Loc, - Strval => String_From_Name_Buffer)); - - -- Version - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of - (Defining_Entity (Pkg_Spec), Loc), - Attribute_Name => Name_Version)); - - -- Handler - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Pkg_RPC_Receiver, Loc), - Attribute_Name => Name_Access)); - - -- Receiver - - Append_To (Register_Pkg_Actuals, - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of ( - 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)); - - -- ??? - - 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); - - Arguments : Node_Id; - -- Name of the named values list used to transmit parameters - -- to the remote package - - Request : Node_Id; - -- The request object constructed by these stubs - - Result : Node_Id; - -- Name of the result named value (in non-APC cases) which get the - -- result of the remote subprogram. - - Result_TC : Node_Id; - -- Typecode expression for the result of the request (void - -- typecode for procedures). - - Exception_Return_Parameter : Node_Id; - -- Name of the parameter which will hold the exception sent by the - -- remote subprogram. - - Current_Parameter : Node_Id; - -- Current parameter being handled - - Ordered_Parameters_List : constant List_Id := - Build_Ordered_Parameters_List (Spec); - - Asynchronous_P : Node_Id; - -- A Boolean expression indicating whether this call is asynchronous - - Asynchronous_Statements : List_Id := No_List; - Non_Asynchronous_Statements : List_Id := No_List; - -- Statements specifics to the Asynchronous/Non-Asynchronous cases - - Extra_Formal_Statements : constant List_Id := New_List; - -- List of statements for extra formal parameters. It will appear - -- after the regular statements for writing out parameters. - - After_Statements : constant List_Id := New_List; - -- Statements to be executed after call returns (to assign - -- in out or out parameter values). - - Etyp : Entity_Id; - -- The type of the formal parameter being processed - - Is_Controlling_Formal : Boolean; - Is_First_Controlling_Formal : Boolean; - First_Controlling_Formal_Seen : Boolean := False; - -- Controlling formal parameters of distributed object primitives - -- require special handling, and the first such parameter needs even - -- more special handling. - - begin - -- ??? document general form of stub subprograms for the PolyORB case - Request := Make_Defining_Identifier (Loc, New_Internal_Name ('R')); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Request, - Aliased_Present => False, - Object_Definition => - New_Occurrence_Of (RTE (RE_Request_Access), Loc))); - - Result := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('R')); - - if Is_Function then - Result_TC := - PolyORB_Support.Helpers.Build_TypeCode_Call - (Loc, Etype (Result_Definition (Spec)), Decls); - else - Result_TC := New_Occurrence_Of (RTE (RE_TC_Void), Loc); - end if; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Result, - Aliased_Present => False, - Object_Definition => - New_Occurrence_Of (RTE (RE_NamedValue), Loc), - Expression => - Make_Aggregate (Loc, - Component_Associations => New_List ( - Make_Component_Association (Loc, - Choices => New_List (Make_Identifier (Loc, Name_Name)), - Expression => - New_Occurrence_Of (RTE (RE_Result_Name), Loc)), - Make_Component_Association (Loc, - Choices => New_List ( - Make_Identifier (Loc, Name_Argument)), - Expression => - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc), - Parameter_Associations => New_List (Result_TC))), - Make_Component_Association (Loc, - Choices => New_List ( - Make_Identifier (Loc, Name_Arg_Modes)), - Expression => Make_Integer_Literal (Loc, 0)))))); - - if not Is_Known_Asynchronous then - Exception_Return_Parameter := - Make_Defining_Identifier (Loc, New_Internal_Name ('E')); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Exception_Return_Parameter, - Object_Definition => - New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc))); - - else - Exception_Return_Parameter := Empty; - end if; - - -- Initialize and fill in arguments list - - Arguments := - Make_Defining_Identifier (Loc, New_Internal_Name ('A')); - Declare_Create_NVList (Loc, Arguments, Decls, Statements); - - Current_Parameter := First (Ordered_Parameters_List); - while Present (Current_Parameter) loop - if Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) then - Is_Controlling_Formal := True; - Is_First_Controlling_Formal := - not First_Controlling_Formal_Seen; - First_Controlling_Formal_Seen := True; - - else - Is_Controlling_Formal := False; - Is_First_Controlling_Formal := False; - end if; - - if Is_Controlling_Formal then - - -- For a controlling formal argument, we send its reference - - Etyp := RACW_Type; - - else - Etyp := Etype (Parameter_Type (Current_Parameter)); - end if; - - -- The first controlling formal parameter is treated specially: - -- it is used to set the target object of the call. - - if not Is_First_Controlling_Formal then - declare - Constrained : constant Boolean := - Is_Constrained (Etyp) - or else Is_Elementary_Type (Etyp); - - Any : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('A')); - - Actual_Parameter : Node_Id := - New_Occurrence_Of ( - Defining_Identifier ( - Current_Parameter), Loc); - - Expr : Node_Id; - - begin - if Is_Controlling_Formal then - - -- For a controlling formal parameter (other than the - -- first one), use the corresponding RACW. If the - -- parameter is not an anonymous access parameter, that - -- involves taking its 'Unrestricted_Access. - - if Nkind (Parameter_Type (Current_Parameter)) - = N_Access_Definition - then - Actual_Parameter := OK_Convert_To - (Etyp, Actual_Parameter); - else - Actual_Parameter := OK_Convert_To (Etyp, - Make_Attribute_Reference (Loc, - Prefix => Actual_Parameter, - Attribute_Name => Name_Unrestricted_Access)); - end if; - - end if; - - if In_Present (Current_Parameter) - or else not Out_Present (Current_Parameter) - or else not Constrained - or else Is_Controlling_Formal - then - -- The parameter has an input value, is constrained at - -- runtime by an input value, or is a controlling formal - -- parameter (always passed as a reference) other than - -- the first one. - - Expr := PolyORB_Support.Helpers.Build_To_Any_Call - (Actual_Parameter, Decls); - - else - Expr := Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc), - Parameter_Associations => New_List ( - PolyORB_Support.Helpers.Build_TypeCode_Call - (Loc, Etyp, Decls))); - end if; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Any, - Aliased_Present => False, - Object_Definition => - New_Occurrence_Of (RTE (RE_Any), Loc), - Expression => Expr)); - - Append_To (Statements, - Add_Parameter_To_NVList (Loc, - Parameter => Current_Parameter, - NVList => Arguments, - Constrained => Constrained, - Any => Any)); - - if Out_Present (Current_Parameter) - and then not Is_Controlling_Formal - then - Append_To (After_Statements, - Make_Assignment_Statement (Loc, - Name => - New_Occurrence_Of ( - Defining_Identifier (Current_Parameter), Loc), - Expression => - PolyORB_Support.Helpers.Build_From_Any_Call - (Etype (Parameter_Type (Current_Parameter)), - New_Occurrence_Of (Any, Loc), - Decls))); - - end if; - end; - end if; - - -- If the current parameter has a dynamic constrained status, then - -- this status is transmitted as well. - -- This should be done for accessibility as well ??? - - if Nkind (Parameter_Type (Current_Parameter)) /= - N_Access_Definition - and then Need_Extra_Constrained (Current_Parameter) - then - -- In this block, we do not use the extra formal that has been - -- created because it does not exist at the time of expansion - -- when building calling stubs for remote access to subprogram - -- types. We create an extra variable of this type and push it - -- in the stream after the regular parameters. - - declare - Extra_Any_Parameter : constant Entity_Id := - Make_Defining_Identifier - (Loc, New_Internal_Name ('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 - (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_Create), Loc), - - Parameter_Associations => New_List ( - Target_Object, - Subprogram_Id, - New_Occurrence_Of (Arguments, Loc), - New_Occurrence_Of (Result, Loc), - New_Occurrence_Of (RTE (RE_Nil_Exc_List), Loc)))); - - Append_To (Parameter_Associations (Last (Statements)), - New_Occurrence_Of (Request, 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_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Request_Invoke), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Request, Loc)))); - - Non_Asynchronous_Statements := New_List (Make_Null_Statement (Loc)); - Asynchronous_Statements := New_List (Make_Null_Statement (Loc)); - - if not Is_Known_Asynchronous then - - -- Reraise an exception occurrence from the completed request. - -- If the exception occurrence is empty, this is a no-op. - - Append_To (Non_Asynchronous_Statements, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Request_Raise_Occurrence), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Request, Loc)))); - - if Is_Function then - - -- If this is a function call, read the value and return it - - Append_To (Non_Asynchronous_Statements, - Make_Tag_Check (Loc, - Make_Simple_Return_Statement (Loc, - PolyORB_Support.Helpers.Build_From_Any_Call - (Etype (Result_Definition (Spec)), - Make_Selected_Component (Loc, - Prefix => Result, - Selector_Name => Name_Argument), - Decls)))); - end if; - end if; - - Append_List_To (Non_Asynchronous_Statements, After_Statements); - - 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_Defining_Identifier (Loc, - New_Internal_Name ('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_Stub_Type -- - --------------------- - - procedure Build_Stub_Type - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Decl : out Node_Id; - RPC_Receiver_Decl : out Node_Id) - is - Loc : constant Source_Ptr := Sloc (Stub_Type); - pragma Warnings (Off); - pragma Unreferenced (RACW_Type); - pragma Warnings (On); - - begin - Stub_Type_Decl := - Make_Full_Type_Declaration (Loc, - Defining_Identifier => Stub_Type, - Type_Definition => - Make_Record_Definition (Loc, - Tagged_Present => True, - Limited_Present => True, - Component_List => - Make_Component_List (Loc, - Component_Items => New_List ( - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Target), - Component_Definition => - Make_Component_Definition (Loc, - Aliased_Present => False, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Entity_Ptr), Loc))), - - Make_Component_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_Asynchronous), - - Component_Definition => - Make_Component_Definition (Loc, - Aliased_Present => False, - Subtype_Indication => - New_Occurrence_Of (Standard_Boolean, Loc))))))); - - RPC_Receiver_Decl := - Make_Object_Declaration (Loc, - Defining_Identifier => Make_Defining_Identifier (Loc, - New_Internal_Name ('R')), - Aliased_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Servant), Loc)); - end Build_Stub_Type; - - ----------------------------- - -- Build_RPC_Receiver_Body -- - ----------------------------- - - procedure Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Request : out Entity_Id; - Subp_Id : out Entity_Id; - Subp_Index : out Entity_Id; - Stmts : out List_Id; - Decl : out Node_Id) - is - Loc : constant Source_Ptr := Sloc (RPC_Receiver); - - 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_Defining_Identifier (Loc, - New_Internal_Name ('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_Defining_Identifier (Loc, - New_Internal_Name ('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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('A')); - - Is_Local : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('L')); - - begin - -- Special case: obtain the first controlling formal - -- from the target of the remote call, instead of the - -- argument list. - - Append_To (Outer_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Addr, - Object_Definition => - New_Occurrence_Of (RTE (RE_Address), Loc))); - - Append_To (Outer_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Is_Local, - Object_Definition => - New_Occurrence_Of (Standard_Boolean, Loc))); - - Append_To (Outer_Statements, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc), - Parameter_Associations => New_List ( - Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of ( - Request_Parameter, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Target)), - New_Occurrence_Of (Is_Local, Loc), - New_Occurrence_Of (Addr, Loc)))); - - Expr := Unchecked_Convert_To (RACW_Type, - New_Occurrence_Of (Addr, Loc)); - end; - - elsif In_Present (Current_Parameter) - or else not Out_Present (Current_Parameter) - or else not Constrained - then - -- If an input parameter is constrained, then its reading is - -- deferred until the beginning of the subprogram body. If - -- it is unconstrained, then an expression is built for - -- the object declaration and the variable is set using - -- 'Input instead of 'Read. - - Expr := PolyORB_Support.Helpers.Build_From_Any_Call ( - Etyp, New_Occurrence_Of (Any, Loc), Decls); - - if Constrained then - Append_To (Statements, - Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (Object, Loc), - Expression => Expr)); - Expr := Empty; - else - null; - - -- Expr will be used to initialize (and constrain) the - -- parameter when it is declared. - 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 - (New_Occurrence_Of (Object, Loc), Decls)))); - 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 => - 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)); - - Extra_Any : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('A')); - - Formal_Entity : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Chars (Extra_Parameter)); - - Formal_Type : constant Entity_Id := - Etype (Extra_Parameter); - - begin - Append_To (Outer_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Extra_Any, - Object_Definition => - New_Occurrence_Of (RTE (RE_Any), Loc), - Expression => - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Create_Any), Loc), - Parameter_Associations => New_List ( - PolyORB_Support.Helpers.Build_TypeCode_Call - (Loc, Formal_Type, Outer_Decls))))); - - Append_To (Outer_Extra_Formal_Statements, - Add_Parameter_To_NVList (Loc, - Parameter => Extra_Parameter, - NVList => Arguments, - Constrained => True, - Any => Extra_Any)); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Formal_Entity, - Object_Definition => - New_Occurrence_Of (Formal_Type, Loc))); - - Append_To (Statements, - Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (Formal_Entity, Loc), - Expression => - PolyORB_Support.Helpers.Build_From_Any_Call - (Formal_Type, - New_Occurrence_Of (Extra_Any, Loc), - Decls))); - Set_Extra_Constrained (Object, Formal_Entity); - end; - end if; - end; - - 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_Defining_Identifier (Loc, - Chars => New_Internal_Name ('R')); - - begin - Inner_Decls := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Result, - Constant_Present => True, - Object_Definition => New_Occurrence_Of (Etyp, Loc), - Expression => - Make_Function_Call (Loc, - Name => Called_Subprogram, - Parameter_Associations => Parameter_List))); - - if Is_Class_Wide_Type (Etyp) then - - -- For a remote call to a function with a class-wide type, - -- check that the returned value satisfies the requirements - -- of (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 - (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_Defining_Identifier (Loc, New_Internal_Name ('F')), - - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Request_Parameter, - Parameter_Type => - New_Occurrence_Of (RTE (RE_Request_Access), Loc)))); - - -- 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 floating - -- point type from Standard, or the smallest unsigned (modular) type - -- from System.Unsigned_Types, whose range encompasses that of Typ. - - function Make_Helper_Function_Name - (Loc : Source_Ptr; - Typ : Entity_Id; - Nam : Name_Id) return Entity_Id; - -- Return the name to be assigned for helper subprogram Nam of Typ - - ------------------------------------------------------------ - -- Common subprograms for building various tree fragments -- - ------------------------------------------------------------ - - function Build_Get_Aggregate_Element - (Loc : Source_Ptr; - Any : Entity_Id; - TC : Node_Id; - Idx : Node_Id) return Node_Id; - -- Build a call to Get_Aggregate_Element on Any for typecode TC, - -- returning the Idx'th element. - - generic - Subprogram : Entity_Id; - -- Reference location for constructed nodes - - Arry : Entity_Id; - -- For 'Range and Etype - - Indices : List_Id; - -- For the construction of the innermost element expression - - with procedure Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : Entity_Id; - Datum : Node_Id); - - procedure Append_Array_Traversal - (Stmts : List_Id; - Any : Entity_Id; - Counter : Entity_Id := Empty; - Depth : Pos := 1); - -- Build nested loop statements that iterate over the elements of an - -- array Arry. The statement(s) built by Add_Process_Element are - -- executed for each element; Indices is the list of indices to be - -- used in the construction of the indexed component that denotes the - -- current element. Subprogram is the entity for the subprogram for - -- which this iterator is generated. The generated statements are - -- appended to Stmts. - - generic - Rec : Entity_Id; - -- The record entity being dealt with - - with procedure Add_Process_Element - (Stmts : List_Id; - Container : Node_Or_Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id); - -- Rec is the instance of the record type, or Empty. - -- Field is either the N_Defining_Identifier for a component, - -- or an N_Variant_Part. - - procedure Append_Record_Traversal - (Stmts : List_Id; - Clist : Node_Id; - Container : Node_Or_Entity_Id; - Counter : in out Int); - -- Process component list Clist. Individual fields are passed - -- to Field_Processing. Each variant part is also processed. - -- Container is the outer Any (for From_Any/To_Any), - -- the outer typecode (for TC) to which the operation applies. - - ----------------------------- - -- Append_Record_Traversal -- - ----------------------------- - - procedure Append_Record_Traversal - (Stmts : List_Id; - Clist : Node_Id; - Container : Node_Or_Entity_Id; - Counter : in out Int) - is - CI : List_Id; - VP : Node_Id; - -- Clist's Component_Items and Variant_Part - - Item : Node_Id; - Def : Entity_Id; - - 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; - - ------------------------- - -- 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 := Empty; - Lib_RE : RE_Id := RE_Null; - Result : Node_Id; - - begin - -- First simple case where the From_Any function is present - -- in the type's TSS. - - Fnam := Find_Inherited_TSS (U_Type, TSS_From_Any); - - if Sloc (U_Type) <= Standard_Location then - U_Type := Base_Type (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 = Etype (Standard_Short_Short_Integer) then - Lib_RE := RE_FA_SSI; - - elsif U_Type = Etype (Standard_Short_Integer) then - Lib_RE := RE_FA_SI; - - elsif U_Type = Etype (Standard_Integer) then - Lib_RE := RE_FA_I; - - elsif U_Type = Etype (Standard_Long_Integer) then - Lib_RE := RE_FA_LI; - - elsif U_Type = Etype (Standard_Long_Long_Integer) then - Lib_RE := RE_FA_LLI; - - -- Unsigned integer types - - elsif U_Type = RTE (RE_Short_Short_Unsigned) then - Lib_RE := RE_FA_SSU; - - elsif U_Type = RTE (RE_Short_Unsigned) then - Lib_RE := RE_FA_SU; - - elsif U_Type = RTE (RE_Unsigned) then - Lib_RE := RE_FA_U; - - elsif U_Type = RTE (RE_Long_Unsigned) then - Lib_RE := RE_FA_LU; - - elsif U_Type = RTE (RE_Long_Long_Unsigned) then - Lib_RE := RE_FA_LLU; - - elsif U_Type = Standard_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_Defining_Identifier (Loc, - New_Internal_Name ('A')); - - Use_Opaque_Representation : Boolean; - - begin - if Is_Itype (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 following 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 => - OK_Convert_To (Typ, - 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 : Int := 0; - - -- The returned object - - Res : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('R')); - - Res_Definition : Node_Id := New_Occurrence_Of (Typ, Loc); - - procedure FA_Rec_Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id); - - procedure FA_Append_Record_Traversal is - new Append_Record_Traversal - (Rec => Res, - Add_Process_Element => FA_Rec_Add_Process_Element); - - -------------------------------- - -- FA_Rec_Add_Process_Element -- - -------------------------------- - - procedure FA_Rec_Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id) - is - begin - if Nkind (Field) = N_Defining_Identifier then - - -- A regular component - - Append_To (Stmts, - Make_Assignment_Statement (Loc, - Name => Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Rec, Loc), - Selector_Name => - New_Occurrence_Of (Field, Loc)), - Expression => - Build_From_Any_Call (Etype (Field), - Build_Get_Aggregate_Element (Loc, - Any => Any, - TC => Build_TypeCode_Call (Loc, - Etype (Field), Decls), - Idx => Make_Integer_Literal (Loc, - Counter)), - Decls))); - - else - -- A variant part - - declare - Variant : Node_Id; - Struct_Counter : Int := 0; - - Block_Decls : constant List_Id := New_List; - Block_Stmts : constant List_Id := New_List; - VP_Stmts : List_Id; - - Alt_List : constant List_Id := New_List; - Choice_List : List_Id; - - Struct_Any : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('S')); - - begin - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Struct_Any, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Any), Loc), - Expression => - Make_Function_Call (Loc, - Name => - New_Occurrence_Of - (RTE (RE_Extract_Union_Value), Loc), - - Parameter_Associations => New_List ( - Build_Get_Aggregate_Element (Loc, - Any => Any, - TC => - Make_Function_Call (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Any_Member_Type), Loc), - Parameter_Associations => - New_List ( - New_Occurrence_Of (Any, Loc), - Make_Integer_Literal (Loc, - Intval => Counter))), - Idx => - Make_Integer_Literal (Loc, - Intval => Counter)))))); - - Append_To (Stmts, - Make_Block_Statement (Loc, - Declarations => Block_Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Block_Stmts))); - - Append_To (Block_Stmts, - Make_Case_Statement (Loc, - Expression => - Make_Selected_Component (Loc, - Prefix => Rec, - Selector_Name => Chars (Name (Field))), - Alternatives => Alt_List)); - - Variant := First_Non_Pragma (Variants (Field)); - while Present (Variant) loop - Choice_List := - New_Copy_List_Tree - (Discrete_Choices (Variant)); - - VP_Stmts := New_List; - - -- Struct_Counter should be reset before - -- handling a variant part. Indeed only one - -- of the case statement alternatives will be - -- executed at run-time, so the counter must - -- start at 0 for every case statement. - - Struct_Counter := 0; - - FA_Append_Record_Traversal ( - Stmts => VP_Stmts, - Clist => Component_List (Variant), - Container => Struct_Any, - Counter => Struct_Counter); - - Append_To (Alt_List, - Make_Case_Statement_Alternative (Loc, - Discrete_Choices => Choice_List, - Statements => VP_Stmts)); - Next_Non_Pragma (Variant); - end loop; - end; - end if; - - Counter := Counter + 1; - end FA_Rec_Add_Process_Element; - - begin - -- First all discriminants - - if Has_Discriminants (Typ) then - Discriminant_Associations := New_List; - - Disc := First_Discriminant (Typ); - while Present (Disc) loop - declare - Disc_Var_Name : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => Chars (Disc)); - Disc_Type : constant Entity_Id := - Etype (Disc); - - begin - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Disc_Var_Name, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (Disc_Type, Loc), - - Expression => - Build_From_Any_Call (Disc_Type, - Build_Get_Aggregate_Element (Loc, - Any => Any_Parameter, - TC => Build_TypeCode_Call - (Loc, Disc_Type, Decls), - Idx => Make_Integer_Literal (Loc, - Intval => Component_Counter)), - Decls))); - - Component_Counter := Component_Counter + 1; - - Append_To (Discriminant_Associations, - Make_Discriminant_Association (Loc, - Selector_Names => New_List ( - New_Occurrence_Of (Disc, Loc)), - Expression => - New_Occurrence_Of (Disc_Var_Name, Loc))); - end; - Next_Discriminant (Disc); - end loop; - - Res_Definition := - Make_Subtype_Indication (Loc, - Subtype_Mark => Res_Definition, - Constraint => - Make_Index_Or_Discriminant_Constraint (Loc, - Discriminant_Associations)); - end if; - - -- Now we have all the discriminants in variables, we can - -- declared a constrained object. Note that we are not - -- initializing (non-discriminant) components directly in - -- the object declarations, because which fields to - -- initialize depends (at run time) on the discriminant - -- values. - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Res, - Object_Definition => Res_Definition)); - - -- ... then all components - - FA_Append_Record_Traversal (Stms, - Clist => Component_List (Rdef), - Container => Any_Parameter, - Counter => Component_Counter); - - Append_To (Stms, - Make_Simple_Return_Statement (Loc, - Expression => New_Occurrence_Of (Res, Loc))); - end; - end if; - - elsif Is_Array_Type (Typ) then - declare - Constrained : constant Boolean := Is_Constrained (Typ); - - procedure FA_Ary_Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : Entity_Id; - Datum : Node_Id); - -- Assign the current element (as identified by Counter) of - -- Any to the variable denoted by name Datum, and advance - -- Counter by 1. If Datum is not an Any, a call to From_Any - -- for its type is inserted. - - -------------------------------- - -- FA_Ary_Add_Process_Element -- - -------------------------------- - - procedure FA_Ary_Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : Entity_Id; - Datum : Node_Id) - is - Assignment : constant Node_Id := - Make_Assignment_Statement (Loc, - Name => Datum, - Expression => Empty); - - Element_Any : Node_Id; - - begin - declare - Element_TC : Node_Id; - - begin - if Etype (Datum) = RTE (RE_Any) then - - -- When Datum is an Any the Etype field is not - -- sufficient to determine the typecode of Datum - -- (which can be a TC_SEQUENCE or TC_ARRAY - -- depending on the value of Constrained). - - -- Therefore we retrieve the typecode which has - -- been constructed in Append_Array_Traversal with - -- a call to Get_Any_Type. - - Element_TC := - Make_Function_Call (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Get_Any_Type), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Entity (Datum), Loc))); - else - -- For non Any Datum we simply construct a typecode - -- matching the Etype of the Datum. - - Element_TC := Build_TypeCode_Call - (Loc, Etype (Datum), Decls); - end if; - - Element_Any := - Build_Get_Aggregate_Element (Loc, - Any => Any, - TC => Element_TC, - Idx => New_Occurrence_Of (Counter, Loc)); - end; - - -- Note: here we *prepend* statements to Stmts, so - -- we must do it in reverse order. - - Prepend_To (Stmts, - Make_Assignment_Statement (Loc, - Name => - New_Occurrence_Of (Counter, Loc), - Expression => - Make_Op_Add (Loc, - Left_Opnd => New_Occurrence_Of (Counter, Loc), - Right_Opnd => Make_Integer_Literal (Loc, 1)))); - - if Nkind (Datum) /= N_Attribute_Reference then - - -- We ignore the value of the length of each - -- dimension, since the target array has already - -- been constrained anyway. - - if Etype (Datum) /= RTE (RE_Any) then - Set_Expression (Assignment, - Build_From_Any_Call - (Component_Type (Typ), Element_Any, Decls)); - else - Set_Expression (Assignment, Element_Any); - end if; - - Prepend_To (Stmts, Assignment); - end if; - end FA_Ary_Add_Process_Element; - - ------------------------ - -- Local Declarations -- - ------------------------ - - Counter : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_J); - - Initial_Counter_Value : Int := 0; - - Component_TC : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_T); - - Res : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_R); - - procedure Append_From_Any_Array_Iterator is - new Append_Array_Traversal ( - Subprogram => Fnam, - Arry => Res, - Indices => New_List, - Add_Process_Element => FA_Ary_Add_Process_Element); - - Res_Subtype_Indication : Node_Id := - New_Occurrence_Of (Typ, Loc); - - begin - if not Constrained then - declare - Ndim : constant Int := Number_Dimensions (Typ); - Lnam : Name_Id; - Hnam : Name_Id; - Indx : Node_Id := First_Index (Typ); - Indt : Entity_Id; - - Ranges : constant List_Id := New_List; - - begin - for J in 1 .. Ndim loop - Lnam := New_External_Name ('L', J); - Hnam := New_External_Name ('H', J); - Indt := Etype (Indx); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Lnam), - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (Indt, Loc), - Expression => - Build_From_Any_Call - (Indt, - Build_Get_Aggregate_Element (Loc, - Any => Any_Parameter, - TC => Build_TypeCode_Call - (Loc, Indt, Decls), - Idx => - Make_Integer_Literal (Loc, J - 1)), - Decls))); - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Hnam), - - Constant_Present => True, - - Object_Definition => - New_Occurrence_Of (Indt, Loc), - - Expression => Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Indt, Loc), - - Attribute_Name => Name_Val, - - Expressions => New_List ( - Make_Op_Subtract (Loc, - Left_Opnd => - Make_Op_Add (Loc, - Left_Opnd => - OK_Convert_To ( - Standard_Long_Integer, - Make_Identifier (Loc, Lnam)), - - Right_Opnd => - OK_Convert_To ( - Standard_Long_Integer, - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE ( - RE_Get_Nested_Sequence_Length - ), Loc), - Parameter_Associations => - New_List ( - New_Occurrence_Of ( - Any_Parameter, Loc), - Make_Integer_Literal (Loc, - Intval => J))))), - - Right_Opnd => - Make_Integer_Literal (Loc, 1)))))); - - Append_To (Ranges, - Make_Range (Loc, - Low_Bound => Make_Identifier (Loc, Lnam), - High_Bound => Make_Identifier (Loc, Hnam))); - - Next_Index (Indx); - end loop; - - -- Now we have all the necessary bound information: - -- apply the set of range constraints to the - -- (unconstrained) nominal subtype of Res. - - Initial_Counter_Value := Ndim; - Res_Subtype_Indication := Make_Subtype_Indication (Loc, - Subtype_Mark => Res_Subtype_Indication, - Constraint => - Make_Index_Or_Discriminant_Constraint (Loc, - Constraints => Ranges)); - end; - end if; - - Append_To (Decls, - Make_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_Long_Unsigned), 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 - - -- Default: type is represented as an opaque sequence of bytes - - declare - Strm : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('S')); - Res : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('R')); - - begin - -- Strm : Buffer_Stream_Type; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Strm, - Aliased_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc))); - - -- Allocate_Buffer (Strm); - - Append_To (Stms, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Allocate_Buffer), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Strm, Loc)))); - - -- Any_To_BS (Strm, A); - - Append_To (Stms, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Any_To_BS), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Any_Parameter, Loc), - New_Occurrence_Of (Strm, Loc)))); - - -- declare - -- Res : constant T := T'Input (Strm); - -- begin - -- Release_Buffer (Strm); - -- return Res; - -- end; - - Append_To (Stms, Make_Block_Statement (Loc, - Declarations => New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Res, - Constant_Present => True, - Object_Definition => New_Occurrence_Of (Typ, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Typ, Loc), - Attribute_Name => Name_Input, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Strm, Loc), - Attribute_Name => Name_Access))))), - - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Release_Buffer), Loc), - Parameter_Associations => - New_List (New_Occurrence_Of (Strm, Loc))), - Make_Simple_Return_Statement (Loc, - Expression => New_Occurrence_Of (Res, Loc)))))); - - end; - 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_Reposiroty_Id -- - ------------------------- - - procedure Build_Name_And_Repository_Id - (E : Entity_Id; - Name_Str : out String_Id; - Repo_Id_Str : out String_Id) - is - begin - Start_String; - Store_String_Chars ("DSA:"); - Get_Library_Unit_Name_String (Scope (E)); - Store_String_Chars - (Name_Buffer (Name_Buffer'First .. - Name_Buffer'First + Name_Len - 1)); - Store_String_Char ('.'); - Get_Name_String (Chars (E)); - Store_String_Chars - (Name_Buffer (Name_Buffer'First .. - Name_Buffer'First + Name_Len - 1)); - Store_String_Chars (":1.0"); - Repo_Id_Str := End_String; - Name_Str := String_From_Name_Buffer; - end Build_Name_And_Repository_Id; - - ----------------------- - -- Build_To_Any_Call -- - ----------------------- - - function Build_To_Any_Call - (N : Node_Id; - Decls : List_Id) return Node_Id - is - Loc : constant Source_Ptr := Sloc (N); - - Typ : Entity_Id := Etype (N); - U_Type : Entity_Id; - Fnam : Entity_Id := Empty; - Lib_RE : RE_Id := RE_Null; - - 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); - - -- 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 Sloc (U_Type) <= Standard_Location then - U_Type := Base_Type (U_Type); - end if; - - if Present (Fnam) then - null; - - 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 = Etype (Standard_Short_Short_Integer) then - Lib_RE := RE_TA_SSI; - - elsif U_Type = Etype (Standard_Short_Integer) then - Lib_RE := RE_TA_SI; - - elsif U_Type = Etype (Standard_Integer) then - Lib_RE := RE_TA_I; - - elsif U_Type = Etype (Standard_Long_Integer) then - Lib_RE := RE_TA_LI; - - elsif U_Type = Etype (Standard_Long_Long_Integer) then - Lib_RE := RE_TA_LLI; - - -- Unsigned integer types - - elsif U_Type = RTE (RE_Short_Short_Unsigned) then - Lib_RE := RE_TA_SSU; - - elsif U_Type = RTE (RE_Short_Unsigned) then - Lib_RE := RE_TA_SU; - - elsif U_Type = RTE (RE_Unsigned) then - Lib_RE := RE_TA_U; - - elsif U_Type = RTE (RE_Long_Unsigned) then - Lib_RE := RE_TA_LU; - - elsif U_Type = RTE (RE_Long_Long_Unsigned) then - Lib_RE := RE_TA_LLU; - - elsif U_Type = Standard_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; - - return - Make_Function_Call (Loc, - Name => New_Occurrence_Of (Fnam, Loc), - Parameter_Associations => - New_List (Unchecked_Convert_To (U_Type, N))); - end Build_To_Any_Call; - - --------------------------- - -- Build_To_Any_Function -- - --------------------------- - - procedure Build_To_Any_Function - (Loc : Source_Ptr; - Typ : Entity_Id; - Decl : out Node_Id; - Fnam : out Entity_Id) - is - Spec : Node_Id; - Decls : constant List_Id := New_List; - Stms : constant List_Id := New_List; - - Expr_Parameter : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_E); - - Any : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_A); - - Any_Decl : Node_Id; - Result_TC : Node_Id := Build_TypeCode_Call (Loc, Typ, Decls); - - Use_Opaque_Representation : Boolean; - -- When True, use stream attributes and represent type as an - -- opaque sequence of bytes. - - begin - if Is_Itype (Typ) then - Build_To_Any_Function - (Loc => Loc, - Typ => Etype (Typ), - Decl => Decl, - Fnam => Fnam); - return; - end if; - - Fnam := Make_Helper_Function_Name (Loc, Typ, Name_To_Any); - - Spec := - Make_Function_Specification (Loc, - Defining_Unit_Name => Fnam, - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Expr_Parameter, - Parameter_Type => New_Occurrence_Of (Typ, Loc))), - Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc)); - Set_Etype (Expr_Parameter, Typ); - - Any_Decl := - Make_Object_Declaration (Loc, - Defining_Identifier => Any, - Object_Definition => New_Occurrence_Of (RTE (RE_Any), Loc)); - - Use_Opaque_Representation := False; - - if Has_Stream_Attribute_Definition - (Typ, TSS_Stream_Output, At_Any_Place => True) - or else - Has_Stream_Attribute_Definition - (Typ, TSS_Stream_Write, At_Any_Place => True) - then - -- If user-defined stream attributes are specified for this - -- type, use them and transmit data as an opaque sequence of - -- stream elements. - - Use_Opaque_Representation := True; - - elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then - - -- Non-tagged derived type: convert to root type - - declare - Rt_Type : constant Entity_Id := Root_Type (Typ); - Expr : constant Node_Id := - OK_Convert_To - (Rt_Type, - New_Occurrence_Of (Expr_Parameter, Loc)); - begin - Set_Expression (Any_Decl, Build_To_Any_Call (Expr, Decls)); - end; - - elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then - - -- Non-tagged record type - - if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then - declare - Rt_Type : constant Entity_Id := Etype (Typ); - Expr : constant Node_Id := - OK_Convert_To (Rt_Type, - New_Occurrence_Of (Expr_Parameter, Loc)); - - begin - Set_Expression - (Any_Decl, Build_To_Any_Call (Expr, Decls)); - end; - - -- Comment needed here (and label on declare block ???) - - else - declare - Disc : Entity_Id := Empty; - Rdef : constant Node_Id := - Type_Definition (Declaration_Node (Typ)); - Counter : Int := 0; - Elements : constant List_Id := New_List; - - procedure TA_Rec_Add_Process_Element - (Stmts : List_Id; - Container : Node_Or_Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id); - -- Processing routine for traversal below - - procedure TA_Append_Record_Traversal is - new Append_Record_Traversal - (Rec => Expr_Parameter, - Add_Process_Element => TA_Rec_Add_Process_Element); - - -------------------------------- - -- TA_Rec_Add_Process_Element -- - -------------------------------- - - procedure TA_Rec_Add_Process_Element - (Stmts : List_Id; - Container : Node_Or_Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id) - is - Field_Ref : Node_Id; - - begin - if Nkind (Field) = N_Defining_Identifier then - - -- A regular component - - Field_Ref := Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Rec, Loc), - Selector_Name => New_Occurrence_Of (Field, Loc)); - Set_Etype (Field_Ref, Etype (Field)); - - Append_To (Stmts, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Add_Aggregate_Element), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Container, Loc), - Build_To_Any_Call (Field_Ref, Decls)))); - - else - -- A variant part - - Variant_Part : declare - Variant : Node_Id; - Struct_Counter : Int := 0; - - Block_Decls : constant List_Id := New_List; - Block_Stmts : constant List_Id := New_List; - VP_Stmts : List_Id; - - Alt_List : constant List_Id := New_List; - Choice_List : List_Id; - - Union_Any : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('V')); - - Struct_Any : constant Entity_Id := - Make_Defining_Identifier (Loc, - New_Internal_Name ('S')); - - function Make_Discriminant_Reference - return Node_Id; - -- Build reference to the discriminant for this - -- variant part. - - --------------------------------- - -- Make_Discriminant_Reference -- - --------------------------------- - - function Make_Discriminant_Reference - return Node_Id - is - Nod : constant Node_Id := - Make_Selected_Component (Loc, - Prefix => Rec, - Selector_Name => - Chars (Name (Field))); - begin - Set_Etype (Nod, Etype (Name (Field))); - return Nod; - end Make_Discriminant_Reference; - - -- Start processing for Variant_Part - - begin - Append_To (Stmts, - Make_Block_Statement (Loc, - Declarations => - Block_Decls, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Block_Stmts))); - - -- Declare variant part aggregate (Union_Any). - -- Knowing the position of this VP in the - -- variant record, we can fetch the VP typecode - -- from Container. - - Append_To (Block_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Union_Any, - Object_Definition => - New_Occurrence_Of (RTE (RE_Any), Loc), - Expression => - Make_Function_Call (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Create_Any), Loc), - Parameter_Associations => New_List ( - Make_Function_Call (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Any_Member_Type), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Container, Loc), - Make_Integer_Literal (Loc, - Counter))))))); - - -- Declare inner struct aggregate (which - -- contains the components of this VP). - - Append_To (Block_Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Struct_Any, - Object_Definition => - New_Occurrence_Of (RTE (RE_Any), Loc), - Expression => - Make_Function_Call (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Create_Any), Loc), - Parameter_Associations => New_List ( - Make_Function_Call (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Any_Member_Type), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Union_Any, Loc), - Make_Integer_Literal (Loc, - Uint_1))))))); - - -- Build case statement - - Append_To (Block_Stmts, - Make_Case_Statement (Loc, - Expression => Make_Discriminant_Reference, - Alternatives => Alt_List)); - - Variant := First_Non_Pragma (Variants (Field)); - while Present (Variant) loop - Choice_List := New_Copy_List_Tree - (Discrete_Choices (Variant)); - - VP_Stmts := New_List; - - -- Append discriminant val to union aggregate - - Append_To (VP_Stmts, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Add_Aggregate_Element), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Union_Any, Loc), - Build_To_Any_Call - (Make_Discriminant_Reference, - Block_Decls)))); - - -- Populate inner struct aggregate - - -- Struct_Counter should be reset before - -- handling a variant part. Indeed only one - -- of the case statement alternatives will be - -- executed at run-time, so the counter must - -- start at 0 for every case statement. - - Struct_Counter := 0; - - TA_Append_Record_Traversal ( - Stmts => VP_Stmts, - Clist => Component_List (Variant), - Container => Struct_Any, - Counter => Struct_Counter); - - -- Append inner struct to union aggregate - - Append_To (VP_Stmts, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Add_Aggregate_Element), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Union_Any, Loc), - New_Occurrence_Of (Struct_Any, Loc)))); - - -- Append union to outer aggregate - - Append_To (VP_Stmts, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Add_Aggregate_Element), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Container, Loc), - New_Occurrence_Of - (Union_Any, Loc)))); - - Append_To (Alt_List, - Make_Case_Statement_Alternative (Loc, - Discrete_Choices => Choice_List, - Statements => VP_Stmts)); - - Next_Non_Pragma (Variant); - end loop; - end Variant_Part; - end if; - - Counter := Counter + 1; - end TA_Rec_Add_Process_Element; - - begin - -- Records are encoded in a TC_STRUCT aggregate: - - -- -- Outer aggregate (TC_STRUCT) - -- | [discriminant1] - -- | [discriminant2] - -- | ... - -- | - -- | [component1] - -- | [component2] - -- | ... - - -- A component can be a common component or variant part - - -- A variant part is encoded as a TC_UNION aggregate: - - -- -- Variant Part Aggregate (TC_UNION) - -- | [discriminant choice for this Variant Part] - -- | - -- | -- Inner struct (TC_STRUCT) - -- | | [component1] - -- | | [component2] - -- | | ... - - -- Let's start by building the outer aggregate. First we - -- construct Elements array containing all discriminants. - - if Has_Discriminants (Typ) then - Disc := First_Discriminant (Typ); - while Present (Disc) loop - declare - Discriminant : constant Entity_Id := - Make_Selected_Component (Loc, - Prefix => - Expr_Parameter, - Selector_Name => - Chars (Disc)); - - begin - Set_Etype (Discriminant, Etype (Disc)); - - Append_To (Elements, - Make_Component_Association (Loc, - Choices => New_List ( - Make_Integer_Literal (Loc, Counter)), - Expression => - Build_To_Any_Call (Discriminant, Decls))); - end; - - Counter := Counter + 1; - Next_Discriminant (Disc); - end loop; - - else - -- If there are no discriminants, we declare an empty - -- Elements array. - - declare - Dummy_Any : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('A')); - - begin - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Dummy_Any, - Object_Definition => - New_Occurrence_Of (RTE (RE_Any), Loc))); - - Append_To (Elements, - Make_Component_Association (Loc, - Choices => New_List ( - Make_Range (Loc, - Low_Bound => - Make_Integer_Literal (Loc, 1), - High_Bound => - Make_Integer_Literal (Loc, 0))), - Expression => - New_Occurrence_Of (Dummy_Any, Loc))); - end; - end if; - - -- We build the result aggregate with discriminants - -- as the first elements. - - Set_Expression (Any_Decl, - Make_Function_Call (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Any_Aggregate_Build), Loc), - Parameter_Associations => New_List ( - Result_TC, - Make_Aggregate (Loc, - Component_Associations => Elements)))); - Result_TC := Empty; - - -- Then we append all the components to the result - -- aggregate. - - TA_Append_Record_Traversal (Stms, - Clist => Component_List (Rdef), - Container => Any, - Counter => Counter); - end; - end if; - - elsif Is_Array_Type (Typ) then - - -- Constrained and unconstrained array types - - declare - Constrained : constant Boolean := Is_Constrained (Typ); - - procedure TA_Ary_Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : Entity_Id; - Datum : Node_Id); - - -------------------------------- - -- TA_Ary_Add_Process_Element -- - -------------------------------- - - procedure TA_Ary_Add_Process_Element - (Stmts : List_Id; - Any : Entity_Id; - Counter : Entity_Id; - Datum : Node_Id) - is - pragma Warnings (Off); - pragma Unreferenced (Counter); - pragma Warnings (On); - - Element_Any : Node_Id; - - begin - if Etype (Datum) = RTE (RE_Any) then - Element_Any := Datum; - else - Element_Any := Build_To_Any_Call (Datum, Decls); - end if; - - Append_To (Stmts, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of ( - RTE (RE_Add_Aggregate_Element), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Any, Loc), - Element_Any))); - end TA_Ary_Add_Process_Element; - - procedure Append_To_Any_Array_Iterator is - new Append_Array_Traversal ( - Subprogram => Fnam, - Arry => Expr_Parameter, - Indices => New_List, - Add_Process_Element => TA_Ary_Add_Process_Element); - - Index : Node_Id; - - begin - Set_Expression (Any_Decl, - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Create_Any), Loc), - Parameter_Associations => New_List (Result_TC))); - Result_TC := Empty; - - if not Constrained then - Index := First_Index (Typ); - for J in 1 .. Number_Dimensions (Typ) loop - Append_To (Stms, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of ( - RTE (RE_Add_Aggregate_Element), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Any, Loc), - Build_To_Any_Call ( - OK_Convert_To (Etype (Index), - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Expr_Parameter, Loc), - Attribute_Name => Name_First, - Expressions => New_List ( - Make_Integer_Literal (Loc, J)))), - Decls)))); - Next_Index (Index); - end loop; - end if; - - Append_To_Any_Array_Iterator (Stms, Any); - end; - - elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then - - -- Integer types - - Set_Expression (Any_Decl, - Build_To_Any_Call ( - OK_Convert_To ( - Find_Numeric_Representation (Typ), - New_Occurrence_Of (Expr_Parameter, Loc)), - Decls)); - - else - -- Default case, including tagged types: opaque representation - - Use_Opaque_Representation := True; - end if; - - if Use_Opaque_Representation then - declare - Strm : constant Entity_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('S')); - -- Stream used to store data representation produced by - -- stream attribute. - - begin - -- Generate: - -- Strm : aliased Buffer_Stream_Type; - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => - Strm, - Aliased_Present => - True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc))); - - -- Generate: - -- Allocate_Buffer (Strm); - - Append_To (Stms, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Allocate_Buffer), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Strm, Loc)))); - - -- Generate: - -- T'Output (Strm'Access, E); - - Append_To (Stms, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Typ, Loc), - Attribute_Name => Name_Output, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Strm, Loc), - Attribute_Name => Name_Access), - New_Occurrence_Of (Expr_Parameter, Loc)))); - - -- Generate: - -- BS_To_Any (Strm, A); - - Append_To (Stms, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_BS_To_Any), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Strm, Loc), - New_Occurrence_Of (Any, Loc)))); - - -- 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 := Empty; - Lib_RE : RE_Id := RE_Null; - Expr : Node_Id; - - begin - -- Special case System.PolyORB.Interface.Any: its primitives have - -- not been set yet, so can't call Find_Inherited_TSS. - - if Typ = RTE (RE_Any) then - Fnam := RTE (RE_TC_A); - - else - -- First simple case where the TypeCode is present - -- in the type's TSS. - - Fnam := Find_Inherited_TSS (U_Type, TSS_TypeCode); - end if; - - if No (Fnam) then - if Sloc (U_Type) <= Standard_Location then - - -- Do not try to build alias typecodes for subtypes from - -- Standard. - - U_Type := Base_Type (U_Type); - end if; - - if U_Type = Standard_Boolean then - Lib_RE := RE_TC_B; - - 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 = Etype (Standard_Short_Short_Integer) then - Lib_RE := RE_TC_SSI; - - elsif U_Type = Etype (Standard_Short_Integer) then - Lib_RE := RE_TC_SI; - - elsif U_Type = Etype (Standard_Integer) then - Lib_RE := RE_TC_I; - - elsif U_Type = Etype (Standard_Long_Integer) then - Lib_RE := RE_TC_LI; - - elsif U_Type = Etype (Standard_Long_Long_Integer) then - Lib_RE := RE_TC_LLI; - - -- Unsigned integer types - - elsif U_Type = RTE (RE_Short_Short_Unsigned) then - Lib_RE := RE_TC_SSU; - - elsif U_Type = RTE (RE_Short_Unsigned) then - Lib_RE := RE_TC_SU; - - elsif U_Type = RTE (RE_Unsigned) then - Lib_RE := RE_TC_U; - - elsif U_Type = RTE (RE_Long_Unsigned) then - Lib_RE := RE_TC_LU; - - elsif U_Type = RTE (RE_Long_Long_Unsigned) then - Lib_RE := RE_TC_LLU; - - elsif U_Type = Standard_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 TC_Build with the given kind and parameters - - procedure Return_Constructed_TypeCode (Kind : Entity_Id); - -- Make a return statement that calls TC_Build with the given - -- typecode kind, and the constructed parameters list. - - 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_String), Loc), - Parameter_Associations => New_List ( - Make_String_Literal (Loc, S)))); - end Add_String_Parameter; - - ---------------------------- - -- Add_TypeCode_Parameter -- - ---------------------------- - - procedure Add_TypeCode_Parameter - (TC_Node : Node_Id; - Parameter_List : List_Id) - is - begin - Append_To (Parameter_List, - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_TA_TC), Loc), - Parameter_Associations => New_List (TC_Node))); - end Add_TypeCode_Parameter; - - ------------------------ - -- Add_Long_Parameter -- - ------------------------ - - procedure Add_Long_Parameter - (Expr_Node : Node_Id; - Parameter_List : List_Id) - is - begin - Append_To (Parameter_List, - Make_Function_Call (Loc, - Name => New_Occurrence_Of (RTE (RE_TA_LI), Loc), - Parameter_Associations => New_List (Expr_Node))); - end Add_Long_Parameter; - - ------------------------------- - -- Initialize_Parameter_List -- - ------------------------------- - - procedure Initialize_Parameter_List - (Name_String : String_Id; - Repo_Id_String : String_Id; - Parameter_List : out List_Id) - is - begin - Parameter_List := New_List; - Add_String_Parameter (Name_String, Parameter_List); - Add_String_Parameter (Repo_Id_String, Parameter_List); - end Initialize_Parameter_List; - - --------------------------- - -- Return_Alias_TypeCode -- - --------------------------- - - procedure Return_Alias_TypeCode - (Base_TypeCode : Node_Id) - is - begin - Add_TypeCode_Parameter (Base_TypeCode, Parameters); - Return_Constructed_TypeCode (RTE (RE_TC_Alias)); - end Return_Alias_TypeCode; - - ------------------------------- - -- Make_Constructed_TypeCode -- - ------------------------------- - - function Make_Constructed_TypeCode - (Kind : Entity_Id; - Parameters : List_Id) return Node_Id - is - Constructed_TC : constant Node_Id := - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_TC_Build), Loc), - Parameter_Associations => New_List ( - New_Occurrence_Of (Kind, Loc), - Make_Aggregate (Loc, - Expressions => Parameters))); - begin - Set_Etype (Constructed_TC, RTE (RE_TypeCode)); - return Constructed_TC; - end Make_Constructed_TypeCode; - - --------------------------------- - -- Return_Constructed_TypeCode -- - --------------------------------- - - procedure Return_Constructed_TypeCode (Kind : Entity_Id) is - begin - Append_To (Stms, - Make_Simple_Return_Statement (Loc, - Expression => - Make_Constructed_TypeCode (Kind, Parameters))); - end Return_Constructed_TypeCode; - - ------------------ - -- Record types -- - ------------------ - - procedure TC_Rec_Add_Process_Element - (Params : List_Id; - Any : Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id); - - procedure TC_Append_Record_Traversal is - new Append_Record_Traversal ( - Rec => Empty, - Add_Process_Element => TC_Rec_Add_Process_Element); - - -------------------------------- - -- TC_Rec_Add_Process_Element -- - -------------------------------- - - procedure TC_Rec_Add_Process_Element - (Params : List_Id; - Any : Entity_Id; - Counter : in out Int; - Rec : Entity_Id; - Field : Node_Id) - is - pragma Warnings (Off); - pragma Unreferenced (Any, Counter, Rec); - pragma Warnings (On); - - 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 - - declare - Discriminant_Type : constant Entity_Id := - Etype (Name (Field)); - - Is_Enum : constant Boolean := - Is_Enumeration_Type (Discriminant_Type); - - Union_TC_Params : List_Id; - - U_Name : constant Name_Id := - New_External_Name (Chars (Typ), 'V', -1); - - Name_Str : String_Id; - Struct_TC_Params : List_Id; - - Variant : Node_Id; - Choice : Node_Id; - Default : constant Node_Id := - Make_Integer_Literal (Loc, -1); - - Dummy_Counter : Int := 0; - - Choice_Index : Int := 0; - - procedure Add_Params_For_Variant_Components; - -- Add a struct TypeCode and a corresponding member name - -- to the union parameter list. - - -- Ordering of declarations is a complete mess in this - -- area, it is supposed to be types/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_TC_Struct), Struct_TC_Params), - Union_TC_Params); - - Add_String_Parameter (Name_Str, Union_TC_Params); - end Add_Params_For_Variant_Components; - - begin - Get_Name_String (U_Name); - Name_Str := String_From_Name_Buffer; - - Initialize_Parameter_List - (Name_Str, Name_Str, Union_TC_Params); - - -- Add union in enclosing parameter list - - Add_TypeCode_Parameter - (Make_Constructed_TypeCode - (RTE (RE_TC_Union), Union_TC_Params), - Params); - - Add_String_Parameter (Name_Str, Params); - - -- Build union parameters - - Add_TypeCode_Parameter - (Build_TypeCode_Call - (Loc, Discriminant_Type, Decls), - Union_TC_Params); - - Add_Long_Parameter (Default, Union_TC_Params); - - Variant := First_Non_Pragma (Variants (Field)); - while Present (Variant) loop - Choice := First (Discrete_Choices (Variant)); - while Present (Choice) loop - case Nkind (Choice) is - when N_Range => - declare - L : constant Uint := - Expr_Value (Low_Bound (Choice)); - H : constant Uint := - Expr_Value (High_Bound (Choice)); - J : Uint := L; - -- 3.8.1(8) guarantees that the bounds of - -- this range are static. - - Expr : Node_Id; - - begin - while J <= H loop - if Is_Enum then - Expr := New_Occurrence_Of ( - Get_Enum_Lit_From_Pos ( - Discriminant_Type, J, Loc), Loc); - else - Expr := - Make_Integer_Literal (Loc, J); - end if; - Append_To (Union_TC_Params, - Build_To_Any_Call (Expr, Decls)); - - Add_Params_For_Variant_Components; - J := J + Uint_1; - end loop; - end; - - when N_Others_Choice => - - -- This variant possess a default choice. - -- We must therefore set the default - -- parameter to the current choice index. The - -- default parameter is by construction the - -- fourth in the Union_TC_Params list. - - declare - Default_Node : constant Node_Id := - Pick (Union_TC_Params, 4); - - New_Default_Node : constant Node_Id := - Make_Function_Call (Loc, - Name => - New_Occurrence_Of - (RTE (RE_TA_LI), Loc), - Parameter_Associations => - New_List ( - Make_Integer_Literal - (Loc, Choice_Index))); - begin - Insert_Before ( - Default_Node, - New_Default_Node); - - Remove (Default_Node); - end; - - -- Add a placeholder member label - -- for the default case. - -- It must be of the discriminant type. - - declare - Exp : constant Node_Id := - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of - (Discriminant_Type, Loc), - Attribute_Name => Name_First); - begin - Set_Etype (Exp, Discriminant_Type); - Append_To (Union_TC_Params, - Build_To_Any_Call (Exp, Decls)); - end; - - Add_Params_For_Variant_Components; - - when others => - - -- Case of an explicit choice - - declare - Exp : constant Node_Id := - New_Copy_Tree (Choice); - begin - Append_To (Union_TC_Params, - Build_To_Any_Call (Exp, Decls)); - end; - - Add_Params_For_Variant_Components; - end case; - - Next (Choice); - Choice_Index := Choice_Index + 1; - end loop; - - Next_Non_Pragma (Variant); - end loop; - end; - end if; - end TC_Rec_Add_Process_Element; - - Type_Name_Str : String_Id; - Type_Repo_Id_Str : String_Id; - - begin - if Is_Itype (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_TC_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_TC_Array), New_List ( - Build_To_Any_Call ( - OK_Convert_To (RTE (RE_Long_Unsigned), - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Typ, Loc), - Attribute_Name => Name_Length, - Expressions => New_List ( - Make_Integer_Literal (Loc, - Intval => Ndim - J + 1)))), - Decls), - Build_To_Any_Call (Inner_TypeCode, Decls))); - - else - -- Unconstrained case: add low bound for each - -- dimension. - - Add_TypeCode_Parameter - (Build_TypeCode_Call (Loc, Etype (Indx), Decls), - Parameters); - Get_Name_String (New_External_Name ('L', J)); - Add_String_Parameter ( - String_From_Name_Buffer, - Parameters); - Next_Index (Indx); - - Inner_TypeCode := Make_Constructed_TypeCode - (RTE (RE_TC_Sequence), New_List ( - Build_To_Any_Call ( - OK_Convert_To (RTE (RE_Long_Unsigned), - Make_Integer_Literal (Loc, 0)), - Decls), - Build_To_Any_Call (Inner_TypeCode, Decls))); - end if; - end loop; - - if Constrained then - Return_Alias_TypeCode (Inner_TypeCode); - else - Add_TypeCode_Parameter (Inner_TypeCode, Parameters); - Start_String; - Store_String_Char ('V'); - Add_String_Parameter (End_String, Parameters); - Return_Constructed_TypeCode (RTE (RE_TC_Struct)); - end if; - end; - - 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 - if Is_Unsigned_Type (Typ) then - if P_Size <= Standard_Short_Short_Integer_Size then - return RTE (RE_Short_Short_Unsigned); - - elsif P_Size <= Standard_Short_Integer_Size then - return RTE (RE_Short_Unsigned); - - elsif P_Size <= Standard_Integer_Size then - return RTE (RE_Unsigned); - - elsif P_Size <= Standard_Long_Integer_Size then - return RTE (RE_Long_Unsigned); - - else - return RTE (RE_Long_Long_Unsigned); - end if; - - elsif Is_Integer_Type (Typ) then - if P_Size <= Standard_Short_Short_Integer_Size then - return Standard_Short_Short_Integer; - - elsif P_Size <= Standard_Short_Integer_Size then - return Standard_Short_Integer; - - elsif P_Size <= Standard_Integer_Size then - return Standard_Integer; - - elsif P_Size <= Standard_Long_Integer_Size then - return Standard_Long_Integer; - - else - return Standard_Long_Long_Integer; - 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; - - -- TBD: fixed point types??? - -- TBverified numeric types with a biased representation??? - - end Find_Numeric_Representation; - - --------------------------- - -- 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), - Indices); - 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 (Indices, - 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_Long_Unsigned), 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_Long_Unsigned)); - - 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, we use a canonical name so that it matches - -- the primitive spec. For all other cases, we use a serialized - -- name so that multiple generations of the same procedure do - -- not clash. - - begin - if not Is_Tagged_Type (Typ) then - Serial := Increment_Serial_Number; - end if; - - -- Use prefixed underscore to avoid potential clash with used - -- 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; - - 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 : String_Id; - - begin - Get_Library_Unit_Name_String (Package_Spec); - Pkg_Name := String_From_Name_Buffer; - Inst := - Make_Package_Instantiation (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, New_Internal_Name ('R')), - Name => - New_Occurrence_Of (RTE (RE_RCI_Locator), Loc), - Generic_Associations => New_List ( - Make_Generic_Association (Loc, - Selector_Name => - Make_Identifier (Loc, Name_RCI_Name), - Explicit_Generic_Actual_Parameter => - Make_String_Literal (Loc, - Strval => Pkg_Name)), - Make_Generic_Association (Loc, - Selector_Name => - Make_Identifier (Loc, Name_Version), - Explicit_Generic_Actual_Parameter => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Defining_Entity (Package_Spec), Loc), - Attribute_Name => - Name_Version)))); - - RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec), - Defining_Unit_Name (Inst)); - return Inst; - 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 - Set_Ekind (Snam, E_Function); - Set_Etype (Snam, Entity (Result_Definition (Spec))); - else - Set_Ekind (Snam, E_Procedure); - Set_Etype (Snam, Standard_Void_Type); - end if; - - Set_TSS (Typ, Snam); - end Set_Renaming_TSS; - - ---------------------------------------------- - -- Specific_Add_Obj_RPC_Receiver_Completion -- - ---------------------------------------------- - - procedure Specific_Add_Obj_RPC_Receiver_Completion - (Loc : Source_Ptr; - Decls : List_Id; - RPC_Receiver : Entity_Id; - Stub_Elements : Stub_Structure) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Add_Obj_RPC_Receiver_Completion (Loc, - Decls, RPC_Receiver, Stub_Elements); - when others => - GARLIC_Support.Add_Obj_RPC_Receiver_Completion (Loc, - Decls, RPC_Receiver, Stub_Elements); - end case; - end Specific_Add_Obj_RPC_Receiver_Completion; - - -------------------------------- - -- Specific_Add_RACW_Features -- - -------------------------------- - - procedure Specific_Add_RACW_Features - (RACW_Type : Entity_Id; - Desig : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Access : Entity_Id; - RPC_Receiver_Decl : Node_Id; - Body_Decls : List_Id) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Add_RACW_Features - (RACW_Type, - Desig, - Stub_Type, - Stub_Type_Access, - RPC_Receiver_Decl, - Body_Decls); - - when others => - GARLIC_Support.Add_RACW_Features - (RACW_Type, - Stub_Type, - Stub_Type_Access, - RPC_Receiver_Decl, - Body_Decls); - end case; - end Specific_Add_RACW_Features; - - -------------------------------- - -- Specific_Add_RAST_Features -- - -------------------------------- - - procedure Specific_Add_RAST_Features - (Vis_Decl : Node_Id; - RAS_Type : Entity_Id) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Add_RAST_Features (Vis_Decl, RAS_Type); - when others => - GARLIC_Support.Add_RAST_Features (Vis_Decl, RAS_Type); - end case; - end Specific_Add_RAST_Features; - - -------------------------------------------------- - -- Specific_Add_Receiving_Stubs_To_Declarations -- - -------------------------------------------------- - - procedure Specific_Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id; - Stmts : List_Id) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Add_Receiving_Stubs_To_Declarations - (Pkg_Spec, Decls, Stmts); - when others => - GARLIC_Support.Add_Receiving_Stubs_To_Declarations - (Pkg_Spec, Decls, Stmts); - end case; - end Specific_Add_Receiving_Stubs_To_Declarations; - - ------------------------------------------ - -- Specific_Build_General_Calling_Stubs -- - ------------------------------------------ - - procedure Specific_Build_General_Calling_Stubs - (Decls : List_Id; - Statements : List_Id; - Target : RPC_Target; - Subprogram_Id : Node_Id; - Asynchronous : Node_Id := Empty; - Is_Known_Asynchronous : Boolean := False; - Is_Known_Non_Asynchronous : Boolean := False; - Is_Function : Boolean; - Spec : Node_Id; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Nod : Node_Id) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Build_General_Calling_Stubs - (Decls, - Statements, - Target.Object, - Subprogram_Id, - Asynchronous, - Is_Known_Asynchronous, - Is_Known_Non_Asynchronous, - Is_Function, - Spec, - Stub_Type, - RACW_Type, - Nod); - - when others => - GARLIC_Support.Build_General_Calling_Stubs - (Decls, - Statements, - Target.Partition, - Target.RPC_Receiver, - Subprogram_Id, - Asynchronous, - Is_Known_Asynchronous, - Is_Known_Non_Asynchronous, - Is_Function, - Spec, - Stub_Type, - RACW_Type, - Nod); - end case; - end Specific_Build_General_Calling_Stubs; - - -------------------------------------- - -- Specific_Build_RPC_Receiver_Body -- - -------------------------------------- - - procedure Specific_Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Request : out Entity_Id; - Subp_Id : out Entity_Id; - Subp_Index : out Entity_Id; - Stmts : out List_Id; - Decl : out Node_Id) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Build_RPC_Receiver_Body - (RPC_Receiver, - Request, - Subp_Id, - Subp_Index, - Stmts, - Decl); - - when others => - GARLIC_Support.Build_RPC_Receiver_Body - (RPC_Receiver, - Request, - Subp_Id, - Subp_Index, - Stmts, - Decl); - end case; - end Specific_Build_RPC_Receiver_Body; - - -------------------------------- - -- Specific_Build_Stub_Target -- - -------------------------------- - - function Specific_Build_Stub_Target - (Loc : Source_Ptr; - Decls : List_Id; - RCI_Locator : Entity_Id; - Controlling_Parameter : Entity_Id) return RPC_Target - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - return PolyORB_Support.Build_Stub_Target (Loc, - Decls, RCI_Locator, Controlling_Parameter); - - when others => - return GARLIC_Support.Build_Stub_Target (Loc, - Decls, RCI_Locator, Controlling_Parameter); - end case; - end Specific_Build_Stub_Target; - - ------------------------------ - -- Specific_Build_Stub_Type -- - ------------------------------ - - procedure Specific_Build_Stub_Type - (RACW_Type : Entity_Id; - Stub_Type : Entity_Id; - Stub_Type_Decl : out Node_Id; - RPC_Receiver_Decl : out Node_Id) - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - PolyORB_Support.Build_Stub_Type ( - RACW_Type, Stub_Type, - Stub_Type_Decl, RPC_Receiver_Decl); - - when others => - GARLIC_Support.Build_Stub_Type ( - RACW_Type, Stub_Type, - Stub_Type_Decl, RPC_Receiver_Decl); - end case; - end Specific_Build_Stub_Type; - - function Specific_Build_Subprogram_Receiving_Stubs - (Vis_Decl : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Parent_Primitive : Entity_Id := Empty) return Node_Id - is - begin - case Get_PCS_Name is - when Name_PolyORB_DSA => - return PolyORB_Support.Build_Subprogram_Receiving_Stubs - (Vis_Decl, - Asynchronous, - Dynamically_Asynchronous, - Stub_Type, - RACW_Type, - Parent_Primitive); - - when others => - return GARLIC_Support.Build_Subprogram_Receiving_Stubs - (Vis_Decl, - Asynchronous, - Dynamically_Asynchronous, - Stub_Type, - RACW_Type, - Parent_Primitive); - end case; - end Specific_Build_Subprogram_Receiving_Stubs; - - ------------------------------- - -- Transmit_As_Unconstrained -- - ------------------------------- - - function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean is - begin - return - not (Is_Elementary_Type (Typ) or else Is_Constrained (Typ)) - or else (Is_Access_Type (Typ) and then Can_Never_Be_Null (Typ)); - end Transmit_As_Unconstrained; - - -------------------------- - -- Underlying_RACW_Type -- - -------------------------- - - function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is - Record_Type : Entity_Id; - - begin - if Ekind (RAS_Typ) = E_Record_Type then - Record_Type := RAS_Typ; - else - pragma Assert (Present (Equivalent_Type (RAS_Typ))); - Record_Type := Equivalent_Type (RAS_Typ); - end if; - - return - Etype (Subtype_Indication - (Component_Definition - (First (Component_Items - (Component_List - (Type_Definition - (Declaration_Node (Record_Type)))))))); - end Underlying_RACW_Type; - -end Exp_Dist; |