1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Einfo; use Einfo;
29 with Elists; use Elists;
30 with Exp_Strm; use Exp_Strm;
31 with Exp_Tss; use Exp_Tss;
32 with Exp_Util; use Exp_Util;
33 with GNAT.HTable; use GNAT.HTable;
35 with Namet; use Namet;
36 with Nlists; use Nlists;
37 with Nmake; use Nmake;
39 with Rtsfind; use Rtsfind;
41 with Sem_Ch3; use Sem_Ch3;
42 with Sem_Ch8; use Sem_Ch8;
43 with Sem_Dist; use Sem_Dist;
44 with Sem_Util; use Sem_Util;
45 with Sinfo; use Sinfo;
46 with Snames; use Snames;
47 with Stand; use Stand;
48 with Stringt; use Stringt;
49 with Tbuild; use Tbuild;
50 with Uintp; use Uintp;
51 with Uname; use Uname;
53 package body Exp_Dist is
55 -- The following model has been used to implement distributed objects:
56 -- given a designated type D and a RACW type R, then a record of the
59 -- type Stub is tagged record
60 -- [...declaration similar to s-parint.ads RACW_Stub_Type...]
63 -- is built. This type has two properties:
65 -- 1) Since it has the same structure than RACW_Stub_Type, it can be
66 -- converted to and from this type to make it suitable for
67 -- System.Partition_Interface.Get_Unique_Remote_Pointer in order
68 -- to avoid memory leaks when the same remote object arrive on the
69 -- same partition by following different pathes
71 -- 2) It also has the same dispatching table as the designated type D,
72 -- and thus can be used as an object designated by a value of type
73 -- R on any partition other than the one on which the object has
74 -- been created, since only dispatching calls will be performed and
75 -- the fields themselves will not be used. We call Derive_Subprograms
76 -- to fake half a derivation to ensure that the subprograms do have
77 -- the same dispatching table.
79 -----------------------
80 -- Local subprograms --
81 -----------------------
83 function Get_Subprogram_Id (E : Entity_Id) return Int;
84 -- Given a subprogram defined in a RCI package, get its subprogram id
85 -- which will be used for remote calls.
87 procedure Build_General_Calling_Stubs
89 Statements : in List_Id;
90 Target_Partition : in Entity_Id;
91 RPC_Receiver : in Node_Id;
92 Subprogram_Id : in Node_Id;
93 Asynchronous : in Node_Id := Empty;
94 Is_Known_Asynchronous : in Boolean := False;
95 Is_Known_Non_Asynchronous : in Boolean := False;
96 Is_Function : in Boolean;
98 Object_Type : in Entity_Id := Empty;
100 -- Build calling stubs for general purpose. The parameters are:
101 -- Decls : a place to put declarations
102 -- Statements : a place to put statements
103 -- Target_Partition : a node containing the target partition that must
104 -- be a N_Defining_Identifier
105 -- RPC_Receiver : a node containing the RPC receiver
106 -- Subprogram_Id : a node containing the subprogram ID
107 -- Asynchronous : True if an APC must be made instead of an RPC.
108 -- The value needs not be supplied if one of the
109 -- Is_Known_... is True.
110 -- Is_Known_Async... : True if we know that this is asynchronous
111 -- Is_Known_Non_A... : True if we know that this is not asynchronous
112 -- Spec : a node with a Parameter_Specifications and
113 -- a Subtype_Mark if applicable
114 -- Object_Type : in case of a RACW, parameters of type access to
115 -- Object_Type will be marshalled using the
116 -- address of this object (the addr field) rather
117 -- than using the 'Write on the object itself
118 -- Nod : used to provide sloc for generated code
120 function Build_Subprogram_Calling_Stubs
123 Asynchronous : Boolean;
124 Dynamically_Asynchronous : Boolean := False;
125 Stub_Type : Entity_Id := Empty;
126 Locator : Entity_Id := Empty;
127 New_Name : Name_Id := No_Name)
129 -- Build the calling stub for a given subprogram with the subprogram ID
130 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
131 -- parameters of this type will be marshalled instead of the object
132 -- itself. It will then be converted into Stub_Type before performing
133 -- the real call. If Dynamically_Asynchronous is True, then it will be
134 -- computed at run time whether the call is asynchronous or not.
135 -- Otherwise, the value of the formal Asynchronous will be used.
136 -- If Locator is not Empty, it will be used instead of RCI_Cache. If
137 -- New_Name is given, then it will be used instead of the original name.
139 function Build_Subprogram_Receiving_Stubs
141 Asynchronous : Boolean;
142 Dynamically_Asynchronous : Boolean := False;
143 Stub_Type : Entity_Id := Empty;
144 RACW_Type : Entity_Id := Empty;
145 Parent_Primitive : Entity_Id := Empty)
147 -- Build the receiving stub for a given subprogram. The subprogram
148 -- declaration is also built by this procedure, and the value returned
149 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
150 -- found in the specification, then its address is read from the stream
151 -- instead of the object itself and converted into an access to
152 -- class-wide type before doing the real call using any of the RACW type
153 -- pointing on the designated type.
155 function Build_RPC_Receiver_Specification
156 (RPC_Receiver : Entity_Id;
157 Stream_Parameter : Entity_Id;
158 Result_Parameter : Entity_Id)
160 -- Make a subprogram specification for an RPC receiver,
161 -- with the given defining unit name and formal parameters.
163 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
164 -- Return an ordered parameter list: unconstrained parameters are put
165 -- at the beginning of the list and constrained ones are put after. If
166 -- there are no parameters, an empty list is returned.
168 procedure Add_Calling_Stubs_To_Declarations
169 (Pkg_Spec : in Node_Id;
171 -- Add calling stubs to the declarative part
173 procedure Add_Receiving_Stubs_To_Declarations
174 (Pkg_Spec : in Node_Id;
176 -- Add receiving stubs to the declarative part
178 procedure Add_RAS_Dereference_Attribute (N : in Node_Id);
179 -- Add a subprogram body for RAS dereference
181 procedure Add_RAS_Access_Attribute (N : in Node_Id);
182 -- Add a subprogram body for RAS Access attribute
184 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
185 -- Return True if nothing prevents the program whose specification is
186 -- given to be asynchronous (i.e. no out parameter).
188 function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id;
189 function Get_String_Id (Val : String) return String_Id;
190 -- Ugly functions used to retrieve a package name. Inherited from the
191 -- old exp_dist.adb and not rewritten yet ???
193 function Pack_Entity_Into_Stream_Access
197 Etyp : Entity_Id := Empty)
199 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
200 -- then Etype (Object) will be used if present. If the type is
201 -- constrained, then 'Write will be used to output the object,
202 -- If the type is unconstrained, 'Output will be used.
204 function Pack_Node_Into_Stream
210 -- Similar to above, with an arbitrary node instead of an entity
212 function Pack_Node_Into_Stream_Access
218 -- Similar to above, with Stream instead of Stream'Access
220 function Copy_Specification
223 Object_Type : Entity_Id := Empty;
224 Stub_Type : Entity_Id := Empty;
225 New_Name : Name_Id := No_Name)
227 -- Build a specification from another one. If Object_Type is not Empty
228 -- and any access to Object_Type is found, then it is replaced by an
229 -- access to Stub_Type. If New_Name is given, then it will be used as
230 -- the name for the newly created spec.
232 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
233 -- Return the scope represented by a given spec
235 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
236 -- Return True if the current parameter needs an extra formal to reflect
237 -- its constrained status.
239 function Is_RACW_Controlling_Formal
240 (Parameter : Node_Id; Stub_Type : Entity_Id)
242 -- Return True if the current parameter is a controlling formal argument
243 -- of type Stub_Type or access to Stub_Type.
245 type Stub_Structure is record
246 Stub_Type : Entity_Id;
247 Stub_Type_Access : Entity_Id;
248 Object_RPC_Receiver : Entity_Id;
249 RPC_Receiver_Stream : Entity_Id;
250 RPC_Receiver_Result : Entity_Id;
251 RACW_Type : Entity_Id;
253 -- This structure is necessary because of the two phases analysis of
254 -- a RACW declaration occurring in the same Remote_Types package as the
255 -- designated type. RACW_Type is any of the RACW types pointing on this
256 -- designated type, it is used here to save an anonymous type creation
257 -- for each primitive operation.
259 Empty_Stub_Structure : constant Stub_Structure :=
260 (Empty, Empty, Empty, Empty, Empty, Empty);
262 type Hash_Index is range 0 .. 50;
263 function Hash (F : Entity_Id) return Hash_Index;
265 package Stubs_Table is
266 new Simple_HTable (Header_Num => Hash_Index,
267 Element => Stub_Structure,
268 No_Element => Empty_Stub_Structure,
272 -- Mapping between a RACW designated type and its stub type
274 package Asynchronous_Flags_Table is
275 new Simple_HTable (Header_Num => Hash_Index,
281 -- Mapping between a RACW type and the node holding the value True if
282 -- the RACW is asynchronous and False otherwise.
284 package RCI_Locator_Table is
285 new Simple_HTable (Header_Num => Hash_Index,
286 Element => Entity_Id,
291 -- Mapping between a RCI package on which All_Calls_Remote applies and
292 -- the generic instantiation of RCI_Info for this package.
294 package RCI_Calling_Stubs_Table is
295 new Simple_HTable (Header_Num => Hash_Index,
296 Element => Entity_Id,
301 -- Mapping between a RCI subprogram and the corresponding calling stubs
303 procedure Add_Stub_Type
304 (Designated_Type : in Entity_Id;
305 RACW_Type : in Entity_Id;
307 Stub_Type : out Entity_Id;
308 Stub_Type_Access : out Entity_Id;
309 Object_RPC_Receiver : out Entity_Id;
310 Existing : out Boolean);
311 -- Add the declaration of the stub type, the access to stub type and the
312 -- object RPC receiver at the end of Decls. If these already exist,
313 -- then nothing is added in the tree but the right values are returned
314 -- anyhow and Existing is set to True.
316 procedure Add_RACW_Read_Attribute
317 (RACW_Type : in Entity_Id;
318 Stub_Type : in Entity_Id;
319 Stub_Type_Access : in Entity_Id;
320 Declarations : in List_Id);
321 -- Add Read attribute in Decls for the RACW type. The Read attribute
322 -- is added right after the RACW_Type declaration while the body is
323 -- inserted after Declarations.
325 procedure Add_RACW_Write_Attribute
326 (RACW_Type : in Entity_Id;
327 Stub_Type : in Entity_Id;
328 Stub_Type_Access : in Entity_Id;
329 Object_RPC_Receiver : in Entity_Id;
330 Declarations : in List_Id);
331 -- Same thing for the Write attribute
333 procedure Add_RACW_Read_Write_Attributes
334 (RACW_Type : in Entity_Id;
335 Stub_Type : in Entity_Id;
336 Stub_Type_Access : in Entity_Id;
337 Object_RPC_Receiver : in Entity_Id;
338 Declarations : in List_Id);
339 -- Add Read and Write attributes declarations and bodies for a given
340 -- RACW type. The declarations are added just after the declaration
341 -- of the RACW type itself, while the bodies are inserted at the end
344 function RCI_Package_Locator
346 Package_Spec : Node_Id)
348 -- Instantiate the generic package RCI_Info in order to locate the
349 -- RCI package whose spec is given as argument.
351 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
352 -- Surround a node N by a tag check, as in:
356 -- when E : Ada.Tags.Tag_Error =>
357 -- Raise_Exception (Program_Error'Identity,
358 -- Exception_Message (E));
361 function Input_With_Tag_Check
363 Var_Type : Entity_Id;
366 -- Return a function with the following form:
367 -- function R return Var_Type is
369 -- return Var_Type'Input (S);
371 -- when E : Ada.Tags.Tag_Error =>
372 -- Raise_Exception (Program_Error'Identity,
373 -- Exception_Message (E));
376 ------------------------------------
377 -- Local variables and structures --
378 ------------------------------------
382 Output_From_Constrained : constant array (Boolean) of Name_Id :=
383 (False => Name_Output,
385 -- The attribute to choose depending on the fact that the parameter
386 -- is constrained or not. There is no such thing as Input_From_Constrained
387 -- since this require separate mechanisms ('Input is a function while
388 -- 'Read is a procedure).
390 ---------------------------------------
391 -- Add_Calling_Stubs_To_Declarations --
392 ---------------------------------------
394 procedure Add_Calling_Stubs_To_Declarations
395 (Pkg_Spec : in Node_Id;
398 Current_Subprogram_Number : Int := 0;
399 Current_Declaration : Node_Id;
401 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
403 RCI_Instantiation : Node_Id;
405 Subp_Stubs : Node_Id;
408 -- The first thing added is an instantiation of the generic package
409 -- System.Partition_interface.RCI_Info with the name of the (current)
410 -- remote package. This will act as an interface with the name server
411 -- to determine the Partition_ID and the RPC_Receiver for the
412 -- receiver of this package.
414 RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
415 RCI_Cache := Defining_Unit_Name (RCI_Instantiation);
417 Append_To (Decls, RCI_Instantiation);
418 Analyze (RCI_Instantiation);
420 -- For each subprogram declaration visible in the spec, we do
421 -- build a body. We also increment a counter to assign a different
422 -- Subprogram_Id to each subprograms. The receiving stubs processing
423 -- do use the same mechanism and will thus assign the same Id and
424 -- do the correct dispatching.
426 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
428 while Current_Declaration /= Empty loop
430 if Nkind (Current_Declaration) = N_Subprogram_Declaration
431 and then Comes_From_Source (Current_Declaration)
433 pragma Assert (Current_Subprogram_Number =
434 Get_Subprogram_Id (Defining_Unit_Name (Specification (
435 Current_Declaration))));
438 Build_Subprogram_Calling_Stubs (
439 Vis_Decl => Current_Declaration,
440 Subp_Id => Current_Subprogram_Number,
442 Nkind (Specification (Current_Declaration)) =
443 N_Procedure_Specification
445 Is_Asynchronous (Defining_Unit_Name (Specification
446 (Current_Declaration))));
448 Append_To (Decls, Subp_Stubs);
449 Analyze (Subp_Stubs);
451 Current_Subprogram_Number := Current_Subprogram_Number + 1;
454 Next (Current_Declaration);
457 end Add_Calling_Stubs_To_Declarations;
459 -----------------------
460 -- Add_RACW_Features --
461 -----------------------
463 procedure Add_RACW_Features (RACW_Type : in Entity_Id)
465 Desig : constant Entity_Id :=
466 Etype (Designated_Type (RACW_Type));
468 List_Containing (Declaration_Node (RACW_Type));
470 Same_Scope : constant Boolean :=
471 Scope (Desig) = Scope (RACW_Type);
473 Stub_Type : Entity_Id;
474 Stub_Type_Access : Entity_Id;
475 Object_RPC_Receiver : Entity_Id;
479 if not Expander_Active then
485 -- We are declaring a RACW in the same package than its designated
486 -- type, so the list to use for late declarations must be the
487 -- private part of the package. We do know that this private part
488 -- exists since the designated type has to be a private one.
490 Decls := Private_Declarations
491 (Package_Specification_Of_Scope (Current_Scope));
493 elsif Nkind (Parent (Decls)) = N_Package_Specification
494 and then Present (Private_Declarations (Parent (Decls)))
496 Decls := Private_Declarations (Parent (Decls));
499 -- If we were unable to find the declarations, that means that the
500 -- completion of the type was missing. We can safely return and let
501 -- the error be caught by the semantic analysis.
508 (Designated_Type => Desig,
509 RACW_Type => RACW_Type,
511 Stub_Type => Stub_Type,
512 Stub_Type_Access => Stub_Type_Access,
513 Object_RPC_Receiver => Object_RPC_Receiver,
514 Existing => Existing);
516 Add_RACW_Read_Write_Attributes
517 (RACW_Type => RACW_Type,
518 Stub_Type => Stub_Type,
519 Stub_Type_Access => Stub_Type_Access,
520 Object_RPC_Receiver => Object_RPC_Receiver,
521 Declarations => Decls);
523 if not Same_Scope and then not Existing then
525 -- The RACW has been declared in another scope than the designated
526 -- type and has not been handled by another RACW in the same
527 -- package as the first one, so add primitive for the stub type
530 Add_RACW_Primitive_Declarations_And_Bodies
531 (Designated_Type => Desig,
533 Parent (Declaration_Node (Object_RPC_Receiver)),
537 Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
539 end Add_RACW_Features;
541 -------------------------------------------------
542 -- Add_RACW_Primitive_Declarations_And_Bodies --
543 -------------------------------------------------
545 procedure Add_RACW_Primitive_Declarations_And_Bodies
546 (Designated_Type : in Entity_Id;
547 Insertion_Node : in Node_Id;
550 -- Set sloc of generated declaration to be that of the
551 -- insertion node, so the declarations are recognized as
552 -- belonging to the current package.
554 Loc : constant Source_Ptr := Sloc (Insertion_Node);
556 Stub_Elements : constant Stub_Structure :=
557 Stubs_Table.Get (Designated_Type);
559 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
561 Current_Insertion_Node : Node_Id := Insertion_Node;
563 RPC_Receiver_Declarations : List_Id;
564 RPC_Receiver_Statements : List_Id;
565 RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
566 RPC_Receiver_Subp_Id : Entity_Id;
568 Current_Primitive_Elmt : Elmt_Id;
569 Current_Primitive : Entity_Id;
570 Current_Primitive_Body : Node_Id;
571 Current_Primitive_Spec : Node_Id;
572 Current_Primitive_Decl : Node_Id;
573 Current_Primitive_Number : Int := 0;
575 Current_Primitive_Alias : Node_Id;
577 Current_Receiver : Entity_Id;
578 Current_Receiver_Body : Node_Id;
580 RPC_Receiver_Decl : Node_Id;
582 Possibly_Asynchronous : Boolean;
585 if not Expander_Active then
589 -- Build callers, receivers for every primitive operations and a RPC
590 -- receiver for this type.
592 if Present (Primitive_Operations (Designated_Type)) then
594 Current_Primitive_Elmt :=
595 First_Elmt (Primitive_Operations (Designated_Type));
597 while Current_Primitive_Elmt /= No_Elmt loop
599 Current_Primitive := Node (Current_Primitive_Elmt);
601 -- Copy the primitive of all the parents, except predefined
602 -- ones that are not remotely dispatching.
604 if Chars (Current_Primitive) /= Name_uSize
605 and then Chars (Current_Primitive) /= Name_uAlignment
606 and then not Is_TSS (Current_Primitive, TSS_Deep_Finalize)
608 -- The first thing to do is build an up-to-date copy of
609 -- the spec with all the formals referencing Designated_Type
610 -- transformed into formals referencing Stub_Type. Since this
611 -- primitive may have been inherited, go back the alias chain
612 -- until the real primitive has been found.
614 Current_Primitive_Alias := Current_Primitive;
615 while Present (Alias (Current_Primitive_Alias)) loop
617 (Current_Primitive_Alias
618 /= Alias (Current_Primitive_Alias));
619 Current_Primitive_Alias := Alias (Current_Primitive_Alias);
622 Current_Primitive_Spec :=
623 Copy_Specification (Loc,
624 Spec => Parent (Current_Primitive_Alias),
625 Object_Type => Designated_Type,
626 Stub_Type => Stub_Elements.Stub_Type);
628 Current_Primitive_Decl :=
629 Make_Subprogram_Declaration (Loc,
630 Specification => Current_Primitive_Spec);
632 Insert_After (Current_Insertion_Node, Current_Primitive_Decl);
633 Analyze (Current_Primitive_Decl);
634 Current_Insertion_Node := Current_Primitive_Decl;
636 Possibly_Asynchronous :=
637 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
638 and then Could_Be_Asynchronous (Current_Primitive_Spec);
640 Current_Primitive_Body :=
641 Build_Subprogram_Calling_Stubs
642 (Vis_Decl => Current_Primitive_Decl,
643 Subp_Id => Current_Primitive_Number,
644 Asynchronous => Possibly_Asynchronous,
645 Dynamically_Asynchronous => Possibly_Asynchronous,
646 Stub_Type => Stub_Elements.Stub_Type);
647 Append_To (Decls, Current_Primitive_Body);
649 -- Analyzing the body here would cause the Stub type to be
650 -- frozen, thus preventing subsequent primitive declarations.
651 -- For this reason, it will be analyzed later in the
654 -- Build the receiver stubs
656 Current_Receiver_Body :=
657 Build_Subprogram_Receiving_Stubs
658 (Vis_Decl => Current_Primitive_Decl,
659 Asynchronous => Possibly_Asynchronous,
660 Dynamically_Asynchronous => Possibly_Asynchronous,
661 Stub_Type => Stub_Elements.Stub_Type,
662 RACW_Type => Stub_Elements.RACW_Type,
663 Parent_Primitive => Current_Primitive);
666 Defining_Unit_Name (Specification (Current_Receiver_Body));
668 Append_To (Decls, Current_Receiver_Body);
670 -- Add a case alternative to the receiver
672 Append_To (RPC_Receiver_Case_Alternatives,
673 Make_Case_Statement_Alternative (Loc,
674 Discrete_Choices => New_List (
675 Make_Integer_Literal (Loc, Current_Primitive_Number)),
677 Statements => New_List (
678 Make_Procedure_Call_Statement (Loc,
680 New_Occurrence_Of (Current_Receiver, Loc),
681 Parameter_Associations => New_List (
683 (Stub_Elements.RPC_Receiver_Stream, Loc),
685 (Stub_Elements.RPC_Receiver_Result, Loc))))));
687 -- Increment the index of current primitive
689 Current_Primitive_Number := Current_Primitive_Number + 1;
692 Next_Elmt (Current_Primitive_Elmt);
696 -- Build the case statement and the heart of the subprogram
698 Append_To (RPC_Receiver_Case_Alternatives,
699 Make_Case_Statement_Alternative (Loc,
700 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
701 Statements => New_List (Make_Null_Statement (Loc))));
703 RPC_Receiver_Subp_Id :=
704 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
706 RPC_Receiver_Declarations := New_List (
707 Make_Object_Declaration (Loc,
708 Defining_Identifier => RPC_Receiver_Subp_Id,
710 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
712 RPC_Receiver_Statements := New_List (
713 Make_Attribute_Reference (Loc,
715 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
718 Expressions => New_List (
719 New_Occurrence_Of (Stub_Elements.RPC_Receiver_Stream, Loc),
720 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc))));
722 Append_To (RPC_Receiver_Statements,
723 Make_Case_Statement (Loc,
725 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
726 Alternatives => RPC_Receiver_Case_Alternatives));
729 Make_Subprogram_Body (Loc,
731 Copy_Specification (Loc,
732 Parent (Stub_Elements.Object_RPC_Receiver)),
733 Declarations => RPC_Receiver_Declarations,
734 Handled_Statement_Sequence =>
735 Make_Handled_Sequence_Of_Statements (Loc,
736 Statements => RPC_Receiver_Statements));
738 Append_To (Decls, RPC_Receiver_Decl);
740 -- Do not analyze RPC receiver at this stage since it will otherwise
741 -- reference subprograms that have not been analyzed yet. It will
742 -- be analyzed in the regular flow.
744 end Add_RACW_Primitive_Declarations_And_Bodies;
746 -----------------------------
747 -- Add_RACW_Read_Attribute --
748 -----------------------------
750 procedure Add_RACW_Read_Attribute
751 (RACW_Type : in Entity_Id;
752 Stub_Type : in Entity_Id;
753 Stub_Type_Access : in Entity_Id;
754 Declarations : in List_Id)
756 Loc : constant Source_Ptr := Sloc (RACW_Type);
764 Statements : List_Id;
765 Local_Statements : List_Id;
766 Remote_Statements : List_Id;
767 -- Various parts of the procedure
769 Procedure_Name : constant Name_Id :=
770 New_Internal_Name ('R');
771 Source_Partition : constant Entity_Id :=
772 Make_Defining_Identifier
773 (Loc, New_Internal_Name ('P'));
774 Source_Receiver : constant Entity_Id :=
775 Make_Defining_Identifier
776 (Loc, New_Internal_Name ('S'));
777 Source_Address : constant Entity_Id :=
778 Make_Defining_Identifier
779 (Loc, New_Internal_Name ('P'));
780 Stubbed_Result : constant Entity_Id :=
781 Make_Defining_Identifier
782 (Loc, New_Internal_Name ('S'));
783 Asynchronous_Flag : constant Entity_Id :=
784 Make_Defining_Identifier
785 (Loc, New_Internal_Name ('S'));
786 Asynchronous_Node : constant Node_Id :=
787 New_Occurrence_Of (Standard_False, Loc);
789 -- Functions to create occurrences of the formal
792 function Stream_Parameter return Node_Id;
793 function Result return Node_Id;
795 function Stream_Parameter return Node_Id is
797 return Make_Identifier (Loc, Name_S);
798 end Stream_Parameter;
800 function Result return Node_Id is
802 return Make_Identifier (Loc, Name_V);
806 -- Declare the asynchronous flag. This flag will be changed to True
807 -- whenever it is known that the RACW type is asynchronous. Also, the
808 -- node gets stored since it may be rewritten when we process the
809 -- asynchronous pragma.
811 Append_To (Declarations,
812 Make_Object_Declaration (Loc,
813 Defining_Identifier => Asynchronous_Flag,
814 Constant_Present => True,
815 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
816 Expression => Asynchronous_Node));
818 Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Node);
820 -- Object declarations
823 Make_Object_Declaration (Loc,
824 Defining_Identifier => Source_Partition,
826 New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
828 Make_Object_Declaration (Loc,
829 Defining_Identifier => Source_Receiver,
831 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
833 Make_Object_Declaration (Loc,
834 Defining_Identifier => Source_Address,
836 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
838 Make_Object_Declaration (Loc,
839 Defining_Identifier => Stubbed_Result,
841 New_Occurrence_Of (Stub_Type_Access, Loc)));
843 -- Read the source Partition_ID and RPC_Receiver from incoming stream
845 Statements := New_List (
846 Make_Attribute_Reference (Loc,
848 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
849 Attribute_Name => Name_Read,
850 Expressions => New_List (
852 New_Occurrence_Of (Source_Partition, Loc))),
854 Make_Attribute_Reference (Loc,
856 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
859 Expressions => New_List (
861 New_Occurrence_Of (Source_Receiver, Loc))),
863 Make_Attribute_Reference (Loc,
865 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
868 Expressions => New_List (
870 New_Occurrence_Of (Source_Address, Loc))));
872 -- If the Address is Null_Address, then return a null object
874 Append_To (Statements,
875 Make_Implicit_If_Statement (RACW_Type,
878 Left_Opnd => New_Occurrence_Of (Source_Address, Loc),
879 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
880 Then_Statements => New_List (
881 Make_Assignment_Statement (Loc,
883 Expression => Make_Null (Loc)),
884 Make_Return_Statement (Loc))));
886 -- If the RACW denotes an object created on the current partition, then
887 -- Local_Statements will be executed. The real object will be used.
889 Local_Statements := New_List (
890 Make_Assignment_Statement (Loc,
893 Unchecked_Convert_To (RACW_Type,
894 OK_Convert_To (RTE (RE_Address),
895 New_Occurrence_Of (Source_Address, Loc)))));
897 -- If the object is located on another partition, then a stub object
898 -- will be created with all the information needed to rebuild the
899 -- real object at the other end.
901 Remote_Statements := New_List (
903 Make_Assignment_Statement (Loc,
904 Name => New_Occurrence_Of (Stubbed_Result, Loc),
907 New_Occurrence_Of (Stub_Type, Loc))),
909 Make_Assignment_Statement (Loc,
910 Name => Make_Selected_Component (Loc,
911 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
912 Selector_Name => Make_Identifier (Loc, Name_Origin)),
914 New_Occurrence_Of (Source_Partition, Loc)),
916 Make_Assignment_Statement (Loc,
917 Name => Make_Selected_Component (Loc,
918 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
919 Selector_Name => Make_Identifier (Loc, Name_Receiver)),
921 New_Occurrence_Of (Source_Receiver, Loc)),
923 Make_Assignment_Statement (Loc,
924 Name => Make_Selected_Component (Loc,
925 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
926 Selector_Name => Make_Identifier (Loc, Name_Addr)),
928 New_Occurrence_Of (Source_Address, Loc)));
930 Append_To (Remote_Statements,
931 Make_Assignment_Statement (Loc,
932 Name => Make_Selected_Component (Loc,
933 Prefix => New_Occurrence_Of (Stubbed_Result, Loc),
934 Selector_Name => Make_Identifier (Loc, Name_Asynchronous)),
936 New_Occurrence_Of (Asynchronous_Flag, Loc)));
938 Append_To (Remote_Statements,
939 Make_Procedure_Call_Statement (Loc,
941 New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
942 Parameter_Associations => New_List (
943 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
944 New_Occurrence_Of (Stubbed_Result, Loc)))));
946 Append_To (Remote_Statements,
947 Make_Assignment_Statement (Loc,
949 Expression => Unchecked_Convert_To (RACW_Type,
950 New_Occurrence_Of (Stubbed_Result, Loc))));
952 -- Distinguish between the local and remote cases, and execute the
953 -- appropriate piece of code.
955 Append_To (Statements,
956 Make_Implicit_If_Statement (RACW_Type,
960 Make_Function_Call (Loc,
962 New_Occurrence_Of (RTE (RE_Get_Local_Partition_Id), Loc)),
963 Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
964 Then_Statements => Local_Statements,
965 Else_Statements => Remote_Statements));
967 Build_Stream_Procedure
968 (Loc, RACW_Type, Body_Node,
969 Make_Defining_Identifier (Loc, Procedure_Name),
970 Statements, Outp => True);
971 Set_Declarations (Body_Node, Decls);
973 Proc_Decl := Make_Subprogram_Declaration (Loc,
974 Copy_Specification (Loc, Specification (Body_Node)));
977 Make_Attribute_Definition_Clause (Loc,
978 Name => New_Occurrence_Of (RACW_Type, Loc),
982 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
984 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
985 Insert_After (Proc_Decl, Attr_Decl);
986 Append_To (Declarations, Body_Node);
987 end Add_RACW_Read_Attribute;
989 ------------------------------------
990 -- Add_RACW_Read_Write_Attributes --
991 ------------------------------------
993 procedure Add_RACW_Read_Write_Attributes
994 (RACW_Type : in Entity_Id;
995 Stub_Type : in Entity_Id;
996 Stub_Type_Access : in Entity_Id;
997 Object_RPC_Receiver : in Entity_Id;
998 Declarations : in List_Id)
1001 Add_RACW_Write_Attribute
1002 (RACW_Type => RACW_Type,
1003 Stub_Type => Stub_Type,
1004 Stub_Type_Access => Stub_Type_Access,
1005 Object_RPC_Receiver => Object_RPC_Receiver,
1006 Declarations => Declarations);
1008 Add_RACW_Read_Attribute
1009 (RACW_Type => RACW_Type,
1010 Stub_Type => Stub_Type,
1011 Stub_Type_Access => Stub_Type_Access,
1012 Declarations => Declarations);
1013 end Add_RACW_Read_Write_Attributes;
1015 ------------------------------
1016 -- Add_RACW_Write_Attribute --
1017 ------------------------------
1019 procedure Add_RACW_Write_Attribute
1020 (RACW_Type : in Entity_Id;
1021 Stub_Type : in Entity_Id;
1022 Stub_Type_Access : in Entity_Id;
1023 Object_RPC_Receiver : in Entity_Id;
1024 Declarations : in List_Id)
1026 Loc : constant Source_Ptr := Sloc (RACW_Type);
1028 Body_Node : Node_Id;
1029 Proc_Decl : Node_Id;
1030 Attr_Decl : Node_Id;
1032 Statements : List_Id;
1033 Local_Statements : List_Id;
1034 Remote_Statements : List_Id;
1035 Null_Statements : List_Id;
1037 Procedure_Name : constant Name_Id := New_Internal_Name ('R');
1039 -- Functions to create occurrences of the formal
1042 function Stream_Parameter return Node_Id;
1043 function Object return Node_Id;
1045 function Stream_Parameter return Node_Id is
1047 return Make_Identifier (Loc, Name_S);
1048 end Stream_Parameter;
1050 function Object return Node_Id is
1052 return Make_Identifier (Loc, Name_V);
1056 -- Build the code fragment corresponding to the marshalling of a
1059 Local_Statements := New_List (
1061 Pack_Entity_Into_Stream_Access (Loc,
1062 Stream => Stream_Parameter,
1063 Object => RTE (RE_Get_Local_Partition_Id)),
1065 Pack_Node_Into_Stream_Access (Loc,
1066 Stream => Stream_Parameter,
1067 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1068 Make_Attribute_Reference (Loc,
1069 Prefix => New_Occurrence_Of (Object_RPC_Receiver, Loc),
1070 Attribute_Name => Name_Address)),
1071 Etyp => RTE (RE_Unsigned_64)),
1073 Pack_Node_Into_Stream_Access (Loc,
1074 Stream => Stream_Parameter,
1075 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1076 Make_Attribute_Reference (Loc,
1078 Make_Explicit_Dereference (Loc,
1080 Attribute_Name => Name_Address)),
1081 Etyp => RTE (RE_Unsigned_64)));
1083 -- Build the code fragment corresponding to the marshalling of
1086 Remote_Statements := New_List (
1088 Pack_Node_Into_Stream_Access (Loc,
1089 Stream => Stream_Parameter,
1091 Make_Selected_Component (Loc,
1092 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1095 Make_Identifier (Loc, Name_Origin)),
1096 Etyp => RTE (RE_Partition_ID)),
1098 Pack_Node_Into_Stream_Access (Loc,
1099 Stream => Stream_Parameter,
1101 Make_Selected_Component (Loc,
1102 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1105 Make_Identifier (Loc, Name_Receiver)),
1106 Etyp => RTE (RE_Unsigned_64)),
1108 Pack_Node_Into_Stream_Access (Loc,
1109 Stream => Stream_Parameter,
1111 Make_Selected_Component (Loc,
1112 Prefix => Unchecked_Convert_To (Stub_Type_Access,
1115 Make_Identifier (Loc, Name_Addr)),
1116 Etyp => RTE (RE_Unsigned_64)));
1118 -- Build the code fragment corresponding to the marshalling of a null
1121 Null_Statements := New_List (
1123 Pack_Entity_Into_Stream_Access (Loc,
1124 Stream => Stream_Parameter,
1125 Object => RTE (RE_Get_Local_Partition_Id)),
1127 Pack_Node_Into_Stream_Access (Loc,
1128 Stream => Stream_Parameter,
1129 Object => OK_Convert_To (RTE (RE_Unsigned_64),
1130 Make_Attribute_Reference (Loc,
1131 Prefix => New_Occurrence_Of (Object_RPC_Receiver, Loc),
1132 Attribute_Name => Name_Address)),
1133 Etyp => RTE (RE_Unsigned_64)),
1135 Pack_Node_Into_Stream_Access (Loc,
1136 Stream => Stream_Parameter,
1137 Object => Make_Integer_Literal (Loc, Uint_0),
1138 Etyp => RTE (RE_Unsigned_64)));
1140 Statements := New_List (
1141 Make_Implicit_If_Statement (RACW_Type,
1144 Left_Opnd => Object,
1145 Right_Opnd => Make_Null (Loc)),
1146 Then_Statements => Null_Statements,
1147 Elsif_Parts => New_List (
1148 Make_Elsif_Part (Loc,
1152 Make_Attribute_Reference (Loc,
1154 Attribute_Name => Name_Tag),
1156 Make_Attribute_Reference (Loc,
1157 Prefix => New_Occurrence_Of (Stub_Type, Loc),
1158 Attribute_Name => Name_Tag)),
1159 Then_Statements => Remote_Statements)),
1160 Else_Statements => Local_Statements));
1162 Build_Stream_Procedure
1163 (Loc, RACW_Type, Body_Node,
1164 Make_Defining_Identifier (Loc, Procedure_Name),
1165 Statements, Outp => False);
1167 Proc_Decl := Make_Subprogram_Declaration (Loc,
1168 Copy_Specification (Loc, Specification (Body_Node)));
1171 Make_Attribute_Definition_Clause (Loc,
1172 Name => New_Occurrence_Of (RACW_Type, Loc),
1173 Chars => Name_Write,
1176 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
1178 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
1179 Insert_After (Proc_Decl, Attr_Decl);
1180 Append_To (Declarations, Body_Node);
1181 end Add_RACW_Write_Attribute;
1183 ------------------------------
1184 -- Add_RAS_Access_Attribute --
1185 ------------------------------
1187 procedure Add_RAS_Access_Attribute (N : in Node_Id) is
1188 Ras_Type : constant Entity_Id := Defining_Identifier (N);
1189 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
1190 -- Ras_Type is the access to subprogram type while Fat_Type points to
1191 -- the record type corresponding to a remote access to subprogram type.
1193 Proc_Decls : constant List_Id := New_List;
1194 Proc_Statements : constant List_Id := New_List;
1196 Proc_Spec : Node_Id;
1201 Package_Name : Node_Id;
1204 Return_Value : Node_Id;
1206 All_Calls_Remote : Entity_Id;
1207 -- True if an All_Calls_Remote pragma applies to the RCI unit
1208 -- that contains the subprogram (currently unused, all RAS
1209 -- dereferences are handled through the PCS).
1211 Loc : constant Source_Ptr := Sloc (N);
1213 procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id);
1214 -- Set a field name for the return value
1216 procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id)
1219 Append_To (Proc_Statements,
1220 Make_Assignment_Statement (Loc,
1222 Make_Selected_Component (Loc,
1223 Prefix => New_Occurrence_Of (Return_Value, Loc),
1224 Selector_Name => Make_Identifier (Loc, Field_Name)),
1225 Expression => Value));
1228 -- Start of processing for Add_RAS_Access_Attribute
1231 Param := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1232 Package_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1233 Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
1234 Asynch_P := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1235 Return_Value := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1237 Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
1239 -- Create the object which will be returned of type Fat_Type
1241 Append_To (Proc_Decls,
1242 Make_Object_Declaration (Loc,
1243 Defining_Identifier => Return_Value,
1244 Object_Definition =>
1245 New_Occurrence_Of (Fat_Type, Loc)));
1247 -- Initialize the fields of the record type with the appropriate data
1249 Set_Field (Name_Ras,
1250 OK_Convert_To (RTE (RE_Unsigned_64), New_Occurrence_Of (Param, Loc)));
1252 Set_Field (Name_Origin,
1253 Unchecked_Convert_To (Standard_Integer,
1254 Make_Function_Call (Loc,
1256 New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
1257 Parameter_Associations => New_List (
1258 New_Occurrence_Of (Package_Name, Loc)))));
1260 Set_Field (Name_Receiver,
1261 Make_Function_Call (Loc,
1263 New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
1264 Parameter_Associations => New_List (
1265 New_Occurrence_Of (Package_Name, Loc))));
1267 Set_Field (Name_Subp_Id,
1268 New_Occurrence_Of (Subp_Id, Loc));
1270 Set_Field (Name_Async,
1271 New_Occurrence_Of (Asynch_P, Loc));
1273 -- Return the newly created value
1275 Append_To (Proc_Statements,
1276 Make_Return_Statement (Loc,
1278 New_Occurrence_Of (Return_Value, Loc)));
1281 Make_Defining_Identifier (Loc,
1282 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
1285 Make_Function_Specification (Loc,
1286 Defining_Unit_Name => Proc,
1287 Parameter_Specifications => New_List (
1288 Make_Parameter_Specification (Loc,
1289 Defining_Identifier => Param,
1291 New_Occurrence_Of (RTE (RE_Address), Loc)),
1293 Make_Parameter_Specification (Loc,
1294 Defining_Identifier => Package_Name,
1296 New_Occurrence_Of (Standard_String, Loc)),
1298 Make_Parameter_Specification (Loc,
1299 Defining_Identifier => Subp_Id,
1301 New_Occurrence_Of (Standard_Natural, Loc)),
1303 Make_Parameter_Specification (Loc,
1304 Defining_Identifier => Asynch_P,
1306 New_Occurrence_Of (Standard_Boolean, Loc)),
1308 Make_Parameter_Specification (Loc,
1309 Defining_Identifier => All_Calls_Remote,
1311 New_Occurrence_Of (Standard_Boolean, Loc))),
1314 New_Occurrence_Of (Fat_Type, Loc));
1316 -- Set the kind and return type of the function to prevent ambiguities
1317 -- between Ras_Type and Fat_Type in subsequent analysis.
1319 Set_Ekind (Proc, E_Function);
1320 Set_Etype (Proc, New_Occurrence_Of (Fat_Type, Loc));
1323 Make_Subprogram_Body (Loc,
1324 Specification => Proc_Spec,
1325 Declarations => Proc_Decls,
1326 Handled_Statement_Sequence =>
1327 Make_Handled_Sequence_Of_Statements (Loc,
1328 Statements => Proc_Statements)));
1330 Set_TSS (Fat_Type, Proc);
1332 end Add_RAS_Access_Attribute;
1334 -----------------------------------
1335 -- Add_RAS_Dereference_Attribute --
1336 -----------------------------------
1338 procedure Add_RAS_Dereference_Attribute (N : in Node_Id) is
1339 Loc : constant Source_Ptr := Sloc (N);
1341 Type_Def : constant Node_Id := Type_Definition (N);
1343 Ras_Type : constant Entity_Id := Defining_Identifier (N);
1345 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
1347 Proc_Decls : constant List_Id := New_List;
1348 Proc_Statements : constant List_Id := New_List;
1350 Inner_Decls : constant List_Id := New_List;
1351 Inner_Statements : constant List_Id := New_List;
1353 Direct_Statements : constant List_Id := New_List;
1356 Proc_Spec : Node_Id;
1357 Param_Specs : constant List_Id := New_List;
1358 Param_Assoc : constant List_Id := New_List;
1362 Converted_Ras : Node_Id;
1363 Target_Partition : Node_Id;
1364 RPC_Receiver : Node_Id;
1365 Subprogram_Id : Node_Id;
1366 Asynchronous : Node_Id;
1368 Is_Function : constant Boolean :=
1369 Nkind (Type_Def) = N_Access_Function_Definition;
1371 Spec : constant Node_Id := Type_Def;
1373 Current_Parameter : Node_Id;
1376 -- The way to do it is test if the Ras field is non-null and then if
1377 -- the Origin field is equal to the current partition ID (which is in
1378 -- fact Current_Package'Partition_ID). If this is the case, then it
1379 -- is safe to dereference the Ras field directly rather than
1380 -- performing a remote call.
1383 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1386 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1388 Append_To (Proc_Decls,
1389 Make_Object_Declaration (Loc,
1390 Defining_Identifier => Target_Partition,
1391 Constant_Present => True,
1392 Object_Definition =>
1393 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
1395 Unchecked_Convert_To (RTE (RE_Partition_ID),
1396 Make_Selected_Component (Loc,
1398 New_Occurrence_Of (Pointer, Loc),
1400 Make_Identifier (Loc, Name_Origin)))));
1403 Make_Selected_Component (Loc,
1405 New_Occurrence_Of (Pointer, Loc),
1407 Make_Identifier (Loc, Name_Receiver));
1410 Unchecked_Convert_To (RTE (RE_Subprogram_Id),
1411 Make_Selected_Component (Loc,
1413 New_Occurrence_Of (Pointer, Loc),
1415 Make_Identifier (Loc, Name_Subp_Id)));
1417 -- A function is never asynchronous. A procedure may or may not be
1418 -- asynchronous depending on whether a pragma Asynchronous applies
1419 -- on it. Since a RAST may point onto various subprograms, this is
1420 -- only known at runtime so both versions (synchronous and asynchronous)
1421 -- must be built every times it is not a function.
1424 Asynchronous := Empty;
1428 Make_Selected_Component (Loc,
1430 New_Occurrence_Of (Pointer, Loc),
1432 Make_Identifier (Loc, Name_Async));
1436 if Present (Parameter_Specifications (Type_Def)) then
1437 Current_Parameter := First (Parameter_Specifications (Type_Def));
1439 while Current_Parameter /= Empty loop
1440 Append_To (Param_Specs,
1441 Make_Parameter_Specification (Loc,
1442 Defining_Identifier =>
1443 Make_Defining_Identifier (Loc,
1445 Chars (Defining_Identifier (Current_Parameter))),
1446 In_Present => In_Present (Current_Parameter),
1447 Out_Present => Out_Present (Current_Parameter),
1449 New_Copy_Tree (Parameter_Type (Current_Parameter)),
1451 New_Copy_Tree (Expression (Current_Parameter))));
1453 Append_To (Param_Assoc,
1454 Make_Identifier (Loc,
1455 Chars => Chars (Defining_Identifier (Current_Parameter))));
1457 Next (Current_Parameter);
1462 Make_Defining_Identifier (Loc,
1463 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Dereference));
1467 Make_Function_Specification (Loc,
1468 Defining_Unit_Name => Proc,
1469 Parameter_Specifications => Param_Specs,
1472 Entity (Subtype_Mark (Spec)), Loc));
1474 Set_Ekind (Proc, E_Function);
1477 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
1481 Make_Procedure_Specification (Loc,
1482 Defining_Unit_Name => Proc,
1483 Parameter_Specifications => Param_Specs);
1485 Set_Ekind (Proc, E_Procedure);
1486 Set_Etype (Proc, Standard_Void_Type);
1489 -- Build the calling stubs for the dereference of the RAS
1491 Build_General_Calling_Stubs
1492 (Decls => Inner_Decls,
1493 Statements => Inner_Statements,
1494 Target_Partition => Target_Partition,
1495 RPC_Receiver => RPC_Receiver,
1496 Subprogram_Id => Subprogram_Id,
1497 Asynchronous => Asynchronous,
1498 Is_Known_Non_Asynchronous => Is_Function,
1499 Is_Function => Is_Function,
1504 Unchecked_Convert_To (Ras_Type,
1505 OK_Convert_To (RTE (RE_Address),
1506 Make_Selected_Component (Loc,
1507 Prefix => New_Occurrence_Of (Pointer, Loc),
1508 Selector_Name => Make_Identifier (Loc, Name_Ras))));
1511 Append_To (Direct_Statements,
1512 Make_Return_Statement (Loc,
1514 Make_Function_Call (Loc,
1516 Make_Explicit_Dereference (Loc,
1517 Prefix => Converted_Ras),
1518 Parameter_Associations => Param_Assoc)));
1521 Append_To (Direct_Statements,
1522 Make_Procedure_Call_Statement (Loc,
1524 Make_Explicit_Dereference (Loc,
1525 Prefix => Converted_Ras),
1526 Parameter_Associations => Param_Assoc));
1529 Prepend_To (Param_Specs,
1530 Make_Parameter_Specification (Loc,
1531 Defining_Identifier => Pointer,
1534 New_Occurrence_Of (Fat_Type, Loc)));
1536 Append_To (Proc_Statements,
1537 Make_Implicit_If_Statement (N,
1543 Make_Selected_Component (Loc,
1544 Prefix => New_Occurrence_Of (Pointer, Loc),
1545 Selector_Name => Make_Identifier (Loc, Name_Ras)),
1547 Make_Integer_Literal (Loc, Uint_0)),
1552 New_Occurrence_Of (Target_Partition, Loc),
1554 Make_Function_Call (Loc,
1556 RTE (RE_Get_Local_Partition_Id), Loc)))),
1561 Else_Statements => New_List (
1562 Make_Block_Statement (Loc,
1563 Declarations => Inner_Decls,
1564 Handled_Statement_Sequence =>
1565 Make_Handled_Sequence_Of_Statements (Loc,
1566 Statements => Inner_Statements)))));
1569 Make_Subprogram_Body (Loc,
1570 Specification => Proc_Spec,
1571 Declarations => Proc_Decls,
1572 Handled_Statement_Sequence =>
1573 Make_Handled_Sequence_Of_Statements (Loc,
1574 Statements => Proc_Statements)));
1576 Set_TSS (Fat_Type, Defining_Unit_Name (Proc_Spec));
1578 end Add_RAS_Dereference_Attribute;
1580 -----------------------
1581 -- Add_RAST_Features --
1582 -----------------------
1584 procedure Add_RAST_Features (Vis_Decl : Node_Id) is
1586 -- Do not add attributes more than once in any case. This should
1587 -- be replaced by an assert or this comment removed if we decide
1588 -- that this is normal to be called several times ???
1590 if Present (TSS (Equivalent_Type (Defining_Identifier (Vis_Decl)),
1596 Add_RAS_Dereference_Attribute (Vis_Decl);
1597 Add_RAS_Access_Attribute (Vis_Decl);
1598 end Add_RAST_Features;
1600 -----------------------------------------
1601 -- Add_Receiving_Stubs_To_Declarations --
1602 -----------------------------------------
1604 procedure Add_Receiving_Stubs_To_Declarations
1605 (Pkg_Spec : in Node_Id;
1608 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
1610 Stream_Parameter : Node_Id;
1611 Result_Parameter : Node_Id;
1613 Pkg_RPC_Receiver : Node_Id;
1614 Pkg_RPC_Receiver_Spec : Node_Id;
1615 Pkg_RPC_Receiver_Decls : List_Id;
1616 Pkg_RPC_Receiver_Statements : List_Id;
1617 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
1618 Pkg_RPC_Receiver_Body : Node_Id;
1619 -- A Pkg_RPC_Receiver is built to decode the request
1622 -- Subprogram_Id as read from the incoming stream
1624 Current_Declaration : Node_Id;
1625 Current_Subprogram_Number : Int := 0;
1626 Current_Stubs : Node_Id;
1630 Dummy_Register_Name : Name_Id;
1631 Dummy_Register_Spec : Node_Id;
1632 Dummy_Register_Decl : Node_Id;
1633 Dummy_Register_Body : Node_Id;
1636 -- Building receiving stubs consist in several operations:
1638 -- - a package RPC receiver must be built. This subprogram
1639 -- will get a Subprogram_Id from the incoming stream
1640 -- and will dispatch the call to the right subprogram
1642 -- - a receiving stub for any subprogram visible in the package
1643 -- spec. This stub will read all the parameters from the stream,
1644 -- and put the result as well as the exception occurrence in the
1647 -- - a dummy package with an empty spec and a body made of an
1648 -- elaboration part, whose job is to register the receiving
1649 -- part of this RCI package on the name server. This is done
1650 -- by calling System.Partition_Interface.Register_Receiving_Stub
1653 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1655 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
1657 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1660 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1662 -- The parameters of the package RPC receiver are made of two
1663 -- streams, an input one and an output one.
1665 Pkg_RPC_Receiver_Spec :=
1666 Build_RPC_Receiver_Specification
1667 (RPC_Receiver => Pkg_RPC_Receiver,
1668 Stream_Parameter => Stream_Parameter,
1669 Result_Parameter => Result_Parameter);
1671 Pkg_RPC_Receiver_Decls := New_List (
1672 Make_Object_Declaration (Loc,
1673 Defining_Identifier => Subp_Id,
1674 Object_Definition =>
1675 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)));
1677 Pkg_RPC_Receiver_Statements := New_List (
1678 Make_Attribute_Reference (Loc,
1680 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
1683 Expressions => New_List (
1684 New_Occurrence_Of (Stream_Parameter, Loc),
1685 New_Occurrence_Of (Subp_Id, Loc))));
1687 -- For each subprogram, the receiving stub will be built and a
1688 -- case statement will be made on the Subprogram_Id to dispatch
1689 -- to the right subprogram.
1691 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
1693 while Current_Declaration /= Empty loop
1695 if Nkind (Current_Declaration) = N_Subprogram_Declaration
1696 and then Comes_From_Source (Current_Declaration)
1698 pragma Assert (Current_Subprogram_Number =
1699 Get_Subprogram_Id (Defining_Unit_Name (Specification (
1700 Current_Declaration))));
1703 Build_Subprogram_Receiving_Stubs
1704 (Vis_Decl => Current_Declaration,
1706 Nkind (Specification (Current_Declaration)) =
1707 N_Procedure_Specification
1708 and then Is_Asynchronous
1709 (Defining_Unit_Name (Specification
1710 (Current_Declaration))));
1712 Append_To (Decls, Current_Stubs);
1714 Analyze (Current_Stubs);
1716 Actuals := New_List (New_Occurrence_Of (Stream_Parameter, Loc));
1718 if Nkind (Specification (Current_Declaration))
1719 = N_Function_Specification
1721 not Is_Asynchronous (
1722 Defining_Entity (Specification (Current_Declaration)))
1724 -- An asynchronous procedure does not want an output parameter
1725 -- since no result and no exception will ever be returned.
1728 New_Occurrence_Of (Result_Parameter, Loc));
1732 Append_To (Pkg_RPC_Receiver_Cases,
1733 Make_Case_Statement_Alternative (Loc,
1736 Make_Integer_Literal (Loc, Current_Subprogram_Number)),
1740 Make_Procedure_Call_Statement (Loc,
1743 Defining_Entity (Current_Stubs), Loc),
1744 Parameter_Associations =>
1747 Current_Subprogram_Number := Current_Subprogram_Number + 1;
1750 Next (Current_Declaration);
1753 -- If we receive an invalid Subprogram_Id, it is best to do nothing
1754 -- rather than raising an exception since we do not want someone
1755 -- to crash a remote partition by sending invalid subprogram ids.
1756 -- This is consistent with the other parts of the case statement
1757 -- since even in presence of incorrect parameters in the stream,
1758 -- every exception will be caught and (if the subprogram is not an
1759 -- APC) put into the result stream and sent away.
1761 Append_To (Pkg_RPC_Receiver_Cases,
1762 Make_Case_Statement_Alternative (Loc,
1764 New_List (Make_Others_Choice (Loc)),
1766 New_List (Make_Null_Statement (Loc))));
1768 Append_To (Pkg_RPC_Receiver_Statements,
1769 Make_Case_Statement (Loc,
1771 New_Occurrence_Of (Subp_Id, Loc),
1772 Alternatives => Pkg_RPC_Receiver_Cases));
1774 Pkg_RPC_Receiver_Body :=
1775 Make_Subprogram_Body (Loc,
1776 Specification => Pkg_RPC_Receiver_Spec,
1777 Declarations => Pkg_RPC_Receiver_Decls,
1778 Handled_Statement_Sequence =>
1779 Make_Handled_Sequence_Of_Statements (Loc,
1780 Statements => Pkg_RPC_Receiver_Statements));
1782 Append_To (Decls, Pkg_RPC_Receiver_Body);
1783 Analyze (Pkg_RPC_Receiver_Body);
1785 -- Construction of the dummy package used to register the package
1786 -- receiving stubs on the nameserver.
1788 Dummy_Register_Name := New_Internal_Name ('P');
1790 Dummy_Register_Spec :=
1791 Make_Package_Specification (Loc,
1792 Defining_Unit_Name =>
1793 Make_Defining_Identifier (Loc, Dummy_Register_Name),
1794 Visible_Declarations => No_List,
1795 End_Label => Empty);
1797 Dummy_Register_Decl :=
1798 Make_Package_Declaration (Loc,
1799 Specification => Dummy_Register_Spec);
1802 Dummy_Register_Decl);
1803 Analyze (Dummy_Register_Decl);
1805 Dummy_Register_Body :=
1806 Make_Package_Body (Loc,
1807 Defining_Unit_Name =>
1808 Make_Defining_Identifier (Loc, Dummy_Register_Name),
1809 Declarations => No_List,
1811 Handled_Statement_Sequence =>
1812 Make_Handled_Sequence_Of_Statements (Loc,
1813 Statements => New_List (
1814 Make_Procedure_Call_Statement (Loc,
1816 New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
1818 Parameter_Associations => New_List (
1819 Make_String_Literal (Loc,
1820 Strval => Get_Pkg_Name_String_Id (Pkg_Spec)),
1821 Make_Attribute_Reference (Loc,
1823 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
1825 Name_Unrestricted_Access),
1826 Make_Attribute_Reference (Loc,
1828 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
1832 Append_To (Decls, Dummy_Register_Body);
1833 Analyze (Dummy_Register_Body);
1834 end Add_Receiving_Stubs_To_Declarations;
1840 procedure Add_Stub_Type
1841 (Designated_Type : in Entity_Id;
1842 RACW_Type : in Entity_Id;
1844 Stub_Type : out Entity_Id;
1845 Stub_Type_Access : out Entity_Id;
1846 Object_RPC_Receiver : out Entity_Id;
1847 Existing : out Boolean)
1849 Loc : constant Source_Ptr := Sloc (RACW_Type);
1851 Stub_Elements : constant Stub_Structure :=
1852 Stubs_Table.Get (Designated_Type);
1854 Stub_Type_Declaration : Node_Id;
1855 Stub_Type_Access_Declaration : Node_Id;
1856 Object_RPC_Receiver_Declaration : Node_Id;
1858 RPC_Receiver_Stream : Entity_Id;
1859 RPC_Receiver_Result : Entity_Id;
1862 if Stub_Elements /= Empty_Stub_Structure then
1863 Stub_Type := Stub_Elements.Stub_Type;
1864 Stub_Type_Access := Stub_Elements.Stub_Type_Access;
1865 Object_RPC_Receiver := Stub_Elements.Object_RPC_Receiver;
1872 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1874 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1875 Object_RPC_Receiver :=
1876 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
1877 RPC_Receiver_Stream :=
1878 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1879 RPC_Receiver_Result :=
1880 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1881 Stubs_Table.Set (Designated_Type,
1882 (Stub_Type => Stub_Type,
1883 Stub_Type_Access => Stub_Type_Access,
1884 Object_RPC_Receiver => Object_RPC_Receiver,
1885 RPC_Receiver_Stream => RPC_Receiver_Stream,
1886 RPC_Receiver_Result => RPC_Receiver_Result,
1887 RACW_Type => RACW_Type));
1889 -- The stub type definition below must match exactly the one in
1890 -- s-parint.ads, since unchecked conversions will be used in
1891 -- s-parint.adb to modify pointers passed to Get_Unique_Remote_Pointer.
1893 Stub_Type_Declaration :=
1894 Make_Full_Type_Declaration (Loc,
1895 Defining_Identifier => Stub_Type,
1897 Make_Record_Definition (Loc,
1898 Tagged_Present => True,
1899 Limited_Present => True,
1901 Make_Component_List (Loc,
1902 Component_Items => New_List (
1904 Make_Component_Declaration (Loc,
1905 Defining_Identifier =>
1906 Make_Defining_Identifier (Loc, Name_Origin),
1907 Component_Definition =>
1908 Make_Component_Definition (Loc,
1909 Aliased_Present => False,
1910 Subtype_Indication =>
1911 New_Occurrence_Of (RTE (RE_Partition_ID), Loc))),
1913 Make_Component_Declaration (Loc,
1914 Defining_Identifier =>
1915 Make_Defining_Identifier (Loc, Name_Receiver),
1916 Component_Definition =>
1917 Make_Component_Definition (Loc,
1918 Aliased_Present => False,
1919 Subtype_Indication =>
1920 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
1922 Make_Component_Declaration (Loc,
1923 Defining_Identifier =>
1924 Make_Defining_Identifier (Loc, Name_Addr),
1925 Component_Definition =>
1926 Make_Component_Definition (Loc,
1927 Aliased_Present => False,
1928 Subtype_Indication =>
1929 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
1931 Make_Component_Declaration (Loc,
1932 Defining_Identifier =>
1933 Make_Defining_Identifier (Loc, Name_Asynchronous),
1934 Component_Definition =>
1935 Make_Component_Definition (Loc,
1936 Aliased_Present => False,
1937 Subtype_Indication =>
1938 New_Occurrence_Of (Standard_Boolean, Loc)))))));
1940 Append_To (Decls, Stub_Type_Declaration);
1941 Analyze (Stub_Type_Declaration);
1943 -- This is in no way a type derivation, but we fake it to make
1944 -- sure that the dispatching table gets built with the corresponding
1945 -- primitive operations at the right place.
1947 Derive_Subprograms (Parent_Type => Designated_Type,
1948 Derived_Type => Stub_Type);
1950 Stub_Type_Access_Declaration :=
1951 Make_Full_Type_Declaration (Loc,
1952 Defining_Identifier => Stub_Type_Access,
1954 Make_Access_To_Object_Definition (Loc,
1955 Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
1957 Append_To (Decls, Stub_Type_Access_Declaration);
1958 Analyze (Stub_Type_Access_Declaration);
1960 Object_RPC_Receiver_Declaration :=
1961 Make_Subprogram_Declaration (Loc,
1962 Build_RPC_Receiver_Specification (
1963 RPC_Receiver => Object_RPC_Receiver,
1964 Stream_Parameter => RPC_Receiver_Stream,
1965 Result_Parameter => RPC_Receiver_Result));
1967 Append_To (Decls, Object_RPC_Receiver_Declaration);
1970 ---------------------------------
1971 -- Build_General_Calling_Stubs --
1972 ---------------------------------
1974 procedure Build_General_Calling_Stubs
1976 Statements : List_Id;
1977 Target_Partition : Entity_Id;
1978 RPC_Receiver : Node_Id;
1979 Subprogram_Id : Node_Id;
1980 Asynchronous : Node_Id := Empty;
1981 Is_Known_Asynchronous : Boolean := False;
1982 Is_Known_Non_Asynchronous : Boolean := False;
1983 Is_Function : Boolean;
1985 Object_Type : Entity_Id := Empty;
1988 Loc : constant Source_Ptr := Sloc (Nod);
1990 Stream_Parameter : Node_Id;
1991 -- Name of the stream used to transmit parameters to the remote package
1993 Result_Parameter : Node_Id;
1994 -- Name of the result parameter (in non-APC cases) which get the
1995 -- result of the remote subprogram.
1997 Exception_Return_Parameter : Node_Id;
1998 -- Name of the parameter which will hold the exception sent by the
1999 -- remote subprogram.
2001 Current_Parameter : Node_Id;
2002 -- Current parameter being handled
2004 Ordered_Parameters_List : constant List_Id :=
2005 Build_Ordered_Parameters_List (Spec);
2007 Asynchronous_Statements : List_Id := No_List;
2008 Non_Asynchronous_Statements : List_Id := No_List;
2009 -- Statements specifics to the Asynchronous/Non-Asynchronous cases.
2011 Extra_Formal_Statements : constant List_Id := New_List;
2012 -- List of statements for extra formal parameters. It will appear after
2013 -- the regular statements for writing out parameters.
2016 -- The general form of a calling stub for a given subprogram is:
2018 -- procedure X (...) is
2019 -- P : constant Partition_ID := RCI_Cache.Get_Active_Partition_ID;
2020 -- Stream, Result : aliased System.RPC.Params_Stream_Type (0);
2022 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
2023 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
2024 -- Put_Subprogram_Id_In_Stream;
2025 -- Put_Parameters_In_Stream;
2026 -- Do_RPC (Stream, Result);
2027 -- Read_Exception_Occurrence_From_Result; Raise_It;
2028 -- Read_Out_Parameters_And_Function_Return_From_Stream;
2031 -- There are some variations: Do_APC is called for an asynchronous
2032 -- procedure and the part after the call is completely ommitted
2033 -- as well as the declaration of Result. For a function call,
2034 -- 'Input is always used to read the result even if it is constrained.
2037 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2040 Make_Object_Declaration (Loc,
2041 Defining_Identifier => Stream_Parameter,
2042 Aliased_Present => True,
2043 Object_Definition =>
2044 Make_Subtype_Indication (Loc,
2046 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2048 Make_Index_Or_Discriminant_Constraint (Loc,
2050 New_List (Make_Integer_Literal (Loc, 0))))));
2052 if not Is_Known_Asynchronous then
2054 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
2057 Make_Object_Declaration (Loc,
2058 Defining_Identifier => Result_Parameter,
2059 Aliased_Present => True,
2060 Object_Definition =>
2061 Make_Subtype_Indication (Loc,
2063 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
2065 Make_Index_Or_Discriminant_Constraint (Loc,
2067 New_List (Make_Integer_Literal (Loc, 0))))));
2069 Exception_Return_Parameter :=
2070 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
2073 Make_Object_Declaration (Loc,
2074 Defining_Identifier => Exception_Return_Parameter,
2075 Object_Definition =>
2076 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
2079 Result_Parameter := Empty;
2080 Exception_Return_Parameter := Empty;
2083 -- Put first the RPC receiver corresponding to the remote package
2085 Append_To (Statements,
2086 Make_Attribute_Reference (Loc,
2088 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2089 Attribute_Name => Name_Write,
2090 Expressions => New_List (
2091 Make_Attribute_Reference (Loc,
2093 New_Occurrence_Of (Stream_Parameter, Loc),
2098 -- Then put the Subprogram_Id of the subprogram we want to call in
2101 Append_To (Statements,
2102 Make_Attribute_Reference (Loc,
2104 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
2107 Expressions => New_List (
2108 Make_Attribute_Reference (Loc,
2110 New_Occurrence_Of (Stream_Parameter, Loc),
2111 Attribute_Name => Name_Access),
2114 Current_Parameter := First (Ordered_Parameters_List);
2116 while Current_Parameter /= Empty loop
2119 Typ : constant Node_Id :=
2120 Parameter_Type (Current_Parameter);
2122 Constrained : Boolean;
2124 Extra_Parameter : Entity_Id;
2128 if Is_RACW_Controlling_Formal (Current_Parameter, Object_Type) then
2130 -- In the case of a controlling formal argument, we marshall
2131 -- its addr field rather than the local stub.
2133 Append_To (Statements,
2134 Pack_Node_Into_Stream (Loc,
2135 Stream => Stream_Parameter,
2137 Make_Selected_Component (Loc,
2140 Defining_Identifier (Current_Parameter), Loc),
2142 Make_Identifier (Loc, Name_Addr)),
2143 Etyp => RTE (RE_Unsigned_64)));
2146 Value := New_Occurrence_Of
2147 (Defining_Identifier (Current_Parameter), Loc);
2149 -- Access type parameters are transmitted as in out
2150 -- parameters. However, a dereference is needed so that
2151 -- we marshall the designated object.
2153 if Nkind (Typ) = N_Access_Definition then
2154 Value := Make_Explicit_Dereference (Loc, Value);
2155 Etyp := Etype (Subtype_Mark (Typ));
2157 Etyp := Etype (Typ);
2161 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
2163 -- Any parameter but unconstrained out parameters are
2164 -- transmitted to the peer.
2166 if In_Present (Current_Parameter)
2167 or else not Out_Present (Current_Parameter)
2168 or else not Constrained
2170 Append_To (Statements,
2171 Make_Attribute_Reference (Loc,
2173 New_Occurrence_Of (Etyp, Loc),
2174 Attribute_Name => Output_From_Constrained (Constrained),
2175 Expressions => New_List (
2176 Make_Attribute_Reference (Loc,
2178 New_Occurrence_Of (Stream_Parameter, Loc),
2179 Attribute_Name => Name_Access),
2184 -- If the current parameter has a dynamic constrained status,
2185 -- then this status is transmitted as well.
2186 -- This should be done for accessibility as well ???
2188 if Nkind (Typ) /= N_Access_Definition
2189 and then Need_Extra_Constrained (Current_Parameter)
2191 -- In this block, we do not use the extra formal that has been
2192 -- created because it does not exist at the time of expansion
2193 -- when building calling stubs for remote access to subprogram
2194 -- types. We create an extra variable of this type and push it
2195 -- in the stream after the regular parameters.
2197 Extra_Parameter := Make_Defining_Identifier
2198 (Loc, New_Internal_Name ('P'));
2201 Make_Object_Declaration (Loc,
2202 Defining_Identifier => Extra_Parameter,
2203 Constant_Present => True,
2204 Object_Definition =>
2205 New_Occurrence_Of (Standard_Boolean, Loc),
2207 Make_Attribute_Reference (Loc,
2210 Defining_Identifier (Current_Parameter), Loc),
2211 Attribute_Name => Name_Constrained)));
2213 Append_To (Extra_Formal_Statements,
2214 Make_Attribute_Reference (Loc,
2216 New_Occurrence_Of (Standard_Boolean, Loc),
2219 Expressions => New_List (
2220 Make_Attribute_Reference (Loc,
2222 New_Occurrence_Of (Stream_Parameter, Loc),
2225 New_Occurrence_Of (Extra_Parameter, Loc))));
2228 Next (Current_Parameter);
2232 -- Append the formal statements list to the statements
2234 Append_List_To (Statements, Extra_Formal_Statements);
2236 if not Is_Known_Non_Asynchronous then
2238 -- Build the call to System.RPC.Do_APC
2240 Asynchronous_Statements := New_List (
2241 Make_Procedure_Call_Statement (Loc,
2243 New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
2244 Parameter_Associations => New_List (
2245 New_Occurrence_Of (Target_Partition, Loc),
2246 Make_Attribute_Reference (Loc,
2248 New_Occurrence_Of (Stream_Parameter, Loc),
2252 Asynchronous_Statements := No_List;
2255 if not Is_Known_Asynchronous then
2257 -- Build the call to System.RPC.Do_RPC
2259 Non_Asynchronous_Statements := New_List (
2260 Make_Procedure_Call_Statement (Loc,
2262 New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
2263 Parameter_Associations => New_List (
2264 New_Occurrence_Of (Target_Partition, Loc),
2266 Make_Attribute_Reference (Loc,
2268 New_Occurrence_Of (Stream_Parameter, Loc),
2272 Make_Attribute_Reference (Loc,
2274 New_Occurrence_Of (Result_Parameter, Loc),
2278 -- Read the exception occurrence from the result stream and
2279 -- reraise it. It does no harm if this is a Null_Occurrence since
2280 -- this does nothing.
2282 Append_To (Non_Asynchronous_Statements,
2283 Make_Attribute_Reference (Loc,
2285 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
2290 Expressions => New_List (
2291 Make_Attribute_Reference (Loc,
2293 New_Occurrence_Of (Result_Parameter, Loc),
2296 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2298 Append_To (Non_Asynchronous_Statements,
2299 Make_Procedure_Call_Statement (Loc,
2301 New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
2302 Parameter_Associations => New_List (
2303 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
2307 -- If this is a function call, then read the value and return
2308 -- it. The return value is written/read using 'Output/'Input.
2310 Append_To (Non_Asynchronous_Statements,
2311 Make_Tag_Check (Loc,
2312 Make_Return_Statement (Loc,
2314 Make_Attribute_Reference (Loc,
2317 Etype (Subtype_Mark (Spec)), Loc),
2319 Attribute_Name => Name_Input,
2321 Expressions => New_List (
2322 Make_Attribute_Reference (Loc,
2324 New_Occurrence_Of (Result_Parameter, Loc),
2325 Attribute_Name => Name_Access))))));
2328 -- Loop around parameters and assign out (or in out) parameters.
2329 -- In the case of RACW, controlling arguments cannot possibly
2330 -- have changed since they are remote, so we do not read them
2333 Current_Parameter :=
2334 First (Ordered_Parameters_List);
2336 while Current_Parameter /= Empty loop
2339 Typ : constant Node_Id :=
2340 Parameter_Type (Current_Parameter);
2344 Value := New_Occurrence_Of
2345 (Defining_Identifier (Current_Parameter), Loc);
2347 if Nkind (Typ) = N_Access_Definition then
2348 Value := Make_Explicit_Dereference (Loc, Value);
2349 Etyp := Etype (Subtype_Mark (Typ));
2351 Etyp := Etype (Typ);
2354 if (Out_Present (Current_Parameter)
2355 or else Nkind (Typ) = N_Access_Definition)
2356 and then Etyp /= Object_Type
2358 Append_To (Non_Asynchronous_Statements,
2359 Make_Attribute_Reference (Loc,
2361 New_Occurrence_Of (Etyp, Loc),
2363 Attribute_Name => Name_Read,
2365 Expressions => New_List (
2366 Make_Attribute_Reference (Loc,
2368 New_Occurrence_Of (Result_Parameter, Loc),
2375 Next (Current_Parameter);
2380 if Is_Known_Asynchronous then
2381 Append_List_To (Statements, Asynchronous_Statements);
2383 elsif Is_Known_Non_Asynchronous then
2384 Append_List_To (Statements, Non_Asynchronous_Statements);
2387 pragma Assert (Asynchronous /= Empty);
2388 Prepend_To (Asynchronous_Statements,
2389 Make_Attribute_Reference (Loc,
2390 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2391 Attribute_Name => Name_Write,
2392 Expressions => New_List (
2393 Make_Attribute_Reference (Loc,
2394 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2395 Attribute_Name => Name_Access),
2396 New_Occurrence_Of (Standard_True, Loc))));
2397 Prepend_To (Non_Asynchronous_Statements,
2398 Make_Attribute_Reference (Loc,
2399 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
2400 Attribute_Name => Name_Write,
2401 Expressions => New_List (
2402 Make_Attribute_Reference (Loc,
2403 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
2404 Attribute_Name => Name_Access),
2405 New_Occurrence_Of (Standard_False, Loc))));
2406 Append_To (Statements,
2407 Make_Implicit_If_Statement (Nod,
2408 Condition => Asynchronous,
2409 Then_Statements => Asynchronous_Statements,
2410 Else_Statements => Non_Asynchronous_Statements));
2412 end Build_General_Calling_Stubs;
2414 -----------------------------------
2415 -- Build_Ordered_Parameters_List --
2416 -----------------------------------
2418 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
2419 Constrained_List : List_Id;
2420 Unconstrained_List : List_Id;
2421 Current_Parameter : Node_Id;
2424 if not Present (Parameter_Specifications (Spec)) then
2428 Constrained_List := New_List;
2429 Unconstrained_List := New_List;
2431 -- Loop through the parameters and add them to the right list
2433 Current_Parameter := First (Parameter_Specifications (Spec));
2434 while Current_Parameter /= Empty loop
2436 if Nkind (Parameter_Type (Current_Parameter)) = N_Access_Definition
2438 Is_Constrained (Etype (Parameter_Type (Current_Parameter)))
2440 Is_Elementary_Type (Etype (Parameter_Type (Current_Parameter)))
2442 Append_To (Constrained_List, New_Copy (Current_Parameter));
2444 Append_To (Unconstrained_List, New_Copy (Current_Parameter));
2447 Next (Current_Parameter);
2450 -- Unconstrained parameters are returned first
2452 Append_List_To (Unconstrained_List, Constrained_List);
2454 return Unconstrained_List;
2456 end Build_Ordered_Parameters_List;
2458 ----------------------------------
2459 -- Build_Passive_Partition_Stub --
2460 ----------------------------------
2462 procedure Build_Passive_Partition_Stub (U : Node_Id) is
2466 Loc : constant Source_Ptr := Sloc (U);
2469 -- Verify that the implementation supports distribution, by accessing
2470 -- a type defined in the proper version of system.rpc
2473 Dist_OK : Entity_Id;
2474 pragma Warnings (Off, Dist_OK);
2477 Dist_OK := RTE (RE_Params_Stream_Type);
2480 -- Use body if present, spec otherwise
2482 if Nkind (U) = N_Package_Declaration then
2483 Pkg_Spec := Specification (U);
2484 L := Visible_Declarations (Pkg_Spec);
2486 Pkg_Spec := Parent (Corresponding_Spec (U));
2487 L := Declarations (U);
2491 Make_Procedure_Call_Statement (Loc,
2493 New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
2494 Parameter_Associations => New_List (
2495 Make_String_Literal (Loc, Get_Pkg_Name_String_Id (Pkg_Spec)),
2496 Make_Attribute_Reference (Loc,
2498 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
2503 end Build_Passive_Partition_Stub;
2505 --------------------------------------
2506 -- Build_RPC_Receiver_Specification --
2507 --------------------------------------
2509 function Build_RPC_Receiver_Specification
2510 (RPC_Receiver : Entity_Id;
2511 Stream_Parameter : Entity_Id;
2512 Result_Parameter : Entity_Id)
2515 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
2519 Make_Procedure_Specification (Loc,
2520 Defining_Unit_Name => RPC_Receiver,
2521 Parameter_Specifications => New_List (
2522 Make_Parameter_Specification (Loc,
2523 Defining_Identifier => Stream_Parameter,
2525 Make_Access_Definition (Loc,
2527 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
2529 Make_Parameter_Specification (Loc,
2530 Defining_Identifier => Result_Parameter,
2532 Make_Access_Definition (Loc,
2535 (RTE (RE_Params_Stream_Type), Loc)))));
2536 end Build_RPC_Receiver_Specification;
2538 ------------------------------------
2539 -- Build_Subprogram_Calling_Stubs --
2540 ------------------------------------
2542 function Build_Subprogram_Calling_Stubs
2543 (Vis_Decl : Node_Id;
2545 Asynchronous : Boolean;
2546 Dynamically_Asynchronous : Boolean := False;
2547 Stub_Type : Entity_Id := Empty;
2548 Locator : Entity_Id := Empty;
2549 New_Name : Name_Id := No_Name)
2552 Loc : constant Source_Ptr := Sloc (Vis_Decl);
2554 Target_Partition : Node_Id;
2555 -- Contains the name of the target partition
2557 Decls : constant List_Id := New_List;
2558 Statements : constant List_Id := New_List;
2560 Subp_Spec : Node_Id;
2561 -- The specification of the body
2563 Controlling_Parameter : Entity_Id := Empty;
2564 RPC_Receiver : Node_Id;
2566 Asynchronous_Expr : Node_Id := Empty;
2568 RCI_Locator : Entity_Id;
2570 Spec_To_Use : Node_Id;
2572 procedure Insert_Partition_Check (Parameter : in Node_Id);
2573 -- Check that the parameter has been elaborated on the same partition
2574 -- than the controlling parameter (E.4(19)).
2576 ----------------------------
2577 -- Insert_Partition_Check --
2578 ----------------------------
2580 procedure Insert_Partition_Check (Parameter : in Node_Id) is
2581 Parameter_Entity : constant Entity_Id :=
2582 Defining_Identifier (Parameter);
2583 Condition : Node_Id;
2585 Designated_Object : Node_Id;
2586 pragma Warnings (Off, Designated_Object);
2587 -- Is it really right that this is unreferenced ???
2590 -- The expression that will be built is of the form:
2591 -- if not (Parameter in Stub_Type and then
2592 -- Parameter.Origin = Controlling.Origin)
2594 -- raise Constraint_Error;
2597 -- Condition contains the reversed condition. Also, Parameter is
2598 -- dereferenced if it is an access type. We do not check that
2599 -- Parameter is in Stub_Type since such a check has been inserted
2600 -- at the point of call already (a tag check since we have multiple
2601 -- controlling operands).
2603 if Nkind (Parameter_Type (Parameter)) = N_Access_Definition then
2604 Designated_Object :=
2605 Make_Explicit_Dereference (Loc,
2606 Prefix => New_Occurrence_Of (Parameter_Entity, Loc));
2608 Designated_Object := New_Occurrence_Of (Parameter_Entity, Loc);
2614 Make_Selected_Component (Loc,
2616 New_Occurrence_Of (Parameter_Entity, Loc),
2618 Make_Identifier (Loc, Name_Origin)),
2621 Make_Selected_Component (Loc,
2623 New_Occurrence_Of (Controlling_Parameter, Loc),
2625 Make_Identifier (Loc, Name_Origin)));
2628 Make_Raise_Constraint_Error (Loc,
2630 Make_Op_Not (Loc, Right_Opnd => Condition),
2631 Reason => CE_Partition_Check_Failed));
2632 end Insert_Partition_Check;
2634 -- Start of processing for Build_Subprogram_Calling_Stubs
2638 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2640 Subp_Spec := Copy_Specification (Loc,
2641 Spec => Specification (Vis_Decl),
2642 New_Name => New_Name);
2644 if Locator = Empty then
2645 RCI_Locator := RCI_Cache;
2646 Spec_To_Use := Specification (Vis_Decl);
2648 RCI_Locator := Locator;
2649 Spec_To_Use := Subp_Spec;
2652 -- Find a controlling argument if we have a stub type. Also check
2653 -- if this subprogram can be made asynchronous.
2655 if Stub_Type /= Empty
2656 and then Present (Parameter_Specifications (Spec_To_Use))
2659 Current_Parameter : Node_Id :=
2660 First (Parameter_Specifications
2663 while Current_Parameter /= Empty loop
2666 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2668 if Controlling_Parameter = Empty then
2669 Controlling_Parameter :=
2670 Defining_Identifier (Current_Parameter);
2672 Insert_Partition_Check (Current_Parameter);
2676 Next (Current_Parameter);
2681 if Stub_Type /= Empty then
2682 pragma Assert (Controlling_Parameter /= Empty);
2685 Make_Object_Declaration (Loc,
2686 Defining_Identifier => Target_Partition,
2687 Constant_Present => True,
2688 Object_Definition =>
2689 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
2692 Make_Selected_Component (Loc,
2694 New_Occurrence_Of (Controlling_Parameter, Loc),
2696 Make_Identifier (Loc, Name_Origin))));
2699 Make_Selected_Component (Loc,
2701 New_Occurrence_Of (Controlling_Parameter, Loc),
2703 Make_Identifier (Loc, Name_Receiver));
2707 Make_Object_Declaration (Loc,
2708 Defining_Identifier => Target_Partition,
2709 Constant_Present => True,
2710 Object_Definition =>
2711 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
2714 Make_Function_Call (Loc,
2715 Name => Make_Selected_Component (Loc,
2717 Make_Identifier (Loc, Chars (RCI_Locator)),
2719 Make_Identifier (Loc, Name_Get_Active_Partition_ID)))));
2722 Make_Selected_Component (Loc,
2724 Make_Identifier (Loc, Chars (RCI_Locator)),
2726 Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
2729 if Dynamically_Asynchronous then
2730 Asynchronous_Expr :=
2731 Make_Selected_Component (Loc,
2733 New_Occurrence_Of (Controlling_Parameter, Loc),
2735 Make_Identifier (Loc, Name_Asynchronous));
2738 Build_General_Calling_Stubs
2740 Statements => Statements,
2741 Target_Partition => Target_Partition,
2742 RPC_Receiver => RPC_Receiver,
2743 Subprogram_Id => Make_Integer_Literal (Loc, Subp_Id),
2744 Asynchronous => Asynchronous_Expr,
2745 Is_Known_Asynchronous => Asynchronous
2746 and then not Dynamically_Asynchronous,
2747 Is_Known_Non_Asynchronous
2749 and then not Dynamically_Asynchronous,
2750 Is_Function => Nkind (Spec_To_Use) =
2751 N_Function_Specification,
2752 Spec => Spec_To_Use,
2753 Object_Type => Stub_Type,
2756 RCI_Calling_Stubs_Table.Set
2757 (Defining_Unit_Name (Specification (Vis_Decl)),
2758 Defining_Unit_Name (Spec_To_Use));
2761 Make_Subprogram_Body (Loc,
2762 Specification => Subp_Spec,
2763 Declarations => Decls,
2764 Handled_Statement_Sequence =>
2765 Make_Handled_Sequence_Of_Statements (Loc, Statements));
2766 end Build_Subprogram_Calling_Stubs;
2768 -------------------------
2769 -- Build_Subprogram_Id --
2770 -------------------------
2772 function Build_Subprogram_Id
2774 E : Entity_Id) return Node_Id
2777 return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
2778 end Build_Subprogram_Id;
2780 --------------------------------------
2781 -- Build_Subprogram_Receiving_Stubs --
2782 --------------------------------------
2784 function Build_Subprogram_Receiving_Stubs
2785 (Vis_Decl : Node_Id;
2786 Asynchronous : Boolean;
2787 Dynamically_Asynchronous : Boolean := False;
2788 Stub_Type : Entity_Id := Empty;
2789 RACW_Type : Entity_Id := Empty;
2790 Parent_Primitive : Entity_Id := Empty)
2793 Loc : constant Source_Ptr := Sloc (Vis_Decl);
2795 Stream_Parameter : Node_Id;
2796 Result_Parameter : Node_Id;
2797 -- See explanations of those in Build_Subprogram_Calling_Stubs
2799 Decls : constant List_Id := New_List;
2800 -- All the parameters will get declared before calling the real
2801 -- subprograms. Also the out parameters will be declared.
2803 Statements : constant List_Id := New_List;
2805 Extra_Formal_Statements : constant List_Id := New_List;
2806 -- Statements concerning extra formal parameters
2808 After_Statements : constant List_Id := New_List;
2809 -- Statements to be executed after the subprogram call
2811 Inner_Decls : List_Id := No_List;
2812 -- In case of a function, the inner declarations are needed since
2813 -- the result may be unconstrained.
2815 Excep_Handler : Node_Id;
2816 Excep_Choice : Entity_Id;
2817 Excep_Code : List_Id;
2819 Parameter_List : constant List_Id := New_List;
2820 -- List of parameters to be passed to the subprogram
2822 Current_Parameter : Node_Id;
2824 Ordered_Parameters_List : constant List_Id :=
2825 Build_Ordered_Parameters_List
2826 (Specification (Vis_Decl));
2828 Subp_Spec : Node_Id;
2829 -- Subprogram specification
2831 Called_Subprogram : Node_Id;
2832 -- The subprogram to call
2834 Null_Raise_Statement : Node_Id;
2836 Dynamic_Async : Entity_Id;
2839 if RACW_Type /= Empty then
2840 Called_Subprogram :=
2841 New_Occurrence_Of (Parent_Primitive, Loc);
2843 Called_Subprogram :=
2845 Defining_Unit_Name (Specification (Vis_Decl)), Loc);
2849 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2851 if Dynamically_Asynchronous then
2853 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2855 Dynamic_Async := Empty;
2858 if not Asynchronous or else Dynamically_Asynchronous then
2860 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
2862 -- The first statement after the subprogram call is a statement to
2863 -- writes a Null_Occurrence into the result stream.
2865 Null_Raise_Statement :=
2866 Make_Attribute_Reference (Loc,
2868 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
2869 Attribute_Name => Name_Write,
2870 Expressions => New_List (
2871 New_Occurrence_Of (Result_Parameter, Loc),
2872 New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
2874 if Dynamically_Asynchronous then
2875 Null_Raise_Statement :=
2876 Make_Implicit_If_Statement (Vis_Decl,
2878 Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
2879 Then_Statements => New_List (Null_Raise_Statement));
2882 Append_To (After_Statements, Null_Raise_Statement);
2885 Result_Parameter := Empty;
2888 -- Loop through every parameter and get its value from the stream. If
2889 -- the parameter is unconstrained, then the parameter is read using
2890 -- 'Input at the point of declaration.
2892 Current_Parameter := First (Ordered_Parameters_List);
2894 while Current_Parameter /= Empty loop
2898 Constrained : Boolean;
2900 Expr : Node_Id := Empty;
2903 Object := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2904 Set_Ekind (Object, E_Variable);
2907 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2909 -- We have a controlling formal parameter. Read its address
2910 -- rather than a real object. The address is in Unsigned_64
2913 Etyp := RTE (RE_Unsigned_64);
2915 Etyp := Etype (Parameter_Type (Current_Parameter));
2919 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
2921 if In_Present (Current_Parameter)
2922 or else not Out_Present (Current_Parameter)
2923 or else not Constrained
2925 -- If an input parameter is contrained, then its reading is
2926 -- deferred until the beginning of the subprogram body. If
2927 -- it is unconstrained, then an expression is built for
2928 -- the object declaration and the variable is set using
2929 -- 'Input instead of 'Read.
2932 Append_To (Statements,
2933 Make_Attribute_Reference (Loc,
2934 Prefix => New_Occurrence_Of (Etyp, Loc),
2935 Attribute_Name => Name_Read,
2936 Expressions => New_List (
2937 New_Occurrence_Of (Stream_Parameter, Loc),
2938 New_Occurrence_Of (Object, Loc))));
2941 Expr := Input_With_Tag_Check (Loc,
2943 Stream => Stream_Parameter);
2944 Append_To (Decls, Expr);
2945 Expr := Make_Function_Call (Loc,
2946 New_Occurrence_Of (Defining_Unit_Name
2947 (Specification (Expr)), Loc));
2951 -- If we do not have to output the current parameter, then
2952 -- it can well be flagged as constant. This may allow further
2953 -- optimizations done by the back end.
2956 Make_Object_Declaration (Loc,
2957 Defining_Identifier => Object,
2959 not Constrained and then not Out_Present (Current_Parameter),
2960 Object_Definition =>
2961 New_Occurrence_Of (Etyp, Loc),
2962 Expression => Expr));
2964 -- An out parameter may be written back using a 'Write
2965 -- attribute instead of a 'Output because it has been
2966 -- constrained by the parameter given to the caller. Note that
2967 -- out controlling arguments in the case of a RACW are not put
2968 -- back in the stream because the pointer on them has not
2971 if Out_Present (Current_Parameter)
2973 Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
2975 Append_To (After_Statements,
2976 Make_Attribute_Reference (Loc,
2977 Prefix => New_Occurrence_Of (Etyp, Loc),
2978 Attribute_Name => Name_Write,
2979 Expressions => New_List (
2980 New_Occurrence_Of (Result_Parameter, Loc),
2981 New_Occurrence_Of (Object, Loc))));
2985 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2988 if Nkind (Parameter_Type (Current_Parameter)) /=
2991 Append_To (Parameter_List,
2992 Make_Parameter_Association (Loc,
2995 Defining_Identifier (Current_Parameter), Loc),
2996 Explicit_Actual_Parameter =>
2997 Make_Explicit_Dereference (Loc,
2998 Unchecked_Convert_To (RACW_Type,
2999 OK_Convert_To (RTE (RE_Address),
3000 New_Occurrence_Of (Object, Loc))))));
3002 Append_To (Parameter_List,
3003 Make_Parameter_Association (Loc,
3006 Defining_Identifier (Current_Parameter), Loc),
3007 Explicit_Actual_Parameter =>
3008 Unchecked_Convert_To (RACW_Type,
3009 OK_Convert_To (RTE (RE_Address),
3010 New_Occurrence_Of (Object, Loc)))));
3013 Append_To (Parameter_List,
3014 Make_Parameter_Association (Loc,
3017 Defining_Identifier (Current_Parameter), Loc),
3018 Explicit_Actual_Parameter =>
3019 New_Occurrence_Of (Object, Loc)));
3022 -- If the current parameter needs an extra formal, then read it
3023 -- from the stream and set the corresponding semantic field in
3024 -- the variable. If the kind of the parameter identifier is
3025 -- E_Void, then this is a compiler generated parameter that
3026 -- doesn't need an extra constrained status.
3028 -- The case of Extra_Accessibility should also be handled ???
3030 if Nkind (Parameter_Type (Current_Parameter)) /=
3033 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
3035 Present (Extra_Constrained
3036 (Defining_Identifier (Current_Parameter)))
3039 Extra_Parameter : constant Entity_Id :=
3041 (Defining_Identifier
3042 (Current_Parameter));
3044 Formal_Entity : constant Entity_Id :=
3045 Make_Defining_Identifier
3046 (Loc, Chars (Extra_Parameter));
3048 Formal_Type : constant Entity_Id :=
3049 Etype (Extra_Parameter);
3053 Make_Object_Declaration (Loc,
3054 Defining_Identifier => Formal_Entity,
3055 Object_Definition =>
3056 New_Occurrence_Of (Formal_Type, Loc)));
3058 Append_To (Extra_Formal_Statements,
3059 Make_Attribute_Reference (Loc,
3060 Prefix => New_Occurrence_Of (Formal_Type, Loc),
3061 Attribute_Name => Name_Read,
3062 Expressions => New_List (
3063 New_Occurrence_Of (Stream_Parameter, Loc),
3064 New_Occurrence_Of (Formal_Entity, Loc))));
3065 Set_Extra_Constrained (Object, Formal_Entity);
3070 Next (Current_Parameter);
3073 -- Append the formal statements list at the end of regular statements
3075 Append_List_To (Statements, Extra_Formal_Statements);
3077 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
3079 -- The remote subprogram is a function. We build an inner block to
3080 -- be able to hold a potentially unconstrained result in a variable.
3083 Etyp : constant Entity_Id :=
3084 Etype (Subtype_Mark (Specification (Vis_Decl)));
3085 Result : constant Node_Id :=
3086 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3089 Inner_Decls := New_List (
3090 Make_Object_Declaration (Loc,
3091 Defining_Identifier => Result,
3092 Constant_Present => True,
3093 Object_Definition => New_Occurrence_Of (Etyp, Loc),
3095 Make_Function_Call (Loc,
3096 Name => Called_Subprogram,
3097 Parameter_Associations => Parameter_List)));
3099 Append_To (After_Statements,
3100 Make_Attribute_Reference (Loc,
3101 Prefix => New_Occurrence_Of (Etyp, Loc),
3102 Attribute_Name => Name_Output,
3103 Expressions => New_List (
3104 New_Occurrence_Of (Result_Parameter, Loc),
3105 New_Occurrence_Of (Result, Loc))));
3108 Append_To (Statements,
3109 Make_Block_Statement (Loc,
3110 Declarations => Inner_Decls,
3111 Handled_Statement_Sequence =>
3112 Make_Handled_Sequence_Of_Statements (Loc,
3113 Statements => After_Statements)));
3116 -- The remote subprogram is a procedure. We do not need any inner
3117 -- block in this case.
3119 if Dynamically_Asynchronous then
3121 Make_Object_Declaration (Loc,
3122 Defining_Identifier => Dynamic_Async,
3123 Object_Definition =>
3124 New_Occurrence_Of (Standard_Boolean, Loc)));
3126 Append_To (Statements,
3127 Make_Attribute_Reference (Loc,
3128 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
3129 Attribute_Name => Name_Read,
3130 Expressions => New_List (
3131 New_Occurrence_Of (Stream_Parameter, Loc),
3132 New_Occurrence_Of (Dynamic_Async, Loc))));
3135 Append_To (Statements,
3136 Make_Procedure_Call_Statement (Loc,
3137 Name => Called_Subprogram,
3138 Parameter_Associations => Parameter_List));
3140 Append_List_To (Statements, After_Statements);
3144 if Asynchronous and then not Dynamically_Asynchronous then
3146 -- An asynchronous procedure does not want a Result
3147 -- parameter. Also, we put an exception handler with an others
3148 -- clause that does nothing.
3151 Make_Procedure_Specification (Loc,
3152 Defining_Unit_Name =>
3153 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3154 Parameter_Specifications => New_List (
3155 Make_Parameter_Specification (Loc,
3156 Defining_Identifier => Stream_Parameter,
3158 Make_Access_Definition (Loc,
3160 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3163 Make_Exception_Handler (Loc,
3164 Exception_Choices =>
3165 New_List (Make_Others_Choice (Loc)),
3166 Statements => New_List (
3167 Make_Null_Statement (Loc)));
3170 -- In the other cases, if an exception is raised, then the
3171 -- exception occurrence is copied into the output stream and
3172 -- no other output parameter is written.
3175 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3177 Excep_Code := New_List (
3178 Make_Attribute_Reference (Loc,
3180 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3181 Attribute_Name => Name_Write,
3182 Expressions => New_List (
3183 New_Occurrence_Of (Result_Parameter, Loc),
3184 New_Occurrence_Of (Excep_Choice, Loc))));
3186 if Dynamically_Asynchronous then
3187 Excep_Code := New_List (
3188 Make_Implicit_If_Statement (Vis_Decl,
3189 Condition => Make_Op_Not (Loc,
3190 New_Occurrence_Of (Dynamic_Async, Loc)),
3191 Then_Statements => Excep_Code));
3195 Make_Exception_Handler (Loc,
3196 Choice_Parameter => Excep_Choice,
3197 Exception_Choices => New_List (Make_Others_Choice (Loc)),
3198 Statements => Excep_Code);
3201 Make_Procedure_Specification (Loc,
3202 Defining_Unit_Name =>
3203 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
3205 Parameter_Specifications => New_List (
3206 Make_Parameter_Specification (Loc,
3207 Defining_Identifier => Stream_Parameter,
3209 Make_Access_Definition (Loc,
3211 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc))),
3213 Make_Parameter_Specification (Loc,
3214 Defining_Identifier => Result_Parameter,
3216 Make_Access_Definition (Loc,
3218 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc)))));
3222 Make_Subprogram_Body (Loc,
3223 Specification => Subp_Spec,
3224 Declarations => Decls,
3225 Handled_Statement_Sequence =>
3226 Make_Handled_Sequence_Of_Statements (Loc,
3227 Statements => Statements,
3228 Exception_Handlers => New_List (Excep_Handler)));
3230 end Build_Subprogram_Receiving_Stubs;
3232 ------------------------
3233 -- Copy_Specification --
3234 ------------------------
3236 function Copy_Specification
3239 Object_Type : Entity_Id := Empty;
3240 Stub_Type : Entity_Id := Empty;
3241 New_Name : Name_Id := No_Name)
3244 Parameters : List_Id := No_List;
3246 Current_Parameter : Node_Id;
3247 Current_Type : Node_Id;
3248 Current_Etype : Entity_Id;
3250 Name_For_New_Spec : Name_Id;
3252 New_Identifier : Entity_Id;
3255 if New_Name = No_Name then
3256 Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
3258 Name_For_New_Spec := New_Name;
3261 if Present (Parameter_Specifications (Spec)) then
3263 Parameters := New_List;
3264 Current_Parameter := First (Parameter_Specifications (Spec));
3266 while Current_Parameter /= Empty loop
3268 Current_Type := Parameter_Type (Current_Parameter);
3270 if Nkind (Current_Type) = N_Access_Definition then
3271 Current_Etype := Entity (Subtype_Mark (Current_Type));
3273 if Object_Type = Empty then
3275 Make_Access_Definition (Loc,
3277 New_Occurrence_Of (Current_Etype, Loc));
3280 (Root_Type (Current_Etype) = Root_Type (Object_Type));
3282 Make_Access_Definition (Loc,
3283 Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc));
3287 Current_Etype := Entity (Current_Type);
3289 if Object_Type /= Empty
3290 and then Current_Etype = Object_Type
3292 Current_Type := New_Occurrence_Of (Stub_Type, Loc);
3294 Current_Type := New_Occurrence_Of (Current_Etype, Loc);
3298 New_Identifier := Make_Defining_Identifier (Loc,
3299 Chars (Defining_Identifier (Current_Parameter)));
3301 Append_To (Parameters,
3302 Make_Parameter_Specification (Loc,
3303 Defining_Identifier => New_Identifier,
3304 Parameter_Type => Current_Type,
3305 In_Present => In_Present (Current_Parameter),
3306 Out_Present => Out_Present (Current_Parameter),
3308 New_Copy_Tree (Expression (Current_Parameter))));
3310 Next (Current_Parameter);
3314 if Nkind (Spec) = N_Function_Specification then
3316 Make_Function_Specification (Loc,
3317 Defining_Unit_Name =>
3318 Make_Defining_Identifier (Loc,
3319 Chars => Name_For_New_Spec),
3320 Parameter_Specifications => Parameters,
3322 New_Occurrence_Of (Entity (Subtype_Mark (Spec)), Loc));
3326 Make_Procedure_Specification (Loc,
3327 Defining_Unit_Name =>
3328 Make_Defining_Identifier (Loc,
3329 Chars => Name_For_New_Spec),
3330 Parameter_Specifications => Parameters);
3333 end Copy_Specification;
3335 ---------------------------
3336 -- Could_Be_Asynchronous --
3337 ---------------------------
3339 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
3340 Current_Parameter : Node_Id;
3343 if Present (Parameter_Specifications (Spec)) then
3344 Current_Parameter := First (Parameter_Specifications (Spec));
3345 while Current_Parameter /= Empty loop
3346 if Out_Present (Current_Parameter) then
3350 Next (Current_Parameter);
3355 end Could_Be_Asynchronous;
3357 ---------------------------------------------
3358 -- Expand_All_Calls_Remote_Subprogram_Call --
3359 ---------------------------------------------
3361 procedure Expand_All_Calls_Remote_Subprogram_Call (N : in Node_Id) is
3362 Called_Subprogram : constant Entity_Id := Entity (Name (N));
3363 RCI_Package : constant Entity_Id := Scope (Called_Subprogram);
3364 Loc : constant Source_Ptr := Sloc (N);
3365 RCI_Locator : Node_Id;
3366 RCI_Cache : Entity_Id;
3367 Calling_Stubs : Node_Id;
3368 E_Calling_Stubs : Entity_Id;
3371 E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
3373 if E_Calling_Stubs = Empty then
3374 RCI_Cache := RCI_Locator_Table.Get (RCI_Package);
3376 if RCI_Cache = Empty then
3379 (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
3380 Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator);
3382 -- The RCI_Locator package is inserted at the top level in the
3383 -- current unit, and must appear in the proper scope, so that it
3384 -- is not prematurely removed by the GCC back-end.
3387 Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
3390 if Ekind (Scop) = E_Package_Body then
3391 New_Scope (Spec_Entity (Scop));
3393 elsif Ekind (Scop) = E_Subprogram_Body then
3395 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
3401 Analyze (RCI_Locator);
3405 RCI_Cache := Defining_Unit_Name (RCI_Locator);
3408 RCI_Locator := Parent (RCI_Cache);
3411 Calling_Stubs := Build_Subprogram_Calling_Stubs
3412 (Vis_Decl => Parent (Parent (Called_Subprogram)),
3413 Subp_Id => Get_Subprogram_Id (Called_Subprogram),
3414 Asynchronous => Nkind (N) = N_Procedure_Call_Statement
3416 Is_Asynchronous (Called_Subprogram),
3417 Locator => RCI_Cache,
3418 New_Name => New_Internal_Name ('S'));
3419 Insert_After (RCI_Locator, Calling_Stubs);
3420 Analyze (Calling_Stubs);
3421 E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
3424 Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
3425 end Expand_All_Calls_Remote_Subprogram_Call;
3427 ---------------------------------
3428 -- Expand_Calling_Stubs_Bodies --
3429 ---------------------------------
3431 procedure Expand_Calling_Stubs_Bodies (Unit_Node : in Node_Id) is
3432 Spec : constant Node_Id := Specification (Unit_Node);
3433 Decls : constant List_Id := Visible_Declarations (Spec);
3436 New_Scope (Scope_Of_Spec (Spec));
3437 Add_Calling_Stubs_To_Declarations (Specification (Unit_Node),
3440 end Expand_Calling_Stubs_Bodies;
3442 -----------------------------------
3443 -- Expand_Receiving_Stubs_Bodies --
3444 -----------------------------------
3446 procedure Expand_Receiving_Stubs_Bodies (Unit_Node : in Node_Id) is
3452 if Nkind (Unit_Node) = N_Package_Declaration then
3453 Spec := Specification (Unit_Node);
3454 Decls := Visible_Declarations (Spec);
3455 New_Scope (Scope_Of_Spec (Spec));
3456 Add_Receiving_Stubs_To_Declarations (Spec, Decls);
3460 Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
3461 Decls := Declarations (Unit_Node);
3462 New_Scope (Scope_Of_Spec (Unit_Node));
3464 Add_Receiving_Stubs_To_Declarations (Spec, Temp);
3465 Insert_List_Before (First (Decls), Temp);
3469 end Expand_Receiving_Stubs_Bodies;
3471 ----------------------------
3472 -- Get_Pkg_Name_string_Id --
3473 ----------------------------
3475 function Get_Pkg_Name_String_Id (Decl_Node : Node_Id) return String_Id is
3476 Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node);
3479 Get_Unit_Name_String (Unit_Name_Id);
3481 -- Remove seven last character (" (spec)" or " (body)").
3483 Name_Len := Name_Len - 7;
3484 pragma Assert (Name_Buffer (Name_Len + 1) = ' ');
3486 return Get_String_Id (Name_Buffer (1 .. Name_Len));
3487 end Get_Pkg_Name_String_Id;
3493 function Get_String_Id (Val : String) return String_Id is
3496 Store_String_Chars (Val);
3500 -----------------------
3501 -- Get_Subprogram_Id --
3502 -----------------------
3504 function Get_Subprogram_Id (E : Entity_Id) return Int is
3505 Current_Declaration : Node_Id;
3510 (Is_Remote_Call_Interface (Scope (E))
3512 (Nkind (Parent (E)) = N_Procedure_Specification
3514 Nkind (Parent (E)) = N_Function_Specification));
3516 Current_Declaration :=
3517 First (Visible_Declarations
3518 (Package_Specification_Of_Scope (Scope (E))));
3520 while Current_Declaration /= Empty loop
3521 if Nkind (Current_Declaration) = N_Subprogram_Declaration
3522 and then Comes_From_Source (Current_Declaration)
3524 if Defining_Unit_Name
3525 (Specification (Current_Declaration)) = E
3530 Result := Result + 1;
3533 Next (Current_Declaration);
3536 -- Error if we do not find it
3538 raise Program_Error;
3539 end Get_Subprogram_Id;
3545 function Hash (F : Entity_Id) return Hash_Index is
3547 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
3550 --------------------------
3551 -- Input_With_Tag_Check --
3552 --------------------------
3554 function Input_With_Tag_Check
3556 Var_Type : Entity_Id;
3562 Make_Subprogram_Body (Loc,
3563 Specification => Make_Function_Specification (Loc,
3564 Defining_Unit_Name =>
3565 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
3566 Subtype_Mark => New_Occurrence_Of (Var_Type, Loc)),
3567 Declarations => No_List,
3568 Handled_Statement_Sequence =>
3569 Make_Handled_Sequence_Of_Statements (Loc, New_List (
3570 Make_Tag_Check (Loc,
3571 Make_Return_Statement (Loc,
3572 Make_Attribute_Reference (Loc,
3573 Prefix => New_Occurrence_Of (Var_Type, Loc),
3574 Attribute_Name => Name_Input,
3576 New_List (New_Occurrence_Of (Stream, Loc))))))));
3577 end Input_With_Tag_Check;
3579 --------------------------------
3580 -- Is_RACW_Controlling_Formal --
3581 --------------------------------
3583 function Is_RACW_Controlling_Formal
3584 (Parameter : Node_Id;
3585 Stub_Type : Entity_Id)
3591 -- If the kind of the parameter is E_Void, then it is not a
3592 -- controlling formal (this can happen in the context of RAS).
3594 if Ekind (Defining_Identifier (Parameter)) = E_Void then
3598 -- If the parameter is not a controlling formal, then it cannot
3599 -- be possibly a RACW_Controlling_Formal.
3601 if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
3605 Typ := Parameter_Type (Parameter);
3606 return (Nkind (Typ) = N_Access_Definition
3607 and then Etype (Subtype_Mark (Typ)) = Stub_Type)
3608 or else Etype (Typ) = Stub_Type;
3609 end Is_RACW_Controlling_Formal;
3611 --------------------
3612 -- Make_Tag_Check --
3613 --------------------
3615 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
3616 Occ : constant Entity_Id :=
3617 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3620 return Make_Block_Statement (Loc,
3621 Handled_Statement_Sequence =>
3622 Make_Handled_Sequence_Of_Statements (Loc,
3623 Statements => New_List (N),
3625 Exception_Handlers => New_List (
3626 Make_Exception_Handler (Loc,
3627 Choice_Parameter => Occ,
3629 Exception_Choices =>
3630 New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
3633 New_List (Make_Procedure_Call_Statement (Loc,
3635 (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
3636 New_List (New_Occurrence_Of (Occ, Loc))))))));
3639 ----------------------------
3640 -- Need_Extra_Constrained --
3641 ----------------------------
3643 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
3644 Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
3647 return Out_Present (Parameter)
3648 and then Has_Discriminants (Etyp)
3649 and then not Is_Constrained (Etyp)
3650 and then not Is_Indefinite_Subtype (Etyp);
3651 end Need_Extra_Constrained;
3653 ------------------------------------
3654 -- Pack_Entity_Into_Stream_Access --
3655 ------------------------------------
3657 function Pack_Entity_Into_Stream_Access
3661 Etyp : Entity_Id := Empty)
3667 if Etyp /= Empty then
3670 Typ := Etype (Object);
3674 Pack_Node_Into_Stream_Access (Loc,
3676 Object => New_Occurrence_Of (Object, Loc),
3678 end Pack_Entity_Into_Stream_Access;
3680 ---------------------------
3681 -- Pack_Node_Into_Stream --
3682 ---------------------------
3684 function Pack_Node_Into_Stream
3691 Write_Attribute : Name_Id := Name_Write;
3694 if not Is_Constrained (Etyp) then
3695 Write_Attribute := Name_Output;
3699 Make_Attribute_Reference (Loc,
3700 Prefix => New_Occurrence_Of (Etyp, Loc),
3701 Attribute_Name => Write_Attribute,
3702 Expressions => New_List (
3703 Make_Attribute_Reference (Loc,
3704 Prefix => New_Occurrence_Of (Stream, Loc),
3705 Attribute_Name => Name_Access),
3707 end Pack_Node_Into_Stream;
3709 ----------------------------------
3710 -- Pack_Node_Into_Stream_Access --
3711 ----------------------------------
3713 function Pack_Node_Into_Stream_Access
3720 Write_Attribute : Name_Id := Name_Write;
3723 if not Is_Constrained (Etyp) then
3724 Write_Attribute := Name_Output;
3728 Make_Attribute_Reference (Loc,
3729 Prefix => New_Occurrence_Of (Etyp, Loc),
3730 Attribute_Name => Write_Attribute,
3731 Expressions => New_List (
3734 end Pack_Node_Into_Stream_Access;
3736 -------------------------------
3737 -- RACW_Type_Is_Asynchronous --
3738 -------------------------------
3740 procedure RACW_Type_Is_Asynchronous (RACW_Type : in Entity_Id) is
3741 N : constant Node_Id := Asynchronous_Flags_Table.Get (RACW_Type);
3742 pragma Assert (N /= Empty);
3745 Replace (N, New_Occurrence_Of (Standard_True, Sloc (N)));
3746 end RACW_Type_Is_Asynchronous;
3748 -------------------------
3749 -- RCI_Package_Locator --
3750 -------------------------
3752 function RCI_Package_Locator
3754 Package_Spec : Node_Id)
3757 Inst : constant Node_Id :=
3758 Make_Package_Instantiation (Loc,
3759 Defining_Unit_Name =>
3760 Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
3762 New_Occurrence_Of (RTE (RE_RCI_Info), Loc),
3763 Generic_Associations => New_List (
3764 Make_Generic_Association (Loc,
3766 Make_Identifier (Loc, Name_RCI_Name),
3767 Explicit_Generic_Actual_Parameter =>
3768 Make_String_Literal (Loc,
3769 Strval => Get_Pkg_Name_String_Id (Package_Spec)))));
3772 RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
3773 Defining_Unit_Name (Inst));
3775 end RCI_Package_Locator;
3777 -----------------------------------------------
3778 -- Remote_Types_Tagged_Full_View_Encountered --
3779 -----------------------------------------------
3781 procedure Remote_Types_Tagged_Full_View_Encountered
3782 (Full_View : in Entity_Id)
3784 Stub_Elements : constant Stub_Structure :=
3785 Stubs_Table.Get (Full_View);
3788 if Stub_Elements /= Empty_Stub_Structure then
3789 Add_RACW_Primitive_Declarations_And_Bodies
3791 Parent (Declaration_Node (Stub_Elements.Object_RPC_Receiver)),
3792 List_Containing (Declaration_Node (Full_View)));
3794 end Remote_Types_Tagged_Full_View_Encountered;
3800 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
3801 Unit_Name : Node_Id := Defining_Unit_Name (Spec);
3804 while Nkind (Unit_Name) /= N_Defining_Identifier loop
3805 Unit_Name := Defining_Identifier (Unit_Name);