* Mainline merge as of 2006-02-16 (@111136).
[official-gcc.git] / gcc / ada / exp_dist.adb
blob666cd9d3b95da899ffc73d982072dc02b95579ca
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P_ D I S T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
10 -- --
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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
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;
34 with Lib; use Lib;
35 with Namet; use Namet;
36 with Nlists; use Nlists;
37 with Nmake; use Nmake;
38 with Opt; use Opt;
39 with Rtsfind; use Rtsfind;
40 with Sem; use Sem;
41 with Sem_Ch3; use Sem_Ch3;
42 with Sem_Ch8; use Sem_Ch8;
43 with Sem_Dist; use Sem_Dist;
44 with Sem_Eval; use Sem_Eval;
45 with Sem_Util; use Sem_Util;
46 with Sinfo; use Sinfo;
47 with Snames; use Snames;
48 with Stand; use Stand;
49 with Stringt; use Stringt;
50 with Tbuild; use Tbuild;
51 with Ttypes; use Ttypes;
52 with Uintp; use Uintp;
54 package body Exp_Dist is
56 -- The following model has been used to implement distributed objects:
57 -- given a designated type D and a RACW type R, then a record of the
58 -- form:
60 -- type Stub is tagged record
61 -- [...declaration similar to s-parint.ads RACW_Stub_Type...]
62 -- end record;
64 -- is built. This type has two properties:
66 -- 1) Since it has the same structure than RACW_Stub_Type, it can be
67 -- converted to and from this type to make it suitable for
68 -- System.Partition_Interface.Get_Unique_Remote_Pointer in order
69 -- to avoid memory leaks when the same remote object arrive on the
70 -- same partition through several paths;
72 -- 2) It also has the same dispatching table as the designated type D,
73 -- and thus can be used as an object designated by a value of type
74 -- R on any partition other than the one on which the object has
75 -- been created, since only dispatching calls will be performed and
76 -- the fields themselves will not be used. We call Derive_Subprograms
77 -- to fake half a derivation to ensure that the subprograms do have
78 -- the same dispatching table.
80 First_RCI_Subprogram_Id : constant := 2;
81 -- RCI subprograms are numbered starting at 2. The RCI receiver for
82 -- an RCI package can thus identify calls received through remote
83 -- access-to-subprogram dereferences by the fact that they have a
84 -- (primitive) subprogram id of 0, and 1 is used for the internal
85 -- RAS information lookup operation. (This is for the Garlic code
86 -- generation, where subprograms are identified by numbers; in the
87 -- PolyORB version, they are identified by name, with a numeric suffix
88 -- for homonyms.)
90 type Hash_Index is range 0 .. 50;
92 -----------------------
93 -- Local subprograms --
94 -----------------------
96 function Hash (F : Entity_Id) return Hash_Index;
97 -- DSA expansion associates stubs to distributed object types using
98 -- a hash table on entity ids.
100 function Hash (F : Name_Id) return Hash_Index;
101 -- The generation of subprogram identifiers requires an overload counter
102 -- to be associated with each remote subprogram names. These counters
103 -- are maintained in a hash table on name ids.
105 type Subprogram_Identifiers is record
106 Str_Identifier : String_Id;
107 Int_Identifier : Int;
108 end record;
110 package Subprogram_Identifier_Table is
111 new Simple_HTable (Header_Num => Hash_Index,
112 Element => Subprogram_Identifiers,
113 No_Element => (No_String, 0),
114 Key => Entity_Id,
115 Hash => Hash,
116 Equal => "=");
117 -- Mapping between a remote subprogram and the corresponding
118 -- subprogram identifiers.
120 package Overload_Counter_Table is
121 new Simple_HTable (Header_Num => Hash_Index,
122 Element => Int,
123 No_Element => 0,
124 Key => Name_Id,
125 Hash => Hash,
126 Equal => "=");
127 -- Mapping between a subprogram name and an integer that
128 -- counts the number of defining subprogram names with that
129 -- Name_Id encountered so far in a given context (an interface).
131 function Get_Subprogram_Ids (Def : Entity_Id) return Subprogram_Identifiers;
132 function Get_Subprogram_Id (Def : Entity_Id) return String_Id;
133 function Get_Subprogram_Id (Def : Entity_Id) return Int;
134 -- Given a subprogram defined in a RCI package, get its distribution
135 -- subprogram identifiers (the distribution identifiers are a unique
136 -- subprogram number, and the non-qualified subprogram name, in the
137 -- casing used for the subprogram declaration; if the name is overloaded,
138 -- a double underscore and a serial number are appended.
140 -- The integer identifier is used to perform remote calls with GARLIC;
141 -- the string identifier is used in the case of PolyORB.
143 -- Although the PolyORB DSA receiving stubs will make a caseless comparison
144 -- when receiving a call, the calling stubs will create requests with the
145 -- exact casing of the defining unit name of the called subprogram, so as
146 -- to allow calls to subprograms on distributed nodes that do distinguish
147 -- between casings.
149 -- NOTE: Another design would be to allow a representation clause on
150 -- subprogram specs: for Subp'Distribution_Identifier use "fooBar";
152 pragma Warnings (Off, Get_Subprogram_Id);
153 -- One homonym only is unreferenced (specific to the GARLIC version)
155 procedure Add_RAS_Dereference_TSS (N : Node_Id);
156 -- Add a subprogram body for RAS Dereference TSS
158 procedure Add_RAS_Proxy_And_Analyze
159 (Decls : List_Id;
160 Vis_Decl : Node_Id;
161 All_Calls_Remote_E : Entity_Id;
162 Proxy_Object_Addr : out Entity_Id);
163 -- Add the proxy type necessary to call the subprogram declared
164 -- by Vis_Decl through a remote access to subprogram type.
165 -- All_Calls_Remote_E must be Standard_True if a pragma All_Calls_Remote
166 -- applies, Standard_False otherwise. The new proxy type is appended
167 -- to Decls. Proxy_Object_Addr is a constant of type System.Address that
168 -- designates an instance of the proxy object.
170 function Build_Remote_Subprogram_Proxy_Type
171 (Loc : Source_Ptr;
172 ACR_Expression : Node_Id) return Node_Id;
173 -- Build and return a tagged record type definition for an RCI
174 -- subprogram proxy type.
175 -- ACR_Expression is use as the initialization value for
176 -- the All_Calls_Remote component.
178 function Build_Get_Unique_RP_Call
179 (Loc : Source_Ptr;
180 Pointer : Entity_Id;
181 Stub_Type : Entity_Id) return List_Id;
182 -- Build a call to Get_Unique_Remote_Pointer (Pointer), followed by a
183 -- tag fixup (Get_Unique_Remote_Pointer may have changed Pointer'Tag to
184 -- RACW_Stub_Type'Tag, while the desired tag is that of Stub_Type).
186 function Build_Subprogram_Calling_Stubs
187 (Vis_Decl : Node_Id;
188 Subp_Id : Node_Id;
189 Asynchronous : Boolean;
190 Dynamically_Asynchronous : Boolean := False;
191 Stub_Type : Entity_Id := Empty;
192 RACW_Type : Entity_Id := Empty;
193 Locator : Entity_Id := Empty;
194 New_Name : Name_Id := No_Name) return Node_Id;
195 -- Build the calling stub for a given subprogram with the subprogram ID
196 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
197 -- parameters of this type will be marshalled instead of the object
198 -- itself. It will then be converted into Stub_Type before performing
199 -- the real call. If Dynamically_Asynchronous is True, then it will be
200 -- computed at run time whether the call is asynchronous or not.
201 -- Otherwise, the value of the formal Asynchronous will be used.
202 -- If Locator is not Empty, it will be used instead of RCI_Cache. If
203 -- New_Name is given, then it will be used instead of the original name.
205 function Build_RPC_Receiver_Specification
206 (RPC_Receiver : Entity_Id;
207 Request_Parameter : Entity_Id) return Node_Id;
208 -- Make a subprogram specification for an RPC receiver, with the given
209 -- defining unit name and formal parameter.
211 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
212 -- Return an ordered parameter list: unconstrained parameters are put
213 -- at the beginning of the list and constrained ones are put after. If
214 -- there are no parameters, an empty list is returned. Special case:
215 -- the controlling formal of the equivalent RACW operation for a RAS
216 -- type is always left in first position.
218 procedure Add_Calling_Stubs_To_Declarations
219 (Pkg_Spec : Node_Id;
220 Decls : List_Id);
221 -- Add calling stubs to the declarative part
223 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
224 -- Return True if nothing prevents the program whose specification is
225 -- given to be asynchronous (i.e. no out parameter).
227 function Pack_Entity_Into_Stream_Access
228 (Loc : Source_Ptr;
229 Stream : Node_Id;
230 Object : Entity_Id;
231 Etyp : Entity_Id := Empty) return Node_Id;
232 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
233 -- then Etype (Object) will be used if present. If the type is
234 -- constrained, then 'Write will be used to output the object,
235 -- If the type is unconstrained, 'Output will be used.
237 function Pack_Node_Into_Stream
238 (Loc : Source_Ptr;
239 Stream : Entity_Id;
240 Object : Node_Id;
241 Etyp : Entity_Id) return Node_Id;
242 -- Similar to above, with an arbitrary node instead of an entity
244 function Pack_Node_Into_Stream_Access
245 (Loc : Source_Ptr;
246 Stream : Node_Id;
247 Object : Node_Id;
248 Etyp : Entity_Id) return Node_Id;
249 -- Similar to above, with Stream instead of Stream'Access
251 function Make_Selected_Component
252 (Loc : Source_Ptr;
253 Prefix : Entity_Id;
254 Selector_Name : Name_Id) return Node_Id;
255 -- Return a selected_component whose prefix denotes the given entity,
256 -- and with the given Selector_Name.
258 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
259 -- Return the scope represented by a given spec
261 procedure Set_Renaming_TSS
262 (Typ : Entity_Id;
263 Nam : Entity_Id;
264 TSS_Nam : TSS_Name_Type);
265 -- Create a renaming declaration of subprogram Nam,
266 -- and register it as a TSS for Typ with name TSS_Nam.
268 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
269 -- Return True if the current parameter needs an extra formal to reflect
270 -- its constrained status.
272 function Is_RACW_Controlling_Formal
273 (Parameter : Node_Id;
274 Stub_Type : Entity_Id) return Boolean;
275 -- Return True if the current parameter is a controlling formal argument
276 -- of type Stub_Type or access to Stub_Type.
278 procedure Declare_Create_NVList
279 (Loc : Source_Ptr;
280 NVList : Entity_Id;
281 Decls : List_Id;
282 Stmts : List_Id);
283 -- Append the declaration of NVList to Decls, and its
284 -- initialization to Stmts.
286 function Add_Parameter_To_NVList
287 (Loc : Source_Ptr;
288 NVList : Entity_Id;
289 Parameter : Entity_Id;
290 Constrained : Boolean;
291 RACW_Ctrl : Boolean := False;
292 Any : Entity_Id) return Node_Id;
293 -- Return a call to Add_Item to add the Any corresponding
294 -- to the designated formal Parameter (with the indicated
295 -- Constrained status) to NVList. RACW_Ctrl must be set to
296 -- True for controlling formals of distributed object primitive
297 -- operations.
299 type Stub_Structure is record
300 Stub_Type : Entity_Id;
301 Stub_Type_Access : Entity_Id;
302 RPC_Receiver_Decl : Node_Id;
303 RACW_Type : Entity_Id;
304 end record;
305 -- This structure is necessary because of the two phases analysis of
306 -- a RACW declaration occurring in the same Remote_Types package as the
307 -- designated type. RACW_Type is any of the RACW types pointing on this
308 -- designated type, it is used here to save an anonymous type creation
309 -- for each primitive operation.
311 -- For a RACW that implements a RAS, no object RPC receiver is generated.
312 -- Instead, RPC_Receiver_Decl is the declaration after which the
313 -- RPC receiver would have been inserted.
315 Empty_Stub_Structure : constant Stub_Structure :=
316 (Empty, Empty, Empty, Empty);
318 package Stubs_Table is
319 new Simple_HTable (Header_Num => Hash_Index,
320 Element => Stub_Structure,
321 No_Element => Empty_Stub_Structure,
322 Key => Entity_Id,
323 Hash => Hash,
324 Equal => "=");
325 -- Mapping between a RACW designated type and its stub type
327 package Asynchronous_Flags_Table is
328 new Simple_HTable (Header_Num => Hash_Index,
329 Element => Entity_Id,
330 No_Element => Empty,
331 Key => Entity_Id,
332 Hash => Hash,
333 Equal => "=");
334 -- Mapping between a RACW type and a constant having the value True
335 -- if the RACW is asynchronous and False otherwise.
337 package RCI_Locator_Table is
338 new Simple_HTable (Header_Num => Hash_Index,
339 Element => Entity_Id,
340 No_Element => Empty,
341 Key => Entity_Id,
342 Hash => Hash,
343 Equal => "=");
344 -- Mapping between a RCI package on which All_Calls_Remote applies and
345 -- the generic instantiation of RCI_Locator for this package.
347 package RCI_Calling_Stubs_Table is
348 new Simple_HTable (Header_Num => Hash_Index,
349 Element => Entity_Id,
350 No_Element => Empty,
351 Key => Entity_Id,
352 Hash => Hash,
353 Equal => "=");
354 -- Mapping between a RCI subprogram and the corresponding calling stubs
356 procedure Add_Stub_Type
357 (Designated_Type : Entity_Id;
358 RACW_Type : Entity_Id;
359 Decls : List_Id;
360 Stub_Type : out Entity_Id;
361 Stub_Type_Access : out Entity_Id;
362 RPC_Receiver_Decl : out Node_Id;
363 Existing : out Boolean);
364 -- Add the declaration of the stub type, the access to stub type and the
365 -- object RPC receiver at the end of Decls. If these already exist,
366 -- then nothing is added in the tree but the right values are returned
367 -- anyhow and Existing is set to True.
369 procedure Add_RACW_Asynchronous_Flag
370 (Declarations : List_Id;
371 RACW_Type : Entity_Id);
372 -- Declare a boolean constant associated with RACW_Type whose value
373 -- indicates at run time whether a pragma Asynchronous applies to it.
375 procedure Assign_Subprogram_Identifier
376 (Def : Entity_Id;
377 Spn : Int;
378 Id : out String_Id);
379 -- Determine the distribution subprogram identifier to
380 -- be used for remote subprogram Def, return it in Id and
381 -- store it in a hash table for later retrieval by
382 -- Get_Subprogram_Id. Spn is the subprogram number.
384 function RCI_Package_Locator
385 (Loc : Source_Ptr;
386 Package_Spec : Node_Id) return Node_Id;
387 -- Instantiate the generic package RCI_Locator in order to locate the
388 -- RCI package whose spec is given as argument.
390 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
391 -- Surround a node N by a tag check, as in:
392 -- begin
393 -- <N>;
394 -- exception
395 -- when E : Ada.Tags.Tag_Error =>
396 -- Raise_Exception (Program_Error'Identity,
397 -- Exception_Message (E));
398 -- end;
400 function Input_With_Tag_Check
401 (Loc : Source_Ptr;
402 Var_Type : Entity_Id;
403 Stream : Node_Id) return Node_Id;
404 -- Return a function with the following form:
405 -- function R return Var_Type is
406 -- begin
407 -- return Var_Type'Input (S);
408 -- exception
409 -- when E : Ada.Tags.Tag_Error =>
410 -- Raise_Exception (Program_Error'Identity,
411 -- Exception_Message (E));
412 -- end R;
414 --------------------------------------------
415 -- Hooks for PCS-specific code generation --
416 --------------------------------------------
418 -- Part of the code generation circuitry for distribution needs to be
419 -- tailored for each implementation of the PCS. For each routine that
420 -- needs to be specialized, a Specific_<routine> wrapper is created,
421 -- which calls the corresponding <routine> in package
422 -- <pcs_implementation>_Support.
424 procedure Specific_Add_RACW_Features
425 (RACW_Type : Entity_Id;
426 Desig : Entity_Id;
427 Stub_Type : Entity_Id;
428 Stub_Type_Access : Entity_Id;
429 RPC_Receiver_Decl : Node_Id;
430 Declarations : List_Id);
431 -- Add declaration for TSSs for a given RACW type. The declarations are
432 -- added just after the declaration of the RACW type itself, while the
433 -- bodies are inserted at the end of Decls. Runtime-specific ancillary
434 -- subprogram for Add_RACW_Features.
436 procedure Specific_Add_RAST_Features
437 (Vis_Decl : Node_Id;
438 RAS_Type : Entity_Id);
439 -- Add declaration for TSSs for a given RAS type. PCS-specific ancillary
440 -- subprogram for Add_RAST_Features.
442 -- An RPC_Target record is used during construction of calling stubs
443 -- to pass PCS-specific tree fragments corresponding to the information
444 -- necessary to locate the target of a remote subprogram call.
446 type RPC_Target (PCS_Kind : PCS_Names) is record
447 case PCS_Kind is
448 when Name_PolyORB_DSA =>
449 Object : Node_Id;
450 -- An expression whose value is a PolyORB reference to the target
451 -- object.
452 when others =>
453 Partition : Entity_Id;
454 -- A variable containing the Partition_ID of the target parition
456 RPC_Receiver : Node_Id;
457 -- An expression whose value is the address of the target RPC
458 -- receiver.
459 end case;
460 end record;
462 procedure Specific_Build_General_Calling_Stubs
463 (Decls : List_Id;
464 Statements : List_Id;
465 Target : RPC_Target;
466 Subprogram_Id : Node_Id;
467 Asynchronous : Node_Id := Empty;
468 Is_Known_Asynchronous : Boolean := False;
469 Is_Known_Non_Asynchronous : Boolean := False;
470 Is_Function : Boolean;
471 Spec : Node_Id;
472 Stub_Type : Entity_Id := Empty;
473 RACW_Type : Entity_Id := Empty;
474 Nod : Node_Id);
475 -- Build calling stubs for general purpose. The parameters are:
476 -- Decls : a place to put declarations
477 -- Statements : a place to put statements
478 -- Target : PCS-specific target information (see details
479 -- in RPC_Target declaration).
480 -- Subprogram_Id : a node containing the subprogram ID
481 -- Asynchronous : True if an APC must be made instead of an RPC.
482 -- The value needs not be supplied if one of the
483 -- Is_Known_... is True.
484 -- Is_Known_Async... : True if we know that this is asynchronous
485 -- Is_Known_Non_A... : True if we know that this is not asynchronous
486 -- Spec : a node with a Parameter_Specifications and
487 -- a Result_Definition if applicable
488 -- Stub_Type : in case of RACW stubs, parameters of type access
489 -- to Stub_Type will be marshalled using the
490 -- address of the object (the addr field) rather
491 -- than using the 'Write on the stub itself
492 -- Nod : used to provide sloc for generated code
494 function Specific_Build_Stub_Target
495 (Loc : Source_Ptr;
496 Decls : List_Id;
497 RCI_Locator : Entity_Id;
498 Controlling_Parameter : Entity_Id) return RPC_Target;
499 -- Build call target information nodes for use within calling stubs. In the
500 -- RCI case, RCI_Locator is the entity for the instance of RCI_Locator. If
501 -- for an RACW, Controlling_Parameter is the entity for the controlling
502 -- formal parameter used to determine the location of the target of the
503 -- call. Decls provides a location where variable declarations can be
504 -- appended to construct the necessary values.
506 procedure Specific_Build_Stub_Type
507 (RACW_Type : Entity_Id;
508 Stub_Type : Entity_Id;
509 Stub_Type_Decl : out Node_Id;
510 RPC_Receiver_Decl : out Node_Id);
511 -- Build a type declaration for the stub type associated with an RACW
512 -- type, and the necessary RPC receiver, if applicable. PCS-specific
513 -- ancillary subprogram for Add_Stub_Type. If no RPC receiver declaration
514 -- is generated, then RPC_Receiver_Decl is set to Empty.
516 procedure Specific_Build_RPC_Receiver_Body
517 (RPC_Receiver : Entity_Id;
518 Request : out Entity_Id;
519 Subp_Id : out Entity_Id;
520 Subp_Index : out Entity_Id;
521 Stmts : out List_Id;
522 Decl : out Node_Id);
523 -- Make a subprogram body for an RPC receiver, with the given
524 -- defining unit name. On return:
525 -- - Subp_Id is the subprogram identifier from the PCS.
526 -- - Subp_Index is the index in the list of subprograms
527 -- used for dispatching (a variable of type Subprogram_Id).
528 -- - Stmts is the place where the request dispatching
529 -- statements can occur,
530 -- - Decl is the subprogram body declaration.
532 function Specific_Build_Subprogram_Receiving_Stubs
533 (Vis_Decl : Node_Id;
534 Asynchronous : Boolean;
535 Dynamically_Asynchronous : Boolean := False;
536 Stub_Type : Entity_Id := Empty;
537 RACW_Type : Entity_Id := Empty;
538 Parent_Primitive : Entity_Id := Empty) return Node_Id;
539 -- Build the receiving stub for a given subprogram. The subprogram
540 -- declaration is also built by this procedure, and the value returned
541 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
542 -- found in the specification, then its address is read from the stream
543 -- instead of the object itself and converted into an access to
544 -- class-wide type before doing the real call using any of the RACW type
545 -- pointing on the designated type.
547 procedure Specific_Add_Obj_RPC_Receiver_Completion
548 (Loc : Source_Ptr;
549 Decls : List_Id;
550 RPC_Receiver : Entity_Id;
551 Stub_Elements : Stub_Structure);
552 -- Add the necessary code to Decls after the completion of generation
553 -- of the RACW RPC receiver described by Stub_Elements.
555 procedure Specific_Add_Receiving_Stubs_To_Declarations
556 (Pkg_Spec : Node_Id;
557 Decls : List_Id);
558 -- Add receiving stubs to the declarative part of an RCI unit
560 package GARLIC_Support is
562 -- Support for generating DSA code that uses the GARLIC PCS
564 -- The subprograms below provide the GARLIC versions of
565 -- the corresponding Specific_<subprogram> routine declared
566 -- above.
568 procedure Add_RACW_Features
569 (RACW_Type : Entity_Id;
570 Stub_Type : Entity_Id;
571 Stub_Type_Access : Entity_Id;
572 RPC_Receiver_Decl : Node_Id;
573 Declarations : List_Id);
575 procedure Add_RAST_Features
576 (Vis_Decl : Node_Id;
577 RAS_Type : Entity_Id);
579 procedure Build_General_Calling_Stubs
580 (Decls : List_Id;
581 Statements : List_Id;
582 Target_Partition : Entity_Id; -- From RPC_Target
583 Target_RPC_Receiver : Node_Id; -- From RPC_Target
584 Subprogram_Id : Node_Id;
585 Asynchronous : Node_Id := Empty;
586 Is_Known_Asynchronous : Boolean := False;
587 Is_Known_Non_Asynchronous : Boolean := False;
588 Is_Function : Boolean;
589 Spec : Node_Id;
590 Stub_Type : Entity_Id := Empty;
591 RACW_Type : Entity_Id := Empty;
592 Nod : Node_Id);
594 function Build_Stub_Target
595 (Loc : Source_Ptr;
596 Decls : List_Id;
597 RCI_Locator : Entity_Id;
598 Controlling_Parameter : Entity_Id) return RPC_Target;
600 procedure Build_Stub_Type
601 (RACW_Type : Entity_Id;
602 Stub_Type : Entity_Id;
603 Stub_Type_Decl : out Node_Id;
604 RPC_Receiver_Decl : out Node_Id);
606 function Build_Subprogram_Receiving_Stubs
607 (Vis_Decl : Node_Id;
608 Asynchronous : Boolean;
609 Dynamically_Asynchronous : Boolean := False;
610 Stub_Type : Entity_Id := Empty;
611 RACW_Type : Entity_Id := Empty;
612 Parent_Primitive : Entity_Id := Empty) return Node_Id;
614 procedure Add_Obj_RPC_Receiver_Completion
615 (Loc : Source_Ptr;
616 Decls : List_Id;
617 RPC_Receiver : Entity_Id;
618 Stub_Elements : Stub_Structure);
620 procedure Add_Receiving_Stubs_To_Declarations
621 (Pkg_Spec : Node_Id;
622 Decls : List_Id);
624 procedure Build_RPC_Receiver_Body
625 (RPC_Receiver : Entity_Id;
626 Request : out Entity_Id;
627 Subp_Id : out Entity_Id;
628 Subp_Index : out Entity_Id;
629 Stmts : out List_Id;
630 Decl : out Node_Id);
632 end GARLIC_Support;
634 package PolyORB_Support is
636 -- Support for generating DSA code that uses the PolyORB PCS
638 -- The subprograms below provide the PolyORB versions of
639 -- the corresponding Specific_<subprogram> routine declared
640 -- above.
642 procedure Add_RACW_Features
643 (RACW_Type : Entity_Id;
644 Desig : Entity_Id;
645 Stub_Type : Entity_Id;
646 Stub_Type_Access : Entity_Id;
647 RPC_Receiver_Decl : Node_Id;
648 Declarations : List_Id);
650 procedure Add_RAST_Features
651 (Vis_Decl : Node_Id;
652 RAS_Type : Entity_Id);
654 procedure Build_General_Calling_Stubs
655 (Decls : List_Id;
656 Statements : List_Id;
657 Target_Object : Node_Id; -- From RPC_Target
658 Subprogram_Id : Node_Id;
659 Asynchronous : Node_Id := Empty;
660 Is_Known_Asynchronous : Boolean := False;
661 Is_Known_Non_Asynchronous : Boolean := False;
662 Is_Function : Boolean;
663 Spec : Node_Id;
664 Stub_Type : Entity_Id := Empty;
665 RACW_Type : Entity_Id := Empty;
666 Nod : Node_Id);
668 function Build_Stub_Target
669 (Loc : Source_Ptr;
670 Decls : List_Id;
671 RCI_Locator : Entity_Id;
672 Controlling_Parameter : Entity_Id) return RPC_Target;
674 procedure Build_Stub_Type
675 (RACW_Type : Entity_Id;
676 Stub_Type : Entity_Id;
677 Stub_Type_Decl : out Node_Id;
678 RPC_Receiver_Decl : out Node_Id);
680 function Build_Subprogram_Receiving_Stubs
681 (Vis_Decl : Node_Id;
682 Asynchronous : Boolean;
683 Dynamically_Asynchronous : Boolean := False;
684 Stub_Type : Entity_Id := Empty;
685 RACW_Type : Entity_Id := Empty;
686 Parent_Primitive : Entity_Id := Empty) return Node_Id;
688 procedure Add_Obj_RPC_Receiver_Completion
689 (Loc : Source_Ptr;
690 Decls : List_Id;
691 RPC_Receiver : Entity_Id;
692 Stub_Elements : Stub_Structure);
694 procedure Add_Receiving_Stubs_To_Declarations
695 (Pkg_Spec : Node_Id;
696 Decls : List_Id);
698 procedure Build_RPC_Receiver_Body
699 (RPC_Receiver : Entity_Id;
700 Request : out Entity_Id;
701 Subp_Id : out Entity_Id;
702 Subp_Index : out Entity_Id;
703 Stmts : out List_Id;
704 Decl : out Node_Id);
706 procedure Reserve_NamingContext_Methods;
707 -- Mark the method names for interface NamingContext as already used in
708 -- the overload table, so no clashes occur with user code (with the
709 -- PolyORB PCS, RCIs Implement The NamingContext interface to allow
710 -- their methods to be accessed as objects, for the implementation of
711 -- remote access-to-subprogram types).
713 package Helpers is
715 -- Routines to build distribtion helper subprograms for user-defined
716 -- types. For implementation of the Distributed systems annex (DSA)
717 -- over the PolyORB generic middleware components, it is necessary to
718 -- generate several supporting subprograms for each application data
719 -- type used in inter-partition communication. These subprograms are:
720 -- * a Typecode function returning a high-level description of the
721 -- type's structure;
722 -- * two conversion functions allowing conversion of values of the
723 -- type from and to the generic data containers used by PolyORB.
724 -- These generic containers are called 'Any' type values after
725 -- the CORBA terminology, and hence the conversion subprograms
726 -- are named To_Any and From_Any.
728 function Build_From_Any_Call
729 (Typ : Entity_Id;
730 N : Node_Id;
731 Decls : List_Id) return Node_Id;
732 -- Build call to From_Any attribute function of type Typ with
733 -- expression N as actual parameter. Decls is the declarations list
734 -- for an appropriate enclosing scope of the point where the call
735 -- will be inserted; if the From_Any attribute for Typ needs to be
736 -- generated at this point, its declaration is appended to Decls.
738 procedure Build_From_Any_Function
739 (Loc : Source_Ptr;
740 Typ : Entity_Id;
741 Decl : out Node_Id;
742 Fnam : out Entity_Id);
743 -- Build From_Any attribute function for Typ. Loc is the reference
744 -- location for generated nodes, Typ is the type for which the
745 -- conversion function is generated. On return, Decl and Fnam contain
746 -- the declaration and entity for the newly-created function.
748 function Build_To_Any_Call
749 (N : Node_Id;
750 Decls : List_Id) return Node_Id;
751 -- Build call to To_Any attribute function with expression as actual
752 -- parameter. Decls is the declarations list for an appropriate
753 -- enclosing scope of the point where the call will be inserted; if
754 -- the To_Any attribute for Typ needs to be generated at this point,
755 -- its declaration is appended to Decls.
757 procedure Build_To_Any_Function
758 (Loc : Source_Ptr;
759 Typ : Entity_Id;
760 Decl : out Node_Id;
761 Fnam : out Entity_Id);
762 -- Build To_Any attribute function for Typ. Loc is the reference
763 -- location for generated nodes, Typ is the type for which the
764 -- conversion function is generated. On return, Decl and Fnam contain
765 -- the declaration and entity for the newly-created function.
767 function Build_TypeCode_Call
768 (Loc : Source_Ptr;
769 Typ : Entity_Id;
770 Decls : List_Id) return Node_Id;
771 -- Build call to TypeCode attribute function for Typ. Decls is the
772 -- declarations list for an appropriate enclosing scope of the point
773 -- where the call will be inserted; if the To_Any attribute for Typ
774 -- needs to be generated at this point, its declaration is appended
775 -- to Decls.
777 procedure Build_TypeCode_Function
778 (Loc : Source_Ptr;
779 Typ : Entity_Id;
780 Decl : out Node_Id;
781 Fnam : out Entity_Id);
782 -- Build TypeCode attribute function for Typ. Loc is the reference
783 -- location for generated nodes, Typ is the type for which the
784 -- conversion function is generated. On return, Decl and Fnam contain
785 -- the declaration and entity for the newly-created function.
787 procedure Build_Name_And_Repository_Id
788 (E : Entity_Id;
789 Name_Str : out String_Id;
790 Repo_Id_Str : out String_Id);
791 -- In the PolyORB distribution model, each distributed object type
792 -- and each distributed operation has a globally unique identifier,
793 -- its Repository Id. This subprogram builds and returns two strings
794 -- for entity E (a distributed object type or operation): one
795 -- containing the name of E, the second containing its repository id.
797 end Helpers;
799 end PolyORB_Support;
801 ------------------------------------
802 -- Local variables and structures --
803 ------------------------------------
805 RCI_Cache : Node_Id;
806 -- Needs comments ???
808 Output_From_Constrained : constant array (Boolean) of Name_Id :=
809 (False => Name_Output,
810 True => Name_Write);
811 -- The attribute to choose depending on the fact that the parameter
812 -- is constrained or not. There is no such thing as Input_From_Constrained
813 -- since this require separate mechanisms ('Input is a function while
814 -- 'Read is a procedure).
816 ---------------------------------------
817 -- Add_Calling_Stubs_To_Declarations --
818 ---------------------------------------
820 procedure Add_Calling_Stubs_To_Declarations
821 (Pkg_Spec : Node_Id;
822 Decls : List_Id)
824 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
825 -- Subprogram id 0 is reserved for calls received from
826 -- remote access-to-subprogram dereferences.
828 Current_Declaration : Node_Id;
829 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
830 RCI_Instantiation : Node_Id;
831 Subp_Stubs : Node_Id;
832 Subp_Str : String_Id;
834 begin
835 -- The first thing added is an instantiation of the generic package
836 -- System.Partition_Interface.RCI_Locator with the name of this
837 -- remote package. This will act as an interface with the name server
838 -- to determine the Partition_ID and the RPC_Receiver for the
839 -- receiver of this package.
841 RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
842 RCI_Cache := Defining_Unit_Name (RCI_Instantiation);
844 Append_To (Decls, RCI_Instantiation);
845 Analyze (RCI_Instantiation);
847 -- For each subprogram declaration visible in the spec, we do
848 -- build a body. We also increment a counter to assign a different
849 -- Subprogram_Id to each subprograms. The receiving stubs processing
850 -- do use the same mechanism and will thus assign the same Id and
851 -- do the correct dispatching.
853 Overload_Counter_Table.Reset;
854 PolyORB_Support.Reserve_NamingContext_Methods;
856 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
858 while Present (Current_Declaration) loop
859 if Nkind (Current_Declaration) = N_Subprogram_Declaration
860 and then Comes_From_Source (Current_Declaration)
861 then
862 Assign_Subprogram_Identifier (
863 Defining_Unit_Name (Specification (Current_Declaration)),
864 Current_Subprogram_Number,
865 Subp_Str);
867 Subp_Stubs :=
868 Build_Subprogram_Calling_Stubs (
869 Vis_Decl => Current_Declaration,
870 Subp_Id =>
871 Build_Subprogram_Id (Loc,
872 Defining_Unit_Name (Specification (Current_Declaration))),
873 Asynchronous =>
874 Nkind (Specification (Current_Declaration)) =
875 N_Procedure_Specification
876 and then
877 Is_Asynchronous (Defining_Unit_Name (Specification
878 (Current_Declaration))));
880 Append_To (Decls, Subp_Stubs);
881 Analyze (Subp_Stubs);
883 Current_Subprogram_Number := Current_Subprogram_Number + 1;
884 end if;
886 Next (Current_Declaration);
887 end loop;
888 end Add_Calling_Stubs_To_Declarations;
890 -----------------------------
891 -- Add_Parameter_To_NVList --
892 -----------------------------
894 function Add_Parameter_To_NVList
895 (Loc : Source_Ptr;
896 NVList : Entity_Id;
897 Parameter : Entity_Id;
898 Constrained : Boolean;
899 RACW_Ctrl : Boolean := False;
900 Any : Entity_Id) return Node_Id
902 Parameter_Name_String : String_Id;
903 Parameter_Mode : Node_Id;
905 function Parameter_Passing_Mode
906 (Loc : Source_Ptr;
907 Parameter : Entity_Id;
908 Constrained : Boolean) return Node_Id;
909 -- Return an expression that denotes the parameter passing
910 -- mode to be used for Parameter in distribution stubs,
911 -- where Constrained is Parameter's constrained status.
913 ----------------------------
914 -- Parameter_Passing_Mode --
915 ----------------------------
917 function Parameter_Passing_Mode
918 (Loc : Source_Ptr;
919 Parameter : Entity_Id;
920 Constrained : Boolean) return Node_Id
922 Lib_RE : RE_Id;
924 begin
925 if Out_Present (Parameter) then
926 if In_Present (Parameter)
927 or else not Constrained
928 then
929 -- Unconstrained formals must be translated
930 -- to 'in' or 'inout', not 'out', because
931 -- they need to be constrained by the actual.
933 Lib_RE := RE_Mode_Inout;
934 else
935 Lib_RE := RE_Mode_Out;
936 end if;
938 else
939 Lib_RE := RE_Mode_In;
940 end if;
942 return New_Occurrence_Of (RTE (Lib_RE), Loc);
943 end Parameter_Passing_Mode;
945 -- Start of processing for Add_Parameter_To_NVList
947 begin
948 if Nkind (Parameter) = N_Defining_Identifier then
949 Get_Name_String (Chars (Parameter));
950 else
951 Get_Name_String (Chars (Defining_Identifier
952 (Parameter)));
953 end if;
955 Parameter_Name_String := String_From_Name_Buffer;
957 if RACW_Ctrl then
958 Parameter_Mode := New_Occurrence_Of
959 (RTE (RE_Mode_In), Loc);
960 else
961 Parameter_Mode := Parameter_Passing_Mode (Loc,
962 Parameter, Constrained);
963 end if;
965 return
966 Make_Procedure_Call_Statement (Loc,
967 Name =>
968 New_Occurrence_Of
969 (RTE (RE_NVList_Add_Item), Loc),
970 Parameter_Associations => New_List (
971 New_Occurrence_Of (NVList, Loc),
972 Make_Function_Call (Loc,
973 Name =>
974 New_Occurrence_Of
975 (RTE (RE_To_PolyORB_String), Loc),
976 Parameter_Associations => New_List (
977 Make_String_Literal (Loc,
978 Strval => Parameter_Name_String))),
979 New_Occurrence_Of (Any, Loc),
980 Parameter_Mode));
981 end Add_Parameter_To_NVList;
983 --------------------------------
984 -- Add_RACW_Asynchronous_Flag --
985 --------------------------------
987 procedure Add_RACW_Asynchronous_Flag
988 (Declarations : List_Id;
989 RACW_Type : Entity_Id)
991 Loc : constant Source_Ptr := Sloc (RACW_Type);
993 Asynchronous_Flag : constant Entity_Id :=
994 Make_Defining_Identifier (Loc,
995 New_External_Name (Chars (RACW_Type), 'A'));
997 begin
998 -- Declare the asynchronous flag. This flag will be changed to True
999 -- whenever it is known that the RACW type is asynchronous.
1001 Append_To (Declarations,
1002 Make_Object_Declaration (Loc,
1003 Defining_Identifier => Asynchronous_Flag,
1004 Constant_Present => True,
1005 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
1006 Expression => New_Occurrence_Of (Standard_False, Loc)));
1008 Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Flag);
1009 end Add_RACW_Asynchronous_Flag;
1011 -----------------------
1012 -- Add_RACW_Features --
1013 -----------------------
1015 procedure Add_RACW_Features (RACW_Type : Entity_Id)
1017 Desig : constant Entity_Id :=
1018 Etype (Designated_Type (RACW_Type));
1019 Decls : List_Id :=
1020 List_Containing (Declaration_Node (RACW_Type));
1022 Same_Scope : constant Boolean :=
1023 Scope (Desig) = Scope (RACW_Type);
1025 Stub_Type : Entity_Id;
1026 Stub_Type_Access : Entity_Id;
1027 RPC_Receiver_Decl : Node_Id;
1028 Existing : Boolean;
1030 begin
1031 if not Expander_Active then
1032 return;
1033 end if;
1035 if Same_Scope then
1037 -- We are declaring a RACW in the same package than its designated
1038 -- type, so the list to use for late declarations must be the
1039 -- private part of the package. We do know that this private part
1040 -- exists since the designated type has to be a private one.
1042 Decls := Private_Declarations
1043 (Package_Specification_Of_Scope (Current_Scope));
1045 elsif Nkind (Parent (Decls)) = N_Package_Specification
1046 and then Present (Private_Declarations (Parent (Decls)))
1047 then
1048 Decls := Private_Declarations (Parent (Decls));
1049 end if;
1051 -- If we were unable to find the declarations, that means that the
1052 -- completion of the type was missing. We can safely return and let
1053 -- the error be caught by the semantic analysis.
1055 if No (Decls) then
1056 return;
1057 end if;
1059 Add_Stub_Type
1060 (Designated_Type => Desig,
1061 RACW_Type => RACW_Type,
1062 Decls => Decls,
1063 Stub_Type => Stub_Type,
1064 Stub_Type_Access => Stub_Type_Access,
1065 RPC_Receiver_Decl => RPC_Receiver_Decl,
1066 Existing => Existing);
1068 Add_RACW_Asynchronous_Flag
1069 (Declarations => Decls,
1070 RACW_Type => RACW_Type);
1072 Specific_Add_RACW_Features
1073 (RACW_Type => RACW_Type,
1074 Desig => Desig,
1075 Stub_Type => Stub_Type,
1076 Stub_Type_Access => Stub_Type_Access,
1077 RPC_Receiver_Decl => RPC_Receiver_Decl,
1078 Declarations => Decls);
1080 if not Same_Scope and then not Existing then
1082 -- The RACW has been declared in another scope than the designated
1083 -- type and has not been handled by another RACW in the same package
1084 -- as the first one, so add primitive for the stub type here.
1086 Add_RACW_Primitive_Declarations_And_Bodies
1087 (Designated_Type => Desig,
1088 Insertion_Node => RPC_Receiver_Decl,
1089 Decls => Decls);
1091 else
1092 Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
1093 end if;
1094 end Add_RACW_Features;
1096 ------------------------------------------------
1097 -- Add_RACW_Primitive_Declarations_And_Bodies --
1098 ------------------------------------------------
1100 procedure Add_RACW_Primitive_Declarations_And_Bodies
1101 (Designated_Type : Entity_Id;
1102 Insertion_Node : Node_Id;
1103 Decls : List_Id)
1105 -- Set Sloc of generated declaration copy of insertion node Sloc, so
1106 -- the declarations are recognized as belonging to the current package.
1108 Loc : constant Source_Ptr := Sloc (Insertion_Node);
1110 Stub_Elements : constant Stub_Structure :=
1111 Stubs_Table.Get (Designated_Type);
1113 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1114 Is_RAS : constant Boolean :=
1115 not Comes_From_Source (Stub_Elements.RACW_Type);
1117 Current_Insertion_Node : Node_Id := Insertion_Node;
1119 RPC_Receiver : Entity_Id;
1120 RPC_Receiver_Statements : List_Id;
1121 RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
1122 RPC_Receiver_Elsif_Parts : List_Id;
1123 RPC_Receiver_Request : Entity_Id;
1124 RPC_Receiver_Subp_Id : Entity_Id;
1125 RPC_Receiver_Subp_Index : Entity_Id;
1127 Subp_Str : String_Id;
1129 Current_Primitive_Elmt : Elmt_Id;
1130 Current_Primitive : Entity_Id;
1131 Current_Primitive_Body : Node_Id;
1132 Current_Primitive_Spec : Node_Id;
1133 Current_Primitive_Decl : Node_Id;
1134 Current_Primitive_Number : Int := 0;
1136 Current_Primitive_Alias : Node_Id;
1138 Current_Receiver : Entity_Id;
1139 Current_Receiver_Body : Node_Id;
1141 RPC_Receiver_Decl : Node_Id;
1143 Possibly_Asynchronous : Boolean;
1145 begin
1146 if not Expander_Active then
1147 return;
1148 end if;
1150 if not Is_RAS then
1151 RPC_Receiver := Make_Defining_Identifier (Loc,
1152 New_Internal_Name ('P'));
1153 Specific_Build_RPC_Receiver_Body (
1154 RPC_Receiver => RPC_Receiver,
1155 Request => RPC_Receiver_Request,
1156 Subp_Id => RPC_Receiver_Subp_Id,
1157 Subp_Index => RPC_Receiver_Subp_Index,
1158 Stmts => RPC_Receiver_Statements,
1159 Decl => RPC_Receiver_Decl);
1161 if Get_PCS_Name = Name_PolyORB_DSA then
1163 -- For the case of PolyORB, we need to map a textual operation
1164 -- name into a primitive index. Currently we do so using a
1165 -- simple sequence of string comparisons.
1167 RPC_Receiver_Elsif_Parts := New_List;
1168 end if;
1169 end if;
1171 -- Build callers, receivers for every primitive operations and a RPC
1172 -- receiver for this type.
1174 if Present (Primitive_Operations (Designated_Type)) then
1175 Overload_Counter_Table.Reset;
1177 Current_Primitive_Elmt :=
1178 First_Elmt (Primitive_Operations (Designated_Type));
1179 while Current_Primitive_Elmt /= No_Elmt loop
1180 Current_Primitive := Node (Current_Primitive_Elmt);
1182 -- Copy the primitive of all the parents, except predefined
1183 -- ones that are not remotely dispatching.
1185 if Chars (Current_Primitive) /= Name_uSize
1186 and then Chars (Current_Primitive) /= Name_uAlignment
1187 and then not Is_TSS (Current_Primitive, TSS_Deep_Finalize)
1188 then
1189 -- The first thing to do is build an up-to-date copy of
1190 -- the spec with all the formals referencing Designated_Type
1191 -- transformed into formals referencing Stub_Type. Since this
1192 -- primitive may have been inherited, go back the alias chain
1193 -- until the real primitive has been found.
1195 Current_Primitive_Alias := Current_Primitive;
1196 while Present (Alias (Current_Primitive_Alias)) loop
1197 pragma Assert
1198 (Current_Primitive_Alias
1199 /= Alias (Current_Primitive_Alias));
1200 Current_Primitive_Alias := Alias (Current_Primitive_Alias);
1201 end loop;
1203 Current_Primitive_Spec :=
1204 Copy_Specification (Loc,
1205 Spec => Parent (Current_Primitive_Alias),
1206 Object_Type => Designated_Type,
1207 Stub_Type => Stub_Elements.Stub_Type);
1209 Current_Primitive_Decl :=
1210 Make_Subprogram_Declaration (Loc,
1211 Specification => Current_Primitive_Spec);
1213 Insert_After (Current_Insertion_Node, Current_Primitive_Decl);
1214 Analyze (Current_Primitive_Decl);
1215 Current_Insertion_Node := Current_Primitive_Decl;
1217 Possibly_Asynchronous :=
1218 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
1219 and then Could_Be_Asynchronous (Current_Primitive_Spec);
1221 Assign_Subprogram_Identifier (
1222 Defining_Unit_Name (Current_Primitive_Spec),
1223 Current_Primitive_Number,
1224 Subp_Str);
1226 Current_Primitive_Body :=
1227 Build_Subprogram_Calling_Stubs
1228 (Vis_Decl => Current_Primitive_Decl,
1229 Subp_Id =>
1230 Build_Subprogram_Id (Loc,
1231 Defining_Unit_Name (Current_Primitive_Spec)),
1232 Asynchronous => Possibly_Asynchronous,
1233 Dynamically_Asynchronous => Possibly_Asynchronous,
1234 Stub_Type => Stub_Elements.Stub_Type,
1235 RACW_Type => Stub_Elements.RACW_Type);
1236 Append_To (Decls, Current_Primitive_Body);
1238 -- Analyzing the body here would cause the Stub type to be
1239 -- frozen, thus preventing subsequent primitive declarations.
1240 -- For this reason, it will be analyzed later in the
1241 -- regular flow.
1243 -- Build the receiver stubs
1245 if not Is_RAS then
1246 Current_Receiver_Body :=
1247 Specific_Build_Subprogram_Receiving_Stubs
1248 (Vis_Decl => Current_Primitive_Decl,
1249 Asynchronous => Possibly_Asynchronous,
1250 Dynamically_Asynchronous => Possibly_Asynchronous,
1251 Stub_Type => Stub_Elements.Stub_Type,
1252 RACW_Type => Stub_Elements.RACW_Type,
1253 Parent_Primitive => Current_Primitive);
1255 Current_Receiver := Defining_Unit_Name (
1256 Specification (Current_Receiver_Body));
1258 Append_To (Decls, Current_Receiver_Body);
1260 -- Add a case alternative to the receiver
1262 if Get_PCS_Name = Name_PolyORB_DSA then
1263 Append_To (RPC_Receiver_Elsif_Parts,
1264 Make_Elsif_Part (Loc,
1265 Condition =>
1266 Make_Function_Call (Loc,
1267 Name =>
1268 New_Occurrence_Of (
1269 RTE (RE_Caseless_String_Eq), Loc),
1270 Parameter_Associations => New_List (
1271 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
1272 Make_String_Literal (Loc, Subp_Str))),
1273 Then_Statements => New_List (
1274 Make_Assignment_Statement (Loc,
1275 Name => New_Occurrence_Of (
1276 RPC_Receiver_Subp_Index, Loc),
1277 Expression =>
1278 Make_Integer_Literal (Loc,
1279 Current_Primitive_Number)))));
1280 end if;
1282 Append_To (RPC_Receiver_Case_Alternatives,
1283 Make_Case_Statement_Alternative (Loc,
1284 Discrete_Choices => New_List (
1285 Make_Integer_Literal (Loc, Current_Primitive_Number)),
1287 Statements => New_List (
1288 Make_Procedure_Call_Statement (Loc,
1289 Name =>
1290 New_Occurrence_Of (Current_Receiver, Loc),
1291 Parameter_Associations => New_List (
1292 New_Occurrence_Of (RPC_Receiver_Request, Loc))))));
1293 end if;
1295 -- Increment the index of current primitive
1297 Current_Primitive_Number := Current_Primitive_Number + 1;
1298 end if;
1300 Next_Elmt (Current_Primitive_Elmt);
1301 end loop;
1302 end if;
1304 -- Build the case statement and the heart of the subprogram
1306 if not Is_RAS then
1307 if Get_PCS_Name = Name_PolyORB_DSA
1308 and then Present (First (RPC_Receiver_Elsif_Parts))
1309 then
1310 Append_To (RPC_Receiver_Statements,
1311 Make_Implicit_If_Statement (Designated_Type,
1312 Condition => New_Occurrence_Of (Standard_False, Loc),
1313 Then_Statements => New_List,
1314 Elsif_Parts => RPC_Receiver_Elsif_Parts));
1315 end if;
1317 Append_To (RPC_Receiver_Case_Alternatives,
1318 Make_Case_Statement_Alternative (Loc,
1319 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
1320 Statements => New_List (Make_Null_Statement (Loc))));
1322 Append_To (RPC_Receiver_Statements,
1323 Make_Case_Statement (Loc,
1324 Expression =>
1325 New_Occurrence_Of (RPC_Receiver_Subp_Index, Loc),
1326 Alternatives => RPC_Receiver_Case_Alternatives));
1328 Append_To (Decls, RPC_Receiver_Decl);
1329 Specific_Add_Obj_RPC_Receiver_Completion (Loc,
1330 Decls, RPC_Receiver, Stub_Elements);
1331 end if;
1333 -- Do not analyze RPC receiver at this stage since it will otherwise
1334 -- reference subprograms that have not been analyzed yet. It will
1335 -- be analyzed in the regular flow.
1337 end Add_RACW_Primitive_Declarations_And_Bodies;
1339 -----------------------------
1340 -- Add_RAS_Dereference_TSS --
1341 -----------------------------
1343 procedure Add_RAS_Dereference_TSS (N : Node_Id) is
1344 Loc : constant Source_Ptr := Sloc (N);
1346 Type_Def : constant Node_Id := Type_Definition (N);
1348 RAS_Type : constant Entity_Id := Defining_Identifier (N);
1349 Fat_Type : constant Entity_Id := Equivalent_Type (RAS_Type);
1350 RACW_Type : constant Entity_Id := Underlying_RACW_Type (RAS_Type);
1351 Desig : constant Entity_Id := Etype (Designated_Type (RACW_Type));
1353 Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
1354 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1356 RACW_Primitive_Name : Node_Id;
1358 Proc : constant Entity_Id :=
1359 Make_Defining_Identifier (Loc,
1360 Chars => Make_TSS_Name (RAS_Type, TSS_RAS_Dereference));
1362 Proc_Spec : Node_Id;
1363 Param_Specs : List_Id;
1364 Param_Assoc : constant List_Id := New_List;
1365 Stmts : constant List_Id := New_List;
1367 RAS_Parameter : constant Entity_Id :=
1368 Make_Defining_Identifier (Loc,
1369 Chars => New_Internal_Name ('P'));
1371 Is_Function : constant Boolean :=
1372 Nkind (Type_Def) = N_Access_Function_Definition;
1374 Is_Degenerate : Boolean;
1375 -- Set to True if the subprogram_specification for this RAS has
1376 -- an anonymous access parameter (see Process_Remote_AST_Declaration).
1378 Spec : constant Node_Id := Type_Def;
1380 Current_Parameter : Node_Id;
1382 -- Start of processing for Add_RAS_Dereference_TSS
1384 begin
1385 -- The Dereference TSS for a remote access-to-subprogram type
1386 -- has the form:
1388 -- [function|procedure] ras_typeRD (RAS_Value, <RAS_Parameters>)
1389 -- [return <>]
1391 -- This is called whenever a value of a RAS type is dereferenced
1393 -- First construct a list of parameter specifications:
1395 -- The first formal is the RAS values
1397 Param_Specs := New_List (
1398 Make_Parameter_Specification (Loc,
1399 Defining_Identifier => RAS_Parameter,
1400 In_Present => True,
1401 Parameter_Type =>
1402 New_Occurrence_Of (Fat_Type, Loc)));
1404 -- The following formals are copied from the type declaration
1406 Is_Degenerate := False;
1407 Current_Parameter := First (Parameter_Specifications (Type_Def));
1408 Parameters : while Present (Current_Parameter) loop
1409 if Nkind (Parameter_Type (Current_Parameter))
1410 = N_Access_Definition
1411 then
1412 Is_Degenerate := True;
1413 end if;
1414 Append_To (Param_Specs,
1415 Make_Parameter_Specification (Loc,
1416 Defining_Identifier =>
1417 Make_Defining_Identifier (Loc,
1418 Chars => Chars (Defining_Identifier (Current_Parameter))),
1419 In_Present => In_Present (Current_Parameter),
1420 Out_Present => Out_Present (Current_Parameter),
1421 Parameter_Type =>
1422 New_Copy_Tree (Parameter_Type (Current_Parameter)),
1423 Expression =>
1424 New_Copy_Tree (Expression (Current_Parameter))));
1426 Append_To (Param_Assoc,
1427 Make_Identifier (Loc,
1428 Chars => Chars (Defining_Identifier (Current_Parameter))));
1430 Next (Current_Parameter);
1431 end loop Parameters;
1433 if Is_Degenerate then
1434 Prepend_To (Param_Assoc, New_Occurrence_Of (RAS_Parameter, Loc));
1436 -- Generate a dummy body. This code will never actually be executed,
1437 -- because null is the only legal value for a degenerate RAS type.
1438 -- For legality's sake (in order to avoid generating a function
1439 -- that does not contain a return statement), we include a dummy
1440 -- recursive call on the TSS itself.
1442 Append_To (Stmts,
1443 Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
1444 RACW_Primitive_Name := New_Occurrence_Of (Proc, Loc);
1446 else
1447 -- For a normal RAS type, we cast the RAS formal to the corresponding
1448 -- tagged type, and perform a dispatching call to its Call
1449 -- primitive operation.
1451 Prepend_To (Param_Assoc,
1452 Unchecked_Convert_To (RACW_Type,
1453 New_Occurrence_Of (RAS_Parameter, Loc)));
1455 RACW_Primitive_Name := Make_Selected_Component (Loc,
1456 Prefix => Scope (RACW_Type),
1457 Selector_Name => Name_Call);
1458 end if;
1460 if Is_Function then
1461 Append_To (Stmts,
1462 Make_Return_Statement (Loc,
1463 Expression =>
1464 Make_Function_Call (Loc,
1465 Name =>
1466 RACW_Primitive_Name,
1467 Parameter_Associations => Param_Assoc)));
1469 else
1470 Append_To (Stmts,
1471 Make_Procedure_Call_Statement (Loc,
1472 Name =>
1473 RACW_Primitive_Name,
1474 Parameter_Associations => Param_Assoc));
1475 end if;
1477 -- Build the complete subprogram
1479 if Is_Function then
1480 Proc_Spec :=
1481 Make_Function_Specification (Loc,
1482 Defining_Unit_Name => Proc,
1483 Parameter_Specifications => Param_Specs,
1484 Result_Definition =>
1485 New_Occurrence_Of (
1486 Entity (Result_Definition (Spec)), Loc));
1488 Set_Ekind (Proc, E_Function);
1489 Set_Etype (Proc,
1490 New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
1492 else
1493 Proc_Spec :=
1494 Make_Procedure_Specification (Loc,
1495 Defining_Unit_Name => Proc,
1496 Parameter_Specifications => Param_Specs);
1498 Set_Ekind (Proc, E_Procedure);
1499 Set_Etype (Proc, Standard_Void_Type);
1500 end if;
1502 Discard_Node (
1503 Make_Subprogram_Body (Loc,
1504 Specification => Proc_Spec,
1505 Declarations => New_List,
1506 Handled_Statement_Sequence =>
1507 Make_Handled_Sequence_Of_Statements (Loc,
1508 Statements => Stmts)));
1510 Set_TSS (Fat_Type, Proc);
1511 end Add_RAS_Dereference_TSS;
1513 -------------------------------
1514 -- Add_RAS_Proxy_And_Analyze --
1515 -------------------------------
1517 procedure Add_RAS_Proxy_And_Analyze
1518 (Decls : List_Id;
1519 Vis_Decl : Node_Id;
1520 All_Calls_Remote_E : Entity_Id;
1521 Proxy_Object_Addr : out Entity_Id)
1523 Loc : constant Source_Ptr := Sloc (Vis_Decl);
1525 Subp_Name : constant Entity_Id :=
1526 Defining_Unit_Name (Specification (Vis_Decl));
1528 Pkg_Name : constant Entity_Id :=
1529 Make_Defining_Identifier (Loc,
1530 Chars =>
1531 New_External_Name (Chars (Subp_Name), 'P', -1));
1533 Proxy_Type : constant Entity_Id :=
1534 Make_Defining_Identifier (Loc,
1535 Chars =>
1536 New_External_Name (
1537 Related_Id => Chars (Subp_Name),
1538 Suffix => 'P'));
1540 Proxy_Type_Full_View : constant Entity_Id :=
1541 Make_Defining_Identifier (Loc,
1542 Chars (Proxy_Type));
1544 Subp_Decl_Spec : constant Node_Id :=
1545 Build_RAS_Primitive_Specification
1546 (Subp_Spec => Specification (Vis_Decl),
1547 Remote_Object_Type => Proxy_Type);
1549 Subp_Body_Spec : constant Node_Id :=
1550 Build_RAS_Primitive_Specification
1551 (Subp_Spec => Specification (Vis_Decl),
1552 Remote_Object_Type => Proxy_Type);
1554 Vis_Decls : constant List_Id := New_List;
1555 Pvt_Decls : constant List_Id := New_List;
1556 Actuals : constant List_Id := New_List;
1557 Formal : Node_Id;
1558 Perform_Call : Node_Id;
1560 begin
1561 -- type subpP is tagged limited private;
1563 Append_To (Vis_Decls,
1564 Make_Private_Type_Declaration (Loc,
1565 Defining_Identifier => Proxy_Type,
1566 Tagged_Present => True,
1567 Limited_Present => True));
1569 -- [subprogram] Call
1570 -- (Self : access subpP;
1571 -- ...other-formals...)
1572 -- [return T];
1574 Append_To (Vis_Decls,
1575 Make_Subprogram_Declaration (Loc,
1576 Specification => Subp_Decl_Spec));
1578 -- A : constant System.Address;
1580 Proxy_Object_Addr := Make_Defining_Identifier (Loc, Name_uA);
1582 Append_To (Vis_Decls,
1583 Make_Object_Declaration (Loc,
1584 Defining_Identifier =>
1585 Proxy_Object_Addr,
1586 Constant_Present =>
1587 True,
1588 Object_Definition =>
1589 New_Occurrence_Of (RTE (RE_Address), Loc)));
1591 -- private
1593 -- type subpP is tagged limited record
1594 -- All_Calls_Remote : Boolean := [All_Calls_Remote?];
1595 -- ...
1596 -- end record;
1598 Append_To (Pvt_Decls,
1599 Make_Full_Type_Declaration (Loc,
1600 Defining_Identifier =>
1601 Proxy_Type_Full_View,
1602 Type_Definition =>
1603 Build_Remote_Subprogram_Proxy_Type (Loc,
1604 New_Occurrence_Of (All_Calls_Remote_E, Loc))));
1606 -- Trick semantic analysis into swapping the public and
1607 -- full view when freezing the public view.
1609 Set_Comes_From_Source (Proxy_Type_Full_View, True);
1611 -- procedure Call
1612 -- (Self : access O;
1613 -- ...other-formals...) is
1614 -- begin
1615 -- P (...other-formals...);
1616 -- end Call;
1618 -- function Call
1619 -- (Self : access O;
1620 -- ...other-formals...)
1621 -- return T is
1622 -- begin
1623 -- return F (...other-formals...);
1624 -- end Call;
1626 if Nkind (Subp_Decl_Spec) = N_Procedure_Specification then
1627 Perform_Call :=
1628 Make_Procedure_Call_Statement (Loc,
1629 Name =>
1630 New_Occurrence_Of (Subp_Name, Loc),
1631 Parameter_Associations =>
1632 Actuals);
1633 else
1634 Perform_Call :=
1635 Make_Return_Statement (Loc,
1636 Expression =>
1637 Make_Function_Call (Loc,
1638 Name =>
1639 New_Occurrence_Of (Subp_Name, Loc),
1640 Parameter_Associations =>
1641 Actuals));
1642 end if;
1644 Formal := First (Parameter_Specifications (Subp_Decl_Spec));
1645 pragma Assert (Present (Formal));
1646 loop
1647 Next (Formal);
1648 exit when No (Formal);
1649 Append_To (Actuals,
1650 New_Occurrence_Of (Defining_Identifier (Formal), Loc));
1651 end loop;
1653 -- O : aliased subpP;
1655 Append_To (Pvt_Decls,
1656 Make_Object_Declaration (Loc,
1657 Defining_Identifier =>
1658 Make_Defining_Identifier (Loc,
1659 Name_uO),
1660 Aliased_Present =>
1661 True,
1662 Object_Definition =>
1663 New_Occurrence_Of (Proxy_Type, Loc)));
1665 -- A : constant System.Address := O'Address;
1667 Append_To (Pvt_Decls,
1668 Make_Object_Declaration (Loc,
1669 Defining_Identifier =>
1670 Make_Defining_Identifier (Loc,
1671 Chars (Proxy_Object_Addr)),
1672 Constant_Present =>
1673 True,
1674 Object_Definition =>
1675 New_Occurrence_Of (RTE (RE_Address), Loc),
1676 Expression =>
1677 Make_Attribute_Reference (Loc,
1678 Prefix => New_Occurrence_Of (
1679 Defining_Identifier (Last (Pvt_Decls)), Loc),
1680 Attribute_Name =>
1681 Name_Address)));
1683 Append_To (Decls,
1684 Make_Package_Declaration (Loc,
1685 Specification => Make_Package_Specification (Loc,
1686 Defining_Unit_Name => Pkg_Name,
1687 Visible_Declarations => Vis_Decls,
1688 Private_Declarations => Pvt_Decls,
1689 End_Label => Empty)));
1690 Analyze (Last (Decls));
1692 Append_To (Decls,
1693 Make_Package_Body (Loc,
1694 Defining_Unit_Name =>
1695 Make_Defining_Identifier (Loc,
1696 Chars (Pkg_Name)),
1697 Declarations => New_List (
1698 Make_Subprogram_Body (Loc,
1699 Specification =>
1700 Subp_Body_Spec,
1701 Declarations => New_List,
1702 Handled_Statement_Sequence =>
1703 Make_Handled_Sequence_Of_Statements (Loc,
1704 Statements => New_List (Perform_Call))))));
1705 Analyze (Last (Decls));
1706 end Add_RAS_Proxy_And_Analyze;
1708 -----------------------
1709 -- Add_RAST_Features --
1710 -----------------------
1712 procedure Add_RAST_Features (Vis_Decl : Node_Id) is
1713 RAS_Type : constant Entity_Id :=
1714 Equivalent_Type (Defining_Identifier (Vis_Decl));
1715 begin
1716 pragma Assert (No (TSS (RAS_Type, TSS_RAS_Access)));
1717 Add_RAS_Dereference_TSS (Vis_Decl);
1718 Specific_Add_RAST_Features (Vis_Decl, RAS_Type);
1719 end Add_RAST_Features;
1721 -------------------
1722 -- Add_Stub_Type --
1723 -------------------
1725 procedure Add_Stub_Type
1726 (Designated_Type : Entity_Id;
1727 RACW_Type : Entity_Id;
1728 Decls : List_Id;
1729 Stub_Type : out Entity_Id;
1730 Stub_Type_Access : out Entity_Id;
1731 RPC_Receiver_Decl : out Node_Id;
1732 Existing : out Boolean)
1734 Loc : constant Source_Ptr := Sloc (RACW_Type);
1736 Stub_Elements : constant Stub_Structure :=
1737 Stubs_Table.Get (Designated_Type);
1738 Stub_Type_Decl : Node_Id;
1739 Stub_Type_Access_Decl : Node_Id;
1741 begin
1742 if Stub_Elements /= Empty_Stub_Structure then
1743 Stub_Type := Stub_Elements.Stub_Type;
1744 Stub_Type_Access := Stub_Elements.Stub_Type_Access;
1745 RPC_Receiver_Decl := Stub_Elements.RPC_Receiver_Decl;
1746 Existing := True;
1747 return;
1748 end if;
1750 Existing := False;
1751 Stub_Type :=
1752 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
1753 Stub_Type_Access :=
1754 Make_Defining_Identifier (Loc,
1755 New_External_Name (
1756 Related_Id => Chars (Stub_Type),
1757 Suffix => 'A'));
1759 Specific_Build_Stub_Type (
1760 RACW_Type, Stub_Type,
1761 Stub_Type_Decl, RPC_Receiver_Decl);
1763 Stub_Type_Access_Decl :=
1764 Make_Full_Type_Declaration (Loc,
1765 Defining_Identifier => Stub_Type_Access,
1766 Type_Definition =>
1767 Make_Access_To_Object_Definition (Loc,
1768 All_Present => True,
1769 Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
1771 Append_To (Decls, Stub_Type_Decl);
1772 Analyze (Last (Decls));
1773 Append_To (Decls, Stub_Type_Access_Decl);
1774 Analyze (Last (Decls));
1776 -- This is in no way a type derivation, but we fake it to make
1777 -- sure that the dispatching table gets built with the corresponding
1778 -- primitive operations at the right place.
1780 Derive_Subprograms (Parent_Type => Designated_Type,
1781 Derived_Type => Stub_Type);
1783 if Present (RPC_Receiver_Decl) then
1784 Append_To (Decls, RPC_Receiver_Decl);
1785 else
1786 RPC_Receiver_Decl := Last (Decls);
1787 end if;
1789 Stubs_Table.Set (Designated_Type,
1790 (Stub_Type => Stub_Type,
1791 Stub_Type_Access => Stub_Type_Access,
1792 RPC_Receiver_Decl => RPC_Receiver_Decl,
1793 RACW_Type => RACW_Type));
1794 end Add_Stub_Type;
1796 ----------------------------------
1797 -- Assign_Subprogram_Identifier --
1798 ----------------------------------
1800 procedure Assign_Subprogram_Identifier
1801 (Def : Entity_Id;
1802 Spn : Int;
1803 Id : out String_Id)
1805 N : constant Name_Id := Chars (Def);
1807 Overload_Order : constant Int :=
1808 Overload_Counter_Table.Get (N) + 1;
1810 begin
1811 Overload_Counter_Table.Set (N, Overload_Order);
1813 Get_Name_String (N);
1815 -- Homonym handling: as in Exp_Dbug, but much simpler,
1816 -- because the only entities for which we have to generate
1817 -- names here need only to be disambiguated within their
1818 -- own scope.
1820 if Overload_Order > 1 then
1821 Name_Buffer (Name_Len + 1 .. Name_Len + 2) := "__";
1822 Name_Len := Name_Len + 2;
1823 Add_Nat_To_Name_Buffer (Overload_Order);
1824 end if;
1826 Id := String_From_Name_Buffer;
1827 Subprogram_Identifier_Table.Set (Def,
1828 Subprogram_Identifiers'(Str_Identifier => Id, Int_Identifier => Spn));
1829 end Assign_Subprogram_Identifier;
1831 ------------------------------
1832 -- Build_Get_Unique_RP_Call --
1833 ------------------------------
1835 function Build_Get_Unique_RP_Call
1836 (Loc : Source_Ptr;
1837 Pointer : Entity_Id;
1838 Stub_Type : Entity_Id) return List_Id
1840 begin
1841 return New_List (
1842 Make_Procedure_Call_Statement (Loc,
1843 Name =>
1844 New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
1845 Parameter_Associations => New_List (
1846 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
1847 New_Occurrence_Of (Pointer, Loc)))),
1849 Make_Assignment_Statement (Loc,
1850 Name =>
1851 Make_Selected_Component (Loc,
1852 Prefix =>
1853 New_Occurrence_Of (Pointer, Loc),
1854 Selector_Name =>
1855 New_Occurrence_Of (First_Tag_Component
1856 (Designated_Type (Etype (Pointer))), Loc)),
1857 Expression =>
1858 Make_Attribute_Reference (Loc,
1859 Prefix =>
1860 New_Occurrence_Of (Stub_Type, Loc),
1861 Attribute_Name =>
1862 Name_Tag)));
1864 -- Note: The assignment to Pointer._Tag is safe here because
1865 -- we carefully ensured that Stub_Type has exactly the same layout
1866 -- as System.Partition_Interface.RACW_Stub_Type.
1868 end Build_Get_Unique_RP_Call;
1870 -----------------------------------
1871 -- Build_Ordered_Parameters_List --
1872 -----------------------------------
1874 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
1875 Constrained_List : List_Id;
1876 Unconstrained_List : List_Id;
1877 Current_Parameter : Node_Id;
1879 First_Parameter : Node_Id;
1880 For_RAS : Boolean := False;
1882 begin
1883 if No (Parameter_Specifications (Spec)) then
1884 return New_List;
1885 end if;
1887 Constrained_List := New_List;
1888 Unconstrained_List := New_List;
1889 First_Parameter := First (Parameter_Specifications (Spec));
1891 if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition
1892 and then Chars (Defining_Identifier (First_Parameter)) = Name_uS
1893 then
1894 For_RAS := True;
1895 end if;
1897 -- Loop through the parameters and add them to the right list
1899 Current_Parameter := First_Parameter;
1900 while Present (Current_Parameter) loop
1901 if (Nkind (Parameter_Type (Current_Parameter)) = N_Access_Definition
1902 or else
1903 Is_Constrained (Etype (Parameter_Type (Current_Parameter)))
1904 or else
1905 Is_Elementary_Type (Etype (Parameter_Type (Current_Parameter))))
1906 and then not (For_RAS and then Current_Parameter = First_Parameter)
1907 then
1908 Append_To (Constrained_List, New_Copy (Current_Parameter));
1909 else
1910 Append_To (Unconstrained_List, New_Copy (Current_Parameter));
1911 end if;
1913 Next (Current_Parameter);
1914 end loop;
1916 -- Unconstrained parameters are returned first
1918 Append_List_To (Unconstrained_List, Constrained_List);
1920 return Unconstrained_List;
1921 end Build_Ordered_Parameters_List;
1923 ----------------------------------
1924 -- Build_Passive_Partition_Stub --
1925 ----------------------------------
1927 procedure Build_Passive_Partition_Stub (U : Node_Id) is
1928 Pkg_Spec : Node_Id;
1929 Pkg_Name : String_Id;
1930 L : List_Id;
1931 Reg : Node_Id;
1932 Loc : constant Source_Ptr := Sloc (U);
1934 begin
1935 -- Verify that the implementation supports distribution, by accessing
1936 -- a type defined in the proper version of system.rpc
1938 declare
1939 Dist_OK : Entity_Id;
1940 pragma Warnings (Off, Dist_OK);
1941 begin
1942 Dist_OK := RTE (RE_Params_Stream_Type);
1943 end;
1945 -- Use body if present, spec otherwise
1947 if Nkind (U) = N_Package_Declaration then
1948 Pkg_Spec := Specification (U);
1949 L := Visible_Declarations (Pkg_Spec);
1950 else
1951 Pkg_Spec := Parent (Corresponding_Spec (U));
1952 L := Declarations (U);
1953 end if;
1955 Get_Library_Unit_Name_String (Pkg_Spec);
1956 Pkg_Name := String_From_Name_Buffer;
1957 Reg :=
1958 Make_Procedure_Call_Statement (Loc,
1959 Name =>
1960 New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
1961 Parameter_Associations => New_List (
1962 Make_String_Literal (Loc, Pkg_Name),
1963 Make_Attribute_Reference (Loc,
1964 Prefix =>
1965 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
1966 Attribute_Name =>
1967 Name_Version)));
1968 Append_To (L, Reg);
1969 Analyze (Reg);
1970 end Build_Passive_Partition_Stub;
1972 --------------------------------------
1973 -- Build_RPC_Receiver_Specification --
1974 --------------------------------------
1976 function Build_RPC_Receiver_Specification
1977 (RPC_Receiver : Entity_Id;
1978 Request_Parameter : Entity_Id) return Node_Id
1980 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
1981 begin
1982 return
1983 Make_Procedure_Specification (Loc,
1984 Defining_Unit_Name => RPC_Receiver,
1985 Parameter_Specifications => New_List (
1986 Make_Parameter_Specification (Loc,
1987 Defining_Identifier => Request_Parameter,
1988 Parameter_Type =>
1989 New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
1990 end Build_RPC_Receiver_Specification;
1992 ----------------------------------------
1993 -- Build_Remote_Subprogram_Proxy_Type --
1994 ----------------------------------------
1996 function Build_Remote_Subprogram_Proxy_Type
1997 (Loc : Source_Ptr;
1998 ACR_Expression : Node_Id) return Node_Id
2000 begin
2001 return
2002 Make_Record_Definition (Loc,
2003 Tagged_Present => True,
2004 Limited_Present => True,
2005 Component_List =>
2006 Make_Component_List (Loc,
2008 Component_Items => New_List (
2009 Make_Component_Declaration (Loc,
2010 Defining_Identifier =>
2011 Make_Defining_Identifier (Loc,
2012 Name_All_Calls_Remote),
2013 Component_Definition =>
2014 Make_Component_Definition (Loc,
2015 Subtype_Indication =>
2016 New_Occurrence_Of (Standard_Boolean, Loc)),
2017 Expression =>
2018 ACR_Expression),
2020 Make_Component_Declaration (Loc,
2021 Defining_Identifier =>
2022 Make_Defining_Identifier (Loc,
2023 Name_Receiver),
2024 Component_Definition =>
2025 Make_Component_Definition (Loc,
2026 Subtype_Indication =>
2027 New_Occurrence_Of (RTE (RE_Address), Loc)),
2028 Expression =>
2029 New_Occurrence_Of (RTE (RE_Null_Address), Loc)),
2031 Make_Component_Declaration (Loc,
2032 Defining_Identifier =>
2033 Make_Defining_Identifier (Loc,
2034 Name_Subp_Id),
2035 Component_Definition =>
2036 Make_Component_Definition (Loc,
2037 Subtype_Indication =>
2038 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))))));
2039 end Build_Remote_Subprogram_Proxy_Type;
2041 ------------------------------------
2042 -- Build_Subprogram_Calling_Stubs --
2043 ------------------------------------
2045 function Build_Subprogram_Calling_Stubs
2046 (Vis_Decl : Node_Id;
2047 Subp_Id : Node_Id;
2048 Asynchronous : Boolean;
2049 Dynamically_Asynchronous : Boolean := False;
2050 Stub_Type : Entity_Id := Empty;
2051 RACW_Type : Entity_Id := Empty;
2052 Locator : Entity_Id := Empty;
2053 New_Name : Name_Id := No_Name) return Node_Id
2055 Loc : constant Source_Ptr := Sloc (Vis_Decl);
2057 Decls : constant List_Id := New_List;
2058 Statements : constant List_Id := New_List;
2060 Subp_Spec : Node_Id;
2061 -- The specification of the body
2063 Controlling_Parameter : Entity_Id := Empty;
2065 Asynchronous_Expr : Node_Id := Empty;
2067 RCI_Locator : Entity_Id;
2069 Spec_To_Use : Node_Id;
2071 procedure Insert_Partition_Check (Parameter : Node_Id);
2072 -- Check that the parameter has been elaborated on the same partition
2073 -- than the controlling parameter (E.4(19)).
2075 ----------------------------
2076 -- Insert_Partition_Check --
2077 ----------------------------
2079 procedure Insert_Partition_Check (Parameter : Node_Id) is
2080 Parameter_Entity : constant Entity_Id :=
2081 Defining_Identifier (Parameter);
2082 begin
2083 -- The expression that will be built is of the form:
2085 -- if not Same_Partition (Parameter, Controlling_Parameter) then
2086 -- raise Constraint_Error;
2087 -- end if;
2089 -- We do not check that Parameter is in Stub_Type since such a check
2090 -- has been inserted at the point of call already (a tag check since
2091 -- we have multiple controlling operands).
2093 Append_To (Decls,
2094 Make_Raise_Constraint_Error (Loc,
2095 Condition =>
2096 Make_Op_Not (Loc,
2097 Right_Opnd =>
2098 Make_Function_Call (Loc,
2099 Name =>
2100 New_Occurrence_Of (RTE (RE_Same_Partition), Loc),
2101 Parameter_Associations =>
2102 New_List (
2103 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2104 New_Occurrence_Of (Parameter_Entity, Loc)),
2105 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2106 New_Occurrence_Of (Controlling_Parameter, Loc))))),
2107 Reason => CE_Partition_Check_Failed));
2108 end Insert_Partition_Check;
2110 -- Start of processing for Build_Subprogram_Calling_Stubs
2112 begin
2113 Subp_Spec := Copy_Specification (Loc,
2114 Spec => Specification (Vis_Decl),
2115 New_Name => New_Name);
2117 if Locator = Empty then
2118 RCI_Locator := RCI_Cache;
2119 Spec_To_Use := Specification (Vis_Decl);
2120 else
2121 RCI_Locator := Locator;
2122 Spec_To_Use := Subp_Spec;
2123 end if;
2125 -- Find a controlling argument if we have a stub type. Also check
2126 -- if this subprogram can be made asynchronous.
2128 if Present (Stub_Type)
2129 and then Present (Parameter_Specifications (Spec_To_Use))
2130 then
2131 declare
2132 Current_Parameter : Node_Id :=
2133 First (Parameter_Specifications
2134 (Spec_To_Use));
2135 begin
2136 while Present (Current_Parameter) loop
2138 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2139 then
2140 if Controlling_Parameter = Empty then
2141 Controlling_Parameter :=
2142 Defining_Identifier (Current_Parameter);
2143 else
2144 Insert_Partition_Check (Current_Parameter);
2145 end if;
2146 end if;
2148 Next (Current_Parameter);
2149 end loop;
2150 end;
2151 end if;
2153 pragma Assert (No (Stub_Type) or else Present (Controlling_Parameter));
2155 if Dynamically_Asynchronous then
2156 Asynchronous_Expr := Make_Selected_Component (Loc,
2157 Prefix => Controlling_Parameter,
2158 Selector_Name => Name_Asynchronous);
2159 end if;
2161 Specific_Build_General_Calling_Stubs
2162 (Decls => Decls,
2163 Statements => Statements,
2164 Target => Specific_Build_Stub_Target (Loc,
2165 Decls, RCI_Locator, Controlling_Parameter),
2166 Subprogram_Id => Subp_Id,
2167 Asynchronous => Asynchronous_Expr,
2168 Is_Known_Asynchronous => Asynchronous
2169 and then not Dynamically_Asynchronous,
2170 Is_Known_Non_Asynchronous
2171 => not Asynchronous
2172 and then not Dynamically_Asynchronous,
2173 Is_Function => Nkind (Spec_To_Use) =
2174 N_Function_Specification,
2175 Spec => Spec_To_Use,
2176 Stub_Type => Stub_Type,
2177 RACW_Type => RACW_Type,
2178 Nod => Vis_Decl);
2180 RCI_Calling_Stubs_Table.Set
2181 (Defining_Unit_Name (Specification (Vis_Decl)),
2182 Defining_Unit_Name (Spec_To_Use));
2184 return
2185 Make_Subprogram_Body (Loc,
2186 Specification => Subp_Spec,
2187 Declarations => Decls,
2188 Handled_Statement_Sequence =>
2189 Make_Handled_Sequence_Of_Statements (Loc, Statements));
2190 end Build_Subprogram_Calling_Stubs;
2192 -------------------------
2193 -- Build_Subprogram_Id --
2194 -------------------------
2196 function Build_Subprogram_Id
2197 (Loc : Source_Ptr;
2198 E : Entity_Id) return Node_Id
2200 begin
2201 case Get_PCS_Name is
2202 when Name_PolyORB_DSA =>
2203 return Make_String_Literal (Loc, Get_Subprogram_Id (E));
2204 when others =>
2205 return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
2206 end case;
2207 end Build_Subprogram_Id;
2209 ------------------------
2210 -- Copy_Specification --
2211 ------------------------
2213 function Copy_Specification
2214 (Loc : Source_Ptr;
2215 Spec : Node_Id;
2216 Object_Type : Entity_Id := Empty;
2217 Stub_Type : Entity_Id := Empty;
2218 New_Name : Name_Id := No_Name) return Node_Id
2220 Parameters : List_Id := No_List;
2222 Current_Parameter : Node_Id;
2223 Current_Identifier : Entity_Id;
2224 Current_Type : Node_Id;
2225 Current_Etype : Entity_Id;
2227 Name_For_New_Spec : Name_Id;
2229 New_Identifier : Entity_Id;
2231 -- Comments needed in body below ???
2233 begin
2234 if New_Name = No_Name then
2235 pragma Assert (Nkind (Spec) = N_Function_Specification
2236 or else Nkind (Spec) = N_Procedure_Specification);
2238 Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
2239 else
2240 Name_For_New_Spec := New_Name;
2241 end if;
2243 if Present (Parameter_Specifications (Spec)) then
2244 Parameters := New_List;
2245 Current_Parameter := First (Parameter_Specifications (Spec));
2246 while Present (Current_Parameter) loop
2247 Current_Identifier := Defining_Identifier (Current_Parameter);
2248 Current_Type := Parameter_Type (Current_Parameter);
2250 if Nkind (Current_Type) = N_Access_Definition then
2251 Current_Etype := Entity (Subtype_Mark (Current_Type));
2253 if Present (Object_Type) then
2254 pragma Assert (
2255 Root_Type (Current_Etype) = Root_Type (Object_Type));
2256 Current_Type :=
2257 Make_Access_Definition (Loc,
2258 Subtype_Mark => New_Occurrence_Of (Stub_Type, Loc),
2259 Null_Exclusion_Present =>
2260 Null_Exclusion_Present (Current_Type));
2262 else
2263 Current_Type :=
2264 Make_Access_Definition (Loc,
2265 Subtype_Mark =>
2266 New_Occurrence_Of (Current_Etype, Loc),
2267 Null_Exclusion_Present =>
2268 Null_Exclusion_Present (Current_Type));
2269 end if;
2271 else
2272 Current_Etype := Entity (Current_Type);
2274 if Present (Object_Type)
2275 and then Current_Etype = Object_Type
2276 then
2277 Current_Type := New_Occurrence_Of (Stub_Type, Loc);
2278 else
2279 Current_Type := New_Occurrence_Of (Current_Etype, Loc);
2280 end if;
2281 end if;
2283 New_Identifier := Make_Defining_Identifier (Loc,
2284 Chars (Current_Identifier));
2286 Append_To (Parameters,
2287 Make_Parameter_Specification (Loc,
2288 Defining_Identifier => New_Identifier,
2289 Parameter_Type => Current_Type,
2290 In_Present => In_Present (Current_Parameter),
2291 Out_Present => Out_Present (Current_Parameter),
2292 Expression =>
2293 New_Copy_Tree (Expression (Current_Parameter))));
2295 -- For a regular formal parameter (that needs to be marshalled
2296 -- in the context of remote calls), set the Etype now, because
2297 -- marshalling processing might need it.
2299 if Is_Entity_Name (Current_Type) then
2300 Set_Etype (New_Identifier, Entity (Current_Type));
2302 -- Current_Type is an access definition, special processing
2303 -- (not requiring etype) will occur for marshalling.
2305 else
2306 null;
2307 end if;
2309 Next (Current_Parameter);
2310 end loop;
2311 end if;
2313 case Nkind (Spec) is
2315 when N_Function_Specification | N_Access_Function_Definition =>
2316 return
2317 Make_Function_Specification (Loc,
2318 Defining_Unit_Name =>
2319 Make_Defining_Identifier (Loc,
2320 Chars => Name_For_New_Spec),
2321 Parameter_Specifications => Parameters,
2322 Result_Definition =>
2323 New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
2325 when N_Procedure_Specification | N_Access_Procedure_Definition =>
2326 return
2327 Make_Procedure_Specification (Loc,
2328 Defining_Unit_Name =>
2329 Make_Defining_Identifier (Loc,
2330 Chars => Name_For_New_Spec),
2331 Parameter_Specifications => Parameters);
2333 when others =>
2334 raise Program_Error;
2335 end case;
2336 end Copy_Specification;
2338 ---------------------------
2339 -- Could_Be_Asynchronous --
2340 ---------------------------
2342 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
2343 Current_Parameter : Node_Id;
2345 begin
2346 if Present (Parameter_Specifications (Spec)) then
2347 Current_Parameter := First (Parameter_Specifications (Spec));
2348 while Present (Current_Parameter) loop
2349 if Out_Present (Current_Parameter) then
2350 return False;
2351 end if;
2353 Next (Current_Parameter);
2354 end loop;
2355 end if;
2357 return True;
2358 end Could_Be_Asynchronous;
2360 ---------------------------
2361 -- Declare_Create_NVList --
2362 ---------------------------
2364 procedure Declare_Create_NVList
2365 (Loc : Source_Ptr;
2366 NVList : Entity_Id;
2367 Decls : List_Id;
2368 Stmts : List_Id)
2370 begin
2371 Append_To (Decls,
2372 Make_Object_Declaration (Loc,
2373 Defining_Identifier => NVList,
2374 Aliased_Present => False,
2375 Object_Definition =>
2376 New_Occurrence_Of (RTE (RE_NVList_Ref), Loc)));
2378 Append_To (Stmts,
2379 Make_Procedure_Call_Statement (Loc,
2380 Name =>
2381 New_Occurrence_Of (RTE (RE_NVList_Create), Loc),
2382 Parameter_Associations => New_List (
2383 New_Occurrence_Of (NVList, Loc))));
2384 end Declare_Create_NVList;
2386 ---------------------------------------------
2387 -- Expand_All_Calls_Remote_Subprogram_Call --
2388 ---------------------------------------------
2390 procedure Expand_All_Calls_Remote_Subprogram_Call (N : Node_Id) is
2391 Called_Subprogram : constant Entity_Id := Entity (Name (N));
2392 RCI_Package : constant Entity_Id := Scope (Called_Subprogram);
2393 Loc : constant Source_Ptr := Sloc (N);
2394 RCI_Locator : Node_Id;
2395 RCI_Cache : Entity_Id;
2396 Calling_Stubs : Node_Id;
2397 E_Calling_Stubs : Entity_Id;
2399 begin
2400 E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
2402 if E_Calling_Stubs = Empty then
2403 RCI_Cache := RCI_Locator_Table.Get (RCI_Package);
2405 if RCI_Cache = Empty then
2406 RCI_Locator :=
2407 RCI_Package_Locator
2408 (Loc, Specification (Unit_Declaration_Node (RCI_Package)));
2409 Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator);
2411 -- The RCI_Locator package is inserted at the top level in the
2412 -- current unit, and must appear in the proper scope, so that it
2413 -- is not prematurely removed by the GCC back-end.
2415 declare
2416 Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
2418 begin
2419 if Ekind (Scop) = E_Package_Body then
2420 New_Scope (Spec_Entity (Scop));
2422 elsif Ekind (Scop) = E_Subprogram_Body then
2423 New_Scope
2424 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
2426 else
2427 New_Scope (Scop);
2428 end if;
2430 Analyze (RCI_Locator);
2431 Pop_Scope;
2432 end;
2434 RCI_Cache := Defining_Unit_Name (RCI_Locator);
2436 else
2437 RCI_Locator := Parent (RCI_Cache);
2438 end if;
2440 Calling_Stubs := Build_Subprogram_Calling_Stubs
2441 (Vis_Decl => Parent (Parent (Called_Subprogram)),
2442 Subp_Id =>
2443 Build_Subprogram_Id (Loc, Called_Subprogram),
2444 Asynchronous => Nkind (N) = N_Procedure_Call_Statement
2445 and then
2446 Is_Asynchronous (Called_Subprogram),
2447 Locator => RCI_Cache,
2448 New_Name => New_Internal_Name ('S'));
2449 Insert_After (RCI_Locator, Calling_Stubs);
2450 Analyze (Calling_Stubs);
2451 E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
2452 end if;
2454 Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
2455 end Expand_All_Calls_Remote_Subprogram_Call;
2457 ---------------------------------
2458 -- Expand_Calling_Stubs_Bodies --
2459 ---------------------------------
2461 procedure Expand_Calling_Stubs_Bodies (Unit_Node : Node_Id) is
2462 Spec : constant Node_Id := Specification (Unit_Node);
2463 Decls : constant List_Id := Visible_Declarations (Spec);
2464 begin
2465 New_Scope (Scope_Of_Spec (Spec));
2466 Add_Calling_Stubs_To_Declarations
2467 (Specification (Unit_Node), Decls);
2468 Pop_Scope;
2469 end Expand_Calling_Stubs_Bodies;
2471 -----------------------------------
2472 -- Expand_Receiving_Stubs_Bodies --
2473 -----------------------------------
2475 procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is
2476 Spec : Node_Id;
2477 Decls : List_Id;
2478 Temp : List_Id;
2480 begin
2481 if Nkind (Unit_Node) = N_Package_Declaration then
2482 Spec := Specification (Unit_Node);
2483 Decls := Private_Declarations (Spec);
2485 if No (Decls) then
2486 Decls := Visible_Declarations (Spec);
2487 end if;
2489 New_Scope (Scope_Of_Spec (Spec));
2490 Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls);
2492 else
2493 Spec :=
2494 Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
2495 Decls := Declarations (Unit_Node);
2496 New_Scope (Scope_Of_Spec (Unit_Node));
2497 Temp := New_List;
2498 Specific_Add_Receiving_Stubs_To_Declarations (Spec, Temp);
2499 Insert_List_Before (First (Decls), Temp);
2500 end if;
2502 Pop_Scope;
2503 end Expand_Receiving_Stubs_Bodies;
2505 --------------------
2506 -- GARLIC_Support --
2507 --------------------
2509 package body GARLIC_Support is
2511 -- Local subprograms
2513 procedure Add_RACW_Read_Attribute
2514 (RACW_Type : Entity_Id;
2515 Stub_Type : Entity_Id;
2516 Stub_Type_Access : Entity_Id;
2517 Declarations : List_Id);
2518 -- Add Read attribute in Decls for the RACW type. The Read attribute
2519 -- is added right after the RACW_Type declaration while the body is
2520 -- inserted after Declarations.
2522 procedure Add_RACW_Write_Attribute
2523 (RACW_Type : Entity_Id;
2524 Stub_Type : Entity_Id;
2525 Stub_Type_Access : Entity_Id;
2526 RPC_Receiver : Node_Id;
2527 Declarations : List_Id);
2528 -- Same thing for the Write attribute
2530 function Stream_Parameter return Node_Id;
2531 function Result return Node_Id;
2532 function Object return Node_Id renames Result;
2533 -- Functions to create occurrences of the formal parameter names of
2534 -- the 'Read and 'Write attributes.
2536 Loc : Source_Ptr;
2537 -- Shared source location used by Add_{Read,Write}_Read_Attribute
2538 -- and their ancillary subroutines (set on entry by Add_RACW_Features).
2540 procedure Add_RAS_Access_TSS (N : Node_Id);
2541 -- Add a subprogram body for RAS Access TSS
2543 -------------------------------------
2544 -- Add_Obj_RPC_Receiver_Completion --
2545 -------------------------------------
2547 procedure Add_Obj_RPC_Receiver_Completion
2548 (Loc : Source_Ptr;
2549 Decls : List_Id;
2550 RPC_Receiver : Entity_Id;
2551 Stub_Elements : Stub_Structure) is
2552 begin
2553 -- The RPC receiver body should not be the completion of the
2554 -- declaration recorded in the stub structure, because then the
2555 -- occurrences of the formal parameters within the body should
2556 -- refer to the entities from the declaration, not from the
2557 -- completion, to which we do not have easy access. Instead, the
2558 -- RPC receiver body acts as its own declaration, and the RPC
2559 -- receiver declaration is completed by a renaming-as-body.
2561 Append_To (Decls,
2562 Make_Subprogram_Renaming_Declaration (Loc,
2563 Specification =>
2564 Copy_Specification (Loc,
2565 Specification (Stub_Elements.RPC_Receiver_Decl)),
2566 Name => New_Occurrence_Of (RPC_Receiver, Loc)));
2567 end Add_Obj_RPC_Receiver_Completion;
2569 -----------------------
2570 -- Add_RACW_Features --
2571 -----------------------
2573 procedure Add_RACW_Features
2574 (RACW_Type : Entity_Id;
2575 Stub_Type : Entity_Id;
2576 Stub_Type_Access : Entity_Id;
2577 RPC_Receiver_Decl : Node_Id;
2578 Declarations : List_Id)
2580 RPC_Receiver : Node_Id;
2581 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
2583 begin
2584 Loc := Sloc (RACW_Type);
2586 if Is_RAS then
2588 -- For a RAS, the RPC receiver is that of the RCI unit,
2589 -- not that of the corresponding distributed object type.
2590 -- We retrieve its address from the local proxy object.
2592 RPC_Receiver := Make_Selected_Component (Loc,
2593 Prefix =>
2594 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object),
2595 Selector_Name => Make_Identifier (Loc, Name_Receiver));
2597 else
2598 RPC_Receiver := Make_Attribute_Reference (Loc,
2599 Prefix => New_Occurrence_Of (
2600 Defining_Unit_Name (Specification (RPC_Receiver_Decl)), Loc),
2601 Attribute_Name => Name_Address);
2602 end if;
2604 Add_RACW_Write_Attribute (
2605 RACW_Type,
2606 Stub_Type,
2607 Stub_Type_Access,
2608 RPC_Receiver,
2609 Declarations);
2611 Add_RACW_Read_Attribute (
2612 RACW_Type,
2613 Stub_Type,
2614 Stub_Type_Access,
2615 Declarations);
2616 end Add_RACW_Features;
2618 -----------------------------
2619 -- Add_RACW_Read_Attribute --
2620 -----------------------------
2622 procedure Add_RACW_Read_Attribute
2623 (RACW_Type : Entity_Id;
2624 Stub_Type : Entity_Id;
2625 Stub_Type_Access : Entity_Id;
2626 Declarations : List_Id)
2628 Proc_Decl : Node_Id;
2629 Attr_Decl : Node_Id;
2631 Body_Node : Node_Id;
2633 Decls : List_Id;
2634 Statements : List_Id;
2635 Local_Statements : List_Id;
2636 Remote_Statements : List_Id;
2637 -- Various parts of the procedure
2639 Procedure_Name : constant Name_Id :=
2640 New_Internal_Name ('R');
2641 Source_Partition : constant Entity_Id :=
2642 Make_Defining_Identifier
2643 (Loc, New_Internal_Name ('P'));
2644 Source_Receiver : constant Entity_Id :=
2645 Make_Defining_Identifier
2646 (Loc, New_Internal_Name ('S'));
2647 Source_Address : constant Entity_Id :=
2648 Make_Defining_Identifier
2649 (Loc, New_Internal_Name ('P'));
2650 Local_Stub : constant Entity_Id :=
2651 Make_Defining_Identifier
2652 (Loc, New_Internal_Name ('L'));
2653 Stubbed_Result : constant Entity_Id :=
2654 Make_Defining_Identifier
2655 (Loc, New_Internal_Name ('S'));
2656 Asynchronous_Flag : constant Entity_Id :=
2657 Asynchronous_Flags_Table.Get (RACW_Type);
2658 pragma Assert (Present (Asynchronous_Flag));
2660 -- Start of processing for Add_RACW_Read_Attribute
2662 begin
2663 -- Generate object declarations
2665 Decls := New_List (
2666 Make_Object_Declaration (Loc,
2667 Defining_Identifier => Source_Partition,
2668 Object_Definition =>
2669 New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
2671 Make_Object_Declaration (Loc,
2672 Defining_Identifier => Source_Receiver,
2673 Object_Definition =>
2674 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
2676 Make_Object_Declaration (Loc,
2677 Defining_Identifier => Source_Address,
2678 Object_Definition =>
2679 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
2681 Make_Object_Declaration (Loc,
2682 Defining_Identifier => Local_Stub,
2683 Aliased_Present => True,
2684 Object_Definition => New_Occurrence_Of (Stub_Type, Loc)),
2686 Make_Object_Declaration (Loc,
2687 Defining_Identifier => Stubbed_Result,
2688 Object_Definition =>
2689 New_Occurrence_Of (Stub_Type_Access, Loc),
2690 Expression =>
2691 Make_Attribute_Reference (Loc,
2692 Prefix =>
2693 New_Occurrence_Of (Local_Stub, Loc),
2694 Attribute_Name =>
2695 Name_Unchecked_Access)));
2697 -- Read the source Partition_ID and RPC_Receiver from incoming stream
2699 Statements := New_List (
2700 Make_Attribute_Reference (Loc,
2701 Prefix =>
2702 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
2703 Attribute_Name => Name_Read,
2704 Expressions => New_List (
2705 Stream_Parameter,
2706 New_Occurrence_Of (Source_Partition, Loc))),
2708 Make_Attribute_Reference (Loc,
2709 Prefix =>
2710 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2711 Attribute_Name =>
2712 Name_Read,
2713 Expressions => New_List (
2714 Stream_Parameter,
2715 New_Occurrence_Of (Source_Receiver, Loc))),
2717 Make_Attribute_Reference (Loc,
2718 Prefix =>
2719 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
2720 Attribute_Name =>
2721 Name_Read,
2722 Expressions => New_List (
2723 Stream_Parameter,
2724 New_Occurrence_Of (Source_Address, Loc))));
2726 -- Build_Get_Unique_RP_Call needs the type of Stubbed_Result
2728 Set_Etype (Stubbed_Result, Stub_Type_Access);
2730 -- If the Address is Null_Address, then return a null object
2732 Append_To (Statements,
2733 Make_Implicit_If_Statement (RACW_Type,
2734 Condition =>
2735 Make_Op_Eq (Loc,
2736 Left_Opnd => New_Occurrence_Of (Source_Address, Loc),
2737 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
2738 Then_Statements => New_List (
2739 Make_Assignment_Statement (Loc,
2740 Name => Result,
2741 Expression => Make_Null (Loc)),
2742 Make_Return_Statement (Loc))));
2744 -- If the RACW denotes an object created on the current partition,
2745 -- Local_Statements will be executed. The real object will be used.
2747 Local_Statements := New_List (
2748 Make_Assignment_Statement (Loc,
2749 Name => Result,
2750 Expression =>
2751 Unchecked_Convert_To (RACW_Type,
2752 OK_Convert_To (RTE (RE_Address),
2753 New_Occurrence_Of (Source_Address, Loc)))));
2755 -- If the object is located on another partition, then a stub object
2756 -- will be created with all the information needed to rebuild the
2757 -- real object at the other end.
2759 Remote_Statements := New_List (
2761 Make_Assignment_Statement (Loc,
2762 Name => Make_Selected_Component (Loc,
2763 Prefix => Stubbed_Result,
2764 Selector_Name => Name_Origin),
2765 Expression =>
2766 New_Occurrence_Of (Source_Partition, Loc)),
2768 Make_Assignment_Statement (Loc,
2769 Name => Make_Selected_Component (Loc,
2770 Prefix => Stubbed_Result,
2771 Selector_Name => Name_Receiver),
2772 Expression =>
2773 New_Occurrence_Of (Source_Receiver, Loc)),
2775 Make_Assignment_Statement (Loc,
2776 Name => Make_Selected_Component (Loc,
2777 Prefix => Stubbed_Result,
2778 Selector_Name => Name_Addr),
2779 Expression =>
2780 New_Occurrence_Of (Source_Address, Loc)));
2782 Append_To (Remote_Statements,
2783 Make_Assignment_Statement (Loc,
2784 Name => Make_Selected_Component (Loc,
2785 Prefix => Stubbed_Result,
2786 Selector_Name => Name_Asynchronous),
2787 Expression =>
2788 New_Occurrence_Of (Asynchronous_Flag, Loc)));
2790 Append_List_To (Remote_Statements,
2791 Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
2792 -- ??? Issue with asynchronous calls here: the Asynchronous
2793 -- flag is set on the stub type if, and only if, the RACW type
2794 -- has a pragma Asynchronous. This is incorrect for RACWs that
2795 -- implement RAS types, because in that case the /designated
2796 -- subprogram/ (not the type) might be asynchronous, and
2797 -- that causes the stub to need to be asynchronous too.
2798 -- A solution is to transport a RAS as a struct containing
2799 -- a RACW and an asynchronous flag, and to properly alter
2800 -- the Asynchronous component in the stub type in the RAS's
2801 -- Input TSS.
2803 Append_To (Remote_Statements,
2804 Make_Assignment_Statement (Loc,
2805 Name => Result,
2806 Expression => Unchecked_Convert_To (RACW_Type,
2807 New_Occurrence_Of (Stubbed_Result, Loc))));
2809 -- Distinguish between the local and remote cases, and execute the
2810 -- appropriate piece of code.
2812 Append_To (Statements,
2813 Make_Implicit_If_Statement (RACW_Type,
2814 Condition =>
2815 Make_Op_Eq (Loc,
2816 Left_Opnd =>
2817 Make_Function_Call (Loc,
2818 Name => New_Occurrence_Of (
2819 RTE (RE_Get_Local_Partition_Id), Loc)),
2820 Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
2821 Then_Statements => Local_Statements,
2822 Else_Statements => Remote_Statements));
2824 Build_Stream_Procedure
2825 (Loc, RACW_Type, Body_Node,
2826 Make_Defining_Identifier (Loc, Procedure_Name),
2827 Statements, Outp => True);
2828 Set_Declarations (Body_Node, Decls);
2830 Proc_Decl := Make_Subprogram_Declaration (Loc,
2831 Copy_Specification (Loc, Specification (Body_Node)));
2833 Attr_Decl :=
2834 Make_Attribute_Definition_Clause (Loc,
2835 Name => New_Occurrence_Of (RACW_Type, Loc),
2836 Chars => Name_Read,
2837 Expression =>
2838 New_Occurrence_Of (
2839 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
2841 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
2842 Insert_After (Proc_Decl, Attr_Decl);
2843 Append_To (Declarations, Body_Node);
2844 end Add_RACW_Read_Attribute;
2846 ------------------------------
2847 -- Add_RACW_Write_Attribute --
2848 ------------------------------
2850 procedure Add_RACW_Write_Attribute
2851 (RACW_Type : Entity_Id;
2852 Stub_Type : Entity_Id;
2853 Stub_Type_Access : Entity_Id;
2854 RPC_Receiver : Node_Id;
2855 Declarations : List_Id)
2857 Body_Node : Node_Id;
2858 Proc_Decl : Node_Id;
2859 Attr_Decl : Node_Id;
2861 Statements : List_Id;
2862 Local_Statements : List_Id;
2863 Remote_Statements : List_Id;
2864 Null_Statements : List_Id;
2866 Procedure_Name : constant Name_Id := New_Internal_Name ('R');
2868 begin
2869 -- Build the code fragment corresponding to the marshalling of a
2870 -- local object.
2872 Local_Statements := New_List (
2874 Pack_Entity_Into_Stream_Access (Loc,
2875 Stream => Stream_Parameter,
2876 Object => RTE (RE_Get_Local_Partition_Id)),
2878 Pack_Node_Into_Stream_Access (Loc,
2879 Stream => Stream_Parameter,
2880 Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
2881 Etyp => RTE (RE_Unsigned_64)),
2883 Pack_Node_Into_Stream_Access (Loc,
2884 Stream => Stream_Parameter,
2885 Object => OK_Convert_To (RTE (RE_Unsigned_64),
2886 Make_Attribute_Reference (Loc,
2887 Prefix =>
2888 Make_Explicit_Dereference (Loc,
2889 Prefix => Object),
2890 Attribute_Name => Name_Address)),
2891 Etyp => RTE (RE_Unsigned_64)));
2893 -- Build the code fragment corresponding to the marshalling of
2894 -- a remote object.
2896 Remote_Statements := New_List (
2898 Pack_Node_Into_Stream_Access (Loc,
2899 Stream => Stream_Parameter,
2900 Object =>
2901 Make_Selected_Component (Loc,
2902 Prefix => Unchecked_Convert_To (Stub_Type_Access,
2903 Object),
2904 Selector_Name =>
2905 Make_Identifier (Loc, Name_Origin)),
2906 Etyp => RTE (RE_Partition_ID)),
2908 Pack_Node_Into_Stream_Access (Loc,
2909 Stream => Stream_Parameter,
2910 Object =>
2911 Make_Selected_Component (Loc,
2912 Prefix => Unchecked_Convert_To (Stub_Type_Access,
2913 Object),
2914 Selector_Name =>
2915 Make_Identifier (Loc, Name_Receiver)),
2916 Etyp => RTE (RE_Unsigned_64)),
2918 Pack_Node_Into_Stream_Access (Loc,
2919 Stream => Stream_Parameter,
2920 Object =>
2921 Make_Selected_Component (Loc,
2922 Prefix => Unchecked_Convert_To (Stub_Type_Access,
2923 Object),
2924 Selector_Name =>
2925 Make_Identifier (Loc, Name_Addr)),
2926 Etyp => RTE (RE_Unsigned_64)));
2928 -- Build code fragment corresponding to marshalling of a null object
2930 Null_Statements := New_List (
2932 Pack_Entity_Into_Stream_Access (Loc,
2933 Stream => Stream_Parameter,
2934 Object => RTE (RE_Get_Local_Partition_Id)),
2936 Pack_Node_Into_Stream_Access (Loc,
2937 Stream => Stream_Parameter,
2938 Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
2939 Etyp => RTE (RE_Unsigned_64)),
2941 Pack_Node_Into_Stream_Access (Loc,
2942 Stream => Stream_Parameter,
2943 Object => Make_Integer_Literal (Loc, Uint_0),
2944 Etyp => RTE (RE_Unsigned_64)));
2946 Statements := New_List (
2947 Make_Implicit_If_Statement (RACW_Type,
2948 Condition =>
2949 Make_Op_Eq (Loc,
2950 Left_Opnd => Object,
2951 Right_Opnd => Make_Null (Loc)),
2952 Then_Statements => Null_Statements,
2953 Elsif_Parts => New_List (
2954 Make_Elsif_Part (Loc,
2955 Condition =>
2956 Make_Op_Eq (Loc,
2957 Left_Opnd =>
2958 Make_Attribute_Reference (Loc,
2959 Prefix => Object,
2960 Attribute_Name => Name_Tag),
2961 Right_Opnd =>
2962 Make_Attribute_Reference (Loc,
2963 Prefix => New_Occurrence_Of (Stub_Type, Loc),
2964 Attribute_Name => Name_Tag)),
2965 Then_Statements => Remote_Statements)),
2966 Else_Statements => Local_Statements));
2968 Build_Stream_Procedure
2969 (Loc, RACW_Type, Body_Node,
2970 Make_Defining_Identifier (Loc, Procedure_Name),
2971 Statements, Outp => False);
2973 Proc_Decl := Make_Subprogram_Declaration (Loc,
2974 Copy_Specification (Loc, Specification (Body_Node)));
2976 Attr_Decl :=
2977 Make_Attribute_Definition_Clause (Loc,
2978 Name => New_Occurrence_Of (RACW_Type, Loc),
2979 Chars => Name_Write,
2980 Expression =>
2981 New_Occurrence_Of (
2982 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
2984 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
2985 Insert_After (Proc_Decl, Attr_Decl);
2986 Append_To (Declarations, Body_Node);
2987 end Add_RACW_Write_Attribute;
2989 ------------------------
2990 -- Add_RAS_Access_TSS --
2991 ------------------------
2993 procedure Add_RAS_Access_TSS (N : Node_Id) is
2994 Loc : constant Source_Ptr := Sloc (N);
2996 Ras_Type : constant Entity_Id := Defining_Identifier (N);
2997 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
2998 -- Ras_Type is the access to subprogram type while Fat_Type is the
2999 -- corresponding record type.
3001 RACW_Type : constant Entity_Id :=
3002 Underlying_RACW_Type (Ras_Type);
3003 Desig : constant Entity_Id :=
3004 Etype (Designated_Type (RACW_Type));
3006 Stub_Elements : constant Stub_Structure :=
3007 Stubs_Table.Get (Desig);
3008 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
3010 Proc : constant Entity_Id :=
3011 Make_Defining_Identifier (Loc,
3012 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
3014 Proc_Spec : Node_Id;
3016 -- Formal parameters
3018 Package_Name : constant Entity_Id :=
3019 Make_Defining_Identifier (Loc,
3020 Chars => Name_P);
3021 -- Target package
3023 Subp_Id : constant Entity_Id :=
3024 Make_Defining_Identifier (Loc,
3025 Chars => Name_S);
3026 -- Target subprogram
3028 Asynch_P : constant Entity_Id :=
3029 Make_Defining_Identifier (Loc,
3030 Chars => Name_Asynchronous);
3031 -- Is the procedure to which the 'Access applies asynchronous?
3033 All_Calls_Remote : constant Entity_Id :=
3034 Make_Defining_Identifier (Loc,
3035 Chars => Name_All_Calls_Remote);
3036 -- True if an All_Calls_Remote pragma applies to the RCI unit
3037 -- that contains the subprogram.
3039 -- Common local variables
3041 Proc_Decls : List_Id;
3042 Proc_Statements : List_Id;
3044 Origin : constant Entity_Id :=
3045 Make_Defining_Identifier (Loc,
3046 Chars => New_Internal_Name ('P'));
3048 -- Additional local variables for the local case
3050 Proxy_Addr : constant Entity_Id :=
3051 Make_Defining_Identifier (Loc,
3052 Chars => New_Internal_Name ('P'));
3054 -- Additional local variables for the remote case
3056 Local_Stub : constant Entity_Id :=
3057 Make_Defining_Identifier (Loc,
3058 Chars => New_Internal_Name ('L'));
3060 Stub_Ptr : constant Entity_Id :=
3061 Make_Defining_Identifier (Loc,
3062 Chars => New_Internal_Name ('S'));
3064 function Set_Field
3065 (Field_Name : Name_Id;
3066 Value : Node_Id) return Node_Id;
3067 -- Construct an assignment that sets the named component in the
3068 -- returned record
3070 ---------------
3071 -- Set_Field --
3072 ---------------
3074 function Set_Field
3075 (Field_Name : Name_Id;
3076 Value : Node_Id) return Node_Id
3078 begin
3079 return
3080 Make_Assignment_Statement (Loc,
3081 Name =>
3082 Make_Selected_Component (Loc,
3083 Prefix => Stub_Ptr,
3084 Selector_Name => Field_Name),
3085 Expression => Value);
3086 end Set_Field;
3088 -- Start of processing for Add_RAS_Access_TSS
3090 begin
3091 Proc_Decls := New_List (
3093 -- Common declarations
3095 Make_Object_Declaration (Loc,
3096 Defining_Identifier => Origin,
3097 Constant_Present => True,
3098 Object_Definition =>
3099 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3100 Expression =>
3101 Make_Function_Call (Loc,
3102 Name =>
3103 New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
3104 Parameter_Associations => New_List (
3105 New_Occurrence_Of (Package_Name, Loc)))),
3107 -- Declaration use only in the local case: proxy address
3109 Make_Object_Declaration (Loc,
3110 Defining_Identifier => Proxy_Addr,
3111 Object_Definition =>
3112 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
3114 -- Declarations used only in the remote case: stub object and
3115 -- stub pointer.
3117 Make_Object_Declaration (Loc,
3118 Defining_Identifier => Local_Stub,
3119 Aliased_Present => True,
3120 Object_Definition =>
3121 New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
3123 Make_Object_Declaration (Loc,
3124 Defining_Identifier =>
3125 Stub_Ptr,
3126 Object_Definition =>
3127 New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
3128 Expression =>
3129 Make_Attribute_Reference (Loc,
3130 Prefix => New_Occurrence_Of (Local_Stub, Loc),
3131 Attribute_Name => Name_Unchecked_Access)));
3133 Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
3134 -- Build_Get_Unique_RP_Call needs this information
3136 -- Note: Here we assume that the Fat_Type is a record
3137 -- containing just a pointer to a proxy or stub object.
3139 Proc_Statements := New_List (
3141 -- Generate:
3143 -- Get_RAS_Info (Pkg, Subp, PA);
3144 -- if Origin = Local_Partition_Id
3145 -- and then not All_Calls_Remote
3146 -- then
3147 -- return Fat_Type!(PA);
3148 -- end if;
3150 Make_Procedure_Call_Statement (Loc,
3151 Name =>
3152 New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
3153 Parameter_Associations => New_List (
3154 New_Occurrence_Of (Package_Name, Loc),
3155 New_Occurrence_Of (Subp_Id, Loc),
3156 New_Occurrence_Of (Proxy_Addr, Loc))),
3158 Make_Implicit_If_Statement (N,
3159 Condition =>
3160 Make_And_Then (Loc,
3161 Left_Opnd =>
3162 Make_Op_Eq (Loc,
3163 Left_Opnd =>
3164 New_Occurrence_Of (Origin, Loc),
3165 Right_Opnd =>
3166 Make_Function_Call (Loc,
3167 New_Occurrence_Of (
3168 RTE (RE_Get_Local_Partition_Id), Loc))),
3169 Right_Opnd =>
3170 Make_Op_Not (Loc,
3171 New_Occurrence_Of (All_Calls_Remote, Loc))),
3172 Then_Statements => New_List (
3173 Make_Return_Statement (Loc,
3174 Unchecked_Convert_To (Fat_Type,
3175 OK_Convert_To (RTE (RE_Address),
3176 New_Occurrence_Of (Proxy_Addr, Loc)))))),
3178 Set_Field (Name_Origin,
3179 New_Occurrence_Of (Origin, Loc)),
3181 Set_Field (Name_Receiver,
3182 Make_Function_Call (Loc,
3183 Name =>
3184 New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
3185 Parameter_Associations => New_List (
3186 New_Occurrence_Of (Package_Name, Loc)))),
3188 Set_Field (Name_Addr, New_Occurrence_Of (Proxy_Addr, Loc)),
3190 -- E.4.1(9) A remote call is asynchronous if it is a call to
3191 -- a procedure, or a call through a value of an access-to-procedure
3192 -- type, to which a pragma Asynchronous applies.
3194 -- Parameter Asynch_P is true when the procedure is asynchronous;
3195 -- Expression Asynch_T is true when the type is asynchronous.
3197 Set_Field (Name_Asynchronous,
3198 Make_Or_Else (Loc,
3199 New_Occurrence_Of (Asynch_P, Loc),
3200 New_Occurrence_Of (Boolean_Literals (
3201 Is_Asynchronous (Ras_Type)), Loc))));
3203 Append_List_To (Proc_Statements,
3204 Build_Get_Unique_RP_Call
3205 (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
3207 -- Return the newly created value
3209 Append_To (Proc_Statements,
3210 Make_Return_Statement (Loc,
3211 Expression =>
3212 Unchecked_Convert_To (Fat_Type,
3213 New_Occurrence_Of (Stub_Ptr, Loc))));
3215 Proc_Spec :=
3216 Make_Function_Specification (Loc,
3217 Defining_Unit_Name => Proc,
3218 Parameter_Specifications => New_List (
3219 Make_Parameter_Specification (Loc,
3220 Defining_Identifier => Package_Name,
3221 Parameter_Type =>
3222 New_Occurrence_Of (Standard_String, Loc)),
3224 Make_Parameter_Specification (Loc,
3225 Defining_Identifier => Subp_Id,
3226 Parameter_Type =>
3227 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)),
3229 Make_Parameter_Specification (Loc,
3230 Defining_Identifier => Asynch_P,
3231 Parameter_Type =>
3232 New_Occurrence_Of (Standard_Boolean, Loc)),
3234 Make_Parameter_Specification (Loc,
3235 Defining_Identifier => All_Calls_Remote,
3236 Parameter_Type =>
3237 New_Occurrence_Of (Standard_Boolean, Loc))),
3239 Result_Definition =>
3240 New_Occurrence_Of (Fat_Type, Loc));
3242 -- Set the kind and return type of the function to prevent
3243 -- ambiguities between Ras_Type and Fat_Type in subsequent analysis.
3245 Set_Ekind (Proc, E_Function);
3246 Set_Etype (Proc, Fat_Type);
3248 Discard_Node (
3249 Make_Subprogram_Body (Loc,
3250 Specification => Proc_Spec,
3251 Declarations => Proc_Decls,
3252 Handled_Statement_Sequence =>
3253 Make_Handled_Sequence_Of_Statements (Loc,
3254 Statements => Proc_Statements)));
3256 Set_TSS (Fat_Type, Proc);
3257 end Add_RAS_Access_TSS;
3259 -----------------------
3260 -- Add_RAST_Features --
3261 -----------------------
3263 procedure Add_RAST_Features
3264 (Vis_Decl : Node_Id;
3265 RAS_Type : Entity_Id)
3267 pragma Warnings (Off);
3268 pragma Unreferenced (RAS_Type);
3269 pragma Warnings (On);
3270 begin
3271 Add_RAS_Access_TSS (Vis_Decl);
3272 end Add_RAST_Features;
3274 -----------------------------------------
3275 -- Add_Receiving_Stubs_To_Declarations --
3276 -----------------------------------------
3278 procedure Add_Receiving_Stubs_To_Declarations
3279 (Pkg_Spec : Node_Id;
3280 Decls : List_Id)
3282 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
3284 Request_Parameter : Node_Id;
3286 Pkg_RPC_Receiver : constant Entity_Id :=
3287 Make_Defining_Identifier (Loc,
3288 New_Internal_Name ('H'));
3289 Pkg_RPC_Receiver_Statements : List_Id;
3290 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
3291 Pkg_RPC_Receiver_Body : Node_Id;
3292 -- A Pkg_RPC_Receiver is built to decode the request
3294 Lookup_RAS_Info : constant Entity_Id :=
3295 Make_Defining_Identifier (Loc,
3296 Chars => New_Internal_Name ('R'));
3297 -- A remote subprogram is created to allow peers to look up
3298 -- RAS information using subprogram ids.
3300 Subp_Id : Entity_Id;
3301 Subp_Index : Entity_Id;
3302 -- Subprogram_Id as read from the incoming stream
3304 Current_Declaration : Node_Id;
3305 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
3306 Current_Stubs : Node_Id;
3308 Subp_Info_Array : constant Entity_Id :=
3309 Make_Defining_Identifier (Loc,
3310 Chars => New_Internal_Name ('I'));
3312 Subp_Info_List : constant List_Id := New_List;
3314 Register_Pkg_Actuals : constant List_Id := New_List;
3316 All_Calls_Remote_E : Entity_Id;
3317 Proxy_Object_Addr : Entity_Id;
3319 procedure Append_Stubs_To
3320 (RPC_Receiver_Cases : List_Id;
3321 Stubs : Node_Id;
3322 Subprogram_Number : Int);
3323 -- Add one case to the specified RPC receiver case list
3324 -- associating Subprogram_Number with the subprogram declared
3325 -- by Declaration, for which we have receiving stubs in Stubs.
3327 ---------------------
3328 -- Append_Stubs_To --
3329 ---------------------
3331 procedure Append_Stubs_To
3332 (RPC_Receiver_Cases : List_Id;
3333 Stubs : Node_Id;
3334 Subprogram_Number : Int)
3336 begin
3337 Append_To (RPC_Receiver_Cases,
3338 Make_Case_Statement_Alternative (Loc,
3339 Discrete_Choices =>
3340 New_List (Make_Integer_Literal (Loc, Subprogram_Number)),
3341 Statements =>
3342 New_List (
3343 Make_Procedure_Call_Statement (Loc,
3344 Name =>
3345 New_Occurrence_Of (
3346 Defining_Entity (Stubs), Loc),
3347 Parameter_Associations => New_List (
3348 New_Occurrence_Of (Request_Parameter, Loc))))));
3349 end Append_Stubs_To;
3351 -- Start of processing for Add_Receiving_Stubs_To_Declarations
3353 begin
3354 -- Building receiving stubs consist in several operations:
3356 -- - a package RPC receiver must be built. This subprogram
3357 -- will get a Subprogram_Id from the incoming stream
3358 -- and will dispatch the call to the right subprogram
3360 -- - a receiving stub for any subprogram visible in the package
3361 -- spec. This stub will read all the parameters from the stream,
3362 -- and put the result as well as the exception occurrence in the
3363 -- output stream
3365 -- - a dummy package with an empty spec and a body made of an
3366 -- elaboration part, whose job is to register the receiving
3367 -- part of this RCI package on the name server. This is done
3368 -- by calling System.Partition_Interface.Register_Receiving_Stub
3370 Build_RPC_Receiver_Body (
3371 RPC_Receiver => Pkg_RPC_Receiver,
3372 Request => Request_Parameter,
3373 Subp_Id => Subp_Id,
3374 Subp_Index => Subp_Index,
3375 Stmts => Pkg_RPC_Receiver_Statements,
3376 Decl => Pkg_RPC_Receiver_Body);
3377 pragma Assert (Subp_Id = Subp_Index);
3379 -- A null subp_id denotes a call through a RAS, in which case the
3380 -- next Uint_64 element in the stream is the address of the local
3381 -- proxy object, from which we can retrieve the actual subprogram id.
3383 Append_To (Pkg_RPC_Receiver_Statements,
3384 Make_Implicit_If_Statement (Pkg_Spec,
3385 Condition =>
3386 Make_Op_Eq (Loc,
3387 New_Occurrence_Of (Subp_Id, Loc),
3388 Make_Integer_Literal (Loc, 0)),
3389 Then_Statements => New_List (
3390 Make_Assignment_Statement (Loc,
3391 Name =>
3392 New_Occurrence_Of (Subp_Id, Loc),
3393 Expression =>
3394 Make_Selected_Component (Loc,
3395 Prefix =>
3396 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
3397 OK_Convert_To (RTE (RE_Address),
3398 Make_Attribute_Reference (Loc,
3399 Prefix =>
3400 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
3401 Attribute_Name =>
3402 Name_Input,
3403 Expressions => New_List (
3404 Make_Selected_Component (Loc,
3405 Prefix => Request_Parameter,
3406 Selector_Name => Name_Params))))),
3407 Selector_Name =>
3408 Make_Identifier (Loc, Name_Subp_Id))))));
3410 -- Build a subprogram for RAS information lookups
3412 Current_Declaration :=
3413 Make_Subprogram_Declaration (Loc,
3414 Specification =>
3415 Make_Function_Specification (Loc,
3416 Defining_Unit_Name =>
3417 Lookup_RAS_Info,
3418 Parameter_Specifications => New_List (
3419 Make_Parameter_Specification (Loc,
3420 Defining_Identifier =>
3421 Make_Defining_Identifier (Loc, Name_Subp_Id),
3422 In_Present =>
3423 True,
3424 Parameter_Type =>
3425 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
3426 Result_Definition =>
3427 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
3428 Append_To (Decls, Current_Declaration);
3429 Analyze (Current_Declaration);
3431 Current_Stubs := Build_Subprogram_Receiving_Stubs
3432 (Vis_Decl => Current_Declaration,
3433 Asynchronous => False);
3434 Append_To (Decls, Current_Stubs);
3435 Analyze (Current_Stubs);
3437 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
3438 Stubs =>
3439 Current_Stubs,
3440 Subprogram_Number => 1);
3442 -- For each subprogram, the receiving stub will be built and a
3443 -- case statement will be made on the Subprogram_Id to dispatch
3444 -- to the right subprogram.
3446 All_Calls_Remote_E := Boolean_Literals (
3447 Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
3449 Overload_Counter_Table.Reset;
3451 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
3452 while Present (Current_Declaration) loop
3453 if Nkind (Current_Declaration) = N_Subprogram_Declaration
3454 and then Comes_From_Source (Current_Declaration)
3455 then
3456 declare
3457 Loc : constant Source_Ptr :=
3458 Sloc (Current_Declaration);
3459 -- While specifically processing Current_Declaration, use
3460 -- its Sloc as the location of all generated nodes.
3462 Subp_Def : constant Entity_Id :=
3463 Defining_Unit_Name
3464 (Specification (Current_Declaration));
3466 Subp_Val : String_Id;
3468 begin
3469 pragma Assert (Current_Subprogram_Number =
3470 Get_Subprogram_Id (Subp_Def));
3472 -- Build receiving stub
3474 Current_Stubs :=
3475 Build_Subprogram_Receiving_Stubs
3476 (Vis_Decl => Current_Declaration,
3477 Asynchronous =>
3478 Nkind (Specification (Current_Declaration)) =
3479 N_Procedure_Specification
3480 and then Is_Asynchronous (Subp_Def));
3482 Append_To (Decls, Current_Stubs);
3483 Analyze (Current_Stubs);
3485 -- Build RAS proxy
3487 Add_RAS_Proxy_And_Analyze (Decls,
3488 Vis_Decl =>
3489 Current_Declaration,
3490 All_Calls_Remote_E =>
3491 All_Calls_Remote_E,
3492 Proxy_Object_Addr =>
3493 Proxy_Object_Addr);
3495 -- Compute distribution identifier
3497 Assign_Subprogram_Identifier (
3498 Subp_Def,
3499 Current_Subprogram_Number,
3500 Subp_Val);
3502 -- Add subprogram descriptor (RCI_Subp_Info) to the
3503 -- subprograms table for this receiver. The aggregate
3504 -- below must be kept consistent with the declaration
3505 -- of type RCI_Subp_Info in System.Partition_Interface.
3507 Append_To (Subp_Info_List,
3508 Make_Component_Association (Loc,
3509 Choices => New_List (
3510 Make_Integer_Literal (Loc,
3511 Current_Subprogram_Number)),
3512 Expression =>
3513 Make_Aggregate (Loc,
3514 Component_Associations => New_List (
3515 Make_Component_Association (Loc,
3516 Choices => New_List (
3517 Make_Identifier (Loc, Name_Addr)),
3518 Expression =>
3519 New_Occurrence_Of (
3520 Proxy_Object_Addr, Loc))))));
3522 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
3523 Stubs =>
3524 Current_Stubs,
3525 Subprogram_Number =>
3526 Current_Subprogram_Number);
3527 end;
3529 Current_Subprogram_Number := Current_Subprogram_Number + 1;
3530 end if;
3532 Next (Current_Declaration);
3533 end loop;
3535 -- If we receive an invalid Subprogram_Id, it is best to do nothing
3536 -- rather than raising an exception since we do not want someone
3537 -- to crash a remote partition by sending invalid subprogram ids.
3538 -- This is consistent with the other parts of the case statement
3539 -- since even in presence of incorrect parameters in the stream,
3540 -- every exception will be caught and (if the subprogram is not an
3541 -- APC) put into the result stream and sent away.
3543 Append_To (Pkg_RPC_Receiver_Cases,
3544 Make_Case_Statement_Alternative (Loc,
3545 Discrete_Choices =>
3546 New_List (Make_Others_Choice (Loc)),
3547 Statements =>
3548 New_List (Make_Null_Statement (Loc))));
3550 Append_To (Pkg_RPC_Receiver_Statements,
3551 Make_Case_Statement (Loc,
3552 Expression =>
3553 New_Occurrence_Of (Subp_Id, Loc),
3554 Alternatives => Pkg_RPC_Receiver_Cases));
3556 Append_To (Decls,
3557 Make_Object_Declaration (Loc,
3558 Defining_Identifier => Subp_Info_Array,
3559 Constant_Present => True,
3560 Aliased_Present => True,
3561 Object_Definition =>
3562 Make_Subtype_Indication (Loc,
3563 Subtype_Mark =>
3564 New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
3565 Constraint =>
3566 Make_Index_Or_Discriminant_Constraint (Loc,
3567 New_List (
3568 Make_Range (Loc,
3569 Low_Bound => Make_Integer_Literal (Loc,
3570 First_RCI_Subprogram_Id),
3571 High_Bound =>
3572 Make_Integer_Literal (Loc,
3573 First_RCI_Subprogram_Id
3574 + List_Length (Subp_Info_List) - 1))))),
3575 Expression =>
3576 Make_Aggregate (Loc,
3577 Component_Associations => Subp_Info_List)));
3578 Analyze (Last (Decls));
3580 Append_To (Decls,
3581 Make_Subprogram_Body (Loc,
3582 Specification =>
3583 Copy_Specification (Loc, Parent (Lookup_RAS_Info)),
3584 Declarations =>
3585 No_List,
3586 Handled_Statement_Sequence =>
3587 Make_Handled_Sequence_Of_Statements (Loc,
3588 Statements => New_List (
3589 Make_Return_Statement (Loc,
3590 Expression => OK_Convert_To (RTE (RE_Unsigned_64),
3591 Make_Selected_Component (Loc,
3592 Prefix =>
3593 Make_Indexed_Component (Loc,
3594 Prefix =>
3595 New_Occurrence_Of (Subp_Info_Array, Loc),
3596 Expressions => New_List (
3597 Convert_To (Standard_Integer,
3598 Make_Identifier (Loc, Name_Subp_Id)))),
3599 Selector_Name =>
3600 Make_Identifier (Loc, Name_Addr))))))));
3601 Analyze (Last (Decls));
3603 Append_To (Decls, Pkg_RPC_Receiver_Body);
3604 Analyze (Last (Decls));
3606 Get_Library_Unit_Name_String (Pkg_Spec);
3607 Append_To (Register_Pkg_Actuals,
3608 -- Name
3609 Make_String_Literal (Loc,
3610 Strval => String_From_Name_Buffer));
3612 Append_To (Register_Pkg_Actuals,
3613 -- Receiver
3614 Make_Attribute_Reference (Loc,
3615 Prefix =>
3616 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
3617 Attribute_Name =>
3618 Name_Unrestricted_Access));
3620 Append_To (Register_Pkg_Actuals,
3621 -- Version
3622 Make_Attribute_Reference (Loc,
3623 Prefix =>
3624 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
3625 Attribute_Name =>
3626 Name_Version));
3628 Append_To (Register_Pkg_Actuals,
3629 -- Subp_Info
3630 Make_Attribute_Reference (Loc,
3631 Prefix =>
3632 New_Occurrence_Of (Subp_Info_Array, Loc),
3633 Attribute_Name =>
3634 Name_Address));
3636 Append_To (Register_Pkg_Actuals,
3637 -- Subp_Info_Len
3638 Make_Attribute_Reference (Loc,
3639 Prefix =>
3640 New_Occurrence_Of (Subp_Info_Array, Loc),
3641 Attribute_Name =>
3642 Name_Length));
3644 Append_To (Decls,
3645 Make_Procedure_Call_Statement (Loc,
3646 Name =>
3647 New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
3648 Parameter_Associations => Register_Pkg_Actuals));
3649 Analyze (Last (Decls));
3650 end Add_Receiving_Stubs_To_Declarations;
3652 ---------------------------------
3653 -- Build_General_Calling_Stubs --
3654 ---------------------------------
3656 procedure Build_General_Calling_Stubs
3657 (Decls : List_Id;
3658 Statements : List_Id;
3659 Target_Partition : Entity_Id;
3660 Target_RPC_Receiver : Node_Id;
3661 Subprogram_Id : Node_Id;
3662 Asynchronous : Node_Id := Empty;
3663 Is_Known_Asynchronous : Boolean := False;
3664 Is_Known_Non_Asynchronous : Boolean := False;
3665 Is_Function : Boolean;
3666 Spec : Node_Id;
3667 Stub_Type : Entity_Id := Empty;
3668 RACW_Type : Entity_Id := Empty;
3669 Nod : Node_Id)
3671 Loc : constant Source_Ptr := Sloc (Nod);
3673 Stream_Parameter : Node_Id;
3674 -- Name of the stream used to transmit parameters to the
3675 -- remote package.
3677 Result_Parameter : Node_Id;
3678 -- Name of the result parameter (in non-APC cases) which get the
3679 -- result of the remote subprogram.
3681 Exception_Return_Parameter : Node_Id;
3682 -- Name of the parameter which will hold the exception sent by the
3683 -- remote subprogram.
3685 Current_Parameter : Node_Id;
3686 -- Current parameter being handled
3688 Ordered_Parameters_List : constant List_Id :=
3689 Build_Ordered_Parameters_List (Spec);
3691 Asynchronous_Statements : List_Id := No_List;
3692 Non_Asynchronous_Statements : List_Id := No_List;
3693 -- Statements specifics to the Asynchronous/Non-Asynchronous cases
3695 Extra_Formal_Statements : constant List_Id := New_List;
3696 -- List of statements for extra formal parameters. It will appear
3697 -- after the regular statements for writing out parameters.
3699 pragma Warnings (Off);
3700 pragma Unreferenced (RACW_Type);
3701 -- Used only for the PolyORB case
3702 pragma Warnings (On);
3704 begin
3705 -- The general form of a calling stub for a given subprogram is:
3707 -- procedure X (...) is P : constant Partition_ID :=
3708 -- RCI_Cache.Get_Active_Partition_ID; Stream, Result : aliased
3709 -- System.RPC.Params_Stream_Type (0); begin
3710 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
3711 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
3712 -- Put_Subprogram_Id_In_Stream; Put_Parameters_In_Stream; Do_RPC
3713 -- (Stream, Result); Read_Exception_Occurrence_From_Result;
3714 -- Raise_It;
3715 -- Read_Out_Parameters_And_Function_Return_From_Stream; end X;
3717 -- There are some variations: Do_APC is called for an asynchronous
3718 -- procedure and the part after the call is completely ommitted as
3719 -- well as the declaration of Result. For a function call, 'Input is
3720 -- always used to read the result even if it is constrained.
3722 Stream_Parameter :=
3723 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3725 Append_To (Decls,
3726 Make_Object_Declaration (Loc,
3727 Defining_Identifier => Stream_Parameter,
3728 Aliased_Present => True,
3729 Object_Definition =>
3730 Make_Subtype_Indication (Loc,
3731 Subtype_Mark =>
3732 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
3733 Constraint =>
3734 Make_Index_Or_Discriminant_Constraint (Loc,
3735 Constraints =>
3736 New_List (Make_Integer_Literal (Loc, 0))))));
3738 if not Is_Known_Asynchronous then
3739 Result_Parameter :=
3740 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3742 Append_To (Decls,
3743 Make_Object_Declaration (Loc,
3744 Defining_Identifier => Result_Parameter,
3745 Aliased_Present => True,
3746 Object_Definition =>
3747 Make_Subtype_Indication (Loc,
3748 Subtype_Mark =>
3749 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
3750 Constraint =>
3751 Make_Index_Or_Discriminant_Constraint (Loc,
3752 Constraints =>
3753 New_List (Make_Integer_Literal (Loc, 0))))));
3755 Exception_Return_Parameter :=
3756 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3758 Append_To (Decls,
3759 Make_Object_Declaration (Loc,
3760 Defining_Identifier => Exception_Return_Parameter,
3761 Object_Definition =>
3762 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
3764 else
3765 Result_Parameter := Empty;
3766 Exception_Return_Parameter := Empty;
3767 end if;
3769 -- Put first the RPC receiver corresponding to the remote package
3771 Append_To (Statements,
3772 Make_Attribute_Reference (Loc,
3773 Prefix =>
3774 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
3775 Attribute_Name => Name_Write,
3776 Expressions => New_List (
3777 Make_Attribute_Reference (Loc,
3778 Prefix =>
3779 New_Occurrence_Of (Stream_Parameter, Loc),
3780 Attribute_Name =>
3781 Name_Access),
3782 Target_RPC_Receiver)));
3784 -- Then put the Subprogram_Id of the subprogram we want to call in
3785 -- the stream.
3787 Append_To (Statements,
3788 Make_Attribute_Reference (Loc,
3789 Prefix =>
3790 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
3791 Attribute_Name =>
3792 Name_Write,
3793 Expressions => New_List (
3794 Make_Attribute_Reference (Loc,
3795 Prefix =>
3796 New_Occurrence_Of (Stream_Parameter, Loc),
3797 Attribute_Name => Name_Access),
3798 Subprogram_Id)));
3800 Current_Parameter := First (Ordered_Parameters_List);
3801 while Present (Current_Parameter) loop
3802 declare
3803 Typ : constant Node_Id :=
3804 Parameter_Type (Current_Parameter);
3805 Etyp : Entity_Id;
3806 Constrained : Boolean;
3807 Value : Node_Id;
3808 Extra_Parameter : Entity_Id;
3810 begin
3811 if Is_RACW_Controlling_Formal
3812 (Current_Parameter, Stub_Type)
3813 then
3814 -- In the case of a controlling formal argument, we marshall
3815 -- its addr field rather than the local stub.
3817 Append_To (Statements,
3818 Pack_Node_Into_Stream (Loc,
3819 Stream => Stream_Parameter,
3820 Object =>
3821 Make_Selected_Component (Loc,
3822 Prefix =>
3823 Defining_Identifier (Current_Parameter),
3824 Selector_Name => Name_Addr),
3825 Etyp => RTE (RE_Unsigned_64)));
3827 else
3828 Value := New_Occurrence_Of
3829 (Defining_Identifier (Current_Parameter), Loc);
3831 -- Access type parameters are transmitted as in out
3832 -- parameters. However, a dereference is needed so that
3833 -- we marshall the designated object.
3835 if Nkind (Typ) = N_Access_Definition then
3836 Value := Make_Explicit_Dereference (Loc, Value);
3837 Etyp := Etype (Subtype_Mark (Typ));
3838 else
3839 Etyp := Etype (Typ);
3840 end if;
3842 Constrained :=
3843 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
3845 -- Any parameter but unconstrained out parameters are
3846 -- transmitted to the peer.
3848 if In_Present (Current_Parameter)
3849 or else not Out_Present (Current_Parameter)
3850 or else not Constrained
3851 then
3852 Append_To (Statements,
3853 Make_Attribute_Reference (Loc,
3854 Prefix =>
3855 New_Occurrence_Of (Etyp, Loc),
3856 Attribute_Name =>
3857 Output_From_Constrained (Constrained),
3858 Expressions => New_List (
3859 Make_Attribute_Reference (Loc,
3860 Prefix =>
3861 New_Occurrence_Of (Stream_Parameter, Loc),
3862 Attribute_Name => Name_Access),
3863 Value)));
3864 end if;
3865 end if;
3867 -- If the current parameter has a dynamic constrained status,
3868 -- then this status is transmitted as well.
3869 -- This should be done for accessibility as well ???
3871 if Nkind (Typ) /= N_Access_Definition
3872 and then Need_Extra_Constrained (Current_Parameter)
3873 then
3874 -- In this block, we do not use the extra formal that has
3875 -- been created because it does not exist at the time of
3876 -- expansion when building calling stubs for remote access
3877 -- to subprogram types. We create an extra variable of this
3878 -- type and push it in the stream after the regular
3879 -- parameters.
3881 Extra_Parameter := Make_Defining_Identifier
3882 (Loc, New_Internal_Name ('P'));
3884 Append_To (Decls,
3885 Make_Object_Declaration (Loc,
3886 Defining_Identifier => Extra_Parameter,
3887 Constant_Present => True,
3888 Object_Definition =>
3889 New_Occurrence_Of (Standard_Boolean, Loc),
3890 Expression =>
3891 Make_Attribute_Reference (Loc,
3892 Prefix =>
3893 New_Occurrence_Of (
3894 Defining_Identifier (Current_Parameter), Loc),
3895 Attribute_Name => Name_Constrained)));
3897 Append_To (Extra_Formal_Statements,
3898 Make_Attribute_Reference (Loc,
3899 Prefix =>
3900 New_Occurrence_Of (Standard_Boolean, Loc),
3901 Attribute_Name =>
3902 Name_Write,
3903 Expressions => New_List (
3904 Make_Attribute_Reference (Loc,
3905 Prefix =>
3906 New_Occurrence_Of (Stream_Parameter, Loc),
3907 Attribute_Name =>
3908 Name_Access),
3909 New_Occurrence_Of (Extra_Parameter, Loc))));
3910 end if;
3912 Next (Current_Parameter);
3913 end;
3914 end loop;
3916 -- Append the formal statements list to the statements
3918 Append_List_To (Statements, Extra_Formal_Statements);
3920 if not Is_Known_Non_Asynchronous then
3922 -- Build the call to System.RPC.Do_APC
3924 Asynchronous_Statements := New_List (
3925 Make_Procedure_Call_Statement (Loc,
3926 Name =>
3927 New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
3928 Parameter_Associations => New_List (
3929 New_Occurrence_Of (Target_Partition, Loc),
3930 Make_Attribute_Reference (Loc,
3931 Prefix =>
3932 New_Occurrence_Of (Stream_Parameter, Loc),
3933 Attribute_Name =>
3934 Name_Access))));
3935 else
3936 Asynchronous_Statements := No_List;
3937 end if;
3939 if not Is_Known_Asynchronous then
3941 -- Build the call to System.RPC.Do_RPC
3943 Non_Asynchronous_Statements := New_List (
3944 Make_Procedure_Call_Statement (Loc,
3945 Name =>
3946 New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
3947 Parameter_Associations => New_List (
3948 New_Occurrence_Of (Target_Partition, Loc),
3950 Make_Attribute_Reference (Loc,
3951 Prefix =>
3952 New_Occurrence_Of (Stream_Parameter, Loc),
3953 Attribute_Name =>
3954 Name_Access),
3956 Make_Attribute_Reference (Loc,
3957 Prefix =>
3958 New_Occurrence_Of (Result_Parameter, Loc),
3959 Attribute_Name =>
3960 Name_Access))));
3962 -- Read the exception occurrence from the result stream and
3963 -- reraise it. It does no harm if this is a Null_Occurrence since
3964 -- this does nothing.
3966 Append_To (Non_Asynchronous_Statements,
3967 Make_Attribute_Reference (Loc,
3968 Prefix =>
3969 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
3971 Attribute_Name =>
3972 Name_Read,
3974 Expressions => New_List (
3975 Make_Attribute_Reference (Loc,
3976 Prefix =>
3977 New_Occurrence_Of (Result_Parameter, Loc),
3978 Attribute_Name =>
3979 Name_Access),
3980 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
3982 Append_To (Non_Asynchronous_Statements,
3983 Make_Procedure_Call_Statement (Loc,
3984 Name =>
3985 New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
3986 Parameter_Associations => New_List (
3987 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
3989 if Is_Function then
3991 -- If this is a function call, then read the value and return
3992 -- it. The return value is written/read using 'Output/'Input.
3994 Append_To (Non_Asynchronous_Statements,
3995 Make_Tag_Check (Loc,
3996 Make_Return_Statement (Loc,
3997 Expression =>
3998 Make_Attribute_Reference (Loc,
3999 Prefix =>
4000 New_Occurrence_Of (
4001 Etype (Result_Definition (Spec)), Loc),
4003 Attribute_Name => Name_Input,
4005 Expressions => New_List (
4006 Make_Attribute_Reference (Loc,
4007 Prefix =>
4008 New_Occurrence_Of (Result_Parameter, Loc),
4009 Attribute_Name => Name_Access))))));
4011 else
4012 -- Loop around parameters and assign out (or in out)
4013 -- parameters. In the case of RACW, controlling arguments
4014 -- cannot possibly have changed since they are remote, so we do
4015 -- not read them from the stream.
4017 Current_Parameter := First (Ordered_Parameters_List);
4018 while Present (Current_Parameter) loop
4019 declare
4020 Typ : constant Node_Id :=
4021 Parameter_Type (Current_Parameter);
4022 Etyp : Entity_Id;
4023 Value : Node_Id;
4025 begin
4026 Value :=
4027 New_Occurrence_Of
4028 (Defining_Identifier (Current_Parameter), Loc);
4030 if Nkind (Typ) = N_Access_Definition then
4031 Value := Make_Explicit_Dereference (Loc, Value);
4032 Etyp := Etype (Subtype_Mark (Typ));
4033 else
4034 Etyp := Etype (Typ);
4035 end if;
4037 if (Out_Present (Current_Parameter)
4038 or else Nkind (Typ) = N_Access_Definition)
4039 and then Etyp /= Stub_Type
4040 then
4041 Append_To (Non_Asynchronous_Statements,
4042 Make_Attribute_Reference (Loc,
4043 Prefix =>
4044 New_Occurrence_Of (Etyp, Loc),
4046 Attribute_Name => Name_Read,
4048 Expressions => New_List (
4049 Make_Attribute_Reference (Loc,
4050 Prefix =>
4051 New_Occurrence_Of (Result_Parameter, Loc),
4052 Attribute_Name =>
4053 Name_Access),
4054 Value)));
4055 end if;
4056 end;
4058 Next (Current_Parameter);
4059 end loop;
4060 end if;
4061 end if;
4063 if Is_Known_Asynchronous then
4064 Append_List_To (Statements, Asynchronous_Statements);
4066 elsif Is_Known_Non_Asynchronous then
4067 Append_List_To (Statements, Non_Asynchronous_Statements);
4069 else
4070 pragma Assert (Present (Asynchronous));
4071 Prepend_To (Asynchronous_Statements,
4072 Make_Attribute_Reference (Loc,
4073 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
4074 Attribute_Name => Name_Write,
4075 Expressions => New_List (
4076 Make_Attribute_Reference (Loc,
4077 Prefix =>
4078 New_Occurrence_Of (Stream_Parameter, Loc),
4079 Attribute_Name => Name_Access),
4080 New_Occurrence_Of (Standard_True, Loc))));
4082 Prepend_To (Non_Asynchronous_Statements,
4083 Make_Attribute_Reference (Loc,
4084 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
4085 Attribute_Name => Name_Write,
4086 Expressions => New_List (
4087 Make_Attribute_Reference (Loc,
4088 Prefix =>
4089 New_Occurrence_Of (Stream_Parameter, Loc),
4090 Attribute_Name => Name_Access),
4091 New_Occurrence_Of (Standard_False, Loc))));
4093 Append_To (Statements,
4094 Make_Implicit_If_Statement (Nod,
4095 Condition => Asynchronous,
4096 Then_Statements => Asynchronous_Statements,
4097 Else_Statements => Non_Asynchronous_Statements));
4098 end if;
4099 end Build_General_Calling_Stubs;
4101 -----------------------------
4102 -- Build_RPC_Receiver_Body --
4103 -----------------------------
4105 procedure Build_RPC_Receiver_Body
4106 (RPC_Receiver : Entity_Id;
4107 Request : out Entity_Id;
4108 Subp_Id : out Entity_Id;
4109 Subp_Index : out Entity_Id;
4110 Stmts : out List_Id;
4111 Decl : out Node_Id)
4113 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
4115 RPC_Receiver_Spec : Node_Id;
4116 RPC_Receiver_Decls : List_Id;
4118 begin
4119 Request := Make_Defining_Identifier (Loc, Name_R);
4121 RPC_Receiver_Spec :=
4122 Build_RPC_Receiver_Specification
4123 (RPC_Receiver => RPC_Receiver,
4124 Request_Parameter => Request);
4126 Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
4127 Subp_Index := Subp_Id;
4129 -- Subp_Id may not be a constant, because in the case of the RPC
4130 -- receiver for an RCI package, when a call is received from a RAS
4131 -- dereference, it will be assigned during subsequent processing.
4133 RPC_Receiver_Decls := New_List (
4134 Make_Object_Declaration (Loc,
4135 Defining_Identifier => Subp_Id,
4136 Object_Definition =>
4137 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
4138 Expression =>
4139 Make_Attribute_Reference (Loc,
4140 Prefix =>
4141 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
4142 Attribute_Name => Name_Input,
4143 Expressions => New_List (
4144 Make_Selected_Component (Loc,
4145 Prefix => Request,
4146 Selector_Name => Name_Params)))));
4148 Stmts := New_List;
4150 Decl :=
4151 Make_Subprogram_Body (Loc,
4152 Specification => RPC_Receiver_Spec,
4153 Declarations => RPC_Receiver_Decls,
4154 Handled_Statement_Sequence =>
4155 Make_Handled_Sequence_Of_Statements (Loc,
4156 Statements => Stmts));
4157 end Build_RPC_Receiver_Body;
4159 -----------------------
4160 -- Build_Stub_Target --
4161 -----------------------
4163 function Build_Stub_Target
4164 (Loc : Source_Ptr;
4165 Decls : List_Id;
4166 RCI_Locator : Entity_Id;
4167 Controlling_Parameter : Entity_Id) return RPC_Target
4169 Target_Info : RPC_Target (PCS_Kind => Name_GARLIC_DSA);
4170 begin
4171 Target_Info.Partition :=
4172 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
4173 if Present (Controlling_Parameter) then
4174 Append_To (Decls,
4175 Make_Object_Declaration (Loc,
4176 Defining_Identifier => Target_Info.Partition,
4177 Constant_Present => True,
4178 Object_Definition =>
4179 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
4181 Expression =>
4182 Make_Selected_Component (Loc,
4183 Prefix => Controlling_Parameter,
4184 Selector_Name => Name_Origin)));
4186 Target_Info.RPC_Receiver :=
4187 Make_Selected_Component (Loc,
4188 Prefix => Controlling_Parameter,
4189 Selector_Name => Name_Receiver);
4191 else
4192 Append_To (Decls,
4193 Make_Object_Declaration (Loc,
4194 Defining_Identifier => Target_Info.Partition,
4195 Constant_Present => True,
4196 Object_Definition =>
4197 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
4199 Expression =>
4200 Make_Function_Call (Loc,
4201 Name => Make_Selected_Component (Loc,
4202 Prefix =>
4203 Make_Identifier (Loc, Chars (RCI_Locator)),
4204 Selector_Name =>
4205 Make_Identifier (Loc,
4206 Name_Get_Active_Partition_ID)))));
4208 Target_Info.RPC_Receiver :=
4209 Make_Selected_Component (Loc,
4210 Prefix =>
4211 Make_Identifier (Loc, Chars (RCI_Locator)),
4212 Selector_Name =>
4213 Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
4214 end if;
4215 return Target_Info;
4216 end Build_Stub_Target;
4218 ---------------------
4219 -- Build_Stub_Type --
4220 ---------------------
4222 procedure Build_Stub_Type
4223 (RACW_Type : Entity_Id;
4224 Stub_Type : Entity_Id;
4225 Stub_Type_Decl : out Node_Id;
4226 RPC_Receiver_Decl : out Node_Id)
4228 Loc : constant Source_Ptr := Sloc (Stub_Type);
4229 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
4231 begin
4232 Stub_Type_Decl :=
4233 Make_Full_Type_Declaration (Loc,
4234 Defining_Identifier => Stub_Type,
4235 Type_Definition =>
4236 Make_Record_Definition (Loc,
4237 Tagged_Present => True,
4238 Limited_Present => True,
4239 Component_List =>
4240 Make_Component_List (Loc,
4241 Component_Items => New_List (
4243 Make_Component_Declaration (Loc,
4244 Defining_Identifier =>
4245 Make_Defining_Identifier (Loc, Name_Origin),
4246 Component_Definition =>
4247 Make_Component_Definition (Loc,
4248 Aliased_Present => False,
4249 Subtype_Indication =>
4250 New_Occurrence_Of (
4251 RTE (RE_Partition_ID), Loc))),
4253 Make_Component_Declaration (Loc,
4254 Defining_Identifier =>
4255 Make_Defining_Identifier (Loc, Name_Receiver),
4256 Component_Definition =>
4257 Make_Component_Definition (Loc,
4258 Aliased_Present => False,
4259 Subtype_Indication =>
4260 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
4262 Make_Component_Declaration (Loc,
4263 Defining_Identifier =>
4264 Make_Defining_Identifier (Loc, Name_Addr),
4265 Component_Definition =>
4266 Make_Component_Definition (Loc,
4267 Aliased_Present => False,
4268 Subtype_Indication =>
4269 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
4271 Make_Component_Declaration (Loc,
4272 Defining_Identifier =>
4273 Make_Defining_Identifier (Loc, Name_Asynchronous),
4274 Component_Definition =>
4275 Make_Component_Definition (Loc,
4276 Aliased_Present => False,
4277 Subtype_Indication =>
4278 New_Occurrence_Of (
4279 Standard_Boolean, Loc)))))));
4281 if Is_RAS then
4282 RPC_Receiver_Decl := Empty;
4283 else
4284 declare
4285 RPC_Receiver_Request : constant Entity_Id :=
4286 Make_Defining_Identifier (Loc, Name_R);
4287 begin
4288 RPC_Receiver_Decl :=
4289 Make_Subprogram_Declaration (Loc,
4290 Build_RPC_Receiver_Specification (
4291 RPC_Receiver => Make_Defining_Identifier (Loc,
4292 New_Internal_Name ('R')),
4293 Request_Parameter => RPC_Receiver_Request));
4294 end;
4295 end if;
4296 end Build_Stub_Type;
4298 --------------------------------------
4299 -- Build_Subprogram_Receiving_Stubs --
4300 --------------------------------------
4302 function Build_Subprogram_Receiving_Stubs
4303 (Vis_Decl : Node_Id;
4304 Asynchronous : Boolean;
4305 Dynamically_Asynchronous : Boolean := False;
4306 Stub_Type : Entity_Id := Empty;
4307 RACW_Type : Entity_Id := Empty;
4308 Parent_Primitive : Entity_Id := Empty) return Node_Id
4310 Loc : constant Source_Ptr := Sloc (Vis_Decl);
4312 Request_Parameter : Node_Id;
4313 -- ???
4315 Decls : constant List_Id := New_List;
4316 -- All the parameters will get declared before calling the real
4317 -- subprograms. Also the out parameters will be declared.
4319 Statements : constant List_Id := New_List;
4321 Extra_Formal_Statements : constant List_Id := New_List;
4322 -- Statements concerning extra formal parameters
4324 After_Statements : constant List_Id := New_List;
4325 -- Statements to be executed after the subprogram call
4327 Inner_Decls : List_Id := No_List;
4328 -- In case of a function, the inner declarations are needed since
4329 -- the result may be unconstrained.
4331 Excep_Handlers : List_Id := No_List;
4332 Excep_Choice : Entity_Id;
4333 Excep_Code : List_Id;
4335 Parameter_List : constant List_Id := New_List;
4336 -- List of parameters to be passed to the subprogram
4338 Current_Parameter : Node_Id;
4340 Ordered_Parameters_List : constant List_Id :=
4341 Build_Ordered_Parameters_List
4342 (Specification (Vis_Decl));
4344 Subp_Spec : Node_Id;
4345 -- Subprogram specification
4347 Called_Subprogram : Node_Id;
4348 -- The subprogram to call
4350 Null_Raise_Statement : Node_Id;
4352 Dynamic_Async : Entity_Id;
4354 begin
4355 if Present (RACW_Type) then
4356 Called_Subprogram :=
4357 New_Occurrence_Of (Parent_Primitive, Loc);
4358 else
4359 Called_Subprogram :=
4360 New_Occurrence_Of (
4361 Defining_Unit_Name (Specification (Vis_Decl)), Loc);
4362 end if;
4364 Request_Parameter :=
4365 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
4367 if Dynamically_Asynchronous then
4368 Dynamic_Async :=
4369 Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
4370 else
4371 Dynamic_Async := Empty;
4372 end if;
4374 if not Asynchronous or Dynamically_Asynchronous then
4376 -- The first statement after the subprogram call is a statement to
4377 -- writes a Null_Occurrence into the result stream.
4379 Null_Raise_Statement :=
4380 Make_Attribute_Reference (Loc,
4381 Prefix =>
4382 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
4383 Attribute_Name => Name_Write,
4384 Expressions => New_List (
4385 Make_Selected_Component (Loc,
4386 Prefix => Request_Parameter,
4387 Selector_Name => Name_Result),
4388 New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
4390 if Dynamically_Asynchronous then
4391 Null_Raise_Statement :=
4392 Make_Implicit_If_Statement (Vis_Decl,
4393 Condition =>
4394 Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
4395 Then_Statements => New_List (Null_Raise_Statement));
4396 end if;
4398 Append_To (After_Statements, Null_Raise_Statement);
4399 end if;
4401 -- Loop through every parameter and get its value from the stream. If
4402 -- the parameter is unconstrained, then the parameter is read using
4403 -- 'Input at the point of declaration.
4405 Current_Parameter := First (Ordered_Parameters_List);
4406 while Present (Current_Parameter) loop
4407 declare
4408 Etyp : Entity_Id;
4409 Constrained : Boolean;
4411 Object : constant Entity_Id :=
4412 Make_Defining_Identifier (Loc,
4413 New_Internal_Name ('P'));
4415 Expr : Node_Id := Empty;
4417 Is_Controlling_Formal : constant Boolean :=
4418 Is_RACW_Controlling_Formal
4419 (Current_Parameter, Stub_Type);
4421 begin
4422 Set_Ekind (Object, E_Variable);
4424 if Is_Controlling_Formal then
4426 -- We have a controlling formal parameter. Read its address
4427 -- rather than a real object. The address is in Unsigned_64
4428 -- form.
4430 Etyp := RTE (RE_Unsigned_64);
4431 else
4432 Etyp := Etype (Parameter_Type (Current_Parameter));
4433 end if;
4435 Constrained :=
4436 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
4438 if In_Present (Current_Parameter)
4439 or else not Out_Present (Current_Parameter)
4440 or else not Constrained
4441 or else Is_Controlling_Formal
4442 then
4443 -- If an input parameter is contrained, then its reading is
4444 -- deferred until the beginning of the subprogram body. If
4445 -- it is unconstrained, then an expression is built for
4446 -- the object declaration and the variable is set using
4447 -- 'Input instead of 'Read.
4449 if Constrained and then not Is_Controlling_Formal then
4450 Append_To (Statements,
4451 Make_Attribute_Reference (Loc,
4452 Prefix => New_Occurrence_Of (Etyp, Loc),
4453 Attribute_Name => Name_Read,
4454 Expressions => New_List (
4455 Make_Selected_Component (Loc,
4456 Prefix => Request_Parameter,
4457 Selector_Name => Name_Params),
4458 New_Occurrence_Of (Object, Loc))));
4460 else
4461 Expr := Input_With_Tag_Check (Loc,
4462 Var_Type => Etyp,
4463 Stream => Make_Selected_Component (Loc,
4464 Prefix => Request_Parameter,
4465 Selector_Name => Name_Params));
4466 Append_To (Decls, Expr);
4467 Expr := Make_Function_Call (Loc,
4468 New_Occurrence_Of (Defining_Unit_Name
4469 (Specification (Expr)), Loc));
4470 end if;
4471 end if;
4473 -- If we do not have to output the current parameter, then it
4474 -- can well be flagged as constant. This may allow further
4475 -- optimizations done by the back end.
4477 Append_To (Decls,
4478 Make_Object_Declaration (Loc,
4479 Defining_Identifier => Object,
4480 Constant_Present => not Constrained
4481 and then not Out_Present (Current_Parameter),
4482 Object_Definition =>
4483 New_Occurrence_Of (Etyp, Loc),
4484 Expression => Expr));
4486 -- An out parameter may be written back using a 'Write
4487 -- attribute instead of a 'Output because it has been
4488 -- constrained by the parameter given to the caller. Note that
4489 -- out controlling arguments in the case of a RACW are not put
4490 -- back in the stream because the pointer on them has not
4491 -- changed.
4493 if Out_Present (Current_Parameter)
4494 and then
4495 Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
4496 then
4497 Append_To (After_Statements,
4498 Make_Attribute_Reference (Loc,
4499 Prefix => New_Occurrence_Of (Etyp, Loc),
4500 Attribute_Name => Name_Write,
4501 Expressions => New_List (
4502 Make_Selected_Component (Loc,
4503 Prefix => Request_Parameter,
4504 Selector_Name => Name_Result),
4505 New_Occurrence_Of (Object, Loc))));
4506 end if;
4508 -- For RACW controlling formals, the Etyp of Object is always
4509 -- an RACW, even if the parameter is not of an anonymous access
4510 -- type. In such case, we need to dereference it at call time.
4512 if Is_Controlling_Formal then
4513 if Nkind (Parameter_Type (Current_Parameter)) /=
4514 N_Access_Definition
4515 then
4516 Append_To (Parameter_List,
4517 Make_Parameter_Association (Loc,
4518 Selector_Name =>
4519 New_Occurrence_Of (
4520 Defining_Identifier (Current_Parameter), Loc),
4521 Explicit_Actual_Parameter =>
4522 Make_Explicit_Dereference (Loc,
4523 Unchecked_Convert_To (RACW_Type,
4524 OK_Convert_To (RTE (RE_Address),
4525 New_Occurrence_Of (Object, Loc))))));
4527 else
4528 Append_To (Parameter_List,
4529 Make_Parameter_Association (Loc,
4530 Selector_Name =>
4531 New_Occurrence_Of (
4532 Defining_Identifier (Current_Parameter), Loc),
4533 Explicit_Actual_Parameter =>
4534 Unchecked_Convert_To (RACW_Type,
4535 OK_Convert_To (RTE (RE_Address),
4536 New_Occurrence_Of (Object, Loc)))));
4537 end if;
4539 else
4540 Append_To (Parameter_List,
4541 Make_Parameter_Association (Loc,
4542 Selector_Name =>
4543 New_Occurrence_Of (
4544 Defining_Identifier (Current_Parameter), Loc),
4545 Explicit_Actual_Parameter =>
4546 New_Occurrence_Of (Object, Loc)));
4547 end if;
4549 -- If the current parameter needs an extra formal, then read it
4550 -- from the stream and set the corresponding semantic field in
4551 -- the variable. If the kind of the parameter identifier is
4552 -- E_Void, then this is a compiler generated parameter that
4553 -- doesn't need an extra constrained status.
4555 -- The case of Extra_Accessibility should also be handled ???
4557 if Nkind (Parameter_Type (Current_Parameter)) /=
4558 N_Access_Definition
4559 and then
4560 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
4561 and then
4562 Present (Extra_Constrained
4563 (Defining_Identifier (Current_Parameter)))
4564 then
4565 declare
4566 Extra_Parameter : constant Entity_Id :=
4567 Extra_Constrained
4568 (Defining_Identifier
4569 (Current_Parameter));
4571 Formal_Entity : constant Entity_Id :=
4572 Make_Defining_Identifier
4573 (Loc, Chars (Extra_Parameter));
4575 Formal_Type : constant Entity_Id :=
4576 Etype (Extra_Parameter);
4578 begin
4579 Append_To (Decls,
4580 Make_Object_Declaration (Loc,
4581 Defining_Identifier => Formal_Entity,
4582 Object_Definition =>
4583 New_Occurrence_Of (Formal_Type, Loc)));
4585 Append_To (Extra_Formal_Statements,
4586 Make_Attribute_Reference (Loc,
4587 Prefix => New_Occurrence_Of (
4588 Formal_Type, Loc),
4589 Attribute_Name => Name_Read,
4590 Expressions => New_List (
4591 Make_Selected_Component (Loc,
4592 Prefix => Request_Parameter,
4593 Selector_Name => Name_Params),
4594 New_Occurrence_Of (Formal_Entity, Loc))));
4595 Set_Extra_Constrained (Object, Formal_Entity);
4596 end;
4597 end if;
4598 end;
4600 Next (Current_Parameter);
4601 end loop;
4603 -- Append the formal statements list at the end of regular statements
4605 Append_List_To (Statements, Extra_Formal_Statements);
4607 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
4609 -- The remote subprogram is a function. We build an inner block to
4610 -- be able to hold a potentially unconstrained result in a
4611 -- variable.
4613 declare
4614 Etyp : constant Entity_Id :=
4615 Etype (Result_Definition (Specification (Vis_Decl)));
4616 Result : constant Node_Id :=
4617 Make_Defining_Identifier (Loc,
4618 New_Internal_Name ('R'));
4619 begin
4620 Inner_Decls := New_List (
4621 Make_Object_Declaration (Loc,
4622 Defining_Identifier => Result,
4623 Constant_Present => True,
4624 Object_Definition => New_Occurrence_Of (Etyp, Loc),
4625 Expression =>
4626 Make_Function_Call (Loc,
4627 Name => Called_Subprogram,
4628 Parameter_Associations => Parameter_List)));
4630 Append_To (After_Statements,
4631 Make_Attribute_Reference (Loc,
4632 Prefix => New_Occurrence_Of (Etyp, Loc),
4633 Attribute_Name => Name_Output,
4634 Expressions => New_List (
4635 Make_Selected_Component (Loc,
4636 Prefix => Request_Parameter,
4637 Selector_Name => Name_Result),
4638 New_Occurrence_Of (Result, Loc))));
4639 end;
4641 Append_To (Statements,
4642 Make_Block_Statement (Loc,
4643 Declarations => Inner_Decls,
4644 Handled_Statement_Sequence =>
4645 Make_Handled_Sequence_Of_Statements (Loc,
4646 Statements => After_Statements)));
4648 else
4649 -- The remote subprogram is a procedure. We do not need any inner
4650 -- block in this case.
4652 if Dynamically_Asynchronous then
4653 Append_To (Decls,
4654 Make_Object_Declaration (Loc,
4655 Defining_Identifier => Dynamic_Async,
4656 Object_Definition =>
4657 New_Occurrence_Of (Standard_Boolean, Loc)));
4659 Append_To (Statements,
4660 Make_Attribute_Reference (Loc,
4661 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
4662 Attribute_Name => Name_Read,
4663 Expressions => New_List (
4664 Make_Selected_Component (Loc,
4665 Prefix => Request_Parameter,
4666 Selector_Name => Name_Params),
4667 New_Occurrence_Of (Dynamic_Async, Loc))));
4668 end if;
4670 Append_To (Statements,
4671 Make_Procedure_Call_Statement (Loc,
4672 Name => Called_Subprogram,
4673 Parameter_Associations => Parameter_List));
4675 Append_List_To (Statements, After_Statements);
4676 end if;
4678 if Asynchronous and then not Dynamically_Asynchronous then
4680 -- For an asynchronous procedure, add a null exception handler
4682 Excep_Handlers := New_List (
4683 Make_Exception_Handler (Loc,
4684 Exception_Choices => New_List (Make_Others_Choice (Loc)),
4685 Statements => New_List (Make_Null_Statement (Loc))));
4687 else
4688 -- In the other cases, if an exception is raised, then the
4689 -- exception occurrence is copied into the output stream and
4690 -- no other output parameter is written.
4692 Excep_Choice :=
4693 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
4695 Excep_Code := New_List (
4696 Make_Attribute_Reference (Loc,
4697 Prefix =>
4698 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
4699 Attribute_Name => Name_Write,
4700 Expressions => New_List (
4701 Make_Selected_Component (Loc,
4702 Prefix => Request_Parameter,
4703 Selector_Name => Name_Result),
4704 New_Occurrence_Of (Excep_Choice, Loc))));
4706 if Dynamically_Asynchronous then
4707 Excep_Code := New_List (
4708 Make_Implicit_If_Statement (Vis_Decl,
4709 Condition => Make_Op_Not (Loc,
4710 New_Occurrence_Of (Dynamic_Async, Loc)),
4711 Then_Statements => Excep_Code));
4712 end if;
4714 Excep_Handlers := New_List (
4715 Make_Exception_Handler (Loc,
4716 Choice_Parameter => Excep_Choice,
4717 Exception_Choices => New_List (Make_Others_Choice (Loc)),
4718 Statements => Excep_Code));
4720 end if;
4722 Subp_Spec :=
4723 Make_Procedure_Specification (Loc,
4724 Defining_Unit_Name =>
4725 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
4727 Parameter_Specifications => New_List (
4728 Make_Parameter_Specification (Loc,
4729 Defining_Identifier => Request_Parameter,
4730 Parameter_Type =>
4731 New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
4733 return
4734 Make_Subprogram_Body (Loc,
4735 Specification => Subp_Spec,
4736 Declarations => Decls,
4737 Handled_Statement_Sequence =>
4738 Make_Handled_Sequence_Of_Statements (Loc,
4739 Statements => Statements,
4740 Exception_Handlers => Excep_Handlers));
4741 end Build_Subprogram_Receiving_Stubs;
4743 ------------
4744 -- Result --
4745 ------------
4747 function Result return Node_Id is
4748 begin
4749 return Make_Identifier (Loc, Name_V);
4750 end Result;
4752 ----------------------
4753 -- Stream_Parameter --
4754 ----------------------
4756 function Stream_Parameter return Node_Id is
4757 begin
4758 return Make_Identifier (Loc, Name_S);
4759 end Stream_Parameter;
4761 end GARLIC_Support;
4763 -----------------------------
4764 -- Make_Selected_Component --
4765 -----------------------------
4767 function Make_Selected_Component
4768 (Loc : Source_Ptr;
4769 Prefix : Entity_Id;
4770 Selector_Name : Name_Id) return Node_Id
4772 begin
4773 return Make_Selected_Component (Loc,
4774 Prefix => New_Occurrence_Of (Prefix, Loc),
4775 Selector_Name => Make_Identifier (Loc, Selector_Name));
4776 end Make_Selected_Component;
4778 -----------------------
4779 -- Get_Subprogram_Id --
4780 -----------------------
4782 function Get_Subprogram_Id (Def : Entity_Id) return String_Id is
4783 begin
4784 return Get_Subprogram_Ids (Def).Str_Identifier;
4785 end Get_Subprogram_Id;
4787 -----------------------
4788 -- Get_Subprogram_Id --
4789 -----------------------
4791 function Get_Subprogram_Id (Def : Entity_Id) return Int is
4792 begin
4793 return Get_Subprogram_Ids (Def).Int_Identifier;
4794 end Get_Subprogram_Id;
4796 ------------------------
4797 -- Get_Subprogram_Ids --
4798 ------------------------
4800 function Get_Subprogram_Ids
4801 (Def : Entity_Id) return Subprogram_Identifiers
4803 Result : Subprogram_Identifiers :=
4804 Subprogram_Identifier_Table.Get (Def);
4806 Current_Declaration : Node_Id;
4807 Current_Subp : Entity_Id;
4808 Current_Subp_Str : String_Id;
4809 Current_Subp_Number : Int := First_RCI_Subprogram_Id;
4811 begin
4812 if Result.Str_Identifier = No_String then
4814 -- We are looking up this subprogram's identifier outside of the
4815 -- context of generating calling or receiving stubs. Hence we are
4816 -- processing an 'Access attribute_reference for an RCI subprogram,
4817 -- for the purpose of obtaining a RAS value.
4819 pragma Assert
4820 (Is_Remote_Call_Interface (Scope (Def))
4821 and then
4822 (Nkind (Parent (Def)) = N_Procedure_Specification
4823 or else
4824 Nkind (Parent (Def)) = N_Function_Specification));
4826 Current_Declaration :=
4827 First (Visible_Declarations
4828 (Package_Specification_Of_Scope (Scope (Def))));
4829 while Present (Current_Declaration) loop
4830 if Nkind (Current_Declaration) = N_Subprogram_Declaration
4831 and then Comes_From_Source (Current_Declaration)
4832 then
4833 Current_Subp := Defining_Unit_Name (Specification (
4834 Current_Declaration));
4835 Assign_Subprogram_Identifier
4836 (Current_Subp, Current_Subp_Number, Current_Subp_Str);
4838 if Current_Subp = Def then
4839 Result := (Current_Subp_Str, Current_Subp_Number);
4840 end if;
4842 Current_Subp_Number := Current_Subp_Number + 1;
4843 end if;
4845 Next (Current_Declaration);
4846 end loop;
4847 end if;
4849 pragma Assert (Result.Str_Identifier /= No_String);
4850 return Result;
4851 end Get_Subprogram_Ids;
4853 ----------
4854 -- Hash --
4855 ----------
4857 function Hash (F : Entity_Id) return Hash_Index is
4858 begin
4859 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
4860 end Hash;
4862 function Hash (F : Name_Id) return Hash_Index is
4863 begin
4864 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
4865 end Hash;
4867 --------------------------
4868 -- Input_With_Tag_Check --
4869 --------------------------
4871 function Input_With_Tag_Check
4872 (Loc : Source_Ptr;
4873 Var_Type : Entity_Id;
4874 Stream : Node_Id) return Node_Id
4876 begin
4877 return
4878 Make_Subprogram_Body (Loc,
4879 Specification => Make_Function_Specification (Loc,
4880 Defining_Unit_Name =>
4881 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
4882 Result_Definition => New_Occurrence_Of (Var_Type, Loc)),
4883 Declarations => No_List,
4884 Handled_Statement_Sequence =>
4885 Make_Handled_Sequence_Of_Statements (Loc, New_List (
4886 Make_Tag_Check (Loc,
4887 Make_Return_Statement (Loc,
4888 Make_Attribute_Reference (Loc,
4889 Prefix => New_Occurrence_Of (Var_Type, Loc),
4890 Attribute_Name => Name_Input,
4891 Expressions =>
4892 New_List (Stream)))))));
4893 end Input_With_Tag_Check;
4895 --------------------------------
4896 -- Is_RACW_Controlling_Formal --
4897 --------------------------------
4899 function Is_RACW_Controlling_Formal
4900 (Parameter : Node_Id;
4901 Stub_Type : Entity_Id) return Boolean
4903 Typ : Entity_Id;
4905 begin
4906 -- If the kind of the parameter is E_Void, then it is not a
4907 -- controlling formal (this can happen in the context of RAS).
4909 if Ekind (Defining_Identifier (Parameter)) = E_Void then
4910 return False;
4911 end if;
4913 -- If the parameter is not a controlling formal, then it cannot
4914 -- be possibly a RACW_Controlling_Formal.
4916 if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
4917 return False;
4918 end if;
4920 Typ := Parameter_Type (Parameter);
4921 return (Nkind (Typ) = N_Access_Definition
4922 and then Etype (Subtype_Mark (Typ)) = Stub_Type)
4923 or else Etype (Typ) = Stub_Type;
4924 end Is_RACW_Controlling_Formal;
4926 --------------------
4927 -- Make_Tag_Check --
4928 --------------------
4930 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
4931 Occ : constant Entity_Id :=
4932 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
4934 begin
4935 return Make_Block_Statement (Loc,
4936 Handled_Statement_Sequence =>
4937 Make_Handled_Sequence_Of_Statements (Loc,
4938 Statements => New_List (N),
4940 Exception_Handlers => New_List (
4941 Make_Exception_Handler (Loc,
4942 Choice_Parameter => Occ,
4944 Exception_Choices =>
4945 New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
4947 Statements =>
4948 New_List (Make_Procedure_Call_Statement (Loc,
4949 New_Occurrence_Of
4950 (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
4951 New_List (New_Occurrence_Of (Occ, Loc))))))));
4952 end Make_Tag_Check;
4954 ----------------------------
4955 -- Need_Extra_Constrained --
4956 ----------------------------
4958 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
4959 Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
4960 begin
4961 return Out_Present (Parameter)
4962 and then Has_Discriminants (Etyp)
4963 and then not Is_Constrained (Etyp)
4964 and then not Is_Indefinite_Subtype (Etyp);
4965 end Need_Extra_Constrained;
4967 ------------------------------------
4968 -- Pack_Entity_Into_Stream_Access --
4969 ------------------------------------
4971 function Pack_Entity_Into_Stream_Access
4972 (Loc : Source_Ptr;
4973 Stream : Node_Id;
4974 Object : Entity_Id;
4975 Etyp : Entity_Id := Empty) return Node_Id
4977 Typ : Entity_Id;
4979 begin
4980 if Present (Etyp) then
4981 Typ := Etyp;
4982 else
4983 Typ := Etype (Object);
4984 end if;
4986 return
4987 Pack_Node_Into_Stream_Access (Loc,
4988 Stream => Stream,
4989 Object => New_Occurrence_Of (Object, Loc),
4990 Etyp => Typ);
4991 end Pack_Entity_Into_Stream_Access;
4993 ---------------------------
4994 -- Pack_Node_Into_Stream --
4995 ---------------------------
4997 function Pack_Node_Into_Stream
4998 (Loc : Source_Ptr;
4999 Stream : Entity_Id;
5000 Object : Node_Id;
5001 Etyp : Entity_Id) return Node_Id
5003 Write_Attribute : Name_Id := Name_Write;
5005 begin
5006 if not Is_Constrained (Etyp) then
5007 Write_Attribute := Name_Output;
5008 end if;
5010 return
5011 Make_Attribute_Reference (Loc,
5012 Prefix => New_Occurrence_Of (Etyp, Loc),
5013 Attribute_Name => Write_Attribute,
5014 Expressions => New_List (
5015 Make_Attribute_Reference (Loc,
5016 Prefix => New_Occurrence_Of (Stream, Loc),
5017 Attribute_Name => Name_Access),
5018 Object));
5019 end Pack_Node_Into_Stream;
5021 ----------------------------------
5022 -- Pack_Node_Into_Stream_Access --
5023 ----------------------------------
5025 function Pack_Node_Into_Stream_Access
5026 (Loc : Source_Ptr;
5027 Stream : Node_Id;
5028 Object : Node_Id;
5029 Etyp : Entity_Id) return Node_Id
5031 Write_Attribute : Name_Id := Name_Write;
5033 begin
5034 if not Is_Constrained (Etyp) then
5035 Write_Attribute := Name_Output;
5036 end if;
5038 return
5039 Make_Attribute_Reference (Loc,
5040 Prefix => New_Occurrence_Of (Etyp, Loc),
5041 Attribute_Name => Write_Attribute,
5042 Expressions => New_List (
5043 Stream,
5044 Object));
5045 end Pack_Node_Into_Stream_Access;
5047 ---------------------
5048 -- PolyORB_Support --
5049 ---------------------
5051 package body PolyORB_Support is
5053 -- Local subprograms
5055 procedure Add_RACW_Read_Attribute
5056 (RACW_Type : Entity_Id;
5057 Stub_Type : Entity_Id;
5058 Stub_Type_Access : Entity_Id;
5059 Declarations : List_Id);
5060 -- Add Read attribute in Decls for the RACW type. The Read attribute
5061 -- is added right after the RACW_Type declaration while the body is
5062 -- inserted after Declarations.
5064 procedure Add_RACW_Write_Attribute
5065 (RACW_Type : Entity_Id;
5066 Stub_Type : Entity_Id;
5067 Stub_Type_Access : Entity_Id;
5068 Declarations : List_Id);
5069 -- Same thing for the Write attribute
5071 procedure Add_RACW_From_Any
5072 (RACW_Type : Entity_Id;
5073 Stub_Type : Entity_Id;
5074 Stub_Type_Access : Entity_Id;
5075 Declarations : List_Id);
5076 -- Add the From_Any TSS for this RACW type
5078 procedure Add_RACW_To_Any
5079 (Designated_Type : Entity_Id;
5080 RACW_Type : Entity_Id;
5081 Stub_Type : Entity_Id;
5082 Stub_Type_Access : Entity_Id;
5083 Declarations : List_Id);
5084 -- Add the To_Any TSS for this RACW type
5086 procedure Add_RACW_TypeCode
5087 (Designated_Type : Entity_Id;
5088 RACW_Type : Entity_Id;
5089 Declarations : List_Id);
5090 -- Add the TypeCode TSS for this RACW type
5092 procedure Add_RAS_From_Any (RAS_Type : Entity_Id);
5093 -- Add the From_Any TSS for this RAS type
5095 procedure Add_RAS_To_Any (RAS_Type : Entity_Id);
5096 -- Add the To_Any TSS for this RAS type
5098 procedure Add_RAS_TypeCode (RAS_Type : Entity_Id);
5099 -- Add the TypeCode TSS for this RAS type
5101 procedure Add_RAS_Access_TSS (N : Node_Id);
5102 -- Add a subprogram body for RAS Access TSS
5104 -------------------------------------
5105 -- Add_Obj_RPC_Receiver_Completion --
5106 -------------------------------------
5108 procedure Add_Obj_RPC_Receiver_Completion
5109 (Loc : Source_Ptr;
5110 Decls : List_Id;
5111 RPC_Receiver : Entity_Id;
5112 Stub_Elements : Stub_Structure)
5114 Desig : constant Entity_Id :=
5115 Etype (Designated_Type (Stub_Elements.RACW_Type));
5116 begin
5117 Append_To (Decls,
5118 Make_Procedure_Call_Statement (Loc,
5119 Name =>
5120 New_Occurrence_Of (
5121 RTE (RE_Register_Obj_Receiving_Stub), Loc),
5123 Parameter_Associations => New_List (
5125 -- Name
5127 Make_String_Literal (Loc,
5128 Full_Qualified_Name (Desig)),
5130 -- Handler
5132 Make_Attribute_Reference (Loc,
5133 Prefix =>
5134 New_Occurrence_Of (
5135 Defining_Unit_Name (Parent (RPC_Receiver)), Loc),
5136 Attribute_Name =>
5137 Name_Access),
5139 -- Receiver
5141 Make_Attribute_Reference (Loc,
5142 Prefix =>
5143 New_Occurrence_Of (
5144 Defining_Identifier (
5145 Stub_Elements.RPC_Receiver_Decl), Loc),
5146 Attribute_Name =>
5147 Name_Access))));
5148 end Add_Obj_RPC_Receiver_Completion;
5150 -----------------------
5151 -- Add_RACW_Features --
5152 -----------------------
5154 procedure Add_RACW_Features
5155 (RACW_Type : Entity_Id;
5156 Desig : Entity_Id;
5157 Stub_Type : Entity_Id;
5158 Stub_Type_Access : Entity_Id;
5159 RPC_Receiver_Decl : Node_Id;
5160 Declarations : List_Id)
5162 pragma Warnings (Off);
5163 pragma Unreferenced (RPC_Receiver_Decl);
5164 pragma Warnings (On);
5166 begin
5167 Add_RACW_From_Any
5168 (RACW_Type => RACW_Type,
5169 Stub_Type => Stub_Type,
5170 Stub_Type_Access => Stub_Type_Access,
5171 Declarations => Declarations);
5173 Add_RACW_To_Any
5174 (Designated_Type => Desig,
5175 RACW_Type => RACW_Type,
5176 Stub_Type => Stub_Type,
5177 Stub_Type_Access => Stub_Type_Access,
5178 Declarations => Declarations);
5180 -- In the PolyORB case, the RACW 'Read and 'Write attributes
5181 -- are implemented in terms of the From_Any and To_Any TSSs,
5182 -- so these TSSs must be expanded before 'Read and 'Write.
5184 Add_RACW_Write_Attribute
5185 (RACW_Type => RACW_Type,
5186 Stub_Type => Stub_Type,
5187 Stub_Type_Access => Stub_Type_Access,
5188 Declarations => Declarations);
5190 Add_RACW_Read_Attribute
5191 (RACW_Type => RACW_Type,
5192 Stub_Type => Stub_Type,
5193 Stub_Type_Access => Stub_Type_Access,
5194 Declarations => Declarations);
5196 Add_RACW_TypeCode
5197 (Designated_Type => Desig,
5198 RACW_Type => RACW_Type,
5199 Declarations => Declarations);
5200 end Add_RACW_Features;
5202 -----------------------
5203 -- Add_RACW_From_Any --
5204 -----------------------
5206 procedure Add_RACW_From_Any
5207 (RACW_Type : Entity_Id;
5208 Stub_Type : Entity_Id;
5209 Stub_Type_Access : Entity_Id;
5210 Declarations : List_Id)
5212 Loc : constant Source_Ptr := Sloc (RACW_Type);
5213 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5215 Fnam : constant Entity_Id :=
5216 Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
5218 Func_Spec : Node_Id;
5219 Func_Decl : Node_Id;
5220 Func_Body : Node_Id;
5222 Decls : List_Id;
5223 Statements : List_Id;
5224 Stub_Statements : List_Id;
5225 Local_Statements : List_Id;
5226 -- Various parts of the subprogram
5228 Any_Parameter : constant Entity_Id :=
5229 Make_Defining_Identifier (Loc, Name_A);
5230 Reference : constant Entity_Id :=
5231 Make_Defining_Identifier
5232 (Loc, New_Internal_Name ('R'));
5233 Is_Local : constant Entity_Id :=
5234 Make_Defining_Identifier
5235 (Loc, New_Internal_Name ('L'));
5236 Addr : constant Entity_Id :=
5237 Make_Defining_Identifier
5238 (Loc, New_Internal_Name ('A'));
5239 Local_Stub : constant Entity_Id :=
5240 Make_Defining_Identifier
5241 (Loc, New_Internal_Name ('L'));
5242 Stubbed_Result : constant Entity_Id :=
5243 Make_Defining_Identifier
5244 (Loc, New_Internal_Name ('S'));
5246 Stub_Condition : Node_Id;
5247 -- An expression that determines whether we create a stub for the
5248 -- newly-unpacked RACW. Normally we create a stub only for remote
5249 -- objects, but in the case of an RACW used to implement a RAS,
5250 -- we also create a stub for local subprograms if a pragma
5251 -- All_Calls_Remote applies.
5253 Asynchronous_Flag : constant Entity_Id :=
5254 Asynchronous_Flags_Table.Get (RACW_Type);
5255 -- The flag object declared in Add_RACW_Asynchronous_Flag
5257 begin
5258 -- Object declarations
5260 Decls := New_List (
5261 Make_Object_Declaration (Loc,
5262 Defining_Identifier =>
5263 Reference,
5264 Object_Definition =>
5265 New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
5266 Expression =>
5267 Make_Function_Call (Loc,
5268 Name =>
5269 New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
5270 Parameter_Associations => New_List (
5271 New_Occurrence_Of (Any_Parameter, Loc)))),
5273 Make_Object_Declaration (Loc,
5274 Defining_Identifier => Local_Stub,
5275 Aliased_Present => True,
5276 Object_Definition => New_Occurrence_Of (Stub_Type, Loc)),
5278 Make_Object_Declaration (Loc,
5279 Defining_Identifier => Stubbed_Result,
5280 Object_Definition =>
5281 New_Occurrence_Of (Stub_Type_Access, Loc),
5282 Expression =>
5283 Make_Attribute_Reference (Loc,
5284 Prefix =>
5285 New_Occurrence_Of (Local_Stub, Loc),
5286 Attribute_Name =>
5287 Name_Unchecked_Access)),
5289 Make_Object_Declaration (Loc,
5290 Defining_Identifier => Is_Local,
5291 Object_Definition =>
5292 New_Occurrence_Of (Standard_Boolean, Loc)),
5294 Make_Object_Declaration (Loc,
5295 Defining_Identifier => Addr,
5296 Object_Definition =>
5297 New_Occurrence_Of (RTE (RE_Address), Loc)));
5299 -- Build_Get_Unique_RP_Call needs the type of Stubbed_Result
5301 Set_Etype (Stubbed_Result, Stub_Type_Access);
5303 -- If the ref Is_Nil, return a null pointer
5305 Statements := New_List (
5306 Make_Implicit_If_Statement (RACW_Type,
5307 Condition =>
5308 Make_Function_Call (Loc,
5309 Name =>
5310 New_Occurrence_Of (RTE (RE_Is_Nil), Loc),
5311 Parameter_Associations => New_List (
5312 New_Occurrence_Of (Reference, Loc))),
5313 Then_Statements => New_List (
5314 Make_Return_Statement (Loc,
5315 Expression =>
5316 Make_Null (Loc)))));
5318 Append_To (Statements,
5319 Make_Procedure_Call_Statement (Loc,
5320 Name =>
5321 New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
5322 Parameter_Associations => New_List (
5323 New_Occurrence_Of (Reference, Loc),
5324 New_Occurrence_Of (Is_Local, Loc),
5325 New_Occurrence_Of (Addr, Loc))));
5327 -- If the object is located on another partition, then a stub object
5328 -- will be created with all the information needed to rebuild the
5329 -- real object at the other end. This stanza is always used in the
5330 -- case of RAS types, for which a stub is required even for local
5331 -- subprograms.
5333 Stub_Statements := New_List (
5334 Make_Assignment_Statement (Loc,
5335 Name => Make_Selected_Component (Loc,
5336 Prefix => Stubbed_Result,
5337 Selector_Name => Name_Target),
5338 Expression =>
5339 Make_Function_Call (Loc,
5340 Name =>
5341 New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
5342 Parameter_Associations => New_List (
5343 New_Occurrence_Of (Reference, Loc)))),
5345 Make_Procedure_Call_Statement (Loc,
5346 Name =>
5347 New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
5348 Parameter_Associations => New_List (
5349 Make_Selected_Component (Loc,
5350 Prefix => Stubbed_Result,
5351 Selector_Name => Name_Target))),
5353 Make_Assignment_Statement (Loc,
5354 Name => Make_Selected_Component (Loc,
5355 Prefix => Stubbed_Result,
5356 Selector_Name => Name_Asynchronous),
5357 Expression =>
5358 New_Occurrence_Of (Asynchronous_Flag, Loc)));
5360 -- ??? Issue with asynchronous calls here: the Asynchronous
5361 -- flag is set on the stub type if, and only if, the RACW type
5362 -- has a pragma Asynchronous. This is incorrect for RACWs that
5363 -- implement RAS types, because in that case the /designated
5364 -- subprogram/ (not the type) might be asynchronous, and
5365 -- that causes the stub to need to be asynchronous too.
5366 -- A solution is to transport a RAS as a struct containing
5367 -- a RACW and an asynchronous flag, and to properly alter
5368 -- the Asynchronous component in the stub type in the RAS's
5369 -- _From_Any TSS.
5371 Append_List_To (Stub_Statements,
5372 Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
5374 -- Distinguish between the local and remote cases, and execute the
5375 -- appropriate piece of code.
5377 Stub_Condition := New_Occurrence_Of (Is_Local, Loc);
5379 if Is_RAS then
5380 Stub_Condition := Make_And_Then (Loc,
5381 Left_Opnd =>
5382 Stub_Condition,
5383 Right_Opnd =>
5384 Make_Selected_Component (Loc,
5385 Prefix =>
5386 Unchecked_Convert_To (
5387 RTE (RE_RAS_Proxy_Type_Access),
5388 New_Occurrence_Of (Addr, Loc)),
5389 Selector_Name =>
5390 Make_Identifier (Loc,
5391 Name_All_Calls_Remote)));
5392 end if;
5394 Local_Statements := New_List (
5395 Make_Return_Statement (Loc,
5396 Expression =>
5397 Unchecked_Convert_To (RACW_Type,
5398 New_Occurrence_Of (Addr, Loc))));
5400 Append_To (Statements,
5401 Make_Implicit_If_Statement (RACW_Type,
5402 Condition =>
5403 Stub_Condition,
5404 Then_Statements => Local_Statements,
5405 Else_Statements => Stub_Statements));
5407 Append_To (Statements,
5408 Make_Return_Statement (Loc,
5409 Expression => Unchecked_Convert_To (RACW_Type,
5410 New_Occurrence_Of (Stubbed_Result, Loc))));
5412 Func_Spec :=
5413 Make_Function_Specification (Loc,
5414 Defining_Unit_Name =>
5415 Fnam,
5416 Parameter_Specifications => New_List (
5417 Make_Parameter_Specification (Loc,
5418 Defining_Identifier =>
5419 Any_Parameter,
5420 Parameter_Type =>
5421 New_Occurrence_Of (RTE (RE_Any), Loc))),
5422 Result_Definition => New_Occurrence_Of (RACW_Type, Loc));
5424 -- NOTE: The usage occurrences of RACW_Parameter must
5425 -- refer to the entity in the declaration spec, not those
5426 -- of the body spec.
5428 Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
5430 Func_Body :=
5431 Make_Subprogram_Body (Loc,
5432 Specification =>
5433 Copy_Specification (Loc, Func_Spec),
5434 Declarations => Decls,
5435 Handled_Statement_Sequence =>
5436 Make_Handled_Sequence_Of_Statements (Loc,
5437 Statements => Statements));
5439 Insert_After (Declaration_Node (RACW_Type), Func_Decl);
5440 Append_To (Declarations, Func_Body);
5442 Set_Renaming_TSS (RACW_Type, Fnam, TSS_From_Any);
5443 end Add_RACW_From_Any;
5445 -----------------------------
5446 -- Add_RACW_Read_Attribute --
5447 -----------------------------
5449 procedure Add_RACW_Read_Attribute
5450 (RACW_Type : Entity_Id;
5451 Stub_Type : Entity_Id;
5452 Stub_Type_Access : Entity_Id;
5453 Declarations : List_Id)
5455 pragma Warnings (Off);
5456 pragma Unreferenced (Stub_Type, Stub_Type_Access);
5457 pragma Warnings (On);
5458 Loc : constant Source_Ptr := Sloc (RACW_Type);
5460 Proc_Decl : Node_Id;
5461 Attr_Decl : Node_Id;
5463 Body_Node : Node_Id;
5465 Decls : List_Id;
5466 Statements : List_Id;
5467 -- Various parts of the procedure
5469 Procedure_Name : constant Name_Id :=
5470 New_Internal_Name ('R');
5471 Source_Ref : constant Entity_Id :=
5472 Make_Defining_Identifier
5473 (Loc, New_Internal_Name ('R'));
5474 Asynchronous_Flag : constant Entity_Id :=
5475 Asynchronous_Flags_Table.Get (RACW_Type);
5476 pragma Assert (Present (Asynchronous_Flag));
5478 function Stream_Parameter return Node_Id;
5479 function Result return Node_Id;
5480 -- Functions to create occurrences of the formal parameter names
5482 ------------
5483 -- Result --
5484 ------------
5486 function Result return Node_Id is
5487 begin
5488 return Make_Identifier (Loc, Name_V);
5489 end Result;
5491 ----------------------
5492 -- Stream_Parameter --
5493 ----------------------
5495 function Stream_Parameter return Node_Id is
5496 begin
5497 return Make_Identifier (Loc, Name_S);
5498 end Stream_Parameter;
5500 -- Start of processing for Add_RACW_Read_Attribute
5502 begin
5503 -- Generate object declarations
5505 Decls := New_List (
5506 Make_Object_Declaration (Loc,
5507 Defining_Identifier => Source_Ref,
5508 Object_Definition =>
5509 New_Occurrence_Of (RTE (RE_Object_Ref), Loc)));
5511 Statements := New_List (
5512 Make_Attribute_Reference (Loc,
5513 Prefix =>
5514 New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
5515 Attribute_Name => Name_Read,
5516 Expressions => New_List (
5517 Stream_Parameter,
5518 New_Occurrence_Of (Source_Ref, Loc))),
5519 Make_Assignment_Statement (Loc,
5520 Name =>
5521 Result,
5522 Expression =>
5523 PolyORB_Support.Helpers.Build_From_Any_Call (
5524 RACW_Type,
5525 Make_Function_Call (Loc,
5526 Name =>
5527 New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc),
5528 Parameter_Associations => New_List (
5529 New_Occurrence_Of (Source_Ref, Loc))),
5530 Decls)));
5532 Build_Stream_Procedure
5533 (Loc, RACW_Type, Body_Node,
5534 Make_Defining_Identifier (Loc, Procedure_Name),
5535 Statements, Outp => True);
5536 Set_Declarations (Body_Node, Decls);
5538 Proc_Decl := Make_Subprogram_Declaration (Loc,
5539 Copy_Specification (Loc, Specification (Body_Node)));
5541 Attr_Decl :=
5542 Make_Attribute_Definition_Clause (Loc,
5543 Name => New_Occurrence_Of (RACW_Type, Loc),
5544 Chars => Name_Read,
5545 Expression =>
5546 New_Occurrence_Of (
5547 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
5549 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
5550 Insert_After (Proc_Decl, Attr_Decl);
5551 Append_To (Declarations, Body_Node);
5552 end Add_RACW_Read_Attribute;
5554 ---------------------
5555 -- Add_RACW_To_Any --
5556 ---------------------
5558 procedure Add_RACW_To_Any
5559 (Designated_Type : Entity_Id;
5560 RACW_Type : Entity_Id;
5561 Stub_Type : Entity_Id;
5562 Stub_Type_Access : Entity_Id;
5563 Declarations : List_Id)
5565 Loc : constant Source_Ptr := Sloc (RACW_Type);
5567 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5569 Fnam : Entity_Id;
5571 Stub_Elements : constant Stub_Structure :=
5572 Stubs_Table.Get (Designated_Type);
5573 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
5575 Func_Spec : Node_Id;
5576 Func_Decl : Node_Id;
5577 Func_Body : Node_Id;
5579 Decls : List_Id;
5580 Statements : List_Id;
5581 Null_Statements : List_Id;
5582 Local_Statements : List_Id := No_List;
5583 Stub_Statements : List_Id;
5584 If_Node : Node_Id;
5585 -- Various parts of the subprogram
5587 RACW_Parameter : constant Entity_Id
5588 := Make_Defining_Identifier (Loc, Name_R);
5590 Reference : constant Entity_Id :=
5591 Make_Defining_Identifier
5592 (Loc, New_Internal_Name ('R'));
5593 Any : constant Entity_Id :=
5594 Make_Defining_Identifier
5595 (Loc, New_Internal_Name ('A'));
5597 begin
5598 -- Object declarations
5600 Decls := New_List (
5601 Make_Object_Declaration (Loc,
5602 Defining_Identifier =>
5603 Reference,
5604 Object_Definition =>
5605 New_Occurrence_Of (RTE (RE_Object_Ref), Loc)),
5606 Make_Object_Declaration (Loc,
5607 Defining_Identifier =>
5608 Any,
5609 Object_Definition =>
5610 New_Occurrence_Of (RTE (RE_Any), Loc)));
5612 -- If the object is null, nothing to do (Reference is already
5613 -- a Nil ref.)
5615 Null_Statements := New_List (Make_Null_Statement (Loc));
5617 if Is_RAS then
5619 -- If the object is a RAS designating a local subprogram,
5620 -- we already have a target reference.
5622 Local_Statements := New_List (
5623 Make_Procedure_Call_Statement (Loc,
5624 Name =>
5625 New_Occurrence_Of (RTE (RE_Set_Ref), Loc),
5626 Parameter_Associations => New_List (
5627 New_Occurrence_Of (Reference, Loc),
5628 Make_Selected_Component (Loc,
5629 Prefix =>
5630 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
5631 New_Occurrence_Of (RACW_Parameter, Loc)),
5632 Selector_Name => Make_Identifier (Loc, Name_Target)))));
5634 else
5635 -- If the object is a local RACW object, use Get_Reference now
5636 -- to obtain a reference.
5638 Local_Statements := New_List (
5639 Make_Procedure_Call_Statement (Loc,
5640 Name =>
5641 New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
5642 Parameter_Associations => New_List (
5643 Unchecked_Convert_To (
5644 RTE (RE_Address),
5645 New_Occurrence_Of (RACW_Parameter, Loc)),
5646 Make_String_Literal (Loc,
5647 Full_Qualified_Name (Designated_Type)),
5648 Make_Attribute_Reference (Loc,
5649 Prefix =>
5650 New_Occurrence_Of (
5651 Defining_Identifier (
5652 Stub_Elements.RPC_Receiver_Decl), Loc),
5653 Attribute_Name =>
5654 Name_Access),
5655 New_Occurrence_Of (Reference, Loc))));
5656 end if;
5658 -- If the object is located on another partition, use the target
5659 -- from the stub.
5661 Stub_Statements := New_List (
5662 Make_Procedure_Call_Statement (Loc,
5663 Name =>
5664 New_Occurrence_Of (RTE (RE_Set_Ref), Loc),
5665 Parameter_Associations => New_List (
5666 New_Occurrence_Of (Reference, Loc),
5667 Make_Selected_Component (Loc,
5668 Prefix => Unchecked_Convert_To (Stub_Type_Access,
5669 New_Occurrence_Of (RACW_Parameter, Loc)),
5670 Selector_Name =>
5671 Make_Identifier (Loc, Name_Target)))));
5673 -- Distinguish between the null, local and remote cases,
5674 -- and execute the appropriate piece of code.
5676 If_Node :=
5677 Make_Implicit_If_Statement (RACW_Type,
5678 Condition =>
5679 Make_Op_Eq (Loc,
5680 Left_Opnd => New_Occurrence_Of (RACW_Parameter, Loc),
5681 Right_Opnd => Make_Null (Loc)),
5682 Then_Statements => Null_Statements,
5683 Elsif_Parts => New_List (
5684 Make_Elsif_Part (Loc,
5685 Condition =>
5686 Make_Op_Ne (Loc,
5687 Left_Opnd =>
5688 Make_Attribute_Reference (Loc,
5689 Prefix =>
5690 New_Occurrence_Of (RACW_Parameter, Loc),
5691 Attribute_Name => Name_Tag),
5692 Right_Opnd =>
5693 Make_Attribute_Reference (Loc,
5694 Prefix => New_Occurrence_Of (Stub_Type, Loc),
5695 Attribute_Name => Name_Tag)),
5696 Then_Statements => Local_Statements)),
5697 Else_Statements => Stub_Statements);
5699 Statements := New_List (
5700 If_Node,
5701 Make_Assignment_Statement (Loc,
5702 Name =>
5703 New_Occurrence_Of (Any, Loc),
5704 Expression =>
5705 Make_Function_Call (Loc,
5706 Name => New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc),
5707 Parameter_Associations => New_List (
5708 New_Occurrence_Of (Reference, Loc)))),
5709 Make_Procedure_Call_Statement (Loc,
5710 Name =>
5711 New_Occurrence_Of (RTE (RE_Set_TC), Loc),
5712 Parameter_Associations => New_List (
5713 New_Occurrence_Of (Any, Loc),
5714 Make_Selected_Component (Loc,
5715 Prefix =>
5716 Defining_Identifier (
5717 Stub_Elements.RPC_Receiver_Decl),
5718 Selector_Name => Name_Obj_TypeCode))),
5719 Make_Return_Statement (Loc,
5720 Expression =>
5721 New_Occurrence_Of (Any, Loc)));
5723 Fnam := Make_Defining_Identifier (
5724 Loc, New_Internal_Name ('T'));
5726 Func_Spec :=
5727 Make_Function_Specification (Loc,
5728 Defining_Unit_Name =>
5729 Fnam,
5730 Parameter_Specifications => New_List (
5731 Make_Parameter_Specification (Loc,
5732 Defining_Identifier =>
5733 RACW_Parameter,
5734 Parameter_Type =>
5735 New_Occurrence_Of (RACW_Type, Loc))),
5736 Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
5738 -- NOTE: The usage occurrences of RACW_Parameter must
5739 -- refer to the entity in the declaration spec, not in
5740 -- the body spec.
5742 Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
5744 Func_Body :=
5745 Make_Subprogram_Body (Loc,
5746 Specification =>
5747 Copy_Specification (Loc, Func_Spec),
5748 Declarations => Decls,
5749 Handled_Statement_Sequence =>
5750 Make_Handled_Sequence_Of_Statements (Loc,
5751 Statements => Statements));
5753 Insert_After (Declaration_Node (RACW_Type), Func_Decl);
5754 Append_To (Declarations, Func_Body);
5756 Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any);
5757 end Add_RACW_To_Any;
5759 -----------------------
5760 -- Add_RACW_TypeCode --
5761 -----------------------
5763 procedure Add_RACW_TypeCode
5764 (Designated_Type : Entity_Id;
5765 RACW_Type : Entity_Id;
5766 Declarations : List_Id)
5768 Loc : constant Source_Ptr := Sloc (RACW_Type);
5770 Fnam : Entity_Id;
5772 Stub_Elements : constant Stub_Structure :=
5773 Stubs_Table.Get (Designated_Type);
5774 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
5776 Func_Spec : Node_Id;
5777 Func_Decl : Node_Id;
5778 Func_Body : Node_Id;
5780 begin
5781 Fnam :=
5782 Make_Defining_Identifier (Loc,
5783 Chars => New_Internal_Name ('T'));
5785 -- The spec for this subprogram has a dummy 'access RACW'
5786 -- argument, which serves only for overloading purposes.
5788 Func_Spec :=
5789 Make_Function_Specification (Loc,
5790 Defining_Unit_Name =>
5791 Fnam,
5792 Result_Definition => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
5794 -- NOTE: The usage occurrences of RACW_Parameter must
5795 -- refer to the entity in the declaration spec, not those
5796 -- of the body spec.
5798 Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
5800 Func_Body :=
5801 Make_Subprogram_Body (Loc,
5802 Specification =>
5803 Copy_Specification (Loc, Func_Spec),
5804 Declarations => Empty_List,
5805 Handled_Statement_Sequence =>
5806 Make_Handled_Sequence_Of_Statements (Loc,
5807 Statements => New_List (
5808 Make_Return_Statement (Loc,
5809 Expression =>
5810 Make_Selected_Component (Loc,
5811 Prefix =>
5812 Defining_Identifier (
5813 Stub_Elements.RPC_Receiver_Decl),
5814 Selector_Name => Name_Obj_TypeCode)))));
5816 Insert_After (Declaration_Node (RACW_Type), Func_Decl);
5817 Append_To (Declarations, Func_Body);
5819 Set_Renaming_TSS (RACW_Type, Fnam, TSS_TypeCode);
5820 end Add_RACW_TypeCode;
5822 ------------------------------
5823 -- Add_RACW_Write_Attribute --
5824 ------------------------------
5826 procedure Add_RACW_Write_Attribute
5827 (RACW_Type : Entity_Id;
5828 Stub_Type : Entity_Id;
5829 Stub_Type_Access : Entity_Id;
5830 Declarations : List_Id)
5832 Loc : constant Source_Ptr := Sloc (RACW_Type);
5833 pragma Warnings (Off);
5834 pragma Unreferenced (
5835 Stub_Type,
5836 Stub_Type_Access);
5838 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5839 pragma Unreferenced (Is_RAS);
5840 pragma Warnings (On);
5842 Body_Node : Node_Id;
5843 Proc_Decl : Node_Id;
5844 Attr_Decl : Node_Id;
5846 Statements : List_Id;
5847 Procedure_Name : constant Name_Id := New_Internal_Name ('R');
5849 function Stream_Parameter return Node_Id;
5850 function Object return Node_Id;
5851 -- Functions to create occurrences of the formal parameter names
5853 ------------
5854 -- Object --
5855 ------------
5857 function Object return Node_Id is
5858 Object_Ref : constant Node_Id :=
5859 Make_Identifier (Loc, Name_V);
5861 begin
5862 -- Etype must be set for Build_To_Any_Call
5864 Set_Etype (Object_Ref, RACW_Type);
5866 return Object_Ref;
5867 end Object;
5869 ----------------------
5870 -- Stream_Parameter --
5871 ----------------------
5873 function Stream_Parameter return Node_Id is
5874 begin
5875 return Make_Identifier (Loc, Name_S);
5876 end Stream_Parameter;
5878 -- Start of processing for Add_RACW_Write_Attribute
5880 begin
5881 Statements := New_List (
5882 Pack_Node_Into_Stream_Access (Loc,
5883 Stream => Stream_Parameter,
5884 Object =>
5885 Make_Function_Call (Loc,
5886 Name =>
5887 New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
5888 Parameter_Associations => New_List (
5889 PolyORB_Support.Helpers.Build_To_Any_Call
5890 (Object, Declarations))),
5891 Etyp => RTE (RE_Object_Ref)));
5893 Build_Stream_Procedure
5894 (Loc, RACW_Type, Body_Node,
5895 Make_Defining_Identifier (Loc, Procedure_Name),
5896 Statements, Outp => False);
5898 Proc_Decl :=
5899 Make_Subprogram_Declaration (Loc,
5900 Copy_Specification (Loc, Specification (Body_Node)));
5902 Attr_Decl :=
5903 Make_Attribute_Definition_Clause (Loc,
5904 Name => New_Occurrence_Of (RACW_Type, Loc),
5905 Chars => Name_Write,
5906 Expression =>
5907 New_Occurrence_Of (
5908 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
5910 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
5911 Insert_After (Proc_Decl, Attr_Decl);
5912 Append_To (Declarations, Body_Node);
5913 end Add_RACW_Write_Attribute;
5915 -----------------------
5916 -- Add_RAST_Features --
5917 -----------------------
5919 procedure Add_RAST_Features
5920 (Vis_Decl : Node_Id;
5921 RAS_Type : Entity_Id)
5923 begin
5924 Add_RAS_Access_TSS (Vis_Decl);
5926 Add_RAS_From_Any (RAS_Type);
5927 Add_RAS_TypeCode (RAS_Type);
5929 -- To_Any uses TypeCode, and therefore needs to be generated last
5931 Add_RAS_To_Any (RAS_Type);
5932 end Add_RAST_Features;
5934 ------------------------
5935 -- Add_RAS_Access_TSS --
5936 ------------------------
5938 procedure Add_RAS_Access_TSS (N : Node_Id) is
5939 Loc : constant Source_Ptr := Sloc (N);
5941 Ras_Type : constant Entity_Id := Defining_Identifier (N);
5942 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
5943 -- Ras_Type is the access to subprogram type; Fat_Type is the
5944 -- corresponding record type.
5946 RACW_Type : constant Entity_Id :=
5947 Underlying_RACW_Type (Ras_Type);
5948 Desig : constant Entity_Id :=
5949 Etype (Designated_Type (RACW_Type));
5951 Stub_Elements : constant Stub_Structure :=
5952 Stubs_Table.Get (Desig);
5953 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
5955 Proc : constant Entity_Id :=
5956 Make_Defining_Identifier (Loc,
5957 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
5959 Proc_Spec : Node_Id;
5961 -- Formal parameters
5963 Package_Name : constant Entity_Id :=
5964 Make_Defining_Identifier (Loc,
5965 Chars => Name_P);
5967 -- Target package
5969 Subp_Id : constant Entity_Id :=
5970 Make_Defining_Identifier (Loc,
5971 Chars => Name_S);
5973 -- Target subprogram
5975 Asynch_P : constant Entity_Id :=
5976 Make_Defining_Identifier (Loc,
5977 Chars => Name_Asynchronous);
5978 -- Is the procedure to which the 'Access applies asynchronous?
5980 All_Calls_Remote : constant Entity_Id :=
5981 Make_Defining_Identifier (Loc,
5982 Chars => Name_All_Calls_Remote);
5983 -- True if an All_Calls_Remote pragma applies to the RCI unit
5984 -- that contains the subprogram.
5986 -- Common local variables
5988 Proc_Decls : List_Id;
5989 Proc_Statements : List_Id;
5991 Subp_Ref : constant Entity_Id :=
5992 Make_Defining_Identifier (Loc, Name_R);
5993 -- Reference that designates the target subprogram (returned
5994 -- by Get_RAS_Info).
5996 Is_Local : constant Entity_Id :=
5997 Make_Defining_Identifier (Loc, Name_L);
5998 Local_Addr : constant Entity_Id :=
5999 Make_Defining_Identifier (Loc, Name_A);
6000 -- For the call to Get_Local_Address
6002 -- Additional local variables for the remote case
6004 Local_Stub : constant Entity_Id :=
6005 Make_Defining_Identifier (Loc,
6006 Chars => New_Internal_Name ('L'));
6008 Stub_Ptr : constant Entity_Id :=
6009 Make_Defining_Identifier (Loc,
6010 Chars => New_Internal_Name ('S'));
6012 function Set_Field
6013 (Field_Name : Name_Id;
6014 Value : Node_Id) return Node_Id;
6015 -- Construct an assignment that sets the named component in the
6016 -- returned record
6018 ---------------
6019 -- Set_Field --
6020 ---------------
6022 function Set_Field
6023 (Field_Name : Name_Id;
6024 Value : Node_Id) return Node_Id
6026 begin
6027 return
6028 Make_Assignment_Statement (Loc,
6029 Name =>
6030 Make_Selected_Component (Loc,
6031 Prefix => Stub_Ptr,
6032 Selector_Name => Field_Name),
6033 Expression => Value);
6034 end Set_Field;
6036 -- Start of processing for Add_RAS_Access_TSS
6038 begin
6039 Proc_Decls := New_List (
6041 -- Common declarations
6043 Make_Object_Declaration (Loc,
6044 Defining_Identifier => Subp_Ref,
6045 Object_Definition =>
6046 New_Occurrence_Of (RTE (RE_Object_Ref), Loc)),
6048 Make_Object_Declaration (Loc,
6049 Defining_Identifier => Is_Local,
6050 Object_Definition =>
6051 New_Occurrence_Of (Standard_Boolean, Loc)),
6053 Make_Object_Declaration (Loc,
6054 Defining_Identifier => Local_Addr,
6055 Object_Definition =>
6056 New_Occurrence_Of (RTE (RE_Address), Loc)),
6058 Make_Object_Declaration (Loc,
6059 Defining_Identifier => Local_Stub,
6060 Aliased_Present => True,
6061 Object_Definition =>
6062 New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
6064 Make_Object_Declaration (Loc,
6065 Defining_Identifier =>
6066 Stub_Ptr,
6067 Object_Definition =>
6068 New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
6069 Expression =>
6070 Make_Attribute_Reference (Loc,
6071 Prefix => New_Occurrence_Of (Local_Stub, Loc),
6072 Attribute_Name => Name_Unchecked_Access)));
6074 Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
6075 -- Build_Get_Unique_RP_Call needs this information
6077 -- Get_RAS_Info (Pkg, Subp, R);
6078 -- Obtain a reference to the target subprogram
6080 Proc_Statements := New_List (
6081 Make_Procedure_Call_Statement (Loc,
6082 Name =>
6083 New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
6084 Parameter_Associations => New_List (
6085 New_Occurrence_Of (Package_Name, Loc),
6086 New_Occurrence_Of (Subp_Id, Loc),
6087 New_Occurrence_Of (Subp_Ref, Loc))),
6089 -- Get_Local_Address (R, L, A);
6090 -- Determine whether the subprogram is local (L), and if so
6091 -- obtain the local address of its proxy (A).
6093 Make_Procedure_Call_Statement (Loc,
6094 Name =>
6095 New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
6096 Parameter_Associations => New_List (
6097 New_Occurrence_Of (Subp_Ref, Loc),
6098 New_Occurrence_Of (Is_Local, Loc),
6099 New_Occurrence_Of (Local_Addr, Loc))));
6101 -- Note: Here we assume that the Fat_Type is a record containing just
6102 -- an access to a proxy or stub object.
6104 Append_To (Proc_Statements,
6106 -- if L then
6108 Make_Implicit_If_Statement (N,
6109 Condition =>
6110 New_Occurrence_Of (Is_Local, Loc),
6112 Then_Statements => New_List (
6114 -- if A.Target = null then
6116 Make_Implicit_If_Statement (N,
6117 Condition =>
6118 Make_Op_Eq (Loc,
6119 Make_Selected_Component (Loc,
6120 Prefix =>
6121 Unchecked_Convert_To (
6122 RTE (RE_RAS_Proxy_Type_Access),
6123 New_Occurrence_Of (Local_Addr, Loc)),
6124 Selector_Name =>
6125 Make_Identifier (Loc, Name_Target)),
6126 Make_Null (Loc)),
6128 Then_Statements => New_List (
6130 -- A.Target := Entity_Of (Ref);
6132 Make_Assignment_Statement (Loc,
6133 Name =>
6134 Make_Selected_Component (Loc,
6135 Prefix =>
6136 Unchecked_Convert_To (
6137 RTE (RE_RAS_Proxy_Type_Access),
6138 New_Occurrence_Of (Local_Addr, Loc)),
6139 Selector_Name =>
6140 Make_Identifier (Loc, Name_Target)),
6141 Expression =>
6142 Make_Function_Call (Loc,
6143 Name =>
6144 New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
6145 Parameter_Associations => New_List (
6146 New_Occurrence_Of (Subp_Ref, Loc)))),
6148 -- Inc_Usage (A.Target);
6150 Make_Procedure_Call_Statement (Loc,
6151 Name =>
6152 New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
6153 Parameter_Associations => New_List (
6154 Make_Selected_Component (Loc,
6155 Prefix =>
6156 Unchecked_Convert_To (
6157 RTE (RE_RAS_Proxy_Type_Access),
6158 New_Occurrence_Of (Local_Addr, Loc)),
6159 Selector_Name => Make_Identifier (Loc,
6160 Name_Target)))))),
6162 -- end if;
6163 -- if not All_Calls_Remote then
6164 -- return Fat_Type!(A);
6165 -- end if;
6167 Make_Implicit_If_Statement (N,
6168 Condition =>
6169 Make_Op_Not (Loc,
6170 New_Occurrence_Of (All_Calls_Remote, Loc)),
6172 Then_Statements => New_List (
6173 Make_Return_Statement (Loc,
6174 Unchecked_Convert_To (Fat_Type,
6175 New_Occurrence_Of (Local_Addr, Loc))))))));
6177 Append_List_To (Proc_Statements, New_List (
6179 -- Stub.Target := Entity_Of (Ref);
6181 Set_Field (Name_Target,
6182 Make_Function_Call (Loc,
6183 Name =>
6184 New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
6185 Parameter_Associations => New_List (
6186 New_Occurrence_Of (Subp_Ref, Loc)))),
6188 -- Inc_Usage (Stub.Target);
6190 Make_Procedure_Call_Statement (Loc,
6191 Name =>
6192 New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
6193 Parameter_Associations => New_List (
6194 Make_Selected_Component (Loc,
6195 Prefix => Stub_Ptr,
6196 Selector_Name => Name_Target))),
6198 -- E.4.1(9) A remote call is asynchronous if it is a call to
6199 -- a procedure, or a call through a value of an access-to-procedure
6200 -- type, to which a pragma Asynchronous applies.
6202 -- Parameter Asynch_P is true when the procedure is asynchronous;
6203 -- Expression Asynch_T is true when the type is asynchronous.
6205 Set_Field (Name_Asynchronous,
6206 Make_Or_Else (Loc,
6207 New_Occurrence_Of (Asynch_P, Loc),
6208 New_Occurrence_Of (Boolean_Literals (
6209 Is_Asynchronous (Ras_Type)), Loc)))));
6211 Append_List_To (Proc_Statements,
6212 Build_Get_Unique_RP_Call (Loc,
6213 Stub_Ptr, Stub_Elements.Stub_Type));
6215 Append_To (Proc_Statements,
6216 Make_Return_Statement (Loc,
6217 Expression =>
6218 Unchecked_Convert_To (Fat_Type,
6219 New_Occurrence_Of (Stub_Ptr, Loc))));
6221 Proc_Spec :=
6222 Make_Function_Specification (Loc,
6223 Defining_Unit_Name => Proc,
6224 Parameter_Specifications => New_List (
6225 Make_Parameter_Specification (Loc,
6226 Defining_Identifier => Package_Name,
6227 Parameter_Type =>
6228 New_Occurrence_Of (Standard_String, Loc)),
6230 Make_Parameter_Specification (Loc,
6231 Defining_Identifier => Subp_Id,
6232 Parameter_Type =>
6233 New_Occurrence_Of (Standard_String, Loc)),
6235 Make_Parameter_Specification (Loc,
6236 Defining_Identifier => Asynch_P,
6237 Parameter_Type =>
6238 New_Occurrence_Of (Standard_Boolean, Loc)),
6240 Make_Parameter_Specification (Loc,
6241 Defining_Identifier => All_Calls_Remote,
6242 Parameter_Type =>
6243 New_Occurrence_Of (Standard_Boolean, Loc))),
6245 Result_Definition =>
6246 New_Occurrence_Of (Fat_Type, Loc));
6248 -- Set the kind and return type of the function to prevent
6249 -- ambiguities between Ras_Type and Fat_Type in subsequent analysis.
6251 Set_Ekind (Proc, E_Function);
6252 Set_Etype (Proc, Fat_Type);
6254 Discard_Node (
6255 Make_Subprogram_Body (Loc,
6256 Specification => Proc_Spec,
6257 Declarations => Proc_Decls,
6258 Handled_Statement_Sequence =>
6259 Make_Handled_Sequence_Of_Statements (Loc,
6260 Statements => Proc_Statements)));
6262 Set_TSS (Fat_Type, Proc);
6263 end Add_RAS_Access_TSS;
6265 ----------------------
6266 -- Add_RAS_From_Any --
6267 ----------------------
6269 procedure Add_RAS_From_Any (RAS_Type : Entity_Id) is
6270 Loc : constant Source_Ptr := Sloc (RAS_Type);
6272 Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
6273 Make_TSS_Name (RAS_Type, TSS_From_Any));
6275 Func_Spec : Node_Id;
6277 Statements : List_Id;
6279 Any_Parameter : constant Entity_Id :=
6280 Make_Defining_Identifier (Loc, Name_A);
6282 begin
6283 Statements := New_List (
6284 Make_Return_Statement (Loc,
6285 Expression =>
6286 Make_Aggregate (Loc,
6287 Component_Associations => New_List (
6288 Make_Component_Association (Loc,
6289 Choices => New_List (
6290 Make_Identifier (Loc, Name_Ras)),
6291 Expression =>
6292 PolyORB_Support.Helpers.Build_From_Any_Call (
6293 Underlying_RACW_Type (RAS_Type),
6294 New_Occurrence_Of (Any_Parameter, Loc),
6295 No_List))))));
6297 Func_Spec :=
6298 Make_Function_Specification (Loc,
6299 Defining_Unit_Name =>
6300 Fnam,
6301 Parameter_Specifications => New_List (
6302 Make_Parameter_Specification (Loc,
6303 Defining_Identifier =>
6304 Any_Parameter,
6305 Parameter_Type =>
6306 New_Occurrence_Of (RTE (RE_Any), Loc))),
6307 Result_Definition => New_Occurrence_Of (RAS_Type, Loc));
6309 Discard_Node (
6310 Make_Subprogram_Body (Loc,
6311 Specification => Func_Spec,
6312 Declarations => No_List,
6313 Handled_Statement_Sequence =>
6314 Make_Handled_Sequence_Of_Statements (Loc,
6315 Statements => Statements)));
6316 Set_TSS (RAS_Type, Fnam);
6317 end Add_RAS_From_Any;
6319 --------------------
6320 -- Add_RAS_To_Any --
6321 --------------------
6323 procedure Add_RAS_To_Any (RAS_Type : Entity_Id) is
6324 Loc : constant Source_Ptr := Sloc (RAS_Type);
6326 Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
6327 Make_TSS_Name (RAS_Type, TSS_To_Any));
6329 Decls : List_Id;
6330 Statements : List_Id;
6332 Func_Spec : Node_Id;
6334 Any : constant Entity_Id :=
6335 Make_Defining_Identifier (Loc,
6336 Chars => New_Internal_Name ('A'));
6337 RAS_Parameter : constant Entity_Id :=
6338 Make_Defining_Identifier (Loc,
6339 Chars => New_Internal_Name ('R'));
6340 RACW_Parameter : constant Node_Id :=
6341 Make_Selected_Component (Loc,
6342 Prefix => RAS_Parameter,
6343 Selector_Name => Name_Ras);
6345 begin
6346 -- Object declarations
6348 Set_Etype (RACW_Parameter, Underlying_RACW_Type (RAS_Type));
6349 Decls := New_List (
6350 Make_Object_Declaration (Loc,
6351 Defining_Identifier =>
6352 Any,
6353 Object_Definition =>
6354 New_Occurrence_Of (RTE (RE_Any), Loc),
6355 Expression =>
6356 PolyORB_Support.Helpers.Build_To_Any_Call
6357 (RACW_Parameter, No_List)));
6359 Statements := New_List (
6360 Make_Procedure_Call_Statement (Loc,
6361 Name =>
6362 New_Occurrence_Of (RTE (RE_Set_TC), Loc),
6363 Parameter_Associations => New_List (
6364 New_Occurrence_Of (Any, Loc),
6365 PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
6366 RAS_Type, Decls))),
6367 Make_Return_Statement (Loc,
6368 Expression =>
6369 New_Occurrence_Of (Any, Loc)));
6371 Func_Spec :=
6372 Make_Function_Specification (Loc,
6373 Defining_Unit_Name =>
6374 Fnam,
6375 Parameter_Specifications => New_List (
6376 Make_Parameter_Specification (Loc,
6377 Defining_Identifier =>
6378 RAS_Parameter,
6379 Parameter_Type =>
6380 New_Occurrence_Of (RAS_Type, Loc))),
6381 Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
6383 Discard_Node (
6384 Make_Subprogram_Body (Loc,
6385 Specification => Func_Spec,
6386 Declarations => Decls,
6387 Handled_Statement_Sequence =>
6388 Make_Handled_Sequence_Of_Statements (Loc,
6389 Statements => Statements)));
6390 Set_TSS (RAS_Type, Fnam);
6391 end Add_RAS_To_Any;
6393 ----------------------
6394 -- Add_RAS_TypeCode --
6395 ----------------------
6397 procedure Add_RAS_TypeCode (RAS_Type : Entity_Id) is
6398 Loc : constant Source_Ptr := Sloc (RAS_Type);
6400 Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
6401 Make_TSS_Name (RAS_Type, TSS_TypeCode));
6403 Func_Spec : Node_Id;
6405 Decls : constant List_Id := New_List;
6406 Name_String, Repo_Id_String : String_Id;
6408 begin
6409 Func_Spec :=
6410 Make_Function_Specification (Loc,
6411 Defining_Unit_Name =>
6412 Fnam,
6413 Result_Definition => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
6415 PolyORB_Support.Helpers.Build_Name_And_Repository_Id
6416 (RAS_Type, Name_Str => Name_String, Repo_Id_Str => Repo_Id_String);
6418 Discard_Node (
6419 Make_Subprogram_Body (Loc,
6420 Specification => Func_Spec,
6421 Declarations => Decls,
6422 Handled_Statement_Sequence =>
6423 Make_Handled_Sequence_Of_Statements (Loc,
6424 Statements => New_List (
6425 Make_Return_Statement (Loc,
6426 Expression =>
6427 Make_Function_Call (Loc,
6428 Name =>
6429 New_Occurrence_Of (RTE (RE_TC_Build), Loc),
6430 Parameter_Associations => New_List (
6431 New_Occurrence_Of (RTE (RE_TC_Object), Loc),
6432 Make_Aggregate (Loc,
6433 Expressions =>
6434 New_List (
6435 Make_Function_Call (Loc,
6436 Name => New_Occurrence_Of (
6437 RTE (RE_TA_String), Loc),
6438 Parameter_Associations => New_List (
6439 Make_String_Literal (Loc, Name_String))),
6440 Make_Function_Call (Loc,
6441 Name => New_Occurrence_Of (
6442 RTE (RE_TA_String), Loc),
6443 Parameter_Associations => New_List (
6444 Make_String_Literal (Loc,
6445 Repo_Id_String))))))))))));
6446 Set_TSS (RAS_Type, Fnam);
6447 end Add_RAS_TypeCode;
6449 -----------------------------------------
6450 -- Add_Receiving_Stubs_To_Declarations --
6451 -----------------------------------------
6453 procedure Add_Receiving_Stubs_To_Declarations
6454 (Pkg_Spec : Node_Id;
6455 Decls : List_Id)
6457 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
6459 Pkg_RPC_Receiver : constant Entity_Id :=
6460 Make_Defining_Identifier (Loc,
6461 New_Internal_Name ('H'));
6462 Pkg_RPC_Receiver_Object : Node_Id;
6464 Pkg_RPC_Receiver_Body : Node_Id;
6465 Pkg_RPC_Receiver_Decls : List_Id;
6466 Pkg_RPC_Receiver_Statements : List_Id;
6467 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
6468 -- A Pkg_RPC_Receiver is built to decode the request
6470 Request : Node_Id;
6471 -- Request object received from neutral layer
6473 Subp_Id : Entity_Id;
6474 -- Subprogram identifier as received from the neutral
6475 -- distribution core.
6477 Subp_Index : Entity_Id;
6478 -- Internal index as determined by matching either the
6479 -- method name from the request structure, or the local
6480 -- subprogram address (in case of a RAS).
6482 Is_Local : constant Entity_Id :=
6483 Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
6484 Local_Address : constant Entity_Id :=
6485 Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
6486 -- Address of a local subprogram designated by a
6487 -- reference corresponding to a RAS.
6489 Dispatch_On_Address : constant List_Id := New_List;
6490 Dispatch_On_Name : constant List_Id := New_List;
6492 Current_Declaration : Node_Id;
6493 Current_Stubs : Node_Id;
6494 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
6496 Subp_Info_Array : constant Entity_Id :=
6497 Make_Defining_Identifier (Loc,
6498 Chars => New_Internal_Name ('I'));
6500 Subp_Info_List : constant List_Id := New_List;
6502 Register_Pkg_Actuals : constant List_Id := New_List;
6504 All_Calls_Remote_E : Entity_Id;
6506 procedure Append_Stubs_To
6507 (RPC_Receiver_Cases : List_Id;
6508 Declaration : Node_Id;
6509 Stubs : Node_Id;
6510 Subp_Number : Int;
6511 Subp_Dist_Name : Entity_Id;
6512 Subp_Proxy_Addr : Entity_Id);
6513 -- Add one case to the specified RPC receiver case list associating
6514 -- Subprogram_Number with the subprogram declared by Declaration, for
6515 -- which we have receiving stubs in Stubs. Subp_Number is an internal
6516 -- subprogram index. Subp_Dist_Name is the string used to call the
6517 -- subprogram by name, and Subp_Dist_Addr is the address of the proxy
6518 -- object, used in the context of calls through remote
6519 -- access-to-subprogram types.
6521 ---------------------
6522 -- Append_Stubs_To --
6523 ---------------------
6525 procedure Append_Stubs_To
6526 (RPC_Receiver_Cases : List_Id;
6527 Declaration : Node_Id;
6528 Stubs : Node_Id;
6529 Subp_Number : Int;
6530 Subp_Dist_Name : Entity_Id;
6531 Subp_Proxy_Addr : Entity_Id)
6533 Case_Stmts : List_Id;
6534 begin
6535 Case_Stmts := New_List (
6536 Make_Procedure_Call_Statement (Loc,
6537 Name =>
6538 New_Occurrence_Of (
6539 Defining_Entity (Stubs), Loc),
6540 Parameter_Associations =>
6541 New_List (New_Occurrence_Of (Request, Loc))));
6542 if Nkind (Specification (Declaration))
6543 = N_Function_Specification
6544 or else not
6545 Is_Asynchronous (Defining_Entity (Specification (Declaration)))
6546 then
6547 Append_To (Case_Stmts, Make_Return_Statement (Loc));
6548 end if;
6550 Append_To (RPC_Receiver_Cases,
6551 Make_Case_Statement_Alternative (Loc,
6552 Discrete_Choices =>
6553 New_List (Make_Integer_Literal (Loc, Subp_Number)),
6554 Statements =>
6555 Case_Stmts));
6557 Append_To (Dispatch_On_Name,
6558 Make_Elsif_Part (Loc,
6559 Condition =>
6560 Make_Function_Call (Loc,
6561 Name =>
6562 New_Occurrence_Of (RTE (RE_Caseless_String_Eq), Loc),
6563 Parameter_Associations => New_List (
6564 New_Occurrence_Of (Subp_Id, Loc),
6565 New_Occurrence_Of (Subp_Dist_Name, Loc))),
6566 Then_Statements => New_List (
6567 Make_Assignment_Statement (Loc,
6568 New_Occurrence_Of (Subp_Index, Loc),
6569 Make_Integer_Literal (Loc,
6570 Subp_Number)))));
6572 Append_To (Dispatch_On_Address,
6573 Make_Elsif_Part (Loc,
6574 Condition =>
6575 Make_Op_Eq (Loc,
6576 Left_Opnd =>
6577 New_Occurrence_Of (Local_Address, Loc),
6578 Right_Opnd =>
6579 New_Occurrence_Of (Subp_Proxy_Addr, Loc)),
6580 Then_Statements => New_List (
6581 Make_Assignment_Statement (Loc,
6582 New_Occurrence_Of (Subp_Index, Loc),
6583 Make_Integer_Literal (Loc,
6584 Subp_Number)))));
6585 end Append_Stubs_To;
6587 -- Start of processing for Add_Receiving_Stubs_To_Declarations
6589 begin
6590 -- Building receiving stubs consist in several operations:
6592 -- - a package RPC receiver must be built. This subprogram
6593 -- will get a Subprogram_Id from the incoming stream
6594 -- and will dispatch the call to the right subprogram
6596 -- - a receiving stub for any subprogram visible in the package
6597 -- spec. This stub will read all the parameters from the stream,
6598 -- and put the result as well as the exception occurrence in the
6599 -- output stream
6601 -- - a dummy package with an empty spec and a body made of an
6602 -- elaboration part, whose job is to register the receiving
6603 -- part of this RCI package on the name server. This is done
6604 -- by calling System.Partition_Interface.Register_Receiving_Stub
6606 Build_RPC_Receiver_Body (
6607 RPC_Receiver => Pkg_RPC_Receiver,
6608 Request => Request,
6609 Subp_Id => Subp_Id,
6610 Subp_Index => Subp_Index,
6611 Stmts => Pkg_RPC_Receiver_Statements,
6612 Decl => Pkg_RPC_Receiver_Body);
6613 Pkg_RPC_Receiver_Decls := Declarations (Pkg_RPC_Receiver_Body);
6615 -- Extract local address information from the target reference:
6616 -- if non-null, that means that this is a reference that denotes
6617 -- one particular operation, and hence that the operation name
6618 -- must not be taken into account for dispatching.
6620 Append_To (Pkg_RPC_Receiver_Decls,
6621 Make_Object_Declaration (Loc,
6622 Defining_Identifier =>
6623 Is_Local,
6624 Object_Definition =>
6625 New_Occurrence_Of (Standard_Boolean, Loc)));
6626 Append_To (Pkg_RPC_Receiver_Decls,
6627 Make_Object_Declaration (Loc,
6628 Defining_Identifier =>
6629 Local_Address,
6630 Object_Definition =>
6631 New_Occurrence_Of (RTE (RE_Address), Loc)));
6632 Append_To (Pkg_RPC_Receiver_Statements,
6633 Make_Procedure_Call_Statement (Loc,
6634 Name =>
6635 New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
6636 Parameter_Associations => New_List (
6637 Make_Selected_Component (Loc,
6638 Prefix => Request,
6639 Selector_Name => Name_Target),
6640 New_Occurrence_Of (Is_Local, Loc),
6641 New_Occurrence_Of (Local_Address, Loc))));
6643 -- Determine whether the reference that was used to make
6644 -- the call was the base RCI reference (in which case
6645 -- Local_Address is 0, and the method identifier from the
6646 -- request must be used to determine which subprogram is
6647 -- called) or a reference identifying one particular subprogram
6648 -- (in which case Local_Address is the address of that
6649 -- subprogram, and the method name from the request is
6650 -- ignored).
6651 -- In each case, cascaded elsifs are used to determine the
6652 -- proper subprogram index. Using hash tables might be
6653 -- more efficient.
6655 Append_To (Pkg_RPC_Receiver_Statements,
6656 Make_Implicit_If_Statement (Pkg_Spec,
6657 Condition =>
6658 Make_Op_Ne (Loc,
6659 Left_Opnd => New_Occurrence_Of (Local_Address, Loc),
6660 Right_Opnd => New_Occurrence_Of (RTE (RE_Null_Address), Loc)),
6661 Then_Statements => New_List (
6662 Make_Implicit_If_Statement (Pkg_Spec,
6663 Condition =>
6664 New_Occurrence_Of (Standard_False, Loc),
6665 Then_Statements => New_List (
6666 Make_Null_Statement (Loc)),
6667 Elsif_Parts =>
6668 Dispatch_On_Address)),
6669 Else_Statements => New_List (
6670 Make_Implicit_If_Statement (Pkg_Spec,
6671 Condition =>
6672 New_Occurrence_Of (Standard_False, Loc),
6673 Then_Statements => New_List (
6674 Make_Null_Statement (Loc)),
6675 Elsif_Parts =>
6676 Dispatch_On_Name))));
6678 -- For each subprogram, the receiving stub will be built and a
6679 -- case statement will be made on the Subprogram_Id to dispatch
6680 -- to the right subprogram.
6682 All_Calls_Remote_E := Boolean_Literals (
6683 Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
6685 Overload_Counter_Table.Reset;
6686 Reserve_NamingContext_Methods;
6688 Current_Declaration := First (Visible_Declarations (Pkg_Spec));
6689 while Present (Current_Declaration) loop
6690 if Nkind (Current_Declaration) = N_Subprogram_Declaration
6691 and then Comes_From_Source (Current_Declaration)
6692 then
6693 declare
6694 Loc : constant Source_Ptr :=
6695 Sloc (Current_Declaration);
6696 -- While specifically processing Current_Declaration, use
6697 -- its Sloc as the location of all generated nodes.
6699 Subp_Def : constant Entity_Id :=
6700 Defining_Unit_Name
6701 (Specification (Current_Declaration));
6703 Subp_Val : String_Id;
6705 Subp_Dist_Name : constant Entity_Id :=
6706 Make_Defining_Identifier (Loc,
6707 New_External_Name (
6708 Related_Id => Chars (Subp_Def),
6709 Suffix => 'D',
6710 Suffix_Index => -1));
6712 Proxy_Object_Addr : Entity_Id;
6714 begin
6715 pragma Assert (Current_Subprogram_Number =
6716 Get_Subprogram_Id (Subp_Def));
6718 -- Build receiving stub
6720 Current_Stubs :=
6721 Build_Subprogram_Receiving_Stubs
6722 (Vis_Decl => Current_Declaration,
6723 Asynchronous =>
6724 Nkind (Specification (Current_Declaration)) =
6725 N_Procedure_Specification
6726 and then Is_Asynchronous (Subp_Def));
6728 Append_To (Decls, Current_Stubs);
6729 Analyze (Current_Stubs);
6731 -- Build RAS proxy
6733 Add_RAS_Proxy_And_Analyze (Decls,
6734 Vis_Decl =>
6735 Current_Declaration,
6736 All_Calls_Remote_E =>
6737 All_Calls_Remote_E,
6738 Proxy_Object_Addr =>
6739 Proxy_Object_Addr);
6741 -- Compute distribution identifier
6743 Assign_Subprogram_Identifier (
6744 Subp_Def,
6745 Current_Subprogram_Number,
6746 Subp_Val);
6748 Append_To (Decls,
6749 Make_Object_Declaration (Loc,
6750 Defining_Identifier => Subp_Dist_Name,
6751 Constant_Present => True,
6752 Object_Definition => New_Occurrence_Of (
6753 Standard_String, Loc),
6754 Expression =>
6755 Make_String_Literal (Loc, Subp_Val)));
6756 Analyze (Last (Decls));
6758 -- Add subprogram descriptor (RCI_Subp_Info) to the
6759 -- subprograms table for this receiver. The aggregate
6760 -- below must be kept consistent with the declaration
6761 -- of type RCI_Subp_Info in System.Partition_Interface.
6763 Append_To (Subp_Info_List,
6764 Make_Component_Association (Loc,
6765 Choices => New_List (
6766 Make_Integer_Literal (Loc,
6767 Current_Subprogram_Number)),
6768 Expression =>
6769 Make_Aggregate (Loc,
6770 Expressions => New_List (
6771 Make_Attribute_Reference (Loc,
6772 Prefix =>
6773 New_Occurrence_Of (
6774 Subp_Dist_Name, Loc),
6775 Attribute_Name => Name_Address),
6776 Make_Attribute_Reference (Loc,
6777 Prefix =>
6778 New_Occurrence_Of (
6779 Subp_Dist_Name, Loc),
6780 Attribute_Name => Name_Length),
6781 New_Occurrence_Of (Proxy_Object_Addr, Loc)))));
6783 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
6784 Declaration => Current_Declaration,
6785 Stubs => Current_Stubs,
6786 Subp_Number => Current_Subprogram_Number,
6787 Subp_Dist_Name => Subp_Dist_Name,
6788 Subp_Proxy_Addr => Proxy_Object_Addr);
6789 end;
6791 Current_Subprogram_Number := Current_Subprogram_Number + 1;
6792 end if;
6794 Next (Current_Declaration);
6795 end loop;
6797 -- If we receive an invalid Subprogram_Id, it is best to do nothing
6798 -- rather than raising an exception since we do not want someone
6799 -- to crash a remote partition by sending invalid subprogram ids.
6800 -- This is consistent with the other parts of the case statement
6801 -- since even in presence of incorrect parameters in the stream,
6802 -- every exception will be caught and (if the subprogram is not an
6803 -- APC) put into the result stream and sent away.
6805 Append_To (Pkg_RPC_Receiver_Cases,
6806 Make_Case_Statement_Alternative (Loc,
6807 Discrete_Choices =>
6808 New_List (Make_Others_Choice (Loc)),
6809 Statements =>
6810 New_List (Make_Null_Statement (Loc))));
6812 Append_To (Pkg_RPC_Receiver_Statements,
6813 Make_Case_Statement (Loc,
6814 Expression =>
6815 New_Occurrence_Of (Subp_Index, Loc),
6816 Alternatives => Pkg_RPC_Receiver_Cases));
6818 Append_To (Decls,
6819 Make_Object_Declaration (Loc,
6820 Defining_Identifier => Subp_Info_Array,
6821 Constant_Present => True,
6822 Aliased_Present => True,
6823 Object_Definition =>
6824 Make_Subtype_Indication (Loc,
6825 Subtype_Mark =>
6826 New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
6827 Constraint =>
6828 Make_Index_Or_Discriminant_Constraint (Loc,
6829 New_List (
6830 Make_Range (Loc,
6831 Low_Bound => Make_Integer_Literal (Loc,
6832 First_RCI_Subprogram_Id),
6833 High_Bound =>
6834 Make_Integer_Literal (Loc,
6835 First_RCI_Subprogram_Id
6836 + List_Length (Subp_Info_List) - 1))))),
6837 Expression =>
6838 Make_Aggregate (Loc,
6839 Component_Associations => Subp_Info_List)));
6840 Analyze (Last (Decls));
6842 Append_To (Decls, Pkg_RPC_Receiver_Body);
6843 Analyze (Last (Decls));
6845 Pkg_RPC_Receiver_Object :=
6846 Make_Object_Declaration (Loc,
6847 Defining_Identifier =>
6848 Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
6849 Aliased_Present => True,
6850 Object_Definition =>
6851 New_Occurrence_Of (RTE (RE_Servant), Loc));
6852 Append_To (Decls, Pkg_RPC_Receiver_Object);
6853 Analyze (Last (Decls));
6855 Get_Library_Unit_Name_String (Pkg_Spec);
6856 Append_To (Register_Pkg_Actuals,
6857 -- Name
6858 Make_String_Literal (Loc,
6859 Strval => String_From_Name_Buffer));
6861 Append_To (Register_Pkg_Actuals,
6862 -- Version
6863 Make_Attribute_Reference (Loc,
6864 Prefix =>
6865 New_Occurrence_Of
6866 (Defining_Entity (Pkg_Spec), Loc),
6867 Attribute_Name =>
6868 Name_Version));
6870 Append_To (Register_Pkg_Actuals,
6871 -- Handler
6872 Make_Attribute_Reference (Loc,
6873 Prefix =>
6874 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
6875 Attribute_Name => Name_Access));
6877 Append_To (Register_Pkg_Actuals,
6878 -- Receiver
6879 Make_Attribute_Reference (Loc,
6880 Prefix =>
6881 New_Occurrence_Of (
6882 Defining_Identifier (
6883 Pkg_RPC_Receiver_Object), Loc),
6884 Attribute_Name =>
6885 Name_Access));
6887 Append_To (Register_Pkg_Actuals,
6888 -- Subp_Info
6889 Make_Attribute_Reference (Loc,
6890 Prefix =>
6891 New_Occurrence_Of (Subp_Info_Array, Loc),
6892 Attribute_Name =>
6893 Name_Address));
6895 Append_To (Register_Pkg_Actuals,
6896 -- Subp_Info_Len
6897 Make_Attribute_Reference (Loc,
6898 Prefix =>
6899 New_Occurrence_Of (Subp_Info_Array, Loc),
6900 Attribute_Name =>
6901 Name_Length));
6903 Append_To (Register_Pkg_Actuals,
6904 -- Is_All_Calls_Remote
6905 New_Occurrence_Of (All_Calls_Remote_E, Loc));
6907 Append_To (Decls,
6908 Make_Procedure_Call_Statement (Loc,
6909 Name =>
6910 New_Occurrence_Of (RTE (RE_Register_Pkg_Receiving_Stub), Loc),
6911 Parameter_Associations => Register_Pkg_Actuals));
6912 Analyze (Last (Decls));
6914 end Add_Receiving_Stubs_To_Declarations;
6916 ---------------------------------
6917 -- Build_General_Calling_Stubs --
6918 ---------------------------------
6920 procedure Build_General_Calling_Stubs
6921 (Decls : List_Id;
6922 Statements : List_Id;
6923 Target_Object : Node_Id;
6924 Subprogram_Id : Node_Id;
6925 Asynchronous : Node_Id := Empty;
6926 Is_Known_Asynchronous : Boolean := False;
6927 Is_Known_Non_Asynchronous : Boolean := False;
6928 Is_Function : Boolean;
6929 Spec : Node_Id;
6930 Stub_Type : Entity_Id := Empty;
6931 RACW_Type : Entity_Id := Empty;
6932 Nod : Node_Id)
6934 Loc : constant Source_Ptr := Sloc (Nod);
6936 Arguments : Node_Id;
6937 -- Name of the named values list used to transmit parameters
6938 -- to the remote package
6940 Request : Node_Id;
6941 -- The request object constructed by these stubs
6943 Result : Node_Id;
6944 -- Name of the result named value (in non-APC cases) which get the
6945 -- result of the remote subprogram.
6947 Result_TC : Node_Id;
6948 -- Typecode expression for the result of the request (void
6949 -- typecode for procedures).
6951 Exception_Return_Parameter : Node_Id;
6952 -- Name of the parameter which will hold the exception sent by the
6953 -- remote subprogram.
6955 Current_Parameter : Node_Id;
6956 -- Current parameter being handled
6958 Ordered_Parameters_List : constant List_Id :=
6959 Build_Ordered_Parameters_List (Spec);
6961 Asynchronous_P : Node_Id;
6962 -- A Boolean expression indicating whether this call is asynchronous
6964 Asynchronous_Statements : List_Id := No_List;
6965 Non_Asynchronous_Statements : List_Id := No_List;
6966 -- Statements specifics to the Asynchronous/Non-Asynchronous cases
6968 Extra_Formal_Statements : constant List_Id := New_List;
6969 -- List of statements for extra formal parameters. It will appear
6970 -- after the regular statements for writing out parameters.
6972 After_Statements : constant List_Id := New_List;
6973 -- Statements to be executed after call returns (to assign
6974 -- in out or out parameter values).
6976 Etyp : Entity_Id;
6977 -- The type of the formal parameter being processed
6979 Is_Controlling_Formal : Boolean;
6980 Is_First_Controlling_Formal : Boolean;
6981 First_Controlling_Formal_Seen : Boolean := False;
6982 -- Controlling formal parameters of distributed object
6983 -- primitives require special handling, and the first
6984 -- such parameter needs even more.
6986 begin
6987 -- ??? document general form of stub subprograms for the PolyORB case
6988 Request :=
6989 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
6991 Append_To (Decls,
6992 Make_Object_Declaration (Loc,
6993 Defining_Identifier => Request,
6994 Aliased_Present => False,
6995 Object_Definition =>
6996 New_Occurrence_Of (RTE (RE_Request_Access), Loc)));
6998 Result :=
6999 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
7001 if Is_Function then
7002 Result_TC := PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
7003 Etype (Result_Definition (Spec)), Decls);
7004 else
7005 Result_TC := New_Occurrence_Of (RTE (RE_TC_Void), Loc);
7006 end if;
7008 Append_To (Decls,
7009 Make_Object_Declaration (Loc,
7010 Defining_Identifier => Result,
7011 Aliased_Present => False,
7012 Object_Definition =>
7013 New_Occurrence_Of (RTE (RE_NamedValue), Loc),
7014 Expression =>
7015 Make_Aggregate (Loc,
7016 Component_Associations => New_List (
7017 Make_Component_Association (Loc,
7018 Choices => New_List (
7019 Make_Identifier (Loc, Name_Name)),
7020 Expression =>
7021 New_Occurrence_Of (RTE (RE_Result_Name), Loc)),
7022 Make_Component_Association (Loc,
7023 Choices => New_List (
7024 Make_Identifier (Loc, Name_Argument)),
7025 Expression =>
7026 Make_Function_Call (Loc,
7027 Name =>
7028 New_Occurrence_Of (RTE (RE_Create_Any), Loc),
7029 Parameter_Associations => New_List (
7030 Result_TC))),
7031 Make_Component_Association (Loc,
7032 Choices => New_List (
7033 Make_Identifier (Loc, Name_Arg_Modes)),
7034 Expression =>
7035 Make_Integer_Literal (Loc, 0))))));
7037 if not Is_Known_Asynchronous then
7038 Exception_Return_Parameter :=
7039 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
7041 Append_To (Decls,
7042 Make_Object_Declaration (Loc,
7043 Defining_Identifier => Exception_Return_Parameter,
7044 Object_Definition =>
7045 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
7047 else
7048 Exception_Return_Parameter := Empty;
7049 end if;
7051 -- Initialize and fill in arguments list
7053 Arguments :=
7054 Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
7055 Declare_Create_NVList (Loc, Arguments, Decls, Statements);
7057 Current_Parameter := First (Ordered_Parameters_List);
7058 while Present (Current_Parameter) loop
7060 if Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) then
7061 Is_Controlling_Formal := True;
7062 Is_First_Controlling_Formal :=
7063 not First_Controlling_Formal_Seen;
7064 First_Controlling_Formal_Seen := True;
7065 else
7066 Is_Controlling_Formal := False;
7067 Is_First_Controlling_Formal := False;
7068 end if;
7070 if Is_Controlling_Formal then
7072 -- In the case of a controlling formal argument, we send
7073 -- its reference.
7075 Etyp := RACW_Type;
7077 else
7078 Etyp := Etype (Parameter_Type (Current_Parameter));
7079 end if;
7081 -- The first controlling formal parameter is treated
7082 -- specially: it is used to set the target object of
7083 -- the call.
7085 if not Is_First_Controlling_Formal then
7087 declare
7088 Constrained : constant Boolean :=
7089 Is_Constrained (Etyp)
7090 or else Is_Elementary_Type (Etyp);
7092 Any : constant Entity_Id :=
7093 Make_Defining_Identifier (Loc,
7094 New_Internal_Name ('A'));
7096 Actual_Parameter : Node_Id :=
7097 New_Occurrence_Of (
7098 Defining_Identifier (
7099 Current_Parameter), Loc);
7101 Expr : Node_Id;
7103 begin
7104 if Is_Controlling_Formal then
7106 -- For a controlling formal parameter (other
7107 -- than the first one), use the corresponding
7108 -- RACW. If the parameter is not an anonymous
7109 -- access parameter, that involves taking
7110 -- its 'Unrestricted_Access.
7112 if Nkind (Parameter_Type (Current_Parameter))
7113 = N_Access_Definition
7114 then
7115 Actual_Parameter := OK_Convert_To
7116 (Etyp, Actual_Parameter);
7117 else
7118 Actual_Parameter := OK_Convert_To (Etyp,
7119 Make_Attribute_Reference (Loc,
7120 Prefix =>
7121 Actual_Parameter,
7122 Attribute_Name =>
7123 Name_Unrestricted_Access));
7124 end if;
7126 end if;
7128 if In_Present (Current_Parameter)
7129 or else not Out_Present (Current_Parameter)
7130 or else not Constrained
7131 or else Is_Controlling_Formal
7132 then
7133 -- The parameter has an input value, is constrained
7134 -- at runtime by an input value, or is a controlling
7135 -- formal parameter (always passed as a reference)
7136 -- other than the first one.
7138 Expr := PolyORB_Support.Helpers.Build_To_Any_Call (
7139 Actual_Parameter, Decls);
7140 else
7141 Expr := Make_Function_Call (Loc,
7142 Name =>
7143 New_Occurrence_Of (RTE (RE_Create_Any), Loc),
7144 Parameter_Associations => New_List (
7145 PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
7146 Etyp, Decls)));
7147 end if;
7149 Append_To (Decls,
7150 Make_Object_Declaration (Loc,
7151 Defining_Identifier =>
7152 Any,
7153 Aliased_Present => False,
7154 Object_Definition =>
7155 New_Occurrence_Of (RTE (RE_Any), Loc),
7156 Expression =>
7157 Expr));
7159 Append_To (Statements,
7160 Add_Parameter_To_NVList (Loc,
7161 Parameter => Current_Parameter,
7162 NVList => Arguments,
7163 Constrained => Constrained,
7164 Any => Any));
7166 if Out_Present (Current_Parameter)
7167 and then not Is_Controlling_Formal
7168 then
7169 Append_To (After_Statements,
7170 Make_Assignment_Statement (Loc,
7171 Name =>
7172 New_Occurrence_Of (
7173 Defining_Identifier (Current_Parameter), Loc),
7174 Expression =>
7175 PolyORB_Support.Helpers.Build_From_Any_Call (
7176 Etype (Parameter_Type (Current_Parameter)),
7177 New_Occurrence_Of (Any, Loc),
7178 Decls)));
7180 end if;
7181 end;
7182 end if;
7184 -- If the current parameter has a dynamic constrained status,
7185 -- then this status is transmitted as well.
7186 -- This should be done for accessibility as well ???
7188 if Nkind (Parameter_Type (Current_Parameter))
7189 /= N_Access_Definition
7190 and then Need_Extra_Constrained (Current_Parameter)
7191 then
7192 -- In this block, we do not use the extra formal that has been
7193 -- created because it does not exist at the time of expansion
7194 -- when building calling stubs for remote access to subprogram
7195 -- types. We create an extra variable of this type and push it
7196 -- in the stream after the regular parameters.
7198 declare
7199 Extra_Any_Parameter : constant Entity_Id :=
7200 Make_Defining_Identifier
7201 (Loc, New_Internal_Name ('P'));
7203 begin
7204 Append_To (Decls,
7205 Make_Object_Declaration (Loc,
7206 Defining_Identifier =>
7207 Extra_Any_Parameter,
7208 Aliased_Present => False,
7209 Object_Definition =>
7210 New_Occurrence_Of (RTE (RE_Any), Loc),
7211 Expression =>
7212 PolyORB_Support.Helpers.Build_To_Any_Call (
7213 Make_Attribute_Reference (Loc,
7214 Prefix =>
7215 New_Occurrence_Of (
7216 Defining_Identifier (Current_Parameter), Loc),
7217 Attribute_Name => Name_Constrained),
7218 Decls)));
7219 Append_To (Extra_Formal_Statements,
7220 Add_Parameter_To_NVList (Loc,
7221 Parameter => Extra_Any_Parameter,
7222 NVList => Arguments,
7223 Constrained => True,
7224 Any => Extra_Any_Parameter));
7225 end;
7226 end if;
7228 Next (Current_Parameter);
7229 end loop;
7231 -- Append the formal statements list to the statements
7233 Append_List_To (Statements, Extra_Formal_Statements);
7235 Append_To (Statements,
7236 Make_Procedure_Call_Statement (Loc,
7237 Name =>
7238 New_Occurrence_Of (RTE (RE_Request_Create), Loc),
7239 Parameter_Associations => New_List (
7240 Target_Object,
7241 Subprogram_Id,
7242 New_Occurrence_Of (Arguments, Loc),
7243 New_Occurrence_Of (Result, Loc),
7244 New_Occurrence_Of (RTE (RE_Nil_Exc_List), Loc))));
7246 Append_To (Parameter_Associations (Last (Statements)),
7247 New_Occurrence_Of (Request, Loc));
7249 pragma Assert (
7250 not (Is_Known_Non_Asynchronous and Is_Known_Asynchronous));
7251 if Is_Known_Non_Asynchronous or Is_Known_Asynchronous then
7252 Asynchronous_P := New_Occurrence_Of (
7253 Boolean_Literals (Is_Known_Asynchronous), Loc);
7254 else
7255 pragma Assert (Present (Asynchronous));
7256 Asynchronous_P := New_Copy_Tree (Asynchronous);
7257 -- The expression node Asynchronous will be used to build
7258 -- an 'if' statement at the end of Build_General_Calling_Stubs:
7259 -- we need to make a copy here.
7260 end if;
7262 Append_To (Parameter_Associations (Last (Statements)),
7263 Make_Indexed_Component (Loc,
7264 Prefix =>
7265 New_Occurrence_Of (
7266 RTE (RE_Asynchronous_P_To_Sync_Scope), Loc),
7267 Expressions => New_List (Asynchronous_P)));
7269 Append_To (Statements,
7270 Make_Procedure_Call_Statement (Loc,
7271 Name =>
7272 New_Occurrence_Of (RTE (RE_Request_Invoke), Loc),
7273 Parameter_Associations => New_List (
7274 New_Occurrence_Of (Request, Loc))));
7276 Non_Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
7277 Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
7279 if not Is_Known_Asynchronous then
7281 -- Reraise an exception occurrence from the completed request.
7282 -- If the exception occurrence is empty, this is a no-op.
7284 Append_To (Non_Asynchronous_Statements,
7285 Make_Procedure_Call_Statement (Loc,
7286 Name =>
7287 New_Occurrence_Of (RTE (RE_Request_Raise_Occurrence), Loc),
7288 Parameter_Associations => New_List (
7289 New_Occurrence_Of (Request, Loc))));
7291 if Is_Function then
7293 -- If this is a function call, then read the value and
7294 -- return it.
7296 Append_To (Non_Asynchronous_Statements,
7297 Make_Tag_Check (Loc,
7298 Make_Return_Statement (Loc,
7299 PolyORB_Support.Helpers.Build_From_Any_Call (
7300 Etype (Result_Definition (Spec)),
7301 Make_Selected_Component (Loc,
7302 Prefix => Result,
7303 Selector_Name => Name_Argument),
7304 Decls))));
7305 end if;
7306 end if;
7308 Append_List_To (Non_Asynchronous_Statements,
7309 After_Statements);
7311 if Is_Known_Asynchronous then
7312 Append_List_To (Statements, Asynchronous_Statements);
7314 elsif Is_Known_Non_Asynchronous then
7315 Append_List_To (Statements, Non_Asynchronous_Statements);
7317 else
7318 pragma Assert (Present (Asynchronous));
7319 Append_To (Statements,
7320 Make_Implicit_If_Statement (Nod,
7321 Condition => Asynchronous,
7322 Then_Statements => Asynchronous_Statements,
7323 Else_Statements => Non_Asynchronous_Statements));
7324 end if;
7325 end Build_General_Calling_Stubs;
7327 -----------------------
7328 -- Build_Stub_Target --
7329 -----------------------
7331 function Build_Stub_Target
7332 (Loc : Source_Ptr;
7333 Decls : List_Id;
7334 RCI_Locator : Entity_Id;
7335 Controlling_Parameter : Entity_Id) return RPC_Target
7337 Target_Info : RPC_Target (PCS_Kind => Name_PolyORB_DSA);
7338 Target_Reference : constant Entity_Id :=
7339 Make_Defining_Identifier (Loc,
7340 New_Internal_Name ('T'));
7341 begin
7342 if Present (Controlling_Parameter) then
7343 Append_To (Decls,
7344 Make_Object_Declaration (Loc,
7345 Defining_Identifier => Target_Reference,
7346 Object_Definition =>
7347 New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
7348 Expression =>
7349 Make_Function_Call (Loc,
7350 Name =>
7351 New_Occurrence_Of (RTE (RE_Make_Ref), Loc),
7352 Parameter_Associations => New_List (
7353 Make_Selected_Component (Loc,
7354 Prefix => Controlling_Parameter,
7355 Selector_Name => Name_Target)))));
7356 -- Controlling_Parameter has the same components
7357 -- as System.Partition_Interface.RACW_Stub_Type.
7359 Target_Info.Object := New_Occurrence_Of (Target_Reference, Loc);
7361 else
7362 Target_Info.Object :=
7363 Make_Selected_Component (Loc,
7364 Prefix =>
7365 Make_Identifier (Loc, Chars (RCI_Locator)),
7366 Selector_Name =>
7367 Make_Identifier (Loc, Name_Get_RCI_Package_Ref));
7368 end if;
7369 return Target_Info;
7370 end Build_Stub_Target;
7372 ---------------------
7373 -- Build_Stub_Type --
7374 ---------------------
7376 procedure Build_Stub_Type
7377 (RACW_Type : Entity_Id;
7378 Stub_Type : Entity_Id;
7379 Stub_Type_Decl : out Node_Id;
7380 RPC_Receiver_Decl : out Node_Id)
7382 Loc : constant Source_Ptr := Sloc (Stub_Type);
7383 pragma Warnings (Off);
7384 pragma Unreferenced (RACW_Type);
7385 pragma Warnings (On);
7387 begin
7388 Stub_Type_Decl :=
7389 Make_Full_Type_Declaration (Loc,
7390 Defining_Identifier => Stub_Type,
7391 Type_Definition =>
7392 Make_Record_Definition (Loc,
7393 Tagged_Present => True,
7394 Limited_Present => True,
7395 Component_List =>
7396 Make_Component_List (Loc,
7397 Component_Items => New_List (
7399 Make_Component_Declaration (Loc,
7400 Defining_Identifier =>
7401 Make_Defining_Identifier (Loc, Name_Target),
7402 Component_Definition =>
7403 Make_Component_Definition (Loc,
7404 Aliased_Present =>
7405 False,
7406 Subtype_Indication =>
7407 New_Occurrence_Of (RTE (RE_Entity_Ptr), Loc))),
7409 Make_Component_Declaration (Loc,
7410 Defining_Identifier =>
7411 Make_Defining_Identifier (Loc, Name_Asynchronous),
7412 Component_Definition =>
7413 Make_Component_Definition (Loc,
7414 Aliased_Present => False,
7415 Subtype_Indication =>
7416 New_Occurrence_Of (
7417 Standard_Boolean, Loc)))))));
7419 RPC_Receiver_Decl :=
7420 Make_Object_Declaration (Loc,
7421 Defining_Identifier => Make_Defining_Identifier (Loc,
7422 New_Internal_Name ('R')),
7423 Aliased_Present => True,
7424 Object_Definition =>
7425 New_Occurrence_Of (RTE (RE_Servant), Loc));
7426 end Build_Stub_Type;
7428 -----------------------------
7429 -- Build_RPC_Receiver_Body --
7430 -----------------------------
7432 procedure Build_RPC_Receiver_Body
7433 (RPC_Receiver : Entity_Id;
7434 Request : out Entity_Id;
7435 Subp_Id : out Entity_Id;
7436 Subp_Index : out Entity_Id;
7437 Stmts : out List_Id;
7438 Decl : out Node_Id)
7440 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
7442 RPC_Receiver_Spec : Node_Id;
7443 RPC_Receiver_Decls : List_Id;
7445 begin
7446 Request := Make_Defining_Identifier (Loc, Name_R);
7448 RPC_Receiver_Spec :=
7449 Build_RPC_Receiver_Specification (
7450 RPC_Receiver => RPC_Receiver,
7451 Request_Parameter => Request);
7453 Subp_Id := Make_Defining_Identifier (Loc, Name_P);
7454 Subp_Index := Make_Defining_Identifier (Loc, Name_I);
7456 RPC_Receiver_Decls := New_List (
7457 Make_Object_Renaming_Declaration (Loc,
7458 Defining_Identifier => Subp_Id,
7459 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
7460 Name =>
7461 Make_Explicit_Dereference (Loc,
7462 Prefix =>
7463 Make_Selected_Component (Loc,
7464 Prefix => Request,
7465 Selector_Name => Name_Operation))),
7467 Make_Object_Declaration (Loc,
7468 Defining_Identifier => Subp_Index,
7469 Object_Definition =>
7470 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
7471 Expression =>
7472 Make_Attribute_Reference (Loc,
7473 Prefix =>
7474 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
7475 Attribute_Name => Name_Last)));
7477 Stmts := New_List;
7479 Decl :=
7480 Make_Subprogram_Body (Loc,
7481 Specification => RPC_Receiver_Spec,
7482 Declarations => RPC_Receiver_Decls,
7483 Handled_Statement_Sequence =>
7484 Make_Handled_Sequence_Of_Statements (Loc,
7485 Statements => Stmts));
7486 end Build_RPC_Receiver_Body;
7488 --------------------------------------
7489 -- Build_Subprogram_Receiving_Stubs --
7490 --------------------------------------
7492 function Build_Subprogram_Receiving_Stubs
7493 (Vis_Decl : Node_Id;
7494 Asynchronous : Boolean;
7495 Dynamically_Asynchronous : Boolean := False;
7496 Stub_Type : Entity_Id := Empty;
7497 RACW_Type : Entity_Id := Empty;
7498 Parent_Primitive : Entity_Id := Empty) return Node_Id
7500 Loc : constant Source_Ptr := Sloc (Vis_Decl);
7502 Request_Parameter : Node_Id;
7503 -- ???
7505 Outer_Decls : constant List_Id := New_List;
7506 -- At the outermost level, an NVList and Any's are
7507 -- declared for all parameters. The Dynamic_Async
7508 -- flag also needs to be declared there to be visible
7509 -- from the exception handling code.
7511 Outer_Statements : constant List_Id := New_List;
7512 -- Statements that occur prior to the declaration of the actual
7513 -- parameter variables.
7515 Decls : constant List_Id := New_List;
7516 -- All the parameters will get declared before calling the real
7517 -- subprograms. Also the out parameters will be declared.
7518 -- At this level, parameters may be unconstrained.
7520 Statements : constant List_Id := New_List;
7522 Extra_Formal_Statements : constant List_Id := New_List;
7523 -- Statements concerning extra formal parameters
7525 After_Statements : constant List_Id := New_List;
7526 -- Statements to be executed after the subprogram call
7528 Inner_Decls : List_Id := No_List;
7529 -- In case of a function, the inner declarations are needed since
7530 -- the result may be unconstrained.
7532 Excep_Handlers : List_Id := No_List;
7534 Parameter_List : constant List_Id := New_List;
7535 -- List of parameters to be passed to the subprogram
7537 First_Controlling_Formal_Seen : Boolean := False;
7539 Current_Parameter : Node_Id;
7541 Ordered_Parameters_List : constant List_Id :=
7542 Build_Ordered_Parameters_List
7543 (Specification (Vis_Decl));
7545 Arguments : Node_Id;
7546 -- Name of the named values list used to retrieve parameters
7548 Subp_Spec : Node_Id;
7549 -- Subprogram specification
7551 Called_Subprogram : Node_Id;
7552 -- The subprogram to call
7554 begin
7555 if Present (RACW_Type) then
7556 Called_Subprogram :=
7557 New_Occurrence_Of (Parent_Primitive, Loc);
7558 else
7559 Called_Subprogram :=
7560 New_Occurrence_Of (
7561 Defining_Unit_Name (Specification (Vis_Decl)), Loc);
7562 end if;
7564 Request_Parameter :=
7565 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
7567 Arguments :=
7568 Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
7569 Declare_Create_NVList (Loc, Arguments, Outer_Decls, Outer_Statements);
7571 -- Loop through every parameter and get its value from the stream. If
7572 -- the parameter is unconstrained, then the parameter is read using
7573 -- 'Input at the point of declaration.
7575 Current_Parameter := First (Ordered_Parameters_List);
7576 while Present (Current_Parameter) loop
7577 declare
7578 Etyp : Entity_Id;
7579 Constrained : Boolean;
7580 Any : Entity_Id := Empty;
7581 Object : constant Entity_Id :=
7582 Make_Defining_Identifier (Loc,
7583 New_Internal_Name ('P'));
7584 Expr : Node_Id := Empty;
7586 Is_Controlling_Formal : constant Boolean
7587 := Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type);
7589 Is_First_Controlling_Formal : Boolean := False;
7590 begin
7591 Set_Ekind (Object, E_Variable);
7593 if Is_Controlling_Formal then
7595 -- Controlling formals in distributed object primitive
7596 -- operations are handled specially:
7597 -- - the first controlling formal is used as the
7598 -- target of the call;
7599 -- - the remaining controlling formals are transmitted
7600 -- as RACWs.
7602 Etyp := RACW_Type;
7603 Is_First_Controlling_Formal :=
7604 not First_Controlling_Formal_Seen;
7605 First_Controlling_Formal_Seen := True;
7606 else
7607 Etyp := Etype (Parameter_Type (Current_Parameter));
7608 end if;
7610 Constrained :=
7611 Is_Constrained (Etyp)
7612 or else Is_Elementary_Type (Etyp);
7614 if not Is_First_Controlling_Formal then
7615 Any := Make_Defining_Identifier (Loc,
7616 New_Internal_Name ('A'));
7617 Append_To (Outer_Decls,
7618 Make_Object_Declaration (Loc,
7619 Defining_Identifier =>
7620 Any,
7621 Object_Definition =>
7622 New_Occurrence_Of (RTE (RE_Any), Loc),
7623 Expression =>
7624 Make_Function_Call (Loc,
7625 Name =>
7626 New_Occurrence_Of (RTE (RE_Create_Any), Loc),
7627 Parameter_Associations => New_List (
7628 PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
7629 Etyp, Outer_Decls)))));
7631 Append_To (Outer_Statements,
7632 Add_Parameter_To_NVList (Loc,
7633 Parameter => Current_Parameter,
7634 NVList => Arguments,
7635 Constrained => Constrained,
7636 Any => Any));
7637 end if;
7639 if Is_First_Controlling_Formal then
7640 declare
7641 Addr : constant Entity_Id :=
7642 Make_Defining_Identifier (Loc,
7643 New_Internal_Name ('A'));
7644 Is_Local : constant Entity_Id :=
7645 Make_Defining_Identifier (Loc,
7646 New_Internal_Name ('L'));
7647 begin
7649 -- Special case: obtain the first controlling
7650 -- formal from the target of the remote call,
7651 -- instead of the argument list.
7653 Append_To (Outer_Decls,
7654 Make_Object_Declaration (Loc,
7655 Defining_Identifier =>
7656 Addr,
7657 Object_Definition =>
7658 New_Occurrence_Of (RTE (RE_Address), Loc)));
7659 Append_To (Outer_Decls,
7660 Make_Object_Declaration (Loc,
7661 Defining_Identifier =>
7662 Is_Local,
7663 Object_Definition =>
7664 New_Occurrence_Of (Standard_Boolean, Loc)));
7665 Append_To (Outer_Statements,
7666 Make_Procedure_Call_Statement (Loc,
7667 Name =>
7668 New_Occurrence_Of (
7669 RTE (RE_Get_Local_Address), Loc),
7670 Parameter_Associations => New_List (
7671 Make_Selected_Component (Loc,
7672 Prefix =>
7673 New_Occurrence_Of (
7674 Request_Parameter, Loc),
7675 Selector_Name =>
7676 Make_Identifier (Loc, Name_Target)),
7677 New_Occurrence_Of (Is_Local, Loc),
7678 New_Occurrence_Of (Addr, Loc))));
7680 Expr := Unchecked_Convert_To (RACW_Type,
7681 New_Occurrence_Of (Addr, Loc));
7682 end;
7684 elsif In_Present (Current_Parameter)
7685 or else not Out_Present (Current_Parameter)
7686 or else not Constrained
7687 then
7688 -- If an input parameter is contrained, then its reading is
7689 -- deferred until the beginning of the subprogram body. If
7690 -- it is unconstrained, then an expression is built for
7691 -- the object declaration and the variable is set using
7692 -- 'Input instead of 'Read.
7694 Expr := PolyORB_Support.Helpers.Build_From_Any_Call (
7695 Etyp, New_Occurrence_Of (Any, Loc), Decls);
7697 if Constrained then
7699 Append_To (Statements,
7700 Make_Assignment_Statement (Loc,
7701 Name =>
7702 New_Occurrence_Of (Object, Loc),
7703 Expression =>
7704 Expr));
7705 Expr := Empty;
7706 else
7707 null;
7708 -- Expr will be used to initialize (and constrain)
7709 -- the parameter when it is declared.
7710 end if;
7712 end if;
7714 -- If we do not have to output the current parameter, then
7715 -- it can well be flagged as constant. This may allow further
7716 -- optimizations done by the back end.
7718 Append_To (Decls,
7719 Make_Object_Declaration (Loc,
7720 Defining_Identifier => Object,
7721 Constant_Present => not Constrained
7722 and then not Out_Present (Current_Parameter),
7723 Object_Definition =>
7724 New_Occurrence_Of (Etyp, Loc),
7725 Expression => Expr));
7726 Set_Etype (Object, Etyp);
7728 -- An out parameter may be written back using a 'Write
7729 -- attribute instead of a 'Output because it has been
7730 -- constrained by the parameter given to the caller. Note that
7731 -- out controlling arguments in the case of a RACW are not put
7732 -- back in the stream because the pointer on them has not
7733 -- changed.
7735 if Out_Present (Current_Parameter)
7736 and then not Is_Controlling_Formal
7737 then
7738 Append_To (After_Statements,
7739 Make_Procedure_Call_Statement (Loc,
7740 Name =>
7741 New_Occurrence_Of (RTE (RE_Copy_Any_Value), Loc),
7742 Parameter_Associations => New_List (
7743 New_Occurrence_Of (Any, Loc),
7744 PolyORB_Support.Helpers.Build_To_Any_Call (
7745 New_Occurrence_Of (Object, Loc),
7746 Decls))));
7747 end if;
7749 -- For RACW controlling formals, the Etyp of Object is always
7750 -- an RACW, even if the parameter is not of an anonymous access
7751 -- type. In such case, we need to dereference it at call time.
7753 if Is_Controlling_Formal then
7754 if Nkind (Parameter_Type (Current_Parameter)) /=
7755 N_Access_Definition
7756 then
7757 Append_To (Parameter_List,
7758 Make_Parameter_Association (Loc,
7759 Selector_Name =>
7760 New_Occurrence_Of (
7761 Defining_Identifier (Current_Parameter), Loc),
7762 Explicit_Actual_Parameter =>
7763 Make_Explicit_Dereference (Loc,
7764 Unchecked_Convert_To (RACW_Type,
7765 OK_Convert_To (RTE (RE_Address),
7766 New_Occurrence_Of (Object, Loc))))));
7768 else
7769 Append_To (Parameter_List,
7770 Make_Parameter_Association (Loc,
7771 Selector_Name =>
7772 New_Occurrence_Of (
7773 Defining_Identifier (Current_Parameter), Loc),
7774 Explicit_Actual_Parameter =>
7775 Unchecked_Convert_To (RACW_Type,
7776 OK_Convert_To (RTE (RE_Address),
7777 New_Occurrence_Of (Object, Loc)))));
7778 end if;
7780 else
7781 Append_To (Parameter_List,
7782 Make_Parameter_Association (Loc,
7783 Selector_Name =>
7784 New_Occurrence_Of (
7785 Defining_Identifier (Current_Parameter), Loc),
7786 Explicit_Actual_Parameter =>
7787 New_Occurrence_Of (Object, Loc)));
7788 end if;
7790 -- If the current parameter needs an extra formal, then read it
7791 -- from the stream and set the corresponding semantic field in
7792 -- the variable. If the kind of the parameter identifier is
7793 -- E_Void, then this is a compiler generated parameter that
7794 -- doesn't need an extra constrained status.
7796 -- The case of Extra_Accessibility should also be handled ???
7798 if Nkind (Parameter_Type (Current_Parameter)) /=
7799 N_Access_Definition
7800 and then
7801 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
7802 and then
7803 Present (Extra_Constrained
7804 (Defining_Identifier (Current_Parameter)))
7805 then
7806 declare
7807 Extra_Parameter : constant Entity_Id :=
7808 Extra_Constrained
7809 (Defining_Identifier
7810 (Current_Parameter));
7811 Extra_Any : constant Entity_Id :=
7812 Make_Defining_Identifier
7813 (Loc, New_Internal_Name ('A'));
7814 Formal_Entity : constant Entity_Id :=
7815 Make_Defining_Identifier
7816 (Loc, Chars (Extra_Parameter));
7818 Formal_Type : constant Entity_Id :=
7819 Etype (Extra_Parameter);
7820 begin
7821 Append_To (Outer_Decls,
7822 Make_Object_Declaration (Loc,
7823 Defining_Identifier =>
7824 Extra_Any,
7825 Object_Definition =>
7826 New_Occurrence_Of (RTE (RE_Any), Loc)));
7828 Append_To (Outer_Statements,
7829 Add_Parameter_To_NVList (Loc,
7830 Parameter => Extra_Parameter,
7831 NVList => Arguments,
7832 Constrained => True,
7833 Any => Extra_Any));
7835 Append_To (Decls,
7836 Make_Object_Declaration (Loc,
7837 Defining_Identifier => Formal_Entity,
7838 Object_Definition =>
7839 New_Occurrence_Of (Formal_Type, Loc)));
7841 Append_To (Extra_Formal_Statements,
7842 Make_Assignment_Statement (Loc,
7843 Name =>
7844 New_Occurrence_Of (Extra_Parameter, Loc),
7845 Expression =>
7846 PolyORB_Support.Helpers.Build_From_Any_Call (
7847 Etype (Extra_Parameter),
7848 New_Occurrence_Of (Extra_Any, Loc),
7849 Decls)));
7850 Set_Extra_Constrained (Object, Formal_Entity);
7852 end;
7853 end if;
7854 end;
7856 Next (Current_Parameter);
7857 end loop;
7859 Append_To (Outer_Statements,
7860 Make_Procedure_Call_Statement (Loc,
7861 Name =>
7862 New_Occurrence_Of (RTE (RE_Request_Arguments), Loc),
7863 Parameter_Associations => New_List (
7864 New_Occurrence_Of (Request_Parameter, Loc),
7865 New_Occurrence_Of (Arguments, Loc))));
7867 Append_List_To (Statements, Extra_Formal_Statements);
7869 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
7871 -- The remote subprogram is a function. We build an inner block to
7872 -- be able to hold a potentially unconstrained result in a
7873 -- variable.
7875 declare
7876 Etyp : constant Entity_Id :=
7877 Etype (Result_Definition (Specification (Vis_Decl)));
7878 Result : constant Node_Id :=
7879 Make_Defining_Identifier (Loc,
7880 New_Internal_Name ('R'));
7881 begin
7882 Inner_Decls := New_List (
7883 Make_Object_Declaration (Loc,
7884 Defining_Identifier => Result,
7885 Constant_Present => True,
7886 Object_Definition => New_Occurrence_Of (Etyp, Loc),
7887 Expression =>
7888 Make_Function_Call (Loc,
7889 Name => Called_Subprogram,
7890 Parameter_Associations => Parameter_List)));
7892 Set_Etype (Result, Etyp);
7893 Append_To (After_Statements,
7894 Make_Procedure_Call_Statement (Loc,
7895 Name =>
7896 New_Occurrence_Of (RTE (RE_Set_Result), Loc),
7897 Parameter_Associations => New_List (
7898 New_Occurrence_Of (Request_Parameter, Loc),
7899 PolyORB_Support.Helpers.Build_To_Any_Call (
7900 New_Occurrence_Of (Result, Loc),
7901 Decls))));
7902 -- A DSA function does not have out or inout arguments
7903 end;
7905 Append_To (Statements,
7906 Make_Block_Statement (Loc,
7907 Declarations => Inner_Decls,
7908 Handled_Statement_Sequence =>
7909 Make_Handled_Sequence_Of_Statements (Loc,
7910 Statements => After_Statements)));
7912 else
7913 -- The remote subprogram is a procedure. We do not need any inner
7914 -- block in this case. No specific processing is required here for
7915 -- the dynamically asynchronous case: the indication of whether
7916 -- call is asynchronous or not is managed by the Sync_Scope
7917 -- attibute of the request, and is handled entirely in the
7918 -- protocol layer.
7920 Append_To (After_Statements,
7921 Make_Procedure_Call_Statement (Loc,
7922 Name =>
7923 New_Occurrence_Of (RTE (RE_Request_Set_Out), Loc),
7924 Parameter_Associations => New_List (
7925 New_Occurrence_Of (Request_Parameter, Loc))));
7927 Append_To (Statements,
7928 Make_Procedure_Call_Statement (Loc,
7929 Name => Called_Subprogram,
7930 Parameter_Associations => Parameter_List));
7932 Append_List_To (Statements, After_Statements);
7933 end if;
7935 Subp_Spec :=
7936 Make_Procedure_Specification (Loc,
7937 Defining_Unit_Name =>
7938 Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
7940 Parameter_Specifications => New_List (
7941 Make_Parameter_Specification (Loc,
7942 Defining_Identifier => Request_Parameter,
7943 Parameter_Type =>
7944 New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
7946 -- An exception raised during the execution of an incoming
7947 -- remote subprogram call and that needs to be sent back
7948 -- to the caller is propagated by the receiving stubs, and
7949 -- will be handled by the caller (the distribution runtime).
7951 if Asynchronous and then not Dynamically_Asynchronous then
7953 -- For an asynchronous procedure, add a null exception handler
7955 Excep_Handlers := New_List (
7956 Make_Exception_Handler (Loc,
7957 Exception_Choices => New_List (Make_Others_Choice (Loc)),
7958 Statements => New_List (Make_Null_Statement (Loc))));
7960 else
7962 -- In the other cases, if an exception is raised, then the
7963 -- exception occurrence is propagated.
7965 null;
7966 end if;
7968 Append_To (Outer_Statements,
7969 Make_Block_Statement (Loc,
7970 Declarations =>
7971 Decls,
7972 Handled_Statement_Sequence =>
7973 Make_Handled_Sequence_Of_Statements (Loc,
7974 Statements => Statements)));
7976 return
7977 Make_Subprogram_Body (Loc,
7978 Specification => Subp_Spec,
7979 Declarations => Outer_Decls,
7980 Handled_Statement_Sequence =>
7981 Make_Handled_Sequence_Of_Statements (Loc,
7982 Statements => Outer_Statements,
7983 Exception_Handlers => Excep_Handlers));
7984 end Build_Subprogram_Receiving_Stubs;
7985 -------------
7986 -- Helpers --
7987 -------------
7989 package body Helpers is
7991 -----------------------
7992 -- Local Subprograms --
7993 -----------------------
7995 function Find_Numeric_Representation
7996 (Typ : Entity_Id) return Entity_Id;
7997 -- Given a numeric type Typ, return the smallest integer or floarting
7998 -- point type from Standard, or the smallest unsigned (modular) type
7999 -- from System.Unsigned_Types, whose range encompasses that of Typ.
8001 function Make_Stream_Procedure_Function_Name
8002 (Loc : Source_Ptr;
8003 Typ : Entity_Id;
8004 Nam : Name_Id) return Entity_Id;
8005 -- Return the name to be assigned for stream subprogram Nam of Typ.
8006 -- (copied from exp_strm.adb, should be shared???)
8008 ------------------------------------------------------------
8009 -- Common subprograms for building various tree fragments --
8010 ------------------------------------------------------------
8012 function Build_Get_Aggregate_Element
8013 (Loc : Source_Ptr;
8014 Any : Entity_Id;
8015 TC : Node_Id;
8016 Idx : Node_Id) return Node_Id;
8017 -- Build a call to Get_Aggregate_Element on Any
8018 -- for typecode TC, returning the Idx'th element.
8020 generic
8021 Subprogram : Entity_Id;
8022 -- Reference location for constructed nodes
8024 Arry : Entity_Id;
8025 -- For 'Range and Etype
8027 Indices : List_Id;
8028 -- For the construction of the innermost element expression
8030 with procedure Add_Process_Element
8031 (Stmts : List_Id;
8032 Any : Entity_Id;
8033 Counter : Entity_Id;
8034 Datum : Node_Id);
8036 procedure Append_Array_Traversal
8037 (Stmts : List_Id;
8038 Any : Entity_Id;
8039 Counter : Entity_Id := Empty;
8040 Depth : Pos := 1);
8041 -- Build nested loop statements that iterate over the elements of an
8042 -- array Arry. The statement(s) built by Add_Process_Element are
8043 -- executed for each element; Indices is the list of indices to be
8044 -- used in the construction of the indexed component that denotes the
8045 -- current element. Subprogram is the entity for the subprogram for
8046 -- which this iterator is generated. The generated statements are
8047 -- appended to Stmts.
8049 generic
8050 Rec : Entity_Id;
8051 -- The record entity being dealt with
8053 with procedure Add_Process_Element
8054 (Stmts : List_Id;
8055 Container : Node_Or_Entity_Id;
8056 Counter : in out Int;
8057 Rec : Entity_Id;
8058 Field : Node_Id);
8059 -- Rec is the instance of the record type, or Empty.
8060 -- Field is either the N_Defining_Identifier for a component,
8061 -- or an N_Variant_Part.
8063 procedure Append_Record_Traversal
8064 (Stmts : List_Id;
8065 Clist : Node_Id;
8066 Container : Node_Or_Entity_Id;
8067 Counter : in out Int);
8068 -- Process component list Clist. Individual fields are passed
8069 -- to Field_Processing. Each variant part is also processed.
8070 -- Container is the outer Any (for From_Any/To_Any),
8071 -- the outer typecode (for TC) to which the operation applies.
8073 -----------------------------
8074 -- Append_Record_Traversal --
8075 -----------------------------
8077 procedure Append_Record_Traversal
8078 (Stmts : List_Id;
8079 Clist : Node_Id;
8080 Container : Node_Or_Entity_Id;
8081 Counter : in out Int)
8083 CI : constant List_Id := Component_Items (Clist);
8084 VP : constant Node_Id := Variant_Part (Clist);
8086 Item : Node_Id := First (CI);
8087 Def : Entity_Id;
8089 begin
8090 while Present (Item) loop
8091 Def := Defining_Identifier (Item);
8092 if not Is_Internal_Name (Chars (Def)) then
8093 Add_Process_Element
8094 (Stmts, Container, Counter, Rec, Def);
8095 end if;
8096 Next (Item);
8097 end loop;
8099 if Present (VP) then
8100 Add_Process_Element (Stmts, Container, Counter, Rec, VP);
8101 end if;
8102 end Append_Record_Traversal;
8104 -------------------------
8105 -- Build_From_Any_Call --
8106 -------------------------
8108 function Build_From_Any_Call
8109 (Typ : Entity_Id;
8110 N : Node_Id;
8111 Decls : List_Id) return Node_Id
8113 Loc : constant Source_Ptr := Sloc (N);
8115 U_Type : Entity_Id := Underlying_Type (Typ);
8117 Fnam : Entity_Id := Empty;
8118 Lib_RE : RE_Id := RE_Null;
8120 begin
8122 -- First simple case where the From_Any function is present
8123 -- in the type's TSS.
8125 Fnam := Find_Inherited_TSS (U_Type, TSS_From_Any);
8127 if Sloc (U_Type) <= Standard_Location then
8128 U_Type := Base_Type (U_Type);
8129 end if;
8131 -- Check first for Boolean and Character. These are enumeration
8132 -- types, but we treat them specially, since they may require
8133 -- special handling in the transfer protocol. However, this
8134 -- special handling only applies if they have standard
8135 -- representation, otherwise they are treated like any other
8136 -- enumeration type.
8138 if Present (Fnam) then
8139 null;
8141 elsif U_Type = Standard_Boolean then
8142 Lib_RE := RE_FA_B;
8144 elsif U_Type = Standard_Character then
8145 Lib_RE := RE_FA_C;
8147 elsif U_Type = Standard_Wide_Character then
8148 Lib_RE := RE_FA_WC;
8150 elsif U_Type = Standard_Wide_Wide_Character then
8151 Lib_RE := RE_FA_WWC;
8153 -- Floating point types
8155 elsif U_Type = Standard_Short_Float then
8156 Lib_RE := RE_FA_SF;
8158 elsif U_Type = Standard_Float then
8159 Lib_RE := RE_FA_F;
8161 elsif U_Type = Standard_Long_Float then
8162 Lib_RE := RE_FA_LF;
8164 elsif U_Type = Standard_Long_Long_Float then
8165 Lib_RE := RE_FA_LLF;
8167 -- Integer types
8169 elsif U_Type = Etype (Standard_Short_Short_Integer) then
8170 Lib_RE := RE_FA_SSI;
8172 elsif U_Type = Etype (Standard_Short_Integer) then
8173 Lib_RE := RE_FA_SI;
8175 elsif U_Type = Etype (Standard_Integer) then
8176 Lib_RE := RE_FA_I;
8178 elsif U_Type = Etype (Standard_Long_Integer) then
8179 Lib_RE := RE_FA_LI;
8181 elsif U_Type = Etype (Standard_Long_Long_Integer) then
8182 Lib_RE := RE_FA_LLI;
8184 -- Unsigned integer types
8186 elsif U_Type = RTE (RE_Short_Short_Unsigned) then
8187 Lib_RE := RE_FA_SSU;
8189 elsif U_Type = RTE (RE_Short_Unsigned) then
8190 Lib_RE := RE_FA_SU;
8192 elsif U_Type = RTE (RE_Unsigned) then
8193 Lib_RE := RE_FA_U;
8195 elsif U_Type = RTE (RE_Long_Unsigned) then
8196 Lib_RE := RE_FA_LU;
8198 elsif U_Type = RTE (RE_Long_Long_Unsigned) then
8199 Lib_RE := RE_FA_LLU;
8201 elsif U_Type = Standard_String then
8202 Lib_RE := RE_FA_String;
8204 -- Other (non-primitive) types
8206 else
8207 declare
8208 Decl : Entity_Id;
8209 begin
8210 Build_From_Any_Function (Loc, U_Type, Decl, Fnam);
8211 Append_To (Decls, Decl);
8212 end;
8213 end if;
8215 -- Call the function
8217 if Lib_RE /= RE_Null then
8218 pragma Assert (No (Fnam));
8219 Fnam := RTE (Lib_RE);
8220 end if;
8222 return
8223 Make_Function_Call (Loc,
8224 Name => New_Occurrence_Of (Fnam, Loc),
8225 Parameter_Associations => New_List (N));
8226 end Build_From_Any_Call;
8228 -----------------------------
8229 -- Build_From_Any_Function --
8230 -----------------------------
8232 procedure Build_From_Any_Function
8233 (Loc : Source_Ptr;
8234 Typ : Entity_Id;
8235 Decl : out Node_Id;
8236 Fnam : out Entity_Id)
8238 Spec : Node_Id;
8239 Decls : constant List_Id := New_List;
8240 Stms : constant List_Id := New_List;
8241 Any_Parameter : constant Entity_Id
8242 := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
8243 begin
8244 Fnam := Make_Stream_Procedure_Function_Name (Loc,
8245 Typ, Name_uFrom_Any);
8247 Spec :=
8248 Make_Function_Specification (Loc,
8249 Defining_Unit_Name => Fnam,
8250 Parameter_Specifications => New_List (
8251 Make_Parameter_Specification (Loc,
8252 Defining_Identifier =>
8253 Any_Parameter,
8254 Parameter_Type =>
8255 New_Occurrence_Of (RTE (RE_Any), Loc))),
8256 Result_Definition => New_Occurrence_Of (Typ, Loc));
8258 -- The following is taken care of by Exp_Dist.Add_RACW_From_Any
8260 pragma Assert
8261 (not (Is_Remote_Access_To_Class_Wide_Type (Typ)));
8263 if Is_Derived_Type (Typ)
8264 and then not Is_Tagged_Type (Typ)
8265 then
8266 Append_To (Stms,
8267 Make_Return_Statement (Loc,
8268 Expression =>
8269 OK_Convert_To (
8270 Typ,
8271 Build_From_Any_Call (
8272 Root_Type (Typ),
8273 New_Occurrence_Of (Any_Parameter, Loc),
8274 Decls))));
8276 elsif Is_Record_Type (Typ)
8277 and then not Is_Derived_Type (Typ)
8278 and then not Is_Tagged_Type (Typ)
8279 then
8280 if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
8281 Append_To (Stms,
8282 Make_Return_Statement (Loc,
8283 Expression =>
8284 OK_Convert_To (
8285 Typ,
8286 Build_From_Any_Call (
8287 Etype (Typ),
8288 New_Occurrence_Of (Any_Parameter, Loc),
8289 Decls))));
8290 else
8291 declare
8292 Disc : Entity_Id := Empty;
8293 Discriminant_Associations : List_Id;
8294 Rdef : constant Node_Id :=
8295 Type_Definition (Declaration_Node (Typ));
8296 Component_Counter : Int := 0;
8298 -- The returned object
8300 Res : constant Entity_Id :=
8301 Make_Defining_Identifier (Loc,
8302 New_Internal_Name ('R'));
8304 Res_Definition : Node_Id := New_Occurrence_Of (Typ, Loc);
8306 procedure FA_Rec_Add_Process_Element
8307 (Stmts : List_Id;
8308 Any : Entity_Id;
8309 Counter : in out Int;
8310 Rec : Entity_Id;
8311 Field : Node_Id);
8313 procedure FA_Append_Record_Traversal is
8314 new Append_Record_Traversal
8315 (Rec => Res,
8316 Add_Process_Element => FA_Rec_Add_Process_Element);
8318 --------------------------------
8319 -- FA_Rec_Add_Process_Element --
8320 --------------------------------
8322 procedure FA_Rec_Add_Process_Element
8323 (Stmts : List_Id;
8324 Any : Entity_Id;
8325 Counter : in out Int;
8326 Rec : Entity_Id;
8327 Field : Node_Id)
8329 begin
8330 if Nkind (Field) = N_Defining_Identifier then
8332 -- A regular component
8334 Append_To (Stmts,
8335 Make_Assignment_Statement (Loc,
8336 Name => Make_Selected_Component (Loc,
8337 Prefix =>
8338 New_Occurrence_Of (Rec, Loc),
8339 Selector_Name =>
8340 New_Occurrence_Of (Field, Loc)),
8341 Expression =>
8342 Build_From_Any_Call (Etype (Field),
8343 Build_Get_Aggregate_Element (Loc,
8344 Any => Any,
8345 Tc => Build_TypeCode_Call (Loc,
8346 Etype (Field), Decls),
8347 Idx => Make_Integer_Literal (Loc,
8348 Counter)),
8349 Decls)));
8351 else
8352 -- A variant part
8354 declare
8355 Variant : Node_Id;
8356 Struct_Counter : Int := 0;
8358 Block_Decls : constant List_Id := New_List;
8359 Block_Stmts : constant List_Id := New_List;
8360 VP_Stmts : List_Id;
8362 Alt_List : constant List_Id := New_List;
8363 Choice_List : List_Id;
8365 Struct_Any : constant Entity_Id :=
8366 Make_Defining_Identifier (Loc,
8367 New_Internal_Name ('S'));
8369 begin
8370 Append_To (Decls,
8371 Make_Object_Declaration (Loc,
8372 Defining_Identifier =>
8373 Struct_Any,
8374 Constant_Present =>
8375 True,
8376 Object_Definition =>
8377 New_Occurrence_Of (RTE (RE_Any), Loc),
8378 Expression =>
8379 Make_Function_Call (Loc,
8380 Name => New_Occurrence_Of (
8381 RTE (RE_Extract_Union_Value), Loc),
8382 Parameter_Associations => New_List (
8383 Build_Get_Aggregate_Element (Loc,
8384 Any => Any,
8385 Tc => Make_Function_Call (Loc,
8386 Name => New_Occurrence_Of (
8387 RTE (RE_Any_Member_Type), Loc),
8388 Parameter_Associations =>
8389 New_List (
8390 New_Occurrence_Of (Any, Loc),
8391 Make_Integer_Literal (Loc,
8392 Counter))),
8393 Idx => Make_Integer_Literal (Loc,
8394 Counter))))));
8396 Append_To (Stmts,
8397 Make_Block_Statement (Loc,
8398 Declarations =>
8399 Block_Decls,
8400 Handled_Statement_Sequence =>
8401 Make_Handled_Sequence_Of_Statements (Loc,
8402 Statements => Block_Stmts)));
8404 Append_To (Block_Stmts,
8405 Make_Case_Statement (Loc,
8406 Expression =>
8407 Make_Selected_Component (Loc,
8408 Prefix => Rec,
8409 Selector_Name =>
8410 Chars (Name (Field))),
8411 Alternatives =>
8412 Alt_List));
8414 Variant := First_Non_Pragma (Variants (Field));
8416 while Present (Variant) loop
8417 Choice_List := New_Copy_List_Tree
8418 (Discrete_Choices (Variant));
8420 VP_Stmts := New_List;
8421 FA_Append_Record_Traversal (
8422 Stmts => VP_Stmts,
8423 Clist => Component_List (Variant),
8424 Container => Struct_Any,
8425 Counter => Struct_Counter);
8427 Append_To (Alt_List,
8428 Make_Case_Statement_Alternative (Loc,
8429 Discrete_Choices => Choice_List,
8430 Statements =>
8431 VP_Stmts));
8432 Next_Non_Pragma (Variant);
8433 end loop;
8434 end;
8435 end if;
8436 Counter := Counter + 1;
8437 end FA_Rec_Add_Process_Element;
8439 begin
8440 -- First all discriminants
8442 if Has_Discriminants (Typ) then
8443 Disc := First_Discriminant (Typ);
8444 Discriminant_Associations := New_List;
8446 while Present (Disc) loop
8447 declare
8448 Disc_Var_Name : constant Entity_Id :=
8449 Make_Defining_Identifier (Loc, Chars (Disc));
8450 Disc_Type : constant Entity_Id :=
8451 Etype (Disc);
8452 begin
8453 Append_To (Decls,
8454 Make_Object_Declaration (Loc,
8455 Defining_Identifier =>
8456 Disc_Var_Name,
8457 Constant_Present => True,
8458 Object_Definition =>
8459 New_Occurrence_Of (Disc_Type, Loc),
8460 Expression =>
8461 Build_From_Any_Call (Etype (Disc),
8462 Build_Get_Aggregate_Element (Loc,
8463 Any => Any_Parameter,
8464 Tc => Build_TypeCode_Call
8465 (Loc, Etype (Disc), Decls),
8466 Idx => Make_Integer_Literal
8467 (Loc, Component_Counter)),
8468 Decls)));
8469 Component_Counter := Component_Counter + 1;
8471 Append_To (Discriminant_Associations,
8472 Make_Discriminant_Association (Loc,
8473 Selector_Names => New_List (
8474 New_Occurrence_Of (Disc, Loc)),
8475 Expression =>
8476 New_Occurrence_Of (Disc_Var_Name, Loc)));
8477 end;
8478 Next_Discriminant (Disc);
8479 end loop;
8481 Res_Definition := Make_Subtype_Indication (Loc,
8482 Subtype_Mark => Res_Definition,
8483 Constraint =>
8484 Make_Index_Or_Discriminant_Constraint (Loc,
8485 Discriminant_Associations));
8486 end if;
8488 -- Now we have all the discriminants in variables, we can
8489 -- declared a constrained object. Note that we are not
8490 -- initializing (non-discriminant) components directly in
8491 -- the object declarations, because which fields to
8492 -- initialize depends (at run time) on the discriminant
8493 -- values.
8495 Append_To (Decls,
8496 Make_Object_Declaration (Loc,
8497 Defining_Identifier =>
8498 Res,
8499 Object_Definition =>
8500 Res_Definition));
8502 -- ... then all components
8504 FA_Append_Record_Traversal (Stms,
8505 Clist => Component_List (Rdef),
8506 Container => Any_Parameter,
8507 Counter => Component_Counter);
8509 Append_To (Stms,
8510 Make_Return_Statement (Loc,
8511 Expression => New_Occurrence_Of (Res, Loc)));
8512 end;
8513 end if;
8515 elsif Is_Array_Type (Typ) then
8516 declare
8517 Constrained : constant Boolean := Is_Constrained (Typ);
8519 procedure FA_Ary_Add_Process_Element
8520 (Stmts : List_Id;
8521 Any : Entity_Id;
8522 Counter : Entity_Id;
8523 Datum : Node_Id);
8524 -- Assign the current element (as identified by Counter) of
8525 -- Any to the variable denoted by name Datum, and advance
8526 -- Counter by 1. If Datum is not an Any, a call to From_Any
8527 -- for its type is inserted.
8529 --------------------------------
8530 -- FA_Ary_Add_Process_Element --
8531 --------------------------------
8533 procedure FA_Ary_Add_Process_Element
8534 (Stmts : List_Id;
8535 Any : Entity_Id;
8536 Counter : Entity_Id;
8537 Datum : Node_Id)
8539 Assignment : constant Node_Id :=
8540 Make_Assignment_Statement (Loc,
8541 Name => Datum,
8542 Expression => Empty);
8544 Element_Any : constant Node_Id :=
8545 Build_Get_Aggregate_Element (Loc,
8546 Any => Any,
8547 Tc => Build_TypeCode_Call (Loc,
8548 Etype (Datum), Decls),
8549 Idx => New_Occurrence_Of (Counter, Loc));
8551 begin
8552 -- Note: here we *prepend* statements to Stmts, so
8553 -- we must do it in reverse order.
8555 Prepend_To (Stmts,
8556 Make_Assignment_Statement (Loc,
8557 Name =>
8558 New_Occurrence_Of (Counter, Loc),
8559 Expression =>
8560 Make_Op_Add (Loc,
8561 Left_Opnd =>
8562 New_Occurrence_Of (Counter, Loc),
8563 Right_Opnd =>
8564 Make_Integer_Literal (Loc, 1))));
8566 if Nkind (Datum) /= N_Attribute_Reference then
8568 -- We ignore the value of the length of each
8569 -- dimension, since the target array has already
8570 -- been constrained anyway.
8572 if Etype (Datum) /= RTE (RE_Any) then
8573 Set_Expression (Assignment,
8574 Build_From_Any_Call (
8575 Component_Type (Typ),
8576 Element_Any,
8577 Decls));
8578 else
8579 Set_Expression (Assignment, Element_Any);
8580 end if;
8581 Prepend_To (Stmts, Assignment);
8582 end if;
8583 end FA_Ary_Add_Process_Element;
8585 Counter : constant Entity_Id :=
8586 Make_Defining_Identifier (Loc, Name_J);
8588 Initial_Counter_Value : Int := 0;
8590 Component_TC : constant Entity_Id :=
8591 Make_Defining_Identifier (Loc, Name_T);
8593 Res : constant Entity_Id :=
8594 Make_Defining_Identifier (Loc, Name_R);
8596 procedure Append_From_Any_Array_Iterator is
8597 new Append_Array_Traversal (
8598 Subprogram => Fnam,
8599 Arry => Res,
8600 Indices => New_List,
8601 Add_Process_Element => FA_Ary_Add_Process_Element);
8603 Res_Subtype_Indication : Node_Id :=
8604 New_Occurrence_Of (Typ, Loc);
8606 begin
8607 if not Constrained then
8608 declare
8609 Ndim : constant Int := Number_Dimensions (Typ);
8610 Lnam : Name_Id;
8611 Hnam : Name_Id;
8612 Indx : Node_Id := First_Index (Typ);
8613 Indt : Entity_Id;
8615 Ranges : constant List_Id := New_List;
8617 begin
8618 for J in 1 .. Ndim loop
8619 Lnam := New_External_Name ('L', J);
8620 Hnam := New_External_Name ('H', J);
8621 Indt := Etype (Indx);
8623 Append_To (Decls,
8624 Make_Object_Declaration (Loc,
8625 Defining_Identifier =>
8626 Make_Defining_Identifier (Loc, Lnam),
8627 Constant_Present =>
8628 True,
8629 Object_Definition =>
8630 New_Occurrence_Of (Indt, Loc),
8631 Expression =>
8632 Build_From_Any_Call (
8633 Indt,
8634 Build_Get_Aggregate_Element (Loc,
8635 Any => Any_Parameter,
8636 Tc => Build_TypeCode_Call (Loc,
8637 Indt, Decls),
8638 Idx => Make_Integer_Literal (Loc, J - 1)),
8639 Decls)));
8641 Append_To (Decls,
8642 Make_Object_Declaration (Loc,
8643 Defining_Identifier =>
8644 Make_Defining_Identifier (Loc, Hnam),
8645 Constant_Present =>
8646 True,
8647 Object_Definition =>
8648 New_Occurrence_Of (Indt, Loc),
8649 Expression => Make_Attribute_Reference (Loc,
8650 Prefix =>
8651 New_Occurrence_Of (Indt, Loc),
8652 Attribute_Name => Name_Val,
8653 Expressions => New_List (
8654 Make_Op_Subtract (Loc,
8655 Left_Opnd =>
8656 Make_Op_Add (Loc,
8657 Left_Opnd =>
8658 Make_Attribute_Reference (Loc,
8659 Prefix =>
8660 New_Occurrence_Of (Indt, Loc),
8661 Attribute_Name =>
8662 Name_Pos,
8663 Expressions => New_List (
8664 Make_Identifier (Loc, Lnam))),
8665 Right_Opnd =>
8666 Make_Function_Call (Loc,
8667 Name => New_Occurrence_Of (RTE (
8668 RE_Get_Nested_Sequence_Length),
8669 Loc),
8670 Parameter_Associations =>
8671 New_List (
8672 New_Occurrence_Of (
8673 Any_Parameter, Loc),
8674 Make_Integer_Literal (Loc,
8675 J)))),
8676 Right_Opnd =>
8677 Make_Integer_Literal (Loc, 1))))));
8679 Append_To (Ranges,
8680 Make_Range (Loc,
8681 Low_Bound => Make_Identifier (Loc, Lnam),
8682 High_Bound => Make_Identifier (Loc, Hnam)));
8684 Next_Index (Indx);
8685 end loop;
8687 -- Now we have all the necessary bound information:
8688 -- apply the set of range constraints to the
8689 -- (unconstrained) nominal subtype of Res.
8691 Initial_Counter_Value := Ndim;
8692 Res_Subtype_Indication := Make_Subtype_Indication (Loc,
8693 Subtype_Mark =>
8694 Res_Subtype_Indication,
8695 Constraint =>
8696 Make_Index_Or_Discriminant_Constraint (Loc,
8697 Constraints => Ranges));
8698 end;
8699 end if;
8701 Append_To (Decls,
8702 Make_Object_Declaration (Loc,
8703 Defining_Identifier => Res,
8704 Object_Definition => Res_Subtype_Indication));
8705 Set_Etype (Res, Typ);
8707 Append_To (Decls,
8708 Make_Object_Declaration (Loc,
8709 Defining_Identifier => Counter,
8710 Object_Definition =>
8711 New_Occurrence_Of (RTE (RE_Long_Unsigned), Loc),
8712 Expression =>
8713 Make_Integer_Literal (Loc, Initial_Counter_Value)));
8715 Append_To (Decls,
8716 Make_Object_Declaration (Loc,
8717 Defining_Identifier => Component_TC,
8718 Constant_Present => True,
8719 Object_Definition =>
8720 New_Occurrence_Of (RTE (RE_TypeCode), Loc),
8721 Expression =>
8722 Build_TypeCode_Call (Loc,
8723 Component_Type (Typ), Decls)));
8725 Append_From_Any_Array_Iterator (Stms,
8726 Any_Parameter, Counter);
8728 Append_To (Stms,
8729 Make_Return_Statement (Loc,
8730 Expression => New_Occurrence_Of (Res, Loc)));
8731 end;
8733 elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
8734 Append_To (Stms,
8735 Make_Return_Statement (Loc,
8736 Expression =>
8737 Unchecked_Convert_To (
8738 Typ,
8739 Build_From_Any_Call (
8740 Find_Numeric_Representation (Typ),
8741 New_Occurrence_Of (Any_Parameter, Loc),
8742 Decls))));
8744 else
8745 -- Default: type is represented as an opaque sequence of bytes
8747 declare
8748 Strm : constant Entity_Id :=
8749 Make_Defining_Identifier (Loc,
8750 Chars => New_Internal_Name ('S'));
8751 Res : constant Entity_Id :=
8752 Make_Defining_Identifier (Loc,
8753 Chars => New_Internal_Name ('R'));
8755 begin
8756 -- Strm : Buffer_Stream_Type;
8758 Append_To (Decls,
8759 Make_Object_Declaration (Loc,
8760 Defining_Identifier =>
8761 Strm,
8762 Aliased_Present =>
8763 True,
8764 Object_Definition =>
8765 New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
8767 -- Any_To_BS (Strm, A);
8769 Append_To (Stms,
8770 Make_Procedure_Call_Statement (Loc,
8771 Name =>
8772 New_Occurrence_Of (RTE (RE_Any_To_BS), Loc),
8773 Parameter_Associations => New_List (
8774 New_Occurrence_Of (Any_Parameter, Loc),
8775 New_Occurrence_Of (Strm, Loc))));
8777 -- declare
8778 -- Res : constant T := T'Input (Strm);
8779 -- begin
8780 -- Release_Buffer (Strm);
8781 -- return Res;
8782 -- end;
8784 Append_To (Stms, Make_Block_Statement (Loc,
8785 Declarations => New_List (
8786 Make_Object_Declaration (Loc,
8787 Defining_Identifier => Res,
8788 Constant_Present => True,
8789 Object_Definition =>
8790 New_Occurrence_Of (Typ, Loc),
8791 Expression =>
8792 Make_Attribute_Reference (Loc,
8793 Prefix => New_Occurrence_Of (Typ, Loc),
8794 Attribute_Name => Name_Input,
8795 Expressions => New_List (
8796 Make_Attribute_Reference (Loc,
8797 Prefix => New_Occurrence_Of (Strm, Loc),
8798 Attribute_Name => Name_Access))))),
8800 Handled_Statement_Sequence =>
8801 Make_Handled_Sequence_Of_Statements (Loc,
8802 Statements => New_List (
8803 Make_Procedure_Call_Statement (Loc,
8804 Name =>
8805 New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
8806 Parameter_Associations =>
8807 New_List (
8808 New_Occurrence_Of (Strm, Loc))),
8809 Make_Return_Statement (Loc,
8810 Expression => New_Occurrence_Of (Res, Loc))))));
8812 end;
8813 end if;
8815 Decl :=
8816 Make_Subprogram_Body (Loc,
8817 Specification => Spec,
8818 Declarations => Decls,
8819 Handled_Statement_Sequence =>
8820 Make_Handled_Sequence_Of_Statements (Loc,
8821 Statements => Stms));
8822 end Build_From_Any_Function;
8824 ---------------------------------
8825 -- Build_Get_Aggregate_Element --
8826 ---------------------------------
8828 function Build_Get_Aggregate_Element
8829 (Loc : Source_Ptr;
8830 Any : Entity_Id;
8831 TC : Node_Id;
8832 Idx : Node_Id) return Node_Id
8834 begin
8835 return Make_Function_Call (Loc,
8836 Name =>
8837 New_Occurrence_Of (
8838 RTE (RE_Get_Aggregate_Element), Loc),
8839 Parameter_Associations => New_List (
8840 New_Occurrence_Of (Any, Loc),
8842 Idx));
8843 end Build_Get_Aggregate_Element;
8845 -------------------------
8846 -- Build_Reposiroty_Id --
8847 -------------------------
8849 procedure Build_Name_And_Repository_Id
8850 (E : Entity_Id;
8851 Name_Str : out String_Id;
8852 Repo_Id_Str : out String_Id)
8854 begin
8855 Start_String;
8856 Store_String_Chars ("DSA:");
8857 Get_Library_Unit_Name_String (Scope (E));
8858 Store_String_Chars (
8859 Name_Buffer (Name_Buffer'First
8860 .. Name_Buffer'First + Name_Len - 1));
8861 Store_String_Char ('.');
8862 Get_Name_String (Chars (E));
8863 Store_String_Chars (
8864 Name_Buffer (Name_Buffer'First
8865 .. Name_Buffer'First + Name_Len - 1));
8866 Store_String_Chars (":1.0");
8867 Repo_Id_Str := End_String;
8868 Name_Str := String_From_Name_Buffer;
8869 end Build_Name_And_Repository_Id;
8871 -----------------------
8872 -- Build_To_Any_Call --
8873 -----------------------
8875 function Build_To_Any_Call
8876 (N : Node_Id;
8877 Decls : List_Id) return Node_Id
8879 Loc : constant Source_Ptr := Sloc (N);
8881 Typ : Entity_Id := Etype (N);
8882 U_Type : Entity_Id;
8884 Fnam : Entity_Id := Empty;
8885 Lib_RE : RE_Id := RE_Null;
8887 begin
8888 -- If N is a selected component, then maybe its Etype
8889 -- has not been set yet: try to use the Etype of the
8890 -- selector_name in that case.
8892 if No (Typ) and then Nkind (N) = N_Selected_Component then
8893 Typ := Etype (Selector_Name (N));
8894 end if;
8895 pragma Assert (Present (Typ));
8897 -- The full view, if Typ is private; the completion,
8898 -- if Typ is incomplete.
8900 U_Type := Underlying_Type (Typ);
8902 -- First simple case where the To_Any function is present
8903 -- in the type's TSS.
8905 Fnam := Find_Inherited_TSS (U_Type, TSS_To_Any);
8907 -- Check first for Boolean and Character. These are enumeration
8908 -- types, but we treat them specially, since they may require
8909 -- special handling in the transfer protocol. However, this
8910 -- special handling only applies if they have standard
8911 -- representation, otherwise they are treated like any other
8912 -- enumeration type.
8914 if Sloc (U_Type) <= Standard_Location then
8915 U_Type := Base_Type (U_Type);
8916 end if;
8918 if Present (Fnam) then
8919 null;
8921 elsif U_Type = Standard_Boolean then
8922 Lib_RE := RE_TA_B;
8924 elsif U_Type = Standard_Character then
8925 Lib_RE := RE_TA_C;
8927 elsif U_Type = Standard_Wide_Character then
8928 Lib_RE := RE_TA_WC;
8930 elsif U_Type = Standard_Wide_Wide_Character then
8931 Lib_RE := RE_TA_WWC;
8933 -- Floating point types
8935 elsif U_Type = Standard_Short_Float then
8936 Lib_RE := RE_TA_SF;
8938 elsif U_Type = Standard_Float then
8939 Lib_RE := RE_TA_F;
8941 elsif U_Type = Standard_Long_Float then
8942 Lib_RE := RE_TA_LF;
8944 elsif U_Type = Standard_Long_Long_Float then
8945 Lib_RE := RE_TA_LLF;
8947 -- Integer types
8949 elsif U_Type = Etype (Standard_Short_Short_Integer) then
8950 Lib_RE := RE_TA_SSI;
8952 elsif U_Type = Etype (Standard_Short_Integer) then
8953 Lib_RE := RE_TA_SI;
8955 elsif U_Type = Etype (Standard_Integer) then
8956 Lib_RE := RE_TA_I;
8958 elsif U_Type = Etype (Standard_Long_Integer) then
8959 Lib_RE := RE_TA_LI;
8961 elsif U_Type = Etype (Standard_Long_Long_Integer) then
8962 Lib_RE := RE_TA_LLI;
8964 -- Unsigned integer types
8966 elsif U_Type = RTE (RE_Short_Short_Unsigned) then
8967 Lib_RE := RE_TA_SSU;
8969 elsif U_Type = RTE (RE_Short_Unsigned) then
8970 Lib_RE := RE_TA_SU;
8972 elsif U_Type = RTE (RE_Unsigned) then
8973 Lib_RE := RE_TA_U;
8975 elsif U_Type = RTE (RE_Long_Unsigned) then
8976 Lib_RE := RE_TA_LU;
8978 elsif U_Type = RTE (RE_Long_Long_Unsigned) then
8979 Lib_RE := RE_TA_LLU;
8981 elsif U_Type = Standard_String then
8982 Lib_RE := RE_TA_String;
8984 elsif U_Type = Underlying_Type (RTE (RE_TypeCode)) then
8985 Lib_RE := RE_TA_TC;
8987 -- Other (non-primitive) types
8989 else
8990 declare
8991 Decl : Entity_Id;
8992 begin
8993 Build_To_Any_Function (Loc, U_Type, Decl, Fnam);
8994 Append_To (Decls, Decl);
8995 end;
8996 end if;
8998 -- Call the function
9000 if Lib_RE /= RE_Null then
9001 pragma Assert (No (Fnam));
9002 Fnam := RTE (Lib_RE);
9003 end if;
9005 return
9006 Make_Function_Call (Loc,
9007 Name => New_Occurrence_Of (Fnam, Loc),
9008 Parameter_Associations => New_List (N));
9009 end Build_To_Any_Call;
9011 ---------------------------
9012 -- Build_To_Any_Function --
9013 ---------------------------
9015 procedure Build_To_Any_Function
9016 (Loc : Source_Ptr;
9017 Typ : Entity_Id;
9018 Decl : out Node_Id;
9019 Fnam : out Entity_Id)
9021 Spec : Node_Id;
9022 Decls : constant List_Id := New_List;
9023 Stms : constant List_Id := New_List;
9025 Expr_Parameter : constant Entity_Id :=
9026 Make_Defining_Identifier (Loc, Name_E);
9028 Any : constant Entity_Id :=
9029 Make_Defining_Identifier (Loc, Name_A);
9031 Any_Decl : Node_Id;
9032 Result_TC : Node_Id := Build_TypeCode_Call (Loc, Typ, Decls);
9034 begin
9035 Fnam := Make_Stream_Procedure_Function_Name (Loc,
9036 Typ, Name_uTo_Any);
9038 Spec :=
9039 Make_Function_Specification (Loc,
9040 Defining_Unit_Name => Fnam,
9041 Parameter_Specifications => New_List (
9042 Make_Parameter_Specification (Loc,
9043 Defining_Identifier =>
9044 Expr_Parameter,
9045 Parameter_Type =>
9046 New_Occurrence_Of (Typ, Loc))),
9047 Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
9048 Set_Etype (Expr_Parameter, Typ);
9050 Any_Decl :=
9051 Make_Object_Declaration (Loc,
9052 Defining_Identifier =>
9053 Any,
9054 Object_Definition =>
9055 New_Occurrence_Of (RTE (RE_Any), Loc));
9057 if Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
9058 declare
9059 Rt_Type : constant Entity_Id
9060 := Root_Type (Typ);
9061 Expr : constant Node_Id
9062 := OK_Convert_To (
9063 Rt_Type,
9064 New_Occurrence_Of (Expr_Parameter, Loc));
9065 begin
9066 Set_Expression (Any_Decl, Build_To_Any_Call (Expr, Decls));
9067 end;
9069 elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then
9070 if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
9071 declare
9072 Rt_Type : constant Entity_Id
9073 := Etype (Typ);
9074 Expr : constant Node_Id
9075 := OK_Convert_To (
9076 Rt_Type,
9077 New_Occurrence_Of (Expr_Parameter, Loc));
9079 begin
9080 Set_Expression (Any_Decl,
9081 Build_To_Any_Call (Expr, Decls));
9082 end;
9084 else
9085 declare
9086 Disc : Entity_Id := Empty;
9087 Rdef : constant Node_Id :=
9088 Type_Definition (Declaration_Node (Typ));
9089 Counter : Int := 0;
9090 Elements : constant List_Id := New_List;
9092 procedure TA_Rec_Add_Process_Element
9093 (Stmts : List_Id;
9094 Container : Node_Or_Entity_Id;
9095 Counter : in out Int;
9096 Rec : Entity_Id;
9097 Field : Node_Id);
9099 procedure TA_Append_Record_Traversal is
9100 new Append_Record_Traversal
9101 (Rec => Expr_Parameter,
9102 Add_Process_Element => TA_Rec_Add_Process_Element);
9104 --------------------------------
9105 -- TA_Rec_Add_Process_Element --
9106 --------------------------------
9108 procedure TA_Rec_Add_Process_Element
9109 (Stmts : List_Id;
9110 Container : Node_Or_Entity_Id;
9111 Counter : in out Int;
9112 Rec : Entity_Id;
9113 Field : Node_Id)
9115 Field_Ref : Node_Id;
9117 begin
9118 if Nkind (Field) = N_Defining_Identifier then
9120 -- A regular component
9122 Field_Ref := Make_Selected_Component (Loc,
9123 Prefix => New_Occurrence_Of (Rec, Loc),
9124 Selector_Name => New_Occurrence_Of (Field, Loc));
9125 Set_Etype (Field_Ref, Etype (Field));
9127 Append_To (Stmts,
9128 Make_Procedure_Call_Statement (Loc,
9129 Name =>
9130 New_Occurrence_Of (
9131 RTE (RE_Add_Aggregate_Element), Loc),
9132 Parameter_Associations => New_List (
9133 New_Occurrence_Of (Any, Loc),
9134 Build_To_Any_Call (Field_Ref, Decls))));
9136 else
9137 -- A variant part
9139 declare
9140 Variant : Node_Id;
9141 Struct_Counter : Int := 0;
9143 Block_Decls : constant List_Id := New_List;
9144 Block_Stmts : constant List_Id := New_List;
9145 VP_Stmts : List_Id;
9147 Alt_List : constant List_Id := New_List;
9148 Choice_List : List_Id;
9150 Union_Any : constant Entity_Id :=
9151 Make_Defining_Identifier (Loc,
9152 New_Internal_Name ('U'));
9154 Struct_Any : constant Entity_Id :=
9155 Make_Defining_Identifier (Loc,
9156 New_Internal_Name ('S'));
9158 function Make_Discriminant_Reference
9159 return Node_Id;
9160 -- Build a selected component for the
9161 -- discriminant of this variant part.
9163 ---------------------------------
9164 -- Make_Discriminant_Reference --
9165 ---------------------------------
9167 function Make_Discriminant_Reference
9168 return Node_Id
9170 Nod : constant Node_Id :=
9171 Make_Selected_Component (Loc,
9172 Prefix => Rec,
9173 Selector_Name =>
9174 Chars (Name (Field)));
9175 begin
9176 Set_Etype (Nod, Name (Field));
9177 return Nod;
9178 end Make_Discriminant_Reference;
9180 begin
9181 Append_To (Stmts,
9182 Make_Block_Statement (Loc,
9183 Declarations =>
9184 Block_Decls,
9185 Handled_Statement_Sequence =>
9186 Make_Handled_Sequence_Of_Statements (Loc,
9187 Statements => Block_Stmts)));
9189 Append_To (Block_Decls,
9190 Make_Object_Declaration (Loc,
9191 Defining_Identifier => Union_Any,
9192 Object_Definition =>
9193 New_Occurrence_Of (RTE (RE_Any), Loc),
9194 Expression =>
9195 Make_Function_Call (Loc,
9196 Name => New_Occurrence_Of (
9197 RTE (RE_Create_Any), Loc),
9198 Parameter_Associations => New_List (
9199 Make_Function_Call (Loc,
9200 Name =>
9201 New_Occurrence_Of (
9202 RTE (RE_Any_Member_Type), Loc),
9203 Parameter_Associations => New_List (
9204 New_Occurrence_Of (Container, Loc),
9205 Make_Integer_Literal (Loc,
9206 Counter)))))));
9208 Append_To (Block_Decls,
9209 Make_Object_Declaration (Loc,
9210 Defining_Identifier => Struct_Any,
9211 Object_Definition =>
9212 New_Occurrence_Of (RTE (RE_Any), Loc),
9213 Expression =>
9214 Make_Function_Call (Loc,
9215 Name => New_Occurrence_Of (
9216 RTE (RE_Create_Any), Loc),
9217 Parameter_Associations => New_List (
9218 Make_Function_Call (Loc,
9219 Name =>
9220 New_Occurrence_Of (
9221 RTE (RE_Any_Member_Type), Loc),
9222 Parameter_Associations => New_List (
9223 New_Occurrence_Of (Union_Any, Loc),
9224 Make_Integer_Literal (Loc,
9225 Uint_0)))))));
9227 Append_To (Block_Stmts,
9228 Make_Case_Statement (Loc,
9229 Expression =>
9230 Make_Discriminant_Reference,
9231 Alternatives =>
9232 Alt_List));
9234 Variant := First_Non_Pragma (Variants (Field));
9235 while Present (Variant) loop
9236 Choice_List := New_Copy_List_Tree
9237 (Discrete_Choices (Variant));
9239 VP_Stmts := New_List;
9240 TA_Append_Record_Traversal (
9241 Stmts => VP_Stmts,
9242 Clist => Component_List (Variant),
9243 Container => Struct_Any,
9244 Counter => Struct_Counter);
9246 -- Append discriminant value and inner struct
9247 -- to union aggregate.
9249 Append_To (VP_Stmts,
9250 Make_Procedure_Call_Statement (Loc,
9251 Name =>
9252 New_Occurrence_Of (
9253 RTE (RE_Add_Aggregate_Element), Loc),
9254 Parameter_Associations => New_List (
9255 New_Occurrence_Of (Union_Any, Loc),
9256 Build_To_Any_Call (
9257 Make_Discriminant_Reference,
9258 Block_Decls))));
9260 Append_To (VP_Stmts,
9261 Make_Procedure_Call_Statement (Loc,
9262 Name =>
9263 New_Occurrence_Of (
9264 RTE (RE_Add_Aggregate_Element), Loc),
9265 Parameter_Associations => New_List (
9266 New_Occurrence_Of (Union_Any, Loc),
9267 New_Occurrence_Of (Struct_Any, Loc))));
9269 -- Append union to outer aggregate
9271 Append_To (VP_Stmts,
9272 Make_Procedure_Call_Statement (Loc,
9273 Name =>
9274 New_Occurrence_Of (
9275 RTE (RE_Add_Aggregate_Element), Loc),
9276 Parameter_Associations => New_List (
9277 New_Occurrence_Of (Container, Loc),
9278 Make_Function_Call (Loc,
9279 Name => New_Occurrence_Of (
9280 RTE (RE_Any_Aggregate_Build), Loc),
9281 Parameter_Associations => New_List (
9282 New_Occurrence_Of (
9283 Union_Any, Loc))))));
9285 Append_To (Alt_List,
9286 Make_Case_Statement_Alternative (Loc,
9287 Discrete_Choices => Choice_List,
9288 Statements =>
9289 VP_Stmts));
9290 Next_Non_Pragma (Variant);
9291 end loop;
9292 end;
9293 end if;
9294 end TA_Rec_Add_Process_Element;
9296 begin
9297 -- First all discriminants
9299 if Has_Discriminants (Typ) then
9300 Disc := First_Discriminant (Typ);
9302 while Present (Disc) loop
9303 Append_To (Elements,
9304 Make_Component_Association (Loc,
9305 Choices => New_List (
9306 Make_Integer_Literal (Loc, Counter)),
9307 Expression =>
9308 Build_To_Any_Call (
9309 Make_Selected_Component (Loc,
9310 Prefix => Expr_Parameter,
9311 Selector_Name => Chars (Disc)),
9312 Decls)));
9313 Counter := Counter + 1;
9314 Next_Discriminant (Disc);
9315 end loop;
9317 else
9318 -- Make elements an empty array
9320 declare
9321 Dummy_Any : constant Entity_Id :=
9322 Make_Defining_Identifier (Loc,
9323 Chars => New_Internal_Name ('A'));
9325 begin
9326 Append_To (Decls,
9327 Make_Object_Declaration (Loc,
9328 Defining_Identifier => Dummy_Any,
9329 Object_Definition =>
9330 New_Occurrence_Of (RTE (RE_Any), Loc)));
9332 Append_To (Elements,
9333 Make_Component_Association (Loc,
9334 Choices => New_List (
9335 Make_Range (Loc,
9336 Low_Bound =>
9337 Make_Integer_Literal (Loc, 1),
9338 High_Bound =>
9339 Make_Integer_Literal (Loc, 0))),
9340 Expression =>
9341 New_Occurrence_Of (Dummy_Any, Loc)));
9342 end;
9343 end if;
9345 Set_Expression (Any_Decl,
9346 Make_Function_Call (Loc,
9347 Name => New_Occurrence_Of (
9348 RTE (RE_Any_Aggregate_Build), Loc),
9349 Parameter_Associations => New_List (
9350 Result_TC,
9351 Make_Aggregate (Loc,
9352 Component_Associations => Elements))));
9353 Result_TC := Empty;
9355 -- ... then all components
9357 TA_Append_Record_Traversal (Stms,
9358 Clist => Component_List (Rdef),
9359 Container => Any,
9360 Counter => Counter);
9361 end;
9362 end if;
9364 elsif Is_Array_Type (Typ) then
9365 declare
9366 Constrained : constant Boolean := Is_Constrained (Typ);
9368 procedure TA_Ary_Add_Process_Element
9369 (Stmts : List_Id;
9370 Any : Entity_Id;
9371 Counter : Entity_Id;
9372 Datum : Node_Id);
9374 --------------------------------
9375 -- TA_Ary_Add_Process_Element --
9376 --------------------------------
9378 procedure TA_Ary_Add_Process_Element
9379 (Stmts : List_Id;
9380 Any : Entity_Id;
9381 Counter : Entity_Id;
9382 Datum : Node_Id)
9384 pragma Warnings (Off);
9385 pragma Unreferenced (Counter);
9386 pragma Warnings (On);
9388 Element_Any : Node_Id;
9390 begin
9391 if Etype (Datum) = RTE (RE_Any) then
9392 Element_Any := Datum;
9393 else
9394 Element_Any := Build_To_Any_Call (Datum, Decls);
9395 end if;
9397 Append_To (Stmts,
9398 Make_Procedure_Call_Statement (Loc,
9399 Name => New_Occurrence_Of (
9400 RTE (RE_Add_Aggregate_Element), Loc),
9401 Parameter_Associations => New_List (
9402 New_Occurrence_Of (Any, Loc),
9403 Element_Any)));
9404 end TA_Ary_Add_Process_Element;
9406 procedure Append_To_Any_Array_Iterator is
9407 new Append_Array_Traversal (
9408 Subprogram => Fnam,
9409 Arry => Expr_Parameter,
9410 Indices => New_List,
9411 Add_Process_Element => TA_Ary_Add_Process_Element);
9413 Index : Node_Id;
9415 begin
9416 Set_Expression (Any_Decl,
9417 Make_Function_Call (Loc,
9418 Name =>
9419 New_Occurrence_Of (RTE (RE_Create_Any), Loc),
9420 Parameter_Associations => New_List (Result_TC)));
9421 Result_TC := Empty;
9423 if not Constrained then
9424 Index := First_Index (Typ);
9425 for J in 1 .. Number_Dimensions (Typ) loop
9426 Append_To (Stms,
9427 Make_Procedure_Call_Statement (Loc,
9428 Name =>
9429 New_Occurrence_Of (
9430 RTE (RE_Add_Aggregate_Element), Loc),
9431 Parameter_Associations => New_List (
9432 New_Occurrence_Of (Any, Loc),
9433 Build_To_Any_Call (
9434 OK_Convert_To (Etype (Index),
9435 Make_Attribute_Reference (Loc,
9436 Prefix =>
9437 New_Occurrence_Of (Expr_Parameter, Loc),
9438 Attribute_Name => Name_First,
9439 Expressions => New_List (
9440 Make_Integer_Literal (Loc, J)))),
9441 Decls))));
9442 Next_Index (Index);
9443 end loop;
9444 end if;
9446 Append_To_Any_Array_Iterator (Stms, Any);
9447 end;
9449 elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
9450 Set_Expression (Any_Decl,
9451 Build_To_Any_Call (
9452 OK_Convert_To (
9453 Find_Numeric_Representation (Typ),
9454 New_Occurrence_Of (Expr_Parameter, Loc)),
9455 Decls));
9457 else
9458 -- Default: type is represented as an opaque sequence of bytes
9460 declare
9461 Strm : constant Entity_Id := Make_Defining_Identifier (Loc,
9462 New_Internal_Name ('S'));
9464 begin
9465 -- Strm : aliased Buffer_Stream_Type;
9467 Append_To (Decls,
9468 Make_Object_Declaration (Loc,
9469 Defining_Identifier =>
9470 Strm,
9471 Aliased_Present =>
9472 True,
9473 Object_Definition =>
9474 New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
9476 -- Allocate_Buffer (Strm);
9478 Append_To (Stms,
9479 Make_Procedure_Call_Statement (Loc,
9480 Name =>
9481 New_Occurrence_Of (RTE (RE_Allocate_Buffer), Loc),
9482 Parameter_Associations => New_List (
9483 New_Occurrence_Of (Strm, Loc))));
9485 -- T'Output (Strm'Access, E);
9487 Append_To (Stms,
9488 Make_Attribute_Reference (Loc,
9489 Prefix => New_Occurrence_Of (Typ, Loc),
9490 Attribute_Name => Name_Output,
9491 Expressions => New_List (
9492 Make_Attribute_Reference (Loc,
9493 Prefix => New_Occurrence_Of (Strm, Loc),
9494 Attribute_Name => Name_Access),
9495 New_Occurrence_Of (Expr_Parameter, Loc))));
9497 -- BS_To_Any (Strm, A);
9499 Append_To (Stms,
9500 Make_Procedure_Call_Statement (Loc,
9501 Name =>
9502 New_Occurrence_Of (RTE (RE_BS_To_Any), Loc),
9503 Parameter_Associations => New_List (
9504 New_Occurrence_Of (Strm, Loc),
9505 New_Occurrence_Of (Any, Loc))));
9507 -- Release_Buffer (Strm);
9509 Append_To (Stms,
9510 Make_Procedure_Call_Statement (Loc,
9511 Name =>
9512 New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
9513 Parameter_Associations => New_List (
9514 New_Occurrence_Of (Strm, Loc))));
9515 end;
9516 end if;
9518 Append_To (Decls, Any_Decl);
9520 if Present (Result_TC) then
9521 Append_To (Stms,
9522 Make_Procedure_Call_Statement (Loc,
9523 Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
9524 Parameter_Associations => New_List (
9525 New_Occurrence_Of (Any, Loc),
9526 Result_TC)));
9527 end if;
9529 Append_To (Stms,
9530 Make_Return_Statement (Loc,
9531 Expression => New_Occurrence_Of (Any, Loc)));
9533 Decl :=
9534 Make_Subprogram_Body (Loc,
9535 Specification => Spec,
9536 Declarations => Decls,
9537 Handled_Statement_Sequence =>
9538 Make_Handled_Sequence_Of_Statements (Loc,
9539 Statements => Stms));
9540 end Build_To_Any_Function;
9542 -------------------------
9543 -- Build_TypeCode_Call --
9544 -------------------------
9546 function Build_TypeCode_Call
9547 (Loc : Source_Ptr;
9548 Typ : Entity_Id;
9549 Decls : List_Id) return Node_Id
9551 U_Type : Entity_Id := Underlying_Type (Typ);
9552 -- The full view, if Typ is private; the completion,
9553 -- if Typ is incomplete.
9555 Fnam : Entity_Id := Empty;
9556 Lib_RE : RE_Id := RE_Null;
9558 Expr : Node_Id;
9560 begin
9561 -- Special case System.PolyORB.Interface.Any: its primitives have
9562 -- not been set yet, so can't call Find_Inherited_TSS.
9564 if Typ = RTE (RE_Any) then
9565 Fnam := RTE (RE_TC_Any);
9567 else
9568 -- First simple case where the TypeCode is present
9569 -- in the type's TSS.
9571 Fnam := Find_Inherited_TSS (U_Type, TSS_TypeCode);
9572 end if;
9574 if No (Fnam) then
9575 if Sloc (U_Type) <= Standard_Location then
9577 -- Do not try to build alias typecodes for subtypes from
9578 -- Standard.
9580 U_Type := Base_Type (U_Type);
9581 end if;
9583 if U_Type = Standard_Boolean then
9584 Lib_RE := RE_TC_B;
9586 elsif U_Type = Standard_Character then
9587 Lib_RE := RE_TC_C;
9589 elsif U_Type = Standard_Wide_Character then
9590 Lib_RE := RE_TC_WC;
9592 elsif U_Type = Standard_Wide_Wide_Character then
9593 Lib_RE := RE_TC_WWC;
9595 -- Floating point types
9597 elsif U_Type = Standard_Short_Float then
9598 Lib_RE := RE_TC_SF;
9600 elsif U_Type = Standard_Float then
9601 Lib_RE := RE_TC_F;
9603 elsif U_Type = Standard_Long_Float then
9604 Lib_RE := RE_TC_LF;
9606 elsif U_Type = Standard_Long_Long_Float then
9607 Lib_RE := RE_TC_LLF;
9609 -- Integer types (walk back to the base type)
9611 elsif U_Type = Etype (Standard_Short_Short_Integer) then
9612 Lib_RE := RE_TC_SSI;
9614 elsif U_Type = Etype (Standard_Short_Integer) then
9615 Lib_RE := RE_TC_SI;
9617 elsif U_Type = Etype (Standard_Integer) then
9618 Lib_RE := RE_TC_I;
9620 elsif U_Type = Etype (Standard_Long_Integer) then
9621 Lib_RE := RE_TC_LI;
9623 elsif U_Type = Etype (Standard_Long_Long_Integer) then
9624 Lib_RE := RE_TC_LLI;
9626 -- Unsigned integer types
9628 elsif U_Type = RTE (RE_Short_Short_Unsigned) then
9629 Lib_RE := RE_TC_SSU;
9631 elsif U_Type = RTE (RE_Short_Unsigned) then
9632 Lib_RE := RE_TC_SU;
9634 elsif U_Type = RTE (RE_Unsigned) then
9635 Lib_RE := RE_TC_U;
9637 elsif U_Type = RTE (RE_Long_Unsigned) then
9638 Lib_RE := RE_TC_LU;
9640 elsif U_Type = RTE (RE_Long_Long_Unsigned) then
9641 Lib_RE := RE_TC_LLU;
9643 elsif U_Type = Standard_String then
9644 Lib_RE := RE_TC_String;
9646 -- Other (non-primitive) types
9648 else
9649 declare
9650 Decl : Entity_Id;
9651 begin
9652 Build_TypeCode_Function (Loc, U_Type, Decl, Fnam);
9653 Append_To (Decls, Decl);
9654 end;
9655 end if;
9657 if Lib_RE /= RE_Null then
9658 Fnam := RTE (Lib_RE);
9659 end if;
9660 end if;
9662 -- Call the function
9664 Expr :=
9665 Make_Function_Call (Loc, Name => New_Occurrence_Of (Fnam, Loc));
9667 -- Allow Expr to be used as arg to Build_To_Any_Call immediately
9669 Set_Etype (Expr, RTE (RE_TypeCode));
9671 return Expr;
9672 end Build_TypeCode_Call;
9674 -----------------------------
9675 -- Build_TypeCode_Function --
9676 -----------------------------
9678 procedure Build_TypeCode_Function
9679 (Loc : Source_Ptr;
9680 Typ : Entity_Id;
9681 Decl : out Node_Id;
9682 Fnam : out Entity_Id)
9684 Spec : Node_Id;
9685 Decls : constant List_Id := New_List;
9686 Stms : constant List_Id := New_List;
9688 TCNam : constant Entity_Id :=
9689 Make_Stream_Procedure_Function_Name (Loc,
9690 Typ, Name_uTypeCode);
9692 Parameters : List_Id;
9694 procedure Add_String_Parameter
9695 (S : String_Id;
9696 Parameter_List : List_Id);
9697 -- Add a literal for S to Parameters
9699 procedure Add_TypeCode_Parameter
9700 (TC_Node : Node_Id;
9701 Parameter_List : List_Id);
9702 -- Add the typecode for Typ to Parameters
9704 procedure Add_Long_Parameter
9705 (Expr_Node : Node_Id;
9706 Parameter_List : List_Id);
9707 -- Add a signed long integer expression to Parameters
9709 procedure Initialize_Parameter_List
9710 (Name_String : String_Id;
9711 Repo_Id_String : String_Id;
9712 Parameter_List : out List_Id);
9713 -- Return a list that contains the first two parameters
9714 -- for a parameterized typecode: name and repository id.
9716 function Make_Constructed_TypeCode
9717 (Kind : Entity_Id;
9718 Parameters : List_Id) return Node_Id;
9719 -- Call TC_Build with the given kind and parameters
9721 procedure Return_Constructed_TypeCode (Kind : Entity_Id);
9722 -- Make a return statement that calls TC_Build with the given
9723 -- typecode kind, and the constructed parameters list.
9725 procedure Return_Alias_TypeCode (Base_TypeCode : Node_Id);
9726 -- Return a typecode that is a TC_Alias for the given typecode
9728 --------------------------
9729 -- Add_String_Parameter --
9730 --------------------------
9732 procedure Add_String_Parameter
9733 (S : String_Id;
9734 Parameter_List : List_Id)
9736 begin
9737 Append_To (Parameter_List,
9738 Make_Function_Call (Loc,
9739 Name =>
9740 New_Occurrence_Of (RTE (RE_TA_String), Loc),
9741 Parameter_Associations => New_List (
9742 Make_String_Literal (Loc, S))));
9743 end Add_String_Parameter;
9745 ----------------------------
9746 -- Add_TypeCode_Parameter --
9747 ----------------------------
9749 procedure Add_TypeCode_Parameter
9750 (TC_Node : Node_Id;
9751 Parameter_List : List_Id)
9753 begin
9754 Append_To (Parameter_List,
9755 Make_Function_Call (Loc,
9756 Name =>
9757 New_Occurrence_Of (RTE (RE_TA_TC), Loc),
9758 Parameter_Associations => New_List (
9759 TC_Node)));
9760 end Add_TypeCode_Parameter;
9762 ------------------------
9763 -- Add_Long_Parameter --
9764 ------------------------
9766 procedure Add_Long_Parameter
9767 (Expr_Node : Node_Id;
9768 Parameter_List : List_Id)
9770 begin
9771 Append_To (Parameter_List,
9772 Make_Function_Call (Loc,
9773 Name =>
9774 New_Occurrence_Of (RTE (RE_TA_LI), Loc),
9775 Parameter_Associations => New_List (Expr_Node)));
9776 end Add_Long_Parameter;
9778 -------------------------------
9779 -- Initialize_Parameter_List --
9780 -------------------------------
9782 procedure Initialize_Parameter_List
9783 (Name_String : String_Id;
9784 Repo_Id_String : String_Id;
9785 Parameter_List : out List_Id)
9787 begin
9788 Parameter_List := New_List;
9789 Add_String_Parameter (Name_String, Parameter_List);
9790 Add_String_Parameter (Repo_Id_String, Parameter_List);
9791 end Initialize_Parameter_List;
9793 ---------------------------
9794 -- Return_Alias_TypeCode --
9795 ---------------------------
9797 procedure Return_Alias_TypeCode
9798 (Base_TypeCode : Node_Id)
9800 begin
9801 Add_TypeCode_Parameter (Base_TypeCode, Parameters);
9802 Return_Constructed_TypeCode (RTE (RE_TC_Alias));
9803 end Return_Alias_TypeCode;
9805 -------------------------------
9806 -- Make_Constructed_TypeCode --
9807 -------------------------------
9809 function Make_Constructed_TypeCode
9810 (Kind : Entity_Id;
9811 Parameters : List_Id) return Node_Id
9813 Constructed_TC : constant Node_Id :=
9814 Make_Function_Call (Loc,
9815 Name =>
9816 New_Occurrence_Of (RTE (RE_TC_Build), Loc),
9817 Parameter_Associations => New_List (
9818 New_Occurrence_Of (Kind, Loc),
9819 Make_Aggregate (Loc,
9820 Expressions => Parameters)));
9821 begin
9822 Set_Etype (Constructed_TC, RTE (RE_TypeCode));
9823 return Constructed_TC;
9824 end Make_Constructed_TypeCode;
9826 ---------------------------------
9827 -- Return_Constructed_TypeCode --
9828 ---------------------------------
9830 procedure Return_Constructed_TypeCode (Kind : Entity_Id) is
9831 begin
9832 Append_To (Stms,
9833 Make_Return_Statement (Loc,
9834 Expression =>
9835 Make_Constructed_TypeCode (Kind, Parameters)));
9836 end Return_Constructed_TypeCode;
9838 ------------------
9839 -- Record types --
9840 ------------------
9842 procedure TC_Rec_Add_Process_Element
9843 (Params : List_Id;
9844 Any : Entity_Id;
9845 Counter : in out Int;
9846 Rec : Entity_Id;
9847 Field : Node_Id);
9849 procedure TC_Append_Record_Traversal is
9850 new Append_Record_Traversal (
9851 Rec => Empty,
9852 Add_Process_Element => TC_Rec_Add_Process_Element);
9854 --------------------------------
9855 -- TC_Rec_Add_Process_Element --
9856 --------------------------------
9858 procedure TC_Rec_Add_Process_Element
9859 (Params : List_Id;
9860 Any : Entity_Id;
9861 Counter : in out Int;
9862 Rec : Entity_Id;
9863 Field : Node_Id)
9865 pragma Warnings (Off);
9866 pragma Unreferenced (Any, Counter, Rec);
9867 pragma Warnings (On);
9869 begin
9870 if Nkind (Field) = N_Defining_Identifier then
9872 -- A regular component
9874 Add_TypeCode_Parameter (
9875 Build_TypeCode_Call (Loc, Etype (Field), Decls), Params);
9876 Get_Name_String (Chars (Field));
9877 Add_String_Parameter (String_From_Name_Buffer, Params);
9879 else
9881 -- A variant part
9883 declare
9884 Discriminant_Type : constant Entity_Id :=
9885 Etype (Name (Field));
9887 Is_Enum : constant Boolean :=
9888 Is_Enumeration_Type (Discriminant_Type);
9890 Union_TC_Params : List_Id;
9892 U_Name : constant Name_Id :=
9893 New_External_Name (Chars (Typ), 'U', -1);
9895 Name_Str : String_Id;
9896 Struct_TC_Params : List_Id;
9898 Variant : Node_Id;
9899 Choice : Node_Id;
9900 Default : constant Node_Id :=
9901 Make_Integer_Literal (Loc, -1);
9903 Dummy_Counter : Int := 0;
9905 procedure Add_Params_For_Variant_Components;
9906 -- Add a struct TypeCode and a corresponding member name
9907 -- to the union parameter list.
9909 -- Ordering of declarations is a complete mess in this
9910 -- area, it is supposed to be types/varibles, then
9911 -- subprogram specs, then subprogram bodies ???
9913 ---------------------------------------
9914 -- Add_Params_For_Variant_Components --
9915 ---------------------------------------
9917 procedure Add_Params_For_Variant_Components
9919 S_Name : constant Name_Id :=
9920 New_External_Name (U_Name, 'S', -1);
9922 begin
9923 Get_Name_String (S_Name);
9924 Name_Str := String_From_Name_Buffer;
9925 Initialize_Parameter_List
9926 (Name_Str, Name_Str, Struct_TC_Params);
9928 -- Build struct parameters
9930 TC_Append_Record_Traversal (Struct_TC_Params,
9931 Component_List (Variant),
9932 Empty,
9933 Dummy_Counter);
9935 Add_TypeCode_Parameter
9936 (Make_Constructed_TypeCode
9937 (RTE (RE_TC_Struct), Struct_TC_Params),
9938 Union_TC_Params);
9940 Add_String_Parameter (Name_Str, Union_TC_Params);
9941 end Add_Params_For_Variant_Components;
9943 begin
9944 Get_Name_String (U_Name);
9945 Name_Str := String_From_Name_Buffer;
9947 Initialize_Parameter_List
9948 (Name_Str, Name_Str, Union_TC_Params);
9950 Add_String_Parameter (Name_Str, Params);
9952 -- Add union in enclosing parameter list
9954 Add_TypeCode_Parameter
9955 (Make_Constructed_TypeCode
9956 (RTE (RE_TC_Union), Union_TC_Params),
9957 Parameters);
9959 -- Build union parameters
9961 Add_TypeCode_Parameter
9962 (Discriminant_Type, Union_TC_Params);
9963 Add_Long_Parameter (Default, Union_TC_Params);
9965 Variant := First_Non_Pragma (Variants (Field));
9966 while Present (Variant) loop
9967 Choice := First (Discrete_Choices (Variant));
9968 while Present (Choice) loop
9969 case Nkind (Choice) is
9970 when N_Range =>
9971 declare
9972 L : constant Uint :=
9973 Expr_Value (Low_Bound (Choice));
9974 H : constant Uint :=
9975 Expr_Value (High_Bound (Choice));
9976 J : Uint := L;
9977 -- 3.8.1(8) guarantees that the bounds of
9978 -- this range are static.
9980 Expr : Node_Id;
9982 begin
9983 while J <= H loop
9984 if Is_Enum then
9985 Expr := New_Occurrence_Of (
9986 Get_Enum_Lit_From_Pos (
9987 Discriminant_Type, J, Loc), Loc);
9988 else
9989 Expr :=
9990 Make_Integer_Literal (Loc, J);
9991 end if;
9992 Append_To (Union_TC_Params,
9993 Build_To_Any_Call (Expr, Decls));
9994 Add_Params_For_Variant_Components;
9995 J := J + Uint_1;
9996 end loop;
9997 end;
9999 when N_Others_Choice =>
10000 Add_Long_Parameter (
10001 Make_Integer_Literal (Loc, 0),
10002 Union_TC_Params);
10003 Add_Params_For_Variant_Components;
10005 when others =>
10006 Append_To (Union_TC_Params,
10007 Build_To_Any_Call (Choice, Decls));
10008 Add_Params_For_Variant_Components;
10010 end case;
10012 end loop;
10014 Next_Non_Pragma (Variant);
10015 end loop;
10017 end;
10018 end if;
10019 end TC_Rec_Add_Process_Element;
10021 Type_Name_Str : String_Id;
10022 Type_Repo_Id_Str : String_Id;
10024 begin
10025 pragma Assert (not Is_Itype (Typ));
10026 Fnam := TCNam;
10028 Spec :=
10029 Make_Function_Specification (Loc,
10030 Defining_Unit_Name => Fnam,
10031 Parameter_Specifications => Empty_List,
10032 Result_Definition =>
10033 New_Occurrence_Of (RTE (RE_TypeCode), Loc));
10035 Build_Name_And_Repository_Id (Typ,
10036 Name_Str => Type_Name_Str, Repo_Id_Str => Type_Repo_Id_Str);
10037 Initialize_Parameter_List
10038 (Type_Name_Str, Type_Repo_Id_Str, Parameters);
10040 if Is_Derived_Type (Typ)
10041 and then not Is_Tagged_Type (Typ)
10042 then
10043 declare
10044 Parent_Type : Entity_Id := Etype (Typ);
10045 begin
10047 if Is_Itype (Parent_Type) then
10049 -- Skip implicit base type
10051 Parent_Type := Etype (Parent_Type);
10052 end if;
10054 Return_Alias_TypeCode (
10055 Build_TypeCode_Call (Loc, Parent_Type, Decls));
10056 end;
10058 elsif Is_Integer_Type (Typ)
10059 or else Is_Unsigned_Type (Typ)
10060 then
10061 Return_Alias_TypeCode (
10062 Build_TypeCode_Call (Loc,
10063 Find_Numeric_Representation (Typ), Decls));
10065 elsif Is_Record_Type (Typ)
10066 and then not Is_Tagged_Type (Typ)
10067 then
10068 if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
10069 Return_Alias_TypeCode (
10070 Build_TypeCode_Call (Loc, Etype (Typ), Decls));
10071 else
10072 declare
10073 Disc : Entity_Id := Empty;
10074 Rdef : constant Node_Id :=
10075 Type_Definition (Declaration_Node (Typ));
10076 Dummy_Counter : Int := 0;
10077 begin
10078 -- First all discriminants
10080 if Has_Discriminants (Typ) then
10081 Disc := First_Discriminant (Typ);
10082 end if;
10083 while Present (Disc) loop
10084 Add_TypeCode_Parameter (
10085 Build_TypeCode_Call (Loc, Etype (Disc), Decls),
10086 Parameters);
10087 Get_Name_String (Chars (Disc));
10088 Add_String_Parameter (
10089 String_From_Name_Buffer,
10090 Parameters);
10091 Next_Discriminant (Disc);
10092 end loop;
10094 -- ... then all components
10096 TC_Append_Record_Traversal
10097 (Parameters, Component_List (Rdef),
10098 Empty, Dummy_Counter);
10099 Return_Constructed_TypeCode (RTE (RE_TC_Struct));
10100 end;
10101 end if;
10103 elsif Is_Array_Type (Typ) then
10104 declare
10105 Ndim : constant Pos := Number_Dimensions (Typ);
10106 Inner_TypeCode : Node_Id;
10107 Constrained : constant Boolean := Is_Constrained (Typ);
10108 Indx : Node_Id := First_Index (Typ);
10110 begin
10111 Inner_TypeCode := Build_TypeCode_Call (Loc,
10112 Component_Type (Typ),
10113 Decls);
10115 for J in 1 .. Ndim loop
10116 if Constrained then
10117 Inner_TypeCode := Make_Constructed_TypeCode
10118 (RTE (RE_TC_Array), New_List (
10119 Build_To_Any_Call (
10120 OK_Convert_To (RTE (RE_Long_Unsigned),
10121 Make_Attribute_Reference (Loc,
10122 Prefix =>
10123 New_Occurrence_Of (Typ, Loc),
10124 Attribute_Name =>
10125 Name_Length,
10126 Expressions => New_List (
10127 Make_Integer_Literal (Loc,
10128 Ndim - J + 1)))),
10129 Decls),
10130 Build_To_Any_Call (Inner_TypeCode, Decls)));
10132 else
10133 -- Unconstrained case: add low bound for each
10134 -- dimension.
10136 Add_TypeCode_Parameter
10137 (Build_TypeCode_Call (Loc, Etype (Indx), Decls),
10138 Parameters);
10139 Get_Name_String (New_External_Name ('L', J));
10140 Add_String_Parameter (
10141 String_From_Name_Buffer,
10142 Parameters);
10143 Next_Index (Indx);
10145 Inner_TypeCode := Make_Constructed_TypeCode
10146 (RTE (RE_TC_Sequence), New_List (
10147 Build_To_Any_Call (
10148 OK_Convert_To (RTE (RE_Long_Unsigned),
10149 Make_Integer_Literal (Loc, 0)),
10150 Decls),
10151 Build_To_Any_Call (Inner_TypeCode, Decls)));
10152 end if;
10153 end loop;
10155 if Constrained then
10156 Return_Alias_TypeCode (Inner_TypeCode);
10157 else
10158 Add_TypeCode_Parameter (Inner_TypeCode, Parameters);
10159 Start_String;
10160 Store_String_Char ('V');
10161 Add_String_Parameter (End_String, Parameters);
10162 Return_Constructed_TypeCode (RTE (RE_TC_Struct));
10163 end if;
10164 end;
10166 else
10167 -- Default: type is represented as an opaque sequence of bytes
10169 Return_Alias_TypeCode
10170 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
10171 end if;
10173 Decl :=
10174 Make_Subprogram_Body (Loc,
10175 Specification => Spec,
10176 Declarations => Decls,
10177 Handled_Statement_Sequence =>
10178 Make_Handled_Sequence_Of_Statements (Loc,
10179 Statements => Stms));
10180 end Build_TypeCode_Function;
10182 ---------------------------------
10183 -- Find_Numeric_Representation --
10184 ---------------------------------
10186 function Find_Numeric_Representation
10187 (Typ : Entity_Id) return Entity_Id
10189 FST : constant Entity_Id := First_Subtype (Typ);
10190 P_Size : constant Uint := Esize (FST);
10192 begin
10193 if Is_Unsigned_Type (Typ) then
10194 if P_Size <= Standard_Short_Short_Integer_Size then
10195 return RTE (RE_Short_Short_Unsigned);
10197 elsif P_Size <= Standard_Short_Integer_Size then
10198 return RTE (RE_Short_Unsigned);
10200 elsif P_Size <= Standard_Integer_Size then
10201 return RTE (RE_Unsigned);
10203 elsif P_Size <= Standard_Long_Integer_Size then
10204 return RTE (RE_Long_Unsigned);
10206 else
10207 return RTE (RE_Long_Long_Unsigned);
10208 end if;
10210 elsif Is_Integer_Type (Typ) then
10211 if P_Size <= Standard_Short_Short_Integer_Size then
10212 return Standard_Short_Short_Integer;
10214 elsif P_Size <= Standard_Short_Integer_Size then
10215 return Standard_Short_Integer;
10217 elsif P_Size <= Standard_Integer_Size then
10218 return Standard_Integer;
10220 elsif P_Size <= Standard_Long_Integer_Size then
10221 return Standard_Long_Integer;
10223 else
10224 return Standard_Long_Long_Integer;
10225 end if;
10227 elsif Is_Floating_Point_Type (Typ) then
10228 if P_Size <= Standard_Short_Float_Size then
10229 return Standard_Short_Float;
10231 elsif P_Size <= Standard_Float_Size then
10232 return Standard_Float;
10234 elsif P_Size <= Standard_Long_Float_Size then
10235 return Standard_Long_Float;
10237 else
10238 return Standard_Long_Long_Float;
10239 end if;
10241 else
10242 raise Program_Error;
10243 end if;
10245 -- TBD: fixed point types???
10246 -- TBverified numeric types with a biased representation???
10248 end Find_Numeric_Representation;
10250 ---------------------------
10251 -- Append_Array_Traversal --
10252 ---------------------------
10254 procedure Append_Array_Traversal
10255 (Stmts : List_Id;
10256 Any : Entity_Id;
10257 Counter : Entity_Id := Empty;
10258 Depth : Pos := 1)
10260 Loc : constant Source_Ptr := Sloc (Subprogram);
10261 Typ : constant Entity_Id := Etype (Arry);
10262 Constrained : constant Boolean := Is_Constrained (Typ);
10263 Ndim : constant Pos := Number_Dimensions (Typ);
10265 Inner_Any, Inner_Counter : Entity_Id;
10267 Loop_Stm : Node_Id;
10268 Inner_Stmts : constant List_Id := New_List;
10270 begin
10271 if Depth > Ndim then
10273 -- Processing for one element of an array
10275 declare
10276 Element_Expr : constant Node_Id :=
10277 Make_Indexed_Component (Loc,
10278 New_Occurrence_Of (Arry, Loc),
10279 Indices);
10281 begin
10282 Set_Etype (Element_Expr, Component_Type (Typ));
10283 Add_Process_Element (Stmts,
10284 Any => Any,
10285 Counter => Counter,
10286 Datum => Element_Expr);
10287 end;
10289 return;
10290 end if;
10292 Append_To (Indices,
10293 Make_Identifier (Loc, New_External_Name ('L', Depth)));
10295 if not Constrained or else Depth > 1 then
10296 Inner_Any := Make_Defining_Identifier (Loc,
10297 New_External_Name ('A', Depth));
10298 Set_Etype (Inner_Any, RTE (RE_Any));
10299 else
10300 Inner_Any := Empty;
10301 end if;
10303 if Present (Counter) then
10304 Inner_Counter := Make_Defining_Identifier (Loc,
10305 New_External_Name ('J', Depth));
10306 else
10307 Inner_Counter := Empty;
10308 end if;
10310 declare
10311 Loop_Any : Node_Id := Inner_Any;
10312 begin
10314 -- For the first dimension of a constrained array, we add
10315 -- elements directly in the corresponding Any; there is no
10316 -- intervening inner Any.
10318 if No (Loop_Any) then
10319 Loop_Any := Any;
10320 end if;
10322 Append_Array_Traversal (Inner_Stmts,
10323 Any => Loop_Any,
10324 Counter => Inner_Counter,
10325 Depth => Depth + 1);
10326 end;
10328 Loop_Stm :=
10329 Make_Implicit_Loop_Statement (Subprogram,
10330 Iteration_Scheme =>
10331 Make_Iteration_Scheme (Loc,
10332 Loop_Parameter_Specification =>
10333 Make_Loop_Parameter_Specification (Loc,
10334 Defining_Identifier =>
10335 Make_Defining_Identifier (Loc,
10336 Chars => New_External_Name ('L', Depth)),
10338 Discrete_Subtype_Definition =>
10339 Make_Attribute_Reference (Loc,
10340 Prefix => New_Occurrence_Of (Arry, Loc),
10341 Attribute_Name => Name_Range,
10343 Expressions => New_List (
10344 Make_Integer_Literal (Loc, Depth))))),
10345 Statements => Inner_Stmts);
10347 declare
10348 Decls : constant List_Id := New_List;
10349 Dimen_Stmts : constant List_Id := New_List;
10350 Length_Node : Node_Id;
10352 Inner_Any_TypeCode : constant Entity_Id :=
10353 Make_Defining_Identifier (Loc,
10354 New_External_Name ('T', Depth));
10356 Inner_Any_TypeCode_Expr : Node_Id;
10358 begin
10359 if Depth = 1 then
10360 if Constrained then
10361 Inner_Any_TypeCode_Expr :=
10362 Make_Function_Call (Loc,
10363 Name =>
10364 New_Occurrence_Of (RTE (RE_Get_TC), Loc),
10365 Parameter_Associations => New_List (
10366 New_Occurrence_Of (Any, Loc)));
10367 else
10368 Inner_Any_TypeCode_Expr :=
10369 Make_Function_Call (Loc,
10370 Name =>
10371 New_Occurrence_Of (RTE (RE_Any_Member_Type), Loc),
10372 Parameter_Associations => New_List (
10373 New_Occurrence_Of (Any, Loc),
10374 Make_Integer_Literal (Loc, Ndim)));
10375 end if;
10376 else
10377 Inner_Any_TypeCode_Expr :=
10378 Make_Function_Call (Loc,
10379 Name =>
10380 New_Occurrence_Of (RTE (RE_Content_Type), Loc),
10381 Parameter_Associations => New_List (
10382 Make_Identifier (Loc,
10383 New_External_Name ('T', Depth - 1))));
10384 end if;
10386 Append_To (Decls,
10387 Make_Object_Declaration (Loc,
10388 Defining_Identifier => Inner_Any_TypeCode,
10389 Constant_Present => True,
10390 Object_Definition => New_Occurrence_Of (
10391 RTE (RE_TypeCode), Loc),
10392 Expression => Inner_Any_TypeCode_Expr));
10394 if Present (Inner_Any) then
10395 Append_To (Decls,
10396 Make_Object_Declaration (Loc,
10397 Defining_Identifier => Inner_Any,
10398 Object_Definition =>
10399 New_Occurrence_Of (RTE (RE_Any), Loc),
10400 Expression =>
10401 Make_Function_Call (Loc,
10402 Name =>
10403 New_Occurrence_Of (
10404 RTE (RE_Create_Any), Loc),
10405 Parameter_Associations => New_List (
10406 New_Occurrence_Of (Inner_Any_TypeCode, Loc)))));
10407 end if;
10409 if Present (Inner_Counter) then
10410 Append_To (Decls,
10411 Make_Object_Declaration (Loc,
10412 Defining_Identifier => Inner_Counter,
10413 Object_Definition =>
10414 New_Occurrence_Of (RTE (RE_Long_Unsigned), Loc),
10415 Expression =>
10416 Make_Integer_Literal (Loc, 0)));
10417 end if;
10419 if not Constrained then
10420 Length_Node := Make_Attribute_Reference (Loc,
10421 Prefix => New_Occurrence_Of (Arry, Loc),
10422 Attribute_Name => Name_Length,
10423 Expressions =>
10424 New_List (Make_Integer_Literal (Loc, Depth)));
10425 Set_Etype (Length_Node, RTE (RE_Long_Unsigned));
10427 Add_Process_Element (Dimen_Stmts,
10428 Datum => Length_Node,
10429 Any => Inner_Any,
10430 Counter => Inner_Counter);
10431 end if;
10433 -- Loop_Stm does approrpriate processing for each element
10434 -- of Inner_Any.
10436 Append_To (Dimen_Stmts, Loop_Stm);
10438 -- Link outer and inner any
10440 if Present (Inner_Any) then
10441 Add_Process_Element (Dimen_Stmts,
10442 Any => Any,
10443 Counter => Counter,
10444 Datum => New_Occurrence_Of (Inner_Any, Loc));
10445 end if;
10447 Append_To (Stmts,
10448 Make_Block_Statement (Loc,
10449 Declarations =>
10450 Decls,
10451 Handled_Statement_Sequence =>
10452 Make_Handled_Sequence_Of_Statements (Loc,
10453 Statements => Dimen_Stmts)));
10454 end;
10455 end Append_Array_Traversal;
10457 -----------------------------------------
10458 -- Make_Stream_Procedure_Function_Name --
10459 -----------------------------------------
10461 function Make_Stream_Procedure_Function_Name
10462 (Loc : Source_Ptr;
10463 Typ : Entity_Id;
10464 Nam : Name_Id) return Entity_Id
10466 begin
10467 -- For tagged types, we use a canonical name so that it matches
10468 -- the primitive spec. For all other cases, we use a serialized
10469 -- name so that multiple generations of the same procedure do not
10470 -- clash.
10472 if Is_Tagged_Type (Typ) then
10473 return Make_Defining_Identifier (Loc, Nam);
10474 else
10475 return Make_Defining_Identifier (Loc,
10476 Chars =>
10477 New_External_Name (Nam, ' ', Increment_Serial_Number));
10478 end if;
10479 end Make_Stream_Procedure_Function_Name;
10480 end Helpers;
10482 -----------------------------------
10483 -- Reserve_NamingContext_Methods --
10484 -----------------------------------
10486 procedure Reserve_NamingContext_Methods is
10487 Str_Resolve : constant String := "resolve";
10488 begin
10489 Name_Buffer (1 .. Str_Resolve'Length) := Str_Resolve;
10490 Name_Len := Str_Resolve'Length;
10491 Overload_Counter_Table.Set (Name_Find, 1);
10492 end Reserve_NamingContext_Methods;
10494 end PolyORB_Support;
10496 -------------------------------
10497 -- RACW_Type_Is_Asynchronous --
10498 -------------------------------
10500 procedure RACW_Type_Is_Asynchronous (RACW_Type : Entity_Id) is
10501 Asynchronous_Flag : constant Entity_Id :=
10502 Asynchronous_Flags_Table.Get (RACW_Type);
10503 begin
10504 Replace (Expression (Parent (Asynchronous_Flag)),
10505 New_Occurrence_Of (Standard_True, Sloc (Asynchronous_Flag)));
10506 end RACW_Type_Is_Asynchronous;
10508 -------------------------
10509 -- RCI_Package_Locator --
10510 -------------------------
10512 function RCI_Package_Locator
10513 (Loc : Source_Ptr;
10514 Package_Spec : Node_Id) return Node_Id
10516 Inst : Node_Id;
10517 Pkg_Name : String_Id;
10519 begin
10520 Get_Library_Unit_Name_String (Package_Spec);
10521 Pkg_Name := String_From_Name_Buffer;
10522 Inst :=
10523 Make_Package_Instantiation (Loc,
10524 Defining_Unit_Name =>
10525 Make_Defining_Identifier (Loc, New_Internal_Name ('R')),
10526 Name =>
10527 New_Occurrence_Of (RTE (RE_RCI_Locator), Loc),
10528 Generic_Associations => New_List (
10529 Make_Generic_Association (Loc,
10530 Selector_Name =>
10531 Make_Identifier (Loc, Name_RCI_Name),
10532 Explicit_Generic_Actual_Parameter =>
10533 Make_String_Literal (Loc,
10534 Strval => Pkg_Name))));
10536 RCI_Locator_Table.Set (Defining_Unit_Name (Package_Spec),
10537 Defining_Unit_Name (Inst));
10538 return Inst;
10539 end RCI_Package_Locator;
10541 -----------------------------------------------
10542 -- Remote_Types_Tagged_Full_View_Encountered --
10543 -----------------------------------------------
10545 procedure Remote_Types_Tagged_Full_View_Encountered
10546 (Full_View : Entity_Id)
10548 Stub_Elements : constant Stub_Structure :=
10549 Stubs_Table.Get (Full_View);
10550 begin
10551 if Stub_Elements /= Empty_Stub_Structure then
10552 Add_RACW_Primitive_Declarations_And_Bodies
10553 (Full_View,
10554 Stub_Elements.RPC_Receiver_Decl,
10555 List_Containing (Declaration_Node (Full_View)));
10556 end if;
10557 end Remote_Types_Tagged_Full_View_Encountered;
10559 -------------------
10560 -- Scope_Of_Spec --
10561 -------------------
10563 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
10564 Unit_Name : Node_Id;
10566 begin
10567 Unit_Name := Defining_Unit_Name (Spec);
10568 while Nkind (Unit_Name) /= N_Defining_Identifier loop
10569 Unit_Name := Defining_Identifier (Unit_Name);
10570 end loop;
10572 return Unit_Name;
10573 end Scope_Of_Spec;
10575 ----------------------
10576 -- Set_Renaming_TSS --
10577 ----------------------
10579 procedure Set_Renaming_TSS
10580 (Typ : Entity_Id;
10581 Nam : Entity_Id;
10582 TSS_Nam : TSS_Name_Type)
10584 Loc : constant Source_Ptr := Sloc (Nam);
10585 Spec : constant Node_Id := Parent (Nam);
10587 TSS_Node : constant Node_Id :=
10588 Make_Subprogram_Renaming_Declaration (Loc,
10589 Specification =>
10590 Copy_Specification (Loc,
10591 Spec => Spec,
10592 New_Name => Make_TSS_Name (Typ, TSS_Nam)),
10593 Name => New_Occurrence_Of (Nam, Loc));
10595 Snam : constant Entity_Id :=
10596 Defining_Unit_Name (Specification (TSS_Node));
10598 begin
10599 if Nkind (Spec) = N_Function_Specification then
10600 Set_Ekind (Snam, E_Function);
10601 Set_Etype (Snam, Entity (Result_Definition (Spec)));
10602 else
10603 Set_Ekind (Snam, E_Procedure);
10604 Set_Etype (Snam, Standard_Void_Type);
10605 end if;
10607 Set_TSS (Typ, Snam);
10608 end Set_Renaming_TSS;
10610 ----------------------------------------------
10611 -- Specific_Add_Obj_RPC_Receiver_Completion --
10612 ----------------------------------------------
10614 procedure Specific_Add_Obj_RPC_Receiver_Completion
10615 (Loc : Source_Ptr;
10616 Decls : List_Id;
10617 RPC_Receiver : Entity_Id;
10618 Stub_Elements : Stub_Structure) is
10619 begin
10620 case Get_PCS_Name is
10621 when Name_PolyORB_DSA =>
10622 PolyORB_Support.Add_Obj_RPC_Receiver_Completion (Loc,
10623 Decls, RPC_Receiver, Stub_Elements);
10624 when others =>
10625 GARLIC_Support.Add_Obj_RPC_Receiver_Completion (Loc,
10626 Decls, RPC_Receiver, Stub_Elements);
10627 end case;
10628 end Specific_Add_Obj_RPC_Receiver_Completion;
10630 --------------------------------
10631 -- Specific_Add_RACW_Features --
10632 --------------------------------
10634 procedure Specific_Add_RACW_Features
10635 (RACW_Type : Entity_Id;
10636 Desig : Entity_Id;
10637 Stub_Type : Entity_Id;
10638 Stub_Type_Access : Entity_Id;
10639 RPC_Receiver_Decl : Node_Id;
10640 Declarations : List_Id) is
10641 begin
10642 case Get_PCS_Name is
10643 when Name_PolyORB_DSA =>
10644 PolyORB_Support.Add_RACW_Features (
10645 RACW_Type,
10646 Desig,
10647 Stub_Type,
10648 Stub_Type_Access,
10649 RPC_Receiver_Decl,
10650 Declarations);
10652 when others =>
10653 GARLIC_Support.Add_RACW_Features (
10654 RACW_Type,
10655 Stub_Type,
10656 Stub_Type_Access,
10657 RPC_Receiver_Decl,
10658 Declarations);
10659 end case;
10660 end Specific_Add_RACW_Features;
10662 --------------------------------
10663 -- Specific_Add_RAST_Features --
10664 --------------------------------
10666 procedure Specific_Add_RAST_Features
10667 (Vis_Decl : Node_Id;
10668 RAS_Type : Entity_Id) is
10669 begin
10670 case Get_PCS_Name is
10671 when Name_PolyORB_DSA =>
10672 PolyORB_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
10673 when others =>
10674 GARLIC_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
10675 end case;
10676 end Specific_Add_RAST_Features;
10678 --------------------------------------------------
10679 -- Specific_Add_Receiving_Stubs_To_Declarations --
10680 --------------------------------------------------
10682 procedure Specific_Add_Receiving_Stubs_To_Declarations
10683 (Pkg_Spec : Node_Id;
10684 Decls : List_Id)
10686 begin
10687 case Get_PCS_Name is
10688 when Name_PolyORB_DSA =>
10689 PolyORB_Support.Add_Receiving_Stubs_To_Declarations (
10690 Pkg_Spec, Decls);
10691 when others =>
10692 GARLIC_Support.Add_Receiving_Stubs_To_Declarations (
10693 Pkg_Spec, Decls);
10694 end case;
10695 end Specific_Add_Receiving_Stubs_To_Declarations;
10697 ------------------------------------------
10698 -- Specific_Build_General_Calling_Stubs --
10699 ------------------------------------------
10701 procedure Specific_Build_General_Calling_Stubs
10702 (Decls : List_Id;
10703 Statements : List_Id;
10704 Target : RPC_Target;
10705 Subprogram_Id : Node_Id;
10706 Asynchronous : Node_Id := Empty;
10707 Is_Known_Asynchronous : Boolean := False;
10708 Is_Known_Non_Asynchronous : Boolean := False;
10709 Is_Function : Boolean;
10710 Spec : Node_Id;
10711 Stub_Type : Entity_Id := Empty;
10712 RACW_Type : Entity_Id := Empty;
10713 Nod : Node_Id)
10715 begin
10716 case Get_PCS_Name is
10717 when Name_PolyORB_DSA =>
10718 PolyORB_Support.Build_General_Calling_Stubs (
10719 Decls,
10720 Statements,
10721 Target.Object,
10722 Subprogram_Id,
10723 Asynchronous,
10724 Is_Known_Asynchronous,
10725 Is_Known_Non_Asynchronous,
10726 Is_Function,
10727 Spec,
10728 Stub_Type,
10729 RACW_Type,
10730 Nod);
10731 when others =>
10732 GARLIC_Support.Build_General_Calling_Stubs (
10733 Decls,
10734 Statements,
10735 Target.Partition,
10736 Target.RPC_Receiver,
10737 Subprogram_Id,
10738 Asynchronous,
10739 Is_Known_Asynchronous,
10740 Is_Known_Non_Asynchronous,
10741 Is_Function,
10742 Spec,
10743 Stub_Type,
10744 RACW_Type,
10745 Nod);
10746 end case;
10747 end Specific_Build_General_Calling_Stubs;
10749 --------------------------------------
10750 -- Specific_Build_RPC_Receiver_Body --
10751 --------------------------------------
10753 procedure Specific_Build_RPC_Receiver_Body
10754 (RPC_Receiver : Entity_Id;
10755 Request : out Entity_Id;
10756 Subp_Id : out Entity_Id;
10757 Subp_Index : out Entity_Id;
10758 Stmts : out List_Id;
10759 Decl : out Node_Id)
10761 begin
10762 case Get_PCS_Name is
10763 when Name_PolyORB_DSA =>
10764 PolyORB_Support.Build_RPC_Receiver_Body
10765 (RPC_Receiver,
10766 Request,
10767 Subp_Id,
10768 Subp_Index,
10769 Stmts,
10770 Decl);
10771 when others =>
10772 GARLIC_Support.Build_RPC_Receiver_Body
10773 (RPC_Receiver,
10774 Request,
10775 Subp_Id,
10776 Subp_Index,
10777 Stmts,
10778 Decl);
10779 end case;
10780 end Specific_Build_RPC_Receiver_Body;
10782 --------------------------------
10783 -- Specific_Build_Stub_Target --
10784 --------------------------------
10786 function Specific_Build_Stub_Target
10787 (Loc : Source_Ptr;
10788 Decls : List_Id;
10789 RCI_Locator : Entity_Id;
10790 Controlling_Parameter : Entity_Id) return RPC_Target
10792 begin
10793 case Get_PCS_Name is
10794 when Name_PolyORB_DSA =>
10795 return PolyORB_Support.Build_Stub_Target (Loc,
10796 Decls, RCI_Locator, Controlling_Parameter);
10797 when others =>
10798 return GARLIC_Support.Build_Stub_Target (Loc,
10799 Decls, RCI_Locator, Controlling_Parameter);
10800 end case;
10801 end Specific_Build_Stub_Target;
10803 ------------------------------
10804 -- Specific_Build_Stub_Type --
10805 ------------------------------
10807 procedure Specific_Build_Stub_Type
10808 (RACW_Type : Entity_Id;
10809 Stub_Type : Entity_Id;
10810 Stub_Type_Decl : out Node_Id;
10811 RPC_Receiver_Decl : out Node_Id)
10813 begin
10814 case Get_PCS_Name is
10815 when Name_PolyORB_DSA =>
10816 PolyORB_Support.Build_Stub_Type (
10817 RACW_Type, Stub_Type,
10818 Stub_Type_Decl, RPC_Receiver_Decl);
10819 when others =>
10820 GARLIC_Support.Build_Stub_Type (
10821 RACW_Type, Stub_Type,
10822 Stub_Type_Decl, RPC_Receiver_Decl);
10823 end case;
10824 end Specific_Build_Stub_Type;
10826 function Specific_Build_Subprogram_Receiving_Stubs
10827 (Vis_Decl : Node_Id;
10828 Asynchronous : Boolean;
10829 Dynamically_Asynchronous : Boolean := False;
10830 Stub_Type : Entity_Id := Empty;
10831 RACW_Type : Entity_Id := Empty;
10832 Parent_Primitive : Entity_Id := Empty) return Node_Id
10834 begin
10835 case Get_PCS_Name is
10836 when Name_PolyORB_DSA =>
10837 return PolyORB_Support.Build_Subprogram_Receiving_Stubs (
10838 Vis_Decl,
10839 Asynchronous,
10840 Dynamically_Asynchronous,
10841 Stub_Type,
10842 RACW_Type,
10843 Parent_Primitive);
10844 when others =>
10845 return GARLIC_Support.Build_Subprogram_Receiving_Stubs (
10846 Vis_Decl,
10847 Asynchronous,
10848 Dynamically_Asynchronous,
10849 Stub_Type,
10850 RACW_Type,
10851 Parent_Primitive);
10852 end case;
10853 end Specific_Build_Subprogram_Receiving_Stubs;
10855 --------------------------
10856 -- Underlying_RACW_Type --
10857 --------------------------
10859 function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is
10860 Record_Type : Entity_Id;
10862 begin
10863 if Ekind (RAS_Typ) = E_Record_Type then
10864 Record_Type := RAS_Typ;
10865 else
10866 pragma Assert (Present (Equivalent_Type (RAS_Typ)));
10867 Record_Type := Equivalent_Type (RAS_Typ);
10868 end if;
10870 return
10871 Etype (Subtype_Indication (
10872 Component_Definition (
10873 First (Component_Items (Component_List (
10874 Type_Definition (Declaration_Node (Record_Type))))))));
10875 end Underlying_RACW_Type;
10877 end Exp_Dist;