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;
135 RACW_Type : Entity_Id := Empty;
137 -- Build calling stubs for general purpose. The parameters are:
138 -- Decls : a place to put declarations
139 -- Statements : a place to put statements
140 -- Target_Partition : a node containing the target partition that must
141 -- be a N_Defining_Identifier
142 -- RPC_Receiver : a node containing the RPC receiver
143 -- Subprogram_Id : a node containing the subprogram ID
144 -- Asynchronous : True if an APC must be made instead of an RPC.
145 -- The value needs not be supplied if one of the
146 -- Is_Known_... is True.
147 -- Is_Known_Async... : True if we know that this is asynchronous
148 -- Is_Known_Non_A... : True if we know that this is not asynchronous
149 -- Spec : a node with a Parameter_Specifications and
150 -- a Subtype_Mark if applicable
151 -- Stub_Type : in case of RACW stubs, parameters of type access
152 -- to Stub_Type will be marshalled using the
153 -- address of the object (the addr field) rather
154 -- than using the 'Write on the stub itself
155 -- Nod : used to provide sloc for generated code
157 function Build_Subprogram_Calling_Stubs
160 Asynchronous : Boolean;
161 Dynamically_Asynchronous : Boolean := False;
162 Stub_Type : Entity_Id := Empty;
163 RACW_Type : Entity_Id := Empty;
164 Locator : Entity_Id := Empty;
165 New_Name : Name_Id := No_Name) return Node_Id;
166 -- Build the calling stub for a given subprogram with the subprogram ID
167 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
168 -- parameters of this type will be marshalled instead of the object
169 -- itself. It will then be converted into Stub_Type before performing
170 -- the real call. If Dynamically_Asynchronous is True, then it will be
171 -- computed at run time whether the call is asynchronous or not.
172 -- Otherwise, the value of the formal Asynchronous will be used.
173 -- If Locator is not Empty, it will be used instead of RCI_Cache. If
174 -- New_Name is given, then it will be used instead of the original name.
176 function Build_Subprogram_Receiving_Stubs
178 Asynchronous : Boolean;
179 Dynamically_Asynchronous : Boolean := False;
180 Stub_Type : Entity_Id := Empty;
181 RACW_Type : Entity_Id := Empty;
182 Parent_Primitive : Entity_Id := Empty) return Node_Id;
183 -- Build the receiving stub for a given subprogram. The subprogram
184 -- declaration is also built by this procedure, and the value returned
185 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
186 -- found in the specification, then its address is read from the stream
187 -- instead of the object itself and converted into an access to
188 -- class-wide type before doing the real call using any of the RACW type
189 -- pointing on the designated type.
191 function Build_RPC_Receiver_Specification
192 (RPC_Receiver : Entity_Id;
193 Stream_Parameter : Entity_Id;
194 Result_Parameter : Entity_Id) return Node_Id;
195 -- Make a subprogram specification for an RPC receiver,
196 -- with the given defining unit name and formal parameters.
198 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
199 -- Return an ordered parameter list: unconstrained parameters are put
200 -- at the beginning of the list and constrained ones are put after. If
201 -- there are no parameters, an empty list is returned. Special case:
202 -- the controlling formal of the equivalent RACW operation for a RAS
203 -- type is always left in first position.
205 procedure Add_Calling_Stubs_To_Declarations
208 -- Add calling stubs to the declarative part
210 procedure Add_Receiving_Stubs_To_Declarations
213 -- Add receiving stubs to the declarative part
215 procedure Add_RAS_Dereference_TSS (N : Node_Id);
216 -- Add a subprogram body for RAS Dereference TSS
218 procedure Add_RAS_Access_TSS (N : Node_Id);
219 -- Add a subprogram body for RAS Access TSS
221 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
222 -- Return True if nothing prevents the program whose specification is
223 -- given to be asynchronous (i.e. no out parameter).
225 procedure Get_Pkg_Name_String (Decl_Node : Node_Id);
226 -- Retrieve the fully expanded name of the library unit declared by decl
227 -- into the name buffer.
229 function Pack_Entity_Into_Stream_Access
233 Etyp : Entity_Id := Empty) return Node_Id;
234 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
235 -- then Etype (Object) will be used if present. If the type is
236 -- constrained, then 'Write will be used to output the object,
237 -- If the type is unconstrained, 'Output will be used.
239 function Pack_Node_Into_Stream
243 Etyp : Entity_Id) return Node_Id;
244 -- Similar to above, with an arbitrary node instead of an entity
246 function Pack_Node_Into_Stream_Access
250 Etyp : Entity_Id) return Node_Id;
251 -- Similar to above, with Stream instead of Stream'Access
253 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
254 -- Return the scope represented by a given spec
256 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
257 -- Return True if the current parameter needs an extra formal to reflect
258 -- its constrained status.
260 function Is_RACW_Controlling_Formal
261 (Parameter : Node_Id; Stub_Type : Entity_Id) return Boolean;
262 -- Return True if the current parameter is a controlling formal argument
263 -- of type Stub_Type or access to Stub_Type.
265 type Stub_Structure is record
266 Stub_Type : Entity_Id;
267 Stub_Type_Access : Entity_Id;
268 Object_RPC_Receiver : Entity_Id;
269 RPC_Receiver_Stream : Entity_Id;
270 RPC_Receiver_Result : Entity_Id;
271 RACW_Type : Entity_Id;
273 -- This structure is necessary because of the two phases analysis of
274 -- a RACW declaration occurring in the same Remote_Types package as the
275 -- designated type. RACW_Type is any of the RACW types pointing on this
276 -- designated type, it is used here to save an anonymous type creation
277 -- for each primitive operation.
279 Empty_Stub_Structure : constant Stub_Structure :=
280 (Empty, Empty, Empty, Empty, Empty, Empty);
282 type Hash_Index is range 0 .. 50;
283 function Hash (F : Entity_Id) return Hash_Index;
285 package Stubs_Table is
286 new Simple_HTable (Header_Num => Hash_Index,
287 Element => Stub_Structure,
288 No_Element => Empty_Stub_Structure,
292 -- Mapping between a RACW designated type and its stub type
294 package Asynchronous_Flags_Table is
295 new Simple_HTable (Header_Num => Hash_Index,
296 Element => Entity_Id,
301 -- Mapping between a RACW type and a constant having the value True
302 -- if the RACW is asynchronous and False otherwise.
304 package RCI_Locator_Table is
305 new Simple_HTable (Header_Num => Hash_Index,
306 Element => Entity_Id,
311 -- Mapping between a RCI package on which All_Calls_Remote applies and
312 -- the generic instantiation of RCI_Locator for this package.
314 package RCI_Calling_Stubs_Table is
315 new Simple_HTable (Header_Num => Hash_Index,
316 Element => Entity_Id,
321 -- Mapping between a RCI subprogram and the corresponding calling stubs
323 procedure Add_Stub_Type
324 (Designated_Type : Entity_Id;
325 RACW_Type : Entity_Id;
327 Stub_Type : out Entity_Id;
328 Stub_Type_Access : out Entity_Id;
329 Object_RPC_Receiver : out Entity_Id;
330 Existing : out Boolean);
331 -- Add the declaration of the stub type, the access to stub type and the
332 -- object RPC receiver at the end of Decls. If these already exist,
333 -- then nothing is added in the tree but the right values are returned
334 -- anyhow and Existing is set to True.
336 procedure Add_RACW_Asynchronous_Flag
337 (Declarations : List_Id;
338 RACW_Type : Entity_Id);
339 -- Declare a boolean constant associated with RACW_Type whose value
340 -- indicates at run time whether a pragma Asynchronous applies to it.
342 procedure Add_RACW_Read_Attribute
343 (RACW_Type : Entity_Id;
344 Stub_Type : Entity_Id;
345 Stub_Type_Access : Entity_Id;
346 Declarations : List_Id);
347 -- Add Read attribute in Decls for the RACW type. The Read attribute
348 -- is added right after the RACW_Type declaration while the body is
349 -- inserted after Declarations.
351 procedure Add_RACW_Write_Attribute
352 (RACW_Type : Entity_Id;
353 Stub_Type : Entity_Id;
354 Stub_Type_Access : Entity_Id;
355 Object_RPC_Receiver : Entity_Id;
356 Declarations : List_Id);
357 -- Same thing for the Write attribute
359 procedure Add_RACW_Read_Write_Attributes
360 (RACW_Type : Entity_Id;
361 Stub_Type : Entity_Id;
362 Stub_Type_Access : Entity_Id;
363 Object_RPC_Receiver : Entity_Id;
364 Declarations : List_Id);
365 -- Add Read and Write attributes declarations and bodies for a given
366 -- RACW type. The declarations are added just after the declaration
367 -- of the RACW type itself, while the bodies are inserted at the end
370 function RCI_Package_Locator
372 Package_Spec : Node_Id) return Node_Id;
373 -- Instantiate the generic package RCI_Locator in order to locate the
374 -- RCI package whose spec is given as argument.
376 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
377 -- Surround a node N by a tag check, as in:
381 -- when E : Ada.Tags.Tag_Error =>
382 -- Raise_Exception (Program_Error'Identity,
383 -- Exception_Message (E));
386 function Input_With_Tag_Check
388 Var_Type : Entity_Id;
389 Stream : Entity_Id) return Node_Id;
390 -- Return a function with the following form:
391 -- function R return Var_Type is
393 -- return Var_Type'Input (S);
395 -- when E : Ada.Tags.Tag_Error =>
396 -- Raise_Exception (Program_Error'Identity,
397 -- Exception_Message (E));
400 ------------------------------------
401 -- Local variables and structures --
402 ------------------------------------
406 Output_From_Constrained : constant array (Boolean) of Name_Id :=
407 (False => Name_Output,
409 -- The attribute to choose depending on the fact that the parameter
410 -- is constrained or not. There is no such thing as Input_From_Constrained
411 -- since this require separate mechanisms ('Input is a function while
412 -- 'Read is a procedure).
414 ---------------------------------------
415 -- Add_Calling_Stubs_To_Declarations --
416 ---------------------------------------
418 procedure Add_Calling_Stubs_To_Declarations
422 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
423 -- Subprogram id 0 is reserved for calls received from
424 -- remote access-to-subprogram dereferences.
426 Current_Declaration : Node_Id;
427 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
428 RCI_Instantiation : Node_Id;
429 Subp_Stubs : Node_Id;
432 -- The first thing added is an instantiation of the generic package
433 -- System.Partition_interface.RCI_Locator with the name of this
434 -- remote package. This will act as an interface with the name server
435 -- to determine the Partition_ID and the RPC_Receiver for the
436 -- receiver of this package.
438 RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
439 RCI_Cache := Defining_Unit_Name (RCI_Instantiation);
441 Append_To (Decls, RCI_Instantiation);
442 Analyze (RCI_Instantiation);
444 -- For each subprogram declaration visible in the spec, we do
445 -- build a body. We also increment a counter to assign a different
446 -- Subprogram_Id to each subprograms. The receiving stubs processing
447 -- do use the same mechanism and will thus assign the same Id and
448 -- do the correct dispatching.
450 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
451 while Current_Declaration /= Empty loop
452 if Nkind (Current_Declaration) = N_Subprogram_Declaration
453 and then Comes_From_Source (Current_Declaration)
455 pragma Assert (Current_Subprogram_Number =
456 Get_Subprogram_Id (Defining_Unit_Name (Specification (
457 Current_Declaration))));
460 Build_Subprogram_Calling_Stubs (
461 Vis_Decl => Current_Declaration,
462 Subp_Id => Current_Subprogram_Number,
464 Nkind (Specification (Current_Declaration)) =
465 N_Procedure_Specification
467 Is_Asynchronous (Defining_Unit_Name (Specification
468 (Current_Declaration))));
470 Append_To (Decls, Subp_Stubs);
471 Analyze (Subp_Stubs);
473 Current_Subprogram_Number := Current_Subprogram_Number + 1;
476 Next (Current_Declaration);
478 end Add_Calling_Stubs_To_Declarations;
480 --------------------------------
481 -- Add_RACW_Asynchronous_Flag --
482 --------------------------------
484 procedure Add_RACW_Asynchronous_Flag
485 (Declarations : List_Id;
486 RACW_Type : Entity_Id)
488 Loc : constant Source_Ptr := Sloc (RACW_Type);
490 Asynchronous_Flag : constant Entity_Id :=
491 Make_Defining_Identifier (Loc,
492 New_External_Name (Chars (RACW_Type), 'A'));
495 -- Declare the asynchronous flag. This flag will be changed to True
496 -- whenever it is known that the RACW type is asynchronous.
498 Append_To (Declarations,
499 Make_Object_Declaration (Loc,
500 Defining_Identifier => Asynchronous_Flag,
501 Constant_Present => True,
502 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
503 Expression => New_Occurrence_Of (Standard_False, Loc)));
505 Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Flag);
506 end Add_RACW_Asynchronous_Flag;
508 -----------------------
509 -- Add_RACW_Features --
510 -----------------------
512 procedure Add_RACW_Features (RACW_Type : Entity_Id)
514 Desig : constant Entity_Id :=
515 Etype (Designated_Type (RACW_Type));
517 List_Containing (Declaration_Node (RACW_Type));
519 Same_Scope : constant Boolean :=
520 Scope (Desig) = Scope (RACW_Type);
522 Stub_Type : Entity_Id;
523 Stub_Type_Access : Entity_Id;
524 Object_RPC_Receiver : Entity_Id;
528 if not Expander_Active then
534 -- We are declaring a RACW in the same package than its designated
535 -- type, so the list to use for late declarations must be the
536 -- private part of the package. We do know that this private part
537 -- exists since the designated type has to be a private one.
539 Decls := Private_Declarations
540 (Package_Specification_Of_Scope (Current_Scope));
542 elsif Nkind (Parent (Decls)) = N_Package_Specification
543 and then Present (Private_Declarations (Parent (Decls)))
545 Decls := Private_Declarations (Parent (Decls));
548 -- If we were unable to find the declarations, that means that the
549 -- completion of the type was missing. We can safely return and let
550 -- the error be caught by the semantic analysis.
557 (Designated_Type => Desig,
558 RACW_Type => RACW_Type,
560 Stub_Type => Stub_Type,
561 Stub_Type_Access => Stub_Type_Access,
562 Object_RPC_Receiver => Object_RPC_Receiver,
563 Existing => Existing);
565 Add_RACW_Asynchronous_Flag
566 (Declarations => Decls,
567 RACW_Type => RACW_Type);
569 Add_RACW_Read_Write_Attributes
570 (RACW_Type => RACW_Type,
571 Stub_Type => Stub_Type,
572 Stub_Type_Access => Stub_Type_Access,
573 Object_RPC_Receiver => Object_RPC_Receiver,
574 Declarations => Decls);
576 if not Same_Scope and then not Existing then
578 -- The RACW has been declared in another scope than the designated
579 -- type and has not been handled by another RACW in the same package
580 -- as the first one, so add primitive for the stub type here.
582 Add_RACW_Primitive_Declarations_And_Bodies
583 (Designated_Type => Desig,
585 Parent (Declaration_Node (Object_RPC_Receiver)),
589 Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
591 end Add_RACW_Features;
593 ------------------------------------------------
594 -- Add_RACW_Primitive_Declarations_And_Bodies --
595 ------------------------------------------------
597 procedure Add_RACW_Primitive_Declarations_And_Bodies
598 (Designated_Type : Entity_Id;
599 Insertion_Node : Node_Id;
602 -- Set sloc of generated declaration copy of insertion node sloc, so
603 -- the declarations are recognized as belonging to the current package.
605 Loc : constant Source_Ptr := Sloc (Insertion_Node);
607 Stub_Elements : constant Stub_Structure :=
608 Stubs_Table.Get (Designated_Type);
610 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
612 Current_Insertion_Node : Node_Id := Insertion_Node;
614 RPC_Receiver_Declarations : List_Id;
615 RPC_Receiver_Statements : List_Id;
616 RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
617 RPC_Receiver_Subp_Id : Entity_Id;
619 Current_Primitive_Elmt : Elmt_Id;
620 Current_Primitive : Entity_Id;
621 Current_Primitive_Body : Node_Id;
622 Current_Primitive_Spec : Node_Id;
623 Current_Primitive_Decl : Node_Id;
624 Current_Primitive_Number : Int := 0;
626 Current_Primitive_Alias : Node_Id;
628 Current_Receiver : Entity_Id;
629 Current_Receiver_Body : Node_Id;
631 RPC_Receiver_Decl : Node_Id;
633 Possibly_Asynchronous : Boolean;
636 if not Expander_Active then
640 -- Build callers, receivers for every primitive operations and a RPC
641 -- receiver for this type.
643 if Present (Primitive_Operations (Designated_Type)) then
645 Current_Primitive_Elmt :=
646 First_Elmt (Primitive_Operations (Designated_Type));
647 while Current_Primitive_Elmt /= No_Elmt loop
648 Current_Primitive := Node (Current_Primitive_Elmt);
650 -- Copy the primitive of all the parents, except predefined
651 -- ones that are not remotely dispatching.
653 if Chars (Current_Primitive) /= Name_uSize
654 and then Chars (Current_Primitive) /= Name_uAlignment
655 and then not Is_TSS (Current_Primitive, TSS_Deep_Finalize)
657 -- The first thing to do is build an up-to-date copy of
658 -- the spec with all the formals referencing Designated_Type
659 -- transformed into formals referencing Stub_Type. Since this
660 -- primitive may have been inherited, go back the alias chain
661 -- until the real primitive has been found.
663 Current_Primitive_Alias := Current_Primitive;
664 while Present (Alias (Current_Primitive_Alias)) loop
666 (Current_Primitive_Alias
667 /= Alias (Current_Primitive_Alias));
668 Current_Primitive_Alias := Alias (Current_Primitive_Alias);
671 Current_Primitive_Spec :=
672 Copy_Specification (Loc,
673 Spec => Parent (Current_Primitive_Alias),
674 Object_Type => Designated_Type,
675 Stub_Type => Stub_Elements.Stub_Type);
677 Current_Primitive_Decl :=
678 Make_Subprogram_Declaration (Loc,
679 Specification => Current_Primitive_Spec);
681 Insert_After (Current_Insertion_Node, Current_Primitive_Decl);
682 Analyze (Current_Primitive_Decl);
683 Current_Insertion_Node := Current_Primitive_Decl;
685 Possibly_Asynchronous :=
686 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
687 and then Could_Be_Asynchronous (Current_Primitive_Spec);
689 Current_Primitive_Body :=
690 Build_Subprogram_Calling_Stubs
691 (Vis_Decl => Current_Primitive_Decl,
692 Subp_Id => Current_Primitive_Number,
693 Asynchronous => Possibly_Asynchronous,
694 Dynamically_Asynchronous => Possibly_Asynchronous,
695 Stub_Type => Stub_Elements.Stub_Type);
696 Append_To (Decls, Current_Primitive_Body);
698 -- Analyzing the body here would cause the Stub type to be
699 -- frozen, thus preventing subsequent primitive declarations.
700 -- For this reason, it will be analyzed later in the
703 -- Build the receiver stubs
705 Current_Receiver_Body :=
706 Build_Subprogram_Receiving_Stubs
707 (Vis_Decl => Current_Primitive_Decl,
708 Asynchronous => Possibly_Asynchronous,
709 Dynamically_Asynchronous => Possibly_Asynchronous,
710 Stub_Type => Stub_Elements.Stub_Type,
711 RACW_Type => Stub_Elements.RACW_Type,
712 Parent_Primitive => Current_Primitive);
715 Defining_Unit_Name (Specification (Current_Receiver_Body));
717 Append_To (Decls, Current_Receiver_Body);
719 -- Add a case alternative to the receiver
721 Append_To (RPC_Receiver_Case_Alternatives,
722 Make_Case_Statement_Alternative (Loc,
723 Discrete_Choices => New_List (
724 Make_Integer_Literal (Loc, Current_Primitive_Number)),
726 Statements => New_List (
727 Make_Procedure_Call_Statement (Loc,
729 New_Occurrence_Of (Current_Receiver, Loc),
730 Parameter_Associations => New_List (
732 (Stub_Elements.RPC_Receiver_Stream, Loc),
734 (Stub_Elements.RPC_Receiver_Result, Loc))))));
736 -- Increment the index of current primitive
738 Current_Primitive_Number := Current_Primitive_Number + 1;
741 Next_Elmt (Current_Primitive_Elmt);
745 -- Build the case statement and the heart of the subprogram
747 Append_To (RPC_Receiver_Case_Alternatives,
748 Make_Case_Statement_Alternative (Loc,
749 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
750 Statements => New_List (Make_Null_Statement (Loc))));
752 RPC_Receiver_Subp_Id :=
753 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
755 RPC_Receiver_Declarations := New_List (
756 Make_Object_Declaration (Loc,
757 Defining_Identifier => RPC_Receiver_Subp_Id,
759 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
761 RPC_Receiver_Statements := New_List (
762 Make_Attribute_Reference (Loc,
764 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
767 Expressions => New_List (
768 New_Occurrence_Of (Stub_Elements.RPC_Receiver_Stream, Loc),
769 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc))));
771 Append_To (RPC_Receiver_Statements,
772 Make_Case_Statement (Loc,
774 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
775 Alternatives => RPC_Receiver_Case_Alternatives));
778 Make_Subprogram_Body (Loc,
780 Copy_Specification (Loc,
781 Parent (Stub_Elements.Object_RPC_Receiver)),
782 Declarations => RPC_Receiver_Declarations,
783 Handled_Statement_Sequence =>
784 Make_Handled_Sequence_Of_Statements (Loc,
785 Statements => RPC_Receiver_Statements));
787 Append_To (Decls, RPC_Receiver_Decl);
789 -- Do not analyze RPC receiver at this stage since it will otherwise
790 -- reference subprograms that have not been analyzed yet. It will
791 -- be analyzed in the regular flow.
793 end Add_RACW_Primitive_Declarations_And_Bodies;
795 -----------------------------
796 -- Add_RACW_Read_Attribute --
797 -----------------------------
799 procedure Add_RACW_Read_Attribute
800 (RACW_Type : Entity_Id;
801 Stub_Type : Entity_Id;
802 Stub_Type_Access : Entity_Id;
803 Declarations : List_Id)
805 Loc : constant Source_Ptr := Sloc (RACW_Type);
813 Statements : List_Id;
814 Local_Statements : List_Id;
815 Remote_Statements : List_Id;
816 -- Various parts of the procedure
818 Procedure_Name : constant Name_Id :=
819 New_Internal_Name ('R');
820 Source_Partition : constant Entity_Id :=
821 Make_Defining_Identifier
822 (Loc, New_Internal_Name ('P'));
823 Source_Receiver : constant Entity_Id :=
824 Make_Defining_Identifier
825 (Loc, New_Internal_Name ('S'));
826 Source_Address : constant Entity_Id :=
827 Make_Defining_Identifier
828 (Loc, New_Internal_Name ('P'));
829 Local_Stub : constant Entity_Id :=
830 Make_Defining_Identifier
831 (Loc, New_Internal_Name ('L'));
832 Stubbed_Result : constant Entity_Id :=
833 Make_Defining_Identifier
834 (Loc, New_Internal_Name ('S'));
835 Asynchronous_Flag : constant Entity_Id :=
836 Asynchronous_Flags_Table.Get (RACW_Type);
837 pragma Assert (Present (Asynchronous_Flag));
839 function Stream_Parameter return Node_Id;
840 function Result return Node_Id;
841 -- Functions to create occurrences of the formal parameter names
847 function Result return Node_Id is
849 return Make_Identifier (Loc, Name_V);
852 ----------------------
853 -- Stream_Parameter --
854 ----------------------
856 function Stream_Parameter return Node_Id is
858 return Make_Identifier (Loc, Name_S);
859 end Stream_Parameter;
861 -- Start of processing for Add_RACW_Read_Attribute
864 -- Generate object declarations
867 Make_Object_Declaration (Loc,
868 Defining_Identifier => Source_Partition,
870 New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
872 Make_Object_Declaration (Loc,
873 Defining_Identifier => Source_Receiver,
875 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
877 Make_Object_Declaration (Loc,
878 Defining_Identifier => Source_Address,
880 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
882 Make_Object_Declaration (Loc,
883 Defining_Identifier => Local_Stub,
884 Aliased_Present => True,
885 Object_Definition => New_Occurrence_Of (Stub_Type, Loc)),
887 Make_Object_Declaration (Loc,
888 Defining_Identifier => Stubbed_Result,
890 New_Occurrence_Of (Stub_Type_Access, Loc),
892 Make_Attribute_Reference (Loc,
894 New_Occurrence_Of (Local_Stub, Loc),
896 Name_Unchecked_Access)));
898 -- Read the source Partition_ID and RPC_Receiver from incoming stream
900 Statements := New_List (
901 Make_Attribute_Reference (Loc,
903 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
904 Attribute_Name => Name_Read,
905 Expressions => New_List (
907 New_Occurrence_Of (Source_Partition, Loc))),
909 Make_Attribute_Reference (Loc,
911 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
914 Expressions => New_List (
916 New_Occurrence_Of (Source_Receiver, Loc))),
918 Make_Attribute_Reference (Loc,
920 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
923 Expressions => New_List (
925 New_Occurrence_Of (Source_Address, Loc))));
927 -- Build_Get_Unique_RP_Call needs the type of Stubbed_Result
929 Set_Etype (Stubbed_Result, Stub_Type_Access);
931 -- If the Address is Null_Address, then return a null object
933 Append_To (Statements,
934 Make_Implicit_If_Statement (RACW_Type,
937 Left_Opnd => New_Occurrence_Of (Source_Address, Loc),
938 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
939 Then_Statements => New_List (
940 Make_Assignment_Statement (Loc,
942 Expression => Make_Null (Loc)),
943 Make_Return_Statement (Loc))));
945 -- If the RACW denotes an object created on the current partition, then
946 -- Local_Statements will be executed. The real object will be used.
948 Local_Statements := New_List (
949 Make_Assignment_Statement (Loc,
952 Unchecked_Convert_To (RACW_Type,
953 OK_Convert_To (RTE (RE_Address),
954 New_Occurrence_Of (Source_Address, Loc)))));
956 -- If the object is located on another partition, then a stub object
957 -- will be created with all the information needed to rebuild the
958 -- real object at the other end.
960 Remote_Statements := New_List (
962 Make_Assignment_Statement (Loc,
963 Name => Make_Selected_Component (Loc,
964 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
965 Selector_Name => Make_Identifier (Loc, Name_Origin)),
967 New_Occurrence_Of (Source_Partition, Loc)),
969 Make_Assignment_Statement (Loc,
970 Name => Make_Selected_Component (Loc,
971 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
972 Selector_Name => Make_Identifier (Loc, Name_Receiver)),
974 New_Occurrence_Of (Source_Receiver, Loc)),
976 Make_Assignment_Statement (Loc,
977 Name => Make_Selected_Component (Loc,
978 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
979 Selector_Name => Make_Identifier (Loc, Name_Addr)),
981 New_Occurrence_Of (Source_Address, Loc)));
983 Append_To (Remote_Statements,
984 Make_Assignment_Statement (Loc,
985 Name => Make_Selected_Component (Loc,
986 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
987 Selector_Name => Make_Identifier (Loc, Name_Asynchronous)),
989 New_Occurrence_Of (Asynchronous_Flag, Loc)));
991 Append_List_To (Remote_Statements,
992 Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
993 -- ??? Issue with asynchronous calls here: the Asynchronous
994 -- flag is set on the stub type if, and only if, the RACW type
995 -- has a pragma Asynchronous. This is incorrect for RACWs that
996 -- implement RAS types, because in that case the /designated
997 -- subprogram/ (not the type) might be asynchronous, and
998 -- that causes the stub to need to be asynchronous too.
999 -- A solution is to transport a RAS as a struct containing
1000 -- a RACW and an asynchronous flag, and to properly alter
1001 -- the Asynchronous component in the stub type in the RAS's
1004 Append_To (Remote_Statements,
1005 Make_Assignment_Statement (Loc,
1007 Expression => Unchecked_Convert_To (RACW_Type,
1008 New_Occurrence_Of (Stubbed_Result, Loc))));
1010 -- Distinguish between the local and remote cases, and execute the
1011 -- appropriate piece of code.
1013 Append_To (Statements,
1014 Make_Implicit_If_Statement (RACW_Type,
1018 Make_Function_Call (Loc,
1020 New_Occurrence_Of (RTE (RE_Get_Local_Partition_Id), Loc)),
1021 Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
1022 Then_Statements => Local_Statements,
1023 Else_Statements => Remote_Statements));
1025 Build_Stream_Procedure
1026 (Loc, RACW_Type, Body_Node,
1027 Make_Defining_Identifier (Loc, Procedure_Name),
1028 Statements, Outp => True);
1029 Set_Declarations (Body_Node, Decls);
1031 Proc_Decl := Make_Subprogram_Declaration (Loc,
1032 Copy_Specification (Loc, Specification (Body_Node)));
1035 Make_Attribute_Definition_Clause (Loc,
1036 Name => New_Occurrence_Of (RACW_Type, Loc),
1040 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
1042 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
1043 Insert_After (Proc_Decl, Attr_Decl);
1044 Append_To (Declarations, Body_Node);
1045 end Add_RACW_Read_Attribute;
1047 ------------------------------------
1048 -- Add_RACW_Read_Write_Attributes --
1049 ------------------------------------
1051 procedure Add_RACW_Read_Write_Attributes
1052 (RACW_Type : Entity_Id;
1053 Stub_Type : Entity_Id;
1054 Stub_Type_Access : Entity_Id;
1055 Object_RPC_Receiver : Entity_Id;
1056 Declarations : List_Id)
1059 Add_RACW_Write_Attribute
1060 (RACW_Type => RACW_Type,
1061 Stub_Type => Stub_Type,
1062 Stub_Type_Access => Stub_Type_Access,
1063 Object_RPC_Receiver => Object_RPC_Receiver,
1064 Declarations => Declarations);
1066 Add_RACW_Read_Attribute
1067 (RACW_Type => RACW_Type,
1068 Stub_Type => Stub_Type,
1069 Stub_Type_Access => Stub_Type_Access,
1070 Declarations => Declarations);
1071 end Add_RACW_Read_Write_Attributes;
1073 ------------------------------
1074 -- Add_RACW_Write_Attribute --
1075 ------------------------------
1077 procedure Add_RACW_Write_Attribute
1078 (RACW_Type : Entity_Id;
1079 Stub_Type : Entity_Id;
1080 Stub_Type_Access : Entity_Id;
1081 Object_RPC_Receiver : Entity_Id;
1082 Declarations : List_Id)
1084 Loc : constant Source_Ptr := Sloc (RACW_Type);
1086 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
1088 Body_Node : Node_Id;
1089 Proc_Decl : Node_Id;
1090 Attr_Decl : Node_Id;
1092 RPC_Receiver : Node_Id;
1094 Statements : List_Id;
1095 Local_Statements : List_Id;
1096 Remote_Statements : List_Id;
1097 Null_Statements : List_Id;
1099 Procedure_Name : constant Name_Id := New_Internal_Name ('R');
1101 -- Functions to create occurrences of the formal
1104 function Stream_Parameter return Node_Id;
1105 function Object return Node_Id;
1107 function Stream_Parameter return Node_Id is
1109 return Make_Identifier (Loc, Name_S);
1110 end Stream_Parameter;
1112 function Object return Node_Id is
1114 return Make_Identifier (Loc, Name_V);
1118 -- Build the code fragment corresponding to the marshalling of a
1123 -- For a RAS, the RPC receiver is that of the RCI unit,
1124 -- not that of the corresponding distributed object type.
1125 -- We retrieve its address from the local proxy object.
1127 RPC_Receiver := Make_Selected_Component (Loc,
1129 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object),
1131 Make_Identifier (Loc, Name_Receiver));
1134 RPC_Receiver := Make_Attribute_Reference (Loc,
1136 New_Occurrence_Of (Object_RPC_Receiver, Loc),
1141 Local_Statements := New_List (
1143 Pack_Entity_Into_Stream_Access (Loc,
1144 Stream => Stream_Parameter,
1145 Object => RTE (RE_Get_Local_Partition_Id)),
1147 Pack_Node_Into_Stream_Access (Loc,
1148 Stream => Stream_Parameter,
1149 Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
1150 Etyp => RTE (RE_Unsigned_64)),
1152 Pack_Node_Into_Stream_Access (Loc,
1153 Stream => Stream_Parameter,
1154 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1155 Make_Attribute_Reference (Loc,
1157 Make_Explicit_Dereference (Loc,
1159 Attribute_Name => Name_Address)),
1160 Etyp => RTE (RE_Unsigned_64)));
1162 -- Build the code fragment corresponding to the marshalling of
1165 Remote_Statements := New_List (
1167 Pack_Node_Into_Stream_Access (Loc,
1168 Stream => Stream_Parameter,
1170 Make_Selected_Component (Loc,
1171 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1174 Make_Identifier (Loc, Name_Origin)),
1175 Etyp => RTE (RE_Partition_ID)),
1177 Pack_Node_Into_Stream_Access (Loc,
1178 Stream => Stream_Parameter,
1180 Make_Selected_Component (Loc,
1181 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1184 Make_Identifier (Loc, Name_Receiver)),
1185 Etyp => RTE (RE_Unsigned_64)),
1187 Pack_Node_Into_Stream_Access (Loc,
1188 Stream => Stream_Parameter,
1190 Make_Selected_Component (Loc,
1191 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1194 Make_Identifier (Loc, Name_Addr)),
1195 Etyp => RTE (RE_Unsigned_64)));
1197 -- Build the code fragment corresponding to the marshalling of a null
1200 Null_Statements := New_List (
1202 Pack_Entity_Into_Stream_Access (Loc,
1203 Stream => Stream_Parameter,
1204 Object => RTE (RE_Get_Local_Partition_Id)),
1206 Pack_Node_Into_Stream_Access (Loc,
1207 Stream => Stream_Parameter,
1208 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1209 Make_Attribute_Reference (Loc,
1210 Prefix => New_Occurrence_Of (Object_RPC_Receiver, Loc),
1211 Attribute_Name => Name_Address)),
1212 Etyp => RTE (RE_Unsigned_64)),
1214 Pack_Node_Into_Stream_Access (Loc,
1215 Stream => Stream_Parameter,
1216 Object => Make_Integer_Literal (Loc, Uint_0),
1217 Etyp => RTE (RE_Unsigned_64)));
1219 Statements := New_List (
1220 Make_Implicit_If_Statement (RACW_Type,
1223 Left_Opnd => Object,
1224 Right_Opnd => Make_Null (Loc)),
1225 Then_Statements => Null_Statements,
1226 Elsif_Parts => New_List (
1227 Make_Elsif_Part (Loc,
1231 Make_Attribute_Reference (Loc,
1233 Attribute_Name => Name_Tag),
1235 Make_Attribute_Reference (Loc,
1236 Prefix => New_Occurrence_Of (Stub_Type, Loc),
1237 Attribute_Name => Name_Tag)),
1238 Then_Statements => Remote_Statements)),
1239 Else_Statements => Local_Statements));
1241 Build_Stream_Procedure
1242 (Loc, RACW_Type, Body_Node,
1243 Make_Defining_Identifier (Loc, Procedure_Name),
1244 Statements, Outp => False);
1246 Proc_Decl := Make_Subprogram_Declaration (Loc,
1247 Copy_Specification (Loc, Specification (Body_Node)));
1250 Make_Attribute_Definition_Clause (Loc,
1251 Name => New_Occurrence_Of (RACW_Type, Loc),
1252 Chars => Name_Write,
1255 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
1257 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
1258 Insert_After (Proc_Decl, Attr_Decl);
1259 Append_To (Declarations, Body_Node);
1260 end Add_RACW_Write_Attribute;
1262 ------------------------
1263 -- Add_RAS_Access_TSS --
1264 ------------------------
1266 procedure Add_RAS_Access_TSS (N : Node_Id) is
1267 Loc : constant Source_Ptr := Sloc (N);
1269 Ras_Type : constant Entity_Id := Defining_Identifier (N);
1270 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
1271 -- Ras_Type is the access to subprogram type while Fat_Type points to
1272 -- the record type corresponding to a remote access to subprogram type.
1274 RACW_Type : constant Entity_Id :=
1275 Underlying_RACW_Type (Ras_Type);
1276 Desig : constant Entity_Id :=
1277 Etype (Designated_Type (RACW_Type));
1279 Stub_Elements : constant Stub_Structure :=
1280 Stubs_Table.Get (Desig);
1281 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1283 Proc : constant Entity_Id :=
1284 Make_Defining_Identifier (Loc,
1285 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
1286 Proc_Spec : Node_Id;
1288 -- Formal parameters
1290 Package_Name : constant Entity_Id :=
1291 Make_Defining_Identifier (Loc,
1295 Subp_Id : constant Entity_Id :=
1296 Make_Defining_Identifier (Loc,
1298 -- Target subprogram
1300 Asynch_P : constant Entity_Id :=
1301 Make_Defining_Identifier (Loc,
1302 Chars => Name_Asynchronous);
1303 -- Is the procedure to which the 'Access applies asynchronous?
1305 All_Calls_Remote : constant Entity_Id :=
1306 Make_Defining_Identifier (Loc,
1307 Chars => Name_All_Calls_Remote);
1308 -- True if an All_Calls_Remote pragma applies to the RCI unit
1309 -- that contains the subprogram.
1311 -- Common local variables
1313 Proc_Decls : List_Id;
1314 Proc_Statements : List_Id;
1316 Origin : constant Entity_Id :=
1317 Make_Defining_Identifier (Loc,
1318 Chars => New_Internal_Name ('P'));
1320 -- Additional local variables for the local case
1322 Proxy_Addr : constant Entity_Id :=
1323 Make_Defining_Identifier (Loc,
1324 Chars => New_Internal_Name ('P'));
1326 -- Additional local variables for the remote case
1328 Local_Stub : constant Entity_Id :=
1329 Make_Defining_Identifier (Loc,
1330 Chars => New_Internal_Name ('L'));
1332 Stub_Ptr : constant Entity_Id :=
1333 Make_Defining_Identifier (Loc,
1334 Chars => New_Internal_Name ('S'));
1337 (Field_Name : Name_Id;
1338 Value : Node_Id) return Node_Id;
1339 -- Construct an assignment that sets the named component in the
1347 (Field_Name : Name_Id;
1348 Value : Node_Id) return Node_Id
1352 Make_Assignment_Statement (Loc,
1354 Make_Selected_Component (Loc,
1355 Prefix => New_Occurrence_Of (Stub_Ptr, Loc),
1356 Selector_Name => Make_Identifier (Loc, Field_Name)),
1357 Expression => Value);
1360 -- Start of processing for Add_RAS_Access_TSS
1363 Proc_Decls := New_List (
1365 -- Common declarations
1367 Make_Object_Declaration (Loc,
1368 Defining_Identifier => Origin,
1369 Constant_Present => True,
1370 Object_Definition =>
1371 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
1373 Make_Function_Call (Loc,
1375 New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
1376 Parameter_Associations => New_List (
1377 New_Occurrence_Of (Package_Name, Loc)))),
1379 -- Declaration use only in the local case: proxy address
1381 Make_Object_Declaration (Loc,
1382 Defining_Identifier => Proxy_Addr,
1383 Object_Definition =>
1384 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
1386 -- Declarations used only in the remote case: stub object and
1389 Make_Object_Declaration (Loc,
1390 Defining_Identifier => Local_Stub,
1391 Aliased_Present => True,
1392 Object_Definition =>
1393 New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
1395 Make_Object_Declaration (Loc,
1396 Defining_Identifier =>
1398 Object_Definition =>
1399 New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
1401 Make_Attribute_Reference (Loc,
1402 Prefix => New_Occurrence_Of (Local_Stub, Loc),
1403 Attribute_Name => Name_Unchecked_Access)));
1405 Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
1406 -- Build_Get_Unique_RP_Call needs this information
1408 -- Note: Here we assume that the Fat_Type is a record
1409 -- containing just a pointer to a proxy or stub object.
1411 Proc_Statements := New_List (
1415 -- Get_RAS_Info (Pkg, Subp, PA);
1416 -- if Origin = Local_Partition_Id and then not All_Calls_Remote then
1417 -- return Fat_Type!(PA);
1420 Make_Procedure_Call_Statement (Loc,
1422 New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
1423 Parameter_Associations => New_List (
1424 New_Occurrence_Of (Package_Name, Loc),
1425 New_Occurrence_Of (Subp_Id, Loc),
1426 New_Occurrence_Of (Proxy_Addr, Loc))),
1428 Make_Implicit_If_Statement (N,
1434 New_Occurrence_Of (Origin, Loc),
1436 Make_Function_Call (Loc,
1438 RTE (RE_Get_Local_Partition_Id), Loc))),
1441 New_Occurrence_Of (All_Calls_Remote, Loc))),
1442 Then_Statements => New_List (
1443 Make_Return_Statement (Loc,
1444 Unchecked_Convert_To (Fat_Type,
1445 OK_Convert_To (RTE (RE_Address),
1446 New_Occurrence_Of (Proxy_Addr, Loc)))))),
1448 Set_Field (Name_Origin,
1449 New_Occurrence_Of (Origin, Loc)),
1451 Set_Field (Name_Receiver,
1452 Make_Function_Call (Loc,
1454 New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
1455 Parameter_Associations => New_List (
1456 New_Occurrence_Of (Package_Name, Loc)))),
1458 Set_Field (Name_Addr, New_Occurrence_Of (Proxy_Addr, Loc)),
1460 -- E.4.1(9) A remote call is asynchronous if it is a call to
1461 -- a procedure, or a call through a value of an access-to-procedure
1462 -- type, to which a pragma Asynchronous applies.
1464 -- Parameter Asynch_P is true when the procedure is asynchronous;
1465 -- Expression Asynch_T is true when the type is asynchronous.
1467 Set_Field (Name_Asynchronous,
1469 New_Occurrence_Of (Asynch_P, Loc),
1470 New_Occurrence_Of (Boolean_Literals (
1471 Is_Asynchronous (Ras_Type)), Loc))));
1473 Append_List_To (Proc_Statements,
1474 Build_Get_Unique_RP_Call
1475 (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
1477 -- Return the newly created value
1479 Append_To (Proc_Statements,
1480 Make_Return_Statement (Loc,
1482 Unchecked_Convert_To (Fat_Type,
1483 New_Occurrence_Of (Stub_Ptr, Loc))));
1486 Make_Function_Specification (Loc,
1487 Defining_Unit_Name => Proc,
1488 Parameter_Specifications => New_List (
1489 Make_Parameter_Specification (Loc,
1490 Defining_Identifier => Package_Name,
1492 New_Occurrence_Of (Standard_String, Loc)),
1494 Make_Parameter_Specification (Loc,
1495 Defining_Identifier => Subp_Id,
1497 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)),
1499 Make_Parameter_Specification (Loc,
1500 Defining_Identifier => Asynch_P,
1502 New_Occurrence_Of (Standard_Boolean, Loc)),
1504 Make_Parameter_Specification (Loc,
1505 Defining_Identifier => All_Calls_Remote,
1507 New_Occurrence_Of (Standard_Boolean, Loc))),
1510 New_Occurrence_Of (Fat_Type, Loc));
1512 -- Set the kind and return type of the function to prevent ambiguities
1513 -- between Ras_Type and Fat_Type in subsequent analysis.
1515 Set_Ekind (Proc, E_Function);
1516 Set_Etype (Proc, New_Occurrence_Of (Fat_Type, Loc));
1519 Make_Subprogram_Body (Loc,
1520 Specification => Proc_Spec,
1521 Declarations => Proc_Decls,
1522 Handled_Statement_Sequence =>
1523 Make_Handled_Sequence_Of_Statements (Loc,
1524 Statements => Proc_Statements)));
1526 Set_TSS (Fat_Type, Proc);
1527 end Add_RAS_Access_TSS;
1529 -----------------------------
1530 -- Add_RAS_Dereference_TSS --
1531 -----------------------------
1533 -- This subprogram could use more comments ???
1535 procedure Add_RAS_Dereference_TSS (N : Node_Id) is
1536 Loc : constant Source_Ptr := Sloc (N);
1538 Type_Def : constant Node_Id := Type_Definition (N);
1540 RAS_Type : constant Entity_Id := Defining_Identifier (N);
1541 Fat_Type : constant Entity_Id := Equivalent_Type (RAS_Type);
1542 RACW_Type : constant Entity_Id := Underlying_RACW_Type (RAS_Type);
1543 Desig : constant Entity_Id := Etype (Designated_Type (RACW_Type));
1545 Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
1546 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1548 RACW_Primitive_Name : Node_Id;
1550 Proc : constant Entity_Id :=
1551 Make_Defining_Identifier (Loc,
1552 Chars => Make_TSS_Name (RAS_Type, TSS_RAS_Dereference));
1554 Proc_Spec : Node_Id;
1555 Param_Specs : List_Id;
1556 Param_Assoc : constant List_Id := New_List;
1557 Stmts : constant List_Id := New_List;
1559 RAS_Parameter : constant Entity_Id :=
1560 Make_Defining_Identifier (Loc,
1561 Chars => New_Internal_Name ('P'));
1563 Is_Function : constant Boolean :=
1564 Nkind (Type_Def) = N_Access_Function_Definition;
1566 Is_Degenerate : Boolean;
1567 -- Set to True if the subprogram_specification for this RAS has
1568 -- an anonymous access parameter (see Process_Remote_AST_Declaration).
1570 Spec : constant Node_Id := Type_Def;
1572 Current_Parameter : Node_Id;
1575 Param_Specs := New_List (
1576 Make_Parameter_Specification (Loc,
1577 Defining_Identifier => RAS_Parameter,
1580 New_Occurrence_Of (Fat_Type, Loc)));
1582 Is_Degenerate := False;
1583 Current_Parameter := First (Parameter_Specifications (Type_Def));
1584 Parameters : while Current_Parameter /= Empty loop
1585 if Nkind (Parameter_Type (Current_Parameter))
1586 = N_Access_Definition
1588 Is_Degenerate := True;
1590 Append_To (Param_Specs,
1591 Make_Parameter_Specification (Loc,
1592 Defining_Identifier =>
1593 Make_Defining_Identifier (Loc,
1594 Chars => Chars (Defining_Identifier (Current_Parameter))),
1595 In_Present => In_Present (Current_Parameter),
1596 Out_Present => Out_Present (Current_Parameter),
1598 New_Copy_Tree (Parameter_Type (Current_Parameter)),
1600 New_Copy_Tree (Expression (Current_Parameter))));
1602 Append_To (Param_Assoc,
1603 Make_Identifier (Loc,
1604 Chars => Chars (Defining_Identifier (Current_Parameter))));
1606 Next (Current_Parameter);
1607 end loop Parameters;
1609 if Is_Degenerate then
1610 Prepend_To (Param_Assoc, New_Occurrence_Of (RAS_Parameter, Loc));
1612 -- Generate a dummy body recursing on the Dereference TSS, since
1613 -- actually it will never be executed.
1616 Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
1617 RACW_Primitive_Name := New_Occurrence_Of (Proc, Loc);
1620 Prepend_To (Param_Assoc,
1621 Unchecked_Convert_To (RACW_Type,
1622 New_Occurrence_Of (RAS_Parameter, Loc)));
1624 RACW_Primitive_Name :=
1625 Make_Selected_Component (Loc,
1627 New_Occurrence_Of (Scope (RACW_Type), Loc),
1629 Make_Identifier (Loc, Name_Call));
1634 Make_Return_Statement (Loc,
1636 Make_Function_Call (Loc,
1638 RACW_Primitive_Name,
1639 Parameter_Associations => Param_Assoc)));
1643 Make_Procedure_Call_Statement (Loc,
1645 RACW_Primitive_Name,
1646 Parameter_Associations => Param_Assoc));
1649 -- Build the complete subprogram
1653 Make_Function_Specification (Loc,
1654 Defining_Unit_Name => Proc,
1655 Parameter_Specifications => Param_Specs,
1658 Entity (Subtype_Mark (Spec)), Loc));
1660 Set_Ekind (Proc, E_Function);
1662 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
1666 Make_Procedure_Specification (Loc,
1667 Defining_Unit_Name => Proc,
1668 Parameter_Specifications => Param_Specs);
1670 Set_Ekind (Proc, E_Procedure);
1671 Set_Etype (Proc, Standard_Void_Type);
1675 Make_Subprogram_Body (Loc,
1676 Specification => Proc_Spec,
1677 Declarations => New_List,
1678 Handled_Statement_Sequence =>
1679 Make_Handled_Sequence_Of_Statements (Loc,
1680 Statements => Stmts)));
1682 Set_TSS (Fat_Type, Proc);
1683 end Add_RAS_Dereference_TSS;
1685 -------------------------------
1686 -- Add_RAS_Proxy_And_Analyze --
1687 -------------------------------
1689 procedure Add_RAS_Proxy_And_Analyze
1692 All_Calls_Remote_E : Entity_Id;
1693 Proxy_Object_Addr : out Entity_Id)
1695 Loc : constant Source_Ptr := Sloc (Vis_Decl);
1697 Subp_Name : constant Entity_Id :=
1698 Defining_Unit_Name (Specification (Vis_Decl));
1700 Pkg_Name : constant Entity_Id :=
1701 Make_Defining_Identifier (Loc,
1703 New_External_Name (Chars (Subp_Name), 'P', -1));
1705 Proxy_Type : constant Entity_Id :=
1706 Make_Defining_Identifier (Loc,
1709 Related_Id => Chars (Subp_Name),
1712 Proxy_Type_Full_View : constant Entity_Id :=
1713 Make_Defining_Identifier (Loc,
1714 Chars (Proxy_Type));
1716 Subp_Decl_Spec : constant Node_Id :=
1717 Build_RAS_Primitive_Specification
1718 (Subp_Spec => Specification (Vis_Decl),
1719 Remote_Object_Type => Proxy_Type);
1721 Subp_Body_Spec : constant Node_Id :=
1722 Build_RAS_Primitive_Specification
1723 (Subp_Spec => Specification (Vis_Decl),
1724 Remote_Object_Type => Proxy_Type);
1726 Vis_Decls : constant List_Id := New_List;
1727 Pvt_Decls : constant List_Id := New_List;
1728 Actuals : constant List_Id := New_List;
1730 Perform_Call : Node_Id;
1733 -- type subpP is tagged limited private;
1735 Append_To (Vis_Decls,
1736 Make_Private_Type_Declaration (Loc,
1737 Defining_Identifier => Proxy_Type,
1738 Tagged_Present => True,
1739 Limited_Present => True));
1741 -- [subprogram] Call
1742 -- (Self : access subpP;
1743 -- ...other-formals...)
1746 Append_To (Vis_Decls,
1747 Make_Subprogram_Declaration (Loc,
1748 Specification => Subp_Decl_Spec));
1750 -- A : constant System.Address;
1752 Proxy_Object_Addr := Make_Defining_Identifier (Loc, Name_uA);
1754 Append_To (Vis_Decls,
1755 Make_Object_Declaration (Loc,
1756 Defining_Identifier =>
1760 Object_Definition =>
1761 New_Occurrence_Of (RTE (RE_Address), Loc)));
1765 -- type subpP is tagged limited record
1766 -- All_Calls_Remote : Boolean := [All_Calls_Remote?];
1770 Append_To (Pvt_Decls,
1771 Make_Full_Type_Declaration (Loc,
1772 Defining_Identifier =>
1773 Proxy_Type_Full_View,
1775 Build_Remote_Subprogram_Proxy_Type (Loc,
1776 New_Occurrence_Of (All_Calls_Remote_E, Loc))));
1778 -- Trick semantic analysis into swapping the public and
1779 -- full view when freezing the public view.
1781 Set_Comes_From_Source (Proxy_Type_Full_View, True);
1784 -- (Self : access O;
1785 -- ...other-formals...) is
1787 -- P (...other-formals...);
1791 -- (Self : access O;
1792 -- ...other-formals...)
1795 -- return F (...other-formals...);
1798 if Nkind (Subp_Decl_Spec) = N_Procedure_Specification then
1800 Make_Procedure_Call_Statement (Loc,
1802 New_Occurrence_Of (Subp_Name, Loc),
1803 Parameter_Associations =>
1807 Make_Return_Statement (Loc,
1809 Make_Function_Call (Loc,
1811 New_Occurrence_Of (Subp_Name, Loc),
1812 Parameter_Associations =>
1816 Formal := First (Parameter_Specifications (Subp_Decl_Spec));
1817 pragma Assert (Present (Formal));
1820 while Present (Formal) loop
1821 Append_To (Actuals, New_Occurrence_Of (
1822 Defining_Identifier (Formal), Loc));
1826 -- O : aliased subpP;
1828 Append_To (Pvt_Decls,
1829 Make_Object_Declaration (Loc,
1830 Defining_Identifier =>
1831 Make_Defining_Identifier (Loc,
1835 Object_Definition =>
1836 New_Occurrence_Of (Proxy_Type, Loc)));
1838 -- A : constant System.Address := O'Address;
1840 Append_To (Pvt_Decls,
1841 Make_Object_Declaration (Loc,
1842 Defining_Identifier =>
1843 Make_Defining_Identifier (Loc,
1844 Chars (Proxy_Object_Addr)),
1847 Object_Definition =>
1848 New_Occurrence_Of (RTE (RE_Address), Loc),
1850 Make_Attribute_Reference (Loc,
1851 Prefix => New_Occurrence_Of (
1852 Defining_Identifier (Last (Pvt_Decls)), Loc),
1857 Make_Package_Declaration (Loc,
1858 Specification => Make_Package_Specification (Loc,
1859 Defining_Unit_Name => Pkg_Name,
1860 Visible_Declarations => Vis_Decls,
1861 Private_Declarations => Pvt_Decls,
1862 End_Label => Empty)));
1863 Analyze (Last (Decls));
1866 Make_Package_Body (Loc,
1867 Defining_Unit_Name =>
1868 Make_Defining_Identifier (Loc,
1870 Declarations => New_List (
1871 Make_Subprogram_Body (Loc,
1874 Declarations => New_List,
1875 Handled_Statement_Sequence =>
1876 Make_Handled_Sequence_Of_Statements (Loc,
1877 Statements => New_List (Perform_Call))))));
1878 Analyze (Last (Decls));
1879 end Add_RAS_Proxy_And_Analyze;
1881 -----------------------
1882 -- Add_RAST_Features --
1883 -----------------------
1885 procedure Add_RAST_Features (Vis_Decl : Node_Id) is
1887 -- Do not add attributes more than once in any case. This should
1888 -- be replaced by an assert or this comment removed if we decide
1889 -- that this is normal to be called several times ???
1891 if Present (TSS (Equivalent_Type (Defining_Identifier (Vis_Decl)),
1897 Add_RAS_Dereference_TSS (Vis_Decl);
1898 Add_RAS_Access_TSS (Vis_Decl);
1899 end Add_RAST_Features;
1901 -----------------------------------------
1902 -- Add_Receiving_Stubs_To_Declarations --
1903 -----------------------------------------
1905 procedure Add_Receiving_Stubs_To_Declarations
1906 (Pkg_Spec : Node_Id;
1909 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
1911 Stream_Parameter : Node_Id;
1912 Result_Parameter : Node_Id;
1914 Pkg_RPC_Receiver : Node_Id;
1915 Pkg_RPC_Receiver_Spec : Node_Id;
1916 Pkg_RPC_Receiver_Decls : List_Id;
1917 Pkg_RPC_Receiver_Statements : List_Id;
1918 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
1919 Pkg_RPC_Receiver_Body : Node_Id;
1920 -- A Pkg_RPC_Receiver is built to decode the request
1922 Lookup_RAS_Info : constant Entity_Id :=
1923 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
1924 -- A remote subprogram is created to allow peers to look up
1925 -- RAS information using subprogram ids.
1928 -- Subprogram_Id as read from the incoming stream
1930 Current_Declaration : Node_Id;
1931 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
1932 Current_Stubs : Node_Id;
1934 Subp_Info_Array : constant Entity_Id :=
1935 Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
1937 Subp_Info_List : constant List_Id := New_List;
1939 Register_Pkg_Actuals : constant List_Id := New_List;
1941 Dummy_Register_Name : Name_Id;
1942 Dummy_Register_Spec : Node_Id;
1943 Dummy_Register_Decl : Node_Id;
1944 Dummy_Register_Body : Node_Id;
1946 All_Calls_Remote_E : Entity_Id;
1947 Proxy_Object_Addr : Entity_Id;
1949 procedure Append_Stubs_To
1950 (RPC_Receiver_Cases : List_Id;
1951 Declaration : Node_Id;
1953 Subprogram_Number : Int);
1954 -- Add one case to the specified RPC receiver case list
1955 -- associating Subprogram_Number with the subprogram declared
1956 -- by Declaration, for which we have receiving stubs in Stubs.
1958 ---------------------
1959 -- Append_Stubs_To --
1960 ---------------------
1962 procedure Append_Stubs_To
1963 (RPC_Receiver_Cases : List_Id;
1964 Declaration : Node_Id;
1966 Subprogram_Number : Int)
1968 Actuals : constant List_Id :=
1969 New_List (New_Occurrence_Of (Stream_Parameter, Loc));
1971 if Nkind (Specification (Declaration)) = N_Function_Specification
1973 Is_Asynchronous (Defining_Entity (Specification (Declaration)))
1975 -- An asynchronous procedure does not want an output parameter
1976 -- since no result and no exception will ever be returned.
1979 New_Occurrence_Of (Result_Parameter, Loc));
1982 Append_To (RPC_Receiver_Cases,
1983 Make_Case_Statement_Alternative (Loc,
1986 Make_Integer_Literal (Loc, Subprogram_Number)),
1990 Make_Procedure_Call_Statement (Loc,
1993 Defining_Entity (Stubs), Loc),
1994 Parameter_Associations =>
1996 end Append_Stubs_To;
1998 -- Start of processing for Add_Receiving_Stubs_To_Declarations
2001 -- Building receiving stubs consist in several operations:
2003 -- - a package RPC receiver must be built. This subprogram
2004 -- will get a Subprogram_Id from the incoming stream
2005 -- and will dispatch the call to the right subprogram
2007 -- - a receiving stub for any subprogram visible in the package
2008 -- spec. This stub will read all the parameters from the stream,
2009 -- and put the result as well as the exception occurrence in the
2012 -- - a dummy package with an empty spec and a body made of an
2013 -- elaboration part, whose job is to register the receiving
2014 -- part of this RCI package on the name server. This is done
2015 -- by calling System.Partition_Interface.Register_Receiving_Stub
2018 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2020 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2022 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2025 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2027 -- The parameters of the package RPC receiver are made of two
2028 -- streams, an input one and an output one.
2030 Pkg_RPC_Receiver_Spec :=
2031 Build_RPC_Receiver_Specification
2032 (RPC_Receiver => Pkg_RPC_Receiver,
2033 Stream_Parameter => Stream_Parameter,
2034 Result_Parameter => Result_Parameter);
2036 Pkg_RPC_Receiver_Decls := New_List (
2037 Make_Object_Declaration (Loc,
2038 Defining_Identifier => Subp_Id,
2039 Object_Definition =>
2040 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
2042 Pkg_RPC_Receiver_Statements := New_List (
2043 Make_Attribute_Reference (Loc,
2045 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
2048 Expressions => New_List (
2049 New_Occurrence_Of (Stream_Parameter, Loc),
2050 New_Occurrence_Of (Subp_Id, Loc))));
2052 -- A null subp_id denotes a call through a RAS, in which case the
2053 -- next Uint_64 element in the stream is the address of the local
2054 -- proxy object, from which we can retrieve the actual subprogram id.
2056 Append_To (Pkg_RPC_Receiver_Statements,
2057 Make_Implicit_If_Statement (Pkg_Spec,
2060 New_Occurrence_Of (Subp_Id, Loc),
2061 Make_Integer_Literal (Loc, 0)),
2062 Then_Statements => New_List (
2063 Make_Assignment_Statement (Loc,
2065 New_Occurrence_Of (Subp_Id, Loc),
2067 Make_Selected_Component (Loc,
2069 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
2070 OK_Convert_To (RTE (RE_Address),
2071 Make_Attribute_Reference (Loc,
2073 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2076 Expressions => New_List (
2077 New_Occurrence_Of (Stream_Parameter, Loc))))),
2079 Make_Identifier (Loc, Name_Subp_Id))))));
2081 All_Calls_Remote_E := Boolean_Literals (
2082 Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
2084 -- Build a subprogram for RAS information lookups
2086 Current_Declaration :=
2087 Make_Subprogram_Declaration (Loc,
2089 Make_Function_Specification (Loc,
2090 Defining_Unit_Name =>
2092 Parameter_Specifications => New_List (
2093 Make_Parameter_Specification (Loc,
2094 Defining_Identifier =>
2095 Make_Defining_Identifier (Loc, Name_Subp_Id),
2099 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
2101 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
2102 Append_To (Decls, Current_Declaration);
2103 Analyze (Current_Declaration);
2105 Current_Stubs := Build_Subprogram_Receiving_Stubs
2106 (Vis_Decl => Current_Declaration,
2107 Asynchronous => False);
2108 Append_To (Decls, Current_Stubs);
2109 Analyze (Current_Stubs);
2111 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
2113 Current_Declaration,
2116 Subprogram_Number => 1);
2118 -- For each subprogram, the receiving stub will be built and a
2119 -- case statement will be made on the Subprogram_Id to dispatch
2120 -- to the right subprogram.
2122 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
2123 while Current_Declaration /= Empty loop
2124 if Nkind (Current_Declaration) = N_Subprogram_Declaration
2125 and then Comes_From_Source (Current_Declaration)
2127 pragma Assert (Current_Subprogram_Number =
2128 Get_Subprogram_Id (Defining_Unit_Name (Specification (
2129 Current_Declaration))));
2131 -- Build receiving stub
2134 Build_Subprogram_Receiving_Stubs
2135 (Vis_Decl => Current_Declaration,
2137 Nkind (Specification (Current_Declaration)) =
2138 N_Procedure_Specification
2139 and then Is_Asynchronous
2140 (Defining_Unit_Name (Specification
2141 (Current_Declaration))));
2143 Append_To (Decls, Current_Stubs);
2144 Analyze (Current_Stubs);
2148 Add_RAS_Proxy_And_Analyze (Decls,
2150 Current_Declaration,
2151 All_Calls_Remote_E =>
2153 Proxy_Object_Addr =>
2156 -- Add subprogram descriptor (RCI_Subp_Info) to the
2157 -- subprograms table for this receiver. The aggregate
2158 -- below must be kept consistent with the declaration
2159 -- of type RCI_Subp_Info in System.Partition_Interface.
2161 Append_To (Subp_Info_List,
2162 Make_Component_Association (Loc,
2163 Choices => New_List (
2164 Make_Integer_Literal (Loc,
2165 Current_Subprogram_Number)),
2167 Make_Aggregate (Loc,
2168 Component_Associations => New_List (
2169 Make_Component_Association (Loc,
2170 Choices => New_List (
2171 Make_Identifier (Loc, Name_Addr)),
2173 New_Occurrence_Of (Proxy_Object_Addr, Loc))))));
2175 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
2177 Current_Declaration,
2180 Subprogram_Number =>
2181 Current_Subprogram_Number);
2182 Current_Subprogram_Number := Current_Subprogram_Number + 1;
2185 Next (Current_Declaration);
2188 -- If we receive an invalid Subprogram_Id, it is best to do nothing
2189 -- rather than raising an exception since we do not want someone
2190 -- to crash a remote partition by sending invalid subprogram ids.
2191 -- This is consistent with the other parts of the case statement
2192 -- since even in presence of incorrect parameters in the stream,
2193 -- every exception will be caught and (if the subprogram is not an
2194 -- APC) put into the result stream and sent away.
2196 Append_To (Pkg_RPC_Receiver_Cases,
2197 Make_Case_Statement_Alternative (Loc,
2199 New_List (Make_Others_Choice (Loc)),
2201 New_List (Make_Null_Statement (Loc))));
2203 Append_To (Pkg_RPC_Receiver_Statements,
2204 Make_Case_Statement (Loc,
2206 New_Occurrence_Of (Subp_Id, Loc),
2207 Alternatives => Pkg_RPC_Receiver_Cases));
2210 Make_Object_Declaration (Loc,
2211 Defining_Identifier => Subp_Info_Array,
2212 Constant_Present => True,
2213 Aliased_Present => True,
2214 Object_Definition =>
2215 Make_Subtype_Indication (Loc,
2217 New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
2219 Make_Index_Or_Discriminant_Constraint (Loc,
2222 Low_Bound => Make_Integer_Literal (Loc,
2223 First_RCI_Subprogram_Id),
2225 Make_Integer_Literal (Loc,
2226 First_RCI_Subprogram_Id
2227 + List_Length (Subp_Info_List) - 1))))),
2229 Make_Aggregate (Loc,
2230 Component_Associations => Subp_Info_List)));
2231 Analyze (Last (Decls));
2234 Make_Subprogram_Body (Loc,
2236 Copy_Specification (Loc, Parent (Lookup_RAS_Info)),
2239 Handled_Statement_Sequence =>
2240 Make_Handled_Sequence_Of_Statements (Loc,
2241 Statements => New_List (
2242 Make_Return_Statement (Loc,
2243 Expression => OK_Convert_To (RTE (RE_Unsigned_64),
2244 Make_Selected_Component (Loc,
2246 Make_Indexed_Component (Loc,
2248 New_Occurrence_Of (Subp_Info_Array, Loc),
2249 Expressions => New_List (
2250 Convert_To (Standard_Integer,
2251 Make_Identifier (Loc, Name_Subp_Id)))),
2253 Make_Identifier (Loc, Name_Addr))))))));
2254 Analyze (Last (Decls));
2256 Pkg_RPC_Receiver_Body :=
2257 Make_Subprogram_Body (Loc,
2258 Specification => Pkg_RPC_Receiver_Spec,
2259 Declarations => Pkg_RPC_Receiver_Decls,
2260 Handled_Statement_Sequence =>
2261 Make_Handled_Sequence_Of_Statements (Loc,
2262 Statements => Pkg_RPC_Receiver_Statements));
2264 Append_To (Decls, Pkg_RPC_Receiver_Body);
2265 Analyze (Pkg_RPC_Receiver_Body);
2267 -- Construction of the dummy package used to register the package
2268 -- receiving stubs on the nameserver.
2270 Dummy_Register_Name := New_Internal_Name ('P');
2272 Dummy_Register_Spec :=
2273 Make_Package_Specification (Loc,
2274 Defining_Unit_Name =>
2275 Make_Defining_Identifier (Loc, Dummy_Register_Name),
2276 Visible_Declarations => No_List,
2277 End_Label => Empty);
2279 Dummy_Register_Decl :=
2280 Make_Package_Declaration (Loc,
2281 Specification => Dummy_Register_Spec);
2283 Append_To (Decls, Dummy_Register_Decl);
2284 Analyze (Dummy_Register_Decl);
2286 Get_Pkg_Name_String (Pkg_Spec);
2287 Append_To (Register_Pkg_Actuals,
2289 Make_String_Literal (Loc,
2290 Strval => String_From_Name_Buffer));
2292 Append_To (Register_Pkg_Actuals,
2294 Make_Attribute_Reference (Loc,
2296 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
2298 Name_Unrestricted_Access));
2300 Append_To (Register_Pkg_Actuals,
2302 Make_Attribute_Reference (Loc,
2304 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
2308 Append_To (Register_Pkg_Actuals,
2310 Make_Attribute_Reference (Loc,
2312 New_Occurrence_Of (Subp_Info_Array, Loc),
2316 Append_To (Register_Pkg_Actuals,
2318 Make_Attribute_Reference (Loc,
2320 New_Occurrence_Of (Subp_Info_Array, Loc),
2324 Dummy_Register_Body :=
2325 Make_Package_Body (Loc,
2326 Defining_Unit_Name =>
2327 Make_Defining_Identifier (Loc, Dummy_Register_Name),
2328 Declarations => No_List,
2330 Handled_Statement_Sequence =>
2331 Make_Handled_Sequence_Of_Statements (Loc,
2332 Statements => New_List (
2333 Make_Procedure_Call_Statement (Loc,
2335 New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
2337 Parameter_Associations => Register_Pkg_Actuals))));
2339 Append_To (Decls, Dummy_Register_Body);
2340 Analyze (Dummy_Register_Body);
2341 end Add_Receiving_Stubs_To_Declarations;
2347 procedure Add_Stub_Type
2348 (Designated_Type : Entity_Id;
2349 RACW_Type : Entity_Id;
2351 Stub_Type : out Entity_Id;
2352 Stub_Type_Access : out Entity_Id;
2353 Object_RPC_Receiver : out Entity_Id;
2354 Existing : out Boolean)
2356 Loc : constant Source_Ptr := Sloc (RACW_Type);
2358 Stub_Elements : constant Stub_Structure :=
2359 Stubs_Table.Get (Designated_Type);
2361 Stub_Type_Declaration : Node_Id;
2362 Stub_Type_Access_Declaration : Node_Id;
2363 Object_RPC_Receiver_Declaration : Node_Id;
2365 RPC_Receiver_Stream : Entity_Id;
2366 RPC_Receiver_Result : Entity_Id;
2369 if Stub_Elements /= Empty_Stub_Structure then
2370 Stub_Type := Stub_Elements.Stub_Type;
2371 Stub_Type_Access := Stub_Elements.Stub_Type_Access;
2372 Object_RPC_Receiver := Stub_Elements.Object_RPC_Receiver;
2379 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2381 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2382 Object_RPC_Receiver :=
2383 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2384 RPC_Receiver_Stream :=
2385 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2386 RPC_Receiver_Result :=
2387 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2388 Stubs_Table.Set (Designated_Type,
2389 (Stub_Type => Stub_Type,
2390 Stub_Type_Access => Stub_Type_Access,
2391 Object_RPC_Receiver => Object_RPC_Receiver,
2392 RPC_Receiver_Stream => RPC_Receiver_Stream,
2393 RPC_Receiver_Result => RPC_Receiver_Result,
2394 RACW_Type => RACW_Type));
2396 -- The stub type definition below must match exactly the one in
2397 -- s-parint.ads, since unchecked conversions will be used in
2398 -- s-parint.adb to modify pointers passed to Get_Unique_Remote_Pointer.
2400 Stub_Type_Declaration :=
2401 Make_Full_Type_Declaration (Loc,
2402 Defining_Identifier => Stub_Type,
2404 Make_Record_Definition (Loc,
2405 Tagged_Present => True,
2406 Limited_Present => True,
2408 Make_Component_List (Loc,
2409 Component_Items => New_List (
2411 Make_Component_Declaration (Loc,
2412 Defining_Identifier =>
2413 Make_Defining_Identifier (Loc, Name_Origin),
2414 Component_Definition =>
2415 Make_Component_Definition (Loc,
2416 Aliased_Present => False,
2417 Subtype_Indication =>
2418 New_Occurrence_Of (RTE (RE_Partition_ID), Loc))),
2420 Make_Component_Declaration (Loc,
2421 Defining_Identifier =>
2422 Make_Defining_Identifier (Loc, Name_Receiver),
2423 Component_Definition =>
2424 Make_Component_Definition (Loc,
2425 Aliased_Present => False,
2426 Subtype_Indication =>
2427 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
2429 Make_Component_Declaration (Loc,
2430 Defining_Identifier =>
2431 Make_Defining_Identifier (Loc, Name_Addr),
2432 Component_Definition =>
2433 Make_Component_Definition (Loc,
2434 Aliased_Present => False,
2435 Subtype_Indication =>
2436 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
2438 Make_Component_Declaration (Loc,
2439 Defining_Identifier =>
2440 Make_Defining_Identifier (Loc, Name_Asynchronous),
2441 Component_Definition =>
2442 Make_Component_Definition (Loc,
2443 Aliased_Present => False,
2444 Subtype_Indication =>
2445 New_Occurrence_Of (Standard_Boolean, Loc)))))));
2447 Append_To (Decls, Stub_Type_Declaration);
2448 Analyze (Stub_Type_Declaration);
2450 -- This is in no way a type derivation, but we fake it to make
2451 -- sure that the dispatching table gets built with the corresponding
2452 -- primitive operations at the right place.
2454 Derive_Subprograms (Parent_Type => Designated_Type,
2455 Derived_Type => Stub_Type);
2457 Stub_Type_Access_Declaration :=
2458 Make_Full_Type_Declaration (Loc,
2459 Defining_Identifier => Stub_Type_Access,
2461 Make_Access_To_Object_Definition (Loc,
2462 All_Present => True,
2463 Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
2465 Append_To (Decls, Stub_Type_Access_Declaration);
2466 Analyze (Stub_Type_Access_Declaration);
2468 Object_RPC_Receiver_Declaration :=
2469 Make_Subprogram_Declaration (Loc,
2470 Build_RPC_Receiver_Specification (
2471 RPC_Receiver => Object_RPC_Receiver,
2472 Stream_Parameter => RPC_Receiver_Stream,
2473 Result_Parameter => RPC_Receiver_Result));
2475 Append_To (Decls, Object_RPC_Receiver_Declaration);
2478 ---------------------------------
2479 -- Build_General_Calling_Stubs --
2480 ---------------------------------
2482 procedure Build_General_Calling_Stubs
2484 Statements : List_Id;
2485 Target_Partition : Entity_Id;
2486 RPC_Receiver : Node_Id;
2487 Subprogram_Id : Node_Id;
2488 Asynchronous : Node_Id := Empty;
2489 Is_Known_Asynchronous : Boolean := False;
2490 Is_Known_Non_Asynchronous : Boolean := False;
2491 Is_Function : Boolean;
2493 Stub_Type : Entity_Id := Empty;
2494 RACW_Type : Entity_Id := Empty;
2497 Loc : constant Source_Ptr := Sloc (Nod);
2499 Stream_Parameter : Node_Id;
2500 -- Name of the stream used to transmit parameters to the remote package
2502 Result_Parameter : Node_Id;
2503 -- Name of the result parameter (in non-APC cases) which get the
2504 -- result of the remote subprogram.
2506 Exception_Return_Parameter : Node_Id;
2507 -- Name of the parameter which will hold the exception sent by the
2508 -- remote subprogram.
2510 Current_Parameter : Node_Id;
2511 -- Current parameter being handled
2513 Ordered_Parameters_List : constant List_Id :=
2514 Build_Ordered_Parameters_List (Spec);
2516 Asynchronous_Statements : List_Id := No_List;
2517 Non_Asynchronous_Statements : List_Id := No_List;
2518 -- Statements specifics to the Asynchronous/Non-Asynchronous cases
2520 Extra_Formal_Statements : constant List_Id := New_List;
2521 -- List of statements for extra formal parameters. It will appear after
2522 -- the regular statements for writing out parameters.
2524 pragma Warnings (Off, RACW_Type);
2525 -- Unreferenced formal parameter.
2528 -- The general form of a calling stub for a given subprogram is:
2530 -- procedure X (...) is
2531 -- P : constant Partition_ID := RCI_Cache.Get_Active_Partition_ID;
2532 -- Stream, Result : aliased System.RPC.Params_Stream_Type (0);
2534 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
2535 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
2536 -- Put_Subprogram_Id_In_Stream;
2537 -- Put_Parameters_In_Stream;
2538 -- Do_RPC (Stream, Result);
2539 -- Read_Exception_Occurrence_From_Result; Raise_It;
2540 -- Read_Out_Parameters_And_Function_Return_From_Stream;
2543 -- There are some variations: Do_APC is called for an asynchronous
2544 -- procedure and the part after the call is completely ommitted
2545 -- as well as the declaration of Result. For a function call,
2546 -- 'Input is always used to read the result even if it is constrained.
2549 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2552 Make_Object_Declaration (Loc,
2553 Defining_Identifier => Stream_Parameter,
2554 Aliased_Present => True,
2555 Object_Definition =>
2556 Make_Subtype_Indication (Loc,
2558 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2560 Make_Index_Or_Discriminant_Constraint (Loc,
2562 New_List (Make_Integer_Literal (Loc, 0))))));
2564 if not Is_Known_Asynchronous then
2566 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2569 Make_Object_Declaration (Loc,
2570 Defining_Identifier => Result_Parameter,
2571 Aliased_Present => True,
2572 Object_Definition =>
2573 Make_Subtype_Indication (Loc,
2575 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2577 Make_Index_Or_Discriminant_Constraint (Loc,
2579 New_List (Make_Integer_Literal (Loc, 0))))));
2581 Exception_Return_Parameter :=
2582 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
2585 Make_Object_Declaration (Loc,
2586 Defining_Identifier => Exception_Return_Parameter,
2587 Object_Definition =>
2588 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
2591 Result_Parameter := Empty;
2592 Exception_Return_Parameter := Empty;
2595 -- Put first the RPC receiver corresponding to the remote package
2597 Append_To (Statements,
2598 Make_Attribute_Reference (Loc,
2600 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2601 Attribute_Name => Name_Write,
2602 Expressions => New_List (
2603 Make_Attribute_Reference (Loc,
2605 New_Occurrence_Of (Stream_Parameter, Loc),
2610 -- Then put the Subprogram_Id of the subprogram we want to call in
2613 Append_To (Statements,
2614 Make_Attribute_Reference (Loc,
2616 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
2619 Expressions => New_List (
2620 Make_Attribute_Reference (Loc,
2622 New_Occurrence_Of (Stream_Parameter, Loc),
2623 Attribute_Name => Name_Access),
2626 Current_Parameter := First (Ordered_Parameters_List);
2627 while Current_Parameter /= Empty loop
2629 Typ : constant Node_Id :=
2630 Parameter_Type (Current_Parameter);
2632 Constrained : Boolean;
2634 Extra_Parameter : Entity_Id;
2637 if Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) then
2639 -- In the case of a controlling formal argument, we marshall
2640 -- its addr field rather than the local stub.
2642 Append_To (Statements,
2643 Pack_Node_Into_Stream (Loc,
2644 Stream => Stream_Parameter,
2646 Make_Selected_Component (Loc,
2649 Defining_Identifier (Current_Parameter), Loc),
2651 Make_Identifier (Loc, Name_Addr)),
2652 Etyp => RTE (RE_Unsigned_64)));
2655 Value := New_Occurrence_Of
2656 (Defining_Identifier (Current_Parameter), Loc);
2658 -- Access type parameters are transmitted as in out
2659 -- parameters. However, a dereference is needed so that
2660 -- we marshall the designated object.
2662 if Nkind (Typ) = N_Access_Definition then
2663 Value := Make_Explicit_Dereference (Loc, Value);
2664 Etyp := Etype (Subtype_Mark (Typ));
2666 Etyp := Etype (Typ);
2670 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
2672 -- Any parameter but unconstrained out parameters are
2673 -- transmitted to the peer.
2675 if In_Present (Current_Parameter)
2676 or else not Out_Present (Current_Parameter)
2677 or else not Constrained
2679 Append_To (Statements,
2680 Make_Attribute_Reference (Loc,
2682 New_Occurrence_Of (Etyp, Loc),
2683 Attribute_Name => Output_From_Constrained (Constrained),
2684 Expressions => New_List (
2685 Make_Attribute_Reference (Loc,
2687 New_Occurrence_Of (Stream_Parameter, Loc),
2688 Attribute_Name => Name_Access),
2693 -- If the current parameter has a dynamic constrained status,
2694 -- then this status is transmitted as well.
2695 -- This should be done for accessibility as well ???
2697 if Nkind (Typ) /= N_Access_Definition
2698 and then Need_Extra_Constrained (Current_Parameter)
2700 -- In this block, we do not use the extra formal that has been
2701 -- created because it does not exist at the time of expansion
2702 -- when building calling stubs for remote access to subprogram
2703 -- types. We create an extra variable of this type and push it
2704 -- in the stream after the regular parameters.
2706 Extra_Parameter := Make_Defining_Identifier
2707 (Loc, New_Internal_Name ('P'));
2710 Make_Object_Declaration (Loc,
2711 Defining_Identifier => Extra_Parameter,
2712 Constant_Present => True,
2713 Object_Definition =>
2714 New_Occurrence_Of (Standard_Boolean, Loc),
2716 Make_Attribute_Reference (Loc,
2719 Defining_Identifier (Current_Parameter), Loc),
2720 Attribute_Name => Name_Constrained)));
2722 Append_To (Extra_Formal_Statements,
2723 Make_Attribute_Reference (Loc,
2725 New_Occurrence_Of (Standard_Boolean, Loc),
2728 Expressions => New_List (
2729 Make_Attribute_Reference (Loc,
2731 New_Occurrence_Of (Stream_Parameter, Loc),
2734 New_Occurrence_Of (Extra_Parameter, Loc))));
2737 Next (Current_Parameter);
2741 -- Append the formal statements list to the statements
2743 Append_List_To (Statements, Extra_Formal_Statements);
2745 if not Is_Known_Non_Asynchronous then
2747 -- Build the call to System.RPC.Do_APC
2749 Asynchronous_Statements := New_List (
2750 Make_Procedure_Call_Statement (Loc,
2752 New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
2753 Parameter_Associations => New_List (
2754 New_Occurrence_Of (Target_Partition, Loc),
2755 Make_Attribute_Reference (Loc,
2757 New_Occurrence_Of (Stream_Parameter, Loc),
2761 Asynchronous_Statements := No_List;
2764 if not Is_Known_Asynchronous then
2766 -- Build the call to System.RPC.Do_RPC
2768 Non_Asynchronous_Statements := New_List (
2769 Make_Procedure_Call_Statement (Loc,
2771 New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
2772 Parameter_Associations => New_List (
2773 New_Occurrence_Of (Target_Partition, Loc),
2775 Make_Attribute_Reference (Loc,
2777 New_Occurrence_Of (Stream_Parameter, Loc),
2781 Make_Attribute_Reference (Loc,
2783 New_Occurrence_Of (Result_Parameter, Loc),
2787 -- Read the exception occurrence from the result stream and
2788 -- reraise it. It does no harm if this is a Null_Occurrence since
2789 -- this does nothing.
2791 Append_To (Non_Asynchronous_Statements,
2792 Make_Attribute_Reference (Loc,
2794 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
2799 Expressions => New_List (
2800 Make_Attribute_Reference (Loc,
2802 New_Occurrence_Of (Result_Parameter, Loc),
2805 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2807 Append_To (Non_Asynchronous_Statements,
2808 Make_Procedure_Call_Statement (Loc,
2810 New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
2811 Parameter_Associations => New_List (
2812 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2816 -- If this is a function call, then read the value and return
2817 -- it. The return value is written/read using 'Output/'Input.
2819 Append_To (Non_Asynchronous_Statements,
2820 Make_Tag_Check (Loc,
2821 Make_Return_Statement (Loc,
2823 Make_Attribute_Reference (Loc,
2826 Etype (Subtype_Mark (Spec)), Loc),
2828 Attribute_Name => Name_Input,
2830 Expressions => New_List (
2831 Make_Attribute_Reference (Loc,
2833 New_Occurrence_Of (Result_Parameter, Loc),
2834 Attribute_Name => Name_Access))))));
2837 -- Loop around parameters and assign out (or in out) parameters.
2838 -- In the case of RACW, controlling arguments cannot possibly
2839 -- have changed since they are remote, so we do not read them
2842 Current_Parameter := First (Ordered_Parameters_List);
2843 while Current_Parameter /= Empty loop
2845 Typ : constant Node_Id :=
2846 Parameter_Type (Current_Parameter);
2853 (Defining_Identifier (Current_Parameter), Loc);
2855 if Nkind (Typ) = N_Access_Definition then
2856 Value := Make_Explicit_Dereference (Loc, Value);
2857 Etyp := Etype (Subtype_Mark (Typ));
2859 Etyp := Etype (Typ);
2862 if (Out_Present (Current_Parameter)
2863 or else Nkind (Typ) = N_Access_Definition)
2864 and then Etyp /= Stub_Type
2866 Append_To (Non_Asynchronous_Statements,
2867 Make_Attribute_Reference (Loc,
2869 New_Occurrence_Of (Etyp, Loc),
2871 Attribute_Name => Name_Read,
2873 Expressions => New_List (
2874 Make_Attribute_Reference (Loc,
2876 New_Occurrence_Of (Result_Parameter, Loc),
2883 Next (Current_Parameter);
2888 if Is_Known_Asynchronous then
2889 Append_List_To (Statements, Asynchronous_Statements);
2891 elsif Is_Known_Non_Asynchronous then
2892 Append_List_To (Statements, Non_Asynchronous_Statements);
2895 pragma Assert (Asynchronous /= Empty);
2896 Prepend_To (Asynchronous_Statements,
2897 Make_Attribute_Reference (Loc,
2898 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2899 Attribute_Name => Name_Write,
2900 Expressions => New_List (
2901 Make_Attribute_Reference (Loc,
2902 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2903 Attribute_Name => Name_Access),
2904 New_Occurrence_Of (Standard_True, Loc))));
2906 Prepend_To (Non_Asynchronous_Statements,
2907 Make_Attribute_Reference (Loc,
2908 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2909 Attribute_Name => Name_Write,
2910 Expressions => New_List (
2911 Make_Attribute_Reference (Loc,
2912 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2913 Attribute_Name => Name_Access),
2914 New_Occurrence_Of (Standard_False, Loc))));
2916 Append_To (Statements,
2917 Make_Implicit_If_Statement (Nod,
2918 Condition => Asynchronous,
2919 Then_Statements => Asynchronous_Statements,
2920 Else_Statements => Non_Asynchronous_Statements));
2922 end Build_General_Calling_Stubs;
2924 ------------------------------
2925 -- Build_Get_Unique_RP_Call --
2926 ------------------------------
2928 function Build_Get_Unique_RP_Call
2930 Pointer : Entity_Id;
2931 Stub_Type : Entity_Id) return List_Id
2935 Make_Procedure_Call_Statement (Loc,
2937 New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
2938 Parameter_Associations => New_List (
2939 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2940 New_Occurrence_Of (Pointer, Loc)))),
2942 Make_Assignment_Statement (Loc,
2944 Make_Selected_Component (Loc,
2946 New_Occurrence_Of (Pointer, Loc),
2948 New_Occurrence_Of (Tag_Component
2949 (Designated_Type (Etype (Pointer))), Loc)),
2951 Make_Attribute_Reference (Loc,
2953 New_Occurrence_Of (Stub_Type, Loc),
2957 -- Note: The assignment to Pointer._Tag is safe here because
2958 -- we carefully ensured that Stub_Type has exactly the same layout
2959 -- as System.Partition_Interface.RACW_Stub_Type.
2961 end Build_Get_Unique_RP_Call;
2963 ----------------------------------------
2964 -- Build_Remote_Subprogram_Proxy_Type --
2965 ----------------------------------------
2967 function Build_Remote_Subprogram_Proxy_Type
2969 ACR_Expression : Node_Id) return Node_Id
2973 Make_Record_Definition (Loc,
2974 Tagged_Present => True,
2975 Limited_Present => True,
2977 Make_Component_List (Loc,
2979 Component_Items => New_List (
2980 Make_Component_Declaration (Loc,
2981 Make_Defining_Identifier (Loc,
2982 Name_All_Calls_Remote),
2983 Make_Component_Definition (Loc,
2984 Subtype_Indication =>
2985 New_Occurrence_Of (Standard_Boolean, Loc)),
2988 Make_Component_Declaration (Loc,
2989 Make_Defining_Identifier (Loc,
2991 Make_Component_Definition (Loc,
2992 Subtype_Indication =>
2993 New_Occurrence_Of (RTE (RE_Address), Loc)),
2994 New_Occurrence_Of (RTE (RE_Null_Address), Loc)),
2996 Make_Component_Declaration (Loc,
2997 Make_Defining_Identifier (Loc,
2999 Make_Component_Definition (Loc,
3000 Subtype_Indication =>
3001 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))))));
3002 end Build_Remote_Subprogram_Proxy_Type;
3004 -----------------------------------
3005 -- Build_Ordered_Parameters_List --
3006 -----------------------------------
3008 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
3009 Constrained_List : List_Id;
3010 Unconstrained_List : List_Id;
3011 Current_Parameter : Node_Id;
3013 First_Parameter : Node_Id;
3014 For_RAS : Boolean := False;
3017 if not Present (Parameter_Specifications (Spec)) then
3021 Constrained_List := New_List;
3022 Unconstrained_List := New_List;
3023 First_Parameter := First (Parameter_Specifications (Spec));
3025 if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition
3026 and then Chars (Defining_Identifier (First_Parameter)) = Name_uS
3031 -- Loop through the parameters and add them to the right list
3033 Current_Parameter := First_Parameter;
3034 while Current_Parameter /= Empty loop
3035 if (Nkind (Parameter_Type (Current_Parameter)) = N_Access_Definition
3037 Is_Constrained (Etype (Parameter_Type (Current_Parameter)))
3039 Is_Elementary_Type (Etype (Parameter_Type (Current_Parameter))))
3040 and then not (For_RAS and then Current_Parameter = First_Parameter)
3042 Append_To (Constrained_List, New_Copy (Current_Parameter));
3044 Append_To (Unconstrained_List, New_Copy (Current_Parameter));
3047 Next (Current_Parameter);
3050 -- Unconstrained parameters are returned first
3052 Append_List_To (Unconstrained_List, Constrained_List);
3054 return Unconstrained_List;
3055 end Build_Ordered_Parameters_List;
3057 ----------------------------------
3058 -- Build_Passive_Partition_Stub --
3059 ----------------------------------
3061 procedure Build_Passive_Partition_Stub (U : Node_Id) is
3063 Pkg_Name : String_Id;
3066 Loc : constant Source_Ptr := Sloc (U);
3069 -- Verify that the implementation supports distribution, by accessing
3070 -- a type defined in the proper version of system.rpc
3073 Dist_OK : Entity_Id;
3074 pragma Warnings (Off, Dist_OK);
3076 Dist_OK := RTE (RE_Params_Stream_Type);
3079 -- Use body if present, spec otherwise
3081 if Nkind (U) = N_Package_Declaration then
3082 Pkg_Spec := Specification (U);
3083 L := Visible_Declarations (Pkg_Spec);
3085 Pkg_Spec := Parent (Corresponding_Spec (U));
3086 L := Declarations (U);
3089 Get_Pkg_Name_String (Pkg_Spec);
3090 Pkg_Name := String_From_Name_Buffer;
3092 Make_Procedure_Call_Statement (Loc,
3094 New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
3095 Parameter_Associations => New_List (
3096 Make_String_Literal (Loc, Pkg_Name),
3097 Make_Attribute_Reference (Loc,
3099 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
3104 end Build_Passive_Partition_Stub;
3106 --------------------------------------
3107 -- Build_RPC_Receiver_Specification --
3108 --------------------------------------
3110 function Build_RPC_Receiver_Specification
3111 (RPC_Receiver : Entity_Id;
3112 Stream_Parameter : Entity_Id;
3113 Result_Parameter : Entity_Id) return Node_Id
3115 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
3119 Make_Procedure_Specification (Loc,
3120 Defining_Unit_Name => RPC_Receiver,
3121 Parameter_Specifications => New_List (
3122 Make_Parameter_Specification (Loc,
3123 Defining_Identifier => Stream_Parameter,
3125 Make_Access_Definition (Loc,
3127 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
3129 Make_Parameter_Specification (Loc,
3130 Defining_Identifier => Result_Parameter,
3132 Make_Access_Definition (Loc,
3135 (RTE (RE_Params_Stream_Type), Loc)))));
3136 end Build_RPC_Receiver_Specification;
3138 ------------------------------------
3139 -- Build_Subprogram_Calling_Stubs --
3140 ------------------------------------
3142 function Build_Subprogram_Calling_Stubs
3143 (Vis_Decl : Node_Id;
3145 Asynchronous : Boolean;
3146 Dynamically_Asynchronous : Boolean := False;
3147 Stub_Type : Entity_Id := Empty;
3148 RACW_Type : Entity_Id := Empty;
3149 Locator : Entity_Id := Empty;
3150 New_Name : Name_Id := No_Name) return Node_Id
3152 Loc : constant Source_Ptr := Sloc (Vis_Decl);
3154 Target_Partition : Node_Id;
3155 -- Contains the name of the target partition
3157 Decls : constant List_Id := New_List;
3158 Statements : constant List_Id := New_List;
3160 Subp_Spec : Node_Id;
3161 -- The specification of the body
3163 Controlling_Parameter : Entity_Id := Empty;
3164 RPC_Receiver : Node_Id;
3166 Asynchronous_Expr : Node_Id := Empty;
3168 RCI_Locator : Entity_Id;
3170 Spec_To_Use : Node_Id;
3172 procedure Insert_Partition_Check (Parameter : Node_Id);
3173 -- Check that the parameter has been elaborated on the same partition
3174 -- than the controlling parameter (E.4(19)).
3176 ----------------------------
3177 -- Insert_Partition_Check --
3178 ----------------------------
3180 procedure Insert_Partition_Check (Parameter : Node_Id) is
3181 Parameter_Entity : constant Entity_Id :=
3182 Defining_Identifier (Parameter);
3183 Condition : Node_Id;
3185 Designated_Object : Node_Id;
3186 pragma Warnings (Off, Designated_Object);
3187 -- Is it really right that this is unreferenced ???
3190 -- The expression that will be built is of the form:
3191 -- if not (Parameter in Stub_Type and then
3192 -- Parameter.Origin = Controlling.Origin)
3194 -- raise Constraint_Error;
3197 -- Condition contains the reversed condition. Also, Parameter is
3198 -- dereferenced if it is an access type. We do not check that
3199 -- Parameter is in Stub_Type since such a check has been inserted
3200 -- at the point of call already (a tag check since we have multiple
3201 -- controlling operands).
3203 if Nkind (Parameter_Type (Parameter)) = N_Access_Definition then
3204 Designated_Object :=
3205 Make_Explicit_Dereference (Loc,
3206 Prefix => New_Occurrence_Of (Parameter_Entity, Loc));
3208 Designated_Object := New_Occurrence_Of (Parameter_Entity, Loc);
3214 Make_Selected_Component (Loc,
3216 New_Occurrence_Of (Parameter_Entity, Loc),
3218 Make_Identifier (Loc, Name_Origin)),
3221 Make_Selected_Component (Loc,
3223 New_Occurrence_Of (Controlling_Parameter, Loc),
3225 Make_Identifier (Loc, Name_Origin)));
3228 Make_Raise_Constraint_Error (Loc,
3230 Make_Op_Not (Loc, Right_Opnd => Condition),
3231 Reason => CE_Partition_Check_Failed));
3232 end Insert_Partition_Check;
3234 -- Start of processing for Build_Subprogram_Calling_Stubs
3238 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3240 Subp_Spec := Copy_Specification (Loc,
3241 Spec => Specification (Vis_Decl),
3242 New_Name => New_Name);
3244 if Locator = Empty then
3245 RCI_Locator := RCI_Cache;
3246 Spec_To_Use := Specification (Vis_Decl);
3248 RCI_Locator := Locator;
3249 Spec_To_Use := Subp_Spec;
3252 -- Find a controlling argument if we have a stub type. Also check
3253 -- if this subprogram can be made asynchronous.
3255 if Stub_Type /= Empty
3256 and then Present (Parameter_Specifications (Spec_To_Use))
3259 Current_Parameter : Node_Id :=
3260 First (Parameter_Specifications
3263 while Current_Parameter /= Empty loop
3266 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
3268 if Controlling_Parameter = Empty then
3269 Controlling_Parameter :=
3270 Defining_Identifier (Current_Parameter);
3272 Insert_Partition_Check (Current_Parameter);
3276 Next (Current_Parameter);
3281 if Stub_Type /= Empty then
3282 pragma Assert (Controlling_Parameter /= Empty);
3285 Make_Object_Declaration (Loc,
3286 Defining_Identifier => Target_Partition,
3287 Constant_Present => True,
3288 Object_Definition =>
3289 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3292 Make_Selected_Component (Loc,
3294 New_Occurrence_Of (Controlling_Parameter, Loc),
3296 Make_Identifier (Loc, Name_Origin))));
3299 Make_Selected_Component (Loc,
3301 New_Occurrence_Of (Controlling_Parameter, Loc),
3303 Make_Identifier (Loc, Name_Receiver));
3307 Make_Object_Declaration (Loc,
3308 Defining_Identifier => Target_Partition,
3309 Constant_Present => True,
3310 Object_Definition =>
3311 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3314 Make_Function_Call (Loc,
3315 Name => Make_Selected_Component (Loc,
3317 Make_Identifier (Loc, Chars (RCI_Locator)),
3319 Make_Identifier (Loc, Name_Get_Active_Partition_ID)))));
3322 Make_Selected_Component (Loc,
3324 Make_Identifier (Loc, Chars (RCI_Locator)),
3326 Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
3329 if Dynamically_Asynchronous then
3330 Asynchronous_Expr :=
3331 Make_Selected_Component (Loc,
3333 New_Occurrence_Of (Controlling_Parameter, Loc),
3335 Make_Identifier (Loc, Name_Asynchronous));
3338 Build_General_Calling_Stubs
3340 Statements => Statements,
3341 Target_Partition => Target_Partition,
3342 RPC_Receiver => RPC_Receiver,
3343 Subprogram_Id => Make_Integer_Literal (Loc, Subp_Id),
3344 Asynchronous => Asynchronous_Expr,
3345 Is_Known_Asynchronous => Asynchronous
3346 and then not Dynamically_Asynchronous,
3347 Is_Known_Non_Asynchronous
3349 and then not Dynamically_Asynchronous,
3350 Is_Function => Nkind (Spec_To_Use) =
3351 N_Function_Specification,
3352 Spec => Spec_To_Use,
3353 Stub_Type => Stub_Type,
3354 RACW_Type => RACW_Type,
3357 RCI_Calling_Stubs_Table.Set
3358 (Defining_Unit_Name (Specification (Vis_Decl)),
3359 Defining_Unit_Name (Spec_To_Use));
3362 Make_Subprogram_Body (Loc,
3363 Specification => Subp_Spec,
3364 Declarations => Decls,
3365 Handled_Statement_Sequence =>
3366 Make_Handled_Sequence_Of_Statements (Loc, Statements));
3367 end Build_Subprogram_Calling_Stubs;
3369 -------------------------
3370 -- Build_Subprogram_Id --
3371 -------------------------
3373 function Build_Subprogram_Id
3375 E : Entity_Id) return Node_Id
3378 return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
3379 end Build_Subprogram_Id;
3381 --------------------------------------
3382 -- Build_Subprogram_Receiving_Stubs --
3383 --------------------------------------
3385 function Build_Subprogram_Receiving_Stubs
3386 (Vis_Decl : Node_Id;
3387 Asynchronous : Boolean;
3388 Dynamically_Asynchronous : Boolean := False;
3389 Stub_Type : Entity_Id := Empty;
3390 RACW_Type : Entity_Id := Empty;
3391 Parent_Primitive : Entity_Id := Empty) return Node_Id
3393 Loc : constant Source_Ptr := Sloc (Vis_Decl);
3395 Stream_Parameter : Node_Id;
3396 Result_Parameter : Node_Id;
3397 -- See explanations of those in Build_Subprogram_Calling_Stubs
3399 Decls : constant List_Id := New_List;
3400 -- All the parameters will get declared before calling the real
3401 -- subprograms. Also the out parameters will be declared.
3403 Statements : constant List_Id := New_List;
3405 Extra_Formal_Statements : constant List_Id := New_List;
3406 -- Statements concerning extra formal parameters
3408 After_Statements : constant List_Id := New_List;
3409 -- Statements to be executed after the subprogram call
3411 Inner_Decls : List_Id := No_List;
3412 -- In case of a function, the inner declarations are needed since
3413 -- the result may be unconstrained.
3415 Excep_Handler : Node_Id;
3416 Excep_Choice : Entity_Id;
3417 Excep_Code : List_Id;
3419 Parameter_List : constant List_Id := New_List;
3420 -- List of parameters to be passed to the subprogram
3422 Current_Parameter : Node_Id;
3424 Ordered_Parameters_List : constant List_Id :=
3425 Build_Ordered_Parameters_List
3426 (Specification (Vis_Decl));
3428 Subp_Spec : Node_Id;
3429 -- Subprogram specification
3431 Called_Subprogram : Node_Id;
3432 -- The subprogram to call
3434 Null_Raise_Statement : Node_Id;
3436 Dynamic_Async : Entity_Id;
3439 if RACW_Type /= Empty then
3440 Called_Subprogram :=
3441 New_Occurrence_Of (Parent_Primitive, Loc);
3443 Called_Subprogram :=
3445 Defining_Unit_Name (Specification (Vis_Decl)), Loc);
3449 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3451 if Dynamically_Asynchronous then
3453 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3455 Dynamic_Async := Empty;
3458 if not Asynchronous or else Dynamically_Asynchronous then
3460 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3462 -- The first statement after the subprogram call is a statement to
3463 -- writes a Null_Occurrence into the result stream.
3465 Null_Raise_Statement :=
3466 Make_Attribute_Reference (Loc,
3468 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3469 Attribute_Name => Name_Write,
3470 Expressions => New_List (
3471 New_Occurrence_Of (Result_Parameter, Loc),
3472 New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
3474 if Dynamically_Asynchronous then
3475 Null_Raise_Statement :=
3476 Make_Implicit_If_Statement (Vis_Decl,
3478 Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
3479 Then_Statements => New_List (Null_Raise_Statement));
3482 Append_To (After_Statements, Null_Raise_Statement);
3485 Result_Parameter := Empty;
3488 -- Loop through every parameter and get its value from the stream. If
3489 -- the parameter is unconstrained, then the parameter is read using
3490 -- 'Input at the point of declaration.
3492 Current_Parameter := First (Ordered_Parameters_List);
3494 while Current_Parameter /= Empty loop
3498 RACW_Controlling : Boolean;
3499 Constrained : Boolean;
3501 Expr : Node_Id := Empty;
3504 Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3505 Set_Ekind (Object, E_Variable);
3508 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type);
3510 if RACW_Controlling then
3512 -- We have a controlling formal parameter. Read its address
3513 -- rather than a real object. The address is in Unsigned_64
3516 Etyp := RTE (RE_Unsigned_64);
3518 Etyp := Etype (Parameter_Type (Current_Parameter));
3522 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
3524 if In_Present (Current_Parameter)
3525 or else not Out_Present (Current_Parameter)
3526 or else not Constrained
3527 or else RACW_Controlling
3529 -- If an input parameter is contrained, then its reading is
3530 -- deferred until the beginning of the subprogram body. If
3531 -- it is unconstrained, then an expression is built for
3532 -- the object declaration and the variable is set using
3533 -- 'Input instead of 'Read.
3535 if Constrained and then not RACW_Controlling then
3536 Append_To (Statements,
3537 Make_Attribute_Reference (Loc,
3538 Prefix => New_Occurrence_Of (Etyp, Loc),
3539 Attribute_Name => Name_Read,
3540 Expressions => New_List (
3541 New_Occurrence_Of (Stream_Parameter, Loc),
3542 New_Occurrence_Of (Object, Loc))));
3545 Expr := Input_With_Tag_Check (Loc,
3547 Stream => Stream_Parameter);
3548 Append_To (Decls, Expr);
3549 Expr := Make_Function_Call (Loc,
3550 New_Occurrence_Of (Defining_Unit_Name
3551 (Specification (Expr)), Loc));
3555 -- If we do not have to output the current parameter, then
3556 -- it can well be flagged as constant. This may allow further
3557 -- optimizations done by the back end.
3560 Make_Object_Declaration (Loc,
3561 Defining_Identifier => Object,
3563 not Constrained and then not Out_Present (Current_Parameter),
3564 Object_Definition =>
3565 New_Occurrence_Of (Etyp, Loc),
3566 Expression => Expr));
3568 -- An out parameter may be written back using a 'Write
3569 -- attribute instead of a 'Output because it has been
3570 -- constrained by the parameter given to the caller. Note that
3571 -- out controlling arguments in the case of a RACW are not put
3572 -- back in the stream because the pointer on them has not
3575 if Out_Present (Current_Parameter)
3577 Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
3579 Append_To (After_Statements,
3580 Make_Attribute_Reference (Loc,
3581 Prefix => New_Occurrence_Of (Etyp, Loc),
3582 Attribute_Name => Name_Write,
3583 Expressions => New_List (
3584 New_Occurrence_Of (Result_Parameter, Loc),
3585 New_Occurrence_Of (Object, Loc))));
3589 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
3591 if Nkind (Parameter_Type (Current_Parameter)) /=
3594 Append_To (Parameter_List,
3595 Make_Parameter_Association (Loc,
3598 Defining_Identifier (Current_Parameter), Loc),
3599 Explicit_Actual_Parameter =>
3600 Make_Explicit_Dereference (Loc,
3601 Unchecked_Convert_To (RACW_Type,
3602 OK_Convert_To (RTE (RE_Address),
3603 New_Occurrence_Of (Object, Loc))))));
3606 Append_To (Parameter_List,
3607 Make_Parameter_Association (Loc,
3610 Defining_Identifier (Current_Parameter), Loc),
3611 Explicit_Actual_Parameter =>
3612 Unchecked_Convert_To (RACW_Type,
3613 OK_Convert_To (RTE (RE_Address),
3614 New_Occurrence_Of (Object, Loc)))));
3618 Append_To (Parameter_List,
3619 Make_Parameter_Association (Loc,
3622 Defining_Identifier (Current_Parameter), Loc),
3623 Explicit_Actual_Parameter =>
3624 New_Occurrence_Of (Object, Loc)));
3627 -- If the current parameter needs an extra formal, then read it
3628 -- from the stream and set the corresponding semantic field in
3629 -- the variable. If the kind of the parameter identifier is
3630 -- E_Void, then this is a compiler generated parameter that
3631 -- doesn't need an extra constrained status.
3633 -- The case of Extra_Accessibility should also be handled ???
3635 if Nkind (Parameter_Type (Current_Parameter)) /=
3638 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
3640 Present (Extra_Constrained
3641 (Defining_Identifier (Current_Parameter)))
3644 Extra_Parameter : constant Entity_Id :=
3646 (Defining_Identifier
3647 (Current_Parameter));
3649 Formal_Entity : constant Entity_Id :=
3650 Make_Defining_Identifier
3651 (Loc, Chars (Extra_Parameter));
3653 Formal_Type : constant Entity_Id :=
3654 Etype (Extra_Parameter);
3658 Make_Object_Declaration (Loc,
3659 Defining_Identifier => Formal_Entity,
3660 Object_Definition =>
3661 New_Occurrence_Of (Formal_Type, Loc)));
3663 Append_To (Extra_Formal_Statements,
3664 Make_Attribute_Reference (Loc,
3665 Prefix => New_Occurrence_Of (Formal_Type, Loc),
3666 Attribute_Name => Name_Read,
3667 Expressions => New_List (
3668 New_Occurrence_Of (Stream_Parameter, Loc),
3669 New_Occurrence_Of (Formal_Entity, Loc))));
3670 Set_Extra_Constrained (Object, Formal_Entity);
3675 Next (Current_Parameter);
3678 -- Append the formal statements list at the end of regular statements
3680 Append_List_To (Statements, Extra_Formal_Statements);
3682 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
3684 -- The remote subprogram is a function. We build an inner block to
3685 -- be able to hold a potentially unconstrained result in a variable.
3688 Etyp : constant Entity_Id :=
3689 Etype (Subtype_Mark (Specification (Vis_Decl)));
3690 Result : constant Node_Id :=
3691 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3694 Inner_Decls := New_List (
3695 Make_Object_Declaration (Loc,
3696 Defining_Identifier => Result,
3697 Constant_Present => True,
3698 Object_Definition => New_Occurrence_Of (Etyp, Loc),
3700 Make_Function_Call (Loc,
3701 Name => Called_Subprogram,
3702 Parameter_Associations => Parameter_List)));
3704 Append_To (After_Statements,
3705 Make_Attribute_Reference (Loc,
3706 Prefix => New_Occurrence_Of (Etyp, Loc),
3707 Attribute_Name => Name_Output,
3708 Expressions => New_List (
3709 New_Occurrence_Of (Result_Parameter, Loc),
3710 New_Occurrence_Of (Result, Loc))));
3713 Append_To (Statements,
3714 Make_Block_Statement (Loc,
3715 Declarations => Inner_Decls,
3716 Handled_Statement_Sequence =>
3717 Make_Handled_Sequence_Of_Statements (Loc,
3718 Statements => After_Statements)));
3721 -- The remote subprogram is a procedure. We do not need any inner
3722 -- block in this case.
3724 if Dynamically_Asynchronous then
3726 Make_Object_Declaration (Loc,
3727 Defining_Identifier => Dynamic_Async,
3728 Object_Definition =>
3729 New_Occurrence_Of (Standard_Boolean, Loc)));
3731 Append_To (Statements,
3732 Make_Attribute_Reference (Loc,
3733 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
3734 Attribute_Name => Name_Read,
3735 Expressions => New_List (
3736 New_Occurrence_Of (Stream_Parameter, Loc),
3737 New_Occurrence_Of (Dynamic_Async, Loc))));
3740 Append_To (Statements,
3741 Make_Procedure_Call_Statement (Loc,
3742 Name => Called_Subprogram,
3743 Parameter_Associations => Parameter_List));
3745 Append_List_To (Statements, After_Statements);
3748 if Asynchronous and then not Dynamically_Asynchronous then
3750 -- An asynchronous procedure does not want a Result
3751 -- parameter. Also, we put an exception handler with an others
3752 -- clause that does nothing.
3755 Make_Procedure_Specification (Loc,
3756 Defining_Unit_Name =>
3757 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3758 Parameter_Specifications => New_List (
3759 Make_Parameter_Specification (Loc,
3760 Defining_Identifier => Stream_Parameter,
3762 Make_Access_Definition (Loc,
3764 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3767 Make_Exception_Handler (Loc,
3768 Exception_Choices =>
3769 New_List (Make_Others_Choice (Loc)),
3770 Statements => New_List (
3771 Make_Null_Statement (Loc)));
3774 -- In the other cases, if an exception is raised, then the
3775 -- exception occurrence is copied into the output stream and
3776 -- no other output parameter is written.
3779 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3781 Excep_Code := New_List (
3782 Make_Attribute_Reference (Loc,
3784 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3785 Attribute_Name => Name_Write,
3786 Expressions => New_List (
3787 New_Occurrence_Of (Result_Parameter, Loc),
3788 New_Occurrence_Of (Excep_Choice, Loc))));
3790 if Dynamically_Asynchronous then
3791 Excep_Code := New_List (
3792 Make_Implicit_If_Statement (Vis_Decl,
3793 Condition => Make_Op_Not (Loc,
3794 New_Occurrence_Of (Dynamic_Async, Loc)),
3795 Then_Statements => Excep_Code));
3799 Make_Exception_Handler (Loc,
3800 Choice_Parameter => Excep_Choice,
3801 Exception_Choices => New_List (Make_Others_Choice (Loc)),
3802 Statements => Excep_Code);
3805 Make_Procedure_Specification (Loc,
3806 Defining_Unit_Name =>
3807 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3809 Parameter_Specifications => New_List (
3810 Make_Parameter_Specification (Loc,
3811 Defining_Identifier => Stream_Parameter,
3813 Make_Access_Definition (Loc,
3815 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
3817 Make_Parameter_Specification (Loc,
3818 Defining_Identifier => Result_Parameter,
3820 Make_Access_Definition (Loc,
3822 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3826 Make_Subprogram_Body (Loc,
3827 Specification => Subp_Spec,
3828 Declarations => Decls,
3829 Handled_Statement_Sequence =>
3830 Make_Handled_Sequence_Of_Statements (Loc,
3831 Statements => Statements,
3832 Exception_Handlers => New_List (Excep_Handler)));
3833 end Build_Subprogram_Receiving_Stubs;
3835 ------------------------
3836 -- Copy_Specification --
3837 ------------------------
3839 function Copy_Specification
3842 Object_Type : Entity_Id := Empty;
3843 Stub_Type : Entity_Id := Empty;
3844 New_Name : Name_Id := No_Name) return Node_Id
3846 Parameters : List_Id := No_List;
3848 Current_Parameter : Node_Id;
3849 Current_Identifier : Entity_Id;
3850 Current_Type : Node_Id;
3851 Current_Etype : Entity_Id;
3853 Name_For_New_Spec : Name_Id;
3855 New_Identifier : Entity_Id;
3858 if New_Name = No_Name then
3859 pragma Assert (Nkind (Spec) = N_Function_Specification
3860 or else Nkind (Spec) = N_Procedure_Specification);
3862 Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
3864 Name_For_New_Spec := New_Name;
3867 if Present (Parameter_Specifications (Spec)) then
3868 Parameters := New_List;
3869 Current_Parameter := First (Parameter_Specifications (Spec));
3870 while Current_Parameter /= Empty loop
3871 Current_Identifier := Defining_Identifier (Current_Parameter);
3872 Current_Type := Parameter_Type (Current_Parameter);
3874 if Nkind (Current_Type) = N_Access_Definition then
3875 Current_Etype := Entity (Subtype_Mark (Current_Type));
3877 if Present (Object_Type) then
3879 Root_Type (Current_Etype) = Root_Type (Object_Type));
3881 Make_Access_Definition (Loc,
3882 Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc));
3885 Make_Access_Definition (Loc,
3887 New_Occurrence_Of (Current_Etype, Loc));
3891 Current_Etype := Entity (Current_Type);
3893 if Object_Type /= Empty
3894 and then Current_Etype = Object_Type
3896 Current_Type := New_Occurrence_Of (Stub_Type, Loc);
3898 Current_Type := New_Occurrence_Of (Current_Etype, Loc);
3902 New_Identifier := Make_Defining_Identifier (Loc,
3903 Chars (Current_Identifier));
3905 Append_To (Parameters,
3906 Make_Parameter_Specification (Loc,
3907 Defining_Identifier => New_Identifier,
3908 Parameter_Type => Current_Type,
3909 In_Present => In_Present (Current_Parameter),
3910 Out_Present => Out_Present (Current_Parameter),
3912 New_Copy_Tree (Expression (Current_Parameter))));
3914 Next (Current_Parameter);
3918 case Nkind (Spec) is
3920 when N_Function_Specification | N_Access_Function_Definition =>
3922 Make_Function_Specification (Loc,
3923 Defining_Unit_Name =>
3924 Make_Defining_Identifier (Loc,
3925 Chars => Name_For_New_Spec),
3926 Parameter_Specifications => Parameters,
3928 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
3930 when N_Procedure_Specification | N_Access_Procedure_Definition =>
3932 Make_Procedure_Specification (Loc,
3933 Defining_Unit_Name =>
3934 Make_Defining_Identifier (Loc,
3935 Chars => Name_For_New_Spec),
3936 Parameter_Specifications => Parameters);
3939 raise Program_Error;
3941 end Copy_Specification;
3943 ---------------------------
3944 -- Could_Be_Asynchronous --
3945 ---------------------------
3947 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
3948 Current_Parameter : Node_Id;
3951 if Present (Parameter_Specifications (Spec)) then
3952 Current_Parameter := First (Parameter_Specifications (Spec));
3953 while Current_Parameter /= Empty loop
3954 if Out_Present (Current_Parameter) then
3958 Next (Current_Parameter);
3963 end Could_Be_Asynchronous;
3965 ---------------------------------------------
3966 -- Expand_All_Calls_Remote_Subprogram_Call --
3967 ---------------------------------------------
3969 procedure Expand_All_Calls_Remote_Subprogram_Call (N : Node_Id) is
3970 Called_Subprogram : constant Entity_Id := Entity (Name (N));
3971 RCI_Package : constant Entity_Id := Scope (Called_Subprogram);
3972 Loc : constant Source_Ptr := Sloc (N);
3973 RCI_Locator : Node_Id;
3974 RCI_Cache : Entity_Id;
3975 Calling_Stubs : Node_Id;
3976 E_Calling_Stubs : Entity_Id;
3979 E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
3981 if E_Calling_Stubs = Empty then
3982 RCI_Cache := RCI_Locator_Table.Get (RCI_Package);
3984 if RCI_Cache = Empty then
3987 (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
3988 Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator);
3990 -- The RCI_Locator package is inserted at the top level in the
3991 -- current unit, and must appear in the proper scope, so that it
3992 -- is not prematurely removed by the GCC back-end.
3995 Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
3998 if Ekind (Scop) = E_Package_Body then
3999 New_Scope (Spec_Entity (Scop));
4001 elsif Ekind (Scop) = E_Subprogram_Body then
4003 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
4009 Analyze (RCI_Locator);
4013 RCI_Cache := Defining_Unit_Name (RCI_Locator);
4016 RCI_Locator := Parent (RCI_Cache);
4019 Calling_Stubs := Build_Subprogram_Calling_Stubs
4020 (Vis_Decl => Parent (Parent (Called_Subprogram)),
4021 Subp_Id => Get_Subprogram_Id (Called_Subprogram),
4022 Asynchronous => Nkind (N) = N_Procedure_Call_Statement
4024 Is_Asynchronous (Called_Subprogram),
4025 Locator => RCI_Cache,
4026 New_Name => New_Internal_Name ('S'));
4027 Insert_After (RCI_Locator, Calling_Stubs);
4028 Analyze (Calling_Stubs);
4029 E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
4032 Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
4033 end Expand_All_Calls_Remote_Subprogram_Call;
4035 ---------------------------------
4036 -- Expand_Calling_Stubs_Bodies --
4037 ---------------------------------
4039 procedure Expand_Calling_Stubs_Bodies (Unit_Node : Node_Id) is
4040 Spec : constant Node_Id := Specification (Unit_Node);
4041 Decls : constant List_Id := Visible_Declarations (Spec);
4044 New_Scope (Scope_Of_Spec (Spec));
4045 Add_Calling_Stubs_To_Declarations (Specification (Unit_Node),
4048 end Expand_Calling_Stubs_Bodies;
4050 -----------------------------------
4051 -- Expand_Receiving_Stubs_Bodies --
4052 -----------------------------------
4054 procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is
4060 if Nkind (Unit_Node) = N_Package_Declaration then
4061 Spec := Specification (Unit_Node);
4062 Decls := Visible_Declarations (Spec);
4063 New_Scope (Scope_Of_Spec (Spec));
4064 Add_Receiving_Stubs_To_Declarations (Spec, Decls);
4068 Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
4069 Decls := Declarations (Unit_Node);
4070 New_Scope (Scope_Of_Spec (Unit_Node));
4072 Add_Receiving_Stubs_To_Declarations (Spec, Temp);
4073 Insert_List_Before (First (Decls), Temp);
4077 end Expand_Receiving_Stubs_Bodies;
4079 -------------------------
4080 -- Get_Pkg_Name_string --
4081 -------------------------
4083 procedure Get_Pkg_Name_String (Decl_Node : Node_Id) is
4084 Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
4087 Get_Unit_Name_String (Unit_Name_Id);
4089 -- Remove seven last character (" (spec)" or " (body)").
4091 Name_Len := Name_Len - 7;
4092 pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
4093 end Get_Pkg_Name_String;
4095 -----------------------
4096 -- Get_Subprogram_Id --
4097 -----------------------
4099 function Get_Subprogram_Id (E : Entity_Id) return Int is
4100 Current_Declaration : Node_Id;
4101 Result : Int := First_RCI_Subprogram_Id;
4105 (Is_Remote_Call_Interface (Scope (E))
4107 (Nkind (Parent (E)) = N_Procedure_Specification
4109 Nkind (Parent (E)) = N_Function_Specification));
4111 Current_Declaration :=
4112 First (Visible_Declarations
4113 (Package_Specification_Of_Scope (Scope (E))));
4115 while Current_Declaration /= Empty loop
4116 if Nkind (Current_Declaration) = N_Subprogram_Declaration
4117 and then Comes_From_Source (Current_Declaration)
4119 if Defining_Unit_Name
4120 (Specification (Current_Declaration)) = E
4125 Result := Result + 1;
4128 Next (Current_Declaration);
4131 -- Error if we do not find it
4133 raise Program_Error;
4134 end Get_Subprogram_Id;
4140 function Hash (F : Entity_Id) return Hash_Index is
4142 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
4145 --------------------------
4146 -- Input_With_Tag_Check --
4147 --------------------------
4149 function Input_With_Tag_Check
4151 Var_Type : Entity_Id;
4157 Make_Subprogram_Body (Loc,
4158 Specification => Make_Function_Specification (Loc,
4159 Defining_Unit_Name =>
4160 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
4161 Subtype_Mark => New_Occurrence_Of (Var_Type, Loc)),
4162 Declarations => No_List,
4163 Handled_Statement_Sequence =>
4164 Make_Handled_Sequence_Of_Statements (Loc, New_List (
4165 Make_Tag_Check (Loc,
4166 Make_Return_Statement (Loc,
4167 Make_Attribute_Reference (Loc,
4168 Prefix => New_Occurrence_Of (Var_Type, Loc),
4169 Attribute_Name => Name_Input,
4171 New_List (New_Occurrence_Of (Stream, Loc))))))));
4172 end Input_With_Tag_Check;
4174 --------------------------------
4175 -- Is_RACW_Controlling_Formal --
4176 --------------------------------
4178 function Is_RACW_Controlling_Formal
4179 (Parameter : Node_Id;
4180 Stub_Type : Entity_Id)
4186 -- If the kind of the parameter is E_Void, then it is not a
4187 -- controlling formal (this can happen in the context of RAS).
4189 if Ekind (Defining_Identifier (Parameter)) = E_Void then
4193 -- If the parameter is not a controlling formal, then it cannot
4194 -- be possibly a RACW_Controlling_Formal.
4196 if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
4200 Typ := Parameter_Type (Parameter);
4201 return (Nkind (Typ) = N_Access_Definition
4202 and then Etype (Subtype_Mark (Typ)) = Stub_Type)
4203 or else Etype (Typ) = Stub_Type;
4204 end Is_RACW_Controlling_Formal;
4206 --------------------
4207 -- Make_Tag_Check --
4208 --------------------
4210 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
4211 Occ : constant Entity_Id :=
4212 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
4215 return Make_Block_Statement (Loc,
4216 Handled_Statement_Sequence =>
4217 Make_Handled_Sequence_Of_Statements (Loc,
4218 Statements => New_List (N),
4220 Exception_Handlers => New_List (
4221 Make_Exception_Handler (Loc,
4222 Choice_Parameter => Occ,
4224 Exception_Choices =>
4225 New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
4228 New_List (Make_Procedure_Call_Statement (Loc,
4230 (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
4231 New_List (New_Occurrence_Of (Occ, Loc))))))));
4234 ----------------------------
4235 -- Need_Extra_Constrained --
4236 ----------------------------
4238 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
4239 Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
4242 return Out_Present (Parameter)
4243 and then Has_Discriminants (Etyp)
4244 and then not Is_Constrained (Etyp)
4245 and then not Is_Indefinite_Subtype (Etyp);
4246 end Need_Extra_Constrained;
4248 ------------------------------------
4249 -- Pack_Entity_Into_Stream_Access --
4250 ------------------------------------
4252 function Pack_Entity_Into_Stream_Access
4256 Etyp : Entity_Id := Empty) return Node_Id
4261 if Etyp /= Empty then
4264 Typ := Etype (Object);
4268 Pack_Node_Into_Stream_Access (Loc,
4270 Object => New_Occurrence_Of (Object, Loc),
4272 end Pack_Entity_Into_Stream_Access;
4274 ---------------------------
4275 -- Pack_Node_Into_Stream --
4276 ---------------------------
4278 function Pack_Node_Into_Stream
4282 Etyp : Entity_Id) return Node_Id
4284 Write_Attribute : Name_Id := Name_Write;
4287 if not Is_Constrained (Etyp) then
4288 Write_Attribute := Name_Output;
4292 Make_Attribute_Reference (Loc,
4293 Prefix => New_Occurrence_Of (Etyp, Loc),
4294 Attribute_Name => Write_Attribute,
4295 Expressions => New_List (
4296 Make_Attribute_Reference (Loc,
4297 Prefix => New_Occurrence_Of (Stream, Loc),
4298 Attribute_Name => Name_Access),
4300 end Pack_Node_Into_Stream;
4302 ----------------------------------
4303 -- Pack_Node_Into_Stream_Access --
4304 ----------------------------------
4306 function Pack_Node_Into_Stream_Access
4310 Etyp : Entity_Id) return Node_Id
4312 Write_Attribute : Name_Id := Name_Write;
4315 if not Is_Constrained (Etyp) then
4316 Write_Attribute := Name_Output;
4320 Make_Attribute_Reference (Loc,
4321 Prefix => New_Occurrence_Of (Etyp, Loc),
4322 Attribute_Name => Write_Attribute,
4323 Expressions => New_List (
4326 end Pack_Node_Into_Stream_Access;
4328 -------------------------------
4329 -- RACW_Type_Is_Asynchronous --
4330 -------------------------------
4332 procedure RACW_Type_Is_Asynchronous (RACW_Type : Entity_Id) is
4333 Asynchronous_Flag : constant Entity_Id :=
4334 Asynchronous_Flags_Table.Get (RACW_Type);
4336 Replace (Expression (Parent (Asynchronous_Flag)),
4337 New_Occurrence_Of (Standard_True, Sloc (Asynchronous_Flag)));
4338 end RACW_Type_Is_Asynchronous;
4340 -------------------------
4341 -- RCI_Package_Locator --
4342 -------------------------
4344 function RCI_Package_Locator
4346 Package_Spec : Node_Id) return Node_Id
4349 Pkg_Name : String_Id;
4352 Get_Pkg_Name_String (Package_Spec);
4353 Pkg_Name := String_From_Name_Buffer;
4355 Make_Package_Instantiation (Loc,
4356 Defining_Unit_Name =>
4357 Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
4359 New_Occurrence_Of (RTE (RE_RCI_Locator), Loc),
4360 Generic_Associations => New_List (
4361 Make_Generic_Association (Loc,
4363 Make_Identifier (Loc, Name_RCI_Name),
4364 Explicit_Generic_Actual_Parameter =>
4365 Make_String_Literal (Loc,
4366 Strval => Pkg_Name))));
4368 RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
4369 Defining_Unit_Name (Inst));
4371 end RCI_Package_Locator;
4373 -----------------------------------------------
4374 -- Remote_Types_Tagged_Full_View_Encountered --
4375 -----------------------------------------------
4377 procedure Remote_Types_Tagged_Full_View_Encountered
4378 (Full_View : Entity_Id)
4380 Stub_Elements : constant Stub_Structure :=
4381 Stubs_Table.Get (Full_View);
4384 if Stub_Elements /= Empty_Stub_Structure then
4385 Add_RACW_Primitive_Declarations_And_Bodies
4387 Parent (Declaration_Node (Stub_Elements.Object_RPC_Receiver)),
4388 List_Containing (Declaration_Node (Full_View)));
4390 end Remote_Types_Tagged_Full_View_Encountered;
4396 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
4397 Unit_Name : Node_Id := Defining_Unit_Name (Spec);
4400 while Nkind (Unit_Name) /= N_Defining_Identifier loop
4401 Unit_Name := Defining_Identifier (Unit_Name);
4407 --------------------------
4408 -- Underlying_RACW_Type --
4409 --------------------------
4411 function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is
4412 Record_Type : Entity_Id;
4415 if Ekind (RAS_Typ) = E_Record_Type then
4416 Record_Type := RAS_Typ;
4418 pragma Assert (Present (Equivalent_Type (RAS_Typ)));
4419 Record_Type := Equivalent_Type (RAS_Typ);
4423 Etype (Subtype_Indication (
4424 Component_Definition (
4425 First (Component_Items (Component_List (
4426 Type_Definition (Declaration_Node (Record_Type))))))));
4427 end Underlying_RACW_Type;