aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/gcc/ada/exp_dist.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/gcc/ada/exp_dist.adb')
-rw-r--r--gcc-4.4.3/gcc/ada/exp_dist.adb11487
1 files changed, 0 insertions, 11487 deletions
diff --git a/gcc-4.4.3/gcc/ada/exp_dist.adb b/gcc-4.4.3/gcc/ada/exp_dist.adb
deleted file mode 100644
index 546bbcc57..000000000
--- a/gcc-4.4.3/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;