1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Einfo; use Einfo;
29 with Elists; use Elists;
30 with Exp_Strm; use Exp_Strm;
31 with Exp_Tss; use Exp_Tss;
32 with Exp_Util; use Exp_Util;
33 with GNAT.HTable; use GNAT.HTable;
35 with Namet; use Namet;
36 with Nlists; use Nlists;
37 with Nmake; use Nmake;
39 with Rtsfind; use Rtsfind;
41 with Sem_Ch3; use Sem_Ch3;
42 with Sem_Ch8; use Sem_Ch8;
43 with Sem_Dist; use Sem_Dist;
44 with Sem_Util; use Sem_Util;
45 with Sinfo; use Sinfo;
46 with Snames; use Snames;
47 with Stand; use Stand;
48 with Stringt; use Stringt;
49 with Tbuild; use Tbuild;
50 with Uintp; use Uintp;
51 with Uname; use Uname;
53 package body Exp_Dist is
55 -- The following model has been used to implement distributed objects:
56 -- given a designated type D and a RACW type R, then a record of the
59 -- type Stub is tagged record
60 -- [...declaration similar to s-parint.ads RACW_Stub_Type...]
63 -- is built. This type has two properties:
65 -- 1) Since it has the same structure than RACW_Stub_Type, it can be
66 -- converted to and from this type to make it suitable for
67 -- System.Partition_Interface.Get_Unique_Remote_Pointer in order
68 -- to avoid memory leaks when the same remote object arrive on the
69 -- same partition through several paths;
71 -- 2) It also has the same dispatching table as the designated type D,
72 -- and thus can be used as an object designated by a value of type
73 -- R on any partition other than the one on which the object has
74 -- been created, since only dispatching calls will be performed and
75 -- the fields themselves will not be used. We call Derive_Subprograms
76 -- to fake half a derivation to ensure that the subprograms do have
77 -- the same dispatching table.
79 First_RCI_Subprogram_Id : constant := 2;
80 -- RCI subprograms are numbered starting at 2. The RCI receiver for
81 -- an RCI package can thus identify calls received through remote
82 -- access-to-subprogram dereferences by the fact that they have a
83 -- (primitive) subprogram id of 0, and 1 is used for the internal
84 -- RAS information lookup operation.
86 -----------------------
87 -- Local subprograms --
88 -----------------------
90 procedure Add_RAS_Proxy_And_Analyze
93 All_Calls_Remote_E : Entity_Id;
94 Proxy_Object_Addr : out Entity_Id);
95 -- Add the proxy type necessary to call the subprogram declared
96 -- by Vis_Decl through a remote access to subprogram type.
97 -- All_Calls_Remote_E must be Standard_True if a pragma All_Calls_Remote
98 -- applies, Standard_False otherwise. The new proxy type is appended
99 -- to Decls. Proxy_Object_Addr is a constant of type System.Address that
100 -- designates an instance of the proxy object.
102 function Build_Remote_Subprogram_Proxy_Type
104 ACR_Expression : Node_Id) return Node_Id;
105 -- Build and return a tagged record type definition for an RCI
106 -- subprogram proxy type.
107 -- ACR_Expression is use as the initialization value for
108 -- the All_Calls_Remote component.
110 function Get_Subprogram_Id (E : Entity_Id) return Int;
111 -- Given a subprogram defined in a RCI package, get its subprogram id
112 -- which will be used for remote calls.
114 function Build_Get_Unique_RP_Call
117 Stub_Type : Entity_Id) return List_Id;
118 -- Build a call to Get_Unique_Remote_Pointer (Pointer),
119 -- followed by a tag fixup (Get_Unique_Remote_Pointer may have
120 -- changed Pointer'Tag to RACW_Stub_Type'Tag, while the desired
121 -- tag is that of Stub_Type).
123 procedure Build_General_Calling_Stubs
125 Statements : List_Id;
126 Target_Partition : Entity_Id;
127 RPC_Receiver : Node_Id;
128 Subprogram_Id : Node_Id;
129 Asynchronous : Node_Id := Empty;
130 Is_Known_Asynchronous : Boolean := False;
131 Is_Known_Non_Asynchronous : Boolean := False;
132 Is_Function : Boolean;
134 Stub_Type : Entity_Id := Empty;
136 -- Build calling stubs for general purpose. The parameters are:
137 -- Decls : a place to put declarations
138 -- Statements : a place to put statements
139 -- Target_Partition : a node containing the target partition that must
140 -- be a N_Defining_Identifier
141 -- RPC_Receiver : a node containing the RPC receiver
142 -- Subprogram_Id : a node containing the subprogram ID
143 -- Asynchronous : True if an APC must be made instead of an RPC.
144 -- The value needs not be supplied if one of the
145 -- Is_Known_... is True.
146 -- Is_Known_Async... : True if we know that this is asynchronous
147 -- Is_Known_Non_A... : True if we know that this is not asynchronous
148 -- Spec : a node with a Parameter_Specifications and
149 -- a Subtype_Mark if applicable
150 -- Stub_Type : in case of RACW stubs, parameters of type access
151 -- to Stub_Type will be marshalled using the
152 -- address of the object (the addr field) rather
153 -- than using the 'Write on the stub itself
154 -- Nod : used to provide sloc for generated code
156 function Build_Subprogram_Calling_Stubs
159 Asynchronous : Boolean;
160 Dynamically_Asynchronous : Boolean := False;
161 Stub_Type : Entity_Id := Empty;
162 Locator : Entity_Id := Empty;
163 New_Name : Name_Id := No_Name) return Node_Id;
164 -- Build the calling stub for a given subprogram with the subprogram ID
165 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
166 -- parameters of this type will be marshalled instead of the object
167 -- itself. It will then be converted into Stub_Type before performing
168 -- the real call. If Dynamically_Asynchronous is True, then it will be
169 -- computed at run time whether the call is asynchronous or not.
170 -- Otherwise, the value of the formal Asynchronous will be used.
171 -- If Locator is not Empty, it will be used instead of RCI_Cache. If
172 -- New_Name is given, then it will be used instead of the original name.
174 function Build_Subprogram_Receiving_Stubs
176 Asynchronous : Boolean;
177 Dynamically_Asynchronous : Boolean := False;
178 Stub_Type : Entity_Id := Empty;
179 RACW_Type : Entity_Id := Empty;
180 Parent_Primitive : Entity_Id := Empty) return Node_Id;
181 -- Build the receiving stub for a given subprogram. The subprogram
182 -- declaration is also built by this procedure, and the value returned
183 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
184 -- found in the specification, then its address is read from the stream
185 -- instead of the object itself and converted into an access to
186 -- class-wide type before doing the real call using any of the RACW type
187 -- pointing on the designated type.
189 function Build_RPC_Receiver_Specification
190 (RPC_Receiver : Entity_Id;
191 Stream_Parameter : Entity_Id;
192 Result_Parameter : Entity_Id) return Node_Id;
193 -- Make a subprogram specification for an RPC receiver,
194 -- with the given defining unit name and formal parameters.
196 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
197 -- Return an ordered parameter list: unconstrained parameters are put
198 -- at the beginning of the list and constrained ones are put after. If
199 -- there are no parameters, an empty list is returned. Special case:
200 -- the controlling formal of the equivalent RACW operation for a RAS
201 -- type is always left in first position.
203 procedure Add_Calling_Stubs_To_Declarations
206 -- Add calling stubs to the declarative part
208 procedure Add_Receiving_Stubs_To_Declarations
211 -- Add receiving stubs to the declarative part
213 procedure Add_RAS_Dereference_TSS (N : Node_Id);
214 -- Add a subprogram body for RAS Dereference TSS
216 procedure Add_RAS_Access_TSS (N : Node_Id);
217 -- Add a subprogram body for RAS Access TSS
219 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
220 -- Return True if nothing prevents the program whose specification is
221 -- given to be asynchronous (i.e. no out parameter).
223 function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id;
224 function Get_String_Id (Val : String) return String_Id;
225 -- Ugly functions used to retrieve a package name. Inherited from the
226 -- old exp_dist.adb and not rewritten yet ???
228 function Pack_Entity_Into_Stream_Access
232 Etyp : Entity_Id := Empty) return Node_Id;
233 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
234 -- then Etype (Object) will be used if present. If the type is
235 -- constrained, then 'Write will be used to output the object,
236 -- If the type is unconstrained, 'Output will be used.
238 function Pack_Node_Into_Stream
242 Etyp : Entity_Id) return Node_Id;
243 -- Similar to above, with an arbitrary node instead of an entity
245 function Pack_Node_Into_Stream_Access
249 Etyp : Entity_Id) return Node_Id;
250 -- Similar to above, with Stream instead of Stream'Access
252 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
253 -- Return the scope represented by a given spec
255 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
256 -- Return True if the current parameter needs an extra formal to reflect
257 -- its constrained status.
259 function Is_RACW_Controlling_Formal
260 (Parameter : Node_Id; Stub_Type : Entity_Id) return Boolean;
261 -- Return True if the current parameter is a controlling formal argument
262 -- of type Stub_Type or access to Stub_Type.
264 type Stub_Structure is record
265 Stub_Type : Entity_Id;
266 Stub_Type_Access : Entity_Id;
267 Object_RPC_Receiver : Entity_Id;
268 RPC_Receiver_Stream : Entity_Id;
269 RPC_Receiver_Result : Entity_Id;
270 RACW_Type : Entity_Id;
272 -- This structure is necessary because of the two phases analysis of
273 -- a RACW declaration occurring in the same Remote_Types package as the
274 -- designated type. RACW_Type is any of the RACW types pointing on this
275 -- designated type, it is used here to save an anonymous type creation
276 -- for each primitive operation.
278 Empty_Stub_Structure : constant Stub_Structure :=
279 (Empty, Empty, Empty, Empty, Empty, Empty);
281 type Hash_Index is range 0 .. 50;
282 function Hash (F : Entity_Id) return Hash_Index;
284 package Stubs_Table is
285 new Simple_HTable (Header_Num => Hash_Index,
286 Element => Stub_Structure,
287 No_Element => Empty_Stub_Structure,
291 -- Mapping between a RACW designated type and its stub type
293 package Asynchronous_Flags_Table is
294 new Simple_HTable (Header_Num => Hash_Index,
295 Element => Entity_Id,
300 -- Mapping between a RACW type and a constant having the value True
301 -- if the RACW is asynchronous and False otherwise.
303 package RCI_Locator_Table is
304 new Simple_HTable (Header_Num => Hash_Index,
305 Element => Entity_Id,
310 -- Mapping between a RCI package on which All_Calls_Remote applies and
311 -- the generic instantiation of RCI_Info for this package.
313 package RCI_Calling_Stubs_Table is
314 new Simple_HTable (Header_Num => Hash_Index,
315 Element => Entity_Id,
320 -- Mapping between a RCI subprogram and the corresponding calling stubs
322 procedure Add_Stub_Type
323 (Designated_Type : Entity_Id;
324 RACW_Type : Entity_Id;
326 Stub_Type : out Entity_Id;
327 Stub_Type_Access : out Entity_Id;
328 Object_RPC_Receiver : out Entity_Id;
329 Existing : out Boolean);
330 -- Add the declaration of the stub type, the access to stub type and the
331 -- object RPC receiver at the end of Decls. If these already exist,
332 -- then nothing is added in the tree but the right values are returned
333 -- anyhow and Existing is set to True.
335 procedure Add_RACW_Asynchronous_Flag
336 (Declarations : List_Id;
337 RACW_Type : Entity_Id);
338 -- Declare a boolean constant associated with RACW_Type whose value
339 -- indicates at run time whether a pragma Asynchronous applies to it.
341 procedure Add_RACW_Read_Attribute
342 (RACW_Type : Entity_Id;
343 Stub_Type : Entity_Id;
344 Stub_Type_Access : Entity_Id;
345 Declarations : List_Id);
346 -- Add Read attribute in Decls for the RACW type. The Read attribute
347 -- is added right after the RACW_Type declaration while the body is
348 -- inserted after Declarations.
350 procedure Add_RACW_Write_Attribute
351 (RACW_Type : Entity_Id;
352 Stub_Type : Entity_Id;
353 Stub_Type_Access : Entity_Id;
354 Object_RPC_Receiver : Entity_Id;
355 Declarations : List_Id);
356 -- Same thing for the Write attribute
358 procedure Add_RACW_Read_Write_Attributes
359 (RACW_Type : Entity_Id;
360 Stub_Type : Entity_Id;
361 Stub_Type_Access : Entity_Id;
362 Object_RPC_Receiver : Entity_Id;
363 Declarations : List_Id);
364 -- Add Read and Write attributes declarations and bodies for a given
365 -- RACW type. The declarations are added just after the declaration
366 -- of the RACW type itself, while the bodies are inserted at the end
369 function RCI_Package_Locator
371 Package_Spec : Node_Id) return Node_Id;
372 -- Instantiate the generic package RCI_Info in order to locate the
373 -- RCI package whose spec is given as argument.
375 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
376 -- Surround a node N by a tag check, as in:
380 -- when E : Ada.Tags.Tag_Error =>
381 -- Raise_Exception (Program_Error'Identity,
382 -- Exception_Message (E));
385 function Input_With_Tag_Check
387 Var_Type : Entity_Id;
388 Stream : Entity_Id) return Node_Id;
389 -- Return a function with the following form:
390 -- function R return Var_Type is
392 -- return Var_Type'Input (S);
394 -- when E : Ada.Tags.Tag_Error =>
395 -- Raise_Exception (Program_Error'Identity,
396 -- Exception_Message (E));
399 ------------------------------------
400 -- Local variables and structures --
401 ------------------------------------
405 Output_From_Constrained : constant array (Boolean) of Name_Id :=
406 (False => Name_Output,
408 -- The attribute to choose depending on the fact that the parameter
409 -- is constrained or not. There is no such thing as Input_From_Constrained
410 -- since this require separate mechanisms ('Input is a function while
411 -- 'Read is a procedure).
413 ---------------------------------------
414 -- Add_Calling_Stubs_To_Declarations --
415 ---------------------------------------
417 procedure Add_Calling_Stubs_To_Declarations
421 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
422 -- Subprogram id 0 is reserved for calls received from
423 -- remote access-to-subprogram dereferences.
425 Current_Declaration : Node_Id;
426 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
427 RCI_Instantiation : Node_Id;
428 Subp_Stubs : Node_Id;
431 -- The first thing added is an instantiation of the generic package
432 -- System.Partition_interface.RCI_Info with the name of the (current)
433 -- remote package. This will act as an interface with the name server
434 -- to determine the Partition_ID and the RPC_Receiver for the
435 -- receiver of this package.
437 RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
438 RCI_Cache := Defining_Unit_Name (RCI_Instantiation);
440 Append_To (Decls, RCI_Instantiation);
441 Analyze (RCI_Instantiation);
443 -- For each subprogram declaration visible in the spec, we do
444 -- build a body. We also increment a counter to assign a different
445 -- Subprogram_Id to each subprograms. The receiving stubs processing
446 -- do use the same mechanism and will thus assign the same Id and
447 -- do the correct dispatching.
449 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
450 while Current_Declaration /= Empty loop
451 if Nkind (Current_Declaration) = N_Subprogram_Declaration
452 and then Comes_From_Source (Current_Declaration)
454 pragma Assert (Current_Subprogram_Number =
455 Get_Subprogram_Id (Defining_Unit_Name (Specification (
456 Current_Declaration))));
459 Build_Subprogram_Calling_Stubs (
460 Vis_Decl => Current_Declaration,
461 Subp_Id => Current_Subprogram_Number,
463 Nkind (Specification (Current_Declaration)) =
464 N_Procedure_Specification
466 Is_Asynchronous (Defining_Unit_Name (Specification
467 (Current_Declaration))));
469 Append_To (Decls, Subp_Stubs);
470 Analyze (Subp_Stubs);
472 Current_Subprogram_Number := Current_Subprogram_Number + 1;
475 Next (Current_Declaration);
477 end Add_Calling_Stubs_To_Declarations;
479 --------------------------------
480 -- Add_RACW_Asynchronous_Flag --
481 --------------------------------
483 procedure Add_RACW_Asynchronous_Flag
484 (Declarations : List_Id;
485 RACW_Type : Entity_Id)
487 Loc : constant Source_Ptr := Sloc (RACW_Type);
489 Asynchronous_Flag : constant Entity_Id :=
490 Make_Defining_Identifier (Loc,
491 New_External_Name (Chars (RACW_Type), 'A'));
494 -- Declare the asynchronous flag. This flag will be changed to True
495 -- whenever it is known that the RACW type is asynchronous.
497 Append_To (Declarations,
498 Make_Object_Declaration (Loc,
499 Defining_Identifier => Asynchronous_Flag,
500 Constant_Present => True,
501 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
502 Expression => New_Occurrence_Of (Standard_False, Loc)));
504 Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Flag);
505 end Add_RACW_Asynchronous_Flag;
507 -----------------------
508 -- Add_RACW_Features --
509 -----------------------
511 procedure Add_RACW_Features (RACW_Type : Entity_Id)
513 Desig : constant Entity_Id :=
514 Etype (Designated_Type (RACW_Type));
516 List_Containing (Declaration_Node (RACW_Type));
518 Same_Scope : constant Boolean :=
519 Scope (Desig) = Scope (RACW_Type);
521 Stub_Type : Entity_Id;
522 Stub_Type_Access : Entity_Id;
523 Object_RPC_Receiver : Entity_Id;
527 if not Expander_Active then
533 -- We are declaring a RACW in the same package than its designated
534 -- type, so the list to use for late declarations must be the
535 -- private part of the package. We do know that this private part
536 -- exists since the designated type has to be a private one.
538 Decls := Private_Declarations
539 (Package_Specification_Of_Scope (Current_Scope));
541 elsif Nkind (Parent (Decls)) = N_Package_Specification
542 and then Present (Private_Declarations (Parent (Decls)))
544 Decls := Private_Declarations (Parent (Decls));
547 -- If we were unable to find the declarations, that means that the
548 -- completion of the type was missing. We can safely return and let
549 -- the error be caught by the semantic analysis.
556 (Designated_Type => Desig,
557 RACW_Type => RACW_Type,
559 Stub_Type => Stub_Type,
560 Stub_Type_Access => Stub_Type_Access,
561 Object_RPC_Receiver => Object_RPC_Receiver,
562 Existing => Existing);
564 Add_RACW_Asynchronous_Flag
565 (Declarations => Decls,
566 RACW_Type => RACW_Type);
568 Add_RACW_Read_Write_Attributes
569 (RACW_Type => RACW_Type,
570 Stub_Type => Stub_Type,
571 Stub_Type_Access => Stub_Type_Access,
572 Object_RPC_Receiver => Object_RPC_Receiver,
573 Declarations => Decls);
575 if not Same_Scope and then not Existing then
577 -- The RACW has been declared in another scope than the designated
578 -- type and has not been handled by another RACW in the same package
579 -- as the first one, so add primitive for the stub type here.
581 Add_RACW_Primitive_Declarations_And_Bodies
582 (Designated_Type => Desig,
584 Parent (Declaration_Node (Object_RPC_Receiver)),
588 Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
590 end Add_RACW_Features;
592 ------------------------------------------------
593 -- Add_RACW_Primitive_Declarations_And_Bodies --
594 ------------------------------------------------
596 procedure Add_RACW_Primitive_Declarations_And_Bodies
597 (Designated_Type : Entity_Id;
598 Insertion_Node : Node_Id;
601 -- Set sloc of generated declaration copy of insertion node sloc, so
602 -- the declarations are recognized as belonging to the current package.
604 Loc : constant Source_Ptr := Sloc (Insertion_Node);
606 Stub_Elements : constant Stub_Structure :=
607 Stubs_Table.Get (Designated_Type);
609 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
611 Current_Insertion_Node : Node_Id := Insertion_Node;
613 RPC_Receiver_Declarations : List_Id;
614 RPC_Receiver_Statements : List_Id;
615 RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
616 RPC_Receiver_Subp_Id : Entity_Id;
618 Current_Primitive_Elmt : Elmt_Id;
619 Current_Primitive : Entity_Id;
620 Current_Primitive_Body : Node_Id;
621 Current_Primitive_Spec : Node_Id;
622 Current_Primitive_Decl : Node_Id;
623 Current_Primitive_Number : Int := 0;
625 Current_Primitive_Alias : Node_Id;
627 Current_Receiver : Entity_Id;
628 Current_Receiver_Body : Node_Id;
630 RPC_Receiver_Decl : Node_Id;
632 Possibly_Asynchronous : Boolean;
635 if not Expander_Active then
639 -- Build callers, receivers for every primitive operations and a RPC
640 -- receiver for this type.
642 if Present (Primitive_Operations (Designated_Type)) then
644 Current_Primitive_Elmt :=
645 First_Elmt (Primitive_Operations (Designated_Type));
646 while Current_Primitive_Elmt /= No_Elmt loop
647 Current_Primitive := Node (Current_Primitive_Elmt);
649 -- Copy the primitive of all the parents, except predefined
650 -- ones that are not remotely dispatching.
652 if Chars (Current_Primitive) /= Name_uSize
653 and then Chars (Current_Primitive) /= Name_uAlignment
654 and then not Is_TSS (Current_Primitive, TSS_Deep_Finalize)
656 -- The first thing to do is build an up-to-date copy of
657 -- the spec with all the formals referencing Designated_Type
658 -- transformed into formals referencing Stub_Type. Since this
659 -- primitive may have been inherited, go back the alias chain
660 -- until the real primitive has been found.
662 Current_Primitive_Alias := Current_Primitive;
663 while Present (Alias (Current_Primitive_Alias)) loop
665 (Current_Primitive_Alias
666 /= Alias (Current_Primitive_Alias));
667 Current_Primitive_Alias := Alias (Current_Primitive_Alias);
670 Current_Primitive_Spec :=
671 Copy_Specification (Loc,
672 Spec => Parent (Current_Primitive_Alias),
673 Object_Type => Designated_Type,
674 Stub_Type => Stub_Elements.Stub_Type);
676 Current_Primitive_Decl :=
677 Make_Subprogram_Declaration (Loc,
678 Specification => Current_Primitive_Spec);
680 Insert_After (Current_Insertion_Node, Current_Primitive_Decl);
681 Analyze (Current_Primitive_Decl);
682 Current_Insertion_Node := Current_Primitive_Decl;
684 Possibly_Asynchronous :=
685 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
686 and then Could_Be_Asynchronous (Current_Primitive_Spec);
688 Current_Primitive_Body :=
689 Build_Subprogram_Calling_Stubs
690 (Vis_Decl => Current_Primitive_Decl,
691 Subp_Id => Current_Primitive_Number,
692 Asynchronous => Possibly_Asynchronous,
693 Dynamically_Asynchronous => Possibly_Asynchronous,
694 Stub_Type => Stub_Elements.Stub_Type);
695 Append_To (Decls, Current_Primitive_Body);
697 -- Analyzing the body here would cause the Stub type to be
698 -- frozen, thus preventing subsequent primitive declarations.
699 -- For this reason, it will be analyzed later in the
702 -- Build the receiver stubs
704 Current_Receiver_Body :=
705 Build_Subprogram_Receiving_Stubs
706 (Vis_Decl => Current_Primitive_Decl,
707 Asynchronous => Possibly_Asynchronous,
708 Dynamically_Asynchronous => Possibly_Asynchronous,
709 Stub_Type => Stub_Elements.Stub_Type,
710 RACW_Type => Stub_Elements.RACW_Type,
711 Parent_Primitive => Current_Primitive);
714 Defining_Unit_Name (Specification (Current_Receiver_Body));
716 Append_To (Decls, Current_Receiver_Body);
718 -- Add a case alternative to the receiver
720 Append_To (RPC_Receiver_Case_Alternatives,
721 Make_Case_Statement_Alternative (Loc,
722 Discrete_Choices => New_List (
723 Make_Integer_Literal (Loc, Current_Primitive_Number)),
725 Statements => New_List (
726 Make_Procedure_Call_Statement (Loc,
728 New_Occurrence_Of (Current_Receiver, Loc),
729 Parameter_Associations => New_List (
731 (Stub_Elements.RPC_Receiver_Stream, Loc),
733 (Stub_Elements.RPC_Receiver_Result, Loc))))));
735 -- Increment the index of current primitive
737 Current_Primitive_Number := Current_Primitive_Number + 1;
740 Next_Elmt (Current_Primitive_Elmt);
744 -- Build the case statement and the heart of the subprogram
746 Append_To (RPC_Receiver_Case_Alternatives,
747 Make_Case_Statement_Alternative (Loc,
748 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
749 Statements => New_List (Make_Null_Statement (Loc))));
751 RPC_Receiver_Subp_Id :=
752 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
754 RPC_Receiver_Declarations := New_List (
755 Make_Object_Declaration (Loc,
756 Defining_Identifier => RPC_Receiver_Subp_Id,
758 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
760 RPC_Receiver_Statements := New_List (
761 Make_Attribute_Reference (Loc,
763 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
766 Expressions => New_List (
767 New_Occurrence_Of (Stub_Elements.RPC_Receiver_Stream, Loc),
768 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc))));
770 Append_To (RPC_Receiver_Statements,
771 Make_Case_Statement (Loc,
773 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
774 Alternatives => RPC_Receiver_Case_Alternatives));
777 Make_Subprogram_Body (Loc,
779 Copy_Specification (Loc,
780 Parent (Stub_Elements.Object_RPC_Receiver)),
781 Declarations => RPC_Receiver_Declarations,
782 Handled_Statement_Sequence =>
783 Make_Handled_Sequence_Of_Statements (Loc,
784 Statements => RPC_Receiver_Statements));
786 Append_To (Decls, RPC_Receiver_Decl);
788 -- Do not analyze RPC receiver at this stage since it will otherwise
789 -- reference subprograms that have not been analyzed yet. It will
790 -- be analyzed in the regular flow.
792 end Add_RACW_Primitive_Declarations_And_Bodies;
794 -----------------------------
795 -- Add_RACW_Read_Attribute --
796 -----------------------------
798 procedure Add_RACW_Read_Attribute
799 (RACW_Type : Entity_Id;
800 Stub_Type : Entity_Id;
801 Stub_Type_Access : Entity_Id;
802 Declarations : List_Id)
804 Loc : constant Source_Ptr := Sloc (RACW_Type);
812 Statements : List_Id;
813 Local_Statements : List_Id;
814 Remote_Statements : List_Id;
815 -- Various parts of the procedure
817 Procedure_Name : constant Name_Id :=
818 New_Internal_Name ('R');
819 Source_Partition : constant Entity_Id :=
820 Make_Defining_Identifier
821 (Loc, New_Internal_Name ('P'));
822 Source_Receiver : constant Entity_Id :=
823 Make_Defining_Identifier
824 (Loc, New_Internal_Name ('S'));
825 Source_Address : constant Entity_Id :=
826 Make_Defining_Identifier
827 (Loc, New_Internal_Name ('P'));
828 Local_Stub : constant Entity_Id :=
829 Make_Defining_Identifier
830 (Loc, New_Internal_Name ('L'));
831 Stubbed_Result : constant Entity_Id :=
832 Make_Defining_Identifier
833 (Loc, New_Internal_Name ('S'));
834 Asynchronous_Flag : constant Entity_Id :=
835 Asynchronous_Flags_Table.Get (RACW_Type);
836 pragma Assert (Present (Asynchronous_Flag));
838 function Stream_Parameter return Node_Id;
839 function Result return Node_Id;
840 -- Functions to create occurrences of the formal parameter names
846 function Result return Node_Id is
848 return Make_Identifier (Loc, Name_V);
851 ----------------------
852 -- Stream_Parameter --
853 ----------------------
855 function Stream_Parameter return Node_Id is
857 return Make_Identifier (Loc, Name_S);
858 end Stream_Parameter;
860 -- Start of processing for Add_RACW_Read_Attribute
863 -- Generate object declarations
866 Make_Object_Declaration (Loc,
867 Defining_Identifier => Source_Partition,
869 New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
871 Make_Object_Declaration (Loc,
872 Defining_Identifier => Source_Receiver,
874 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
876 Make_Object_Declaration (Loc,
877 Defining_Identifier => Source_Address,
879 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
881 Make_Object_Declaration (Loc,
882 Defining_Identifier => Local_Stub,
883 Aliased_Present => True,
884 Object_Definition => New_Occurrence_Of (Stub_Type, Loc)),
886 Make_Object_Declaration (Loc,
887 Defining_Identifier => Stubbed_Result,
889 New_Occurrence_Of (Stub_Type_Access, Loc),
891 Make_Attribute_Reference (Loc,
893 New_Occurrence_Of (Local_Stub, Loc),
895 Name_Unchecked_Access)));
897 -- Read the source Partition_ID and RPC_Receiver from incoming stream
899 Statements := New_List (
900 Make_Attribute_Reference (Loc,
902 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
903 Attribute_Name => Name_Read,
904 Expressions => New_List (
906 New_Occurrence_Of (Source_Partition, Loc))),
908 Make_Attribute_Reference (Loc,
910 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
913 Expressions => New_List (
915 New_Occurrence_Of (Source_Receiver, Loc))),
917 Make_Attribute_Reference (Loc,
919 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
922 Expressions => New_List (
924 New_Occurrence_Of (Source_Address, Loc))));
926 -- Build_Get_Unique_RP_Call needs the type of Stubbed_Result
928 Set_Etype (Stubbed_Result, Stub_Type_Access);
930 -- If the Address is Null_Address, then return a null object
932 Append_To (Statements,
933 Make_Implicit_If_Statement (RACW_Type,
936 Left_Opnd => New_Occurrence_Of (Source_Address, Loc),
937 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
938 Then_Statements => New_List (
939 Make_Assignment_Statement (Loc,
941 Expression => Make_Null (Loc)),
942 Make_Return_Statement (Loc))));
944 -- If the RACW denotes an object created on the current partition, then
945 -- Local_Statements will be executed. The real object will be used.
947 Local_Statements := New_List (
948 Make_Assignment_Statement (Loc,
951 Unchecked_Convert_To (RACW_Type,
952 OK_Convert_To (RTE (RE_Address),
953 New_Occurrence_Of (Source_Address, Loc)))));
955 -- If the object is located on another partition, then a stub object
956 -- will be created with all the information needed to rebuild the
957 -- real object at the other end.
959 Remote_Statements := New_List (
961 Make_Assignment_Statement (Loc,
962 Name => Make_Selected_Component (Loc,
963 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
964 Selector_Name => Make_Identifier (Loc, Name_Origin)),
966 New_Occurrence_Of (Source_Partition, Loc)),
968 Make_Assignment_Statement (Loc,
969 Name => Make_Selected_Component (Loc,
970 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
971 Selector_Name => Make_Identifier (Loc, Name_Receiver)),
973 New_Occurrence_Of (Source_Receiver, Loc)),
975 Make_Assignment_Statement (Loc,
976 Name => Make_Selected_Component (Loc,
977 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
978 Selector_Name => Make_Identifier (Loc, Name_Addr)),
980 New_Occurrence_Of (Source_Address, Loc)));
982 Append_To (Remote_Statements,
983 Make_Assignment_Statement (Loc,
984 Name => Make_Selected_Component (Loc,
985 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
986 Selector_Name => Make_Identifier (Loc, Name_Asynchronous)),
988 New_Occurrence_Of (Asynchronous_Flag, Loc)));
990 Append_List_To (Remote_Statements,
991 Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
992 -- ??? Issue with asynchronous calls here: the Asynchronous
993 -- flag is set on the stub type if, and only if, the RACW type
994 -- has a pragma Asynchronous. This is incorrect for RACWs that
995 -- implement RAS types, because in that case the /designated
996 -- subprogram/ (not the type) might be asynchronous, and
997 -- that causes the stub to need to be asynchronous too.
998 -- A solution is to transport a RAS as a struct containing
999 -- a RACW and an asynchronous flag, and to properly alter
1000 -- the Asynchronous component in the stub type in the RAS's
1003 Append_To (Remote_Statements,
1004 Make_Assignment_Statement (Loc,
1006 Expression => Unchecked_Convert_To (RACW_Type,
1007 New_Occurrence_Of (Stubbed_Result, Loc))));
1009 -- Distinguish between the local and remote cases, and execute the
1010 -- appropriate piece of code.
1012 Append_To (Statements,
1013 Make_Implicit_If_Statement (RACW_Type,
1017 Make_Function_Call (Loc,
1019 New_Occurrence_Of (RTE (RE_Get_Local_Partition_Id), Loc)),
1020 Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
1021 Then_Statements => Local_Statements,
1022 Else_Statements => Remote_Statements));
1024 Build_Stream_Procedure
1025 (Loc, RACW_Type, Body_Node,
1026 Make_Defining_Identifier (Loc, Procedure_Name),
1027 Statements, Outp => True);
1028 Set_Declarations (Body_Node, Decls);
1030 Proc_Decl := Make_Subprogram_Declaration (Loc,
1031 Copy_Specification (Loc, Specification (Body_Node)));
1034 Make_Attribute_Definition_Clause (Loc,
1035 Name => New_Occurrence_Of (RACW_Type, Loc),
1039 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
1041 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
1042 Insert_After (Proc_Decl, Attr_Decl);
1043 Append_To (Declarations, Body_Node);
1044 end Add_RACW_Read_Attribute;
1046 ------------------------------------
1047 -- Add_RACW_Read_Write_Attributes --
1048 ------------------------------------
1050 procedure Add_RACW_Read_Write_Attributes
1051 (RACW_Type : Entity_Id;
1052 Stub_Type : Entity_Id;
1053 Stub_Type_Access : Entity_Id;
1054 Object_RPC_Receiver : Entity_Id;
1055 Declarations : List_Id)
1058 Add_RACW_Write_Attribute
1059 (RACW_Type => RACW_Type,
1060 Stub_Type => Stub_Type,
1061 Stub_Type_Access => Stub_Type_Access,
1062 Object_RPC_Receiver => Object_RPC_Receiver,
1063 Declarations => Declarations);
1065 Add_RACW_Read_Attribute
1066 (RACW_Type => RACW_Type,
1067 Stub_Type => Stub_Type,
1068 Stub_Type_Access => Stub_Type_Access,
1069 Declarations => Declarations);
1070 end Add_RACW_Read_Write_Attributes;
1072 ------------------------------
1073 -- Add_RACW_Write_Attribute --
1074 ------------------------------
1076 procedure Add_RACW_Write_Attribute
1077 (RACW_Type : Entity_Id;
1078 Stub_Type : Entity_Id;
1079 Stub_Type_Access : Entity_Id;
1080 Object_RPC_Receiver : Entity_Id;
1081 Declarations : List_Id)
1083 Loc : constant Source_Ptr := Sloc (RACW_Type);
1085 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
1087 Body_Node : Node_Id;
1088 Proc_Decl : Node_Id;
1089 Attr_Decl : Node_Id;
1091 RPC_Receiver : Node_Id;
1093 Statements : List_Id;
1094 Local_Statements : List_Id;
1095 Remote_Statements : List_Id;
1096 Null_Statements : List_Id;
1098 Procedure_Name : constant Name_Id := New_Internal_Name ('R');
1100 -- Functions to create occurrences of the formal
1103 function Stream_Parameter return Node_Id;
1104 function Object return Node_Id;
1106 function Stream_Parameter return Node_Id is
1108 return Make_Identifier (Loc, Name_S);
1109 end Stream_Parameter;
1111 function Object return Node_Id is
1113 return Make_Identifier (Loc, Name_V);
1117 -- Build the code fragment corresponding to the marshalling of a
1122 -- For a RAS, the RPC receiver is that of the RCI unit,
1123 -- not that of the corresponding distributed object type.
1124 -- We retrieve its address from the local proxy object.
1126 RPC_Receiver := Make_Selected_Component (Loc,
1128 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object),
1130 Make_Identifier (Loc, Name_Receiver));
1133 RPC_Receiver := Make_Attribute_Reference (Loc,
1135 New_Occurrence_Of (Object_RPC_Receiver, Loc),
1140 Local_Statements := New_List (
1142 Pack_Entity_Into_Stream_Access (Loc,
1143 Stream => Stream_Parameter,
1144 Object => RTE (RE_Get_Local_Partition_Id)),
1146 Pack_Node_Into_Stream_Access (Loc,
1147 Stream => Stream_Parameter,
1148 Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
1149 Etyp => RTE (RE_Unsigned_64)),
1151 Pack_Node_Into_Stream_Access (Loc,
1152 Stream => Stream_Parameter,
1153 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1154 Make_Attribute_Reference (Loc,
1156 Make_Explicit_Dereference (Loc,
1158 Attribute_Name => Name_Address)),
1159 Etyp => RTE (RE_Unsigned_64)));
1161 -- Build the code fragment corresponding to the marshalling of
1164 Remote_Statements := New_List (
1166 Pack_Node_Into_Stream_Access (Loc,
1167 Stream => Stream_Parameter,
1169 Make_Selected_Component (Loc,
1170 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1173 Make_Identifier (Loc, Name_Origin)),
1174 Etyp => RTE (RE_Partition_ID)),
1176 Pack_Node_Into_Stream_Access (Loc,
1177 Stream => Stream_Parameter,
1179 Make_Selected_Component (Loc,
1180 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1183 Make_Identifier (Loc, Name_Receiver)),
1184 Etyp => RTE (RE_Unsigned_64)),
1186 Pack_Node_Into_Stream_Access (Loc,
1187 Stream => Stream_Parameter,
1189 Make_Selected_Component (Loc,
1190 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1193 Make_Identifier (Loc, Name_Addr)),
1194 Etyp => RTE (RE_Unsigned_64)));
1196 -- Build the code fragment corresponding to the marshalling of a null
1199 Null_Statements := New_List (
1201 Pack_Entity_Into_Stream_Access (Loc,
1202 Stream => Stream_Parameter,
1203 Object => RTE (RE_Get_Local_Partition_Id)),
1205 Pack_Node_Into_Stream_Access (Loc,
1206 Stream => Stream_Parameter,
1207 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1208 Make_Attribute_Reference (Loc,
1209 Prefix => New_Occurrence_Of (Object_RPC_Receiver, Loc),
1210 Attribute_Name => Name_Address)),
1211 Etyp => RTE (RE_Unsigned_64)),
1213 Pack_Node_Into_Stream_Access (Loc,
1214 Stream => Stream_Parameter,
1215 Object => Make_Integer_Literal (Loc, Uint_0),
1216 Etyp => RTE (RE_Unsigned_64)));
1218 Statements := New_List (
1219 Make_Implicit_If_Statement (RACW_Type,
1222 Left_Opnd => Object,
1223 Right_Opnd => Make_Null (Loc)),
1224 Then_Statements => Null_Statements,
1225 Elsif_Parts => New_List (
1226 Make_Elsif_Part (Loc,
1230 Make_Attribute_Reference (Loc,
1232 Attribute_Name => Name_Tag),
1234 Make_Attribute_Reference (Loc,
1235 Prefix => New_Occurrence_Of (Stub_Type, Loc),
1236 Attribute_Name => Name_Tag)),
1237 Then_Statements => Remote_Statements)),
1238 Else_Statements => Local_Statements));
1240 Build_Stream_Procedure
1241 (Loc, RACW_Type, Body_Node,
1242 Make_Defining_Identifier (Loc, Procedure_Name),
1243 Statements, Outp => False);
1245 Proc_Decl := Make_Subprogram_Declaration (Loc,
1246 Copy_Specification (Loc, Specification (Body_Node)));
1249 Make_Attribute_Definition_Clause (Loc,
1250 Name => New_Occurrence_Of (RACW_Type, Loc),
1251 Chars => Name_Write,
1254 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
1256 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
1257 Insert_After (Proc_Decl, Attr_Decl);
1258 Append_To (Declarations, Body_Node);
1259 end Add_RACW_Write_Attribute;
1261 ------------------------
1262 -- Add_RAS_Access_TSS --
1263 ------------------------
1265 procedure Add_RAS_Access_TSS (N : Node_Id) is
1266 Loc : constant Source_Ptr := Sloc (N);
1268 Ras_Type : constant Entity_Id := Defining_Identifier (N);
1269 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
1270 -- Ras_Type is the access to subprogram type while Fat_Type points to
1271 -- the record type corresponding to a remote access to subprogram type.
1273 RACW_Type : constant Entity_Id :=
1274 Underlying_RACW_Type (Ras_Type);
1275 Desig : constant Entity_Id :=
1276 Etype (Designated_Type (RACW_Type));
1278 Stub_Elements : constant Stub_Structure :=
1279 Stubs_Table.Get (Desig);
1280 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1282 Proc : constant Entity_Id :=
1283 Make_Defining_Identifier (Loc,
1284 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
1285 Proc_Spec : Node_Id;
1287 -- Formal parameters
1289 Package_Name : constant Entity_Id :=
1290 Make_Defining_Identifier (Loc,
1294 Subp_Id : constant Entity_Id :=
1295 Make_Defining_Identifier (Loc,
1297 -- Target subprogram
1299 Asynch_P : constant Entity_Id :=
1300 Make_Defining_Identifier (Loc,
1301 Chars => Name_Asynchronous);
1302 -- Is the procedure to which the 'Access applies asynchronous?
1304 All_Calls_Remote : constant Entity_Id :=
1305 Make_Defining_Identifier (Loc,
1306 Chars => Name_All_Calls_Remote);
1307 -- True if an All_Calls_Remote pragma applies to the RCI unit
1308 -- that contains the subprogram.
1310 -- Common local variables
1312 Proc_Decls : List_Id;
1313 Proc_Statements : List_Id;
1315 Origin : constant Entity_Id :=
1316 Make_Defining_Identifier (Loc,
1317 Chars => New_Internal_Name ('P'));
1319 -- Additional local variables for the local case
1321 Proxy_Addr : constant Entity_Id :=
1322 Make_Defining_Identifier (Loc,
1323 Chars => New_Internal_Name ('P'));
1325 -- Additional local variables for the remote case
1327 Local_Stub : constant Entity_Id :=
1328 Make_Defining_Identifier (Loc,
1329 Chars => New_Internal_Name ('L'));
1331 Stub_Ptr : constant Entity_Id :=
1332 Make_Defining_Identifier (Loc,
1333 Chars => New_Internal_Name ('S'));
1336 (Field_Name : Name_Id;
1337 Value : Node_Id) return Node_Id;
1338 -- Construct an assignment that sets the named component in the
1346 (Field_Name : Name_Id;
1347 Value : Node_Id) return Node_Id
1351 Make_Assignment_Statement (Loc,
1353 Make_Selected_Component (Loc,
1354 Prefix => New_Occurrence_Of (Stub_Ptr, Loc),
1355 Selector_Name => Make_Identifier (Loc, Field_Name)),
1356 Expression => Value);
1359 -- Start of processing for Add_RAS_Access_TSS
1362 Proc_Decls := New_List (
1364 -- Common declarations
1366 Make_Object_Declaration (Loc,
1367 Defining_Identifier => Origin,
1368 Constant_Present => True,
1369 Object_Definition =>
1370 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
1372 Make_Function_Call (Loc,
1374 New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
1375 Parameter_Associations => New_List (
1376 New_Occurrence_Of (Package_Name, Loc)))),
1378 -- Declaration use only in the local case: proxy address
1380 Make_Object_Declaration (Loc,
1381 Defining_Identifier => Proxy_Addr,
1382 Object_Definition =>
1383 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
1385 -- Declarations used only in the remote case: stub object and
1388 Make_Object_Declaration (Loc,
1389 Defining_Identifier => Local_Stub,
1390 Aliased_Present => True,
1391 Object_Definition =>
1392 New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
1394 Make_Object_Declaration (Loc,
1395 Defining_Identifier =>
1397 Object_Definition =>
1398 New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
1400 Make_Attribute_Reference (Loc,
1401 Prefix => New_Occurrence_Of (Local_Stub, Loc),
1402 Attribute_Name => Name_Unchecked_Access)));
1404 Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
1405 -- Build_Get_Unique_RP_Call needs this information
1407 -- Note: Here we assume that the Fat_Type is a record
1408 -- containing just a pointer to a proxy or stub object.
1410 Proc_Statements := New_List (
1414 -- Get_RAS_Info (Pkg, Subp, PA);
1415 -- if Origin = Local_Partition_Id and then not All_Calls_Remote then
1416 -- return Fat_Type!(PA);
1419 Make_Procedure_Call_Statement (Loc,
1421 New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
1422 Parameter_Associations => New_List (
1423 New_Occurrence_Of (Package_Name, Loc),
1424 New_Occurrence_Of (Subp_Id, Loc),
1425 New_Occurrence_Of (Proxy_Addr, Loc))),
1427 Make_Implicit_If_Statement (N,
1433 New_Occurrence_Of (Origin, Loc),
1435 Make_Function_Call (Loc,
1437 RTE (RE_Get_Local_Partition_Id), Loc))),
1440 New_Occurrence_Of (All_Calls_Remote, Loc))),
1441 Then_Statements => New_List (
1442 Make_Return_Statement (Loc,
1443 Unchecked_Convert_To (Fat_Type,
1444 OK_Convert_To (RTE (RE_Address),
1445 New_Occurrence_Of (Proxy_Addr, Loc)))))),
1447 Set_Field (Name_Origin,
1448 New_Occurrence_Of (Origin, Loc)),
1450 Set_Field (Name_Receiver,
1451 Make_Function_Call (Loc,
1453 New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
1454 Parameter_Associations => New_List (
1455 New_Occurrence_Of (Package_Name, Loc)))),
1457 Set_Field (Name_Addr, New_Occurrence_Of (Proxy_Addr, Loc)),
1459 -- E.4.1(9) A remote call is asynchronous if it is a call to
1460 -- a procedure, or a call through a value of an access-to-procedure
1461 -- type, to which a pragma Asynchronous applies.
1463 -- Parameter Asynch_P is true when the procedure is asynchronous;
1464 -- Expression Asynch_T is true when the type is asynchronous.
1466 Set_Field (Name_Asynchronous,
1468 New_Occurrence_Of (Asynch_P, Loc),
1469 New_Occurrence_Of (Boolean_Literals (
1470 Is_Asynchronous (Ras_Type)), Loc))));
1472 Append_List_To (Proc_Statements,
1473 Build_Get_Unique_RP_Call
1474 (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
1476 -- Return the newly created value
1478 Append_To (Proc_Statements,
1479 Make_Return_Statement (Loc,
1481 Unchecked_Convert_To (Fat_Type,
1482 New_Occurrence_Of (Stub_Ptr, Loc))));
1485 Make_Function_Specification (Loc,
1486 Defining_Unit_Name => Proc,
1487 Parameter_Specifications => New_List (
1488 Make_Parameter_Specification (Loc,
1489 Defining_Identifier => Package_Name,
1491 New_Occurrence_Of (Standard_String, Loc)),
1493 Make_Parameter_Specification (Loc,
1494 Defining_Identifier => Subp_Id,
1496 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)),
1498 Make_Parameter_Specification (Loc,
1499 Defining_Identifier => Asynch_P,
1501 New_Occurrence_Of (Standard_Boolean, Loc)),
1503 Make_Parameter_Specification (Loc,
1504 Defining_Identifier => All_Calls_Remote,
1506 New_Occurrence_Of (Standard_Boolean, Loc))),
1509 New_Occurrence_Of (Fat_Type, Loc));
1511 -- Set the kind and return type of the function to prevent ambiguities
1512 -- between Ras_Type and Fat_Type in subsequent analysis.
1514 Set_Ekind (Proc, E_Function);
1515 Set_Etype (Proc, New_Occurrence_Of (Fat_Type, Loc));
1518 Make_Subprogram_Body (Loc,
1519 Specification => Proc_Spec,
1520 Declarations => Proc_Decls,
1521 Handled_Statement_Sequence =>
1522 Make_Handled_Sequence_Of_Statements (Loc,
1523 Statements => Proc_Statements)));
1525 Set_TSS (Fat_Type, Proc);
1526 end Add_RAS_Access_TSS;
1528 -----------------------------
1529 -- Add_RAS_Dereference_TSS --
1530 -----------------------------
1532 -- This subprogram could use more comments ???
1534 procedure Add_RAS_Dereference_TSS (N : Node_Id) is
1535 Loc : constant Source_Ptr := Sloc (N);
1537 Type_Def : constant Node_Id := Type_Definition (N);
1539 RAS_Type : constant Entity_Id := Defining_Identifier (N);
1540 Fat_Type : constant Entity_Id := Equivalent_Type (RAS_Type);
1541 RACW_Type : constant Entity_Id := Underlying_RACW_Type (RAS_Type);
1542 Desig : constant Entity_Id := Etype (Designated_Type (RACW_Type));
1544 Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
1545 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1547 RACW_Primitive_Name : Node_Id;
1549 Proc : constant Entity_Id :=
1550 Make_Defining_Identifier (Loc,
1551 Chars => Make_TSS_Name (RAS_Type, TSS_RAS_Dereference));
1553 Proc_Spec : Node_Id;
1554 Param_Specs : List_Id;
1555 Param_Assoc : constant List_Id := New_List;
1556 Stmts : constant List_Id := New_List;
1558 RAS_Parameter : constant Entity_Id :=
1559 Make_Defining_Identifier (Loc,
1560 Chars => New_Internal_Name ('P'));
1562 Is_Function : constant Boolean :=
1563 Nkind (Type_Def) = N_Access_Function_Definition;
1565 Is_Degenerate : Boolean;
1566 -- Set to True if the subprogram_specification for this RAS has
1567 -- an anonymous access parameter (see Process_Remote_AST_Declaration).
1569 Spec : constant Node_Id := Type_Def;
1571 Current_Parameter : Node_Id;
1574 Param_Specs := New_List (
1575 Make_Parameter_Specification (Loc,
1576 Defining_Identifier => RAS_Parameter,
1579 New_Occurrence_Of (Fat_Type, Loc)));
1581 Is_Degenerate := False;
1582 Current_Parameter := First (Parameter_Specifications (Type_Def));
1583 Parameters : while Current_Parameter /= Empty loop
1584 if Nkind (Parameter_Type (Current_Parameter))
1585 = N_Access_Definition
1587 Is_Degenerate := True;
1589 Append_To (Param_Specs,
1590 Make_Parameter_Specification (Loc,
1591 Defining_Identifier =>
1592 Make_Defining_Identifier (Loc,
1593 Chars => Chars (Defining_Identifier (Current_Parameter))),
1594 In_Present => In_Present (Current_Parameter),
1595 Out_Present => Out_Present (Current_Parameter),
1597 New_Copy_Tree (Parameter_Type (Current_Parameter)),
1599 New_Copy_Tree (Expression (Current_Parameter))));
1601 Append_To (Param_Assoc,
1602 Make_Identifier (Loc,
1603 Chars => Chars (Defining_Identifier (Current_Parameter))));
1605 Next (Current_Parameter);
1606 end loop Parameters;
1608 if Is_Degenerate then
1609 Prepend_To (Param_Assoc, New_Occurrence_Of (RAS_Parameter, Loc));
1611 -- Generate a dummy body recursing on the Dereference TSS, since
1612 -- actually it will never be executed.
1615 Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
1616 RACW_Primitive_Name := New_Occurrence_Of (Proc, Loc);
1619 Prepend_To (Param_Assoc,
1620 Unchecked_Convert_To (RACW_Type,
1621 New_Occurrence_Of (RAS_Parameter, Loc)));
1623 RACW_Primitive_Name :=
1624 Make_Selected_Component (Loc,
1626 New_Occurrence_Of (Scope (RACW_Type), Loc),
1628 Make_Identifier (Loc, Name_Call));
1633 Make_Return_Statement (Loc,
1635 Make_Function_Call (Loc,
1637 RACW_Primitive_Name,
1638 Parameter_Associations => Param_Assoc)));
1642 Make_Procedure_Call_Statement (Loc,
1644 RACW_Primitive_Name,
1645 Parameter_Associations => Param_Assoc));
1648 -- Build the complete subprogram
1652 Make_Function_Specification (Loc,
1653 Defining_Unit_Name => Proc,
1654 Parameter_Specifications => Param_Specs,
1657 Entity (Subtype_Mark (Spec)), Loc));
1659 Set_Ekind (Proc, E_Function);
1661 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
1665 Make_Procedure_Specification (Loc,
1666 Defining_Unit_Name => Proc,
1667 Parameter_Specifications => Param_Specs);
1669 Set_Ekind (Proc, E_Procedure);
1670 Set_Etype (Proc, Standard_Void_Type);
1674 Make_Subprogram_Body (Loc,
1675 Specification => Proc_Spec,
1676 Declarations => New_List,
1677 Handled_Statement_Sequence =>
1678 Make_Handled_Sequence_Of_Statements (Loc,
1679 Statements => Stmts)));
1681 Set_TSS (Fat_Type, Proc);
1682 end Add_RAS_Dereference_TSS;
1684 -------------------------------
1685 -- Add_RAS_Proxy_And_Analyze --
1686 -------------------------------
1688 procedure Add_RAS_Proxy_And_Analyze
1691 All_Calls_Remote_E : Entity_Id;
1692 Proxy_Object_Addr : out Entity_Id)
1694 Loc : constant Source_Ptr := Sloc (Vis_Decl);
1696 Subp_Name : constant Entity_Id :=
1697 Defining_Unit_Name (Specification (Vis_Decl));
1699 Pkg_Name : constant Entity_Id :=
1700 Make_Defining_Identifier (Loc,
1702 New_External_Name (Chars (Subp_Name), 'P', -1));
1704 Proxy_Type : constant Entity_Id :=
1705 Make_Defining_Identifier (Loc,
1708 Related_Id => Chars (Subp_Name),
1711 Proxy_Type_Full_View : constant Entity_Id :=
1712 Make_Defining_Identifier (Loc,
1713 Chars (Proxy_Type));
1715 Subp_Decl_Spec : constant Node_Id :=
1716 Build_RAS_Primitive_Specification
1717 (Subp_Spec => Specification (Vis_Decl),
1718 Remote_Object_Type => Proxy_Type);
1720 Subp_Body_Spec : constant Node_Id :=
1721 Build_RAS_Primitive_Specification
1722 (Subp_Spec => Specification (Vis_Decl),
1723 Remote_Object_Type => Proxy_Type);
1725 Vis_Decls : constant List_Id := New_List;
1726 Pvt_Decls : constant List_Id := New_List;
1727 Actuals : constant List_Id := New_List;
1729 Perform_Call : Node_Id;
1732 -- type subpP is tagged limited private;
1734 Append_To (Vis_Decls,
1735 Make_Private_Type_Declaration (Loc,
1736 Defining_Identifier => Proxy_Type,
1737 Tagged_Present => True,
1738 Limited_Present => True));
1740 -- [subprogram] Call
1741 -- (Self : access subpP;
1742 -- ...other-formals...)
1745 Append_To (Vis_Decls,
1746 Make_Subprogram_Declaration (Loc,
1747 Specification => Subp_Decl_Spec));
1749 -- A : constant System.Address;
1751 Proxy_Object_Addr := Make_Defining_Identifier (Loc, Name_uA);
1753 Append_To (Vis_Decls,
1754 Make_Object_Declaration (Loc,
1755 Defining_Identifier =>
1759 Object_Definition =>
1760 New_Occurrence_Of (RTE (RE_Address), Loc)));
1764 -- type subpP is tagged limited record
1765 -- All_Calls_Remote : Boolean := [All_Calls_Remote?];
1769 Append_To (Pvt_Decls,
1770 Make_Full_Type_Declaration (Loc,
1771 Defining_Identifier =>
1772 Proxy_Type_Full_View,
1774 Build_Remote_Subprogram_Proxy_Type (Loc,
1775 New_Occurrence_Of (All_Calls_Remote_E, Loc))));
1777 -- Trick semantic analysis into swapping the public and
1778 -- full view when freezing the public view.
1780 Set_Comes_From_Source (Proxy_Type_Full_View, True);
1783 -- (Self : access O;
1784 -- ...other-formals...) is
1786 -- P (...other-formals...);
1790 -- (Self : access O;
1791 -- ...other-formals...)
1794 -- return F (...other-formals...);
1797 if Nkind (Subp_Decl_Spec) = N_Procedure_Specification then
1799 Make_Procedure_Call_Statement (Loc,
1801 New_Occurrence_Of (Subp_Name, Loc),
1802 Parameter_Associations =>
1806 Make_Return_Statement (Loc,
1808 Make_Function_Call (Loc,
1810 New_Occurrence_Of (Subp_Name, Loc),
1811 Parameter_Associations =>
1815 Formal := First (Parameter_Specifications (Subp_Decl_Spec));
1816 pragma Assert (Present (Formal));
1819 while Present (Formal) loop
1820 Append_To (Actuals, New_Occurrence_Of (
1821 Defining_Identifier (Formal), Loc));
1825 -- O : aliased subpP;
1827 Append_To (Pvt_Decls,
1828 Make_Object_Declaration (Loc,
1829 Defining_Identifier =>
1830 Make_Defining_Identifier (Loc,
1834 Object_Definition =>
1835 New_Occurrence_Of (Proxy_Type, Loc)));
1837 -- A : constant System.Address := O'Address;
1839 Append_To (Pvt_Decls,
1840 Make_Object_Declaration (Loc,
1841 Defining_Identifier =>
1842 Make_Defining_Identifier (Loc,
1843 Chars (Proxy_Object_Addr)),
1846 Object_Definition =>
1847 New_Occurrence_Of (RTE (RE_Address), Loc),
1849 Make_Attribute_Reference (Loc,
1850 Prefix => New_Occurrence_Of (
1851 Defining_Identifier (Last (Pvt_Decls)), Loc),
1856 Make_Package_Declaration (Loc,
1857 Specification => Make_Package_Specification (Loc,
1858 Defining_Unit_Name => Pkg_Name,
1859 Visible_Declarations => Vis_Decls,
1860 Private_Declarations => Pvt_Decls,
1861 End_Label => Empty)));
1862 Analyze (Last (Decls));
1865 Make_Package_Body (Loc,
1866 Defining_Unit_Name =>
1867 Make_Defining_Identifier (Loc,
1869 Declarations => New_List (
1870 Make_Subprogram_Body (Loc,
1873 Declarations => New_List,
1874 Handled_Statement_Sequence =>
1875 Make_Handled_Sequence_Of_Statements (Loc,
1876 Statements => New_List (Perform_Call))))));
1877 Analyze (Last (Decls));
1878 end Add_RAS_Proxy_And_Analyze;
1880 -----------------------
1881 -- Add_RAST_Features --
1882 -----------------------
1884 procedure Add_RAST_Features (Vis_Decl : Node_Id) is
1886 -- Do not add attributes more than once in any case. This should
1887 -- be replaced by an assert or this comment removed if we decide
1888 -- that this is normal to be called several times ???
1890 if Present (TSS (Equivalent_Type (Defining_Identifier (Vis_Decl)),
1896 Add_RAS_Dereference_TSS (Vis_Decl);
1897 Add_RAS_Access_TSS (Vis_Decl);
1898 end Add_RAST_Features;
1900 -----------------------------------------
1901 -- Add_Receiving_Stubs_To_Declarations --
1902 -----------------------------------------
1904 procedure Add_Receiving_Stubs_To_Declarations
1905 (Pkg_Spec : Node_Id;
1908 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
1910 Stream_Parameter : Node_Id;
1911 Result_Parameter : Node_Id;
1913 Pkg_RPC_Receiver : Node_Id;
1914 Pkg_RPC_Receiver_Spec : Node_Id;
1915 Pkg_RPC_Receiver_Decls : List_Id;
1916 Pkg_RPC_Receiver_Statements : List_Id;
1917 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
1918 Pkg_RPC_Receiver_Body : Node_Id;
1919 -- A Pkg_RPC_Receiver is built to decode the request
1921 Lookup_RAS_Info : constant Entity_Id :=
1922 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
1923 -- A remote subprogram is created to allow peers to look up
1924 -- RAS information using subprogram ids.
1927 -- Subprogram_Id as read from the incoming stream
1929 Current_Declaration : Node_Id;
1930 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
1931 Current_Stubs : Node_Id;
1933 Subp_Info_Array : constant Entity_Id :=
1934 Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
1936 Subp_Info_List : constant List_Id := New_List;
1938 Dummy_Register_Name : Name_Id;
1939 Dummy_Register_Spec : Node_Id;
1940 Dummy_Register_Decl : Node_Id;
1941 Dummy_Register_Body : Node_Id;
1943 All_Calls_Remote_E : Entity_Id;
1944 Proxy_Object_Addr : Entity_Id;
1946 procedure Append_Stubs_To
1947 (RPC_Receiver_Cases : List_Id;
1948 Declaration : Node_Id;
1950 Subprogram_Number : Int);
1951 -- Add one case to the specified RPC receiver case list
1952 -- associating Subprogram_Number with the subprogram declared
1953 -- by Declaration, for which we have receiving stubs in Stubs.
1955 ---------------------
1956 -- Append_Stubs_To --
1957 ---------------------
1959 procedure Append_Stubs_To
1960 (RPC_Receiver_Cases : List_Id;
1961 Declaration : Node_Id;
1963 Subprogram_Number : Int)
1965 Actuals : constant List_Id :=
1966 New_List (New_Occurrence_Of (Stream_Parameter, Loc));
1968 if Nkind (Specification (Declaration)) = N_Function_Specification
1970 Is_Asynchronous (Defining_Entity (Specification (Declaration)))
1972 -- An asynchronous procedure does not want an output parameter
1973 -- since no result and no exception will ever be returned.
1976 New_Occurrence_Of (Result_Parameter, Loc));
1979 Append_To (RPC_Receiver_Cases,
1980 Make_Case_Statement_Alternative (Loc,
1983 Make_Integer_Literal (Loc, Subprogram_Number)),
1987 Make_Procedure_Call_Statement (Loc,
1990 Defining_Entity (Stubs), Loc),
1991 Parameter_Associations =>
1993 end Append_Stubs_To;
1995 -- Start of processing for Add_Receiving_Stubs_To_Declarations
1998 -- Building receiving stubs consist in several operations:
2000 -- - a package RPC receiver must be built. This subprogram
2001 -- will get a Subprogram_Id from the incoming stream
2002 -- and will dispatch the call to the right subprogram
2004 -- - a receiving stub for any subprogram visible in the package
2005 -- spec. This stub will read all the parameters from the stream,
2006 -- and put the result as well as the exception occurrence in the
2009 -- - a dummy package with an empty spec and a body made of an
2010 -- elaboration part, whose job is to register the receiving
2011 -- part of this RCI package on the name server. This is done
2012 -- by calling System.Partition_Interface.Register_Receiving_Stub
2015 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2017 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2019 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2022 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2024 -- The parameters of the package RPC receiver are made of two
2025 -- streams, an input one and an output one.
2027 Pkg_RPC_Receiver_Spec :=
2028 Build_RPC_Receiver_Specification
2029 (RPC_Receiver => Pkg_RPC_Receiver,
2030 Stream_Parameter => Stream_Parameter,
2031 Result_Parameter => Result_Parameter);
2033 Pkg_RPC_Receiver_Decls := New_List (
2034 Make_Object_Declaration (Loc,
2035 Defining_Identifier => Subp_Id,
2036 Object_Definition =>
2037 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
2039 Pkg_RPC_Receiver_Statements := New_List (
2040 Make_Attribute_Reference (Loc,
2042 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
2045 Expressions => New_List (
2046 New_Occurrence_Of (Stream_Parameter, Loc),
2047 New_Occurrence_Of (Subp_Id, Loc))));
2049 -- A null subp_id denotes a call through a RAS, in which case the
2050 -- next Uint_64 element in the stream is the address of the local
2051 -- proxy object, from which we can retrieve the actual subprogram id.
2053 Append_To (Pkg_RPC_Receiver_Statements,
2054 Make_Implicit_If_Statement (Pkg_Spec,
2057 New_Occurrence_Of (Subp_Id, Loc),
2058 Make_Integer_Literal (Loc, 0)),
2059 Then_Statements => New_List (
2060 Make_Assignment_Statement (Loc,
2062 New_Occurrence_Of (Subp_Id, Loc),
2064 Make_Selected_Component (Loc,
2066 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
2067 OK_Convert_To (RTE (RE_Address),
2068 Make_Attribute_Reference (Loc,
2070 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2073 Expressions => New_List (
2074 New_Occurrence_Of (Stream_Parameter, Loc))))),
2076 Make_Identifier (Loc, Name_Subp_Id))))));
2078 All_Calls_Remote_E := Boolean_Literals (
2079 Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
2081 -- Build a subprogram for RAS information lookups
2083 Current_Declaration :=
2084 Make_Subprogram_Declaration (Loc,
2086 Make_Function_Specification (Loc,
2087 Defining_Unit_Name =>
2089 Parameter_Specifications => New_List (
2090 Make_Parameter_Specification (Loc,
2091 Defining_Identifier =>
2092 Make_Defining_Identifier (Loc, Name_Subp_Id),
2096 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
2098 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
2099 Append_To (Decls, Current_Declaration);
2100 Analyze (Current_Declaration);
2102 Current_Stubs := Build_Subprogram_Receiving_Stubs
2103 (Vis_Decl => Current_Declaration,
2104 Asynchronous => False);
2105 Append_To (Decls, Current_Stubs);
2106 Analyze (Current_Stubs);
2108 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
2110 Current_Declaration,
2113 Subprogram_Number => 1);
2115 -- For each subprogram, the receiving stub will be built and a
2116 -- case statement will be made on the Subprogram_Id to dispatch
2117 -- to the right subprogram.
2119 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
2120 while Current_Declaration /= Empty loop
2121 if Nkind (Current_Declaration) = N_Subprogram_Declaration
2122 and then Comes_From_Source (Current_Declaration)
2124 pragma Assert (Current_Subprogram_Number =
2125 Get_Subprogram_Id (Defining_Unit_Name (Specification (
2126 Current_Declaration))));
2128 -- Build receiving stub
2131 Build_Subprogram_Receiving_Stubs
2132 (Vis_Decl => Current_Declaration,
2134 Nkind (Specification (Current_Declaration)) =
2135 N_Procedure_Specification
2136 and then Is_Asynchronous
2137 (Defining_Unit_Name (Specification
2138 (Current_Declaration))));
2140 Append_To (Decls, Current_Stubs);
2141 Analyze (Current_Stubs);
2145 Add_RAS_Proxy_And_Analyze (Decls,
2147 Current_Declaration,
2148 All_Calls_Remote_E =>
2150 Proxy_Object_Addr =>
2153 -- Add subprogram descriptor (RCI_Subp_Info) to the
2154 -- subprograms table for this receiver. The aggregate
2155 -- below must be kept consistent with the declaration
2156 -- of type RCI_Subp_Info in System.Partition_Interface.
2158 Append_To (Subp_Info_List,
2159 Make_Component_Association (Loc,
2160 Choices => New_List (
2161 Make_Integer_Literal (Loc,
2162 Current_Subprogram_Number)),
2164 Make_Aggregate (Loc,
2165 Component_Associations => New_List (
2166 Make_Component_Association (Loc,
2167 Choices => New_List (
2168 Make_Identifier (Loc, Name_Addr)),
2170 New_Occurrence_Of (Proxy_Object_Addr, Loc))))));
2172 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
2174 Current_Declaration,
2177 Subprogram_Number =>
2178 Current_Subprogram_Number);
2179 Current_Subprogram_Number := Current_Subprogram_Number + 1;
2182 Next (Current_Declaration);
2185 -- If we receive an invalid Subprogram_Id, it is best to do nothing
2186 -- rather than raising an exception since we do not want someone
2187 -- to crash a remote partition by sending invalid subprogram ids.
2188 -- This is consistent with the other parts of the case statement
2189 -- since even in presence of incorrect parameters in the stream,
2190 -- every exception will be caught and (if the subprogram is not an
2191 -- APC) put into the result stream and sent away.
2193 Append_To (Pkg_RPC_Receiver_Cases,
2194 Make_Case_Statement_Alternative (Loc,
2196 New_List (Make_Others_Choice (Loc)),
2198 New_List (Make_Null_Statement (Loc))));
2200 Append_To (Pkg_RPC_Receiver_Statements,
2201 Make_Case_Statement (Loc,
2203 New_Occurrence_Of (Subp_Id, Loc),
2204 Alternatives => Pkg_RPC_Receiver_Cases));
2207 Make_Object_Declaration (Loc,
2208 Defining_Identifier => Subp_Info_Array,
2209 Constant_Present => True,
2210 Aliased_Present => True,
2211 Object_Definition =>
2212 Make_Subtype_Indication (Loc,
2214 New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
2216 Make_Index_Or_Discriminant_Constraint (Loc,
2219 Low_Bound => Make_Integer_Literal (Loc,
2220 First_RCI_Subprogram_Id),
2222 Make_Integer_Literal (Loc,
2223 First_RCI_Subprogram_Id
2224 + List_Length (Subp_Info_List) - 1))))),
2226 Make_Aggregate (Loc,
2227 Component_Associations => Subp_Info_List)));
2228 Analyze (Last (Decls));
2231 Make_Subprogram_Body (Loc,
2233 Copy_Specification (Loc, Parent (Lookup_RAS_Info)),
2236 Handled_Statement_Sequence =>
2237 Make_Handled_Sequence_Of_Statements (Loc,
2238 Statements => New_List (
2239 Make_Return_Statement (Loc,
2240 Expression => OK_Convert_To (RTE (RE_Unsigned_64),
2241 Make_Selected_Component (Loc,
2243 Make_Indexed_Component (Loc,
2245 New_Occurrence_Of (Subp_Info_Array, Loc),
2246 Expressions => New_List (
2247 Convert_To (Standard_Integer,
2248 Make_Identifier (Loc, Name_Subp_Id)))),
2250 Make_Identifier (Loc, Name_Addr))))))));
2251 Analyze (Last (Decls));
2253 Pkg_RPC_Receiver_Body :=
2254 Make_Subprogram_Body (Loc,
2255 Specification => Pkg_RPC_Receiver_Spec,
2256 Declarations => Pkg_RPC_Receiver_Decls,
2257 Handled_Statement_Sequence =>
2258 Make_Handled_Sequence_Of_Statements (Loc,
2259 Statements => Pkg_RPC_Receiver_Statements));
2261 Append_To (Decls, Pkg_RPC_Receiver_Body);
2262 Analyze (Pkg_RPC_Receiver_Body);
2264 -- Construction of the dummy package used to register the package
2265 -- receiving stubs on the nameserver.
2267 Dummy_Register_Name := New_Internal_Name ('P');
2269 Dummy_Register_Spec :=
2270 Make_Package_Specification (Loc,
2271 Defining_Unit_Name =>
2272 Make_Defining_Identifier (Loc, Dummy_Register_Name),
2273 Visible_Declarations => No_List,
2274 End_Label => Empty);
2276 Dummy_Register_Decl :=
2277 Make_Package_Declaration (Loc,
2278 Specification => Dummy_Register_Spec);
2281 Dummy_Register_Decl);
2282 Analyze (Dummy_Register_Decl);
2284 Dummy_Register_Body :=
2285 Make_Package_Body (Loc,
2286 Defining_Unit_Name =>
2287 Make_Defining_Identifier (Loc, Dummy_Register_Name),
2288 Declarations => No_List,
2290 Handled_Statement_Sequence =>
2291 Make_Handled_Sequence_Of_Statements (Loc,
2292 Statements => New_List (
2293 Make_Procedure_Call_Statement (Loc,
2295 New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
2297 Parameter_Associations => New_List (
2298 Make_String_Literal (Loc,
2299 Strval => Get_Pkg_Name_String_Id (Pkg_Spec)),
2300 Make_Attribute_Reference (Loc,
2302 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
2304 Name_Unrestricted_Access),
2305 Make_Attribute_Reference (Loc,
2307 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
2310 Make_Attribute_Reference (Loc,
2312 New_Occurrence_Of (Subp_Info_Array, Loc),
2315 Make_Attribute_Reference (Loc,
2317 New_Occurrence_Of (Subp_Info_Array, Loc),
2321 Append_To (Decls, Dummy_Register_Body);
2322 Analyze (Dummy_Register_Body);
2323 end Add_Receiving_Stubs_To_Declarations;
2329 procedure Add_Stub_Type
2330 (Designated_Type : Entity_Id;
2331 RACW_Type : Entity_Id;
2333 Stub_Type : out Entity_Id;
2334 Stub_Type_Access : out Entity_Id;
2335 Object_RPC_Receiver : out Entity_Id;
2336 Existing : out Boolean)
2338 Loc : constant Source_Ptr := Sloc (RACW_Type);
2340 Stub_Elements : constant Stub_Structure :=
2341 Stubs_Table.Get (Designated_Type);
2343 Stub_Type_Declaration : Node_Id;
2344 Stub_Type_Access_Declaration : Node_Id;
2345 Object_RPC_Receiver_Declaration : Node_Id;
2347 RPC_Receiver_Stream : Entity_Id;
2348 RPC_Receiver_Result : Entity_Id;
2351 if Stub_Elements /= Empty_Stub_Structure then
2352 Stub_Type := Stub_Elements.Stub_Type;
2353 Stub_Type_Access := Stub_Elements.Stub_Type_Access;
2354 Object_RPC_Receiver := Stub_Elements.Object_RPC_Receiver;
2361 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2363 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2364 Object_RPC_Receiver :=
2365 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2366 RPC_Receiver_Stream :=
2367 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2368 RPC_Receiver_Result :=
2369 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2370 Stubs_Table.Set (Designated_Type,
2371 (Stub_Type => Stub_Type,
2372 Stub_Type_Access => Stub_Type_Access,
2373 Object_RPC_Receiver => Object_RPC_Receiver,
2374 RPC_Receiver_Stream => RPC_Receiver_Stream,
2375 RPC_Receiver_Result => RPC_Receiver_Result,
2376 RACW_Type => RACW_Type));
2378 -- The stub type definition below must match exactly the one in
2379 -- s-parint.ads, since unchecked conversions will be used in
2380 -- s-parint.adb to modify pointers passed to Get_Unique_Remote_Pointer.
2382 Stub_Type_Declaration :=
2383 Make_Full_Type_Declaration (Loc,
2384 Defining_Identifier => Stub_Type,
2386 Make_Record_Definition (Loc,
2387 Tagged_Present => True,
2388 Limited_Present => True,
2390 Make_Component_List (Loc,
2391 Component_Items => New_List (
2393 Make_Component_Declaration (Loc,
2394 Defining_Identifier =>
2395 Make_Defining_Identifier (Loc, Name_Origin),
2396 Component_Definition =>
2397 Make_Component_Definition (Loc,
2398 Aliased_Present => False,
2399 Subtype_Indication =>
2400 New_Occurrence_Of (RTE (RE_Partition_ID), Loc))),
2402 Make_Component_Declaration (Loc,
2403 Defining_Identifier =>
2404 Make_Defining_Identifier (Loc, Name_Receiver),
2405 Component_Definition =>
2406 Make_Component_Definition (Loc,
2407 Aliased_Present => False,
2408 Subtype_Indication =>
2409 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
2411 Make_Component_Declaration (Loc,
2412 Defining_Identifier =>
2413 Make_Defining_Identifier (Loc, Name_Addr),
2414 Component_Definition =>
2415 Make_Component_Definition (Loc,
2416 Aliased_Present => False,
2417 Subtype_Indication =>
2418 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
2420 Make_Component_Declaration (Loc,
2421 Defining_Identifier =>
2422 Make_Defining_Identifier (Loc, Name_Asynchronous),
2423 Component_Definition =>
2424 Make_Component_Definition (Loc,
2425 Aliased_Present => False,
2426 Subtype_Indication =>
2427 New_Occurrence_Of (Standard_Boolean, Loc)))))));
2429 Append_To (Decls, Stub_Type_Declaration);
2430 Analyze (Stub_Type_Declaration);
2432 -- This is in no way a type derivation, but we fake it to make
2433 -- sure that the dispatching table gets built with the corresponding
2434 -- primitive operations at the right place.
2436 Derive_Subprograms (Parent_Type => Designated_Type,
2437 Derived_Type => Stub_Type);
2439 Stub_Type_Access_Declaration :=
2440 Make_Full_Type_Declaration (Loc,
2441 Defining_Identifier => Stub_Type_Access,
2443 Make_Access_To_Object_Definition (Loc,
2444 All_Present => True,
2445 Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
2447 Append_To (Decls, Stub_Type_Access_Declaration);
2448 Analyze (Stub_Type_Access_Declaration);
2450 Object_RPC_Receiver_Declaration :=
2451 Make_Subprogram_Declaration (Loc,
2452 Build_RPC_Receiver_Specification (
2453 RPC_Receiver => Object_RPC_Receiver,
2454 Stream_Parameter => RPC_Receiver_Stream,
2455 Result_Parameter => RPC_Receiver_Result));
2457 Append_To (Decls, Object_RPC_Receiver_Declaration);
2460 ---------------------------------
2461 -- Build_General_Calling_Stubs --
2462 ---------------------------------
2464 procedure Build_General_Calling_Stubs
2466 Statements : List_Id;
2467 Target_Partition : Entity_Id;
2468 RPC_Receiver : Node_Id;
2469 Subprogram_Id : Node_Id;
2470 Asynchronous : Node_Id := Empty;
2471 Is_Known_Asynchronous : Boolean := False;
2472 Is_Known_Non_Asynchronous : Boolean := False;
2473 Is_Function : Boolean;
2475 Stub_Type : Entity_Id := Empty;
2478 Loc : constant Source_Ptr := Sloc (Nod);
2480 Stream_Parameter : Node_Id;
2481 -- Name of the stream used to transmit parameters to the remote package
2483 Result_Parameter : Node_Id;
2484 -- Name of the result parameter (in non-APC cases) which get the
2485 -- result of the remote subprogram.
2487 Exception_Return_Parameter : Node_Id;
2488 -- Name of the parameter which will hold the exception sent by the
2489 -- remote subprogram.
2491 Current_Parameter : Node_Id;
2492 -- Current parameter being handled
2494 Ordered_Parameters_List : constant List_Id :=
2495 Build_Ordered_Parameters_List (Spec);
2497 Asynchronous_Statements : List_Id := No_List;
2498 Non_Asynchronous_Statements : List_Id := No_List;
2499 -- Statements specifics to the Asynchronous/Non-Asynchronous cases
2501 Extra_Formal_Statements : constant List_Id := New_List;
2502 -- List of statements for extra formal parameters. It will appear after
2503 -- the regular statements for writing out parameters.
2506 -- The general form of a calling stub for a given subprogram is:
2508 -- procedure X (...) is
2509 -- P : constant Partition_ID := RCI_Cache.Get_Active_Partition_ID;
2510 -- Stream, Result : aliased System.RPC.Params_Stream_Type (0);
2512 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
2513 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
2514 -- Put_Subprogram_Id_In_Stream;
2515 -- Put_Parameters_In_Stream;
2516 -- Do_RPC (Stream, Result);
2517 -- Read_Exception_Occurrence_From_Result; Raise_It;
2518 -- Read_Out_Parameters_And_Function_Return_From_Stream;
2521 -- There are some variations: Do_APC is called for an asynchronous
2522 -- procedure and the part after the call is completely ommitted
2523 -- as well as the declaration of Result. For a function call,
2524 -- 'Input is always used to read the result even if it is constrained.
2527 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2530 Make_Object_Declaration (Loc,
2531 Defining_Identifier => Stream_Parameter,
2532 Aliased_Present => True,
2533 Object_Definition =>
2534 Make_Subtype_Indication (Loc,
2536 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2538 Make_Index_Or_Discriminant_Constraint (Loc,
2540 New_List (Make_Integer_Literal (Loc, 0))))));
2542 if not Is_Known_Asynchronous then
2544 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2547 Make_Object_Declaration (Loc,
2548 Defining_Identifier => Result_Parameter,
2549 Aliased_Present => True,
2550 Object_Definition =>
2551 Make_Subtype_Indication (Loc,
2553 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2555 Make_Index_Or_Discriminant_Constraint (Loc,
2557 New_List (Make_Integer_Literal (Loc, 0))))));
2559 Exception_Return_Parameter :=
2560 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
2563 Make_Object_Declaration (Loc,
2564 Defining_Identifier => Exception_Return_Parameter,
2565 Object_Definition =>
2566 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
2569 Result_Parameter := Empty;
2570 Exception_Return_Parameter := Empty;
2573 -- Put first the RPC receiver corresponding to the remote package
2575 Append_To (Statements,
2576 Make_Attribute_Reference (Loc,
2578 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2579 Attribute_Name => Name_Write,
2580 Expressions => New_List (
2581 Make_Attribute_Reference (Loc,
2583 New_Occurrence_Of (Stream_Parameter, Loc),
2588 -- Then put the Subprogram_Id of the subprogram we want to call in
2591 Append_To (Statements,
2592 Make_Attribute_Reference (Loc,
2594 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
2597 Expressions => New_List (
2598 Make_Attribute_Reference (Loc,
2600 New_Occurrence_Of (Stream_Parameter, Loc),
2601 Attribute_Name => Name_Access),
2604 Current_Parameter := First (Ordered_Parameters_List);
2605 while Current_Parameter /= Empty loop
2607 Typ : constant Node_Id :=
2608 Parameter_Type (Current_Parameter);
2610 Constrained : Boolean;
2612 Extra_Parameter : Entity_Id;
2615 if Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) then
2617 -- In the case of a controlling formal argument, we marshall
2618 -- its addr field rather than the local stub.
2620 Append_To (Statements,
2621 Pack_Node_Into_Stream (Loc,
2622 Stream => Stream_Parameter,
2624 Make_Selected_Component (Loc,
2627 Defining_Identifier (Current_Parameter), Loc),
2629 Make_Identifier (Loc, Name_Addr)),
2630 Etyp => RTE (RE_Unsigned_64)));
2633 Value := New_Occurrence_Of
2634 (Defining_Identifier (Current_Parameter), Loc);
2636 -- Access type parameters are transmitted as in out
2637 -- parameters. However, a dereference is needed so that
2638 -- we marshall the designated object.
2640 if Nkind (Typ) = N_Access_Definition then
2641 Value := Make_Explicit_Dereference (Loc, Value);
2642 Etyp := Etype (Subtype_Mark (Typ));
2644 Etyp := Etype (Typ);
2648 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
2650 -- Any parameter but unconstrained out parameters are
2651 -- transmitted to the peer.
2653 if In_Present (Current_Parameter)
2654 or else not Out_Present (Current_Parameter)
2655 or else not Constrained
2657 Append_To (Statements,
2658 Make_Attribute_Reference (Loc,
2660 New_Occurrence_Of (Etyp, Loc),
2661 Attribute_Name => Output_From_Constrained (Constrained),
2662 Expressions => New_List (
2663 Make_Attribute_Reference (Loc,
2665 New_Occurrence_Of (Stream_Parameter, Loc),
2666 Attribute_Name => Name_Access),
2671 -- If the current parameter has a dynamic constrained status,
2672 -- then this status is transmitted as well.
2673 -- This should be done for accessibility as well ???
2675 if Nkind (Typ) /= N_Access_Definition
2676 and then Need_Extra_Constrained (Current_Parameter)
2678 -- In this block, we do not use the extra formal that has been
2679 -- created because it does not exist at the time of expansion
2680 -- when building calling stubs for remote access to subprogram
2681 -- types. We create an extra variable of this type and push it
2682 -- in the stream after the regular parameters.
2684 Extra_Parameter := Make_Defining_Identifier
2685 (Loc, New_Internal_Name ('P'));
2688 Make_Object_Declaration (Loc,
2689 Defining_Identifier => Extra_Parameter,
2690 Constant_Present => True,
2691 Object_Definition =>
2692 New_Occurrence_Of (Standard_Boolean, Loc),
2694 Make_Attribute_Reference (Loc,
2697 Defining_Identifier (Current_Parameter), Loc),
2698 Attribute_Name => Name_Constrained)));
2700 Append_To (Extra_Formal_Statements,
2701 Make_Attribute_Reference (Loc,
2703 New_Occurrence_Of (Standard_Boolean, Loc),
2706 Expressions => New_List (
2707 Make_Attribute_Reference (Loc,
2709 New_Occurrence_Of (Stream_Parameter, Loc),
2712 New_Occurrence_Of (Extra_Parameter, Loc))));
2715 Next (Current_Parameter);
2719 -- Append the formal statements list to the statements
2721 Append_List_To (Statements, Extra_Formal_Statements);
2723 if not Is_Known_Non_Asynchronous then
2725 -- Build the call to System.RPC.Do_APC
2727 Asynchronous_Statements := New_List (
2728 Make_Procedure_Call_Statement (Loc,
2730 New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
2731 Parameter_Associations => New_List (
2732 New_Occurrence_Of (Target_Partition, Loc),
2733 Make_Attribute_Reference (Loc,
2735 New_Occurrence_Of (Stream_Parameter, Loc),
2739 Asynchronous_Statements := No_List;
2742 if not Is_Known_Asynchronous then
2744 -- Build the call to System.RPC.Do_RPC
2746 Non_Asynchronous_Statements := New_List (
2747 Make_Procedure_Call_Statement (Loc,
2749 New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
2750 Parameter_Associations => New_List (
2751 New_Occurrence_Of (Target_Partition, Loc),
2753 Make_Attribute_Reference (Loc,
2755 New_Occurrence_Of (Stream_Parameter, Loc),
2759 Make_Attribute_Reference (Loc,
2761 New_Occurrence_Of (Result_Parameter, Loc),
2765 -- Read the exception occurrence from the result stream and
2766 -- reraise it. It does no harm if this is a Null_Occurrence since
2767 -- this does nothing.
2769 Append_To (Non_Asynchronous_Statements,
2770 Make_Attribute_Reference (Loc,
2772 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
2777 Expressions => New_List (
2778 Make_Attribute_Reference (Loc,
2780 New_Occurrence_Of (Result_Parameter, Loc),
2783 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2785 Append_To (Non_Asynchronous_Statements,
2786 Make_Procedure_Call_Statement (Loc,
2788 New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
2789 Parameter_Associations => New_List (
2790 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2794 -- If this is a function call, then read the value and return
2795 -- it. The return value is written/read using 'Output/'Input.
2797 Append_To (Non_Asynchronous_Statements,
2798 Make_Tag_Check (Loc,
2799 Make_Return_Statement (Loc,
2801 Make_Attribute_Reference (Loc,
2804 Etype (Subtype_Mark (Spec)), Loc),
2806 Attribute_Name => Name_Input,
2808 Expressions => New_List (
2809 Make_Attribute_Reference (Loc,
2811 New_Occurrence_Of (Result_Parameter, Loc),
2812 Attribute_Name => Name_Access))))));
2815 -- Loop around parameters and assign out (or in out) parameters.
2816 -- In the case of RACW, controlling arguments cannot possibly
2817 -- have changed since they are remote, so we do not read them
2820 Current_Parameter := First (Ordered_Parameters_List);
2821 while Current_Parameter /= Empty loop
2823 Typ : constant Node_Id :=
2824 Parameter_Type (Current_Parameter);
2831 (Defining_Identifier (Current_Parameter), Loc);
2833 if Nkind (Typ) = N_Access_Definition then
2834 Value := Make_Explicit_Dereference (Loc, Value);
2835 Etyp := Etype (Subtype_Mark (Typ));
2837 Etyp := Etype (Typ);
2840 if (Out_Present (Current_Parameter)
2841 or else Nkind (Typ) = N_Access_Definition)
2842 and then Etyp /= Stub_Type
2844 Append_To (Non_Asynchronous_Statements,
2845 Make_Attribute_Reference (Loc,
2847 New_Occurrence_Of (Etyp, Loc),
2849 Attribute_Name => Name_Read,
2851 Expressions => New_List (
2852 Make_Attribute_Reference (Loc,
2854 New_Occurrence_Of (Result_Parameter, Loc),
2861 Next (Current_Parameter);
2866 if Is_Known_Asynchronous then
2867 Append_List_To (Statements, Asynchronous_Statements);
2869 elsif Is_Known_Non_Asynchronous then
2870 Append_List_To (Statements, Non_Asynchronous_Statements);
2873 pragma Assert (Asynchronous /= Empty);
2874 Prepend_To (Asynchronous_Statements,
2875 Make_Attribute_Reference (Loc,
2876 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2877 Attribute_Name => Name_Write,
2878 Expressions => New_List (
2879 Make_Attribute_Reference (Loc,
2880 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2881 Attribute_Name => Name_Access),
2882 New_Occurrence_Of (Standard_True, Loc))));
2884 Prepend_To (Non_Asynchronous_Statements,
2885 Make_Attribute_Reference (Loc,
2886 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2887 Attribute_Name => Name_Write,
2888 Expressions => New_List (
2889 Make_Attribute_Reference (Loc,
2890 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2891 Attribute_Name => Name_Access),
2892 New_Occurrence_Of (Standard_False, Loc))));
2894 Append_To (Statements,
2895 Make_Implicit_If_Statement (Nod,
2896 Condition => Asynchronous,
2897 Then_Statements => Asynchronous_Statements,
2898 Else_Statements => Non_Asynchronous_Statements));
2900 end Build_General_Calling_Stubs;
2902 ------------------------------
2903 -- Build_Get_Unique_RP_Call --
2904 ------------------------------
2906 function Build_Get_Unique_RP_Call
2908 Pointer : Entity_Id;
2909 Stub_Type : Entity_Id) return List_Id
2913 Make_Procedure_Call_Statement (Loc,
2915 New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
2916 Parameter_Associations => New_List (
2917 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2918 New_Occurrence_Of (Pointer, Loc)))),
2920 Make_Assignment_Statement (Loc,
2922 Make_Selected_Component (Loc,
2924 New_Occurrence_Of (Pointer, Loc),
2926 New_Occurrence_Of (Tag_Component
2927 (Designated_Type (Etype (Pointer))), Loc)),
2929 Make_Attribute_Reference (Loc,
2931 New_Occurrence_Of (Stub_Type, Loc),
2935 -- Note: The assignment to Pointer._Tag is safe here because
2936 -- we carefully ensured that Stub_Type has exactly the same layout
2937 -- as System.Partition_Interface.RACW_Stub_Type.
2939 end Build_Get_Unique_RP_Call;
2941 ----------------------------------------
2942 -- Build_Remote_Subprogram_Proxy_Type --
2943 ----------------------------------------
2945 function Build_Remote_Subprogram_Proxy_Type
2947 ACR_Expression : Node_Id) return Node_Id
2951 Make_Record_Definition (Loc,
2952 Tagged_Present => True,
2953 Limited_Present => True,
2955 Make_Component_List (Loc,
2957 Component_Items => New_List (
2958 Make_Component_Declaration (Loc,
2959 Make_Defining_Identifier (Loc,
2960 Name_All_Calls_Remote),
2961 Make_Component_Definition (Loc,
2962 Subtype_Indication =>
2963 New_Occurrence_Of (Standard_Boolean, Loc)),
2966 Make_Component_Declaration (Loc,
2967 Make_Defining_Identifier (Loc,
2969 Make_Component_Definition (Loc,
2970 Subtype_Indication =>
2971 New_Occurrence_Of (RTE (RE_Address), Loc)),
2972 New_Occurrence_Of (RTE (RE_Null_Address), Loc)),
2974 Make_Component_Declaration (Loc,
2975 Make_Defining_Identifier (Loc,
2977 Make_Component_Definition (Loc,
2978 Subtype_Indication =>
2979 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))))));
2980 end Build_Remote_Subprogram_Proxy_Type;
2982 -----------------------------------
2983 -- Build_Ordered_Parameters_List --
2984 -----------------------------------
2986 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
2987 Constrained_List : List_Id;
2988 Unconstrained_List : List_Id;
2989 Current_Parameter : Node_Id;
2991 First_Parameter : Node_Id;
2992 For_RAS : Boolean := False;
2995 if not Present (Parameter_Specifications (Spec)) then
2999 Constrained_List := New_List;
3000 Unconstrained_List := New_List;
3001 First_Parameter := First (Parameter_Specifications (Spec));
3003 if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition
3004 and then Chars (Defining_Identifier (First_Parameter)) = Name_uS
3009 -- Loop through the parameters and add them to the right list
3011 Current_Parameter := First_Parameter;
3012 while Current_Parameter /= Empty loop
3013 if (Nkind (Parameter_Type (Current_Parameter)) = N_Access_Definition
3015 Is_Constrained (Etype (Parameter_Type (Current_Parameter)))
3017 Is_Elementary_Type (Etype (Parameter_Type (Current_Parameter))))
3018 and then not (For_RAS and then Current_Parameter = First_Parameter)
3020 Append_To (Constrained_List, New_Copy (Current_Parameter));
3022 Append_To (Unconstrained_List, New_Copy (Current_Parameter));
3025 Next (Current_Parameter);
3028 -- Unconstrained parameters are returned first
3030 Append_List_To (Unconstrained_List, Constrained_List);
3032 return Unconstrained_List;
3033 end Build_Ordered_Parameters_List;
3035 ----------------------------------
3036 -- Build_Passive_Partition_Stub --
3037 ----------------------------------
3039 procedure Build_Passive_Partition_Stub (U : Node_Id) is
3043 Loc : constant Source_Ptr := Sloc (U);
3046 -- Verify that the implementation supports distribution, by accessing
3047 -- a type defined in the proper version of system.rpc
3050 Dist_OK : Entity_Id;
3051 pragma Warnings (Off, Dist_OK);
3053 Dist_OK := RTE (RE_Params_Stream_Type);
3056 -- Use body if present, spec otherwise
3058 if Nkind (U) = N_Package_Declaration then
3059 Pkg_Spec := Specification (U);
3060 L := Visible_Declarations (Pkg_Spec);
3062 Pkg_Spec := Parent (Corresponding_Spec (U));
3063 L := Declarations (U);
3067 Make_Procedure_Call_Statement (Loc,
3069 New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
3070 Parameter_Associations => New_List (
3071 Make_String_Literal (Loc, Get_Pkg_Name_String_Id (Pkg_Spec)),
3072 Make_Attribute_Reference (Loc,
3074 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
3079 end Build_Passive_Partition_Stub;
3081 --------------------------------------
3082 -- Build_RPC_Receiver_Specification --
3083 --------------------------------------
3085 function Build_RPC_Receiver_Specification
3086 (RPC_Receiver : Entity_Id;
3087 Stream_Parameter : Entity_Id;
3088 Result_Parameter : Entity_Id) return Node_Id
3090 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
3094 Make_Procedure_Specification (Loc,
3095 Defining_Unit_Name => RPC_Receiver,
3096 Parameter_Specifications => New_List (
3097 Make_Parameter_Specification (Loc,
3098 Defining_Identifier => Stream_Parameter,
3100 Make_Access_Definition (Loc,
3102 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
3104 Make_Parameter_Specification (Loc,
3105 Defining_Identifier => Result_Parameter,
3107 Make_Access_Definition (Loc,
3110 (RTE (RE_Params_Stream_Type), Loc)))));
3111 end Build_RPC_Receiver_Specification;
3113 ------------------------------------
3114 -- Build_Subprogram_Calling_Stubs --
3115 ------------------------------------
3117 function Build_Subprogram_Calling_Stubs
3118 (Vis_Decl : Node_Id;
3120 Asynchronous : Boolean;
3121 Dynamically_Asynchronous : Boolean := False;
3122 Stub_Type : Entity_Id := Empty;
3123 Locator : Entity_Id := Empty;
3124 New_Name : Name_Id := No_Name) return Node_Id
3126 Loc : constant Source_Ptr := Sloc (Vis_Decl);
3128 Target_Partition : Node_Id;
3129 -- Contains the name of the target partition
3131 Decls : constant List_Id := New_List;
3132 Statements : constant List_Id := New_List;
3134 Subp_Spec : Node_Id;
3135 -- The specification of the body
3137 Controlling_Parameter : Entity_Id := Empty;
3138 RPC_Receiver : Node_Id;
3140 Asynchronous_Expr : Node_Id := Empty;
3142 RCI_Locator : Entity_Id;
3144 Spec_To_Use : Node_Id;
3146 procedure Insert_Partition_Check (Parameter : Node_Id);
3147 -- Check that the parameter has been elaborated on the same partition
3148 -- than the controlling parameter (E.4(19)).
3150 ----------------------------
3151 -- Insert_Partition_Check --
3152 ----------------------------
3154 procedure Insert_Partition_Check (Parameter : Node_Id) is
3155 Parameter_Entity : constant Entity_Id :=
3156 Defining_Identifier (Parameter);
3157 Condition : Node_Id;
3159 Designated_Object : Node_Id;
3160 pragma Warnings (Off, Designated_Object);
3161 -- Is it really right that this is unreferenced ???
3164 -- The expression that will be built is of the form:
3165 -- if not (Parameter in Stub_Type and then
3166 -- Parameter.Origin = Controlling.Origin)
3168 -- raise Constraint_Error;
3171 -- Condition contains the reversed condition. Also, Parameter is
3172 -- dereferenced if it is an access type. We do not check that
3173 -- Parameter is in Stub_Type since such a check has been inserted
3174 -- at the point of call already (a tag check since we have multiple
3175 -- controlling operands).
3177 if Nkind (Parameter_Type (Parameter)) = N_Access_Definition then
3178 Designated_Object :=
3179 Make_Explicit_Dereference (Loc,
3180 Prefix => New_Occurrence_Of (Parameter_Entity, Loc));
3182 Designated_Object := New_Occurrence_Of (Parameter_Entity, Loc);
3188 Make_Selected_Component (Loc,
3190 New_Occurrence_Of (Parameter_Entity, Loc),
3192 Make_Identifier (Loc, Name_Origin)),
3195 Make_Selected_Component (Loc,
3197 New_Occurrence_Of (Controlling_Parameter, Loc),
3199 Make_Identifier (Loc, Name_Origin)));
3202 Make_Raise_Constraint_Error (Loc,
3204 Make_Op_Not (Loc, Right_Opnd => Condition),
3205 Reason => CE_Partition_Check_Failed));
3206 end Insert_Partition_Check;
3208 -- Start of processing for Build_Subprogram_Calling_Stubs
3212 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3214 Subp_Spec := Copy_Specification (Loc,
3215 Spec => Specification (Vis_Decl),
3216 New_Name => New_Name);
3218 if Locator = Empty then
3219 RCI_Locator := RCI_Cache;
3220 Spec_To_Use := Specification (Vis_Decl);
3222 RCI_Locator := Locator;
3223 Spec_To_Use := Subp_Spec;
3226 -- Find a controlling argument if we have a stub type. Also check
3227 -- if this subprogram can be made asynchronous.
3229 if Stub_Type /= Empty
3230 and then Present (Parameter_Specifications (Spec_To_Use))
3233 Current_Parameter : Node_Id :=
3234 First (Parameter_Specifications
3237 while Current_Parameter /= Empty loop
3240 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
3242 if Controlling_Parameter = Empty then
3243 Controlling_Parameter :=
3244 Defining_Identifier (Current_Parameter);
3246 Insert_Partition_Check (Current_Parameter);
3250 Next (Current_Parameter);
3255 if Stub_Type /= Empty then
3256 pragma Assert (Controlling_Parameter /= Empty);
3259 Make_Object_Declaration (Loc,
3260 Defining_Identifier => Target_Partition,
3261 Constant_Present => True,
3262 Object_Definition =>
3263 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3266 Make_Selected_Component (Loc,
3268 New_Occurrence_Of (Controlling_Parameter, Loc),
3270 Make_Identifier (Loc, Name_Origin))));
3273 Make_Selected_Component (Loc,
3275 New_Occurrence_Of (Controlling_Parameter, Loc),
3277 Make_Identifier (Loc, Name_Receiver));
3281 Make_Object_Declaration (Loc,
3282 Defining_Identifier => Target_Partition,
3283 Constant_Present => True,
3284 Object_Definition =>
3285 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3288 Make_Function_Call (Loc,
3289 Name => Make_Selected_Component (Loc,
3291 Make_Identifier (Loc, Chars (RCI_Locator)),
3293 Make_Identifier (Loc, Name_Get_Active_Partition_ID)))));
3296 Make_Selected_Component (Loc,
3298 Make_Identifier (Loc, Chars (RCI_Locator)),
3300 Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
3303 if Dynamically_Asynchronous then
3304 Asynchronous_Expr :=
3305 Make_Selected_Component (Loc,
3307 New_Occurrence_Of (Controlling_Parameter, Loc),
3309 Make_Identifier (Loc, Name_Asynchronous));
3312 Build_General_Calling_Stubs
3314 Statements => Statements,
3315 Target_Partition => Target_Partition,
3316 RPC_Receiver => RPC_Receiver,
3317 Subprogram_Id => Make_Integer_Literal (Loc, Subp_Id),
3318 Asynchronous => Asynchronous_Expr,
3319 Is_Known_Asynchronous => Asynchronous
3320 and then not Dynamically_Asynchronous,
3321 Is_Known_Non_Asynchronous
3323 and then not Dynamically_Asynchronous,
3324 Is_Function => Nkind (Spec_To_Use) =
3325 N_Function_Specification,
3326 Spec => Spec_To_Use,
3327 Stub_Type => Stub_Type,
3330 RCI_Calling_Stubs_Table.Set
3331 (Defining_Unit_Name (Specification (Vis_Decl)),
3332 Defining_Unit_Name (Spec_To_Use));
3335 Make_Subprogram_Body (Loc,
3336 Specification => Subp_Spec,
3337 Declarations => Decls,
3338 Handled_Statement_Sequence =>
3339 Make_Handled_Sequence_Of_Statements (Loc, Statements));
3340 end Build_Subprogram_Calling_Stubs;
3342 -------------------------
3343 -- Build_Subprogram_Id --
3344 -------------------------
3346 function Build_Subprogram_Id
3348 E : Entity_Id) return Node_Id
3351 return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
3352 end Build_Subprogram_Id;
3354 --------------------------------------
3355 -- Build_Subprogram_Receiving_Stubs --
3356 --------------------------------------
3358 function Build_Subprogram_Receiving_Stubs
3359 (Vis_Decl : Node_Id;
3360 Asynchronous : Boolean;
3361 Dynamically_Asynchronous : Boolean := False;
3362 Stub_Type : Entity_Id := Empty;
3363 RACW_Type : Entity_Id := Empty;
3364 Parent_Primitive : Entity_Id := Empty) return Node_Id
3366 Loc : constant Source_Ptr := Sloc (Vis_Decl);
3368 Stream_Parameter : Node_Id;
3369 Result_Parameter : Node_Id;
3370 -- See explanations of those in Build_Subprogram_Calling_Stubs
3372 Decls : constant List_Id := New_List;
3373 -- All the parameters will get declared before calling the real
3374 -- subprograms. Also the out parameters will be declared.
3376 Statements : constant List_Id := New_List;
3378 Extra_Formal_Statements : constant List_Id := New_List;
3379 -- Statements concerning extra formal parameters
3381 After_Statements : constant List_Id := New_List;
3382 -- Statements to be executed after the subprogram call
3384 Inner_Decls : List_Id := No_List;
3385 -- In case of a function, the inner declarations are needed since
3386 -- the result may be unconstrained.
3388 Excep_Handler : Node_Id;
3389 Excep_Choice : Entity_Id;
3390 Excep_Code : List_Id;
3392 Parameter_List : constant List_Id := New_List;
3393 -- List of parameters to be passed to the subprogram
3395 Current_Parameter : Node_Id;
3397 Ordered_Parameters_List : constant List_Id :=
3398 Build_Ordered_Parameters_List
3399 (Specification (Vis_Decl));
3401 Subp_Spec : Node_Id;
3402 -- Subprogram specification
3404 Called_Subprogram : Node_Id;
3405 -- The subprogram to call
3407 Null_Raise_Statement : Node_Id;
3409 Dynamic_Async : Entity_Id;
3412 if RACW_Type /= Empty then
3413 Called_Subprogram :=
3414 New_Occurrence_Of (Parent_Primitive, Loc);
3416 Called_Subprogram :=
3418 Defining_Unit_Name (Specification (Vis_Decl)), Loc);
3422 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3424 if Dynamically_Asynchronous then
3426 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3428 Dynamic_Async := Empty;
3431 if not Asynchronous or else Dynamically_Asynchronous then
3433 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3435 -- The first statement after the subprogram call is a statement to
3436 -- writes a Null_Occurrence into the result stream.
3438 Null_Raise_Statement :=
3439 Make_Attribute_Reference (Loc,
3441 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3442 Attribute_Name => Name_Write,
3443 Expressions => New_List (
3444 New_Occurrence_Of (Result_Parameter, Loc),
3445 New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
3447 if Dynamically_Asynchronous then
3448 Null_Raise_Statement :=
3449 Make_Implicit_If_Statement (Vis_Decl,
3451 Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
3452 Then_Statements => New_List (Null_Raise_Statement));
3455 Append_To (After_Statements, Null_Raise_Statement);
3458 Result_Parameter := Empty;
3461 -- Loop through every parameter and get its value from the stream. If
3462 -- the parameter is unconstrained, then the parameter is read using
3463 -- 'Input at the point of declaration.
3465 Current_Parameter := First (Ordered_Parameters_List);
3467 while Current_Parameter /= Empty loop
3471 RACW_Controlling : Boolean;
3472 Constrained : Boolean;
3474 Expr : Node_Id := Empty;
3477 Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3478 Set_Ekind (Object, E_Variable);
3481 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type);
3483 if RACW_Controlling then
3485 -- We have a controlling formal parameter. Read its address
3486 -- rather than a real object. The address is in Unsigned_64
3489 Etyp := RTE (RE_Unsigned_64);
3491 Etyp := Etype (Parameter_Type (Current_Parameter));
3495 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
3497 if In_Present (Current_Parameter)
3498 or else not Out_Present (Current_Parameter)
3499 or else not Constrained
3500 or else RACW_Controlling
3502 -- If an input parameter is contrained, then its reading is
3503 -- deferred until the beginning of the subprogram body. If
3504 -- it is unconstrained, then an expression is built for
3505 -- the object declaration and the variable is set using
3506 -- 'Input instead of 'Read.
3508 if Constrained and then not RACW_Controlling then
3509 Append_To (Statements,
3510 Make_Attribute_Reference (Loc,
3511 Prefix => New_Occurrence_Of (Etyp, Loc),
3512 Attribute_Name => Name_Read,
3513 Expressions => New_List (
3514 New_Occurrence_Of (Stream_Parameter, Loc),
3515 New_Occurrence_Of (Object, Loc))));
3518 Expr := Input_With_Tag_Check (Loc,
3520 Stream => Stream_Parameter);
3521 Append_To (Decls, Expr);
3522 Expr := Make_Function_Call (Loc,
3523 New_Occurrence_Of (Defining_Unit_Name
3524 (Specification (Expr)), Loc));
3528 -- If we do not have to output the current parameter, then
3529 -- it can well be flagged as constant. This may allow further
3530 -- optimizations done by the back end.
3533 Make_Object_Declaration (Loc,
3534 Defining_Identifier => Object,
3536 not Constrained and then not Out_Present (Current_Parameter),
3537 Object_Definition =>
3538 New_Occurrence_Of (Etyp, Loc),
3539 Expression => Expr));
3541 -- An out parameter may be written back using a 'Write
3542 -- attribute instead of a 'Output because it has been
3543 -- constrained by the parameter given to the caller. Note that
3544 -- out controlling arguments in the case of a RACW are not put
3545 -- back in the stream because the pointer on them has not
3548 if Out_Present (Current_Parameter)
3550 Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
3552 Append_To (After_Statements,
3553 Make_Attribute_Reference (Loc,
3554 Prefix => New_Occurrence_Of (Etyp, Loc),
3555 Attribute_Name => Name_Write,
3556 Expressions => New_List (
3557 New_Occurrence_Of (Result_Parameter, Loc),
3558 New_Occurrence_Of (Object, Loc))));
3562 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
3564 if Nkind (Parameter_Type (Current_Parameter)) /=
3567 Append_To (Parameter_List,
3568 Make_Parameter_Association (Loc,
3571 Defining_Identifier (Current_Parameter), Loc),
3572 Explicit_Actual_Parameter =>
3573 Make_Explicit_Dereference (Loc,
3574 Unchecked_Convert_To (RACW_Type,
3575 OK_Convert_To (RTE (RE_Address),
3576 New_Occurrence_Of (Object, Loc))))));
3579 Append_To (Parameter_List,
3580 Make_Parameter_Association (Loc,
3583 Defining_Identifier (Current_Parameter), Loc),
3584 Explicit_Actual_Parameter =>
3585 Unchecked_Convert_To (RACW_Type,
3586 OK_Convert_To (RTE (RE_Address),
3587 New_Occurrence_Of (Object, Loc)))));
3591 Append_To (Parameter_List,
3592 Make_Parameter_Association (Loc,
3595 Defining_Identifier (Current_Parameter), Loc),
3596 Explicit_Actual_Parameter =>
3597 New_Occurrence_Of (Object, Loc)));
3600 -- If the current parameter needs an extra formal, then read it
3601 -- from the stream and set the corresponding semantic field in
3602 -- the variable. If the kind of the parameter identifier is
3603 -- E_Void, then this is a compiler generated parameter that
3604 -- doesn't need an extra constrained status.
3606 -- The case of Extra_Accessibility should also be handled ???
3608 if Nkind (Parameter_Type (Current_Parameter)) /=
3611 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
3613 Present (Extra_Constrained
3614 (Defining_Identifier (Current_Parameter)))
3617 Extra_Parameter : constant Entity_Id :=
3619 (Defining_Identifier
3620 (Current_Parameter));
3622 Formal_Entity : constant Entity_Id :=
3623 Make_Defining_Identifier
3624 (Loc, Chars (Extra_Parameter));
3626 Formal_Type : constant Entity_Id :=
3627 Etype (Extra_Parameter);
3631 Make_Object_Declaration (Loc,
3632 Defining_Identifier => Formal_Entity,
3633 Object_Definition =>
3634 New_Occurrence_Of (Formal_Type, Loc)));
3636 Append_To (Extra_Formal_Statements,
3637 Make_Attribute_Reference (Loc,
3638 Prefix => New_Occurrence_Of (Formal_Type, Loc),
3639 Attribute_Name => Name_Read,
3640 Expressions => New_List (
3641 New_Occurrence_Of (Stream_Parameter, Loc),
3642 New_Occurrence_Of (Formal_Entity, Loc))));
3643 Set_Extra_Constrained (Object, Formal_Entity);
3648 Next (Current_Parameter);
3651 -- Append the formal statements list at the end of regular statements
3653 Append_List_To (Statements, Extra_Formal_Statements);
3655 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
3657 -- The remote subprogram is a function. We build an inner block to
3658 -- be able to hold a potentially unconstrained result in a variable.
3661 Etyp : constant Entity_Id :=
3662 Etype (Subtype_Mark (Specification (Vis_Decl)));
3663 Result : constant Node_Id :=
3664 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3667 Inner_Decls := New_List (
3668 Make_Object_Declaration (Loc,
3669 Defining_Identifier => Result,
3670 Constant_Present => True,
3671 Object_Definition => New_Occurrence_Of (Etyp, Loc),
3673 Make_Function_Call (Loc,
3674 Name => Called_Subprogram,
3675 Parameter_Associations => Parameter_List)));
3677 Append_To (After_Statements,
3678 Make_Attribute_Reference (Loc,
3679 Prefix => New_Occurrence_Of (Etyp, Loc),
3680 Attribute_Name => Name_Output,
3681 Expressions => New_List (
3682 New_Occurrence_Of (Result_Parameter, Loc),
3683 New_Occurrence_Of (Result, Loc))));
3686 Append_To (Statements,
3687 Make_Block_Statement (Loc,
3688 Declarations => Inner_Decls,
3689 Handled_Statement_Sequence =>
3690 Make_Handled_Sequence_Of_Statements (Loc,
3691 Statements => After_Statements)));
3694 -- The remote subprogram is a procedure. We do not need any inner
3695 -- block in this case.
3697 if Dynamically_Asynchronous then
3699 Make_Object_Declaration (Loc,
3700 Defining_Identifier => Dynamic_Async,
3701 Object_Definition =>
3702 New_Occurrence_Of (Standard_Boolean, Loc)));
3704 Append_To (Statements,
3705 Make_Attribute_Reference (Loc,
3706 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
3707 Attribute_Name => Name_Read,
3708 Expressions => New_List (
3709 New_Occurrence_Of (Stream_Parameter, Loc),
3710 New_Occurrence_Of (Dynamic_Async, Loc))));
3713 Append_To (Statements,
3714 Make_Procedure_Call_Statement (Loc,
3715 Name => Called_Subprogram,
3716 Parameter_Associations => Parameter_List));
3718 Append_List_To (Statements, After_Statements);
3721 if Asynchronous and then not Dynamically_Asynchronous then
3723 -- An asynchronous procedure does not want a Result
3724 -- parameter. Also, we put an exception handler with an others
3725 -- clause that does nothing.
3728 Make_Procedure_Specification (Loc,
3729 Defining_Unit_Name =>
3730 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3731 Parameter_Specifications => New_List (
3732 Make_Parameter_Specification (Loc,
3733 Defining_Identifier => Stream_Parameter,
3735 Make_Access_Definition (Loc,
3737 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3740 Make_Exception_Handler (Loc,
3741 Exception_Choices =>
3742 New_List (Make_Others_Choice (Loc)),
3743 Statements => New_List (
3744 Make_Null_Statement (Loc)));
3747 -- In the other cases, if an exception is raised, then the
3748 -- exception occurrence is copied into the output stream and
3749 -- no other output parameter is written.
3752 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3754 Excep_Code := New_List (
3755 Make_Attribute_Reference (Loc,
3757 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3758 Attribute_Name => Name_Write,
3759 Expressions => New_List (
3760 New_Occurrence_Of (Result_Parameter, Loc),
3761 New_Occurrence_Of (Excep_Choice, Loc))));
3763 if Dynamically_Asynchronous then
3764 Excep_Code := New_List (
3765 Make_Implicit_If_Statement (Vis_Decl,
3766 Condition => Make_Op_Not (Loc,
3767 New_Occurrence_Of (Dynamic_Async, Loc)),
3768 Then_Statements => Excep_Code));
3772 Make_Exception_Handler (Loc,
3773 Choice_Parameter => Excep_Choice,
3774 Exception_Choices => New_List (Make_Others_Choice (Loc)),
3775 Statements => Excep_Code);
3778 Make_Procedure_Specification (Loc,
3779 Defining_Unit_Name =>
3780 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3782 Parameter_Specifications => New_List (
3783 Make_Parameter_Specification (Loc,
3784 Defining_Identifier => Stream_Parameter,
3786 Make_Access_Definition (Loc,
3788 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
3790 Make_Parameter_Specification (Loc,
3791 Defining_Identifier => Result_Parameter,
3793 Make_Access_Definition (Loc,
3795 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3799 Make_Subprogram_Body (Loc,
3800 Specification => Subp_Spec,
3801 Declarations => Decls,
3802 Handled_Statement_Sequence =>
3803 Make_Handled_Sequence_Of_Statements (Loc,
3804 Statements => Statements,
3805 Exception_Handlers => New_List (Excep_Handler)));
3806 end Build_Subprogram_Receiving_Stubs;
3808 ------------------------
3809 -- Copy_Specification --
3810 ------------------------
3812 function Copy_Specification
3815 Object_Type : Entity_Id := Empty;
3816 Stub_Type : Entity_Id := Empty;
3817 New_Name : Name_Id := No_Name) return Node_Id
3819 Parameters : List_Id := No_List;
3821 Current_Parameter : Node_Id;
3822 Current_Identifier : Entity_Id;
3823 Current_Type : Node_Id;
3824 Current_Etype : Entity_Id;
3826 Name_For_New_Spec : Name_Id;
3828 New_Identifier : Entity_Id;
3831 if New_Name = No_Name then
3832 pragma Assert (Nkind (Spec) = N_Function_Specification
3833 or else Nkind (Spec) = N_Procedure_Specification);
3835 Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
3837 Name_For_New_Spec := New_Name;
3840 if Present (Parameter_Specifications (Spec)) then
3841 Parameters := New_List;
3842 Current_Parameter := First (Parameter_Specifications (Spec));
3843 while Current_Parameter /= Empty loop
3844 Current_Identifier := Defining_Identifier (Current_Parameter);
3845 Current_Type := Parameter_Type (Current_Parameter);
3847 if Nkind (Current_Type) = N_Access_Definition then
3848 Current_Etype := Entity (Subtype_Mark (Current_Type));
3850 if Present (Object_Type) then
3852 Root_Type (Current_Etype) = Root_Type (Object_Type));
3854 Make_Access_Definition (Loc,
3855 Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc));
3858 Make_Access_Definition (Loc,
3860 New_Occurrence_Of (Current_Etype, Loc));
3864 Current_Etype := Entity (Current_Type);
3866 if Object_Type /= Empty
3867 and then Current_Etype = Object_Type
3869 Current_Type := New_Occurrence_Of (Stub_Type, Loc);
3871 Current_Type := New_Occurrence_Of (Current_Etype, Loc);
3875 New_Identifier := Make_Defining_Identifier (Loc,
3876 Chars (Current_Identifier));
3878 Append_To (Parameters,
3879 Make_Parameter_Specification (Loc,
3880 Defining_Identifier => New_Identifier,
3881 Parameter_Type => Current_Type,
3882 In_Present => In_Present (Current_Parameter),
3883 Out_Present => Out_Present (Current_Parameter),
3885 New_Copy_Tree (Expression (Current_Parameter))));
3887 Next (Current_Parameter);
3891 case Nkind (Spec) is
3893 when N_Function_Specification | N_Access_Function_Definition =>
3895 Make_Function_Specification (Loc,
3896 Defining_Unit_Name =>
3897 Make_Defining_Identifier (Loc,
3898 Chars => Name_For_New_Spec),
3899 Parameter_Specifications => Parameters,
3901 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
3903 when N_Procedure_Specification | N_Access_Procedure_Definition =>
3905 Make_Procedure_Specification (Loc,
3906 Defining_Unit_Name =>
3907 Make_Defining_Identifier (Loc,
3908 Chars => Name_For_New_Spec),
3909 Parameter_Specifications => Parameters);
3912 raise Program_Error;
3914 end Copy_Specification;
3916 ---------------------------
3917 -- Could_Be_Asynchronous --
3918 ---------------------------
3920 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
3921 Current_Parameter : Node_Id;
3924 if Present (Parameter_Specifications (Spec)) then
3925 Current_Parameter := First (Parameter_Specifications (Spec));
3926 while Current_Parameter /= Empty loop
3927 if Out_Present (Current_Parameter) then
3931 Next (Current_Parameter);
3936 end Could_Be_Asynchronous;
3938 ---------------------------------------------
3939 -- Expand_All_Calls_Remote_Subprogram_Call --
3940 ---------------------------------------------
3942 procedure Expand_All_Calls_Remote_Subprogram_Call (N : Node_Id) is
3943 Called_Subprogram : constant Entity_Id := Entity (Name (N));
3944 RCI_Package : constant Entity_Id := Scope (Called_Subprogram);
3945 Loc : constant Source_Ptr := Sloc (N);
3946 RCI_Locator : Node_Id;
3947 RCI_Cache : Entity_Id;
3948 Calling_Stubs : Node_Id;
3949 E_Calling_Stubs : Entity_Id;
3952 E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
3954 if E_Calling_Stubs = Empty then
3955 RCI_Cache := RCI_Locator_Table.Get (RCI_Package);
3957 if RCI_Cache = Empty then
3960 (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
3961 Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator);
3963 -- The RCI_Locator package is inserted at the top level in the
3964 -- current unit, and must appear in the proper scope, so that it
3965 -- is not prematurely removed by the GCC back-end.
3968 Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
3971 if Ekind (Scop) = E_Package_Body then
3972 New_Scope (Spec_Entity (Scop));
3974 elsif Ekind (Scop) = E_Subprogram_Body then
3976 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
3982 Analyze (RCI_Locator);
3986 RCI_Cache := Defining_Unit_Name (RCI_Locator);
3989 RCI_Locator := Parent (RCI_Cache);
3992 Calling_Stubs := Build_Subprogram_Calling_Stubs
3993 (Vis_Decl => Parent (Parent (Called_Subprogram)),
3994 Subp_Id => Get_Subprogram_Id (Called_Subprogram),
3995 Asynchronous => Nkind (N) = N_Procedure_Call_Statement
3997 Is_Asynchronous (Called_Subprogram),
3998 Locator => RCI_Cache,
3999 New_Name => New_Internal_Name ('S'));
4000 Insert_After (RCI_Locator, Calling_Stubs);
4001 Analyze (Calling_Stubs);
4002 E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
4005 Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
4006 end Expand_All_Calls_Remote_Subprogram_Call;
4008 ---------------------------------
4009 -- Expand_Calling_Stubs_Bodies --
4010 ---------------------------------
4012 procedure Expand_Calling_Stubs_Bodies (Unit_Node : Node_Id) is
4013 Spec : constant Node_Id := Specification (Unit_Node);
4014 Decls : constant List_Id := Visible_Declarations (Spec);
4017 New_Scope (Scope_Of_Spec (Spec));
4018 Add_Calling_Stubs_To_Declarations (Specification (Unit_Node),
4021 end Expand_Calling_Stubs_Bodies;
4023 -----------------------------------
4024 -- Expand_Receiving_Stubs_Bodies --
4025 -----------------------------------
4027 procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is
4033 if Nkind (Unit_Node) = N_Package_Declaration then
4034 Spec := Specification (Unit_Node);
4035 Decls := Visible_Declarations (Spec);
4036 New_Scope (Scope_Of_Spec (Spec));
4037 Add_Receiving_Stubs_To_Declarations (Spec, Decls);
4041 Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
4042 Decls := Declarations (Unit_Node);
4043 New_Scope (Scope_Of_Spec (Unit_Node));
4045 Add_Receiving_Stubs_To_Declarations (Spec, Temp);
4046 Insert_List_Before (First (Decls), Temp);
4050 end Expand_Receiving_Stubs_Bodies;
4052 ----------------------------
4053 -- Get_Pkg_Name_string_Id --
4054 ----------------------------
4056 function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id is
4057 Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
4060 Get_Unit_Name_String (Unit_Name_Id);
4062 -- Remove seven last character (" (spec)" or " (body)").
4064 Name_Len := Name_Len - 7;
4065 pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
4067 return Get_String_Id (Name_Buffer (1 .. Name_Len));
4068 end Get_Pkg_Name_String_Id;
4074 function Get_String_Id (Val : String) return String_Id is
4077 Store_String_Chars (Val);
4081 -----------------------
4082 -- Get_Subprogram_Id --
4083 -----------------------
4085 function Get_Subprogram_Id (E : Entity_Id) return Int is
4086 Current_Declaration : Node_Id;
4087 Result : Int := First_RCI_Subprogram_Id;
4091 (Is_Remote_Call_Interface (Scope (E))
4093 (Nkind (Parent (E)) = N_Procedure_Specification
4095 Nkind (Parent (E)) = N_Function_Specification));
4097 Current_Declaration :=
4098 First (Visible_Declarations
4099 (Package_Specification_Of_Scope (Scope (E))));
4101 while Current_Declaration /= Empty loop
4102 if Nkind (Current_Declaration) = N_Subprogram_Declaration
4103 and then Comes_From_Source (Current_Declaration)
4105 if Defining_Unit_Name
4106 (Specification (Current_Declaration)) = E
4111 Result := Result + 1;
4114 Next (Current_Declaration);
4117 -- Error if we do not find it
4119 raise Program_Error;
4120 end Get_Subprogram_Id;
4126 function Hash (F : Entity_Id) return Hash_Index is
4128 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
4131 --------------------------
4132 -- Input_With_Tag_Check --
4133 --------------------------
4135 function Input_With_Tag_Check
4137 Var_Type : Entity_Id;
4143 Make_Subprogram_Body (Loc,
4144 Specification => Make_Function_Specification (Loc,
4145 Defining_Unit_Name =>
4146 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
4147 Subtype_Mark => New_Occurrence_Of (Var_Type, Loc)),
4148 Declarations => No_List,
4149 Handled_Statement_Sequence =>
4150 Make_Handled_Sequence_Of_Statements (Loc, New_List (
4151 Make_Tag_Check (Loc,
4152 Make_Return_Statement (Loc,
4153 Make_Attribute_Reference (Loc,
4154 Prefix => New_Occurrence_Of (Var_Type, Loc),
4155 Attribute_Name => Name_Input,
4157 New_List (New_Occurrence_Of (Stream, Loc))))))));
4158 end Input_With_Tag_Check;
4160 --------------------------------
4161 -- Is_RACW_Controlling_Formal --
4162 --------------------------------
4164 function Is_RACW_Controlling_Formal
4165 (Parameter : Node_Id;
4166 Stub_Type : Entity_Id)
4172 -- If the kind of the parameter is E_Void, then it is not a
4173 -- controlling formal (this can happen in the context of RAS).
4175 if Ekind (Defining_Identifier (Parameter)) = E_Void then
4179 -- If the parameter is not a controlling formal, then it cannot
4180 -- be possibly a RACW_Controlling_Formal.
4182 if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
4186 Typ := Parameter_Type (Parameter);
4187 return (Nkind (Typ) = N_Access_Definition
4188 and then Etype (Subtype_Mark (Typ)) = Stub_Type)
4189 or else Etype (Typ) = Stub_Type;
4190 end Is_RACW_Controlling_Formal;
4192 --------------------
4193 -- Make_Tag_Check --
4194 --------------------
4196 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
4197 Occ : constant Entity_Id :=
4198 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
4201 return Make_Block_Statement (Loc,
4202 Handled_Statement_Sequence =>
4203 Make_Handled_Sequence_Of_Statements (Loc,
4204 Statements => New_List (N),
4206 Exception_Handlers => New_List (
4207 Make_Exception_Handler (Loc,
4208 Choice_Parameter => Occ,
4210 Exception_Choices =>
4211 New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
4214 New_List (Make_Procedure_Call_Statement (Loc,
4216 (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
4217 New_List (New_Occurrence_Of (Occ, Loc))))))));
4220 ----------------------------
4221 -- Need_Extra_Constrained --
4222 ----------------------------
4224 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
4225 Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
4228 return Out_Present (Parameter)
4229 and then Has_Discriminants (Etyp)
4230 and then not Is_Constrained (Etyp)
4231 and then not Is_Indefinite_Subtype (Etyp);
4232 end Need_Extra_Constrained;
4234 ------------------------------------
4235 -- Pack_Entity_Into_Stream_Access --
4236 ------------------------------------
4238 function Pack_Entity_Into_Stream_Access
4242 Etyp : Entity_Id := Empty) return Node_Id
4247 if Etyp /= Empty then
4250 Typ := Etype (Object);
4254 Pack_Node_Into_Stream_Access (Loc,
4256 Object => New_Occurrence_Of (Object, Loc),
4258 end Pack_Entity_Into_Stream_Access;
4260 ---------------------------
4261 -- Pack_Node_Into_Stream --
4262 ---------------------------
4264 function Pack_Node_Into_Stream
4268 Etyp : Entity_Id) return Node_Id
4270 Write_Attribute : Name_Id := Name_Write;
4273 if not Is_Constrained (Etyp) then
4274 Write_Attribute := Name_Output;
4278 Make_Attribute_Reference (Loc,
4279 Prefix => New_Occurrence_Of (Etyp, Loc),
4280 Attribute_Name => Write_Attribute,
4281 Expressions => New_List (
4282 Make_Attribute_Reference (Loc,
4283 Prefix => New_Occurrence_Of (Stream, Loc),
4284 Attribute_Name => Name_Access),
4286 end Pack_Node_Into_Stream;
4288 ----------------------------------
4289 -- Pack_Node_Into_Stream_Access --
4290 ----------------------------------
4292 function Pack_Node_Into_Stream_Access
4296 Etyp : Entity_Id) return Node_Id
4298 Write_Attribute : Name_Id := Name_Write;
4301 if not Is_Constrained (Etyp) then
4302 Write_Attribute := Name_Output;
4306 Make_Attribute_Reference (Loc,
4307 Prefix => New_Occurrence_Of (Etyp, Loc),
4308 Attribute_Name => Write_Attribute,
4309 Expressions => New_List (
4312 end Pack_Node_Into_Stream_Access;
4314 -------------------------------
4315 -- RACW_Type_Is_Asynchronous --
4316 -------------------------------
4318 procedure RACW_Type_Is_Asynchronous (RACW_Type : Entity_Id) is
4319 Asynchronous_Flag : constant Entity_Id :=
4320 Asynchronous_Flags_Table.Get (RACW_Type);
4322 Replace (Expression (Parent (Asynchronous_Flag)),
4323 New_Occurrence_Of (Standard_True, Sloc (Asynchronous_Flag)));
4324 end RACW_Type_Is_Asynchronous;
4326 -------------------------
4327 -- RCI_Package_Locator --
4328 -------------------------
4330 function RCI_Package_Locator
4332 Package_Spec : Node_Id) return Node_Id
4334 Inst : constant Node_Id :=
4335 Make_Package_Instantiation (Loc,
4336 Defining_Unit_Name =>
4337 Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
4339 New_Occurrence_Of (RTE (RE_RCI_Info), Loc),
4340 Generic_Associations => New_List (
4341 Make_Generic_Association (Loc,
4343 Make_Identifier (Loc, Name_RCI_Name),
4344 Explicit_Generic_Actual_Parameter =>
4345 Make_String_Literal (Loc,
4346 Strval => Get_Pkg_Name_String_Id (Package_Spec)))));
4349 RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
4350 Defining_Unit_Name (Inst));
4352 end RCI_Package_Locator;
4354 -----------------------------------------------
4355 -- Remote_Types_Tagged_Full_View_Encountered --
4356 -----------------------------------------------
4358 procedure Remote_Types_Tagged_Full_View_Encountered
4359 (Full_View : Entity_Id)
4361 Stub_Elements : constant Stub_Structure :=
4362 Stubs_Table.Get (Full_View);
4365 if Stub_Elements /= Empty_Stub_Structure then
4366 Add_RACW_Primitive_Declarations_And_Bodies
4368 Parent (Declaration_Node (Stub_Elements.Object_RPC_Receiver)),
4369 List_Containing (Declaration_Node (Full_View)));
4371 end Remote_Types_Tagged_Full_View_Encountered;
4377 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
4378 Unit_Name : Node_Id := Defining_Unit_Name (Spec);
4381 while Nkind (Unit_Name) /= N_Defining_Identifier loop
4382 Unit_Name := Defining_Identifier (Unit_Name);
4388 --------------------------
4389 -- Underlying_RACW_Type --
4390 --------------------------
4392 function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is
4393 Record_Type : Entity_Id;
4396 if Ekind (RAS_Typ) = E_Record_Type then
4397 Record_Type := RAS_Typ;
4399 pragma Assert (Present (Equivalent_Type (RAS_Typ)));
4400 Record_Type := Equivalent_Type (RAS_Typ);
4404 Etype (Subtype_Indication (
4405 Component_Definition (
4406 First (Component_Items (Component_List (
4407 Type_Definition (Declaration_Node (Record_Type))))))));
4408 end Underlying_RACW_Type;