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 by following different pathes
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 -----------------------
80 -- Local subprograms --
81 -----------------------
83 procedure Build_General_Calling_Stubs
85 Statements : in List_Id;
86 Target_Partition : in Entity_Id;
87 RPC_Receiver : in Node_Id;
88 Subprogram_Id : in Node_Id;
89 Asynchronous : in Node_Id := Empty;
90 Is_Known_Asynchronous : in Boolean := False;
91 Is_Known_Non_Asynchronous : in Boolean := False;
92 Is_Function : in Boolean;
94 Object_Type : in Entity_Id := Empty;
96 -- Build calling stubs for general purpose. The parameters are:
97 -- Decls : a place to put declarations
98 -- Statements : a place to put statements
99 -- Target_Partition : a node containing the target partition that must
100 -- be a N_Defining_Identifier
101 -- RPC_Receiver : a node containing the RPC receiver
102 -- Subprogram_Id : a node containing the subprogram ID
103 -- Asynchronous : True if an APC must be made instead of an RPC.
104 -- The value needs not be supplied if one of the
105 -- Is_Known_... is True.
106 -- Is_Known_Async... : True if we know that this is asynchronous
107 -- Is_Known_Non_A... : True if we know that this is not asynchronous
108 -- Spec : a node with a Parameter_Specifications and
109 -- a Subtype_Mark if applicable
110 -- Object_Type : in case of a RACW, parameters of type access to
111 -- Object_Type will be marshalled using the
112 -- address of this object (the addr field) rather
113 -- than using the 'Write on the object itself
114 -- Nod : used to provide sloc for generated code
116 function Build_Subprogram_Calling_Stubs
119 Asynchronous : Boolean;
120 Dynamically_Asynchronous : Boolean := False;
121 Stub_Type : Entity_Id := Empty;
122 Locator : Entity_Id := Empty;
123 New_Name : Name_Id := No_Name)
125 -- Build the calling stub for a given subprogram with the subprogram ID
126 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
127 -- parameters of this type will be marshalled instead of the object
128 -- itself. It will then be converted into Stub_Type before performing
129 -- the real call. If Dynamically_Asynchronous is True, then it will be
130 -- computed at run time whether the call is asynchronous or not.
131 -- Otherwise, the value of the formal Asynchronous will be used.
132 -- If Locator is not Empty, it will be used instead of RCI_Cache. If
133 -- New_Name is given, then it will be used instead of the original name.
135 function Build_Subprogram_Receiving_Stubs
137 Asynchronous : Boolean;
138 Dynamically_Asynchronous : Boolean := False;
139 Stub_Type : Entity_Id := Empty;
140 RACW_Type : Entity_Id := Empty;
141 Parent_Primitive : Entity_Id := Empty)
143 -- Build the receiving stub for a given subprogram. The subprogram
144 -- declaration is also built by this procedure, and the value returned
145 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
146 -- found in the specification, then its address is read from the stream
147 -- instead of the object itself and converted into an access to
148 -- class-wide type before doing the real call using any of the RACW type
149 -- pointing on the designated type.
151 function Build_RPC_Receiver_Specification
152 (RPC_Receiver : Entity_Id;
153 Stream_Parameter : Entity_Id;
154 Result_Parameter : Entity_Id)
156 -- Make a subprogram specification for an RPC receiver,
157 -- with the given defining unit name and formal parameters.
159 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
160 -- Return an ordered parameter list: unconstrained parameters are put
161 -- at the beginning of the list and constrained ones are put after. If
162 -- there are no parameters, an empty list is returned.
164 procedure Add_Calling_Stubs_To_Declarations
165 (Pkg_Spec : in Node_Id;
167 -- Add calling stubs to the declarative part
169 procedure Add_Receiving_Stubs_To_Declarations
170 (Pkg_Spec : in Node_Id;
172 -- Add receiving stubs to the declarative part
174 procedure Add_RAS_Dereference_Attribute (N : in Node_Id);
175 -- Add a subprogram body for RAS dereference
177 procedure Add_RAS_Access_Attribute (N : in Node_Id);
178 -- Add a subprogram body for RAS Access attribute
180 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
181 -- Return True if nothing prevents the program whose specification is
182 -- given to be asynchronous (i.e. no out parameter).
184 function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id;
185 function Get_String_Id (Val : String) return String_Id;
186 -- Ugly functions used to retrieve a package name. Inherited from the
187 -- old exp_dist.adb and not rewritten yet ???
189 function Pack_Entity_Into_Stream_Access
193 Etyp : Entity_Id := Empty)
195 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
196 -- then Etype (Object) will be used if present. If the type is
197 -- constrained, then 'Write will be used to output the object,
198 -- If the type is unconstrained, 'Output will be used.
200 function Pack_Node_Into_Stream
206 -- Similar to above, with an arbitrary node instead of an entity
208 function Pack_Node_Into_Stream_Access
214 -- Similar to above, with Stream instead of Stream'Access
216 function Copy_Specification
219 Object_Type : Entity_Id := Empty;
220 Stub_Type : Entity_Id := Empty;
221 New_Name : Name_Id := No_Name)
223 -- Build a specification from another one. If Object_Type is not Empty
224 -- and any access to Object_Type is found, then it is replaced by an
225 -- access to Stub_Type. If New_Name is given, then it will be used as
226 -- the name for the newly created spec.
228 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
229 -- Return the scope represented by a given spec
231 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
232 -- Return True if the current parameter needs an extra formal to reflect
233 -- its constrained status.
235 function Is_RACW_Controlling_Formal
236 (Parameter : Node_Id; Stub_Type : Entity_Id)
238 -- Return True if the current parameter is a controlling formal argument
239 -- of type Stub_Type or access to Stub_Type.
241 type Stub_Structure is record
242 Stub_Type : Entity_Id;
243 Stub_Type_Access : Entity_Id;
244 Object_RPC_Receiver : Entity_Id;
245 RPC_Receiver_Stream : Entity_Id;
246 RPC_Receiver_Result : Entity_Id;
247 RACW_Type : Entity_Id;
249 -- This structure is necessary because of the two phases analysis of
250 -- a RACW declaration occurring in the same Remote_Types package as the
251 -- designated type. RACW_Type is any of the RACW types pointing on this
252 -- designated type, it is used here to save an anonymous type creation
253 -- for each primitive operation.
255 Empty_Stub_Structure : constant Stub_Structure :=
256 (Empty, Empty, Empty, Empty, Empty, Empty);
258 type Hash_Index is range 0 .. 50;
259 function Hash (F : Entity_Id) return Hash_Index;
261 package Stubs_Table is
262 new Simple_HTable (Header_Num => Hash_Index,
263 Element => Stub_Structure,
264 No_Element => Empty_Stub_Structure,
268 -- Mapping between a RACW designated type and its stub type
270 package Asynchronous_Flags_Table is
271 new Simple_HTable (Header_Num => Hash_Index,
277 -- Mapping between a RACW type and the node holding the value True if
278 -- the RACW is asynchronous and False otherwise.
280 package RCI_Locator_Table is
281 new Simple_HTable (Header_Num => Hash_Index,
282 Element => Entity_Id,
287 -- Mapping between a RCI package on which All_Calls_Remote applies and
288 -- the generic instantiation of RCI_Info for this package.
290 package RCI_Calling_Stubs_Table is
291 new Simple_HTable (Header_Num => Hash_Index,
292 Element => Entity_Id,
297 -- Mapping between a RCI subprogram and the corresponding calling stubs
299 procedure Add_Stub_Type
300 (Designated_Type : in Entity_Id;
301 RACW_Type : in Entity_Id;
303 Stub_Type : out Entity_Id;
304 Stub_Type_Access : out Entity_Id;
305 Object_RPC_Receiver : out Entity_Id;
306 Existing : out Boolean);
307 -- Add the declaration of the stub type, the access to stub type and the
308 -- object RPC receiver at the end of Decls. If these already exist,
309 -- then nothing is added in the tree but the right values are returned
310 -- anyhow and Existing is set to True.
312 procedure Add_RACW_Read_Attribute
313 (RACW_Type : in Entity_Id;
314 Stub_Type : in Entity_Id;
315 Stub_Type_Access : in Entity_Id;
316 Declarations : in List_Id);
317 -- Add Read attribute in Decls for the RACW type. The Read attribute
318 -- is added right after the RACW_Type declaration while the body is
319 -- inserted after Declarations.
321 procedure Add_RACW_Write_Attribute
322 (RACW_Type : in Entity_Id;
323 Stub_Type : in Entity_Id;
324 Stub_Type_Access : in Entity_Id;
325 Object_RPC_Receiver : in Entity_Id;
326 Declarations : in List_Id);
327 -- Same thing for the Write attribute
329 procedure Add_RACW_Read_Write_Attributes
330 (RACW_Type : in Entity_Id;
331 Stub_Type : in Entity_Id;
332 Stub_Type_Access : in Entity_Id;
333 Object_RPC_Receiver : in Entity_Id;
334 Declarations : in List_Id);
335 -- Add Read and Write attributes declarations and bodies for a given
336 -- RACW type. The declarations are added just after the declaration
337 -- of the RACW type itself, while the bodies are inserted at the end
340 function RCI_Package_Locator
342 Package_Spec : Node_Id)
344 -- Instantiate the generic package RCI_Info in order to locate the
345 -- RCI package whose spec is given as argument.
347 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
348 -- Surround a node N by a tag check, as in:
352 -- when E : Ada.Tags.Tag_Error =>
353 -- Raise_Exception (Program_Error'Identity,
354 -- Exception_Message (E));
357 function Input_With_Tag_Check
359 Var_Type : Entity_Id;
362 -- Return a function with the following form:
363 -- function R return Var_Type is
365 -- return Var_Type'Input (S);
367 -- when E : Ada.Tags.Tag_Error =>
368 -- Raise_Exception (Program_Error'Identity,
369 -- Exception_Message (E));
372 ------------------------------------
373 -- Local variables and structures --
374 ------------------------------------
378 Output_From_Constrained : constant array (Boolean) of Name_Id :=
379 (False => Name_Output,
381 -- The attribute to choose depending on the fact that the parameter
382 -- is constrained or not. There is no such thing as Input_From_Constrained
383 -- since this require separate mechanisms ('Input is a function while
384 -- 'Read is a procedure).
386 ---------------------------------------
387 -- Add_Calling_Stubs_To_Declarations --
388 ---------------------------------------
390 procedure Add_Calling_Stubs_To_Declarations
391 (Pkg_Spec : in Node_Id;
394 Current_Subprogram_Number : Int := 0;
395 Current_Declaration : Node_Id;
397 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
399 RCI_Instantiation : Node_Id;
401 Subp_Stubs : Node_Id;
404 -- The first thing added is an instantiation of the generic package
405 -- System.Partition_interface.RCI_Info with the name of the (current)
406 -- remote package. This will act as an interface with the name server
407 -- to determine the Partition_ID and the RPC_Receiver for the
408 -- receiver of this package.
410 RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
411 RCI_Cache := Defining_Unit_Name (RCI_Instantiation);
413 Append_To (Decls, RCI_Instantiation);
414 Analyze (RCI_Instantiation);
416 -- For each subprogram declaration visible in the spec, we do
417 -- build a body. We also increment a counter to assign a different
418 -- Subprogram_Id to each subprograms. The receiving stubs processing
419 -- do use the same mechanism and will thus assign the same Id and
420 -- do the correct dispatching.
422 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
424 while Current_Declaration /= Empty loop
426 if Nkind (Current_Declaration) = N_Subprogram_Declaration
427 and then Comes_From_Source (Current_Declaration)
429 pragma Assert (Current_Subprogram_Number =
430 Get_Subprogram_Id (Defining_Unit_Name (Specification (
431 Current_Declaration))));
434 Build_Subprogram_Calling_Stubs (
435 Vis_Decl => Current_Declaration,
436 Subp_Id => Current_Subprogram_Number,
438 Nkind (Specification (Current_Declaration)) =
439 N_Procedure_Specification
441 Is_Asynchronous (Defining_Unit_Name (Specification
442 (Current_Declaration))));
444 Append_To (Decls, Subp_Stubs);
445 Analyze (Subp_Stubs);
447 Current_Subprogram_Number := Current_Subprogram_Number + 1;
450 Next (Current_Declaration);
453 end Add_Calling_Stubs_To_Declarations;
455 -----------------------
456 -- Add_RACW_Features --
457 -----------------------
459 procedure Add_RACW_Features (RACW_Type : in Entity_Id)
461 Desig : constant Entity_Id :=
462 Etype (Designated_Type (RACW_Type));
464 List_Containing (Declaration_Node (RACW_Type));
466 Same_Scope : constant Boolean :=
467 Scope (Desig) = Scope (RACW_Type);
469 Stub_Type : Entity_Id;
470 Stub_Type_Access : Entity_Id;
471 Object_RPC_Receiver : Entity_Id;
475 if not Expander_Active then
481 -- We are declaring a RACW in the same package than its designated
482 -- type, so the list to use for late declarations must be the
483 -- private part of the package. We do know that this private part
484 -- exists since the designated type has to be a private one.
486 Decls := Private_Declarations
487 (Package_Specification_Of_Scope (Current_Scope));
489 elsif Nkind (Parent (Decls)) = N_Package_Specification
490 and then Present (Private_Declarations (Parent (Decls)))
492 Decls := Private_Declarations (Parent (Decls));
495 -- If we were unable to find the declarations, that means that the
496 -- completion of the type was missing. We can safely return and let
497 -- the error be caught by the semantic analysis.
504 (Designated_Type => Desig,
505 RACW_Type => RACW_Type,
507 Stub_Type => Stub_Type,
508 Stub_Type_Access => Stub_Type_Access,
509 Object_RPC_Receiver => Object_RPC_Receiver,
510 Existing => Existing);
512 Add_RACW_Read_Write_Attributes
513 (RACW_Type => RACW_Type,
514 Stub_Type => Stub_Type,
515 Stub_Type_Access => Stub_Type_Access,
516 Object_RPC_Receiver => Object_RPC_Receiver,
517 Declarations => Decls);
519 if not Same_Scope and then not Existing then
521 -- The RACW has been declared in another scope than the designated
522 -- type and has not been handled by another RACW in the same
523 -- package as the first one, so add primitive for the stub type
526 Add_RACW_Primitive_Declarations_And_Bodies
527 (Designated_Type => Desig,
529 Parent (Declaration_Node (Object_RPC_Receiver)),
533 Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
535 end Add_RACW_Features;
537 -------------------------------------------------
538 -- Add_RACW_Primitive_Declarations_And_Bodies --
539 -------------------------------------------------
541 procedure Add_RACW_Primitive_Declarations_And_Bodies
542 (Designated_Type : in Entity_Id;
543 Insertion_Node : in Node_Id;
546 -- Set sloc of generated declaration to be that of the
547 -- insertion node, so the declarations are recognized as
548 -- belonging to the current package.
550 Loc : constant Source_Ptr := Sloc (Insertion_Node);
552 Stub_Elements : constant Stub_Structure :=
553 Stubs_Table.Get (Designated_Type);
555 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
557 Current_Insertion_Node : Node_Id := Insertion_Node;
559 RPC_Receiver_Declarations : List_Id;
560 RPC_Receiver_Statements : List_Id;
561 RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
562 RPC_Receiver_Subp_Id : Entity_Id;
564 Current_Primitive_Elmt : Elmt_Id;
565 Current_Primitive : Entity_Id;
566 Current_Primitive_Body : Node_Id;
567 Current_Primitive_Spec : Node_Id;
568 Current_Primitive_Decl : Node_Id;
569 Current_Primitive_Number : Int := 0;
571 Current_Primitive_Alias : Node_Id;
573 Current_Receiver : Entity_Id;
574 Current_Receiver_Body : Node_Id;
576 RPC_Receiver_Decl : Node_Id;
578 Possibly_Asynchronous : Boolean;
581 if not Expander_Active then
585 -- Build callers, receivers for every primitive operations and a RPC
586 -- receiver for this type.
588 if Present (Primitive_Operations (Designated_Type)) then
590 Current_Primitive_Elmt :=
591 First_Elmt (Primitive_Operations (Designated_Type));
593 while Current_Primitive_Elmt /= No_Elmt loop
595 Current_Primitive := Node (Current_Primitive_Elmt);
597 -- Copy the primitive of all the parents, except predefined
598 -- ones that are not remotely dispatching.
600 if Chars (Current_Primitive) /= Name_uSize
601 and then Chars (Current_Primitive) /= Name_uAlignment
602 and then not Is_TSS (Current_Primitive, TSS_Deep_Finalize)
604 -- The first thing to do is build an up-to-date copy of
605 -- the spec with all the formals referencing Designated_Type
606 -- transformed into formals referencing Stub_Type. Since this
607 -- primitive may have been inherited, go back the alias chain
608 -- until the real primitive has been found.
610 Current_Primitive_Alias := Current_Primitive;
611 while Present (Alias (Current_Primitive_Alias)) loop
613 (Current_Primitive_Alias
614 /= Alias (Current_Primitive_Alias));
615 Current_Primitive_Alias := Alias (Current_Primitive_Alias);
618 Current_Primitive_Spec :=
619 Copy_Specification (Loc,
620 Spec => Parent (Current_Primitive_Alias),
621 Object_Type => Designated_Type,
622 Stub_Type => Stub_Elements.Stub_Type);
624 Current_Primitive_Decl :=
625 Make_Subprogram_Declaration (Loc,
626 Specification => Current_Primitive_Spec);
628 Insert_After (Current_Insertion_Node, Current_Primitive_Decl);
629 Analyze (Current_Primitive_Decl);
630 Current_Insertion_Node := Current_Primitive_Decl;
632 Possibly_Asynchronous :=
633 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
634 and then Could_Be_Asynchronous (Current_Primitive_Spec);
636 Current_Primitive_Body :=
637 Build_Subprogram_Calling_Stubs
638 (Vis_Decl => Current_Primitive_Decl,
639 Subp_Id => Current_Primitive_Number,
640 Asynchronous => Possibly_Asynchronous,
641 Dynamically_Asynchronous => Possibly_Asynchronous,
642 Stub_Type => Stub_Elements.Stub_Type);
643 Append_To (Decls, Current_Primitive_Body);
645 -- Analyzing the body here would cause the Stub type to be
646 -- frozen, thus preventing subsequent primitive declarations.
647 -- For this reason, it will be analyzed later in the
650 -- Build the receiver stubs
652 Current_Receiver_Body :=
653 Build_Subprogram_Receiving_Stubs
654 (Vis_Decl => Current_Primitive_Decl,
655 Asynchronous => Possibly_Asynchronous,
656 Dynamically_Asynchronous => Possibly_Asynchronous,
657 Stub_Type => Stub_Elements.Stub_Type,
658 RACW_Type => Stub_Elements.RACW_Type,
659 Parent_Primitive => Current_Primitive);
662 Defining_Unit_Name (Specification (Current_Receiver_Body));
664 Append_To (Decls, Current_Receiver_Body);
666 -- Add a case alternative to the receiver
668 Append_To (RPC_Receiver_Case_Alternatives,
669 Make_Case_Statement_Alternative (Loc,
670 Discrete_Choices => New_List (
671 Make_Integer_Literal (Loc, Current_Primitive_Number)),
673 Statements => New_List (
674 Make_Procedure_Call_Statement (Loc,
676 New_Occurrence_Of (Current_Receiver, Loc),
677 Parameter_Associations => New_List (
679 (Stub_Elements.RPC_Receiver_Stream, Loc),
681 (Stub_Elements.RPC_Receiver_Result, Loc))))));
683 -- Increment the index of current primitive
685 Current_Primitive_Number := Current_Primitive_Number + 1;
688 Next_Elmt (Current_Primitive_Elmt);
692 -- Build the case statement and the heart of the subprogram
694 Append_To (RPC_Receiver_Case_Alternatives,
695 Make_Case_Statement_Alternative (Loc,
696 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
697 Statements => New_List (Make_Null_Statement (Loc))));
699 RPC_Receiver_Subp_Id :=
700 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
702 RPC_Receiver_Declarations := New_List (
703 Make_Object_Declaration (Loc,
704 Defining_Identifier => RPC_Receiver_Subp_Id,
706 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
708 RPC_Receiver_Statements := New_List (
709 Make_Attribute_Reference (Loc,
711 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
714 Expressions => New_List (
715 New_Occurrence_Of (Stub_Elements.RPC_Receiver_Stream, Loc),
716 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc))));
718 Append_To (RPC_Receiver_Statements,
719 Make_Case_Statement (Loc,
721 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
722 Alternatives => RPC_Receiver_Case_Alternatives));
725 Make_Subprogram_Body (Loc,
727 Copy_Specification (Loc,
728 Parent (Stub_Elements.Object_RPC_Receiver)),
729 Declarations => RPC_Receiver_Declarations,
730 Handled_Statement_Sequence =>
731 Make_Handled_Sequence_Of_Statements (Loc,
732 Statements => RPC_Receiver_Statements));
734 Append_To (Decls, RPC_Receiver_Decl);
736 -- Do not analyze RPC receiver at this stage since it will otherwise
737 -- reference subprograms that have not been analyzed yet. It will
738 -- be analyzed in the regular flow.
740 end Add_RACW_Primitive_Declarations_And_Bodies;
742 -----------------------------
743 -- Add_RACW_Read_Attribute --
744 -----------------------------
746 procedure Add_RACW_Read_Attribute
747 (RACW_Type : in Entity_Id;
748 Stub_Type : in Entity_Id;
749 Stub_Type_Access : in Entity_Id;
750 Declarations : in List_Id)
752 Loc : constant Source_Ptr := Sloc (RACW_Type);
760 Statements : List_Id;
761 Local_Statements : List_Id;
762 Remote_Statements : List_Id;
763 -- Various parts of the procedure
765 Procedure_Name : constant Name_Id :=
766 New_Internal_Name ('R');
767 Source_Partition : constant Entity_Id :=
768 Make_Defining_Identifier
769 (Loc, New_Internal_Name ('P'));
770 Source_Receiver : constant Entity_Id :=
771 Make_Defining_Identifier
772 (Loc, New_Internal_Name ('S'));
773 Source_Address : constant Entity_Id :=
774 Make_Defining_Identifier
775 (Loc, New_Internal_Name ('P'));
776 Stubbed_Result : constant Entity_Id :=
777 Make_Defining_Identifier
778 (Loc, New_Internal_Name ('S'));
779 Asynchronous_Flag : constant Entity_Id :=
780 Make_Defining_Identifier
781 (Loc, New_Internal_Name ('S'));
782 Asynchronous_Node : constant Node_Id :=
783 New_Occurrence_Of (Standard_False, Loc);
785 -- Functions to create occurrences of the formal
788 function Stream_Parameter return Node_Id;
789 function Result return Node_Id;
791 function Stream_Parameter return Node_Id is
793 return Make_Identifier (Loc, Name_S);
794 end Stream_Parameter;
796 function Result return Node_Id is
798 return Make_Identifier (Loc, Name_V);
802 -- Declare the asynchronous flag. This flag will be changed to True
803 -- whenever it is known that the RACW type is asynchronous. Also, the
804 -- node gets stored since it may be rewritten when we process the
805 -- asynchronous pragma.
807 Append_To (Declarations,
808 Make_Object_Declaration (Loc,
809 Defining_Identifier => Asynchronous_Flag,
810 Constant_Present => True,
811 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
812 Expression => Asynchronous_Node));
814 Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Node);
816 -- Object declarations
819 Make_Object_Declaration (Loc,
820 Defining_Identifier => Source_Partition,
822 New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
824 Make_Object_Declaration (Loc,
825 Defining_Identifier => Source_Receiver,
827 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
829 Make_Object_Declaration (Loc,
830 Defining_Identifier => Source_Address,
832 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
834 Make_Object_Declaration (Loc,
835 Defining_Identifier => Stubbed_Result,
837 New_Occurrence_Of (Stub_Type_Access, Loc)));
839 -- Read the source Partition_ID and RPC_Receiver from incoming stream
841 Statements := New_List (
842 Make_Attribute_Reference (Loc,
844 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
845 Attribute_Name => Name_Read,
846 Expressions => New_List (
848 New_Occurrence_Of (Source_Partition, Loc))),
850 Make_Attribute_Reference (Loc,
852 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
855 Expressions => New_List (
857 New_Occurrence_Of (Source_Receiver, Loc))),
859 Make_Attribute_Reference (Loc,
861 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
864 Expressions => New_List (
866 New_Occurrence_Of (Source_Address, Loc))));
868 -- If the Address is Null_Address, then return a null object
870 Append_To (Statements,
871 Make_Implicit_If_Statement (RACW_Type,
874 Left_Opnd => New_Occurrence_Of (Source_Address, Loc),
875 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
876 Then_Statements => New_List (
877 Make_Assignment_Statement (Loc,
879 Expression => Make_Null (Loc)),
880 Make_Return_Statement (Loc))));
882 -- If the RACW denotes an object created on the current partition, then
883 -- Local_Statements will be executed. The real object will be used.
885 Local_Statements := New_List (
886 Make_Assignment_Statement (Loc,
889 Unchecked_Convert_To (RACW_Type,
890 OK_Convert_To (RTE (RE_Address),
891 New_Occurrence_Of (Source_Address, Loc)))));
893 -- If the object is located on another partition, then a stub object
894 -- will be created with all the information needed to rebuild the
895 -- real object at the other end.
897 Remote_Statements := New_List (
899 Make_Assignment_Statement (Loc,
900 Name => New_Occurrence_Of (Stubbed_Result, Loc),
903 New_Occurrence_Of (Stub_Type, Loc))),
905 Make_Assignment_Statement (Loc,
906 Name => Make_Selected_Component (Loc,
907 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
908 Selector_Name => Make_Identifier (Loc, Name_Origin)),
910 New_Occurrence_Of (Source_Partition, Loc)),
912 Make_Assignment_Statement (Loc,
913 Name => Make_Selected_Component (Loc,
914 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
915 Selector_Name => Make_Identifier (Loc, Name_Receiver)),
917 New_Occurrence_Of (Source_Receiver, Loc)),
919 Make_Assignment_Statement (Loc,
920 Name => Make_Selected_Component (Loc,
921 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
922 Selector_Name => Make_Identifier (Loc, Name_Addr)),
924 New_Occurrence_Of (Source_Address, Loc)));
926 Append_To (Remote_Statements,
927 Make_Assignment_Statement (Loc,
928 Name => Make_Selected_Component (Loc,
929 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
930 Selector_Name => Make_Identifier (Loc, Name_Asynchronous)),
932 New_Occurrence_Of (Asynchronous_Flag, Loc)));
934 Append_To (Remote_Statements,
935 Make_Procedure_Call_Statement (Loc,
937 New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
938 Parameter_Associations => New_List (
939 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
940 New_Occurrence_Of (Stubbed_Result, Loc)))));
942 Append_To (Remote_Statements,
943 Make_Assignment_Statement (Loc,
945 Expression => Unchecked_Convert_To (RACW_Type,
946 New_Occurrence_Of (Stubbed_Result, Loc))));
948 -- Distinguish between the local and remote cases, and execute the
949 -- appropriate piece of code.
951 Append_To (Statements,
952 Make_Implicit_If_Statement (RACW_Type,
956 Make_Function_Call (Loc,
958 New_Occurrence_Of (RTE (RE_Get_Local_Partition_Id), Loc)),
959 Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
960 Then_Statements => Local_Statements,
961 Else_Statements => Remote_Statements));
963 Build_Stream_Procedure
964 (Loc, RACW_Type, Body_Node,
965 Make_Defining_Identifier (Loc, Procedure_Name),
966 Statements, Outp => True);
967 Set_Declarations (Body_Node, Decls);
969 Proc_Decl := Make_Subprogram_Declaration (Loc,
970 Copy_Specification (Loc, Specification (Body_Node)));
973 Make_Attribute_Definition_Clause (Loc,
974 Name => New_Occurrence_Of (RACW_Type, Loc),
978 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
980 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
981 Insert_After (Proc_Decl, Attr_Decl);
982 Append_To (Declarations, Body_Node);
983 end Add_RACW_Read_Attribute;
985 ------------------------------------
986 -- Add_RACW_Read_Write_Attributes --
987 ------------------------------------
989 procedure Add_RACW_Read_Write_Attributes
990 (RACW_Type : in Entity_Id;
991 Stub_Type : in Entity_Id;
992 Stub_Type_Access : in Entity_Id;
993 Object_RPC_Receiver : in Entity_Id;
994 Declarations : in List_Id)
997 Add_RACW_Write_Attribute
998 (RACW_Type => RACW_Type,
999 Stub_Type => Stub_Type,
1000 Stub_Type_Access => Stub_Type_Access,
1001 Object_RPC_Receiver => Object_RPC_Receiver,
1002 Declarations => Declarations);
1004 Add_RACW_Read_Attribute
1005 (RACW_Type => RACW_Type,
1006 Stub_Type => Stub_Type,
1007 Stub_Type_Access => Stub_Type_Access,
1008 Declarations => Declarations);
1009 end Add_RACW_Read_Write_Attributes;
1011 ------------------------------
1012 -- Add_RACW_Write_Attribute --
1013 ------------------------------
1015 procedure Add_RACW_Write_Attribute
1016 (RACW_Type : in Entity_Id;
1017 Stub_Type : in Entity_Id;
1018 Stub_Type_Access : in Entity_Id;
1019 Object_RPC_Receiver : in Entity_Id;
1020 Declarations : in List_Id)
1022 Loc : constant Source_Ptr := Sloc (RACW_Type);
1024 Body_Node : Node_Id;
1025 Proc_Decl : Node_Id;
1026 Attr_Decl : Node_Id;
1028 Statements : List_Id;
1029 Local_Statements : List_Id;
1030 Remote_Statements : List_Id;
1031 Null_Statements : List_Id;
1033 Procedure_Name : constant Name_Id := New_Internal_Name ('R');
1035 -- Functions to create occurrences of the formal
1038 function Stream_Parameter return Node_Id;
1039 function Object return Node_Id;
1041 function Stream_Parameter return Node_Id is
1043 return Make_Identifier (Loc, Name_S);
1044 end Stream_Parameter;
1046 function Object return Node_Id is
1048 return Make_Identifier (Loc, Name_V);
1052 -- Build the code fragment corresponding to the marshalling of a
1055 Local_Statements := New_List (
1057 Pack_Entity_Into_Stream_Access (Loc,
1058 Stream => Stream_Parameter,
1059 Object => RTE (RE_Get_Local_Partition_Id)),
1061 Pack_Node_Into_Stream_Access (Loc,
1062 Stream => Stream_Parameter,
1063 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1064 Make_Attribute_Reference (Loc,
1065 Prefix => New_Occurrence_Of (Object_RPC_Receiver, Loc),
1066 Attribute_Name => Name_Address)),
1067 Etyp => RTE (RE_Unsigned_64)),
1069 Pack_Node_Into_Stream_Access (Loc,
1070 Stream => Stream_Parameter,
1071 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1072 Make_Attribute_Reference (Loc,
1074 Make_Explicit_Dereference (Loc,
1076 Attribute_Name => Name_Address)),
1077 Etyp => RTE (RE_Unsigned_64)));
1079 -- Build the code fragment corresponding to the marshalling of
1082 Remote_Statements := New_List (
1084 Pack_Node_Into_Stream_Access (Loc,
1085 Stream => Stream_Parameter,
1087 Make_Selected_Component (Loc,
1088 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1091 Make_Identifier (Loc, Name_Origin)),
1092 Etyp => RTE (RE_Partition_ID)),
1094 Pack_Node_Into_Stream_Access (Loc,
1095 Stream => Stream_Parameter,
1097 Make_Selected_Component (Loc,
1098 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1101 Make_Identifier (Loc, Name_Receiver)),
1102 Etyp => RTE (RE_Unsigned_64)),
1104 Pack_Node_Into_Stream_Access (Loc,
1105 Stream => Stream_Parameter,
1107 Make_Selected_Component (Loc,
1108 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1111 Make_Identifier (Loc, Name_Addr)),
1112 Etyp => RTE (RE_Unsigned_64)));
1114 -- Build the code fragment corresponding to the marshalling of a null
1117 Null_Statements := New_List (
1119 Pack_Entity_Into_Stream_Access (Loc,
1120 Stream => Stream_Parameter,
1121 Object => RTE (RE_Get_Local_Partition_Id)),
1123 Pack_Node_Into_Stream_Access (Loc,
1124 Stream => Stream_Parameter,
1125 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1126 Make_Attribute_Reference (Loc,
1127 Prefix => New_Occurrence_Of (Object_RPC_Receiver, Loc),
1128 Attribute_Name => Name_Address)),
1129 Etyp => RTE (RE_Unsigned_64)),
1131 Pack_Node_Into_Stream_Access (Loc,
1132 Stream => Stream_Parameter,
1133 Object => Make_Integer_Literal (Loc, Uint_0),
1134 Etyp => RTE (RE_Unsigned_64)));
1136 Statements := New_List (
1137 Make_Implicit_If_Statement (RACW_Type,
1140 Left_Opnd => Object,
1141 Right_Opnd => Make_Null (Loc)),
1142 Then_Statements => Null_Statements,
1143 Elsif_Parts => New_List (
1144 Make_Elsif_Part (Loc,
1148 Make_Attribute_Reference (Loc,
1150 Attribute_Name => Name_Tag),
1152 Make_Attribute_Reference (Loc,
1153 Prefix => New_Occurrence_Of (Stub_Type, Loc),
1154 Attribute_Name => Name_Tag)),
1155 Then_Statements => Remote_Statements)),
1156 Else_Statements => Local_Statements));
1158 Build_Stream_Procedure
1159 (Loc, RACW_Type, Body_Node,
1160 Make_Defining_Identifier (Loc, Procedure_Name),
1161 Statements, Outp => False);
1163 Proc_Decl := Make_Subprogram_Declaration (Loc,
1164 Copy_Specification (Loc, Specification (Body_Node)));
1167 Make_Attribute_Definition_Clause (Loc,
1168 Name => New_Occurrence_Of (RACW_Type, Loc),
1169 Chars => Name_Write,
1172 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
1174 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
1175 Insert_After (Proc_Decl, Attr_Decl);
1176 Append_To (Declarations, Body_Node);
1177 end Add_RACW_Write_Attribute;
1179 ------------------------------
1180 -- Add_RAS_Access_Attribute --
1181 ------------------------------
1183 procedure Add_RAS_Access_Attribute (N : in Node_Id) is
1184 Ras_Type : constant Entity_Id := Defining_Identifier (N);
1185 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
1186 -- Ras_Type is the access to subprogram type while Fat_Type points to
1187 -- the record type corresponding to a remote access to subprogram type.
1189 Proc_Decls : constant List_Id := New_List;
1190 Proc_Statements : constant List_Id := New_List;
1192 Proc_Spec : Node_Id;
1197 Package_Name : Node_Id;
1199 Asynchronous : Node_Id;
1200 Return_Value : Node_Id;
1202 Loc : constant Source_Ptr := Sloc (N);
1204 procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id);
1205 -- Set a field name for the return value
1207 procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id)
1210 Append_To (Proc_Statements,
1211 Make_Assignment_Statement (Loc,
1213 Make_Selected_Component (Loc,
1214 Prefix => New_Occurrence_Of (Return_Value, Loc),
1215 Selector_Name => Make_Identifier (Loc, Field_Name)),
1216 Expression => Value));
1219 -- Start of processing for Add_RAS_Access_Attribute
1222 Param := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1223 Package_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1224 Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
1225 Asynchronous := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1226 Return_Value := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1228 -- Create the object which will be returned of type Fat_Type
1230 Append_To (Proc_Decls,
1231 Make_Object_Declaration (Loc,
1232 Defining_Identifier => Return_Value,
1233 Object_Definition =>
1234 New_Occurrence_Of (Fat_Type, Loc)));
1236 -- Initialize the fields of the record type with the appropriate data
1238 Set_Field (Name_Ras,
1239 OK_Convert_To (RTE (RE_Unsigned_64), New_Occurrence_Of (Param, Loc)));
1241 Set_Field (Name_Origin,
1242 Unchecked_Convert_To (Standard_Integer,
1243 Make_Function_Call (Loc,
1245 New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
1246 Parameter_Associations => New_List (
1247 New_Occurrence_Of (Package_Name, Loc)))));
1249 Set_Field (Name_Receiver,
1250 Make_Function_Call (Loc,
1252 New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
1253 Parameter_Associations => New_List (
1254 New_Occurrence_Of (Package_Name, Loc))));
1256 Set_Field (Name_Subp_Id,
1257 New_Occurrence_Of (Subp_Id, Loc));
1259 Set_Field (Name_Async,
1260 New_Occurrence_Of (Asynchronous, Loc));
1262 -- Return the newly created value
1264 Append_To (Proc_Statements,
1265 Make_Return_Statement (Loc,
1267 New_Occurrence_Of (Return_Value, Loc)));
1270 Make_Defining_Identifier (Loc,
1271 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
1274 Make_Function_Specification (Loc,
1275 Defining_Unit_Name => Proc,
1276 Parameter_Specifications => New_List (
1277 Make_Parameter_Specification (Loc,
1278 Defining_Identifier => Param,
1280 New_Occurrence_Of (RTE (RE_Address), Loc)),
1282 Make_Parameter_Specification (Loc,
1283 Defining_Identifier => Package_Name,
1285 New_Occurrence_Of (Standard_String, Loc)),
1287 Make_Parameter_Specification (Loc,
1288 Defining_Identifier => Subp_Id,
1290 New_Occurrence_Of (Standard_Natural, Loc)),
1292 Make_Parameter_Specification (Loc,
1293 Defining_Identifier => Asynchronous,
1295 New_Occurrence_Of (Standard_Boolean, Loc))),
1298 New_Occurrence_Of (Fat_Type, Loc));
1300 -- Set the kind and return type of the function to prevent ambiguities
1301 -- between Ras_Type and Fat_Type in subsequent analysis.
1303 Set_Ekind (Proc, E_Function);
1304 Set_Etype (Proc, New_Occurrence_Of (Fat_Type, Loc));
1307 Make_Subprogram_Body (Loc,
1308 Specification => Proc_Spec,
1309 Declarations => Proc_Decls,
1310 Handled_Statement_Sequence =>
1311 Make_Handled_Sequence_Of_Statements (Loc,
1312 Statements => Proc_Statements)));
1314 Set_TSS (Fat_Type, Proc);
1316 end Add_RAS_Access_Attribute;
1318 -----------------------------------
1319 -- Add_RAS_Dereference_Attribute --
1320 -----------------------------------
1322 procedure Add_RAS_Dereference_Attribute (N : in Node_Id) is
1323 Loc : constant Source_Ptr := Sloc (N);
1325 Type_Def : constant Node_Id := Type_Definition (N);
1327 Ras_Type : constant Entity_Id := Defining_Identifier (N);
1329 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
1331 Proc_Decls : constant List_Id := New_List;
1332 Proc_Statements : constant List_Id := New_List;
1334 Inner_Decls : constant List_Id := New_List;
1335 Inner_Statements : constant List_Id := New_List;
1337 Direct_Statements : constant List_Id := New_List;
1340 Proc_Spec : Node_Id;
1341 Param_Specs : constant List_Id := New_List;
1342 Param_Assoc : constant List_Id := New_List;
1346 Converted_Ras : Node_Id;
1347 Target_Partition : Node_Id;
1348 RPC_Receiver : Node_Id;
1349 Subprogram_Id : Node_Id;
1350 Asynchronous : Node_Id;
1352 Is_Function : constant Boolean :=
1353 Nkind (Type_Def) = N_Access_Function_Definition;
1355 Spec : constant Node_Id := Type_Def;
1357 Current_Parameter : Node_Id;
1360 -- The way to do it is test if the Ras field is non-null and then if
1361 -- the Origin field is equal to the current partition ID (which is in
1362 -- fact Current_Package'Partition_ID). If this is the case, then it
1363 -- is safe to dereference the Ras field directly rather than
1364 -- performing a remote call.
1367 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1370 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1372 Append_To (Proc_Decls,
1373 Make_Object_Declaration (Loc,
1374 Defining_Identifier => Target_Partition,
1375 Constant_Present => True,
1376 Object_Definition =>
1377 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
1379 Unchecked_Convert_To (RTE (RE_Partition_ID),
1380 Make_Selected_Component (Loc,
1382 New_Occurrence_Of (Pointer, Loc),
1384 Make_Identifier (Loc, Name_Origin)))));
1387 Make_Selected_Component (Loc,
1389 New_Occurrence_Of (Pointer, Loc),
1391 Make_Identifier (Loc, Name_Receiver));
1394 Unchecked_Convert_To (RTE (RE_Subprogram_Id),
1395 Make_Selected_Component (Loc,
1397 New_Occurrence_Of (Pointer, Loc),
1399 Make_Identifier (Loc, Name_Subp_Id)));
1401 -- A function is never asynchronous. A procedure may or may not be
1402 -- asynchronous depending on whether a pragma Asynchronous applies
1403 -- on it. Since a RAST may point onto various subprograms, this is
1404 -- only known at runtime so both versions (synchronous and asynchronous)
1405 -- must be built every times it is not a function.
1408 Asynchronous := Empty;
1412 Make_Selected_Component (Loc,
1414 New_Occurrence_Of (Pointer, Loc),
1416 Make_Identifier (Loc, Name_Async));
1420 if Present (Parameter_Specifications (Type_Def)) then
1421 Current_Parameter := First (Parameter_Specifications (Type_Def));
1423 while Current_Parameter /= Empty loop
1424 Append_To (Param_Specs,
1425 Make_Parameter_Specification (Loc,
1426 Defining_Identifier =>
1427 Make_Defining_Identifier (Loc,
1429 Chars (Defining_Identifier (Current_Parameter))),
1430 In_Present => In_Present (Current_Parameter),
1431 Out_Present => Out_Present (Current_Parameter),
1433 New_Copy_Tree (Parameter_Type (Current_Parameter)),
1435 New_Copy_Tree (Expression (Current_Parameter))));
1437 Append_To (Param_Assoc,
1438 Make_Identifier (Loc,
1439 Chars => Chars (Defining_Identifier (Current_Parameter))));
1441 Next (Current_Parameter);
1446 Make_Defining_Identifier (Loc,
1447 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Dereference));
1451 Make_Function_Specification (Loc,
1452 Defining_Unit_Name => Proc,
1453 Parameter_Specifications => Param_Specs,
1456 Entity (Subtype_Mark (Spec)), Loc));
1458 Set_Ekind (Proc, E_Function);
1461 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
1465 Make_Procedure_Specification (Loc,
1466 Defining_Unit_Name => Proc,
1467 Parameter_Specifications => Param_Specs);
1469 Set_Ekind (Proc, E_Procedure);
1470 Set_Etype (Proc, Standard_Void_Type);
1473 -- Build the calling stubs for the dereference of the RAS
1475 Build_General_Calling_Stubs
1476 (Decls => Inner_Decls,
1477 Statements => Inner_Statements,
1478 Target_Partition => Target_Partition,
1479 RPC_Receiver => RPC_Receiver,
1480 Subprogram_Id => Subprogram_Id,
1481 Asynchronous => Asynchronous,
1482 Is_Known_Non_Asynchronous => Is_Function,
1483 Is_Function => Is_Function,
1488 Unchecked_Convert_To (Ras_Type,
1489 OK_Convert_To (RTE (RE_Address),
1490 Make_Selected_Component (Loc,
1491 Prefix => New_Occurrence_Of (Pointer, Loc),
1492 Selector_Name => Make_Identifier (Loc, Name_Ras))));
1495 Append_To (Direct_Statements,
1496 Make_Return_Statement (Loc,
1498 Make_Function_Call (Loc,
1500 Make_Explicit_Dereference (Loc,
1501 Prefix => Converted_Ras),
1502 Parameter_Associations => Param_Assoc)));
1505 Append_To (Direct_Statements,
1506 Make_Procedure_Call_Statement (Loc,
1508 Make_Explicit_Dereference (Loc,
1509 Prefix => Converted_Ras),
1510 Parameter_Associations => Param_Assoc));
1513 Prepend_To (Param_Specs,
1514 Make_Parameter_Specification (Loc,
1515 Defining_Identifier => Pointer,
1518 New_Occurrence_Of (Fat_Type, Loc)));
1520 Append_To (Proc_Statements,
1521 Make_Implicit_If_Statement (N,
1527 Make_Selected_Component (Loc,
1528 Prefix => New_Occurrence_Of (Pointer, Loc),
1529 Selector_Name => Make_Identifier (Loc, Name_Ras)),
1531 Make_Integer_Literal (Loc, Uint_0)),
1536 New_Occurrence_Of (Target_Partition, Loc),
1538 Make_Function_Call (Loc,
1540 RTE (RE_Get_Local_Partition_Id), Loc)))),
1545 Else_Statements => New_List (
1546 Make_Block_Statement (Loc,
1547 Declarations => Inner_Decls,
1548 Handled_Statement_Sequence =>
1549 Make_Handled_Sequence_Of_Statements (Loc,
1550 Statements => Inner_Statements)))));
1553 Make_Subprogram_Body (Loc,
1554 Specification => Proc_Spec,
1555 Declarations => Proc_Decls,
1556 Handled_Statement_Sequence =>
1557 Make_Handled_Sequence_Of_Statements (Loc,
1558 Statements => Proc_Statements)));
1560 Set_TSS (Fat_Type, Defining_Unit_Name (Proc_Spec));
1562 end Add_RAS_Dereference_Attribute;
1564 -----------------------
1565 -- Add_RAST_Features --
1566 -----------------------
1568 procedure Add_RAST_Features (Vis_Decl : Node_Id) is
1570 -- Do not add attributes more than once in any case. This should
1571 -- be replaced by an assert or this comment removed if we decide
1572 -- that this is normal to be called several times ???
1574 if Present (TSS (Equivalent_Type (Defining_Identifier (Vis_Decl)),
1580 Add_RAS_Dereference_Attribute (Vis_Decl);
1581 Add_RAS_Access_Attribute (Vis_Decl);
1582 end Add_RAST_Features;
1584 -----------------------------------------
1585 -- Add_Receiving_Stubs_To_Declarations --
1586 -----------------------------------------
1588 procedure Add_Receiving_Stubs_To_Declarations
1589 (Pkg_Spec : in Node_Id;
1592 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
1594 Stream_Parameter : Node_Id;
1595 Result_Parameter : Node_Id;
1597 Pkg_RPC_Receiver : Node_Id;
1598 Pkg_RPC_Receiver_Spec : Node_Id;
1599 Pkg_RPC_Receiver_Decls : List_Id;
1600 Pkg_RPC_Receiver_Statements : List_Id;
1601 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
1602 Pkg_RPC_Receiver_Body : Node_Id;
1603 -- A Pkg_RPC_Receiver is built to decode the request
1606 -- Subprogram_Id as read from the incoming stream
1608 Current_Declaration : Node_Id;
1609 Current_Subprogram_Number : Int := 0;
1610 Current_Stubs : Node_Id;
1614 Dummy_Register_Name : Name_Id;
1615 Dummy_Register_Spec : Node_Id;
1616 Dummy_Register_Decl : Node_Id;
1617 Dummy_Register_Body : Node_Id;
1620 -- Building receiving stubs consist in several operations:
1622 -- - a package RPC receiver must be built. This subprogram
1623 -- will get a Subprogram_Id from the incoming stream
1624 -- and will dispatch the call to the right subprogram
1626 -- - a receiving stub for any subprogram visible in the package
1627 -- spec. This stub will read all the parameters from the stream,
1628 -- and put the result as well as the exception occurrence in the
1631 -- - a dummy package with an empty spec and a body made of an
1632 -- elaboration part, whose job is to register the receiving
1633 -- part of this RCI package on the name server. This is done
1634 -- by calling System.Partition_Interface.Register_Receiving_Stub
1637 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1639 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
1641 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1644 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1646 -- The parameters of the package RPC receiver are made of two
1647 -- streams, an input one and an output one.
1649 Pkg_RPC_Receiver_Spec :=
1650 Build_RPC_Receiver_Specification
1651 (RPC_Receiver => Pkg_RPC_Receiver,
1652 Stream_Parameter => Stream_Parameter,
1653 Result_Parameter => Result_Parameter);
1655 Pkg_RPC_Receiver_Decls := New_List (
1656 Make_Object_Declaration (Loc,
1657 Defining_Identifier => Subp_Id,
1658 Object_Definition =>
1659 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
1661 Pkg_RPC_Receiver_Statements := New_List (
1662 Make_Attribute_Reference (Loc,
1664 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
1667 Expressions => New_List (
1668 New_Occurrence_Of (Stream_Parameter, Loc),
1669 New_Occurrence_Of (Subp_Id, Loc))));
1671 -- For each subprogram, the receiving stub will be built and a
1672 -- case statement will be made on the Subprogram_Id to dispatch
1673 -- to the right subprogram.
1675 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
1677 while Current_Declaration /= Empty loop
1679 if Nkind (Current_Declaration) = N_Subprogram_Declaration
1680 and then Comes_From_Source (Current_Declaration)
1682 pragma Assert (Current_Subprogram_Number =
1683 Get_Subprogram_Id (Defining_Unit_Name (Specification (
1684 Current_Declaration))));
1687 Build_Subprogram_Receiving_Stubs
1688 (Vis_Decl => Current_Declaration,
1690 Nkind (Specification (Current_Declaration)) =
1691 N_Procedure_Specification
1692 and then Is_Asynchronous
1693 (Defining_Unit_Name (Specification
1694 (Current_Declaration))));
1696 Append_To (Decls, Current_Stubs);
1698 Analyze (Current_Stubs);
1700 Actuals := New_List (New_Occurrence_Of (Stream_Parameter, Loc));
1702 if Nkind (Specification (Current_Declaration))
1703 = N_Function_Specification
1705 not Is_Asynchronous (
1706 Defining_Entity (Specification (Current_Declaration)))
1708 -- An asynchronous procedure does not want an output parameter
1709 -- since no result and no exception will ever be returned.
1712 New_Occurrence_Of (Result_Parameter, Loc));
1716 Append_To (Pkg_RPC_Receiver_Cases,
1717 Make_Case_Statement_Alternative (Loc,
1720 Make_Integer_Literal (Loc, Current_Subprogram_Number)),
1724 Make_Procedure_Call_Statement (Loc,
1727 Defining_Entity (Current_Stubs), Loc),
1728 Parameter_Associations =>
1731 Current_Subprogram_Number := Current_Subprogram_Number + 1;
1734 Next (Current_Declaration);
1737 -- If we receive an invalid Subprogram_Id, it is best to do nothing
1738 -- rather than raising an exception since we do not want someone
1739 -- to crash a remote partition by sending invalid subprogram ids.
1740 -- This is consistent with the other parts of the case statement
1741 -- since even in presence of incorrect parameters in the stream,
1742 -- every exception will be caught and (if the subprogram is not an
1743 -- APC) put into the result stream and sent away.
1745 Append_To (Pkg_RPC_Receiver_Cases,
1746 Make_Case_Statement_Alternative (Loc,
1748 New_List (Make_Others_Choice (Loc)),
1750 New_List (Make_Null_Statement (Loc))));
1752 Append_To (Pkg_RPC_Receiver_Statements,
1753 Make_Case_Statement (Loc,
1755 New_Occurrence_Of (Subp_Id, Loc),
1756 Alternatives => Pkg_RPC_Receiver_Cases));
1758 Pkg_RPC_Receiver_Body :=
1759 Make_Subprogram_Body (Loc,
1760 Specification => Pkg_RPC_Receiver_Spec,
1761 Declarations => Pkg_RPC_Receiver_Decls,
1762 Handled_Statement_Sequence =>
1763 Make_Handled_Sequence_Of_Statements (Loc,
1764 Statements => Pkg_RPC_Receiver_Statements));
1766 Append_To (Decls, Pkg_RPC_Receiver_Body);
1767 Analyze (Pkg_RPC_Receiver_Body);
1769 -- Construction of the dummy package used to register the package
1770 -- receiving stubs on the nameserver.
1772 Dummy_Register_Name := New_Internal_Name ('P');
1774 Dummy_Register_Spec :=
1775 Make_Package_Specification (Loc,
1776 Defining_Unit_Name =>
1777 Make_Defining_Identifier (Loc, Dummy_Register_Name),
1778 Visible_Declarations => No_List,
1779 End_Label => Empty);
1781 Dummy_Register_Decl :=
1782 Make_Package_Declaration (Loc,
1783 Specification => Dummy_Register_Spec);
1786 Dummy_Register_Decl);
1787 Analyze (Dummy_Register_Decl);
1789 Dummy_Register_Body :=
1790 Make_Package_Body (Loc,
1791 Defining_Unit_Name =>
1792 Make_Defining_Identifier (Loc, Dummy_Register_Name),
1793 Declarations => No_List,
1795 Handled_Statement_Sequence =>
1796 Make_Handled_Sequence_Of_Statements (Loc,
1797 Statements => New_List (
1798 Make_Procedure_Call_Statement (Loc,
1800 New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
1802 Parameter_Associations => New_List (
1803 Make_String_Literal (Loc,
1804 Strval => Get_Pkg_Name_String_Id (Pkg_Spec)),
1805 Make_Attribute_Reference (Loc,
1807 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
1809 Name_Unrestricted_Access),
1810 Make_Attribute_Reference (Loc,
1812 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
1816 Append_To (Decls, Dummy_Register_Body);
1817 Analyze (Dummy_Register_Body);
1818 end Add_Receiving_Stubs_To_Declarations;
1824 procedure Add_Stub_Type
1825 (Designated_Type : in Entity_Id;
1826 RACW_Type : in Entity_Id;
1828 Stub_Type : out Entity_Id;
1829 Stub_Type_Access : out Entity_Id;
1830 Object_RPC_Receiver : out Entity_Id;
1831 Existing : out Boolean)
1833 Loc : constant Source_Ptr := Sloc (RACW_Type);
1835 Stub_Elements : constant Stub_Structure :=
1836 Stubs_Table.Get (Designated_Type);
1838 Stub_Type_Declaration : Node_Id;
1839 Stub_Type_Access_Declaration : Node_Id;
1840 Object_RPC_Receiver_Declaration : Node_Id;
1842 RPC_Receiver_Stream : Entity_Id;
1843 RPC_Receiver_Result : Entity_Id;
1846 if Stub_Elements /= Empty_Stub_Structure then
1847 Stub_Type := Stub_Elements.Stub_Type;
1848 Stub_Type_Access := Stub_Elements.Stub_Type_Access;
1849 Object_RPC_Receiver := Stub_Elements.Object_RPC_Receiver;
1856 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1858 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1859 Object_RPC_Receiver :=
1860 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1861 RPC_Receiver_Stream :=
1862 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1863 RPC_Receiver_Result :=
1864 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1865 Stubs_Table.Set (Designated_Type,
1866 (Stub_Type => Stub_Type,
1867 Stub_Type_Access => Stub_Type_Access,
1868 Object_RPC_Receiver => Object_RPC_Receiver,
1869 RPC_Receiver_Stream => RPC_Receiver_Stream,
1870 RPC_Receiver_Result => RPC_Receiver_Result,
1871 RACW_Type => RACW_Type));
1873 -- The stub type definition below must match exactly the one in
1874 -- s-parint.ads, since unchecked conversions will be used in
1875 -- s-parint.adb to modify pointers passed to Get_Unique_Remote_Pointer.
1877 Stub_Type_Declaration :=
1878 Make_Full_Type_Declaration (Loc,
1879 Defining_Identifier => Stub_Type,
1881 Make_Record_Definition (Loc,
1882 Tagged_Present => True,
1883 Limited_Present => True,
1885 Make_Component_List (Loc,
1886 Component_Items => New_List (
1888 Make_Component_Declaration (Loc,
1889 Defining_Identifier =>
1890 Make_Defining_Identifier (Loc, Name_Origin),
1891 Component_Definition =>
1892 Make_Component_Definition (Loc,
1893 Aliased_Present => False,
1894 Subtype_Indication =>
1895 New_Occurrence_Of (RTE (RE_Partition_ID), Loc))),
1897 Make_Component_Declaration (Loc,
1898 Defining_Identifier =>
1899 Make_Defining_Identifier (Loc, Name_Receiver),
1900 Component_Definition =>
1901 Make_Component_Definition (Loc,
1902 Aliased_Present => False,
1903 Subtype_Indication =>
1904 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
1906 Make_Component_Declaration (Loc,
1907 Defining_Identifier =>
1908 Make_Defining_Identifier (Loc, Name_Addr),
1909 Component_Definition =>
1910 Make_Component_Definition (Loc,
1911 Aliased_Present => False,
1912 Subtype_Indication =>
1913 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
1915 Make_Component_Declaration (Loc,
1916 Defining_Identifier =>
1917 Make_Defining_Identifier (Loc, Name_Asynchronous),
1918 Component_Definition =>
1919 Make_Component_Definition (Loc,
1920 Aliased_Present => False,
1921 Subtype_Indication =>
1922 New_Occurrence_Of (Standard_Boolean, Loc)))))));
1924 Append_To (Decls, Stub_Type_Declaration);
1925 Analyze (Stub_Type_Declaration);
1927 -- This is in no way a type derivation, but we fake it to make
1928 -- sure that the dispatching table gets built with the corresponding
1929 -- primitive operations at the right place.
1931 Derive_Subprograms (Parent_Type => Designated_Type,
1932 Derived_Type => Stub_Type);
1934 Stub_Type_Access_Declaration :=
1935 Make_Full_Type_Declaration (Loc,
1936 Defining_Identifier => Stub_Type_Access,
1938 Make_Access_To_Object_Definition (Loc,
1939 Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
1941 Append_To (Decls, Stub_Type_Access_Declaration);
1942 Analyze (Stub_Type_Access_Declaration);
1944 Object_RPC_Receiver_Declaration :=
1945 Make_Subprogram_Declaration (Loc,
1946 Build_RPC_Receiver_Specification (
1947 RPC_Receiver => Object_RPC_Receiver,
1948 Stream_Parameter => RPC_Receiver_Stream,
1949 Result_Parameter => RPC_Receiver_Result));
1951 Append_To (Decls, Object_RPC_Receiver_Declaration);
1954 ---------------------------------
1955 -- Build_General_Calling_Stubs --
1956 ---------------------------------
1958 procedure Build_General_Calling_Stubs
1960 Statements : List_Id;
1961 Target_Partition : Entity_Id;
1962 RPC_Receiver : Node_Id;
1963 Subprogram_Id : Node_Id;
1964 Asynchronous : Node_Id := Empty;
1965 Is_Known_Asynchronous : Boolean := False;
1966 Is_Known_Non_Asynchronous : Boolean := False;
1967 Is_Function : Boolean;
1969 Object_Type : Entity_Id := Empty;
1972 Loc : constant Source_Ptr := Sloc (Nod);
1974 Stream_Parameter : Node_Id;
1975 -- Name of the stream used to transmit parameters to the remote package
1977 Result_Parameter : Node_Id;
1978 -- Name of the result parameter (in non-APC cases) which get the
1979 -- result of the remote subprogram.
1981 Exception_Return_Parameter : Node_Id;
1982 -- Name of the parameter which will hold the exception sent by the
1983 -- remote subprogram.
1985 Current_Parameter : Node_Id;
1986 -- Current parameter being handled
1988 Ordered_Parameters_List : constant List_Id :=
1989 Build_Ordered_Parameters_List (Spec);
1991 Asynchronous_Statements : List_Id := No_List;
1992 Non_Asynchronous_Statements : List_Id := No_List;
1993 -- Statements specifics to the Asynchronous/Non-Asynchronous cases.
1995 Extra_Formal_Statements : constant List_Id := New_List;
1996 -- List of statements for extra formal parameters. It will appear after
1997 -- the regular statements for writing out parameters.
2000 -- The general form of a calling stub for a given subprogram is:
2002 -- procedure X (...) is
2003 -- P : constant Partition_ID := RCI_Cache.Get_Active_Partition_ID;
2004 -- Stream, Result : aliased System.RPC.Params_Stream_Type (0);
2006 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
2007 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
2008 -- Put_Subprogram_Id_In_Stream;
2009 -- Put_Parameters_In_Stream;
2010 -- Do_RPC (Stream, Result);
2011 -- Read_Exception_Occurrence_From_Result; Raise_It;
2012 -- Read_Out_Parameters_And_Function_Return_From_Stream;
2015 -- There are some variations: Do_APC is called for an asynchronous
2016 -- procedure and the part after the call is completely ommitted
2017 -- as well as the declaration of Result. For a function call,
2018 -- 'Input is always used to read the result even if it is constrained.
2021 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2024 Make_Object_Declaration (Loc,
2025 Defining_Identifier => Stream_Parameter,
2026 Aliased_Present => True,
2027 Object_Definition =>
2028 Make_Subtype_Indication (Loc,
2030 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2032 Make_Index_Or_Discriminant_Constraint (Loc,
2034 New_List (Make_Integer_Literal (Loc, 0))))));
2036 if not Is_Known_Asynchronous then
2038 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2041 Make_Object_Declaration (Loc,
2042 Defining_Identifier => Result_Parameter,
2043 Aliased_Present => True,
2044 Object_Definition =>
2045 Make_Subtype_Indication (Loc,
2047 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2049 Make_Index_Or_Discriminant_Constraint (Loc,
2051 New_List (Make_Integer_Literal (Loc, 0))))));
2053 Exception_Return_Parameter :=
2054 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
2057 Make_Object_Declaration (Loc,
2058 Defining_Identifier => Exception_Return_Parameter,
2059 Object_Definition =>
2060 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
2063 Result_Parameter := Empty;
2064 Exception_Return_Parameter := Empty;
2067 -- Put first the RPC receiver corresponding to the remote package
2069 Append_To (Statements,
2070 Make_Attribute_Reference (Loc,
2072 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2073 Attribute_Name => Name_Write,
2074 Expressions => New_List (
2075 Make_Attribute_Reference (Loc,
2077 New_Occurrence_Of (Stream_Parameter, Loc),
2082 -- Then put the Subprogram_Id of the subprogram we want to call in
2085 Append_To (Statements,
2086 Make_Attribute_Reference (Loc,
2088 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
2091 Expressions => New_List (
2092 Make_Attribute_Reference (Loc,
2094 New_Occurrence_Of (Stream_Parameter, Loc),
2095 Attribute_Name => Name_Access),
2098 Current_Parameter := First (Ordered_Parameters_List);
2100 while Current_Parameter /= Empty loop
2103 Typ : constant Node_Id :=
2104 Parameter_Type (Current_Parameter);
2106 Constrained : Boolean;
2108 Extra_Parameter : Entity_Id;
2112 if Is_RACW_Controlling_Formal (Current_Parameter, Object_Type) then
2114 -- In the case of a controlling formal argument, we marshall
2115 -- its addr field rather than the local stub.
2117 Append_To (Statements,
2118 Pack_Node_Into_Stream (Loc,
2119 Stream => Stream_Parameter,
2121 Make_Selected_Component (Loc,
2124 Defining_Identifier (Current_Parameter), Loc),
2126 Make_Identifier (Loc, Name_Addr)),
2127 Etyp => RTE (RE_Unsigned_64)));
2130 Value := New_Occurrence_Of
2131 (Defining_Identifier (Current_Parameter), Loc);
2133 -- Access type parameters are transmitted as in out
2134 -- parameters. However, a dereference is needed so that
2135 -- we marshall the designated object.
2137 if Nkind (Typ) = N_Access_Definition then
2138 Value := Make_Explicit_Dereference (Loc, Value);
2139 Etyp := Etype (Subtype_Mark (Typ));
2141 Etyp := Etype (Typ);
2145 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
2147 -- Any parameter but unconstrained out parameters are
2148 -- transmitted to the peer.
2150 if In_Present (Current_Parameter)
2151 or else not Out_Present (Current_Parameter)
2152 or else not Constrained
2154 Append_To (Statements,
2155 Make_Attribute_Reference (Loc,
2157 New_Occurrence_Of (Etyp, Loc),
2158 Attribute_Name => Output_From_Constrained (Constrained),
2159 Expressions => New_List (
2160 Make_Attribute_Reference (Loc,
2162 New_Occurrence_Of (Stream_Parameter, Loc),
2163 Attribute_Name => Name_Access),
2168 -- If the current parameter has a dynamic constrained status,
2169 -- then this status is transmitted as well.
2170 -- This should be done for accessibility as well ???
2172 if Nkind (Typ) /= N_Access_Definition
2173 and then Need_Extra_Constrained (Current_Parameter)
2175 -- In this block, we do not use the extra formal that has been
2176 -- created because it does not exist at the time of expansion
2177 -- when building calling stubs for remote access to subprogram
2178 -- types. We create an extra variable of this type and push it
2179 -- in the stream after the regular parameters.
2181 Extra_Parameter := Make_Defining_Identifier
2182 (Loc, New_Internal_Name ('P'));
2185 Make_Object_Declaration (Loc,
2186 Defining_Identifier => Extra_Parameter,
2187 Constant_Present => True,
2188 Object_Definition =>
2189 New_Occurrence_Of (Standard_Boolean, Loc),
2191 Make_Attribute_Reference (Loc,
2194 Defining_Identifier (Current_Parameter), Loc),
2195 Attribute_Name => Name_Constrained)));
2197 Append_To (Extra_Formal_Statements,
2198 Make_Attribute_Reference (Loc,
2200 New_Occurrence_Of (Standard_Boolean, Loc),
2203 Expressions => New_List (
2204 Make_Attribute_Reference (Loc,
2206 New_Occurrence_Of (Stream_Parameter, Loc),
2209 New_Occurrence_Of (Extra_Parameter, Loc))));
2212 Next (Current_Parameter);
2216 -- Append the formal statements list to the statements
2218 Append_List_To (Statements, Extra_Formal_Statements);
2220 if not Is_Known_Non_Asynchronous then
2222 -- Build the call to System.RPC.Do_APC
2224 Asynchronous_Statements := New_List (
2225 Make_Procedure_Call_Statement (Loc,
2227 New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
2228 Parameter_Associations => New_List (
2229 New_Occurrence_Of (Target_Partition, Loc),
2230 Make_Attribute_Reference (Loc,
2232 New_Occurrence_Of (Stream_Parameter, Loc),
2236 Asynchronous_Statements := No_List;
2239 if not Is_Known_Asynchronous then
2241 -- Build the call to System.RPC.Do_RPC
2243 Non_Asynchronous_Statements := New_List (
2244 Make_Procedure_Call_Statement (Loc,
2246 New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
2247 Parameter_Associations => New_List (
2248 New_Occurrence_Of (Target_Partition, Loc),
2250 Make_Attribute_Reference (Loc,
2252 New_Occurrence_Of (Stream_Parameter, Loc),
2256 Make_Attribute_Reference (Loc,
2258 New_Occurrence_Of (Result_Parameter, Loc),
2262 -- Read the exception occurrence from the result stream and
2263 -- reraise it. It does no harm if this is a Null_Occurrence since
2264 -- this does nothing.
2266 Append_To (Non_Asynchronous_Statements,
2267 Make_Attribute_Reference (Loc,
2269 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
2274 Expressions => New_List (
2275 Make_Attribute_Reference (Loc,
2277 New_Occurrence_Of (Result_Parameter, Loc),
2280 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2282 Append_To (Non_Asynchronous_Statements,
2283 Make_Procedure_Call_Statement (Loc,
2285 New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
2286 Parameter_Associations => New_List (
2287 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2291 -- If this is a function call, then read the value and return
2292 -- it. The return value is written/read using 'Output/'Input.
2294 Append_To (Non_Asynchronous_Statements,
2295 Make_Tag_Check (Loc,
2296 Make_Return_Statement (Loc,
2298 Make_Attribute_Reference (Loc,
2301 Etype (Subtype_Mark (Spec)), Loc),
2303 Attribute_Name => Name_Input,
2305 Expressions => New_List (
2306 Make_Attribute_Reference (Loc,
2308 New_Occurrence_Of (Result_Parameter, Loc),
2309 Attribute_Name => Name_Access))))));
2312 -- Loop around parameters and assign out (or in out) parameters.
2313 -- In the case of RACW, controlling arguments cannot possibly
2314 -- have changed since they are remote, so we do not read them
2317 Current_Parameter :=
2318 First (Ordered_Parameters_List);
2320 while Current_Parameter /= Empty loop
2323 Typ : constant Node_Id :=
2324 Parameter_Type (Current_Parameter);
2328 Value := New_Occurrence_Of
2329 (Defining_Identifier (Current_Parameter), Loc);
2331 if Nkind (Typ) = N_Access_Definition then
2332 Value := Make_Explicit_Dereference (Loc, Value);
2333 Etyp := Etype (Subtype_Mark (Typ));
2335 Etyp := Etype (Typ);
2338 if (Out_Present (Current_Parameter)
2339 or else Nkind (Typ) = N_Access_Definition)
2340 and then Etyp /= Object_Type
2342 Append_To (Non_Asynchronous_Statements,
2343 Make_Attribute_Reference (Loc,
2345 New_Occurrence_Of (Etyp, Loc),
2347 Attribute_Name => Name_Read,
2349 Expressions => New_List (
2350 Make_Attribute_Reference (Loc,
2352 New_Occurrence_Of (Result_Parameter, Loc),
2359 Next (Current_Parameter);
2364 if Is_Known_Asynchronous then
2365 Append_List_To (Statements, Asynchronous_Statements);
2367 elsif Is_Known_Non_Asynchronous then
2368 Append_List_To (Statements, Non_Asynchronous_Statements);
2371 pragma Assert (Asynchronous /= Empty);
2372 Prepend_To (Asynchronous_Statements,
2373 Make_Attribute_Reference (Loc,
2374 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2375 Attribute_Name => Name_Write,
2376 Expressions => New_List (
2377 Make_Attribute_Reference (Loc,
2378 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2379 Attribute_Name => Name_Access),
2380 New_Occurrence_Of (Standard_True, Loc))));
2381 Prepend_To (Non_Asynchronous_Statements,
2382 Make_Attribute_Reference (Loc,
2383 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2384 Attribute_Name => Name_Write,
2385 Expressions => New_List (
2386 Make_Attribute_Reference (Loc,
2387 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2388 Attribute_Name => Name_Access),
2389 New_Occurrence_Of (Standard_False, Loc))));
2390 Append_To (Statements,
2391 Make_Implicit_If_Statement (Nod,
2392 Condition => Asynchronous,
2393 Then_Statements => Asynchronous_Statements,
2394 Else_Statements => Non_Asynchronous_Statements));
2396 end Build_General_Calling_Stubs;
2398 -----------------------------------
2399 -- Build_Ordered_Parameters_List --
2400 -----------------------------------
2402 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
2403 Constrained_List : List_Id;
2404 Unconstrained_List : List_Id;
2405 Current_Parameter : Node_Id;
2408 if not Present (Parameter_Specifications (Spec)) then
2412 Constrained_List := New_List;
2413 Unconstrained_List := New_List;
2415 -- Loop through the parameters and add them to the right list
2417 Current_Parameter := First (Parameter_Specifications (Spec));
2418 while Current_Parameter /= Empty loop
2420 if Nkind (Parameter_Type (Current_Parameter)) = N_Access_Definition
2422 Is_Constrained (Etype (Parameter_Type (Current_Parameter)))
2424 Is_Elementary_Type (Etype (Parameter_Type (Current_Parameter)))
2426 Append_To (Constrained_List, New_Copy (Current_Parameter));
2428 Append_To (Unconstrained_List, New_Copy (Current_Parameter));
2431 Next (Current_Parameter);
2434 -- Unconstrained parameters are returned first
2436 Append_List_To (Unconstrained_List, Constrained_List);
2438 return Unconstrained_List;
2440 end Build_Ordered_Parameters_List;
2442 ----------------------------------
2443 -- Build_Passive_Partition_Stub --
2444 ----------------------------------
2446 procedure Build_Passive_Partition_Stub (U : Node_Id) is
2450 Loc : constant Source_Ptr := Sloc (U);
2453 -- Verify that the implementation supports distribution, by accessing
2454 -- a type defined in the proper version of system.rpc
2457 Dist_OK : Entity_Id;
2458 pragma Warnings (Off, Dist_OK);
2461 Dist_OK := RTE (RE_Params_Stream_Type);
2464 -- Use body if present, spec otherwise
2466 if Nkind (U) = N_Package_Declaration then
2467 Pkg_Spec := Specification (U);
2468 L := Visible_Declarations (Pkg_Spec);
2470 Pkg_Spec := Parent (Corresponding_Spec (U));
2471 L := Declarations (U);
2475 Make_Procedure_Call_Statement (Loc,
2477 New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
2478 Parameter_Associations => New_List (
2479 Make_String_Literal (Loc, Get_Pkg_Name_String_Id (Pkg_Spec)),
2480 Make_Attribute_Reference (Loc,
2482 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
2487 end Build_Passive_Partition_Stub;
2489 --------------------------------------
2490 -- Build_RPC_Receiver_Specification --
2491 --------------------------------------
2493 function Build_RPC_Receiver_Specification
2494 (RPC_Receiver : Entity_Id;
2495 Stream_Parameter : Entity_Id;
2496 Result_Parameter : Entity_Id)
2499 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
2503 Make_Procedure_Specification (Loc,
2504 Defining_Unit_Name => RPC_Receiver,
2505 Parameter_Specifications => New_List (
2506 Make_Parameter_Specification (Loc,
2507 Defining_Identifier => Stream_Parameter,
2509 Make_Access_Definition (Loc,
2511 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
2513 Make_Parameter_Specification (Loc,
2514 Defining_Identifier => Result_Parameter,
2516 Make_Access_Definition (Loc,
2519 (RTE (RE_Params_Stream_Type), Loc)))));
2520 end Build_RPC_Receiver_Specification;
2522 ------------------------------------
2523 -- Build_Subprogram_Calling_Stubs --
2524 ------------------------------------
2526 function Build_Subprogram_Calling_Stubs
2527 (Vis_Decl : Node_Id;
2529 Asynchronous : Boolean;
2530 Dynamically_Asynchronous : Boolean := False;
2531 Stub_Type : Entity_Id := Empty;
2532 Locator : Entity_Id := Empty;
2533 New_Name : Name_Id := No_Name)
2536 Loc : constant Source_Ptr := Sloc (Vis_Decl);
2538 Target_Partition : Node_Id;
2539 -- Contains the name of the target partition
2541 Decls : constant List_Id := New_List;
2542 Statements : constant List_Id := New_List;
2544 Subp_Spec : Node_Id;
2545 -- The specification of the body
2547 Controlling_Parameter : Entity_Id := Empty;
2548 RPC_Receiver : Node_Id;
2550 Asynchronous_Expr : Node_Id := Empty;
2552 RCI_Locator : Entity_Id;
2554 Spec_To_Use : Node_Id;
2556 procedure Insert_Partition_Check (Parameter : in Node_Id);
2557 -- Check that the parameter has been elaborated on the same partition
2558 -- than the controlling parameter (E.4(19)).
2560 ----------------------------
2561 -- Insert_Partition_Check --
2562 ----------------------------
2564 procedure Insert_Partition_Check (Parameter : in Node_Id) is
2565 Parameter_Entity : constant Entity_Id :=
2566 Defining_Identifier (Parameter);
2567 Condition : Node_Id;
2569 Designated_Object : Node_Id;
2570 pragma Warnings (Off, Designated_Object);
2571 -- Is it really right that this is unreferenced ???
2574 -- The expression that will be built is of the form:
2575 -- if not (Parameter in Stub_Type and then
2576 -- Parameter.Origin = Controlling.Origin)
2578 -- raise Constraint_Error;
2581 -- Condition contains the reversed condition. Also, Parameter is
2582 -- dereferenced if it is an access type. We do not check that
2583 -- Parameter is in Stub_Type since such a check has been inserted
2584 -- at the point of call already (a tag check since we have multiple
2585 -- controlling operands).
2587 if Nkind (Parameter_Type (Parameter)) = N_Access_Definition then
2588 Designated_Object :=
2589 Make_Explicit_Dereference (Loc,
2590 Prefix => New_Occurrence_Of (Parameter_Entity, Loc));
2592 Designated_Object := New_Occurrence_Of (Parameter_Entity, Loc);
2598 Make_Selected_Component (Loc,
2600 New_Occurrence_Of (Parameter_Entity, Loc),
2602 Make_Identifier (Loc, Name_Origin)),
2605 Make_Selected_Component (Loc,
2607 New_Occurrence_Of (Controlling_Parameter, Loc),
2609 Make_Identifier (Loc, Name_Origin)));
2612 Make_Raise_Constraint_Error (Loc,
2614 Make_Op_Not (Loc, Right_Opnd => Condition),
2615 Reason => CE_Partition_Check_Failed));
2616 end Insert_Partition_Check;
2618 -- Start of processing for Build_Subprogram_Calling_Stubs
2622 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2624 Subp_Spec := Copy_Specification (Loc,
2625 Spec => Specification (Vis_Decl),
2626 New_Name => New_Name);
2628 if Locator = Empty then
2629 RCI_Locator := RCI_Cache;
2630 Spec_To_Use := Specification (Vis_Decl);
2632 RCI_Locator := Locator;
2633 Spec_To_Use := Subp_Spec;
2636 -- Find a controlling argument if we have a stub type. Also check
2637 -- if this subprogram can be made asynchronous.
2639 if Stub_Type /= Empty
2640 and then Present (Parameter_Specifications (Spec_To_Use))
2643 Current_Parameter : Node_Id :=
2644 First (Parameter_Specifications
2647 while Current_Parameter /= Empty loop
2650 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2652 if Controlling_Parameter = Empty then
2653 Controlling_Parameter :=
2654 Defining_Identifier (Current_Parameter);
2656 Insert_Partition_Check (Current_Parameter);
2660 Next (Current_Parameter);
2665 if Stub_Type /= Empty then
2666 pragma Assert (Controlling_Parameter /= Empty);
2669 Make_Object_Declaration (Loc,
2670 Defining_Identifier => Target_Partition,
2671 Constant_Present => True,
2672 Object_Definition =>
2673 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
2676 Make_Selected_Component (Loc,
2678 New_Occurrence_Of (Controlling_Parameter, Loc),
2680 Make_Identifier (Loc, Name_Origin))));
2683 Make_Selected_Component (Loc,
2685 New_Occurrence_Of (Controlling_Parameter, Loc),
2687 Make_Identifier (Loc, Name_Receiver));
2691 Make_Object_Declaration (Loc,
2692 Defining_Identifier => Target_Partition,
2693 Constant_Present => True,
2694 Object_Definition =>
2695 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
2698 Make_Function_Call (Loc,
2699 Name => Make_Selected_Component (Loc,
2701 Make_Identifier (Loc, Chars (RCI_Locator)),
2703 Make_Identifier (Loc, Name_Get_Active_Partition_ID)))));
2706 Make_Selected_Component (Loc,
2708 Make_Identifier (Loc, Chars (RCI_Locator)),
2710 Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
2713 if Dynamically_Asynchronous then
2714 Asynchronous_Expr :=
2715 Make_Selected_Component (Loc,
2717 New_Occurrence_Of (Controlling_Parameter, Loc),
2719 Make_Identifier (Loc, Name_Asynchronous));
2722 Build_General_Calling_Stubs
2724 Statements => Statements,
2725 Target_Partition => Target_Partition,
2726 RPC_Receiver => RPC_Receiver,
2727 Subprogram_Id => Make_Integer_Literal (Loc, Subp_Id),
2728 Asynchronous => Asynchronous_Expr,
2729 Is_Known_Asynchronous => Asynchronous
2730 and then not Dynamically_Asynchronous,
2731 Is_Known_Non_Asynchronous
2733 and then not Dynamically_Asynchronous,
2734 Is_Function => Nkind (Spec_To_Use) =
2735 N_Function_Specification,
2736 Spec => Spec_To_Use,
2737 Object_Type => Stub_Type,
2740 RCI_Calling_Stubs_Table.Set
2741 (Defining_Unit_Name (Specification (Vis_Decl)),
2742 Defining_Unit_Name (Spec_To_Use));
2745 Make_Subprogram_Body (Loc,
2746 Specification => Subp_Spec,
2747 Declarations => Decls,
2748 Handled_Statement_Sequence =>
2749 Make_Handled_Sequence_Of_Statements (Loc, Statements));
2750 end Build_Subprogram_Calling_Stubs;
2752 --------------------------------------
2753 -- Build_Subprogram_Receiving_Stubs --
2754 --------------------------------------
2756 function Build_Subprogram_Receiving_Stubs
2757 (Vis_Decl : Node_Id;
2758 Asynchronous : Boolean;
2759 Dynamically_Asynchronous : Boolean := False;
2760 Stub_Type : Entity_Id := Empty;
2761 RACW_Type : Entity_Id := Empty;
2762 Parent_Primitive : Entity_Id := Empty)
2765 Loc : constant Source_Ptr := Sloc (Vis_Decl);
2767 Stream_Parameter : Node_Id;
2768 Result_Parameter : Node_Id;
2769 -- See explanations of those in Build_Subprogram_Calling_Stubs
2771 Decls : constant List_Id := New_List;
2772 -- All the parameters will get declared before calling the real
2773 -- subprograms. Also the out parameters will be declared.
2775 Statements : constant List_Id := New_List;
2777 Extra_Formal_Statements : constant List_Id := New_List;
2778 -- Statements concerning extra formal parameters
2780 After_Statements : constant List_Id := New_List;
2781 -- Statements to be executed after the subprogram call
2783 Inner_Decls : List_Id := No_List;
2784 -- In case of a function, the inner declarations are needed since
2785 -- the result may be unconstrained.
2787 Excep_Handler : Node_Id;
2788 Excep_Choice : Entity_Id;
2789 Excep_Code : List_Id;
2791 Parameter_List : constant List_Id := New_List;
2792 -- List of parameters to be passed to the subprogram.
2794 Current_Parameter : Node_Id;
2796 Ordered_Parameters_List : constant List_Id :=
2797 Build_Ordered_Parameters_List
2798 (Specification (Vis_Decl));
2800 Subp_Spec : Node_Id;
2801 -- Subprogram specification
2803 Called_Subprogram : Node_Id;
2804 -- The subprogram to call
2806 Null_Raise_Statement : Node_Id;
2808 Dynamic_Async : Entity_Id;
2811 if RACW_Type /= Empty then
2812 Called_Subprogram :=
2813 New_Occurrence_Of (Parent_Primitive, Loc);
2815 Called_Subprogram :=
2817 Defining_Unit_Name (Specification (Vis_Decl)), Loc);
2821 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2823 if Dynamically_Asynchronous then
2825 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2827 Dynamic_Async := Empty;
2830 if not Asynchronous or else Dynamically_Asynchronous then
2832 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2834 -- The first statement after the subprogram call is a statement to
2835 -- writes a Null_Occurrence into the result stream.
2837 Null_Raise_Statement :=
2838 Make_Attribute_Reference (Loc,
2840 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
2841 Attribute_Name => Name_Write,
2842 Expressions => New_List (
2843 New_Occurrence_Of (Result_Parameter, Loc),
2844 New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
2846 if Dynamically_Asynchronous then
2847 Null_Raise_Statement :=
2848 Make_Implicit_If_Statement (Vis_Decl,
2850 Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
2851 Then_Statements => New_List (Null_Raise_Statement));
2854 Append_To (After_Statements, Null_Raise_Statement);
2857 Result_Parameter := Empty;
2860 -- Loop through every parameter and get its value from the stream. If
2861 -- the parameter is unconstrained, then the parameter is read using
2862 -- 'Input at the point of declaration.
2864 Current_Parameter := First (Ordered_Parameters_List);
2866 while Current_Parameter /= Empty loop
2870 Constrained : Boolean;
2872 Expr : Node_Id := Empty;
2875 Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2876 Set_Ekind (Object, E_Variable);
2879 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2881 -- We have a controlling formal parameter. Read its address
2882 -- rather than a real object. The address is in Unsigned_64
2885 Etyp := RTE (RE_Unsigned_64);
2887 Etyp := Etype (Parameter_Type (Current_Parameter));
2891 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
2893 if In_Present (Current_Parameter)
2894 or else not Out_Present (Current_Parameter)
2895 or else not Constrained
2897 -- If an input parameter is contrained, then its reading is
2898 -- deferred until the beginning of the subprogram body. If
2899 -- it is unconstrained, then an expression is built for
2900 -- the object declaration and the variable is set using
2901 -- 'Input instead of 'Read.
2904 Append_To (Statements,
2905 Make_Attribute_Reference (Loc,
2906 Prefix => New_Occurrence_Of (Etyp, Loc),
2907 Attribute_Name => Name_Read,
2908 Expressions => New_List (
2909 New_Occurrence_Of (Stream_Parameter, Loc),
2910 New_Occurrence_Of (Object, Loc))));
2913 Expr := Input_With_Tag_Check (Loc,
2915 Stream => Stream_Parameter);
2916 Append_To (Decls, Expr);
2917 Expr := Make_Function_Call (Loc,
2918 New_Occurrence_Of (Defining_Unit_Name
2919 (Specification (Expr)), Loc));
2923 -- If we do not have to output the current parameter, then
2924 -- it can well be flagged as constant. This may allow further
2925 -- optimizations done by the back end.
2928 Make_Object_Declaration (Loc,
2929 Defining_Identifier => Object,
2931 not Constrained and then not Out_Present (Current_Parameter),
2932 Object_Definition =>
2933 New_Occurrence_Of (Etyp, Loc),
2934 Expression => Expr));
2936 -- An out parameter may be written back using a 'Write
2937 -- attribute instead of a 'Output because it has been
2938 -- constrained by the parameter given to the caller. Note that
2939 -- out controlling arguments in the case of a RACW are not put
2940 -- back in the stream because the pointer on them has not
2943 if Out_Present (Current_Parameter)
2945 Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
2947 Append_To (After_Statements,
2948 Make_Attribute_Reference (Loc,
2949 Prefix => New_Occurrence_Of (Etyp, Loc),
2950 Attribute_Name => Name_Write,
2951 Expressions => New_List (
2952 New_Occurrence_Of (Result_Parameter, Loc),
2953 New_Occurrence_Of (Object, Loc))));
2957 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2960 if Nkind (Parameter_Type (Current_Parameter)) /=
2963 Append_To (Parameter_List,
2964 Make_Parameter_Association (Loc,
2967 Defining_Identifier (Current_Parameter), Loc),
2968 Explicit_Actual_Parameter =>
2969 Make_Explicit_Dereference (Loc,
2970 Unchecked_Convert_To (RACW_Type,
2971 OK_Convert_To (RTE (RE_Address),
2972 New_Occurrence_Of (Object, Loc))))));
2974 Append_To (Parameter_List,
2975 Make_Parameter_Association (Loc,
2978 Defining_Identifier (Current_Parameter), Loc),
2979 Explicit_Actual_Parameter =>
2980 Unchecked_Convert_To (RACW_Type,
2981 OK_Convert_To (RTE (RE_Address),
2982 New_Occurrence_Of (Object, Loc)))));
2985 Append_To (Parameter_List,
2986 Make_Parameter_Association (Loc,
2989 Defining_Identifier (Current_Parameter), Loc),
2990 Explicit_Actual_Parameter =>
2991 New_Occurrence_Of (Object, Loc)));
2994 -- If the current parameter needs an extra formal, then read it
2995 -- from the stream and set the corresponding semantic field in
2996 -- the variable. If the kind of the parameter identifier is
2997 -- E_Void, then this is a compiler generated parameter that
2998 -- doesn't need an extra constrained status.
3000 -- The case of Extra_Accessibility should also be handled ???
3002 if Nkind (Parameter_Type (Current_Parameter)) /=
3005 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
3007 Present (Extra_Constrained
3008 (Defining_Identifier (Current_Parameter)))
3011 Extra_Parameter : constant Entity_Id :=
3013 (Defining_Identifier
3014 (Current_Parameter));
3016 Formal_Entity : constant Entity_Id :=
3017 Make_Defining_Identifier
3018 (Loc, Chars (Extra_Parameter));
3020 Formal_Type : constant Entity_Id :=
3021 Etype (Extra_Parameter);
3025 Make_Object_Declaration (Loc,
3026 Defining_Identifier => Formal_Entity,
3027 Object_Definition =>
3028 New_Occurrence_Of (Formal_Type, Loc)));
3030 Append_To (Extra_Formal_Statements,
3031 Make_Attribute_Reference (Loc,
3032 Prefix => New_Occurrence_Of (Formal_Type, Loc),
3033 Attribute_Name => Name_Read,
3034 Expressions => New_List (
3035 New_Occurrence_Of (Stream_Parameter, Loc),
3036 New_Occurrence_Of (Formal_Entity, Loc))));
3037 Set_Extra_Constrained (Object, Formal_Entity);
3042 Next (Current_Parameter);
3045 -- Append the formal statements list at the end of regular statements
3047 Append_List_To (Statements, Extra_Formal_Statements);
3049 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
3051 -- The remote subprogram is a function. We build an inner block to
3052 -- be able to hold a potentially unconstrained result in a variable.
3055 Etyp : constant Entity_Id :=
3056 Etype (Subtype_Mark (Specification (Vis_Decl)));
3057 Result : constant Node_Id :=
3058 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3061 Inner_Decls := New_List (
3062 Make_Object_Declaration (Loc,
3063 Defining_Identifier => Result,
3064 Constant_Present => True,
3065 Object_Definition => New_Occurrence_Of (Etyp, Loc),
3067 Make_Function_Call (Loc,
3068 Name => Called_Subprogram,
3069 Parameter_Associations => Parameter_List)));
3071 Append_To (After_Statements,
3072 Make_Attribute_Reference (Loc,
3073 Prefix => New_Occurrence_Of (Etyp, Loc),
3074 Attribute_Name => Name_Output,
3075 Expressions => New_List (
3076 New_Occurrence_Of (Result_Parameter, Loc),
3077 New_Occurrence_Of (Result, Loc))));
3080 Append_To (Statements,
3081 Make_Block_Statement (Loc,
3082 Declarations => Inner_Decls,
3083 Handled_Statement_Sequence =>
3084 Make_Handled_Sequence_Of_Statements (Loc,
3085 Statements => After_Statements)));
3088 -- The remote subprogram is a procedure. We do not need any inner
3089 -- block in this case.
3091 if Dynamically_Asynchronous then
3093 Make_Object_Declaration (Loc,
3094 Defining_Identifier => Dynamic_Async,
3095 Object_Definition =>
3096 New_Occurrence_Of (Standard_Boolean, Loc)));
3098 Append_To (Statements,
3099 Make_Attribute_Reference (Loc,
3100 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
3101 Attribute_Name => Name_Read,
3102 Expressions => New_List (
3103 New_Occurrence_Of (Stream_Parameter, Loc),
3104 New_Occurrence_Of (Dynamic_Async, Loc))));
3107 Append_To (Statements,
3108 Make_Procedure_Call_Statement (Loc,
3109 Name => Called_Subprogram,
3110 Parameter_Associations => Parameter_List));
3112 Append_List_To (Statements, After_Statements);
3116 if Asynchronous and then not Dynamically_Asynchronous then
3118 -- An asynchronous procedure does not want a Result
3119 -- parameter. Also, we put an exception handler with an others
3120 -- clause that does nothing.
3123 Make_Procedure_Specification (Loc,
3124 Defining_Unit_Name =>
3125 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3126 Parameter_Specifications => New_List (
3127 Make_Parameter_Specification (Loc,
3128 Defining_Identifier => Stream_Parameter,
3130 Make_Access_Definition (Loc,
3132 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3135 Make_Exception_Handler (Loc,
3136 Exception_Choices =>
3137 New_List (Make_Others_Choice (Loc)),
3138 Statements => New_List (
3139 Make_Null_Statement (Loc)));
3142 -- In the other cases, if an exception is raised, then the
3143 -- exception occurrence is copied into the output stream and
3144 -- no other output parameter is written.
3147 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3149 Excep_Code := New_List (
3150 Make_Attribute_Reference (Loc,
3152 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3153 Attribute_Name => Name_Write,
3154 Expressions => New_List (
3155 New_Occurrence_Of (Result_Parameter, Loc),
3156 New_Occurrence_Of (Excep_Choice, Loc))));
3158 if Dynamically_Asynchronous then
3159 Excep_Code := New_List (
3160 Make_Implicit_If_Statement (Vis_Decl,
3161 Condition => Make_Op_Not (Loc,
3162 New_Occurrence_Of (Dynamic_Async, Loc)),
3163 Then_Statements => Excep_Code));
3167 Make_Exception_Handler (Loc,
3168 Choice_Parameter => Excep_Choice,
3169 Exception_Choices => New_List (Make_Others_Choice (Loc)),
3170 Statements => Excep_Code);
3173 Make_Procedure_Specification (Loc,
3174 Defining_Unit_Name =>
3175 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3177 Parameter_Specifications => New_List (
3178 Make_Parameter_Specification (Loc,
3179 Defining_Identifier => Stream_Parameter,
3181 Make_Access_Definition (Loc,
3183 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
3185 Make_Parameter_Specification (Loc,
3186 Defining_Identifier => Result_Parameter,
3188 Make_Access_Definition (Loc,
3190 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3194 Make_Subprogram_Body (Loc,
3195 Specification => Subp_Spec,
3196 Declarations => Decls,
3197 Handled_Statement_Sequence =>
3198 Make_Handled_Sequence_Of_Statements (Loc,
3199 Statements => Statements,
3200 Exception_Handlers => New_List (Excep_Handler)));
3202 end Build_Subprogram_Receiving_Stubs;
3204 ------------------------
3205 -- Copy_Specification --
3206 ------------------------
3208 function Copy_Specification
3211 Object_Type : Entity_Id := Empty;
3212 Stub_Type : Entity_Id := Empty;
3213 New_Name : Name_Id := No_Name)
3216 Parameters : List_Id := No_List;
3218 Current_Parameter : Node_Id;
3219 Current_Type : Node_Id;
3220 Current_Etype : Entity_Id;
3222 Name_For_New_Spec : Name_Id;
3224 New_Identifier : Entity_Id;
3227 if New_Name = No_Name then
3228 Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
3230 Name_For_New_Spec := New_Name;
3233 if Present (Parameter_Specifications (Spec)) then
3235 Parameters := New_List;
3236 Current_Parameter := First (Parameter_Specifications (Spec));
3238 while Current_Parameter /= Empty loop
3240 Current_Type := Parameter_Type (Current_Parameter);
3242 if Nkind (Current_Type) = N_Access_Definition then
3243 Current_Etype := Entity (Subtype_Mark (Current_Type));
3245 if Object_Type = Empty then
3247 Make_Access_Definition (Loc,
3249 New_Occurrence_Of (Current_Etype, Loc));
3252 (Root_Type (Current_Etype) = Root_Type (Object_Type));
3254 Make_Access_Definition (Loc,
3255 Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc));
3259 Current_Etype := Entity (Current_Type);
3261 if Object_Type /= Empty
3262 and then Current_Etype = Object_Type
3264 Current_Type := New_Occurrence_Of (Stub_Type, Loc);
3266 Current_Type := New_Occurrence_Of (Current_Etype, Loc);
3270 New_Identifier := Make_Defining_Identifier (Loc,
3271 Chars (Defining_Identifier (Current_Parameter)));
3273 Append_To (Parameters,
3274 Make_Parameter_Specification (Loc,
3275 Defining_Identifier => New_Identifier,
3276 Parameter_Type => Current_Type,
3277 In_Present => In_Present (Current_Parameter),
3278 Out_Present => Out_Present (Current_Parameter),
3280 New_Copy_Tree (Expression (Current_Parameter))));
3282 Next (Current_Parameter);
3286 if Nkind (Spec) = N_Function_Specification then
3288 Make_Function_Specification (Loc,
3289 Defining_Unit_Name =>
3290 Make_Defining_Identifier (Loc,
3291 Chars => Name_For_New_Spec),
3292 Parameter_Specifications => Parameters,
3294 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
3298 Make_Procedure_Specification (Loc,
3299 Defining_Unit_Name =>
3300 Make_Defining_Identifier (Loc,
3301 Chars => Name_For_New_Spec),
3302 Parameter_Specifications => Parameters);
3305 end Copy_Specification;
3307 ---------------------------
3308 -- Could_Be_Asynchronous --
3309 ---------------------------
3311 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
3312 Current_Parameter : Node_Id;
3315 if Present (Parameter_Specifications (Spec)) then
3316 Current_Parameter := First (Parameter_Specifications (Spec));
3317 while Current_Parameter /= Empty loop
3318 if Out_Present (Current_Parameter) then
3322 Next (Current_Parameter);
3327 end Could_Be_Asynchronous;
3329 ---------------------------------------------
3330 -- Expand_All_Calls_Remote_Subprogram_Call --
3331 ---------------------------------------------
3333 procedure Expand_All_Calls_Remote_Subprogram_Call (N : in Node_Id) is
3334 Called_Subprogram : constant Entity_Id := Entity (Name (N));
3335 RCI_Package : constant Entity_Id := Scope (Called_Subprogram);
3336 Loc : constant Source_Ptr := Sloc (N);
3337 RCI_Locator : Node_Id;
3338 RCI_Cache : Entity_Id;
3339 Calling_Stubs : Node_Id;
3340 E_Calling_Stubs : Entity_Id;
3343 E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
3345 if E_Calling_Stubs = Empty then
3346 RCI_Cache := RCI_Locator_Table.Get (RCI_Package);
3348 if RCI_Cache = Empty then
3351 (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
3352 Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator);
3354 -- The RCI_Locator package is inserted at the top level in the
3355 -- current unit, and must appear in the proper scope, so that it
3356 -- is not prematurely removed by the GCC back-end.
3359 Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
3362 if Ekind (Scop) = E_Package_Body then
3363 New_Scope (Spec_Entity (Scop));
3365 elsif Ekind (Scop) = E_Subprogram_Body then
3367 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
3373 Analyze (RCI_Locator);
3377 RCI_Cache := Defining_Unit_Name (RCI_Locator);
3380 RCI_Locator := Parent (RCI_Cache);
3383 Calling_Stubs := Build_Subprogram_Calling_Stubs
3384 (Vis_Decl => Parent (Parent (Called_Subprogram)),
3385 Subp_Id => Get_Subprogram_Id (Called_Subprogram),
3386 Asynchronous => Nkind (N) = N_Procedure_Call_Statement
3388 Is_Asynchronous (Called_Subprogram),
3389 Locator => RCI_Cache,
3390 New_Name => New_Internal_Name ('S'));
3391 Insert_After (RCI_Locator, Calling_Stubs);
3392 Analyze (Calling_Stubs);
3393 E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
3396 Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
3397 end Expand_All_Calls_Remote_Subprogram_Call;
3399 ---------------------------------
3400 -- Expand_Calling_Stubs_Bodies --
3401 ---------------------------------
3403 procedure Expand_Calling_Stubs_Bodies (Unit_Node : in Node_Id) is
3404 Spec : constant Node_Id := Specification (Unit_Node);
3405 Decls : constant List_Id := Visible_Declarations (Spec);
3408 New_Scope (Scope_Of_Spec (Spec));
3409 Add_Calling_Stubs_To_Declarations (Specification (Unit_Node),
3412 end Expand_Calling_Stubs_Bodies;
3414 -----------------------------------
3415 -- Expand_Receiving_Stubs_Bodies --
3416 -----------------------------------
3418 procedure Expand_Receiving_Stubs_Bodies (Unit_Node : in Node_Id) is
3424 if Nkind (Unit_Node) = N_Package_Declaration then
3425 Spec := Specification (Unit_Node);
3426 Decls := Visible_Declarations (Spec);
3427 New_Scope (Scope_Of_Spec (Spec));
3428 Add_Receiving_Stubs_To_Declarations (Spec, Decls);
3432 Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
3433 Decls := Declarations (Unit_Node);
3434 New_Scope (Scope_Of_Spec (Unit_Node));
3436 Add_Receiving_Stubs_To_Declarations (Spec, Temp);
3437 Insert_List_Before (First (Decls), Temp);
3441 end Expand_Receiving_Stubs_Bodies;
3443 ----------------------------
3444 -- Get_Pkg_Name_string_Id --
3445 ----------------------------
3447 function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id is
3448 Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
3451 Get_Unit_Name_String (Unit_Name_Id);
3453 -- Remove seven last character (" (spec)" or " (body)").
3455 Name_Len := Name_Len - 7;
3456 pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
3458 return Get_String_Id (Name_Buffer (1 .. Name_Len));
3459 end Get_Pkg_Name_String_Id;
3465 function Get_String_Id (Val : String) return String_Id is
3468 Store_String_Chars (Val);
3476 function Hash (F : Entity_Id) return Hash_Index is
3478 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
3481 --------------------------
3482 -- Input_With_Tag_Check --
3483 --------------------------
3485 function Input_With_Tag_Check
3487 Var_Type : Entity_Id;
3493 Make_Subprogram_Body (Loc,
3494 Specification => Make_Function_Specification (Loc,
3495 Defining_Unit_Name =>
3496 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
3497 Subtype_Mark => New_Occurrence_Of (Var_Type, Loc)),
3498 Declarations => No_List,
3499 Handled_Statement_Sequence =>
3500 Make_Handled_Sequence_Of_Statements (Loc, New_List (
3501 Make_Tag_Check (Loc,
3502 Make_Return_Statement (Loc,
3503 Make_Attribute_Reference (Loc,
3504 Prefix => New_Occurrence_Of (Var_Type, Loc),
3505 Attribute_Name => Name_Input,
3507 New_List (New_Occurrence_Of (Stream, Loc))))))));
3508 end Input_With_Tag_Check;
3510 --------------------------------
3511 -- Is_RACW_Controlling_Formal --
3512 --------------------------------
3514 function Is_RACW_Controlling_Formal
3515 (Parameter : Node_Id;
3516 Stub_Type : Entity_Id)
3522 -- If the kind of the parameter is E_Void, then it is not a
3523 -- controlling formal (this can happen in the context of RAS).
3525 if Ekind (Defining_Identifier (Parameter)) = E_Void then
3529 -- If the parameter is not a controlling formal, then it cannot
3530 -- be possibly a RACW_Controlling_Formal.
3532 if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
3536 Typ := Parameter_Type (Parameter);
3537 return (Nkind (Typ) = N_Access_Definition
3538 and then Etype (Subtype_Mark (Typ)) = Stub_Type)
3539 or else Etype (Typ) = Stub_Type;
3540 end Is_RACW_Controlling_Formal;
3542 --------------------
3543 -- Make_Tag_Check --
3544 --------------------
3546 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
3547 Occ : constant Entity_Id :=
3548 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3551 return Make_Block_Statement (Loc,
3552 Handled_Statement_Sequence =>
3553 Make_Handled_Sequence_Of_Statements (Loc,
3554 Statements => New_List (N),
3556 Exception_Handlers => New_List (
3557 Make_Exception_Handler (Loc,
3558 Choice_Parameter => Occ,
3560 Exception_Choices =>
3561 New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
3564 New_List (Make_Procedure_Call_Statement (Loc,
3566 (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
3567 New_List (New_Occurrence_Of (Occ, Loc))))))));
3570 ----------------------------
3571 -- Need_Extra_Constrained --
3572 ----------------------------
3574 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
3575 Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
3578 return Out_Present (Parameter)
3579 and then Has_Discriminants (Etyp)
3580 and then not Is_Constrained (Etyp)
3581 and then not Is_Indefinite_Subtype (Etyp);
3582 end Need_Extra_Constrained;
3584 ------------------------------------
3585 -- Pack_Entity_Into_Stream_Access --
3586 ------------------------------------
3588 function Pack_Entity_Into_Stream_Access
3592 Etyp : Entity_Id := Empty)
3598 if Etyp /= Empty then
3601 Typ := Etype (Object);
3605 Pack_Node_Into_Stream_Access (Loc,
3607 Object => New_Occurrence_Of (Object, Loc),
3609 end Pack_Entity_Into_Stream_Access;
3611 ---------------------------
3612 -- Pack_Node_Into_Stream --
3613 ---------------------------
3615 function Pack_Node_Into_Stream
3622 Write_Attribute : Name_Id := Name_Write;
3625 if not Is_Constrained (Etyp) then
3626 Write_Attribute := Name_Output;
3630 Make_Attribute_Reference (Loc,
3631 Prefix => New_Occurrence_Of (Etyp, Loc),
3632 Attribute_Name => Write_Attribute,
3633 Expressions => New_List (
3634 Make_Attribute_Reference (Loc,
3635 Prefix => New_Occurrence_Of (Stream, Loc),
3636 Attribute_Name => Name_Access),
3638 end Pack_Node_Into_Stream;
3640 ----------------------------------
3641 -- Pack_Node_Into_Stream_Access --
3642 ----------------------------------
3644 function Pack_Node_Into_Stream_Access
3651 Write_Attribute : Name_Id := Name_Write;
3654 if not Is_Constrained (Etyp) then
3655 Write_Attribute := Name_Output;
3659 Make_Attribute_Reference (Loc,
3660 Prefix => New_Occurrence_Of (Etyp, Loc),
3661 Attribute_Name => Write_Attribute,
3662 Expressions => New_List (
3665 end Pack_Node_Into_Stream_Access;
3667 -------------------------------
3668 -- RACW_Type_Is_Asynchronous --
3669 -------------------------------
3671 procedure RACW_Type_Is_Asynchronous (RACW_Type : in Entity_Id) is
3672 N : constant Node_Id := Asynchronous_Flags_Table.Get (RACW_Type);
3673 pragma Assert (N /= Empty);
3676 Replace (N, New_Occurrence_Of (Standard_True, Sloc (N)));
3677 end RACW_Type_Is_Asynchronous;
3679 -------------------------
3680 -- RCI_Package_Locator --
3681 -------------------------
3683 function RCI_Package_Locator
3685 Package_Spec : Node_Id)
3688 Inst : constant Node_Id :=
3689 Make_Package_Instantiation (Loc,
3690 Defining_Unit_Name =>
3691 Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
3693 New_Occurrence_Of (RTE (RE_RCI_Info), Loc),
3694 Generic_Associations => New_List (
3695 Make_Generic_Association (Loc,
3697 Make_Identifier (Loc, Name_RCI_Name),
3698 Explicit_Generic_Actual_Parameter =>
3699 Make_String_Literal (Loc,
3700 Strval => Get_Pkg_Name_String_Id (Package_Spec)))));
3703 RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
3704 Defining_Unit_Name (Inst));
3706 end RCI_Package_Locator;
3708 -----------------------------------------------
3709 -- Remote_Types_Tagged_Full_View_Encountered --
3710 -----------------------------------------------
3712 procedure Remote_Types_Tagged_Full_View_Encountered
3713 (Full_View : in Entity_Id)
3715 Stub_Elements : constant Stub_Structure :=
3716 Stubs_Table.Get (Full_View);
3719 if Stub_Elements /= Empty_Stub_Structure then
3720 Add_RACW_Primitive_Declarations_And_Bodies
3722 Parent (Declaration_Node (Stub_Elements.Object_RPC_Receiver)),
3723 List_Containing (Declaration_Node (Full_View)));
3725 end Remote_Types_Tagged_Full_View_Encountered;
3731 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
3732 Unit_Name : Node_Id := Defining_Unit_Name (Spec);
3735 while Nkind (Unit_Name) /= N_Defining_Identifier loop
3736 Unit_Name := Defining_Identifier (Unit_Name);