1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2002 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_Tss
; use Exp_Tss
;
31 with Exp_Util
; use Exp_Util
;
32 with GNAT
.HTable
; use GNAT
.HTable
;
34 with Namet
; use Namet
;
35 with Nlists
; use Nlists
;
36 with Nmake
; use Nmake
;
38 with Rtsfind
; use Rtsfind
;
40 with Sem_Ch3
; use Sem_Ch3
;
41 with Sem_Ch8
; use Sem_Ch8
;
42 with Sem_Dist
; use Sem_Dist
;
43 with Sem_Util
; use Sem_Util
;
44 with Sinfo
; use Sinfo
;
45 with Snames
; use Snames
;
46 with Stand
; use Stand
;
47 with Stringt
; use Stringt
;
48 with Tbuild
; use Tbuild
;
49 with Uintp
; use Uintp
;
50 with Uname
; use Uname
;
52 package body Exp_Dist
is
54 -- The following model has been used to implement distributed objects:
55 -- given a designated type D and a RACW type R, then a record of the
57 -- type Stub is tagged record
58 -- [...declaration similar to s-parint.ads RACW_Stub_Type...]
60 -- is built. This type has two properties:
62 -- 1) Since it has the same structure than RACW_Stub_Type, it can be
63 -- converted to and from this type to make it suitable for
64 -- System.Partition_Interface.Get_Unique_Remote_Pointer in order
65 -- to avoid memory leaks when the same remote object arrive on the
66 -- same partition by following different pathes
68 -- 2) It also has the same dispatching table as the designated type D,
69 -- and thus can be used as an object designated by a value of type
70 -- R on any partition other than the one on which the object has
71 -- been created, since only dispatching calls will be performed and
72 -- the fields themselves will not be used. We call Derive_Subprograms
73 -- to fake half a derivation to ensure that the subprograms do have
74 -- the same dispatching table.
76 -----------------------
77 -- Local subprograms --
78 -----------------------
80 procedure Build_General_Calling_Stubs
82 Statements
: in List_Id
;
83 Target_Partition
: in Entity_Id
;
84 RPC_Receiver
: in Node_Id
;
85 Subprogram_Id
: in Node_Id
;
86 Asynchronous
: in Node_Id
:= Empty
;
87 Is_Known_Asynchronous
: in Boolean := False;
88 Is_Known_Non_Asynchronous
: in Boolean := False;
89 Is_Function
: in Boolean;
91 Object_Type
: in Entity_Id
:= Empty
;
93 -- Build calling stubs for general purpose. The parameters are:
94 -- Decls : a place to put declarations
95 -- Statements : a place to put statements
96 -- Target_Partition : a node containing the target partition that must
97 -- be a N_Defining_Identifier
98 -- RPC_Receiver : a node containing the RPC receiver
99 -- Subprogram_Id : a node containing the subprogram ID
100 -- Asynchronous : True if an APC must be made instead of an RPC.
101 -- The value needs not be supplied if one of the
102 -- Is_Known_... is True.
103 -- Is_Known_Async... : True if we know that this is asynchronous
104 -- Is_Known_Non_A... : True if we know that this is not asynchronous
105 -- Spec : a node with a Parameter_Specifications and
106 -- a Subtype_Mark if applicable
107 -- Object_Type : in case of a RACW, parameters of type access to
108 -- Object_Type will be marshalled using the
109 -- address of this object (the addr field) rather
110 -- than using the 'Write on the object itself
111 -- Nod : used to provide sloc for generated code
113 function Build_Subprogram_Calling_Stubs
116 Asynchronous
: Boolean;
117 Dynamically_Asynchronous
: Boolean := False;
118 Stub_Type
: Entity_Id
:= Empty
;
119 Locator
: Entity_Id
:= Empty
;
120 New_Name
: Name_Id
:= No_Name
)
122 -- Build the calling stub for a given subprogram with the subprogram ID
123 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
124 -- parameters of this type will be marshalled instead of the object
125 -- itself. It will then be converted into Stub_Type before performing
126 -- the real call. If Dynamically_Asynchronous is True, then it will be
127 -- computed at run time whether the call is asynchronous or not.
128 -- Otherwise, the value of the formal Asynchronous will be used.
129 -- If Locator is not Empty, it will be used instead of RCI_Cache. If
130 -- New_Name is given, then it will be used instead of the original name.
132 function Build_Subprogram_Receiving_Stubs
134 Asynchronous
: Boolean;
135 Dynamically_Asynchronous
: Boolean := False;
136 Stub_Type
: Entity_Id
:= Empty
;
137 RACW_Type
: Entity_Id
:= Empty
;
138 Parent_Primitive
: Entity_Id
:= Empty
)
140 -- Build the receiving stub for a given subprogram. The subprogram
141 -- declaration is also built by this procedure, and the value returned
142 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
143 -- found in the specification, then its address is read from the stream
144 -- instead of the object itself and converted into an access to
145 -- class-wide type before doing the real call using any of the RACW type
146 -- pointing on the designated type.
148 function Build_Ordered_Parameters_List
(Spec
: Node_Id
) return List_Id
;
149 -- Return an ordered parameter list: unconstrained parameters are put
150 -- at the beginning of the list and constrained ones are put after. If
151 -- there are no parameters, an empty list is returned.
153 procedure Add_Calling_Stubs_To_Declarations
154 (Pkg_Spec
: in Node_Id
;
156 -- Add calling stubs to the declarative part
158 procedure Add_Receiving_Stubs_To_Declarations
159 (Pkg_Spec
: in Node_Id
;
161 -- Add receiving stubs to the declarative part
163 procedure Add_RAS_Dereference_Attribute
(N
: in Node_Id
);
164 -- Add a subprogram body for RAS dereference
166 procedure Add_RAS_Access_Attribute
(N
: in Node_Id
);
167 -- Add a subprogram body for RAS Access attribute
169 function Could_Be_Asynchronous
(Spec
: Node_Id
) return Boolean;
170 -- Return True if nothing prevents the program whose specification is
171 -- given to be asynchronous (i.e. no out parameter).
173 function Get_Pkg_Name_String_Id
(Decl_Node
: Node_Id
) return String_Id
;
174 function Get_String_Id
(Val
: String) return String_Id
;
175 -- Ugly functions used to retrieve a package name. Inherited from the
176 -- old exp_dist.adb and not rewritten yet ???
178 function Pack_Entity_Into_Stream_Access
182 Etyp
: Entity_Id
:= Empty
)
184 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
185 -- then Etype (Object) will be used if present. If the type is
186 -- constrained, then 'Write will be used to output the object,
187 -- If the type is unconstrained, 'Output will be used.
189 function Pack_Node_Into_Stream
195 -- Similar to above, with an arbitrary node instead of an entity
197 function Pack_Node_Into_Stream_Access
203 -- Similar to above, with Stream instead of Stream'Access
205 function Copy_Specification
208 Object_Type
: Entity_Id
:= Empty
;
209 Stub_Type
: Entity_Id
:= Empty
;
210 New_Name
: Name_Id
:= No_Name
)
212 -- Build a specification from another one. If Object_Type is not Empty
213 -- and any access to Object_Type is found, then it is replaced by an
214 -- access to Stub_Type. If New_Name is given, then it will be used as
215 -- the name for the newly created spec.
217 function Scope_Of_Spec
(Spec
: Node_Id
) return Entity_Id
;
218 -- Return the scope represented by a given spec
220 function Need_Extra_Constrained
(Parameter
: Node_Id
) return Boolean;
221 -- Return True if the current parameter needs an extra formal to reflect
222 -- its constrained status.
224 function Is_RACW_Controlling_Formal
225 (Parameter
: Node_Id
; Stub_Type
: Entity_Id
)
227 -- Return True if the current parameter is a controlling formal argument
228 -- of type Stub_Type or access to Stub_Type.
230 type Stub_Structure
is record
231 Stub_Type
: Entity_Id
;
232 Stub_Type_Access
: Entity_Id
;
233 Object_RPC_Receiver
: Entity_Id
;
234 RPC_Receiver_Stream
: Entity_Id
;
235 RPC_Receiver_Result
: Entity_Id
;
236 RACW_Type
: Entity_Id
;
238 -- This structure is necessary because of the two phases analysis of
239 -- a RACW declaration occurring in the same Remote_Types package as the
240 -- designated type. RACW_Type is any of the RACW types pointing on this
241 -- designated type, it is used here to save an anonymous type creation
242 -- for each primitive operation.
244 Empty_Stub_Structure
: constant Stub_Structure
:=
245 (Empty
, Empty
, Empty
, Empty
, Empty
, Empty
);
247 type Hash_Index
is range 0 .. 50;
248 function Hash
(F
: Entity_Id
) return Hash_Index
;
250 package Stubs_Table
is
251 new Simple_HTable
(Header_Num
=> Hash_Index
,
252 Element
=> Stub_Structure
,
253 No_Element
=> Empty_Stub_Structure
,
257 -- Mapping between a RACW designated type and its stub type
259 package Asynchronous_Flags_Table
is
260 new Simple_HTable
(Header_Num
=> Hash_Index
,
266 -- Mapping between a RACW type and the node holding the value True if
267 -- the RACW is asynchronous and False otherwise.
269 package RCI_Locator_Table
is
270 new Simple_HTable
(Header_Num
=> Hash_Index
,
271 Element
=> Entity_Id
,
276 -- Mapping between a RCI package on which All_Calls_Remote applies and
277 -- the generic instantiation of RCI_Info for this package.
279 package RCI_Calling_Stubs_Table
is
280 new Simple_HTable
(Header_Num
=> Hash_Index
,
281 Element
=> Entity_Id
,
286 -- Mapping between a RCI subprogram and the corresponding calling stubs
288 procedure Add_Stub_Type
289 (Designated_Type
: in Entity_Id
;
290 RACW_Type
: in Entity_Id
;
292 Stub_Type
: out Entity_Id
;
293 Stub_Type_Access
: out Entity_Id
;
294 Object_RPC_Receiver
: out Entity_Id
;
295 Existing
: out Boolean);
296 -- Add the declaration of the stub type, the access to stub type and the
297 -- object RPC receiver at the end of Decls. If these already exist,
298 -- then nothing is added in the tree but the right values are returned
299 -- anyhow and Existing is set to True.
301 procedure Add_RACW_Read_Attribute
302 (RACW_Type
: in Entity_Id
;
303 Stub_Type
: in Entity_Id
;
304 Stub_Type_Access
: in Entity_Id
;
305 Declarations
: in List_Id
);
306 -- Add Read attribute in Decls for the RACW type. The Read attribute
307 -- is added right after the RACW_Type declaration while the body is
308 -- inserted after Declarations.
310 procedure Add_RACW_Write_Attribute
311 (RACW_Type
: in Entity_Id
;
312 Stub_Type
: in Entity_Id
;
313 Stub_Type_Access
: in Entity_Id
;
314 Object_RPC_Receiver
: in Entity_Id
;
315 Declarations
: in List_Id
);
316 -- Same thing for the Write attribute
318 procedure Add_RACW_Read_Write_Attributes
319 (RACW_Type
: in Entity_Id
;
320 Stub_Type
: in Entity_Id
;
321 Stub_Type_Access
: in Entity_Id
;
322 Object_RPC_Receiver
: in Entity_Id
;
323 Declarations
: in List_Id
);
324 -- Add Read and Write attributes declarations and bodies for a given
325 -- RACW type. The declarations are added just after the declaration
326 -- of the RACW type itself, while the bodies are inserted at the end
329 function RCI_Package_Locator
331 Package_Spec
: Node_Id
)
333 -- Instantiate the generic package RCI_Info in order to locate the
334 -- RCI package whose spec is given as argument.
336 function Make_Tag_Check
(Loc
: Source_Ptr
; N
: Node_Id
) return Node_Id
;
337 -- Surround a node N by a tag check, as in:
341 -- when E : Ada.Tags.Tag_Error =>
342 -- Raise_Exception (Program_Error'Identity,
343 -- Exception_Message (E));
346 function Input_With_Tag_Check
348 Var_Type
: Entity_Id
;
351 -- Return a function with the following form:
352 -- function R return Var_Type is
354 -- return Var_Type'Input (S);
356 -- when E : Ada.Tags.Tag_Error =>
357 -- Raise_Exception (Program_Error'Identity,
358 -- Exception_Message (E));
361 ------------------------------------
362 -- Local variables and structures --
363 ------------------------------------
367 Output_From_Constrained
: constant array (Boolean) of Name_Id
:=
368 (False => Name_Output
,
370 -- The attribute to choose depending on the fact that the parameter
371 -- is constrained or not. There is no such thing as Input_From_Constrained
372 -- since this require separate mechanisms ('Input is a function while
373 -- 'Read is a procedure).
375 ---------------------------------------
376 -- Add_Calling_Stubs_To_Declarations --
377 ---------------------------------------
379 procedure Add_Calling_Stubs_To_Declarations
380 (Pkg_Spec
: in Node_Id
;
383 Current_Subprogram_Number
: Int
:= 0;
384 Current_Declaration
: Node_Id
;
386 Loc
: constant Source_Ptr
:= Sloc
(Pkg_Spec
);
388 RCI_Instantiation
: Node_Id
;
390 Subp_Stubs
: Node_Id
;
393 -- The first thing added is an instantiation of the generic package
394 -- System.Partition_interface.RCI_Info with the name of the (current)
395 -- remote package. This will act as an interface with the name server
396 -- to determine the Partition_ID and the RPC_Receiver for the
397 -- receiver of this package.
399 RCI_Instantiation
:= RCI_Package_Locator
(Loc
, Pkg_Spec
);
400 RCI_Cache
:= Defining_Unit_Name
(RCI_Instantiation
);
402 Append_To
(Decls
, RCI_Instantiation
);
403 Analyze
(RCI_Instantiation
);
405 -- For each subprogram declaration visible in the spec, we do
406 -- build a body. We also increment a counter to assign a different
407 -- Subprogram_Id to each subprograms. The receiving stubs processing
408 -- do use the same mechanism and will thus assign the same Id and
409 -- do the correct dispatching.
411 Current_Declaration
:= First
(Visible_Declarations
(Pkg_Spec
));
413 while Current_Declaration
/= Empty
loop
415 if Nkind
(Current_Declaration
) = N_Subprogram_Declaration
416 and then Comes_From_Source
(Current_Declaration
)
418 pragma Assert
(Current_Subprogram_Number
=
419 Get_Subprogram_Id
(Defining_Unit_Name
(Specification
(
420 Current_Declaration
))));
423 Build_Subprogram_Calling_Stubs
(
424 Vis_Decl
=> Current_Declaration
,
425 Subp_Id
=> Current_Subprogram_Number
,
427 Nkind
(Specification
(Current_Declaration
)) =
428 N_Procedure_Specification
430 Is_Asynchronous
(Defining_Unit_Name
(Specification
431 (Current_Declaration
))));
433 Append_To
(Decls
, Subp_Stubs
);
434 Analyze
(Subp_Stubs
);
436 Current_Subprogram_Number
:= Current_Subprogram_Number
+ 1;
439 Next
(Current_Declaration
);
442 end Add_Calling_Stubs_To_Declarations
;
444 -----------------------
445 -- Add_RACW_Features --
446 -----------------------
448 procedure Add_RACW_Features
(RACW_Type
: in Entity_Id
)
450 Desig
: constant Entity_Id
:=
451 Etype
(Designated_Type
(RACW_Type
));
453 List_Containing
(Declaration_Node
(RACW_Type
));
455 Same_Scope
: constant Boolean :=
456 Scope
(Desig
) = Scope
(RACW_Type
);
458 Stub_Type
: Entity_Id
;
459 Stub_Type_Access
: Entity_Id
;
460 Object_RPC_Receiver
: Entity_Id
;
464 if not Expander_Active
then
470 -- We are declaring a RACW in the same package than its designated
471 -- type, so the list to use for late declarations must be the
472 -- private part of the package. We do know that this private part
473 -- exists since the designated type has to be a private one.
475 Decls
:= Private_Declarations
476 (Package_Specification_Of_Scope
(Current_Scope
));
478 elsif Nkind
(Parent
(Decls
)) = N_Package_Specification
479 and then Present
(Private_Declarations
(Parent
(Decls
)))
481 Decls
:= Private_Declarations
(Parent
(Decls
));
484 -- If we were unable to find the declarations, that means that the
485 -- completion of the type was missing. We can safely return and let
486 -- the error be caught by the semantic analysis.
493 (Designated_Type
=> Desig
,
494 RACW_Type
=> RACW_Type
,
496 Stub_Type
=> Stub_Type
,
497 Stub_Type_Access
=> Stub_Type_Access
,
498 Object_RPC_Receiver
=> Object_RPC_Receiver
,
499 Existing
=> Existing
);
501 Add_RACW_Read_Write_Attributes
502 (RACW_Type
=> RACW_Type
,
503 Stub_Type
=> Stub_Type
,
504 Stub_Type_Access
=> Stub_Type_Access
,
505 Object_RPC_Receiver
=> Object_RPC_Receiver
,
506 Declarations
=> Decls
);
508 if not Same_Scope
and then not Existing
then
510 -- The RACW has been declared in another scope than the designated
511 -- type and has not been handled by another RACW in the same
512 -- package as the first one, so add primitive for the stub type
515 Add_RACW_Primitive_Declarations_And_Bodies
516 (Designated_Type
=> Desig
,
518 Parent
(Declaration_Node
(Object_RPC_Receiver
)),
522 Add_Access_Type_To_Process
(E
=> Desig
, A
=> RACW_Type
);
524 end Add_RACW_Features
;
526 -------------------------------------------------
527 -- Add_RACW_Primitive_Declarations_And_Bodies --
528 -------------------------------------------------
530 procedure Add_RACW_Primitive_Declarations_And_Bodies
531 (Designated_Type
: in Entity_Id
;
532 Insertion_Node
: in Node_Id
;
535 -- Set sloc of generated declaration to be that of the
536 -- insertion node, so the declarations are recognized as
537 -- belonging to the current package.
539 Loc
: constant Source_Ptr
:= Sloc
(Insertion_Node
);
541 Stub_Elements
: constant Stub_Structure
:=
542 Stubs_Table
.Get
(Designated_Type
);
544 pragma Assert
(Stub_Elements
/= Empty_Stub_Structure
);
546 Current_Insertion_Node
: Node_Id
:= Insertion_Node
;
548 RPC_Receiver_Declarations
: List_Id
;
549 RPC_Receiver_Statements
: List_Id
;
550 RPC_Receiver_Case_Alternatives
: constant List_Id
:= New_List
;
551 RPC_Receiver_Subp_Id
: Entity_Id
;
553 Current_Primitive_Elmt
: Elmt_Id
;
554 Current_Primitive
: Entity_Id
;
555 Current_Primitive_Body
: Node_Id
;
556 Current_Primitive_Spec
: Node_Id
;
557 Current_Primitive_Decl
: Node_Id
;
558 Current_Primitive_Number
: Int
:= 0;
560 Current_Primitive_Alias
: Node_Id
;
562 Current_Receiver
: Entity_Id
;
563 Current_Receiver_Body
: Node_Id
;
565 RPC_Receiver_Decl
: Node_Id
;
567 Possibly_Asynchronous
: Boolean;
571 if not Expander_Active
then
575 -- Build callers, receivers for every primitive operations and a RPC
576 -- receiver for this type.
578 if Present
(Primitive_Operations
(Designated_Type
)) then
580 Current_Primitive_Elmt
:=
581 First_Elmt
(Primitive_Operations
(Designated_Type
));
583 while Current_Primitive_Elmt
/= No_Elmt
loop
585 Current_Primitive
:= Node
(Current_Primitive_Elmt
);
587 -- Copy the primitive of all the parents, except predefined
588 -- ones that are not remotely dispatching.
590 if Chars
(Current_Primitive
) /= Name_uSize
591 and then Chars
(Current_Primitive
) /= Name_uDeep_Finalize
593 -- The first thing to do is build an up-to-date copy of
594 -- the spec with all the formals referencing Designated_Type
595 -- transformed into formals referencing Stub_Type. Since this
596 -- primitive may have been inherited, go back the alias chain
597 -- until the real primitive has been found.
599 Current_Primitive_Alias
:= Current_Primitive
;
600 while Present
(Alias
(Current_Primitive_Alias
)) loop
602 (Current_Primitive_Alias
603 /= Alias
(Current_Primitive_Alias
));
604 Current_Primitive_Alias
:= Alias
(Current_Primitive_Alias
);
607 Current_Primitive_Spec
:=
608 Copy_Specification
(Loc
,
609 Spec
=> Parent
(Current_Primitive_Alias
),
610 Object_Type
=> Designated_Type
,
611 Stub_Type
=> Stub_Elements
.Stub_Type
);
613 Current_Primitive_Decl
:=
614 Make_Subprogram_Declaration
(Loc
,
615 Specification
=> Current_Primitive_Spec
);
617 Insert_After
(Current_Insertion_Node
, Current_Primitive_Decl
);
618 Analyze
(Current_Primitive_Decl
);
619 Current_Insertion_Node
:= Current_Primitive_Decl
;
621 Possibly_Asynchronous
:=
622 Nkind
(Current_Primitive_Spec
) = N_Procedure_Specification
623 and then Could_Be_Asynchronous
(Current_Primitive_Spec
);
625 Current_Primitive_Body
:=
626 Build_Subprogram_Calling_Stubs
627 (Vis_Decl
=> Current_Primitive_Decl
,
628 Subp_Id
=> Current_Primitive_Number
,
629 Asynchronous
=> Possibly_Asynchronous
,
630 Dynamically_Asynchronous
=> Possibly_Asynchronous
,
631 Stub_Type
=> Stub_Elements
.Stub_Type
);
632 Append_To
(Decls
, Current_Primitive_Body
);
634 -- Analyzing the body here would cause the Stub type to be
635 -- frozen, thus preventing subsequent primitive declarations.
636 -- For this reason, it will be analyzed later in the
639 -- Build the receiver stubs
641 Current_Receiver_Body
:=
642 Build_Subprogram_Receiving_Stubs
643 (Vis_Decl
=> Current_Primitive_Decl
,
644 Asynchronous
=> Possibly_Asynchronous
,
645 Dynamically_Asynchronous
=> Possibly_Asynchronous
,
646 Stub_Type
=> Stub_Elements
.Stub_Type
,
647 RACW_Type
=> Stub_Elements
.RACW_Type
,
648 Parent_Primitive
=> Current_Primitive
);
651 Defining_Unit_Name
(Specification
(Current_Receiver_Body
));
653 Append_To
(Decls
, Current_Receiver_Body
);
655 -- Add a case alternative to the receiver
657 Append_To
(RPC_Receiver_Case_Alternatives
,
658 Make_Case_Statement_Alternative
(Loc
,
659 Discrete_Choices
=> New_List
(
660 Make_Integer_Literal
(Loc
, Current_Primitive_Number
)),
662 Statements
=> New_List
(
663 Make_Procedure_Call_Statement
(Loc
,
665 New_Occurrence_Of
(Current_Receiver
, Loc
),
666 Parameter_Associations
=> New_List
(
668 (Stub_Elements
.RPC_Receiver_Stream
, Loc
),
670 (Stub_Elements
.RPC_Receiver_Result
, Loc
))))));
672 -- Increment the index of current primitive
674 Current_Primitive_Number
:= Current_Primitive_Number
+ 1;
677 Next_Elmt
(Current_Primitive_Elmt
);
681 -- Build the case statement and the heart of the subprogram
683 Append_To
(RPC_Receiver_Case_Alternatives
,
684 Make_Case_Statement_Alternative
(Loc
,
685 Discrete_Choices
=> New_List
(Make_Others_Choice
(Loc
)),
686 Statements
=> New_List
(Make_Null_Statement
(Loc
))));
688 RPC_Receiver_Subp_Id
:=
689 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
691 RPC_Receiver_Declarations
:= New_List
(
692 Make_Object_Declaration
(Loc
,
693 Defining_Identifier
=> RPC_Receiver_Subp_Id
,
695 New_Occurrence_Of
(RTE
(RE_Subprogram_Id
), Loc
)));
697 RPC_Receiver_Statements
:= New_List
(
698 Make_Attribute_Reference
(Loc
,
700 New_Occurrence_Of
(RTE
(RE_Subprogram_Id
), Loc
),
703 Expressions
=> New_List
(
704 New_Occurrence_Of
(Stub_Elements
.RPC_Receiver_Stream
, Loc
),
705 New_Occurrence_Of
(RPC_Receiver_Subp_Id
, Loc
))));
707 Append_To
(RPC_Receiver_Statements
,
708 Make_Case_Statement
(Loc
,
710 New_Occurrence_Of
(RPC_Receiver_Subp_Id
, Loc
),
711 Alternatives
=> RPC_Receiver_Case_Alternatives
));
714 Make_Subprogram_Body
(Loc
,
716 Copy_Specification
(Loc
,
717 Parent
(Stub_Elements
.Object_RPC_Receiver
)),
718 Declarations
=> RPC_Receiver_Declarations
,
719 Handled_Statement_Sequence
=>
720 Make_Handled_Sequence_Of_Statements
(Loc
,
721 Statements
=> RPC_Receiver_Statements
));
723 Append_To
(Decls
, RPC_Receiver_Decl
);
725 -- Do not analyze RPC receiver at this stage since it will otherwise
726 -- reference subprograms that have not been analyzed yet. It will
727 -- be analyzed in the regular flow.
729 end Add_RACW_Primitive_Declarations_And_Bodies
;
731 -----------------------------
732 -- Add_RACW_Read_Attribute --
733 -----------------------------
735 procedure Add_RACW_Read_Attribute
736 (RACW_Type
: in Entity_Id
;
737 Stub_Type
: in Entity_Id
;
738 Stub_Type_Access
: in Entity_Id
;
739 Declarations
: in List_Id
)
741 Loc
: constant Source_Ptr
:= Sloc
(RACW_Type
);
744 -- Specification and body of the currently built procedure
746 Proc_Body_Spec
: Node_Id
;
754 Statements
: List_Id
;
755 Local_Statements
: List_Id
;
756 Remote_Statements
: List_Id
;
757 -- Various parts of the procedure
759 Procedure_Name
: constant Name_Id
:=
760 New_Internal_Name
('R');
761 Source_Partition
: constant Entity_Id
:=
762 Make_Defining_Identifier
763 (Loc
, New_Internal_Name
('P'));
764 Source_Receiver
: constant Entity_Id
:=
765 Make_Defining_Identifier
766 (Loc
, New_Internal_Name
('S'));
767 Source_Address
: constant Entity_Id
:=
768 Make_Defining_Identifier
769 (Loc
, New_Internal_Name
('P'));
770 Stream_Parameter
: constant Entity_Id
:=
771 Make_Defining_Identifier
772 (Loc
, New_Internal_Name
('S'));
773 Result
: 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
);
786 -- Declare the asynchronous flag. This flag will be changed to True
787 -- whenever it is known that the RACW type is asynchronous. Also, the
788 -- node gets stored since it may be rewritten when we process the
789 -- asynchronous pragma.
791 Append_To
(Declarations
,
792 Make_Object_Declaration
(Loc
,
793 Defining_Identifier
=> Asynchronous_Flag
,
794 Constant_Present
=> True,
795 Object_Definition
=> New_Occurrence_Of
(Standard_Boolean
, Loc
),
796 Expression
=> Asynchronous_Node
));
798 Asynchronous_Flags_Table
.Set
(RACW_Type
, Asynchronous_Node
);
800 -- Object declarations
803 Make_Object_Declaration
(Loc
,
804 Defining_Identifier
=> Source_Partition
,
806 New_Occurrence_Of
(RTE
(RE_Partition_ID
), Loc
)),
808 Make_Object_Declaration
(Loc
,
809 Defining_Identifier
=> Source_Receiver
,
811 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
)),
813 Make_Object_Declaration
(Loc
,
814 Defining_Identifier
=> Source_Address
,
816 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
)),
818 Make_Object_Declaration
(Loc
,
819 Defining_Identifier
=> Stubbed_Result
,
821 New_Occurrence_Of
(Stub_Type_Access
, Loc
)));
823 -- Read the source Partition_ID and RPC_Receiver from incoming stream
825 Statements
:= New_List
(
826 Make_Attribute_Reference
(Loc
,
828 New_Occurrence_Of
(RTE
(RE_Partition_ID
), Loc
),
829 Attribute_Name
=> Name_Read
,
830 Expressions
=> New_List
(
831 New_Occurrence_Of
(Stream_Parameter
, Loc
),
832 New_Occurrence_Of
(Source_Partition
, Loc
))),
834 Make_Attribute_Reference
(Loc
,
836 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
),
839 Expressions
=> New_List
(
840 New_Occurrence_Of
(Stream_Parameter
, Loc
),
841 New_Occurrence_Of
(Source_Receiver
, Loc
))),
843 Make_Attribute_Reference
(Loc
,
845 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
),
848 Expressions
=> New_List
(
849 New_Occurrence_Of
(Stream_Parameter
, Loc
),
850 New_Occurrence_Of
(Source_Address
, Loc
))));
852 -- If the Address is Null_Address, then return a null object
854 Append_To
(Statements
,
855 Make_Implicit_If_Statement
(RACW_Type
,
858 Left_Opnd
=> New_Occurrence_Of
(Source_Address
, Loc
),
859 Right_Opnd
=> Make_Integer_Literal
(Loc
, Uint_0
)),
860 Then_Statements
=> New_List
(
861 Make_Assignment_Statement
(Loc
,
862 Name
=> New_Occurrence_Of
(Result
, Loc
),
863 Expression
=> Make_Null
(Loc
)),
864 Make_Return_Statement
(Loc
))));
866 -- If the RACW denotes an object created on the current partition, then
867 -- Local_Statements will be executed. The real object will be used.
869 Local_Statements
:= New_List
(
870 Make_Assignment_Statement
(Loc
,
871 Name
=> New_Occurrence_Of
(Result
, Loc
),
873 Unchecked_Convert_To
(RACW_Type
,
874 OK_Convert_To
(RTE
(RE_Address
),
875 New_Occurrence_Of
(Source_Address
, Loc
)))));
877 -- If the object is located on another partition, then a stub object
878 -- will be created with all the information needed to rebuild the
879 -- real object at the other end.
881 Remote_Statements
:= New_List
(
883 Make_Assignment_Statement
(Loc
,
884 Name
=> New_Occurrence_Of
(Stubbed_Result
, Loc
),
887 New_Occurrence_Of
(Stub_Type
, Loc
))),
889 Make_Assignment_Statement
(Loc
,
890 Name
=> Make_Selected_Component
(Loc
,
891 Prefix
=> New_Occurrence_Of
(Stubbed_Result
, Loc
),
892 Selector_Name
=> Make_Identifier
(Loc
, Name_Origin
)),
894 New_Occurrence_Of
(Source_Partition
, Loc
)),
896 Make_Assignment_Statement
(Loc
,
897 Name
=> Make_Selected_Component
(Loc
,
898 Prefix
=> New_Occurrence_Of
(Stubbed_Result
, Loc
),
899 Selector_Name
=> Make_Identifier
(Loc
, Name_Receiver
)),
901 New_Occurrence_Of
(Source_Receiver
, Loc
)),
903 Make_Assignment_Statement
(Loc
,
904 Name
=> Make_Selected_Component
(Loc
,
905 Prefix
=> New_Occurrence_Of
(Stubbed_Result
, Loc
),
906 Selector_Name
=> Make_Identifier
(Loc
, Name_Addr
)),
908 New_Occurrence_Of
(Source_Address
, Loc
)));
910 Append_To
(Remote_Statements
,
911 Make_Assignment_Statement
(Loc
,
912 Name
=> Make_Selected_Component
(Loc
,
913 Prefix
=> New_Occurrence_Of
(Stubbed_Result
, Loc
),
914 Selector_Name
=> Make_Identifier
(Loc
, Name_Asynchronous
)),
916 New_Occurrence_Of
(Asynchronous_Flag
, Loc
)));
918 Append_To
(Remote_Statements
,
919 Make_Procedure_Call_Statement
(Loc
,
921 New_Occurrence_Of
(RTE
(RE_Get_Unique_Remote_Pointer
), Loc
),
922 Parameter_Associations
=> New_List
(
923 Unchecked_Convert_To
(RTE
(RE_RACW_Stub_Type_Access
),
924 New_Occurrence_Of
(Stubbed_Result
, Loc
)))));
926 Append_To
(Remote_Statements
,
927 Make_Assignment_Statement
(Loc
,
928 Name
=> New_Occurrence_Of
(Result
, Loc
),
929 Expression
=> Unchecked_Convert_To
(RACW_Type
,
930 New_Occurrence_Of
(Stubbed_Result
, Loc
))));
932 -- Distinguish between the local and remote cases, and execute the
933 -- appropriate piece of code.
935 Append_To
(Statements
,
936 Make_Implicit_If_Statement
(RACW_Type
,
940 Make_Function_Call
(Loc
,
942 New_Occurrence_Of
(RTE
(RE_Get_Local_Partition_Id
), Loc
)),
943 Right_Opnd
=> New_Occurrence_Of
(Source_Partition
, Loc
)),
944 Then_Statements
=> Local_Statements
,
945 Else_Statements
=> Remote_Statements
));
948 Make_Procedure_Specification
(Loc
,
949 Defining_Unit_Name
=>
950 Make_Defining_Identifier
(Loc
, Procedure_Name
),
952 Parameter_Specifications
=> New_List
(
953 Make_Parameter_Specification
(Loc
,
954 Defining_Identifier
=> Stream_Parameter
,
956 Make_Access_Definition
(Loc
,
958 Make_Attribute_Reference
(Loc
,
960 New_Occurrence_Of
(RTE
(RE_Root_Stream_Type
), Loc
),
964 Make_Parameter_Specification
(Loc
,
965 Defining_Identifier
=> Result
,
968 New_Occurrence_Of
(RACW_Type
, Loc
))));
971 Make_Procedure_Specification
(Loc
,
972 Defining_Unit_Name
=>
973 Make_Defining_Identifier
(Loc
, Procedure_Name
),
975 Parameter_Specifications
=> New_List
(
976 Make_Parameter_Specification
(Loc
,
977 Defining_Identifier
=>
978 Make_Defining_Identifier
(Loc
, Chars
(Stream_Parameter
)),
980 Make_Access_Definition
(Loc
,
982 Make_Attribute_Reference
(Loc
,
984 New_Occurrence_Of
(RTE
(RE_Root_Stream_Type
), Loc
),
988 Make_Parameter_Specification
(Loc
,
989 Defining_Identifier
=>
990 Make_Defining_Identifier
(Loc
, Chars
(Result
)),
993 New_Occurrence_Of
(RACW_Type
, Loc
))));
996 Make_Subprogram_Body
(Loc
,
997 Specification
=> Proc_Body_Spec
,
998 Declarations
=> Decls
,
999 Handled_Statement_Sequence
=>
1000 Make_Handled_Sequence_Of_Statements
(Loc
,
1001 Statements
=> Statements
));
1004 Make_Subprogram_Declaration
(Loc
, Specification
=> Proc_Spec
);
1007 Make_Attribute_Definition_Clause
(Loc
,
1008 Name
=> New_Occurrence_Of
(RACW_Type
, Loc
),
1011 New_Occurrence_Of
(Defining_Unit_Name
(Proc_Spec
), Loc
));
1013 Insert_After
(Declaration_Node
(RACW_Type
), Proc_Decl
);
1014 Insert_After
(Proc_Decl
, Attr_Decl
);
1015 Append_To
(Declarations
, Body_Node
);
1016 end Add_RACW_Read_Attribute
;
1018 ------------------------------------
1019 -- Add_RACW_Read_Write_Attributes --
1020 ------------------------------------
1022 procedure Add_RACW_Read_Write_Attributes
1023 (RACW_Type
: in Entity_Id
;
1024 Stub_Type
: in Entity_Id
;
1025 Stub_Type_Access
: in Entity_Id
;
1026 Object_RPC_Receiver
: in Entity_Id
;
1027 Declarations
: in List_Id
)
1030 Add_RACW_Write_Attribute
1031 (RACW_Type
=> RACW_Type
,
1032 Stub_Type
=> Stub_Type
,
1033 Stub_Type_Access
=> Stub_Type_Access
,
1034 Object_RPC_Receiver
=> Object_RPC_Receiver
,
1035 Declarations
=> Declarations
);
1037 Add_RACW_Read_Attribute
1038 (RACW_Type
=> RACW_Type
,
1039 Stub_Type
=> Stub_Type
,
1040 Stub_Type_Access
=> Stub_Type_Access
,
1041 Declarations
=> Declarations
);
1042 end Add_RACW_Read_Write_Attributes
;
1044 ------------------------------
1045 -- Add_RACW_Write_Attribute --
1046 ------------------------------
1048 procedure Add_RACW_Write_Attribute
1049 (RACW_Type
: in Entity_Id
;
1050 Stub_Type
: in Entity_Id
;
1051 Stub_Type_Access
: in Entity_Id
;
1052 Object_RPC_Receiver
: in Entity_Id
;
1053 Declarations
: in List_Id
)
1055 Loc
: constant Source_Ptr
:= Sloc
(RACW_Type
);
1057 Proc_Spec
: Node_Id
;
1059 Proc_Body_Spec
: Node_Id
;
1061 Body_Node
: Node_Id
;
1063 Proc_Decl
: Node_Id
;
1064 Attr_Decl
: Node_Id
;
1066 Statements
: List_Id
;
1067 Local_Statements
: List_Id
;
1068 Remote_Statements
: List_Id
;
1069 Null_Statements
: List_Id
;
1071 Procedure_Name
: constant Name_Id
:= New_Internal_Name
('R');
1073 Stream_Parameter
: constant Entity_Id
:=
1074 Make_Defining_Identifier
1075 (Loc
, New_Internal_Name
('S'));
1077 Object
: constant Entity_Id
:=
1078 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1081 -- Build the code fragment corresponding to the marshalling of a
1084 Local_Statements
:= New_List
(
1086 Pack_Entity_Into_Stream_Access
(Loc
,
1087 Stream
=> Stream_Parameter
,
1088 Object
=> RTE
(RE_Get_Local_Partition_Id
)),
1090 Pack_Node_Into_Stream_Access
(Loc
,
1091 Stream
=> Stream_Parameter
,
1092 Object
=> OK_Convert_To
(RTE
(RE_Unsigned_64
),
1093 Make_Attribute_Reference
(Loc
,
1094 Prefix
=> New_Occurrence_Of
(Object_RPC_Receiver
, Loc
),
1095 Attribute_Name
=> Name_Address
)),
1096 Etyp
=> RTE
(RE_Unsigned_64
)),
1098 Pack_Node_Into_Stream_Access
(Loc
,
1099 Stream
=> Stream_Parameter
,
1100 Object
=> OK_Convert_To
(RTE
(RE_Unsigned_64
),
1101 Make_Attribute_Reference
(Loc
,
1103 Make_Explicit_Dereference
(Loc
,
1104 Prefix
=> New_Occurrence_Of
(Object
, Loc
)),
1105 Attribute_Name
=> Name_Address
)),
1106 Etyp
=> RTE
(RE_Unsigned_64
)));
1108 -- Build the code fragment corresponding to the marshalling of
1111 Remote_Statements
:= New_List
(
1113 Pack_Node_Into_Stream_Access
(Loc
,
1114 Stream
=> Stream_Parameter
,
1116 Make_Selected_Component
(Loc
,
1117 Prefix
=> Unchecked_Convert_To
(Stub_Type_Access
,
1118 New_Occurrence_Of
(Object
, Loc
)),
1120 Make_Identifier
(Loc
, Name_Origin
)),
1121 Etyp
=> RTE
(RE_Partition_ID
)),
1123 Pack_Node_Into_Stream_Access
(Loc
,
1124 Stream
=> Stream_Parameter
,
1126 Make_Selected_Component
(Loc
,
1127 Prefix
=> Unchecked_Convert_To
(Stub_Type_Access
,
1128 New_Occurrence_Of
(Object
, Loc
)),
1130 Make_Identifier
(Loc
, Name_Receiver
)),
1131 Etyp
=> RTE
(RE_Unsigned_64
)),
1133 Pack_Node_Into_Stream_Access
(Loc
,
1134 Stream
=> Stream_Parameter
,
1136 Make_Selected_Component
(Loc
,
1137 Prefix
=> Unchecked_Convert_To
(Stub_Type_Access
,
1138 New_Occurrence_Of
(Object
, Loc
)),
1140 Make_Identifier
(Loc
, Name_Addr
)),
1141 Etyp
=> RTE
(RE_Unsigned_64
)));
1143 -- Build the code fragment corresponding to the marshalling of a null
1146 Null_Statements
:= New_List
(
1148 Pack_Entity_Into_Stream_Access
(Loc
,
1149 Stream
=> Stream_Parameter
,
1150 Object
=> RTE
(RE_Get_Local_Partition_Id
)),
1152 Pack_Node_Into_Stream_Access
(Loc
,
1153 Stream
=> Stream_Parameter
,
1154 Object
=> OK_Convert_To
(RTE
(RE_Unsigned_64
),
1155 Make_Attribute_Reference
(Loc
,
1156 Prefix
=> New_Occurrence_Of
(Object_RPC_Receiver
, Loc
),
1157 Attribute_Name
=> Name_Address
)),
1158 Etyp
=> RTE
(RE_Unsigned_64
)),
1160 Pack_Node_Into_Stream_Access
(Loc
,
1161 Stream
=> Stream_Parameter
,
1162 Object
=> Make_Integer_Literal
(Loc
, Uint_0
),
1163 Etyp
=> RTE
(RE_Unsigned_64
)));
1165 Statements
:= New_List
(
1166 Make_Implicit_If_Statement
(RACW_Type
,
1169 Left_Opnd
=> New_Occurrence_Of
(Object
, Loc
),
1170 Right_Opnd
=> Make_Null
(Loc
)),
1171 Then_Statements
=> Null_Statements
,
1172 Elsif_Parts
=> New_List
(
1173 Make_Elsif_Part
(Loc
,
1177 Make_Attribute_Reference
(Loc
,
1178 Prefix
=> New_Occurrence_Of
(Object
, Loc
),
1179 Attribute_Name
=> Name_Tag
),
1181 Make_Attribute_Reference
(Loc
,
1182 Prefix
=> New_Occurrence_Of
(Stub_Type
, Loc
),
1183 Attribute_Name
=> Name_Tag
)),
1184 Then_Statements
=> Remote_Statements
)),
1185 Else_Statements
=> Local_Statements
));
1188 Make_Procedure_Specification
(Loc
,
1189 Defining_Unit_Name
=>
1190 Make_Defining_Identifier
(Loc
, Procedure_Name
),
1192 Parameter_Specifications
=> New_List
(
1193 Make_Parameter_Specification
(Loc
,
1194 Defining_Identifier
=> Stream_Parameter
,
1196 Make_Access_Definition
(Loc
,
1198 Make_Attribute_Reference
(Loc
,
1200 New_Occurrence_Of
(RTE
(RE_Root_Stream_Type
), Loc
),
1204 Make_Parameter_Specification
(Loc
,
1205 Defining_Identifier
=> Object
,
1208 New_Occurrence_Of
(RACW_Type
, Loc
))));
1211 Make_Subprogram_Declaration
(Loc
, Specification
=> Proc_Spec
);
1214 Make_Attribute_Definition_Clause
(Loc
,
1215 Name
=> New_Occurrence_Of
(RACW_Type
, Loc
),
1216 Chars
=> Name_Write
,
1218 New_Occurrence_Of
(Defining_Unit_Name
(Proc_Spec
), Loc
));
1221 Make_Procedure_Specification
(Loc
,
1222 Defining_Unit_Name
=>
1223 Make_Defining_Identifier
(Loc
, Procedure_Name
),
1225 Parameter_Specifications
=> New_List
(
1226 Make_Parameter_Specification
(Loc
,
1227 Defining_Identifier
=>
1228 Make_Defining_Identifier
(Loc
, Chars
(Stream_Parameter
)),
1230 Make_Access_Definition
(Loc
,
1232 Make_Attribute_Reference
(Loc
,
1234 New_Occurrence_Of
(RTE
(RE_Root_Stream_Type
), Loc
),
1238 Make_Parameter_Specification
(Loc
,
1239 Defining_Identifier
=>
1240 Make_Defining_Identifier
(Loc
, Chars
(Object
)),
1243 New_Occurrence_Of
(RACW_Type
, Loc
))));
1246 Make_Subprogram_Body
(Loc
,
1247 Specification
=> Proc_Body_Spec
,
1248 Declarations
=> No_List
,
1249 Handled_Statement_Sequence
=>
1250 Make_Handled_Sequence_Of_Statements
(Loc
,
1251 Statements
=> Statements
));
1253 Insert_After
(Declaration_Node
(RACW_Type
), Proc_Decl
);
1254 Insert_After
(Proc_Decl
, Attr_Decl
);
1255 Append_To
(Declarations
, Body_Node
);
1256 end Add_RACW_Write_Attribute
;
1258 ------------------------------
1259 -- Add_RAS_Access_Attribute --
1260 ------------------------------
1262 procedure Add_RAS_Access_Attribute
(N
: in Node_Id
) is
1263 Ras_Type
: constant Entity_Id
:= Defining_Identifier
(N
);
1264 Fat_Type
: constant Entity_Id
:= Equivalent_Type
(Ras_Type
);
1265 -- Ras_Type is the access to subprogram type while Fat_Type points to
1266 -- the record type corresponding to a remote access to subprogram type.
1268 Proc_Decls
: constant List_Id
:= New_List
;
1269 Proc_Statements
: constant List_Id
:= New_List
;
1271 Proc_Spec
: Node_Id
;
1272 Proc_Body
: Node_Id
;
1277 Package_Name
: Node_Id
;
1279 Asynchronous
: Node_Id
;
1280 Return_Value
: Node_Id
;
1282 Loc
: constant Source_Ptr
:= Sloc
(N
);
1284 procedure Set_Field
(Field_Name
: in Name_Id
; Value
: in Node_Id
);
1285 -- Set a field name for the return value
1287 procedure Set_Field
(Field_Name
: in Name_Id
; Value
: in Node_Id
)
1290 Append_To
(Proc_Statements
,
1291 Make_Assignment_Statement
(Loc
,
1293 Make_Selected_Component
(Loc
,
1294 Prefix
=> New_Occurrence_Of
(Return_Value
, Loc
),
1295 Selector_Name
=> Make_Identifier
(Loc
, Field_Name
)),
1296 Expression
=> Value
));
1299 -- Start of processing for Add_RAS_Access_Attribute
1302 Param
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1303 Package_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
1304 Subp_Id
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('N'));
1305 Asynchronous
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('B'));
1306 Return_Value
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1308 -- Create the object which will be returned of type Fat_Type
1310 Append_To
(Proc_Decls
,
1311 Make_Object_Declaration
(Loc
,
1312 Defining_Identifier
=> Return_Value
,
1313 Object_Definition
=>
1314 New_Occurrence_Of
(Fat_Type
, Loc
)));
1316 -- Initialize the fields of the record type with the appropriate data
1318 Set_Field
(Name_Ras
,
1319 OK_Convert_To
(RTE
(RE_Unsigned_64
), New_Occurrence_Of
(Param
, Loc
)));
1321 Set_Field
(Name_Origin
,
1322 Unchecked_Convert_To
(Standard_Integer
,
1323 Make_Function_Call
(Loc
,
1325 New_Occurrence_Of
(RTE
(RE_Get_Active_Partition_Id
), Loc
),
1326 Parameter_Associations
=> New_List
(
1327 New_Occurrence_Of
(Package_Name
, Loc
)))));
1329 Set_Field
(Name_Receiver
,
1330 Make_Function_Call
(Loc
,
1332 New_Occurrence_Of
(RTE
(RE_Get_RCI_Package_Receiver
), Loc
),
1333 Parameter_Associations
=> New_List
(
1334 New_Occurrence_Of
(Package_Name
, Loc
))));
1336 Set_Field
(Name_Subp_Id
,
1337 New_Occurrence_Of
(Subp_Id
, Loc
));
1339 Set_Field
(Name_Async
,
1340 New_Occurrence_Of
(Asynchronous
, Loc
));
1342 -- Return the newly created value
1344 Append_To
(Proc_Statements
,
1345 Make_Return_Statement
(Loc
,
1347 New_Occurrence_Of
(Return_Value
, Loc
)));
1349 Proc
:= Make_Defining_Identifier
(Loc
, Name_uRAS_Access
);
1352 Make_Function_Specification
(Loc
,
1353 Defining_Unit_Name
=> Proc
,
1354 Parameter_Specifications
=> New_List
(
1355 Make_Parameter_Specification
(Loc
,
1356 Defining_Identifier
=> Param
,
1358 New_Occurrence_Of
(RTE
(RE_Address
), Loc
)),
1360 Make_Parameter_Specification
(Loc
,
1361 Defining_Identifier
=> Package_Name
,
1363 New_Occurrence_Of
(Standard_String
, Loc
)),
1365 Make_Parameter_Specification
(Loc
,
1366 Defining_Identifier
=> Subp_Id
,
1368 New_Occurrence_Of
(Standard_Natural
, Loc
)),
1370 Make_Parameter_Specification
(Loc
,
1371 Defining_Identifier
=> Asynchronous
,
1373 New_Occurrence_Of
(Standard_Boolean
, Loc
))),
1376 New_Occurrence_Of
(Fat_Type
, Loc
));
1378 -- Set the kind and return type of the function to prevent ambiguities
1379 -- between Ras_Type and Fat_Type in subsequent analysis.
1381 Set_Ekind
(Proc
, E_Function
);
1382 Set_Etype
(Proc
, New_Occurrence_Of
(Fat_Type
, Loc
));
1385 Make_Subprogram_Body
(Loc
,
1386 Specification
=> Proc_Spec
,
1387 Declarations
=> Proc_Decls
,
1388 Handled_Statement_Sequence
=>
1389 Make_Handled_Sequence_Of_Statements
(Loc
,
1390 Statements
=> Proc_Statements
));
1392 Set_TSS
(Fat_Type
, Proc
);
1394 end Add_RAS_Access_Attribute
;
1396 -----------------------------------
1397 -- Add_RAS_Dereference_Attribute --
1398 -----------------------------------
1400 procedure Add_RAS_Dereference_Attribute
(N
: in Node_Id
) is
1401 Loc
: constant Source_Ptr
:= Sloc
(N
);
1403 Type_Def
: constant Node_Id
:= Type_Definition
(N
);
1405 Ras_Type
: constant Entity_Id
:= Defining_Identifier
(N
);
1407 Fat_Type
: constant Entity_Id
:= Equivalent_Type
(Ras_Type
);
1409 Proc_Decls
: constant List_Id
:= New_List
;
1410 Proc_Statements
: constant List_Id
:= New_List
;
1412 Inner_Decls
: constant List_Id
:= New_List
;
1413 Inner_Statements
: constant List_Id
:= New_List
;
1415 Direct_Statements
: constant List_Id
:= New_List
;
1419 Proc_Spec
: Node_Id
;
1420 Proc_Body
: Node_Id
;
1422 Param_Specs
: constant List_Id
:= New_List
;
1423 Param_Assoc
: constant List_Id
:= New_List
;
1427 Converted_Ras
: Node_Id
;
1428 Target_Partition
: Node_Id
;
1429 RPC_Receiver
: Node_Id
;
1430 Subprogram_Id
: Node_Id
;
1431 Asynchronous
: Node_Id
;
1433 Is_Function
: constant Boolean :=
1434 Nkind
(Type_Def
) = N_Access_Function_Definition
;
1436 Spec
: constant Node_Id
:= Type_Def
;
1438 Current_Parameter
: Node_Id
;
1441 -- The way to do it is test if the Ras field is non-null and then if
1442 -- the Origin field is equal to the current partition ID (which is in
1443 -- fact Current_Package'Partition_ID). If this is the case, then it
1444 -- is safe to dereference the Ras field directly rather than
1445 -- performing a remote call.
1448 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1451 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1453 Append_To
(Proc_Decls
,
1454 Make_Object_Declaration
(Loc
,
1455 Defining_Identifier
=> Target_Partition
,
1456 Constant_Present
=> True,
1457 Object_Definition
=>
1458 New_Occurrence_Of
(RTE
(RE_Partition_ID
), Loc
),
1460 Unchecked_Convert_To
(RTE
(RE_Partition_ID
),
1461 Make_Selected_Component
(Loc
,
1463 New_Occurrence_Of
(Pointer
, Loc
),
1465 Make_Identifier
(Loc
, Name_Origin
)))));
1468 Make_Selected_Component
(Loc
,
1470 New_Occurrence_Of
(Pointer
, Loc
),
1472 Make_Identifier
(Loc
, Name_Receiver
));
1475 Unchecked_Convert_To
(RTE
(RE_Subprogram_Id
),
1476 Make_Selected_Component
(Loc
,
1478 New_Occurrence_Of
(Pointer
, Loc
),
1480 Make_Identifier
(Loc
, Name_Subp_Id
)));
1482 -- A function is never asynchronous. A procedure may or may not be
1483 -- asynchronous depending on whether a pragma Asynchronous applies
1484 -- on it. Since a RAST may point onto various subprograms, this is
1485 -- only known at runtime so both versions (synchronous and asynchronous)
1486 -- must be built every times it is not a function.
1489 Asynchronous
:= Empty
;
1493 Make_Selected_Component
(Loc
,
1495 New_Occurrence_Of
(Pointer
, Loc
),
1497 Make_Identifier
(Loc
, Name_Async
));
1501 if Present
(Parameter_Specifications
(Type_Def
)) then
1502 Current_Parameter
:= First
(Parameter_Specifications
(Type_Def
));
1504 while Current_Parameter
/= Empty
loop
1505 Append_To
(Param_Specs
,
1506 Make_Parameter_Specification
(Loc
,
1507 Defining_Identifier
=>
1508 Make_Defining_Identifier
(Loc
,
1509 Chars
=> Chars
(Defining_Identifier
(Current_Parameter
))),
1510 In_Present
=> In_Present
(Current_Parameter
),
1511 Out_Present
=> Out_Present
(Current_Parameter
),
1514 (Etype
(Parameter_Type
(Current_Parameter
)), Loc
),
1516 New_Copy_Tree
(Expression
(Current_Parameter
))));
1518 Append_To
(Param_Assoc
,
1519 Make_Identifier
(Loc
,
1520 Chars
=> Chars
(Defining_Identifier
(Current_Parameter
))));
1522 Next
(Current_Parameter
);
1526 Proc
:= Make_Defining_Identifier
(Loc
, Name_uRAS_Dereference
);
1530 Make_Function_Specification
(Loc
,
1531 Defining_Unit_Name
=> Proc
,
1532 Parameter_Specifications
=> Param_Specs
,
1535 Entity
(Subtype_Mark
(Spec
)), Loc
));
1537 Set_Ekind
(Proc
, E_Function
);
1540 New_Occurrence_Of
(Entity
(Subtype_Mark
(Spec
)), Loc
));
1544 Make_Procedure_Specification
(Loc
,
1545 Defining_Unit_Name
=> Proc
,
1546 Parameter_Specifications
=> Param_Specs
);
1548 Set_Ekind
(Proc
, E_Procedure
);
1549 Set_Etype
(Proc
, Standard_Void_Type
);
1552 -- Build the calling stubs for the dereference of the RAS
1554 Build_General_Calling_Stubs
1555 (Decls
=> Inner_Decls
,
1556 Statements
=> Inner_Statements
,
1557 Target_Partition
=> Target_Partition
,
1558 RPC_Receiver
=> RPC_Receiver
,
1559 Subprogram_Id
=> Subprogram_Id
,
1560 Asynchronous
=> Asynchronous
,
1561 Is_Known_Non_Asynchronous
=> Is_Function
,
1562 Is_Function
=> Is_Function
,
1567 Unchecked_Convert_To
(Ras_Type
,
1568 OK_Convert_To
(RTE
(RE_Address
),
1569 Make_Selected_Component
(Loc
,
1570 Prefix
=> New_Occurrence_Of
(Pointer
, Loc
),
1571 Selector_Name
=> Make_Identifier
(Loc
, Name_Ras
))));
1574 Append_To
(Direct_Statements
,
1575 Make_Return_Statement
(Loc
,
1577 Make_Function_Call
(Loc
,
1579 Make_Explicit_Dereference
(Loc
,
1580 Prefix
=> Converted_Ras
),
1581 Parameter_Associations
=> Param_Assoc
)));
1584 Append_To
(Direct_Statements
,
1585 Make_Procedure_Call_Statement
(Loc
,
1587 Make_Explicit_Dereference
(Loc
,
1588 Prefix
=> Converted_Ras
),
1589 Parameter_Associations
=> Param_Assoc
));
1592 Prepend_To
(Param_Specs
,
1593 Make_Parameter_Specification
(Loc
,
1594 Defining_Identifier
=> Pointer
,
1597 New_Occurrence_Of
(Fat_Type
, Loc
)));
1599 Append_To
(Proc_Statements
,
1600 Make_Implicit_If_Statement
(N
,
1606 Make_Selected_Component
(Loc
,
1607 Prefix
=> New_Occurrence_Of
(Pointer
, Loc
),
1608 Selector_Name
=> Make_Identifier
(Loc
, Name_Ras
)),
1610 Make_Integer_Literal
(Loc
, Uint_0
)),
1615 New_Occurrence_Of
(Target_Partition
, Loc
),
1617 Make_Function_Call
(Loc
,
1619 RTE
(RE_Get_Local_Partition_Id
), Loc
)))),
1624 Else_Statements
=> New_List
(
1625 Make_Block_Statement
(Loc
,
1626 Declarations
=> Inner_Decls
,
1627 Handled_Statement_Sequence
=>
1628 Make_Handled_Sequence_Of_Statements
(Loc
,
1629 Statements
=> Inner_Statements
)))));
1632 Make_Subprogram_Body
(Loc
,
1633 Specification
=> Proc_Spec
,
1634 Declarations
=> Proc_Decls
,
1635 Handled_Statement_Sequence
=>
1636 Make_Handled_Sequence_Of_Statements
(Loc
,
1637 Statements
=> Proc_Statements
));
1639 Set_TSS
(Fat_Type
, Defining_Unit_Name
(Proc_Spec
));
1641 end Add_RAS_Dereference_Attribute
;
1643 -----------------------
1644 -- Add_RAST_Features --
1645 -----------------------
1647 procedure Add_RAST_Features
(Vis_Decl
: Node_Id
) is
1649 -- Do not add attributes more than once in any case. This should
1650 -- be replaced by an assert or this comment removed if we decide
1651 -- that this is normal to be called several times ???
1653 if Present
(TSS
(Equivalent_Type
(Defining_Identifier
1654 (Vis_Decl
)), Name_uRAS_Access
))
1659 Add_RAS_Dereference_Attribute
(Vis_Decl
);
1660 Add_RAS_Access_Attribute
(Vis_Decl
);
1661 end Add_RAST_Features
;
1663 -----------------------------------------
1664 -- Add_Receiving_Stubs_To_Declarations --
1665 -----------------------------------------
1667 procedure Add_Receiving_Stubs_To_Declarations
1668 (Pkg_Spec
: in Node_Id
;
1671 Loc
: constant Source_Ptr
:= Sloc
(Pkg_Spec
);
1673 Stream_Parameter
: Node_Id
;
1674 Result_Parameter
: Node_Id
;
1676 Pkg_RPC_Receiver
: Node_Id
;
1677 Pkg_RPC_Receiver_Spec
: Node_Id
;
1678 Pkg_RPC_Receiver_Formals
: List_Id
;
1679 Pkg_RPC_Receiver_Decls
: List_Id
;
1680 Pkg_RPC_Receiver_Statements
: List_Id
;
1681 Pkg_RPC_Receiver_Cases
: List_Id
:= New_List
;
1682 Pkg_RPC_Receiver_Body
: Node_Id
;
1683 -- A Pkg_RPC_Receiver is built to decode the request
1686 -- Subprogram_Id as read from the incoming stream
1688 Current_Declaration
: Node_Id
;
1689 Current_Subprogram_Number
: Int
:= 0;
1690 Current_Stubs
: Node_Id
;
1694 Dummy_Register_Name
: Name_Id
;
1695 Dummy_Register_Spec
: Node_Id
;
1696 Dummy_Register_Decl
: Node_Id
;
1697 Dummy_Register_Body
: Node_Id
;
1700 -- Building receiving stubs consist in several operations:
1702 -- - a package RPC receiver must be built. This subprogram
1703 -- will get a Subprogram_Id from the incoming stream
1704 -- and will dispatch the call to the right subprogram
1706 -- - a receiving stub for any subprogram visible in the package
1707 -- spec. This stub will read all the parameters from the stream,
1708 -- and put the result as well as the exception occurrence in the
1711 -- - a dummy package with an empty spec and a body made of an
1712 -- elaboration part, whose job is to register the receiving
1713 -- part of this RCI package on the name server. This is done
1714 -- by calling System.Partition_Interface.Register_Receiving_Stub
1717 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
1719 Make_Defining_Identifier
(Loc
, New_Internal_Name
('R'));
1721 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1724 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1726 -- The parameters of the package RPC receiver are made of two
1727 -- streams, an input one and an output one.
1729 Pkg_RPC_Receiver_Formals
:= New_List
(
1730 Make_Parameter_Specification
(Loc
,
1731 Defining_Identifier
=> Stream_Parameter
,
1733 Make_Access_Definition
(Loc
,
1735 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
))),
1736 Make_Parameter_Specification
(Loc
,
1737 Defining_Identifier
=> Result_Parameter
,
1739 Make_Access_Definition
(Loc
,
1741 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
))));
1743 Pkg_RPC_Receiver_Spec
:=
1744 Make_Procedure_Specification
(Loc
,
1745 Defining_Unit_Name
=> Pkg_RPC_Receiver
,
1746 Parameter_Specifications
=> Pkg_RPC_Receiver_Formals
);
1748 Pkg_RPC_Receiver_Decls
:= New_List
(
1749 Make_Object_Declaration
(Loc
,
1750 Defining_Identifier
=> Subp_Id
,
1751 Object_Definition
=>
1752 New_Occurrence_Of
(RTE
(RE_Subprogram_Id
), Loc
)));
1754 Pkg_RPC_Receiver_Statements
:= New_List
(
1755 Make_Attribute_Reference
(Loc
,
1757 New_Occurrence_Of
(RTE
(RE_Subprogram_Id
), Loc
),
1760 Expressions
=> New_List
(
1761 New_Occurrence_Of
(Stream_Parameter
, Loc
),
1762 New_Occurrence_Of
(Subp_Id
, Loc
))));
1764 -- For each subprogram, the receiving stub will be built and a
1765 -- case statement will be made on the Subprogram_Id to dispatch
1766 -- to the right subprogram.
1768 Current_Declaration
:= First
(Visible_Declarations
(Pkg_Spec
));
1770 while Current_Declaration
/= Empty
loop
1772 if Nkind
(Current_Declaration
) = N_Subprogram_Declaration
1773 and then Comes_From_Source
(Current_Declaration
)
1775 pragma Assert
(Current_Subprogram_Number
=
1776 Get_Subprogram_Id
(Defining_Unit_Name
(Specification
(
1777 Current_Declaration
))));
1780 Build_Subprogram_Receiving_Stubs
1781 (Vis_Decl
=> Current_Declaration
,
1783 Nkind
(Specification
(Current_Declaration
)) =
1784 N_Procedure_Specification
1785 and then Is_Asynchronous
1786 (Defining_Unit_Name
(Specification
1787 (Current_Declaration
))));
1789 Append_To
(Decls
, Current_Stubs
);
1791 Analyze
(Current_Stubs
);
1793 Actuals
:= New_List
(New_Occurrence_Of
(Stream_Parameter
, Loc
));
1795 if Nkind
(Specification
(Current_Declaration
))
1796 = N_Function_Specification
1798 not Is_Asynchronous
(
1799 Defining_Entity
(Specification
(Current_Declaration
)))
1801 -- An asynchronous procedure does not want an output parameter
1802 -- since no result and no exception will ever be returned.
1805 New_Occurrence_Of
(Result_Parameter
, Loc
));
1809 Append_To
(Pkg_RPC_Receiver_Cases
,
1810 Make_Case_Statement_Alternative
(Loc
,
1813 Make_Integer_Literal
(Loc
, Current_Subprogram_Number
)),
1817 Make_Procedure_Call_Statement
(Loc
,
1820 Defining_Entity
(Current_Stubs
), Loc
),
1821 Parameter_Associations
=>
1824 Current_Subprogram_Number
:= Current_Subprogram_Number
+ 1;
1827 Next
(Current_Declaration
);
1830 -- If we receive an invalid Subprogram_Id, it is best to do nothing
1831 -- rather than raising an exception since we do not want someone
1832 -- to crash a remote partition by sending invalid subprogram ids.
1833 -- This is consistent with the other parts of the case statement
1834 -- since even in presence of incorrect parameters in the stream,
1835 -- every exception will be caught and (if the subprogram is not an
1836 -- APC) put into the result stream and sent away.
1838 Append_To
(Pkg_RPC_Receiver_Cases
,
1839 Make_Case_Statement_Alternative
(Loc
,
1841 New_List
(Make_Others_Choice
(Loc
)),
1843 New_List
(Make_Null_Statement
(Loc
))));
1845 Append_To
(Pkg_RPC_Receiver_Statements
,
1846 Make_Case_Statement
(Loc
,
1848 New_Occurrence_Of
(Subp_Id
, Loc
),
1849 Alternatives
=> Pkg_RPC_Receiver_Cases
));
1851 Pkg_RPC_Receiver_Body
:=
1852 Make_Subprogram_Body
(Loc
,
1853 Specification
=> Pkg_RPC_Receiver_Spec
,
1854 Declarations
=> Pkg_RPC_Receiver_Decls
,
1855 Handled_Statement_Sequence
=>
1856 Make_Handled_Sequence_Of_Statements
(Loc
,
1857 Statements
=> Pkg_RPC_Receiver_Statements
));
1859 Append_To
(Decls
, Pkg_RPC_Receiver_Body
);
1860 Analyze
(Pkg_RPC_Receiver_Body
);
1862 -- Construction of the dummy package used to register the package
1863 -- receiving stubs on the nameserver.
1865 Dummy_Register_Name
:= New_Internal_Name
('P');
1867 Dummy_Register_Spec
:=
1868 Make_Package_Specification
(Loc
,
1869 Defining_Unit_Name
=>
1870 Make_Defining_Identifier
(Loc
, Dummy_Register_Name
),
1871 Visible_Declarations
=> No_List
,
1872 End_Label
=> Empty
);
1874 Dummy_Register_Decl
:=
1875 Make_Package_Declaration
(Loc
,
1876 Specification
=> Dummy_Register_Spec
);
1879 Dummy_Register_Decl
);
1880 Analyze
(Dummy_Register_Decl
);
1882 Dummy_Register_Body
:=
1883 Make_Package_Body
(Loc
,
1884 Defining_Unit_Name
=>
1885 Make_Defining_Identifier
(Loc
, Dummy_Register_Name
),
1886 Declarations
=> No_List
,
1888 Handled_Statement_Sequence
=>
1889 Make_Handled_Sequence_Of_Statements
(Loc
,
1890 Statements
=> New_List
(
1891 Make_Procedure_Call_Statement
(Loc
,
1893 New_Occurrence_Of
(RTE
(RE_Register_Receiving_Stub
), Loc
),
1895 Parameter_Associations
=> New_List
(
1896 Make_String_Literal
(Loc
,
1897 Strval
=> Get_Pkg_Name_String_Id
(Pkg_Spec
)),
1898 Make_Attribute_Reference
(Loc
,
1900 New_Occurrence_Of
(Pkg_RPC_Receiver
, Loc
),
1902 Name_Unrestricted_Access
),
1903 Make_Attribute_Reference
(Loc
,
1905 New_Occurrence_Of
(Defining_Entity
(Pkg_Spec
), Loc
),
1909 Append_To
(Decls
, Dummy_Register_Body
);
1910 Analyze
(Dummy_Register_Body
);
1911 end Add_Receiving_Stubs_To_Declarations
;
1917 procedure Add_Stub_Type
1918 (Designated_Type
: in Entity_Id
;
1919 RACW_Type
: in Entity_Id
;
1921 Stub_Type
: out Entity_Id
;
1922 Stub_Type_Access
: out Entity_Id
;
1923 Object_RPC_Receiver
: out Entity_Id
;
1924 Existing
: out Boolean)
1926 Loc
: constant Source_Ptr
:= Sloc
(RACW_Type
);
1928 Stub_Elements
: constant Stub_Structure
:=
1929 Stubs_Table
.Get
(Designated_Type
);
1931 Stub_Type_Declaration
: Node_Id
;
1932 Stub_Type_Access_Declaration
: Node_Id
;
1933 Object_RPC_Receiver_Declaration
: Node_Id
;
1935 RPC_Receiver_Stream
: Entity_Id
;
1936 RPC_Receiver_Result
: Entity_Id
;
1939 if Stub_Elements
/= Empty_Stub_Structure
then
1940 Stub_Type
:= Stub_Elements
.Stub_Type
;
1941 Stub_Type_Access
:= Stub_Elements
.Stub_Type_Access
;
1942 Object_RPC_Receiver
:= Stub_Elements
.Object_RPC_Receiver
;
1949 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
1951 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
1952 Object_RPC_Receiver
:=
1953 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1954 RPC_Receiver_Stream
:=
1955 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
1956 RPC_Receiver_Result
:=
1957 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
1958 Stubs_Table
.Set
(Designated_Type
,
1959 (Stub_Type
=> Stub_Type
,
1960 Stub_Type_Access
=> Stub_Type_Access
,
1961 Object_RPC_Receiver
=> Object_RPC_Receiver
,
1962 RPC_Receiver_Stream
=> RPC_Receiver_Stream
,
1963 RPC_Receiver_Result
=> RPC_Receiver_Result
,
1964 RACW_Type
=> RACW_Type
));
1966 -- The stub type definition below must match exactly the one in
1967 -- s-parint.ads, since unchecked conversions will be used in
1968 -- s-parint.adb to modify pointers passed to Get_Unique_Remote_Pointer.
1970 Stub_Type_Declaration
:=
1971 Make_Full_Type_Declaration
(Loc
,
1972 Defining_Identifier
=> Stub_Type
,
1974 Make_Record_Definition
(Loc
,
1975 Tagged_Present
=> True,
1976 Limited_Present
=> True,
1978 Make_Component_List
(Loc
,
1979 Component_Items
=> New_List
(
1981 Make_Component_Declaration
(Loc
,
1982 Defining_Identifier
=>
1983 Make_Defining_Identifier
(Loc
, Name_Origin
),
1984 Subtype_Indication
=>
1985 New_Occurrence_Of
(RTE
(RE_Partition_ID
), Loc
)),
1987 Make_Component_Declaration
(Loc
,
1988 Defining_Identifier
=>
1989 Make_Defining_Identifier
(Loc
, Name_Receiver
),
1990 Subtype_Indication
=>
1991 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
)),
1993 Make_Component_Declaration
(Loc
,
1994 Defining_Identifier
=>
1995 Make_Defining_Identifier
(Loc
, Name_Addr
),
1996 Subtype_Indication
=>
1997 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
)),
1999 Make_Component_Declaration
(Loc
,
2000 Defining_Identifier
=>
2001 Make_Defining_Identifier
(Loc
, Name_Asynchronous
),
2002 Subtype_Indication
=>
2003 New_Occurrence_Of
(Standard_Boolean
, Loc
))))));
2005 Append_To
(Decls
, Stub_Type_Declaration
);
2006 Analyze
(Stub_Type_Declaration
);
2008 -- This is in no way a type derivation, but we fake it to make
2009 -- sure that the dispatching table gets built with the corresponding
2010 -- primitive operations at the right place.
2012 Derive_Subprograms
(Parent_Type
=> Designated_Type
,
2013 Derived_Type
=> Stub_Type
);
2015 Stub_Type_Access_Declaration
:=
2016 Make_Full_Type_Declaration
(Loc
,
2017 Defining_Identifier
=> Stub_Type_Access
,
2019 Make_Access_To_Object_Definition
(Loc
,
2020 Subtype_Indication
=> New_Occurrence_Of
(Stub_Type
, Loc
)));
2022 Append_To
(Decls
, Stub_Type_Access_Declaration
);
2023 Analyze
(Stub_Type_Access_Declaration
);
2025 Object_RPC_Receiver_Declaration
:=
2026 Make_Subprogram_Declaration
(Loc
,
2027 Make_Procedure_Specification
(Loc
,
2028 Defining_Unit_Name
=> Object_RPC_Receiver
,
2029 Parameter_Specifications
=> New_List
(
2030 Make_Parameter_Specification
(Loc
,
2031 Defining_Identifier
=> RPC_Receiver_Stream
,
2033 Make_Access_Definition
(Loc
,
2035 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
))),
2037 Make_Parameter_Specification
(Loc
,
2038 Defining_Identifier
=> RPC_Receiver_Result
,
2040 Make_Access_Definition
(Loc
,
2043 (RTE
(RE_Params_Stream_Type
), Loc
))))));
2045 Append_To
(Decls
, Object_RPC_Receiver_Declaration
);
2048 ---------------------------------
2049 -- Build_General_Calling_Stubs --
2050 ---------------------------------
2052 procedure Build_General_Calling_Stubs
2054 Statements
: List_Id
;
2055 Target_Partition
: Entity_Id
;
2056 RPC_Receiver
: Node_Id
;
2057 Subprogram_Id
: Node_Id
;
2058 Asynchronous
: Node_Id
:= Empty
;
2059 Is_Known_Asynchronous
: Boolean := False;
2060 Is_Known_Non_Asynchronous
: Boolean := False;
2061 Is_Function
: Boolean;
2063 Object_Type
: Entity_Id
:= Empty
;
2066 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
2068 Stream_Parameter
: Node_Id
;
2069 -- Name of the stream used to transmit parameters to the remote package
2071 Result_Parameter
: Node_Id
;
2072 -- Name of the result parameter (in non-APC cases) which get the
2073 -- result of the remote subprogram.
2075 Exception_Return_Parameter
: Node_Id
;
2076 -- Name of the parameter which will hold the exception sent by the
2077 -- remote subprogram.
2079 Current_Parameter
: Node_Id
;
2080 -- Current parameter being handled
2082 Ordered_Parameters_List
: constant List_Id
:=
2083 Build_Ordered_Parameters_List
(Spec
);
2085 Asynchronous_Statements
: List_Id
:= No_List
;
2086 Non_Asynchronous_Statements
: List_Id
:= No_List
;
2087 -- Statements specifics to the Asynchronous/Non-Asynchronous cases.
2089 Extra_Formal_Statements
: constant List_Id
:= New_List
;
2090 -- List of statements for extra formal parameters. It will appear after
2091 -- the regular statements for writing out parameters.
2094 -- The general form of a calling stub for a given subprogram is:
2096 -- procedure X (...) is
2097 -- P : constant Partition_ID := RCI_Cache.Get_Active_Partition_ID;
2098 -- Stream, Result : aliased System.RPC.Params_Stream_Type (0);
2100 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
2101 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
2102 -- Put_Subprogram_Id_In_Stream;
2103 -- Put_Parameters_In_Stream;
2104 -- Do_RPC (Stream, Result);
2105 -- Read_Exception_Occurrence_From_Result; Raise_It;
2106 -- Read_Out_Parameters_And_Function_Return_From_Stream;
2109 -- There are some variations: Do_APC is called for an asynchronous
2110 -- procedure and the part after the call is completely ommitted
2111 -- as well as the declaration of Result. For a function call,
2112 -- 'Input is always used to read the result even if it is constrained.
2115 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
2118 Make_Object_Declaration
(Loc
,
2119 Defining_Identifier
=> Stream_Parameter
,
2120 Aliased_Present
=> True,
2121 Object_Definition
=>
2122 Make_Subtype_Indication
(Loc
,
2124 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
),
2126 Make_Index_Or_Discriminant_Constraint
(Loc
,
2128 New_List
(Make_Integer_Literal
(Loc
, 0))))));
2130 if not Is_Known_Asynchronous
then
2132 Make_Defining_Identifier
(Loc
, New_Internal_Name
('R'));
2135 Make_Object_Declaration
(Loc
,
2136 Defining_Identifier
=> Result_Parameter
,
2137 Aliased_Present
=> True,
2138 Object_Definition
=>
2139 Make_Subtype_Indication
(Loc
,
2141 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
),
2143 Make_Index_Or_Discriminant_Constraint
(Loc
,
2145 New_List
(Make_Integer_Literal
(Loc
, 0))))));
2147 Exception_Return_Parameter
:=
2148 Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
2151 Make_Object_Declaration
(Loc
,
2152 Defining_Identifier
=> Exception_Return_Parameter
,
2153 Object_Definition
=>
2154 New_Occurrence_Of
(RTE
(RE_Exception_Occurrence
), Loc
)));
2157 Result_Parameter
:= Empty
;
2158 Exception_Return_Parameter
:= Empty
;
2161 -- Put first the RPC receiver corresponding to the remote package
2163 Append_To
(Statements
,
2164 Make_Attribute_Reference
(Loc
,
2166 New_Occurrence_Of
(RTE
(RE_Unsigned_64
), Loc
),
2167 Attribute_Name
=> Name_Write
,
2168 Expressions
=> New_List
(
2169 Make_Attribute_Reference
(Loc
,
2171 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2176 -- Then put the Subprogram_Id of the subprogram we want to call in
2179 Append_To
(Statements
,
2180 Make_Attribute_Reference
(Loc
,
2182 New_Occurrence_Of
(RTE
(RE_Subprogram_Id
), Loc
),
2185 Expressions
=> New_List
(
2186 Make_Attribute_Reference
(Loc
,
2188 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2189 Attribute_Name
=> Name_Access
),
2192 Current_Parameter
:= First
(Ordered_Parameters_List
);
2194 while Current_Parameter
/= Empty
loop
2196 if Is_RACW_Controlling_Formal
(Current_Parameter
, Object_Type
) then
2198 -- In the case of a controlling formal argument, we marshall
2199 -- its addr field rather than the local stub.
2201 Append_To
(Statements
,
2202 Pack_Node_Into_Stream
(Loc
,
2203 Stream
=> Stream_Parameter
,
2205 Make_Selected_Component
(Loc
,
2208 Defining_Identifier
(Current_Parameter
), Loc
),
2210 Make_Identifier
(Loc
, Name_Addr
)),
2211 Etyp
=> RTE
(RE_Unsigned_64
)));
2215 Etyp
: constant Entity_Id
:=
2216 Etype
(Parameter_Type
(Current_Parameter
));
2218 Constrained
: constant Boolean :=
2219 Is_Constrained
(Etyp
)
2220 or else Is_Elementary_Type
(Etyp
);
2223 if In_Present
(Current_Parameter
)
2224 or else not Out_Present
(Current_Parameter
)
2225 or else not Constrained
2227 Append_To
(Statements
,
2228 Make_Attribute_Reference
(Loc
,
2230 New_Occurrence_Of
(Etyp
, Loc
),
2231 Attribute_Name
=> Output_From_Constrained
(Constrained
),
2232 Expressions
=> New_List
(
2233 Make_Attribute_Reference
(Loc
,
2235 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2236 Attribute_Name
=> Name_Access
),
2238 Defining_Identifier
(Current_Parameter
), Loc
))));
2243 -- If the current parameter has a dynamic constrained status,
2244 -- then this status is transmitted as well.
2245 -- This should be done for accessibility as well ???
2247 if Nkind
(Parameter_Type
(Current_Parameter
)) /= N_Access_Definition
2248 and then Need_Extra_Constrained
(Current_Parameter
)
2250 -- In this block, we do not use the extra formal that has been
2251 -- created because it does not exist at the time of expansion
2252 -- when building calling stubs for remote access to subprogram
2253 -- types. We create an extra variable of this type and push it
2254 -- in the stream after the regular parameters.
2257 Extra_Parameter
: constant Entity_Id
:=
2258 Make_Defining_Identifier
2259 (Loc
, New_Internal_Name
('P'));
2263 Make_Object_Declaration
(Loc
,
2264 Defining_Identifier
=> Extra_Parameter
,
2265 Constant_Present
=> True,
2266 Object_Definition
=>
2267 New_Occurrence_Of
(Standard_Boolean
, Loc
),
2269 Make_Attribute_Reference
(Loc
,
2272 Defining_Identifier
(Current_Parameter
), Loc
),
2273 Attribute_Name
=> Name_Constrained
)));
2275 Append_To
(Extra_Formal_Statements
,
2276 Make_Attribute_Reference
(Loc
,
2278 New_Occurrence_Of
(Standard_Boolean
, Loc
),
2281 Expressions
=> New_List
(
2282 Make_Attribute_Reference
(Loc
,
2284 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2287 New_Occurrence_Of
(Extra_Parameter
, Loc
))));
2291 Next
(Current_Parameter
);
2294 -- Append the formal statements list to the statements
2296 Append_List_To
(Statements
, Extra_Formal_Statements
);
2298 if not Is_Known_Non_Asynchronous
then
2300 -- Build the call to System.RPC.Do_APC
2302 Asynchronous_Statements
:= New_List
(
2303 Make_Procedure_Call_Statement
(Loc
,
2305 New_Occurrence_Of
(RTE
(RE_Do_Apc
), Loc
),
2306 Parameter_Associations
=> New_List
(
2307 New_Occurrence_Of
(Target_Partition
, Loc
),
2308 Make_Attribute_Reference
(Loc
,
2310 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2314 Asynchronous_Statements
:= No_List
;
2317 if not Is_Known_Asynchronous
then
2319 -- Build the call to System.RPC.Do_RPC
2321 Non_Asynchronous_Statements
:= New_List
(
2322 Make_Procedure_Call_Statement
(Loc
,
2324 New_Occurrence_Of
(RTE
(RE_Do_Rpc
), Loc
),
2325 Parameter_Associations
=> New_List
(
2326 New_Occurrence_Of
(Target_Partition
, Loc
),
2328 Make_Attribute_Reference
(Loc
,
2330 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2334 Make_Attribute_Reference
(Loc
,
2336 New_Occurrence_Of
(Result_Parameter
, Loc
),
2340 -- Read the exception occurrence from the result stream and
2341 -- reraise it. It does no harm if this is a Null_Occurrence since
2342 -- this does nothing.
2344 Append_To
(Non_Asynchronous_Statements
,
2345 Make_Attribute_Reference
(Loc
,
2347 New_Occurrence_Of
(RTE
(RE_Exception_Occurrence
), Loc
),
2352 Expressions
=> New_List
(
2353 Make_Attribute_Reference
(Loc
,
2355 New_Occurrence_Of
(Result_Parameter
, Loc
),
2358 New_Occurrence_Of
(Exception_Return_Parameter
, Loc
))));
2360 Append_To
(Non_Asynchronous_Statements
,
2361 Make_Procedure_Call_Statement
(Loc
,
2363 New_Occurrence_Of
(RTE
(RE_Reraise_Occurrence
), Loc
),
2364 Parameter_Associations
=> New_List
(
2365 New_Occurrence_Of
(Exception_Return_Parameter
, Loc
))));
2369 -- If this is a function call, then read the value and return
2370 -- it. The return value is written/read using 'Output/'Input.
2372 Append_To
(Non_Asynchronous_Statements
,
2373 Make_Tag_Check
(Loc
,
2374 Make_Return_Statement
(Loc
,
2376 Make_Attribute_Reference
(Loc
,
2379 Etype
(Subtype_Mark
(Spec
)), Loc
),
2381 Attribute_Name
=> Name_Input
,
2383 Expressions
=> New_List
(
2384 Make_Attribute_Reference
(Loc
,
2386 New_Occurrence_Of
(Result_Parameter
, Loc
),
2387 Attribute_Name
=> Name_Access
))))));
2390 -- Loop around parameters and assign out (or in out) parameters.
2391 -- In the case of RACW, controlling arguments cannot possibly
2392 -- have changed since they are remote, so we do not read them
2395 Current_Parameter
:=
2396 First
(Ordered_Parameters_List
);
2398 while Current_Parameter
/= Empty
loop
2400 if Out_Present
(Current_Parameter
)
2402 Etype
(Parameter_Type
(Current_Parameter
)) /= Object_Type
2404 Append_To
(Non_Asynchronous_Statements
,
2405 Make_Attribute_Reference
(Loc
,
2408 Etype
(Parameter_Type
(Current_Parameter
)), Loc
),
2410 Attribute_Name
=> Name_Read
,
2412 Expressions
=> New_List
(
2413 Make_Attribute_Reference
(Loc
,
2415 New_Occurrence_Of
(Result_Parameter
, Loc
),
2419 Defining_Identifier
(Current_Parameter
), Loc
))));
2422 Next
(Current_Parameter
);
2427 if Is_Known_Asynchronous
then
2428 Append_List_To
(Statements
, Asynchronous_Statements
);
2430 elsif Is_Known_Non_Asynchronous
then
2431 Append_List_To
(Statements
, Non_Asynchronous_Statements
);
2434 pragma Assert
(Asynchronous
/= Empty
);
2435 Prepend_To
(Asynchronous_Statements
,
2436 Make_Attribute_Reference
(Loc
,
2437 Prefix
=> New_Occurrence_Of
(Standard_Boolean
, Loc
),
2438 Attribute_Name
=> Name_Write
,
2439 Expressions
=> New_List
(
2440 Make_Attribute_Reference
(Loc
,
2441 Prefix
=> New_Occurrence_Of
(Stream_Parameter
, Loc
),
2442 Attribute_Name
=> Name_Access
),
2443 New_Occurrence_Of
(Standard_True
, Loc
))));
2444 Prepend_To
(Non_Asynchronous_Statements
,
2445 Make_Attribute_Reference
(Loc
,
2446 Prefix
=> New_Occurrence_Of
(Standard_Boolean
, Loc
),
2447 Attribute_Name
=> Name_Write
,
2448 Expressions
=> New_List
(
2449 Make_Attribute_Reference
(Loc
,
2450 Prefix
=> New_Occurrence_Of
(Stream_Parameter
, Loc
),
2451 Attribute_Name
=> Name_Access
),
2452 New_Occurrence_Of
(Standard_False
, Loc
))));
2453 Append_To
(Statements
,
2454 Make_Implicit_If_Statement
(Nod
,
2455 Condition
=> Asynchronous
,
2456 Then_Statements
=> Asynchronous_Statements
,
2457 Else_Statements
=> Non_Asynchronous_Statements
));
2459 end Build_General_Calling_Stubs
;
2461 -----------------------------------
2462 -- Build_Ordered_Parameters_List --
2463 -----------------------------------
2465 function Build_Ordered_Parameters_List
(Spec
: Node_Id
) return List_Id
is
2466 Constrained_List
: List_Id
;
2467 Unconstrained_List
: List_Id
;
2468 Current_Parameter
: Node_Id
;
2471 if not Present
(Parameter_Specifications
(Spec
)) then
2475 Constrained_List
:= New_List
;
2476 Unconstrained_List
:= New_List
;
2478 -- Loop through the parameters and add them to the right list
2480 Current_Parameter
:= First
(Parameter_Specifications
(Spec
));
2481 while Current_Parameter
/= Empty
loop
2483 if Nkind
(Parameter_Type
(Current_Parameter
)) = N_Access_Definition
2485 Is_Constrained
(Etype
(Parameter_Type
(Current_Parameter
)))
2487 Is_Elementary_Type
(Etype
(Parameter_Type
(Current_Parameter
)))
2489 Append_To
(Constrained_List
, New_Copy
(Current_Parameter
));
2491 Append_To
(Unconstrained_List
, New_Copy
(Current_Parameter
));
2494 Next
(Current_Parameter
);
2497 -- Unconstrained parameters are returned first
2499 Append_List_To
(Unconstrained_List
, Constrained_List
);
2501 return Unconstrained_List
;
2503 end Build_Ordered_Parameters_List
;
2505 ----------------------------------
2506 -- Build_Passive_Partition_Stub --
2507 ----------------------------------
2509 procedure Build_Passive_Partition_Stub
(U
: Node_Id
) is
2513 Loc
: constant Source_Ptr
:= Sloc
(U
);
2514 Dist_OK
: Entity_Id
;
2517 -- Verify that the implementation supports distribution, by accessing
2518 -- a type defined in the proper version of system.rpc
2520 Dist_OK
:= RTE
(RE_Params_Stream_Type
);
2522 -- Use body if present, spec otherwise
2524 if Nkind
(U
) = N_Package_Declaration
then
2525 Pkg_Spec
:= Specification
(U
);
2526 L
:= Visible_Declarations
(Pkg_Spec
);
2528 Pkg_Spec
:= Parent
(Corresponding_Spec
(U
));
2529 L
:= Declarations
(U
);
2533 Make_Procedure_Call_Statement
(Loc
,
2535 New_Occurrence_Of
(RTE
(RE_Register_Passive_Package
), Loc
),
2536 Parameter_Associations
=> New_List
(
2537 Make_String_Literal
(Loc
, Get_Pkg_Name_String_Id
(Pkg_Spec
)),
2538 Make_Attribute_Reference
(Loc
,
2540 New_Occurrence_Of
(Defining_Entity
(Pkg_Spec
), Loc
),
2545 end Build_Passive_Partition_Stub
;
2547 ------------------------------------
2548 -- Build_Subprogram_Calling_Stubs --
2549 ------------------------------------
2551 function Build_Subprogram_Calling_Stubs
2552 (Vis_Decl
: Node_Id
;
2554 Asynchronous
: Boolean;
2555 Dynamically_Asynchronous
: Boolean := False;
2556 Stub_Type
: Entity_Id
:= Empty
;
2557 Locator
: Entity_Id
:= Empty
;
2558 New_Name
: Name_Id
:= No_Name
)
2561 Loc
: constant Source_Ptr
:= Sloc
(Vis_Decl
);
2563 Target_Partition
: Node_Id
;
2564 -- Contains the name of the target partition
2566 Decls
: constant List_Id
:= New_List
;
2567 Statements
: constant List_Id
:= New_List
;
2569 Subp_Spec
: Node_Id
;
2570 -- The specification of the body
2572 Controlling_Parameter
: Entity_Id
:= Empty
;
2573 RPC_Receiver
: Node_Id
;
2575 Asynchronous_Expr
: Node_Id
:= Empty
;
2577 RCI_Locator
: Entity_Id
;
2579 Spec_To_Use
: Node_Id
;
2581 procedure Insert_Partition_Check
(Parameter
: in Node_Id
);
2582 -- Check that the parameter has been elaborated on the same partition
2583 -- than the controlling parameter (E.4(19)).
2585 ----------------------------
2586 -- Insert_Partition_Check --
2587 ----------------------------
2589 procedure Insert_Partition_Check
(Parameter
: in Node_Id
) is
2590 Parameter_Entity
: constant Entity_Id
:=
2591 Defining_Identifier
(Parameter
);
2592 Designated_Object
: Node_Id
;
2593 Condition
: Node_Id
;
2596 -- The expression that will be built is of the form:
2597 -- if not (Parameter in Stub_Type and then
2598 -- Parameter.Origin = Controlling.Origin)
2600 -- raise Constraint_Error;
2603 -- Condition contains the reversed condition. Also, Parameter is
2604 -- dereferenced if it is an access type. We do not check that
2605 -- Parameter is in Stub_Type since such a check has been inserted
2606 -- at the point of call already (a tag check since we have multiple
2607 -- controlling operands).
2609 if Nkind
(Parameter_Type
(Parameter
)) = N_Access_Definition
then
2610 Designated_Object
:=
2611 Make_Explicit_Dereference
(Loc
,
2612 Prefix
=> New_Occurrence_Of
(Parameter_Entity
, Loc
));
2614 Designated_Object
:= New_Occurrence_Of
(Parameter_Entity
, Loc
);
2620 Make_Selected_Component
(Loc
,
2622 New_Occurrence_Of
(Parameter_Entity
, Loc
),
2624 Make_Identifier
(Loc
, Name_Origin
)),
2627 Make_Selected_Component
(Loc
,
2629 New_Occurrence_Of
(Controlling_Parameter
, Loc
),
2631 Make_Identifier
(Loc
, Name_Origin
)));
2634 Make_Raise_Constraint_Error
(Loc
,
2636 Make_Op_Not
(Loc
, Right_Opnd
=> Condition
),
2637 Reason
=> CE_Partition_Check_Failed
));
2638 end Insert_Partition_Check
;
2640 -- Start of processing for Build_Subprogram_Calling_Stubs
2644 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
2646 Subp_Spec
:= Copy_Specification
(Loc
,
2647 Spec
=> Specification
(Vis_Decl
),
2648 New_Name
=> New_Name
);
2650 if Locator
= Empty
then
2651 RCI_Locator
:= RCI_Cache
;
2652 Spec_To_Use
:= Specification
(Vis_Decl
);
2654 RCI_Locator
:= Locator
;
2655 Spec_To_Use
:= Subp_Spec
;
2658 -- Find a controlling argument if we have a stub type. Also check
2659 -- if this subprogram can be made asynchronous.
2661 if Stub_Type
/= Empty
2662 and then Present
(Parameter_Specifications
(Spec_To_Use
))
2665 Current_Parameter
: Node_Id
:=
2666 First
(Parameter_Specifications
2669 while Current_Parameter
/= Empty
loop
2672 Is_RACW_Controlling_Formal
(Current_Parameter
, Stub_Type
)
2674 if Controlling_Parameter
= Empty
then
2675 Controlling_Parameter
:=
2676 Defining_Identifier
(Current_Parameter
);
2678 Insert_Partition_Check
(Current_Parameter
);
2682 Next
(Current_Parameter
);
2687 if Stub_Type
/= Empty
then
2688 pragma Assert
(Controlling_Parameter
/= Empty
);
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_Selected_Component
(Loc
,
2700 New_Occurrence_Of
(Controlling_Parameter
, Loc
),
2702 Make_Identifier
(Loc
, Name_Origin
))));
2705 Make_Selected_Component
(Loc
,
2707 New_Occurrence_Of
(Controlling_Parameter
, Loc
),
2709 Make_Identifier
(Loc
, Name_Receiver
));
2713 Make_Object_Declaration
(Loc
,
2714 Defining_Identifier
=> Target_Partition
,
2715 Constant_Present
=> True,
2716 Object_Definition
=>
2717 New_Occurrence_Of
(RTE
(RE_Partition_ID
), Loc
),
2720 Make_Function_Call
(Loc
,
2721 Name
=> Make_Selected_Component
(Loc
,
2723 Make_Identifier
(Loc
, Chars
(RCI_Locator
)),
2725 Make_Identifier
(Loc
, Name_Get_Active_Partition_ID
)))));
2728 Make_Selected_Component
(Loc
,
2730 Make_Identifier
(Loc
, Chars
(RCI_Locator
)),
2732 Make_Identifier
(Loc
, Name_Get_RCI_Package_Receiver
));
2735 if Dynamically_Asynchronous
then
2736 Asynchronous_Expr
:=
2737 Make_Selected_Component
(Loc
,
2739 New_Occurrence_Of
(Controlling_Parameter
, Loc
),
2741 Make_Identifier
(Loc
, Name_Asynchronous
));
2744 Build_General_Calling_Stubs
2746 Statements
=> Statements
,
2747 Target_Partition
=> Target_Partition
,
2748 RPC_Receiver
=> RPC_Receiver
,
2749 Subprogram_Id
=> Make_Integer_Literal
(Loc
, Subp_Id
),
2750 Asynchronous
=> Asynchronous_Expr
,
2751 Is_Known_Asynchronous
=> Asynchronous
2752 and then not Dynamically_Asynchronous
,
2753 Is_Known_Non_Asynchronous
2755 and then not Dynamically_Asynchronous
,
2756 Is_Function
=> Nkind
(Spec_To_Use
) =
2757 N_Function_Specification
,
2758 Spec
=> Spec_To_Use
,
2759 Object_Type
=> Stub_Type
,
2762 RCI_Calling_Stubs_Table
.Set
2763 (Defining_Unit_Name
(Specification
(Vis_Decl
)),
2764 Defining_Unit_Name
(Spec_To_Use
));
2767 Make_Subprogram_Body
(Loc
,
2768 Specification
=> Subp_Spec
,
2769 Declarations
=> Decls
,
2770 Handled_Statement_Sequence
=>
2771 Make_Handled_Sequence_Of_Statements
(Loc
, Statements
));
2772 end Build_Subprogram_Calling_Stubs
;
2774 --------------------------------------
2775 -- Build_Subprogram_Receiving_Stubs --
2776 --------------------------------------
2778 function Build_Subprogram_Receiving_Stubs
2779 (Vis_Decl
: Node_Id
;
2780 Asynchronous
: Boolean;
2781 Dynamically_Asynchronous
: Boolean := False;
2782 Stub_Type
: Entity_Id
:= Empty
;
2783 RACW_Type
: Entity_Id
:= Empty
;
2784 Parent_Primitive
: Entity_Id
:= Empty
)
2787 Loc
: constant Source_Ptr
:= Sloc
(Vis_Decl
);
2789 Stream_Parameter
: Node_Id
;
2790 Result_Parameter
: Node_Id
;
2791 -- See explanations of those in Build_Subprogram_Calling_Stubs
2793 Decls
: List_Id
:= New_List
;
2794 -- All the parameters will get declared before calling the real
2795 -- subprograms. Also the out parameters will be declared.
2797 Statements
: List_Id
:= New_List
;
2799 Extra_Formal_Statements
: List_Id
:= New_List
;
2800 -- Statements concerning extra formal parameters
2802 After_Statements
: List_Id
:= New_List
;
2803 -- Statements to be executed after the subprogram call
2805 Inner_Decls
: List_Id
:= No_List
;
2806 -- In case of a function, the inner declarations are needed since
2807 -- the result may be unconstrained.
2809 Excep_Handler
: Node_Id
;
2810 Excep_Choice
: Entity_Id
;
2811 Excep_Code
: List_Id
;
2813 Parameter_List
: List_Id
:= New_List
;
2814 -- List of parameters to be passed to the subprogram.
2816 Current_Parameter
: Node_Id
;
2818 Ordered_Parameters_List
: constant List_Id
:=
2819 Build_Ordered_Parameters_List
(Specification
(Vis_Decl
));
2821 Subp_Spec
: Node_Id
;
2822 -- Subprogram specification
2824 Called_Subprogram
: Node_Id
;
2825 -- The subprogram to call
2827 Null_Raise_Statement
: Node_Id
;
2829 Dynamic_Async
: Entity_Id
;
2832 if RACW_Type
/= Empty
then
2833 Called_Subprogram
:=
2834 New_Occurrence_Of
(Parent_Primitive
, Loc
);
2836 Called_Subprogram
:=
2838 Defining_Unit_Name
(Specification
(Vis_Decl
)), Loc
);
2842 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
2844 if Dynamically_Asynchronous
then
2846 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
2848 Dynamic_Async
:= Empty
;
2851 if not Asynchronous
or else Dynamically_Asynchronous
then
2853 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S'));
2855 -- The first statement after the subprogram call is a statement to
2856 -- writes a Null_Occurrence into the result stream.
2858 Null_Raise_Statement
:=
2859 Make_Attribute_Reference
(Loc
,
2861 New_Occurrence_Of
(RTE
(RE_Exception_Occurrence
), Loc
),
2862 Attribute_Name
=> Name_Write
,
2863 Expressions
=> New_List
(
2864 New_Occurrence_Of
(Result_Parameter
, Loc
),
2865 New_Occurrence_Of
(RTE
(RE_Null_Occurrence
), Loc
)));
2867 if Dynamically_Asynchronous
then
2868 Null_Raise_Statement
:=
2869 Make_Implicit_If_Statement
(Vis_Decl
,
2871 Make_Op_Not
(Loc
, New_Occurrence_Of
(Dynamic_Async
, Loc
)),
2872 Then_Statements
=> New_List
(Null_Raise_Statement
));
2875 Append_To
(After_Statements
, Null_Raise_Statement
);
2878 Result_Parameter
:= Empty
;
2881 -- Loop through every parameter and get its value from the stream. If
2882 -- the parameter is unconstrained, then the parameter is read using
2883 -- 'Input at the point of declaration.
2885 Current_Parameter
:= First
(Ordered_Parameters_List
);
2887 while Current_Parameter
/= Empty
loop
2891 Constrained
: Boolean;
2893 Expr
: Node_Id
:= Empty
;
2896 Object
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
2897 Set_Ekind
(Object
, E_Variable
);
2900 Is_RACW_Controlling_Formal
(Current_Parameter
, Stub_Type
)
2902 -- We have a controlling formal parameter. Read its address
2903 -- rather than a real object. The address is in Unsigned_64
2906 Etyp
:= RTE
(RE_Unsigned_64
);
2908 Etyp
:= Etype
(Parameter_Type
(Current_Parameter
));
2912 Is_Constrained
(Etyp
) or else Is_Elementary_Type
(Etyp
);
2914 if In_Present
(Current_Parameter
)
2915 or else not Out_Present
(Current_Parameter
)
2916 or else not Constrained
2918 -- If an input parameter is contrained, then its reading is
2919 -- deferred until the beginning of the subprogram body. If
2920 -- it is unconstrained, then an expression is built for
2921 -- the object declaration and the variable is set using
2922 -- 'Input instead of 'Read.
2925 Append_To
(Statements
,
2926 Make_Attribute_Reference
(Loc
,
2927 Prefix
=> New_Occurrence_Of
(Etyp
, Loc
),
2928 Attribute_Name
=> Name_Read
,
2929 Expressions
=> New_List
(
2930 New_Occurrence_Of
(Stream_Parameter
, Loc
),
2931 New_Occurrence_Of
(Object
, Loc
))));
2934 Expr
:= Input_With_Tag_Check
(Loc
,
2936 Stream
=> Stream_Parameter
);
2937 Append_To
(Decls
, Expr
);
2938 Expr
:= Make_Function_Call
(Loc
,
2939 New_Occurrence_Of
(Defining_Unit_Name
2940 (Specification
(Expr
)), Loc
));
2944 -- If we do not have to output the current parameter, then
2945 -- it can well be flagged as constant. This may allow further
2946 -- optimizations done by the back end.
2949 Make_Object_Declaration
(Loc
,
2950 Defining_Identifier
=> Object
,
2952 not Constrained
and then not Out_Present
(Current_Parameter
),
2953 Object_Definition
=>
2954 New_Occurrence_Of
(Etyp
, Loc
),
2955 Expression
=> Expr
));
2957 -- An out parameter may be written back using a 'Write
2958 -- attribute instead of a 'Output because it has been
2959 -- constrained by the parameter given to the caller. Note that
2960 -- out controlling arguments in the case of a RACW are not put
2961 -- back in the stream because the pointer on them has not
2964 if Out_Present
(Current_Parameter
)
2966 Etype
(Parameter_Type
(Current_Parameter
)) /= Stub_Type
2968 Append_To
(After_Statements
,
2969 Make_Attribute_Reference
(Loc
,
2970 Prefix
=> New_Occurrence_Of
(Etyp
, Loc
),
2971 Attribute_Name
=> Name_Write
,
2972 Expressions
=> New_List
(
2973 New_Occurrence_Of
(Result_Parameter
, Loc
),
2974 New_Occurrence_Of
(Object
, Loc
))));
2978 Is_RACW_Controlling_Formal
(Current_Parameter
, Stub_Type
)
2981 if Nkind
(Parameter_Type
(Current_Parameter
)) /=
2984 Append_To
(Parameter_List
,
2985 Make_Parameter_Association
(Loc
,
2988 Defining_Identifier
(Current_Parameter
), Loc
),
2989 Explicit_Actual_Parameter
=>
2990 Make_Explicit_Dereference
(Loc
,
2991 Unchecked_Convert_To
(RACW_Type
,
2992 OK_Convert_To
(RTE
(RE_Address
),
2993 New_Occurrence_Of
(Object
, Loc
))))));
2995 Append_To
(Parameter_List
,
2996 Make_Parameter_Association
(Loc
,
2999 Defining_Identifier
(Current_Parameter
), Loc
),
3000 Explicit_Actual_Parameter
=>
3001 Unchecked_Convert_To
(RACW_Type
,
3002 OK_Convert_To
(RTE
(RE_Address
),
3003 New_Occurrence_Of
(Object
, Loc
)))));
3006 Append_To
(Parameter_List
,
3007 Make_Parameter_Association
(Loc
,
3010 Defining_Identifier
(Current_Parameter
), Loc
),
3011 Explicit_Actual_Parameter
=>
3012 New_Occurrence_Of
(Object
, Loc
)));
3015 -- If the current parameter needs an extra formal, then read it
3016 -- from the stream and set the corresponding semantic field in
3017 -- the variable. If the kind of the parameter identifier is
3018 -- E_Void, then this is a compiler generated parameter that
3019 -- doesn't need an extra constrained status.
3021 -- The case of Extra_Accessibility should also be handled ???
3023 if Nkind
(Parameter_Type
(Current_Parameter
)) /=
3026 Ekind
(Defining_Identifier
(Current_Parameter
)) /= E_Void
3028 Present
(Extra_Constrained
3029 (Defining_Identifier
(Current_Parameter
)))
3032 Extra_Parameter
: constant Entity_Id
:=
3034 (Defining_Identifier
3035 (Current_Parameter
));
3037 Formal_Entity
: constant Entity_Id
:=
3038 Make_Defining_Identifier
3039 (Loc
, Chars
(Extra_Parameter
));
3041 Formal_Type
: constant Entity_Id
:=
3042 Etype
(Extra_Parameter
);
3046 Make_Object_Declaration
(Loc
,
3047 Defining_Identifier
=> Formal_Entity
,
3048 Object_Definition
=>
3049 New_Occurrence_Of
(Formal_Type
, Loc
)));
3051 Append_To
(Extra_Formal_Statements
,
3052 Make_Attribute_Reference
(Loc
,
3053 Prefix
=> New_Occurrence_Of
(Formal_Type
, Loc
),
3054 Attribute_Name
=> Name_Read
,
3055 Expressions
=> New_List
(
3056 New_Occurrence_Of
(Stream_Parameter
, Loc
),
3057 New_Occurrence_Of
(Formal_Entity
, Loc
))));
3058 Set_Extra_Constrained
(Object
, Formal_Entity
);
3063 Next
(Current_Parameter
);
3066 -- Append the formal statements list at the end of regular statements
3068 Append_List_To
(Statements
, Extra_Formal_Statements
);
3070 if Nkind
(Specification
(Vis_Decl
)) = N_Function_Specification
then
3072 -- The remote subprogram is a function. We build an inner block to
3073 -- be able to hold a potentially unconstrained result in a variable.
3076 Etyp
: constant Entity_Id
:=
3077 Etype
(Subtype_Mark
(Specification
(Vis_Decl
)));
3078 Result
: constant Node_Id
:=
3079 Make_Defining_Identifier
(Loc
, New_Internal_Name
('R'));
3082 Inner_Decls
:= New_List
(
3083 Make_Object_Declaration
(Loc
,
3084 Defining_Identifier
=> Result
,
3085 Constant_Present
=> True,
3086 Object_Definition
=> New_Occurrence_Of
(Etyp
, Loc
),
3088 Make_Function_Call
(Loc
,
3089 Name
=> Called_Subprogram
,
3090 Parameter_Associations
=> Parameter_List
)));
3092 Append_To
(After_Statements
,
3093 Make_Attribute_Reference
(Loc
,
3094 Prefix
=> New_Occurrence_Of
(Etyp
, Loc
),
3095 Attribute_Name
=> Name_Output
,
3096 Expressions
=> New_List
(
3097 New_Occurrence_Of
(Result_Parameter
, Loc
),
3098 New_Occurrence_Of
(Result
, Loc
))));
3101 Append_To
(Statements
,
3102 Make_Block_Statement
(Loc
,
3103 Declarations
=> Inner_Decls
,
3104 Handled_Statement_Sequence
=>
3105 Make_Handled_Sequence_Of_Statements
(Loc
,
3106 Statements
=> After_Statements
)));
3109 -- The remote subprogram is a procedure. We do not need any inner
3110 -- block in this case.
3112 if Dynamically_Asynchronous
then
3114 Make_Object_Declaration
(Loc
,
3115 Defining_Identifier
=> Dynamic_Async
,
3116 Object_Definition
=>
3117 New_Occurrence_Of
(Standard_Boolean
, Loc
)));
3119 Append_To
(Statements
,
3120 Make_Attribute_Reference
(Loc
,
3121 Prefix
=> New_Occurrence_Of
(Standard_Boolean
, Loc
),
3122 Attribute_Name
=> Name_Read
,
3123 Expressions
=> New_List
(
3124 New_Occurrence_Of
(Stream_Parameter
, Loc
),
3125 New_Occurrence_Of
(Dynamic_Async
, Loc
))));
3128 Append_To
(Statements
,
3129 Make_Procedure_Call_Statement
(Loc
,
3130 Name
=> Called_Subprogram
,
3131 Parameter_Associations
=> Parameter_List
));
3133 Append_List_To
(Statements
, After_Statements
);
3137 if Asynchronous
and then not Dynamically_Asynchronous
then
3139 -- An asynchronous procedure does not want a Result
3140 -- parameter. Also, we put an exception handler with an others
3141 -- clause that does nothing.
3144 Make_Procedure_Specification
(Loc
,
3145 Defining_Unit_Name
=>
3146 Make_Defining_Identifier
(Loc
, New_Internal_Name
('F')),
3147 Parameter_Specifications
=> New_List
(
3148 Make_Parameter_Specification
(Loc
,
3149 Defining_Identifier
=> Stream_Parameter
,
3151 Make_Access_Definition
(Loc
,
3153 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
)))));
3156 Make_Exception_Handler
(Loc
,
3157 Exception_Choices
=>
3158 New_List
(Make_Others_Choice
(Loc
)),
3159 Statements
=> New_List
(
3160 Make_Null_Statement
(Loc
)));
3163 -- In the other cases, if an exception is raised, then the
3164 -- exception occurrence is copied into the output stream and
3165 -- no other output parameter is written.
3168 Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
3170 Excep_Code
:= New_List
(
3171 Make_Attribute_Reference
(Loc
,
3173 New_Occurrence_Of
(RTE
(RE_Exception_Occurrence
), Loc
),
3174 Attribute_Name
=> Name_Write
,
3175 Expressions
=> New_List
(
3176 New_Occurrence_Of
(Result_Parameter
, Loc
),
3177 New_Occurrence_Of
(Excep_Choice
, Loc
))));
3179 if Dynamically_Asynchronous
then
3180 Excep_Code
:= New_List
(
3181 Make_Implicit_If_Statement
(Vis_Decl
,
3182 Condition
=> Make_Op_Not
(Loc
,
3183 New_Occurrence_Of
(Dynamic_Async
, Loc
)),
3184 Then_Statements
=> Excep_Code
));
3188 Make_Exception_Handler
(Loc
,
3189 Choice_Parameter
=> Excep_Choice
,
3190 Exception_Choices
=> New_List
(Make_Others_Choice
(Loc
)),
3191 Statements
=> Excep_Code
);
3194 Make_Procedure_Specification
(Loc
,
3195 Defining_Unit_Name
=>
3196 Make_Defining_Identifier
(Loc
, New_Internal_Name
('F')),
3198 Parameter_Specifications
=> New_List
(
3199 Make_Parameter_Specification
(Loc
,
3200 Defining_Identifier
=> Stream_Parameter
,
3202 Make_Access_Definition
(Loc
,
3204 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
))),
3206 Make_Parameter_Specification
(Loc
,
3207 Defining_Identifier
=> Result_Parameter
,
3209 Make_Access_Definition
(Loc
,
3211 New_Occurrence_Of
(RTE
(RE_Params_Stream_Type
), Loc
)))));
3215 Make_Subprogram_Body
(Loc
,
3216 Specification
=> Subp_Spec
,
3217 Declarations
=> Decls
,
3218 Handled_Statement_Sequence
=>
3219 Make_Handled_Sequence_Of_Statements
(Loc
,
3220 Statements
=> Statements
,
3221 Exception_Handlers
=> New_List
(Excep_Handler
)));
3223 end Build_Subprogram_Receiving_Stubs
;
3225 ------------------------
3226 -- Copy_Specification --
3227 ------------------------
3229 function Copy_Specification
3232 Object_Type
: Entity_Id
:= Empty
;
3233 Stub_Type
: Entity_Id
:= Empty
;
3234 New_Name
: Name_Id
:= No_Name
)
3237 Parameters
: List_Id
:= No_List
;
3239 Current_Parameter
: Node_Id
;
3240 Current_Type
: Node_Id
;
3242 Name_For_New_Spec
: Name_Id
;
3244 New_Identifier
: Entity_Id
;
3247 if New_Name
= No_Name
then
3248 Name_For_New_Spec
:= Chars
(Defining_Unit_Name
(Spec
));
3250 Name_For_New_Spec
:= New_Name
;
3253 if Present
(Parameter_Specifications
(Spec
)) then
3255 Parameters
:= New_List
;
3256 Current_Parameter
:= First
(Parameter_Specifications
(Spec
));
3258 while Current_Parameter
/= Empty
loop
3260 Current_Type
:= Parameter_Type
(Current_Parameter
);
3262 if Nkind
(Current_Type
) = N_Access_Definition
then
3263 if Object_Type
= Empty
then
3265 Make_Access_Definition
(Loc
,
3267 New_Occurrence_Of
(Etype
(
3268 Subtype_Mark
(Current_Type
)), Loc
));
3271 (Root_Type
(Etype
(Subtype_Mark
(Current_Type
)))
3272 = Root_Type
(Object_Type
));
3274 Make_Access_Definition
(Loc
,
3275 Subtype_Mark
=> New_Occurrence_Of
(Stub_Type
, Loc
));
3278 elsif Object_Type
/= Empty
3279 and then Etype
(Current_Type
) = Object_Type
3281 Current_Type
:= New_Occurrence_Of
(Stub_Type
, Loc
);
3284 Current_Type
:= New_Occurrence_Of
(Etype
(Current_Type
), Loc
);
3287 New_Identifier
:= Make_Defining_Identifier
(Loc
,
3288 Chars
(Defining_Identifier
(Current_Parameter
)));
3290 Append_To
(Parameters
,
3291 Make_Parameter_Specification
(Loc
,
3292 Defining_Identifier
=> New_Identifier
,
3293 Parameter_Type
=> Current_Type
,
3294 In_Present
=> In_Present
(Current_Parameter
),
3295 Out_Present
=> Out_Present
(Current_Parameter
),
3297 New_Copy_Tree
(Expression
(Current_Parameter
))));
3299 Next
(Current_Parameter
);
3303 if Nkind
(Spec
) = N_Function_Specification
then
3305 Make_Function_Specification
(Loc
,
3306 Defining_Unit_Name
=>
3307 Make_Defining_Identifier
(Loc
,
3308 Chars
=> Name_For_New_Spec
),
3309 Parameter_Specifications
=> Parameters
,
3311 New_Occurrence_Of
(Etype
(Subtype_Mark
(Spec
)), Loc
));
3315 Make_Procedure_Specification
(Loc
,
3316 Defining_Unit_Name
=>
3317 Make_Defining_Identifier
(Loc
,
3318 Chars
=> Name_For_New_Spec
),
3319 Parameter_Specifications
=> Parameters
);
3322 end Copy_Specification
;
3324 ---------------------------
3325 -- Could_Be_Asynchronous --
3326 ---------------------------
3328 function Could_Be_Asynchronous
(Spec
: Node_Id
) return Boolean is
3329 Current_Parameter
: Node_Id
;
3332 if Present
(Parameter_Specifications
(Spec
)) then
3333 Current_Parameter
:= First
(Parameter_Specifications
(Spec
));
3334 while Current_Parameter
/= Empty
loop
3335 if Out_Present
(Current_Parameter
) then
3339 Next
(Current_Parameter
);
3344 end Could_Be_Asynchronous
;
3346 ---------------------------------------------
3347 -- Expand_All_Calls_Remote_Subprogram_Call --
3348 ---------------------------------------------
3350 procedure Expand_All_Calls_Remote_Subprogram_Call
(N
: in Node_Id
) is
3351 Called_Subprogram
: constant Entity_Id
:= Entity
(Name
(N
));
3352 RCI_Package
: constant Entity_Id
:= Scope
(Called_Subprogram
);
3353 Loc
: constant Source_Ptr
:= Sloc
(N
);
3354 RCI_Locator
: Node_Id
;
3355 RCI_Cache
: Entity_Id
;
3356 Calling_Stubs
: Node_Id
;
3357 E_Calling_Stubs
: Entity_Id
;
3360 E_Calling_Stubs
:= RCI_Calling_Stubs_Table
.Get
(Called_Subprogram
);
3362 if E_Calling_Stubs
= Empty
then
3363 RCI_Cache
:= RCI_Locator_Table
.Get
(RCI_Package
);
3365 if RCI_Cache
= Empty
then
3368 (Loc
, Specification
(Unit_Declaration_Node
(RCI_Package
)));
3369 Prepend_To
(Current_Sem_Unit_Declarations
, RCI_Locator
);
3371 -- The RCI_Locator package is inserted at the top level in the
3372 -- current unit, and must appear in the proper scope, so that it
3373 -- is not prematurely removed by the GCC back-end.
3376 Scop
: Entity_Id
:= Cunit_Entity
(Current_Sem_Unit
);
3379 if Ekind
(Scop
) = E_Package_Body
then
3380 New_Scope
(Spec_Entity
(Scop
));
3382 elsif Ekind
(Scop
) = E_Subprogram_Body
then
3384 (Corresponding_Spec
(Unit_Declaration_Node
(Scop
)));
3390 Analyze
(RCI_Locator
);
3394 RCI_Cache
:= Defining_Unit_Name
(RCI_Locator
);
3397 RCI_Locator
:= Parent
(RCI_Cache
);
3400 Calling_Stubs
:= Build_Subprogram_Calling_Stubs
3401 (Vis_Decl
=> Parent
(Parent
(Called_Subprogram
)),
3402 Subp_Id
=> Get_Subprogram_Id
(Called_Subprogram
),
3403 Asynchronous
=> Nkind
(N
) = N_Procedure_Call_Statement
3405 Is_Asynchronous
(Called_Subprogram
),
3406 Locator
=> RCI_Cache
,
3407 New_Name
=> New_Internal_Name
('S'));
3408 Insert_After
(RCI_Locator
, Calling_Stubs
);
3409 Analyze
(Calling_Stubs
);
3410 E_Calling_Stubs
:= Defining_Unit_Name
(Specification
(Calling_Stubs
));
3413 Rewrite
(Name
(N
), New_Occurrence_Of
(E_Calling_Stubs
, Loc
));
3414 end Expand_All_Calls_Remote_Subprogram_Call
;
3416 ---------------------------------
3417 -- Expand_Calling_Stubs_Bodies --
3418 ---------------------------------
3420 procedure Expand_Calling_Stubs_Bodies
(Unit_Node
: in Node_Id
) is
3421 Spec
: constant Node_Id
:= Specification
(Unit_Node
);
3422 Decls
: constant List_Id
:= Visible_Declarations
(Spec
);
3425 New_Scope
(Scope_Of_Spec
(Spec
));
3426 Add_Calling_Stubs_To_Declarations
(Specification
(Unit_Node
),
3429 end Expand_Calling_Stubs_Bodies
;
3431 -----------------------------------
3432 -- Expand_Receiving_Stubs_Bodies --
3433 -----------------------------------
3435 procedure Expand_Receiving_Stubs_Bodies
(Unit_Node
: in Node_Id
) is
3441 if Nkind
(Unit_Node
) = N_Package_Declaration
then
3442 Spec
:= Specification
(Unit_Node
);
3443 Decls
:= Visible_Declarations
(Spec
);
3444 New_Scope
(Scope_Of_Spec
(Spec
));
3445 Add_Receiving_Stubs_To_Declarations
(Spec
, Decls
);
3449 Package_Specification_Of_Scope
(Corresponding_Spec
(Unit_Node
));
3450 Decls
:= Declarations
(Unit_Node
);
3451 New_Scope
(Scope_Of_Spec
(Unit_Node
));
3453 Add_Receiving_Stubs_To_Declarations
(Spec
, Temp
);
3454 Insert_List_Before
(First
(Decls
), Temp
);
3458 end Expand_Receiving_Stubs_Bodies
;
3460 ----------------------------
3461 -- Get_Pkg_Name_string_Id --
3462 ----------------------------
3464 function Get_Pkg_Name_String_Id
(Decl_Node
: Node_Id
) return String_Id
is
3465 Unit_Name_Id
: Unit_Name_Type
:= Get_Unit_Name
(Decl_Node
);
3468 Get_Unit_Name_String
(Unit_Name_Id
);
3470 -- Remove seven last character (" (spec)" or " (body)").
3472 Name_Len
:= Name_Len
- 7;
3473 pragma Assert
(Name_Buffer
(Name_Len
+ 1) = ' ');
3475 return Get_String_Id
(Name_Buffer
(1 .. Name_Len
));
3476 end Get_Pkg_Name_String_Id
;
3482 function Get_String_Id
(Val
: String) return String_Id
is
3485 Store_String_Chars
(Val
);
3493 function Hash
(F
: Entity_Id
) return Hash_Index
is
3495 return Hash_Index
(Natural (F
) mod Positive (Hash_Index
'Last + 1));
3498 --------------------------
3499 -- Input_With_Tag_Check --
3500 --------------------------
3502 function Input_With_Tag_Check
3504 Var_Type
: Entity_Id
;
3510 Make_Subprogram_Body
(Loc
,
3511 Specification
=> Make_Function_Specification
(Loc
,
3512 Defining_Unit_Name
=>
3513 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S')),
3514 Subtype_Mark
=> New_Occurrence_Of
(Var_Type
, Loc
)),
3515 Declarations
=> No_List
,
3516 Handled_Statement_Sequence
=>
3517 Make_Handled_Sequence_Of_Statements
(Loc
, New_List
(
3518 Make_Tag_Check
(Loc
,
3519 Make_Return_Statement
(Loc
,
3520 Make_Attribute_Reference
(Loc
,
3521 Prefix
=> New_Occurrence_Of
(Var_Type
, Loc
),
3522 Attribute_Name
=> Name_Input
,
3524 New_List
(New_Occurrence_Of
(Stream
, Loc
))))))));
3525 end Input_With_Tag_Check
;
3527 --------------------------------
3528 -- Is_RACW_Controlling_Formal --
3529 --------------------------------
3531 function Is_RACW_Controlling_Formal
3532 (Parameter
: Node_Id
;
3533 Stub_Type
: Entity_Id
)
3539 -- If the kind of the parameter is E_Void, then it is not a
3540 -- controlling formal (this can happen in the context of RAS).
3542 if Ekind
(Defining_Identifier
(Parameter
)) = E_Void
then
3546 -- If the parameter is not a controlling formal, then it cannot
3547 -- be possibly a RACW_Controlling_Formal.
3549 if not Is_Controlling_Formal
(Defining_Identifier
(Parameter
)) then
3553 Typ
:= Parameter_Type
(Parameter
);
3554 return (Nkind
(Typ
) = N_Access_Definition
3555 and then Etype
(Subtype_Mark
(Typ
)) = Stub_Type
)
3556 or else Etype
(Typ
) = Stub_Type
;
3557 end Is_RACW_Controlling_Formal
;
3559 --------------------
3560 -- Make_Tag_Check --
3561 --------------------
3563 function Make_Tag_Check
(Loc
: Source_Ptr
; N
: Node_Id
) return Node_Id
is
3564 Occ
: constant Entity_Id
:=
3565 Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
3568 return Make_Block_Statement
(Loc
,
3569 Handled_Statement_Sequence
=>
3570 Make_Handled_Sequence_Of_Statements
(Loc
,
3571 Statements
=> New_List
(N
),
3573 Exception_Handlers
=> New_List
(
3574 Make_Exception_Handler
(Loc
,
3575 Choice_Parameter
=> Occ
,
3577 Exception_Choices
=>
3578 New_List
(New_Occurrence_Of
(RTE
(RE_Tag_Error
), Loc
)),
3581 New_List
(Make_Procedure_Call_Statement
(Loc
,
3583 (RTE
(RE_Raise_Program_Error_Unknown_Tag
), Loc
),
3584 New_List
(New_Occurrence_Of
(Occ
, Loc
))))))));
3587 ----------------------------
3588 -- Need_Extra_Constrained --
3589 ----------------------------
3591 function Need_Extra_Constrained
(Parameter
: Node_Id
) return Boolean is
3592 Etyp
: constant Entity_Id
:= Etype
(Parameter_Type
(Parameter
));
3595 return Out_Present
(Parameter
)
3596 and then Has_Discriminants
(Etyp
)
3597 and then not Is_Constrained
(Etyp
)
3598 and then not Is_Indefinite_Subtype
(Etyp
);
3599 end Need_Extra_Constrained
;
3601 ------------------------------------
3602 -- Pack_Entity_Into_Stream_Access --
3603 ------------------------------------
3605 function Pack_Entity_Into_Stream_Access
3609 Etyp
: Entity_Id
:= Empty
)
3615 if Etyp
/= Empty
then
3618 Typ
:= Etype
(Object
);
3622 Pack_Node_Into_Stream_Access
(Loc
,
3624 Object
=> New_Occurrence_Of
(Object
, Loc
),
3626 end Pack_Entity_Into_Stream_Access
;
3628 ---------------------------
3629 -- Pack_Node_Into_Stream --
3630 ---------------------------
3632 function Pack_Node_Into_Stream
3639 Write_Attribute
: Name_Id
:= Name_Write
;
3642 if not Is_Constrained
(Etyp
) then
3643 Write_Attribute
:= Name_Output
;
3647 Make_Attribute_Reference
(Loc
,
3648 Prefix
=> New_Occurrence_Of
(Etyp
, Loc
),
3649 Attribute_Name
=> Write_Attribute
,
3650 Expressions
=> New_List
(
3651 Make_Attribute_Reference
(Loc
,
3652 Prefix
=> New_Occurrence_Of
(Stream
, Loc
),
3653 Attribute_Name
=> Name_Access
),
3655 end Pack_Node_Into_Stream
;
3657 ----------------------------------
3658 -- Pack_Node_Into_Stream_Access --
3659 ----------------------------------
3661 function Pack_Node_Into_Stream_Access
3668 Write_Attribute
: Name_Id
:= Name_Write
;
3671 if not Is_Constrained
(Etyp
) then
3672 Write_Attribute
:= Name_Output
;
3676 Make_Attribute_Reference
(Loc
,
3677 Prefix
=> New_Occurrence_Of
(Etyp
, Loc
),
3678 Attribute_Name
=> Write_Attribute
,
3679 Expressions
=> New_List
(
3680 New_Occurrence_Of
(Stream
, Loc
),
3682 end Pack_Node_Into_Stream_Access
;
3684 -------------------------------
3685 -- RACW_Type_Is_Asynchronous --
3686 -------------------------------
3688 procedure RACW_Type_Is_Asynchronous
(RACW_Type
: in Entity_Id
) is
3689 N
: constant Node_Id
:= Asynchronous_Flags_Table
.Get
(RACW_Type
);
3690 pragma Assert
(N
/= Empty
);
3693 Replace
(N
, New_Occurrence_Of
(Standard_True
, Sloc
(N
)));
3694 end RACW_Type_Is_Asynchronous
;
3696 -------------------------
3697 -- RCI_Package_Locator --
3698 -------------------------
3700 function RCI_Package_Locator
3702 Package_Spec
: Node_Id
)
3705 Inst
: constant Node_Id
:=
3706 Make_Package_Instantiation
(Loc
,
3707 Defining_Unit_Name
=>
3708 Make_Defining_Identifier
(Loc
, New_Internal_Name
('R')),
3710 New_Occurrence_Of
(RTE
(RE_RCI_Info
), Loc
),
3711 Generic_Associations
=> New_List
(
3712 Make_Generic_Association
(Loc
,
3714 Make_Identifier
(Loc
, Name_RCI_Name
),
3715 Explicit_Generic_Actual_Parameter
=>
3716 Make_String_Literal
(Loc
,
3717 Strval
=> Get_Pkg_Name_String_Id
(Package_Spec
)))));
3720 RCI_Locator_Table
.Set
(Defining_Unit_Name
(Package_Spec
),
3721 Defining_Unit_Name
(Inst
));
3723 end RCI_Package_Locator
;
3725 -----------------------------------------------
3726 -- Remote_Types_Tagged_Full_View_Encountered --
3727 -----------------------------------------------
3729 procedure Remote_Types_Tagged_Full_View_Encountered
3730 (Full_View
: in Entity_Id
)
3732 Stub_Elements
: constant Stub_Structure
:=
3733 Stubs_Table
.Get
(Full_View
);
3736 if Stub_Elements
/= Empty_Stub_Structure
then
3737 Add_RACW_Primitive_Declarations_And_Bodies
3739 Parent
(Declaration_Node
(Stub_Elements
.Object_RPC_Receiver
)),
3740 List_Containing
(Declaration_Node
(Full_View
)));
3742 end Remote_Types_Tagged_Full_View_Encountered
;
3748 function Scope_Of_Spec
(Spec
: Node_Id
) return Entity_Id
is
3749 Unit_Name
: Node_Id
:= Defining_Unit_Name
(Spec
);
3752 while Nkind
(Unit_Name
) /= N_Defining_Identifier
loop
3753 Unit_Name
:= Defining_Identifier
(Unit_Name
);