diff options
Diffstat (limited to 'gcc/ada/exp_dist.adb')
-rw-r--r-- | gcc/ada/exp_dist.adb | 3352 |
1 files changed, 2215 insertions, 1137 deletions
diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb index effeee69b44..63c6d3cb21f 100644 --- a/gcc/ada/exp_dist.adb +++ b/gcc/ada/exp_dist.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2004 Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2005 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- -- @@ -207,35 +207,11 @@ package body Exp_Dist is -- If Locator is not Empty, it will be used instead of RCI_Cache. If -- New_Name is given, then it will be used instead of the original name. - function Build_Subprogram_Receiving_Stubs - (Vis_Decl : Node_Id; - Asynchronous : Boolean; - Dynamically_Asynchronous : Boolean := False; - Stub_Type : Entity_Id := Empty; - RACW_Type : Entity_Id := Empty; - Parent_Primitive : Entity_Id := Empty) return Node_Id; - -- Build the receiving stub for a given subprogram. The subprogram - -- declaration is also built by this procedure, and the value returned - -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is - -- found in the specification, then its address is read from the stream - -- instead of the object itself and converted into an access to - -- class-wide type before doing the real call using any of the RACW type - -- pointing on the designated type. - - procedure Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Stream : out Entity_Id; - Result : out Entity_Id; - Subp_Id : 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 Standard.String variable that contains - -- the identifier of the desired subprogram, - -- - Stmts is the place where the request dispatching - -- statements can occur, - -- - Decl is the subprogram body declaration. + 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 @@ -249,11 +225,6 @@ package body Exp_Dist is Decls : List_Id); -- Add calling stubs to the declarative part - procedure Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id); - -- Add receiving 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). @@ -282,6 +253,13 @@ package body Exp_Dist is 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 @@ -426,7 +404,7 @@ package body Exp_Dist is function Input_With_Tag_Check (Loc : Source_Ptr; Var_Type : Entity_Id; - Stream : Entity_Id) return Node_Id; + Stream : Node_Id) return Node_Id; -- Return a function with the following form: -- function R return Var_Type is -- begin @@ -542,6 +520,42 @@ package body Exp_Dist is -- 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_Receiving_Stubs_To_Declarations + (Pkg_Spec : Node_Id; + Decls : List_Id); + -- Add receiving stubs to the declarative part + package GARLIC_Support is -- Support for generating DSA code that uses the GARLIC PCS @@ -589,12 +603,25 @@ package body Exp_Dist is Stub_Type_Decl : out Node_Id; RPC_Receiver_Decl : out Node_Id); - function Build_RPC_Receiver_Specification - (RPC_Receiver : Entity_Id; - Stream_Parameter : Entity_Id; - Result_Parameter : Entity_Id) return Node_Id; - -- Make a subprogram specification for an RPC receiver, - -- with the given defining unit name and formal parameters. + 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_Receiving_Stubs_To_Declarations + (Pkg_Spec : Node_Id; + Decls : 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; @@ -645,16 +672,32 @@ package body Exp_Dist is Stub_Type_Decl : out Node_Id; RPC_Receiver_Decl : out Node_Id); - 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 parameters. + 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; - pragma Warnings (Off); - pragma Unreferenced (Build_RPC_Receiver_Specification); - -- XXX PolyORB support is not completely included yet - pragma Warnings (On); + procedure Add_Receiving_Stubs_To_Declarations + (Pkg_Spec : Node_Id; + Decls : 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 @@ -671,7 +714,6 @@ package body Exp_Dist is -- 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; @@ -798,6 +840,7 @@ package body Exp_Dist is -- do the correct dispatching. Overload_Counter_Table.Reset; + PolyORB_Support.Reserve_NamingContext_Methods; Current_Declaration := First (Visible_Declarations (Pkg_Spec)); @@ -1065,9 +1108,9 @@ package body Exp_Dist is RPC_Receiver : Entity_Id; RPC_Receiver_Statements : List_Id; RPC_Receiver_Case_Alternatives : constant List_Id := New_List; - RPC_Receiver_Stream : Entity_Id; - RPC_Receiver_Result : Entity_Id; + RPC_Receiver_Request : Entity_Id; RPC_Receiver_Subp_Id : Entity_Id; + RPC_Receiver_Subp_Index : Entity_Id; Subp_Str : String_Id; @@ -1095,11 +1138,11 @@ package body Exp_Dist is if not Is_RAS then RPC_Receiver := Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - Build_RPC_Receiver_Body ( + Specific_Build_RPC_Receiver_Body ( RPC_Receiver => RPC_Receiver, - Stream => RPC_Receiver_Stream, - Result => RPC_Receiver_Result, + Request => RPC_Receiver_Request, Subp_Id => RPC_Receiver_Subp_Id, + Subp_Index => RPC_Receiver_Subp_Index, Stmts => RPC_Receiver_Statements, Decl => RPC_Receiver_Decl); end if; @@ -1167,7 +1210,8 @@ package body Exp_Dist is Defining_Unit_Name (Current_Primitive_Spec)), Asynchronous => Possibly_Asynchronous, Dynamically_Asynchronous => Possibly_Asynchronous, - Stub_Type => Stub_Elements.Stub_Type); + Stub_Type => Stub_Elements.Stub_Type, + RACW_Type => Stub_Elements.RACW_Type); Append_To (Decls, Current_Primitive_Body); -- Analyzing the body here would cause the Stub type to be @@ -1179,7 +1223,7 @@ package body Exp_Dist is if not Is_RAS then Current_Receiver_Body := - Build_Subprogram_Receiving_Stubs + Specific_Build_Subprogram_Receiving_Stubs (Vis_Decl => Current_Primitive_Decl, Asynchronous => Possibly_Asynchronous, Dynamically_Asynchronous => Possibly_Asynchronous, @@ -1204,8 +1248,7 @@ package body Exp_Dist is Name => New_Occurrence_Of (Current_Receiver, Loc), Parameter_Associations => New_List ( - New_Occurrence_Of (RPC_Receiver_Stream, Loc), - New_Occurrence_Of (RPC_Receiver_Result, Loc)))))); + New_Occurrence_Of (RPC_Receiver_Request, Loc)))))); end if; -- Increment the index of current primitive @@ -1228,9 +1271,11 @@ package body Exp_Dist is Append_To (RPC_Receiver_Statements, Make_Case_Statement (Loc, Expression => - New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc), + New_Occurrence_Of (RPC_Receiver_Subp_Index, Loc), Alternatives => RPC_Receiver_Case_Alternatives)); + Append_To (Decls, RPC_Receiver_Decl); + -- 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 @@ -1239,7 +1284,6 @@ package body Exp_Dist is -- RPC receiver body acts as its own declaration, and the RPC -- receiver declaration is completed by a renaming-as-body. - Append_To (Decls, RPC_Receiver_Decl); Append_To (Decls, Make_Subprogram_Renaming_Declaration (Loc, Specification => @@ -1370,12 +1414,9 @@ package body Exp_Dist is Unchecked_Convert_To (RACW_Type, New_Occurrence_Of (RAS_Parameter, Loc))); - RACW_Primitive_Name := - Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Scope (RACW_Type), Loc), - Selector_Name => - Make_Identifier (Loc, Name_Call)); + RACW_Primitive_Name := Make_Selected_Component (Loc, + Prefix => Scope (RACW_Type), + Selector_Name => Name_Call); end if; if Is_Function then @@ -1649,434 +1690,6 @@ package body Exp_Dist is Specific_Add_RAST_Features (Vis_Decl, RAS_Type, Decls); end Add_RAST_Features; - ----------------------------------------- - -- Add_Receiving_Stubs_To_Declarations -- - ----------------------------------------- - - procedure Add_Receiving_Stubs_To_Declarations - (Pkg_Spec : Node_Id; - Decls : List_Id) - is - Loc : constant Source_Ptr := Sloc (Pkg_Spec); - - Stream_Parameter : Node_Id; - Result_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 : Node_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; - - Dummy_Register_Name : Name_Id; - Dummy_Register_Spec : Node_Id; - Dummy_Register_Decl : Node_Id; - Dummy_Register_Body : Node_Id; - - All_Calls_Remote_E : Entity_Id; - Proxy_Object_Addr : Entity_Id; - - procedure Append_Stubs_To - (RPC_Receiver_Cases : List_Id; - Declaration : Node_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; - Declaration : Node_Id; - Stubs : Node_Id; - Subprogram_Number : Int) - is - Actuals : constant List_Id := - New_List (New_Occurrence_Of (Stream_Parameter, Loc)); - begin - if Nkind (Specification (Declaration)) = N_Function_Specification - or else not - Is_Asynchronous (Defining_Entity (Specification (Declaration))) - then - -- An asynchronous procedure does not want an output parameter - -- since no result and no exception will ever be returned. - - Append_To (Actuals, - New_Occurrence_Of (Result_Parameter, Loc)); - end if; - - 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 => - Actuals)))); - 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 any subprogram visible in the package - -- spec. This stub will read all the parameters from the stream, - -- and put the result as well as the exception occurrence in the - -- output stream - - -- - a dummy package with an empty spec and a body made of an - -- elaboration part, whose job is to register the receiving - -- part of this RCI package on the name server. This is done - -- by calling System.Partition_Interface.Register_Receiving_Stub - - Build_RPC_Receiver_Body ( - RPC_Receiver => Pkg_RPC_Receiver, - Stream => Stream_Parameter, - Result => Result_Parameter, - Subp_Id => Subp_Id, - Stmts => Pkg_RPC_Receiver_Statements, - Decl => Pkg_RPC_Receiver_Body); - - -- 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 ( - New_Occurrence_Of (Stream_Parameter, Loc))))), - 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))), - Subtype_Mark => - 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, - Declaration => - Current_Declaration, - 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; - - begin - pragma Assert (Current_Subprogram_Number = - Get_Subprogram_Id (Subp_Def)); - - -- Build receiving stub - - Current_Stubs := - Build_Subprogram_Receiving_Stubs - (Vis_Decl => Current_Declaration, - Asynchronous => - Nkind (Specification (Current_Declaration)) = - N_Procedure_Specification - and then Is_Asynchronous (Subp_Def)); - - Append_To (Decls, Current_Stubs); - Analyze (Current_Stubs); - - -- Build RAS proxy - - Add_RAS_Proxy_And_Analyze (Decls, - Vis_Decl => - Current_Declaration, - All_Calls_Remote_E => - All_Calls_Remote_E, - Proxy_Object_Addr => - Proxy_Object_Addr); - - -- Compute distribution identifier - - Assign_Subprogram_Identifier ( - Subp_Def, - Current_Subprogram_Number, - Subp_Val); - - -- Add subprogram descriptor (RCI_Subp_Info) to the - -- subprograms table for this receiver. The aggregate - -- below must be kept consistent with the declaration - -- of type RCI_Subp_Info in System.Partition_Interface. - - Append_To (Subp_Info_List, - Make_Component_Association (Loc, - Choices => New_List ( - Make_Integer_Literal (Loc, - Current_Subprogram_Number)), - Expression => - Make_Aggregate (Loc, - Component_Associations => New_List ( - Make_Component_Association (Loc, - Choices => New_List ( - Make_Identifier (Loc, Name_Addr)), - Expression => - New_Occurrence_Of (Proxy_Object_Addr, Loc)))))); - - Append_Stubs_To (Pkg_RPC_Receiver_Cases, - Declaration => - Current_Declaration, - 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, - First_RCI_Subprogram_Id - + List_Length (Subp_Info_List) - 1))))), - Expression => - Make_Aggregate (Loc, - Component_Associations => Subp_Info_List))); - Analyze (Last (Decls)); - - Append_To (Decls, - Make_Subprogram_Body (Loc, - Specification => - Copy_Specification (Loc, Parent (Lookup_RAS_Info)), - Declarations => - No_List, - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List ( - Make_Return_Statement (Loc, - Expression => OK_Convert_To (RTE (RE_Unsigned_64), - Make_Selected_Component (Loc, - Prefix => - Make_Indexed_Component (Loc, - Prefix => - New_Occurrence_Of (Subp_Info_Array, Loc), - Expressions => New_List ( - Convert_To (Standard_Integer, - Make_Identifier (Loc, Name_Subp_Id)))), - Selector_Name => - Make_Identifier (Loc, Name_Addr)))))))); - Analyze (Last (Decls)); - - Append_To (Decls, Pkg_RPC_Receiver_Body); - Analyze (Last (Decls)); - - -- Construction of the dummy package used to register the package - -- receiving stubs on the nameserver. - - Dummy_Register_Name := New_Internal_Name ('P'); - - Dummy_Register_Spec := - Make_Package_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, Dummy_Register_Name), - Visible_Declarations => No_List, - End_Label => Empty); - - Dummy_Register_Decl := - Make_Package_Declaration (Loc, - Specification => Dummy_Register_Spec); - - Append_To (Decls, Dummy_Register_Decl); - Analyze (Dummy_Register_Decl); - - Get_Library_Unit_Name_String (Pkg_Spec); - Append_To (Register_Pkg_Actuals, - -- Name - Make_String_Literal (Loc, - Strval => String_From_Name_Buffer)); - - Append_To (Register_Pkg_Actuals, - -- Receiver - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Pkg_RPC_Receiver, Loc), - Attribute_Name => - Name_Unrestricted_Access)); - - Append_To (Register_Pkg_Actuals, - -- Version - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc), - Attribute_Name => - Name_Version)); - - Append_To (Register_Pkg_Actuals, - -- Subp_Info - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Subp_Info_Array, Loc), - Attribute_Name => - Name_Address)); - - Append_To (Register_Pkg_Actuals, - -- Subp_Info_Len - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Subp_Info_Array, Loc), - Attribute_Name => - Name_Length)); - - Dummy_Register_Body := - Make_Package_Body (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, Dummy_Register_Name), - Declarations => No_List, - - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc), - - Parameter_Associations => Register_Pkg_Actuals)))); - - Append_To (Decls, Dummy_Register_Body); - Analyze (Dummy_Register_Body); - end Add_Receiving_Stubs_To_Declarations; - ------------------- -- Add_Stub_Type -- ------------------- @@ -2328,6 +1941,26 @@ package body Exp_Dist is 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 -- ---------------------------------------- @@ -2346,86 +1979,37 @@ package body Exp_Dist is Component_Items => New_List ( Make_Component_Declaration (Loc, - Make_Defining_Identifier (Loc, - Name_All_Calls_Remote), - Make_Component_Definition (Loc, - Subtype_Indication => - New_Occurrence_Of (Standard_Boolean, Loc)), - ACR_Expression), + 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, - Make_Defining_Identifier (Loc, - Name_Receiver), - Make_Component_Definition (Loc, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Address), Loc)), - New_Occurrence_Of (RTE (RE_Null_Address), 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, - Make_Defining_Identifier (Loc, - Name_Subp_Id), - Make_Component_Definition (Loc, - Subtype_Indication => - New_Occurrence_Of (RTE (RE_Subprogram_Id), 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_RPC_Receiver_Body -- - ----------------------------- - - procedure Build_RPC_Receiver_Body - (RPC_Receiver : Entity_Id; - Stream : out Entity_Id; - Result : out Entity_Id; - Subp_Id : 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 - Stream := Make_Defining_Identifier (Loc, Name_S); - Result := Make_Defining_Identifier (Loc, Name_R); - - RPC_Receiver_Spec := - GARLIC_Support.Build_RPC_Receiver_Specification - (RPC_Receiver => RPC_Receiver, - Stream_Parameter => Stream, - Result_Parameter => Result); - - Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - - -- 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 ( - New_Occurrence_Of (Stream, Loc))))); - - 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_Calling_Stubs -- ------------------------------------ @@ -2541,12 +2125,9 @@ package body Exp_Dist is pragma Assert (No (Stub_Type) or else Present (Controlling_Parameter)); if Dynamically_Asynchronous then - Asynchronous_Expr := - Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Controlling_Parameter, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Asynchronous)); + Asynchronous_Expr := Make_Selected_Component (Loc, + Prefix => Controlling_Parameter, + Selector_Name => Name_Asynchronous); end if; Specific_Build_General_Calling_Stubs @@ -2592,457 +2173,6 @@ package body Exp_Dist is return Make_Integer_Literal (Loc, Get_Subprogram_Id (E)); end Build_Subprogram_Id; - -------------------------------------- - -- 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); - - Stream_Parameter : Node_Id; - Result_Parameter : Node_Id; - -- See explanations of these in Build_Subprogram_Calling_Stubs - - 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; - - Stream_Parameter := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - - if Dynamically_Asynchronous then - Dynamic_Async := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - else - Dynamic_Async := Empty; - end if; - - if not Asynchronous or else Dynamically_Asynchronous then - Result_Parameter := - Make_Defining_Identifier (Loc, New_Internal_Name ('S')); - - -- The first statement after the subprogram call is a statement to - -- writes 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 ( - New_Occurrence_Of (Result_Parameter, Loc), - 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); - - else - Result_Parameter := Empty; - 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; - RACW_Controlling : Boolean; - Constrained : Boolean; - Object : Entity_Id; - Expr : Node_Id := Empty; - - begin - Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P')); - Set_Ekind (Object, E_Variable); - - RACW_Controlling := - Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type); - - if RACW_Controlling 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 := - Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp); - - if In_Present (Current_Parameter) - or else not Out_Present (Current_Parameter) - or else not Constrained - or else RACW_Controlling - then - -- If an input parameter is contrained, then its reading is - -- deferred until the beginning of the subprogram body. If - -- it is unconstrained, then an expression is built for - -- the object declaration and the variable is set using - -- 'Input instead of 'Read. - - if Constrained and then not RACW_Controlling then - Append_To (Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Name_Read, - Expressions => New_List ( - New_Occurrence_Of (Stream_Parameter, Loc), - New_Occurrence_Of (Object, Loc)))); - - else - Expr := Input_With_Tag_Check (Loc, - Var_Type => Etyp, - Stream => Stream_Parameter); - Append_To (Decls, Expr); - Expr := Make_Function_Call (Loc, - New_Occurrence_Of (Defining_Unit_Name - (Specification (Expr)), Loc)); - end if; - end if; - - -- If we do not have to output the current parameter, then - -- it can well be flagged as constant. This may allow further - -- optimizations done by the back end. - - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Object, - Constant_Present => - not Constrained and then not Out_Present (Current_Parameter), - Object_Definition => - New_Occurrence_Of (Etyp, Loc), - Expression => Expr)); - - -- An out parameter may be written back using a 'Write - -- attribute instead of a 'Output because it has been - -- constrained by the parameter given to the caller. Note that - -- out controlling arguments in the case of a RACW are not put - -- back in the stream because the pointer on them has not - -- changed. - - if Out_Present (Current_Parameter) - and then - Etype (Parameter_Type (Current_Parameter)) /= Stub_Type - then - Append_To (After_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Name_Write, - Expressions => New_List ( - New_Occurrence_Of (Result_Parameter, Loc), - New_Occurrence_Of (Object, Loc)))); - end if; - - if - Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) - 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 Nkind (Parameter_Type (Current_Parameter)) /= - N_Access_Definition - and then - Ekind (Defining_Identifier (Current_Parameter)) /= E_Void - and then - Present (Extra_Constrained - (Defining_Identifier (Current_Parameter))) - then - declare - Extra_Parameter : constant Entity_Id := - Extra_Constrained - (Defining_Identifier - (Current_Parameter)); - - 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 ( - New_Occurrence_Of (Stream_Parameter, Loc), - New_Occurrence_Of (Formal_Entity, Loc)))); - Set_Extra_Constrained (Object, Formal_Entity); - end; - end if; - end; - - Next (Current_Parameter); - end loop; - - -- Append the formal statements list at the end of regular statements - - 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 (Subtype_Mark (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))); - - Append_To (After_Statements, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Etyp, Loc), - Attribute_Name => Name_Output, - Expressions => New_List ( - New_Occurrence_Of (Result_Parameter, Loc), - New_Occurrence_Of (Result, Loc)))); - end; - - Append_To (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 ( - New_Occurrence_Of (Stream_Parameter, Loc), - 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 - - -- An asynchronous procedure does not want a Result parameter. Also - -- put an exception handler with an others clause that does nothing. - - Subp_Spec := - Make_Procedure_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, New_Internal_Name ('F')), - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Stream_Parameter, - Parameter_Type => - Make_Access_Definition (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))))); - - Excep_Handlers := New_List ( - Make_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 ( - New_Occurrence_Of (Result_Parameter, Loc), - 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_Exception_Handler (Loc, - Choice_Parameter => Excep_Choice, - Exception_Choices => New_List (Make_Others_Choice (Loc)), - Statements => Excep_Code)); - - Subp_Spec := - Make_Procedure_Specification (Loc, - Defining_Unit_Name => - Make_Defining_Identifier (Loc, New_Internal_Name ('F')), - - Parameter_Specifications => New_List ( - Make_Parameter_Specification (Loc, - Defining_Identifier => Stream_Parameter, - Parameter_Type => - Make_Access_Definition (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))), - - Make_Parameter_Specification (Loc, - Defining_Identifier => Result_Parameter, - Parameter_Type => - Make_Access_Definition (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))))); - end if; - - 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; - ------------------------ -- Copy_Specification -- ------------------------ @@ -3124,6 +2254,20 @@ package body Exp_Dist is 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; @@ -3300,7 +2444,7 @@ package body Exp_Dist is Spec := Specification (Unit_Node); Decls := Visible_Declarations (Spec); New_Scope (Scope_Of_Spec (Spec)); - Add_Receiving_Stubs_To_Declarations (Spec, Decls); + Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls); else Spec := @@ -3308,7 +2452,7 @@ package body Exp_Dist is Decls := Declarations (Unit_Node); New_Scope (Scope_Of_Spec (Unit_Node)); Temp := New_List; - Add_Receiving_Stubs_To_Declarations (Spec, Temp); + Specific_Add_Receiving_Stubs_To_Declarations (Spec, Temp); Insert_List_Before (First (Decls), Temp); end if; @@ -3547,30 +2691,30 @@ package body Exp_Dist is Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Origin)), + Prefix => Stubbed_Result, + Selector_Name => Name_Origin), Expression => New_Occurrence_Of (Source_Partition, Loc)), Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Receiver)), + Prefix => Stubbed_Result, + Selector_Name => Name_Receiver), Expression => New_Occurrence_Of (Source_Receiver, Loc)), Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Addr)), + 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 => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Asynchronous)), + Prefix => Stubbed_Result, + Selector_Name => Name_Asynchronous), Expression => New_Occurrence_Of (Asynchronous_Flag, Loc))); @@ -3867,8 +3011,8 @@ package body Exp_Dist is Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stub_Ptr, Loc), - Selector_Name => Make_Identifier (Loc, Field_Name)), + Prefix => Stub_Ptr, + Selector_Name => Field_Name), Expression => Value); end Set_Field; @@ -4059,6 +3203,384 @@ package body Exp_Dist is 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) + 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 any subprogram visible in the package + -- spec. This stub will read all the parameters from the stream, + -- and put the result as well as the exception occurrence in the + -- output stream + + -- - a dummy package with an empty spec and a body made of an + -- elaboration part, whose job is to register the receiving + -- part of this RCI package on the name server. This is done + -- by calling System.Partition_Interface.Register_Receiving_Stub + + 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))), + Subtype_Mark => + 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; + + begin + pragma Assert (Current_Subprogram_Number = + Get_Subprogram_Id (Subp_Def)); + + -- Build receiving stub + + Current_Stubs := + Build_Subprogram_Receiving_Stubs + (Vis_Decl => Current_Declaration, + Asynchronous => + Nkind (Specification (Current_Declaration)) = + N_Procedure_Specification + and then Is_Asynchronous (Subp_Def)); + + Append_To (Decls, Current_Stubs); + Analyze (Current_Stubs); + + -- Build RAS proxy + + Add_RAS_Proxy_And_Analyze (Decls, + Vis_Decl => + Current_Declaration, + All_Calls_Remote_E => + All_Calls_Remote_E, + Proxy_Object_Addr => + Proxy_Object_Addr); + + -- Compute distribution identifier + + Assign_Subprogram_Identifier ( + Subp_Def, + Current_Subprogram_Number, + Subp_Val); + + -- Add subprogram descriptor (RCI_Subp_Info) to the + -- subprograms table for this receiver. The aggregate + -- below must be kept consistent with the declaration + -- of type RCI_Subp_Info in System.Partition_Interface. + + Append_To (Subp_Info_List, + Make_Component_Association (Loc, + Choices => New_List ( + Make_Integer_Literal (Loc, + Current_Subprogram_Number)), + Expression => + Make_Aggregate (Loc, + Component_Associations => New_List ( + Make_Component_Association (Loc, + Choices => New_List ( + Make_Identifier (Loc, Name_Addr)), + Expression => + New_Occurrence_Of ( + Proxy_Object_Addr, Loc)))))); + + Append_Stubs_To (Pkg_RPC_Receiver_Cases, + Stubs => + Current_Stubs, + Subprogram_Number => + Current_Subprogram_Number); + end; + + Current_Subprogram_Number := Current_Subprogram_Number + 1; + end if; + + Next (Current_Declaration); + end loop; + + -- 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, + First_RCI_Subprogram_Id + + List_Length (Subp_Info_List) - 1))))), + Expression => + Make_Aggregate (Loc, + Component_Associations => Subp_Info_List))); + Analyze (Last (Decls)); + + Append_To (Decls, + Make_Subprogram_Body (Loc, + Specification => + Copy_Specification (Loc, Parent (Lookup_RAS_Info)), + Declarations => + No_List, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => New_List ( + Make_Return_Statement (Loc, + Expression => OK_Convert_To (RTE (RE_Unsigned_64), + Make_Selected_Component (Loc, + Prefix => + Make_Indexed_Component (Loc, + Prefix => + New_Occurrence_Of (Subp_Info_Array, Loc), + Expressions => New_List ( + Convert_To (Standard_Integer, + Make_Identifier (Loc, Name_Subp_Id)))), + Selector_Name => + Make_Identifier (Loc, Name_Addr)))))))); + Analyze (Last (Decls)); + + Append_To (Decls, Pkg_RPC_Receiver_Body); + Analyze (Last (Decls)); + + Get_Library_Unit_Name_String (Pkg_Spec); + Append_To (Register_Pkg_Actuals, + -- Name + Make_String_Literal (Loc, + Strval => String_From_Name_Buffer)); + + Append_To (Register_Pkg_Actuals, + -- Receiver + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Pkg_RPC_Receiver, Loc), + Attribute_Name => + Name_Unrestricted_Access)); + + Append_To (Register_Pkg_Actuals, + -- Version + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc), + Attribute_Name => + Name_Version)); + + Append_To (Register_Pkg_Actuals, + -- Subp_Info + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Subp_Info_Array, Loc), + Attribute_Name => + Name_Address)); + + Append_To (Register_Pkg_Actuals, + -- Subp_Info_Len + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Subp_Info_Array, Loc), + Attribute_Name => + Name_Length)); + + Append_To (Decls, + Make_Procedure_Call_Statement (Loc, + Name => + New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc), + Parameter_Associations => Register_Pkg_Actuals)); + Analyze (Last (Decls)); + end Add_Receiving_Stubs_To_Declarations; + --------------------------------- -- Build_General_Calling_Stubs -- --------------------------------- @@ -4230,10 +3752,8 @@ package body Exp_Dist is Object => Make_Selected_Component (Loc, Prefix => - New_Occurrence_Of ( - Defining_Identifier (Current_Parameter), Loc), - Selector_Name => - Make_Identifier (Loc, Name_Addr)), + Defining_Identifier (Current_Parameter), + Selector_Name => Name_Addr), Etyp => RTE (RE_Unsigned_64))); else @@ -4510,6 +4030,64 @@ package body Exp_Dist is 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 -- ----------------------- @@ -4534,17 +4112,13 @@ package body Exp_Dist is Expression => Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Controlling_Parameter, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Origin)))); + Prefix => Controlling_Parameter, + Selector_Name => Name_Origin))); Target_Info.RPC_Receiver := Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Controlling_Parameter, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Receiver)); + Prefix => Controlling_Parameter, + Selector_Name => Name_Receiver); else Append_To (Decls, @@ -4640,53 +4214,463 @@ package body Exp_Dist is RPC_Receiver_Decl := Empty; else declare - RPC_Receiver_Stream : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_S); - RPC_Receiver_Result : constant Entity_Id := - Make_Defining_Identifier (Loc, Name_R); + 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')), - Stream_Parameter => RPC_Receiver_Stream, - Result_Parameter => RPC_Receiver_Result)); + RPC_Receiver => Make_Defining_Identifier (Loc, + New_Internal_Name ('R')), + Request_Parameter => RPC_Receiver_Request)); end; end if; end Build_Stub_Type; -------------------------------------- - -- Build_RPC_Receiver_Specification -- + -- Build_Subprogram_Receiving_Stubs -- -------------------------------------- - function Build_RPC_Receiver_Specification - (RPC_Receiver : Entity_Id; - Stream_Parameter : Entity_Id; - Result_Parameter : Entity_Id) return Node_Id + function Build_Subprogram_Receiving_Stubs + (Vis_Decl : Node_Id; + Asynchronous : Boolean; + Dynamically_Asynchronous : Boolean := False; + Stub_Type : Entity_Id := Empty; + RACW_Type : Entity_Id := Empty; + Parent_Primitive : Entity_Id := Empty) return Node_Id is - Loc : constant Source_Ptr := Sloc (RPC_Receiver); + Loc : constant Source_Ptr := Sloc (Vis_Decl); + + Request_Parameter : Node_Id; + -- ??? + + 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 - return + 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; + + Request_Parameter := + Make_Defining_Identifier (Loc, New_Internal_Name ('R')); + + 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 + -- writes 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; + + 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 + Set_Ekind (Object, E_Variable); + + 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 := + Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp); + + if In_Present (Current_Parameter) + or else not Out_Present (Current_Parameter) + or else not Constrained + or else Is_Controlling_Formal + then + -- If an input parameter is contrained, then its reading is + -- deferred until the beginning of the subprogram body. If + -- it is unconstrained, then an expression is built for + -- the object declaration and the variable is set using + -- 'Input instead of 'Read. + + if Constrained and then not Is_Controlling_Formal 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 + Expr := Input_With_Tag_Check (Loc, + Var_Type => Etyp, + Stream => Make_Selected_Component (Loc, + Prefix => Request_Parameter, + Selector_Name => Name_Params)); + Append_To (Decls, Expr); + Expr := Make_Function_Call (Loc, + New_Occurrence_Of (Defining_Unit_Name + (Specification (Expr)), Loc)); + end if; + end if; + + -- If we do not have to output the current parameter, then it + -- can well be flagged as constant. This may allow further + -- optimizations done by the back end. + + Append_To (Decls, + Make_Object_Declaration (Loc, + Defining_Identifier => Object, + Constant_Present => not Constrained + and then not Out_Present (Current_Parameter), + Object_Definition => + New_Occurrence_Of (Etyp, Loc), + Expression => Expr)); + + -- 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 Nkind (Parameter_Type (Current_Parameter)) /= + N_Access_Definition + and then + Ekind (Defining_Identifier (Current_Parameter)) /= E_Void + and then + Present (Extra_Constrained + (Defining_Identifier (Current_Parameter))) + then + declare + Extra_Parameter : constant Entity_Id := + Extra_Constrained + (Defining_Identifier + (Current_Parameter)); + + 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)))); + 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 (Subtype_Mark (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))); + + 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_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_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 => RPC_Receiver, + Defining_Unit_Name => + Make_Defining_Identifier (Loc, New_Internal_Name ('F')), + Parameter_Specifications => New_List ( Make_Parameter_Specification (Loc, - Defining_Identifier => Stream_Parameter, + Defining_Identifier => Request_Parameter, Parameter_Type => - Make_Access_Definition (Loc, - Subtype_Mark => - New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))), + New_Occurrence_Of (RTE (RE_Request_Access), Loc)))); - Make_Parameter_Specification (Loc, - Defining_Identifier => Result_Parameter, - Parameter_Type => - Make_Access_Definition (Loc, - Subtype_Mark => - New_Occurrence_Of - (RTE (RE_Params_Stream_Type), Loc))))); - end Build_RPC_Receiver_Specification; + 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 -- @@ -4708,6 +4692,21 @@ package body Exp_Dist is end GARLIC_Support; + ----------------------------- + -- 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; + ------------------ -- Get_PCS_Name -- ------------------ @@ -4816,7 +4815,7 @@ package body Exp_Dist is function Input_With_Tag_Check (Loc : Source_Ptr; Var_Type : Entity_Id; - Stream : Entity_Id) return Node_Id + Stream : Node_Id) return Node_Id is begin return @@ -4834,7 +4833,7 @@ package body Exp_Dist is Prefix => New_Occurrence_Of (Var_Type, Loc), Attribute_Name => Name_Input, Expressions => - New_List (New_Occurrence_Of (Stream, Loc)))))))); + New_List (Stream))))))); end Input_With_Tag_Check; -------------------------------- @@ -5238,8 +5237,8 @@ package body Exp_Dist is Stub_Statements := New_List ( Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Target)), + Prefix => Stubbed_Result, + Selector_Name => Name_Target), Expression => Make_Function_Call (Loc, Name => @@ -5252,13 +5251,13 @@ package body Exp_Dist is New_Occurrence_Of (RTE (RE_Inc_Usage), Loc), Parameter_Associations => New_List ( Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Target)))), + Prefix => Stubbed_Result, + Selector_Name => Name_Target))), Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stubbed_Result, Loc), - Selector_Name => Make_Identifier (Loc, Name_Asynchronous)), + Prefix => Stubbed_Result, + Selector_Name => Name_Asynchronous), Expression => New_Occurrence_Of (Asynchronous_Flag, Loc))); @@ -5618,11 +5617,9 @@ package body Exp_Dist is New_Occurrence_Of (Any, Loc), Make_Selected_Component (Loc, Prefix => - New_Occurrence_Of ( Defining_Identifier ( - Stub_Elements.RPC_Receiver_Decl), Loc), - Selector_Name => - Make_Identifier (Loc, Name_Obj_TypeCode)))), + Stub_Elements.RPC_Receiver_Decl), + Selector_Name => Name_Obj_TypeCode))), Make_Return_Statement (Loc, Expression => New_Occurrence_Of (Any, Loc))); @@ -5727,11 +5724,9 @@ package body Exp_Dist is Expression => Make_Selected_Component (Loc, Prefix => - New_Occurrence_Of ( Defining_Identifier ( - Stub_Elements.RPC_Receiver_Decl), Loc), - Selector_Name => - Make_Identifier (Loc, Name_Obj_TypeCode)))))); + Stub_Elements.RPC_Receiver_Decl), + Selector_Name => Name_Obj_TypeCode))))); Insert_After (Declaration_Node (RACW_Type), Func_Decl); Append_To (Declarations, Func_Body); @@ -5949,8 +5944,8 @@ package body Exp_Dist is Make_Assignment_Statement (Loc, Name => Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stub_Ptr, Loc), - Selector_Name => Make_Identifier (Loc, Field_Name)), + Prefix => Stub_Ptr, + Selector_Name => Field_Name), Expression => Value); end Set_Field; @@ -6113,8 +6108,8 @@ package body Exp_Dist is New_Occurrence_Of (RTE (RE_Inc_Usage), Loc), Parameter_Associations => New_List ( Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Stub_Ptr, Loc), - Selector_Name => Make_Identifier (Loc, Name_Target)))), + 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 @@ -6280,10 +6275,8 @@ package body Exp_Dist is Chars => New_Internal_Name ('R')); RACW_Parameter : constant Node_Id := Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (RAS_Parameter, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Ras)); + Prefix => RAS_Parameter, + Selector_Name => Name_Ras); begin -- Object declarations @@ -6436,6 +6429,473 @@ package body Exp_Dist is Set_Renaming_TSS (RAS_Type, Fnam, Name_uTypeCode); end Add_RAS_TypeCode; + ----------------------------------------- + -- Add_Receiving_Stubs_To_Declarations -- + ----------------------------------------- + + procedure Add_Receiving_Stubs_To_Declarations + (Pkg_Spec : Node_Id; + Decls : 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, New_Internal_Name ('L')); + Local_Address : constant Entity_Id := + Make_Defining_Identifier (Loc, New_Internal_Name ('A')); + -- Address of a local subprogram designated by a + -- reference corresponding to a RAS. + + 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_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 any subprogram visible in the package + -- spec. This stub will read all the parameters from the stream, + -- and put the result as well as the exception occurrence in the + -- output stream + + -- - a dummy package with an empty spec and a body made of an + -- elaboration part, whose job is to register the receiving + -- part of this RCI package on the name server. This is done + -- by calling System.Partition_Interface.Register_Receiving_Stub + + 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)))); + + -- Determine whether the reference that was used to make + -- the call was the base RCI reference (in which case + -- Local_Address is 0, and the method identifier from the + -- request must be used to determine which subprogram is + -- called) or a reference identifying one particular subprogram + -- (in which case Local_Address is the address of that + -- subprogram, and the method name from the request is + -- ignored). + -- In each case, cascaded elsifs are used to determine the + -- proper subprogram index. Using hash tables might be + -- more efficient. + + Append_To (Pkg_RPC_Receiver_Statements, + Make_Implicit_If_Statement (Pkg_Spec, + Condition => + Make_Op_Ne (Loc, + Left_Opnd => New_Occurrence_Of (Local_Address, Loc), + Right_Opnd => New_Occurrence_Of (RTE (RE_Null_Address), Loc)), + Then_Statements => New_List ( + Make_Implicit_If_Statement (Pkg_Spec, + Condition => + New_Occurrence_Of (Standard_False, Loc), + Then_Statements => New_List ( + Make_Null_Statement (Loc)), + Elsif_Parts => + Dispatch_On_Address)), + Else_Statements => New_List ( + Make_Implicit_If_Statement (Pkg_Spec, + Condition => + New_Occurrence_Of (Standard_False, Loc), + Then_Statements => New_List ( + Make_Null_Statement (Loc)), + Elsif_Parts => + Dispatch_On_Name)))); + + -- For each subprogram, the receiving stub will be built and a + -- case statement will be made on the Subprogram_Id to dispatch + -- to the right subprogram. + + All_Calls_Remote_E := Boolean_Literals ( + Has_All_Calls_Remote (Defining_Entity (Pkg_Spec))); + + Overload_Counter_Table.Reset; + Reserve_NamingContext_Methods; + + Current_Declaration := First (Visible_Declarations (Pkg_Spec)); + while Present (Current_Declaration) loop + if Nkind (Current_Declaration) = N_Subprogram_Declaration + and then Comes_From_Source (Current_Declaration) + then + declare + Loc : constant Source_Ptr := + Sloc (Current_Declaration); + -- While specifically processing Current_Declaration, use + -- its Sloc as the location of all generated nodes. + + Subp_Def : constant Entity_Id := + Defining_Unit_Name + (Specification (Current_Declaration)); + + Subp_Val : String_Id; + + Subp_Dist_Name : constant Entity_Id := + Make_Defining_Identifier (Loc, + New_External_Name ( + Related_Id => Chars (Subp_Def), + Suffix => 'D', + Suffix_Index => -1)); + + Proxy_Object_Addr : Entity_Id; + + begin + pragma Assert (Current_Subprogram_Number = + Get_Subprogram_Id (Subp_Def)); + + -- 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); + + 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; + + -- 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)); + + Append_To (Decls, + Make_Object_Declaration (Loc, + Defining_Identifier => Subp_Info_Array, + Constant_Present => True, + Aliased_Present => True, + Object_Definition => + Make_Subtype_Indication (Loc, + Subtype_Mark => + New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc), + Constraint => + Make_Index_Or_Discriminant_Constraint (Loc, + New_List ( + Make_Range (Loc, + Low_Bound => Make_Integer_Literal (Loc, + First_RCI_Subprogram_Id), + High_Bound => + Make_Integer_Literal (Loc, + First_RCI_Subprogram_Id + + List_Length (Subp_Info_List) - 1))))), + Expression => + Make_Aggregate (Loc, + Component_Associations => Subp_Info_List))); + Analyze (Last (Decls)); + + 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); + Append_To (Register_Pkg_Actuals, + -- Name + Make_String_Literal (Loc, + Strval => String_From_Name_Buffer)); + + Append_To (Register_Pkg_Actuals, + -- Version + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of + (Defining_Entity (Pkg_Spec), Loc), + Attribute_Name => + Name_Version)); + + Append_To (Register_Pkg_Actuals, + -- Handler + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Pkg_RPC_Receiver, Loc), + Attribute_Name => Name_Access)); + + Append_To (Register_Pkg_Actuals, + -- Receiver + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of ( + Defining_Identifier ( + Pkg_RPC_Receiver_Object), Loc), + Attribute_Name => + Name_Access)); + + Append_To (Register_Pkg_Actuals, + -- Subp_Info + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Subp_Info_Array, Loc), + Attribute_Name => + Name_Address)); + + Append_To (Register_Pkg_Actuals, + -- Subp_Info_Len + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Subp_Info_Array, Loc), + Attribute_Name => + Name_Length)); + + Append_To (Register_Pkg_Actuals, + -- Is_All_Calls_Remote + New_Occurrence_Of (All_Calls_Remote_E, Loc)); + + Append_To (Decls, + Make_Procedure_Call_Statement (Loc, + Name => + New_Occurrence_Of (RTE (RE_Register_Pkg_Receiving_Stub), Loc), + Parameter_Associations => Register_Pkg_Actuals)); + Analyze (Last (Decls)); + + end Add_Receiving_Stubs_To_Declarations; + --------------------------------- -- Build_General_Calling_Stubs -- --------------------------------- @@ -6461,7 +6921,7 @@ package body Exp_Dist is -- to the remote package Request : Node_Id; - -- The request object constructed by these stubs. + -- The request object constructed by these stubs Result : Node_Id; -- Name of the result named value (in non-APC cases) which get the @@ -6497,7 +6957,7 @@ package body Exp_Dist is -- in out or out parameter values). Etyp : Entity_Id; - -- The type of the formal parameter being processed. + -- The type of the formal parameter being processed Is_Controlling_Formal : Boolean; Is_First_Controlling_Formal : Boolean; @@ -6822,10 +7282,8 @@ package body Exp_Dist is PolyORB_Support.Helpers.Build_From_Any_Call ( Etype (Subtype_Mark (Spec)), Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Result, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Argument)), + Prefix => Result, + Selector_Name => Name_Argument), Decls)))); end if; end if; @@ -6876,10 +7334,8 @@ package body Exp_Dist is New_Occurrence_Of (RTE (RE_Make_Ref), Loc), Parameter_Associations => New_List ( Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Controlling_Parameter, Loc), - Selector_Name => - Make_Identifier (Loc, Name_Target)))))); + Prefix => Controlling_Parameter, + Selector_Name => Name_Target))))); -- Controlling_Parameter has the same components -- as System.Partition_Interface.RACW_Stub_Type. @@ -6952,28 +7408,563 @@ package body Exp_Dist is 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_RPC_Receiver_Specification -- + -- Build_Subprogram_Receiving_Stubs -- -------------------------------------- - function Build_RPC_Receiver_Specification - (RPC_Receiver : Entity_Id; - Request_Parameter : Entity_Id) return Node_Id + function Build_Subprogram_Receiving_Stubs + (Vis_Decl : Node_Id; + Asynchronous : Boolean; + Dynamically_Asynchronous : Boolean := False; + Stub_Type : Entity_Id := Empty; + RACW_Type : Entity_Id := Empty; + Parent_Primitive : Entity_Id := Empty) return Node_Id is - Loc : constant Source_Ptr := Sloc (RPC_Receiver); + Loc : constant Source_Ptr := Sloc (Vis_Decl); + + Request_Parameter : Node_Id; + -- ??? + + 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. + + 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; + + 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; + + 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 : Node_Id; + -- 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 - return + 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; + + Request_Parameter := + Make_Defining_Identifier (Loc, New_Internal_Name ('R')); + + Arguments := + Make_Defining_Identifier (Loc, New_Internal_Name ('A')); + Declare_Create_NVList (Loc, Arguments, Outer_Decls, Outer_Statements); + + -- Loop through every parameter and get its value from the stream. If + -- 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, + 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; + begin + Set_Ekind (Object, E_Variable); + + 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, + 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, + New_Internal_Name ('A')); + Is_Local : constant Entity_Id := + Make_Defining_Identifier (Loc, + 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 contrained, then its reading is + -- deferred until the beginning of the subprogram body. If + -- it is unconstrained, then an expression is built for + -- the object declaration and the variable is set using + -- 'Input instead of 'Read. + + 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; + + -- If we do not have to output the current parameter, then + -- it can well be flagged as constant. This may allow further + -- optimizations done by the back end. + + Append_To (Decls, + Make_Object_Declaration (Loc, + Defining_Identifier => Object, + Constant_Present => not Constrained + and then not Out_Present (Current_Parameter), + Object_Definition => + New_Occurrence_Of (Etyp, Loc), + Expression => Expr)); + 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_Copy_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, + 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 Nkind (Parameter_Type (Current_Parameter)) /= + N_Access_Definition + and then + Ekind (Defining_Identifier (Current_Parameter)) /= E_Void + and then + Present (Extra_Constrained + (Defining_Identifier (Current_Parameter))) + then + declare + Extra_Parameter : constant Entity_Id := + Extra_Constrained + (Defining_Identifier + (Current_Parameter)); + Extra_Any : constant Entity_Id := + Make_Defining_Identifier + (Loc, New_Internal_Name ('A')); + Formal_Entity : constant Entity_Id := + Make_Defining_Identifier + (Loc, 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))); + + Append_To (Outer_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 (Extra_Formal_Statements, + Make_Assignment_Statement (Loc, + Name => + New_Occurrence_Of (Extra_Parameter, Loc), + Expression => + PolyORB_Support.Helpers.Build_From_Any_Call ( + Etype (Extra_Parameter), + New_Occurrence_Of (Extra_Any, Loc), + Decls))); + Set_Extra_Constrained (Object, Formal_Entity); + + end; + end if; + end; + + Next (Current_Parameter); + end loop; + + 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)))); + + 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 (Subtype_Mark (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))); + + 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 => RPC_Receiver, + 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)))); - end Build_RPC_Receiver_Specification; + 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_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 -- ------------- @@ -7402,11 +8393,9 @@ package body Exp_Dist is Make_Case_Statement (Loc, Expression => Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Rec, Loc), + Prefix => Rec, Selector_Name => - New_Occurrence_Of ( - Entity (Name (Field)), Loc)), + Chars (Name (Field))), Alternatives => Alt_List)); @@ -8116,7 +9105,7 @@ package body Exp_Dist is -- A regular component Field_Ref := Make_Selected_Component (Loc, - Prefix => New_Occurrence_Of (Rec, Loc), + Prefix => New_Occurrence_Of (Rec, Loc), Selector_Name => New_Occurrence_Of (Field, Loc)); Set_Etype (Field_Ref, Etype (Field)); @@ -8165,11 +9154,9 @@ package body Exp_Dist is is Nod : constant Node_Id := Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Rec, Loc), + Prefix => Rec, Selector_Name => - New_Occurrence_Of ( - Entity (Name (Field)), Loc)); + Chars (Name (Field))); begin Set_Etype (Nod, Name (Field)); return Nod; @@ -8305,10 +9292,8 @@ package body Exp_Dist is Expression => Build_To_Any_Call ( Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of (Expr_Parameter, Loc), - Selector_Name => - New_Occurrence_Of (Disc, Loc)), + Prefix => Expr_Parameter, + Selector_Name => Chars (Disc)), Decls))); Counter := Counter + 1; Next_Discriminant (Disc); @@ -9551,6 +10536,19 @@ package body Exp_Dist is end if; end Make_Stream_Procedure_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; ------------------------------- @@ -9719,6 +10717,25 @@ package body Exp_Dist is 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) + is + begin + case Get_PCS_Name is + when Name_PolyORB_DSA => + PolyORB_Support.Add_Receiving_Stubs_To_Declarations ( + Pkg_Spec, Decls); + when others => + GARLIC_Support.Add_Receiving_Stubs_To_Declarations ( + Pkg_Spec, Decls); + end case; + end Specific_Add_Receiving_Stubs_To_Declarations; + ------------------------------------------ -- Specific_Build_General_Calling_Stubs -- ------------------------------------------ @@ -9771,6 +10788,39 @@ package body Exp_Dist is 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 -- -------------------------------- @@ -9814,6 +10864,34 @@ package body Exp_Dist is 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; + -------------------------- -- Underlying_RACW_Type -- -------------------------- |